2025-06-30 从kmz坐标文件生成坐标dataframe

import zipfile
import os
from bs4 import BeautifulSoup
import pandas as pd
import re # 用于更精确的经纬度解析

def parse_kmz_to_dataframe(kmz_file_path):
    """
    读取KMZ文件,解析其中的KML数据,提取地标的名称和经纬度,
    并保存到Pandas DataFrame中。

    Args:
        kmz_file_path (str): KMZ文件的完整路径。

    Returns:
        pandas.DataFrame: 包含 'Name', 'Longitude', 'Latitude' 列的DataFrame。
                          如果文件或KML解析失败,返回空的DataFrame。
    """
    temp_dir = 'temp_kml_extract'
    kml_content = None
    extracted_kml_path = None

    try:
        # 1. 解压缩KMZ文件
        with zipfile.ZipFile(kmz_file_path, 'r') as zip_ref:
            # 创建临时目录
            os.makedirs(temp_dir, exist_ok=True)
            # 提取所有文件到临时目录
            zip_ref.extractall(temp_dir)

            # 查找KML文件 (通常是doc.kml或文件名.kml)
            for file_name in zip_ref.namelist():
                if file_name.endswith('.kml'):
                    extracted_kml_path = os.path.join(temp_dir, file_name)
                    with open(extracted_kml_path, 'r', encoding='utf-8') as f:
                        kml_content = f.read()
                    break
            
            if kml_content is None:
                print(f"错误: 在 {kmz_file_path} 中未找到KML文件。")
                return pd.DataFrame()

        # 2. 解析KML内容
        soup = BeautifulSoup(kml_content, 'xml') # 指定'xml'解析器

        data = []
        # 查找所有 <Placemark> 标签
        placemarks = soup.find_all('Placemark')

        for pm in placemarks:
            name_tag = pm.find('name')
            coordinates_tag = pm.find('coordinates')

            name = name_tag.text.strip() if name_tag else 'Unnamed'
            
            # KML坐标通常是 "longitude,latitude,altitude" 或 "longitude,latitude"
            # 我们只需要经度和纬度
            if coordinates_tag:
                coords_str = coordinates_tag.text.strip()
                # 使用正则表达式或split来分割坐标字符串
                # 假设格式是 "经度,纬度,高度" 或 "经度,纬度"
                # 清理可能的空白字符和逗号分隔
                
                # 尝试匹配常见的坐标格式:经度,纬度,高度 或者 经度,纬度
                match = re.match(r'(-?\d+\.?\d*),(-?\d+\.?\d*)(,(-?\d+\.?\d*))?', coords_str)
                if match:
                    lon = float(match.group(1))
                    lat = float(match.group(2))
                    data.append({'Name': name, 'Longitude': lon, 'Latitude': lat})
                else:
                    print(f"警告: 无法解析坐标字符串 '{coords_str}' for '{name}'")
            else:
                print(f"警告: Placemark '{name}' 没有找到坐标。")

        # 3. 创建DataFrame
        if not data:
            print("没有从KML文件中提取到任何有效数据。")
            return pd.DataFrame()
        
        df = pd.DataFrame(data)
        return df

    except FileNotFoundError:
        print(f"错误: 文件 '{kmz_file_path}' 不存在。")
        return pd.DataFrame()
    except zipfile.BadZipFile:
        print(f"错误: '{kmz_file_path}' 不是一个有效的ZIP文件(KMZ文件)。")
        return pd.DataFrame()
    except Exception as e:
        print(f"处理KMZ文件时发生未知错误: {e}")
        return pd.DataFrame()
    finally:
        # 清理临时文件和目录
        if os.path.exists(temp_dir):
            import shutil
            shutil.rmtree(temp_dir)
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容