Gf1 xml 文件解析到geojson 文件

#!/usr/bin/env python3

-*- coding: utf-8 -*-

python 复制代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import xml.etree.ElementTree as ET
import json
from pathlib import Path

def safe_get_text(element, tag, default=None):
    """Safely extract text from an XML element."""
    child = element.find(tag)
    return child.text if child is not None else default

def safe_get_float(element, tag, default=None):
    """Safely extract a float from an XML element."""
    text = safe_get_text(element, tag)
    try:
        return float(text) if text is not None else default
    except (ValueError, TypeError):
        return default

def main():
    # Sample XML data (GF-1 satellite metadata)
    xml_data = '''<?xml version="1.0" encoding="UTF-8" ?>
    <ProductMetaData>
        <SatelliteID>GF1</SatelliteID>
        <ReceiveStationID>MYC</ReceiveStationID>
        <SensorID>WFV4</SensorID>
        <ReceiveTime>2024-09-24 02:20:48</ReceiveTime>
        <OrbitID>61524</OrbitID>
        <OrbitType>GPS</OrbitType>
        <AttType>DMA</AttType>
        <StripID>481726</StripID>
        <ProduceType>STANDARD</ProduceType>
        <SceneID>13576439</SceneID>
        <DDSFlag>TRUE</DDSFlag>
        <ProductID>13576439001</ProductID>
        <ProductQuality />
        <ProductQualityReport />
        <ProductLevel>LEVEL1A</ProductLevel>
        <ProductFormat>GEOTIFF</ProductFormat>
        <ProduceTime>2024-09-24 22:30:59</ProduceTime>
        <Bands>1,2,3,4</Bands>
        <ScenePath>582</ScenePath>
        <SceneRow>76</SceneRow>
        <SatPath>589</SatPath>
        <SatRow>75</SatRow>
        <SceneCount>1</SceneCount>
        <SceneShift>1</SceneShift>
        <StartTime>2024-09-24 10:20:33</StartTime>
        <EndTime>2024-09-24 10:21:03</EndTime>
        <CenterTime>2024-09-24 10:20:48</CenterTime>
        <StartLine />
        <EndLine />
        <ImageGSD>16.000000000000000</ImageGSD>
        <WidthInPixels>12000</WidthInPixels>
        <HeightInPixels>13400</HeightInPixels>
        <WidthInMeters />
        <HeightInMeters />
        <RegionName>CH</RegionName>
        <CloudPercent>0</CloudPercent>
        <DataSize>1227</DataSize>
        <RollViewingAngle>0.000000000000000</RollViewingAngle>
        <PitchViewingAngle>0.000000000000000</PitchViewingAngle>
        <RollSatelliteAngle>0.000016317655897</RollSatelliteAngle>
        <PitchSatelliteAngle>-0.000021716054218</PitchSatelliteAngle>
        <YawSatelliteAngle>2.543099866083802</YawSatelliteAngle>
        <SolarAzimuth>166.871948556585039</SolarAzimuth>
        <SolarZenith>48.060375213623047</SolarZenith>
        <SatelliteAzimuth>286.730366229627975</SatelliteAzimuth>
        <SatelliteZenith>26.500590498958282</SatelliteZenith>
        <GainMode>G0,G0,G0,G0</GainMode>
        <IntegrationTime>0.002257803868283</IntegrationTime>
        <IntegrationLevel>S0,S0,S0,S0</IntegrationLevel>
        <MapProjection />
        <EarthEllipsoid />
        <ZoneNo />
        <ResamplingKernel />
        <HeightMode />
        <EphemerisData>GPS</EphemerisData>
        <AttitudeData>DMA</AttitudeData>
        <RadiometricMethod>LAB</RadiometricMethod>
        <MtfCorrection>LAB</MtfCorrection>
        <Denoise>MOMENT</Denoise>
        <RayleighCorrection>N</RayleighCorrection>
        <UsedGCPNo>0</UsedGCPNo>
        <CenterLatitude>46.702109160938569</CenterLatitude>
        <CenterLongitude>133.070196050536879</CenterLongitude>
        <TopLeftLatitude>47.885559023882131</TopLeftLatitude>
        <TopLeftLongitude>132.107675516323695</TopLeftLongitude>
        <TopRightLatitude>47.261740594511238</TopRightLatitude>
        <TopRightLongitude>135.066865429476280</TopRightLongitude>
        <BottomRightLatitude>45.459380058829218</BottomRightLatitude>
        <BottomRightLongitude>134.210751915721147</BottomRightLongitude>
        <BottomLeftLatitude>46.065768914899728</BottomLeftLatitude>
        <BottomLeftLongitude>131.343463299378755</BottomLeftLongitude>
        <TopLeftMapX />
        <TopLeftMapY />
        <TopRightMapX />
        <TopRightMapY />
        <BottomRightMapX />
        <BottomRightMapY />
        <BottomLeftMapX />
        <BottomLeftMapY />
        <DataArchiveFile />
        <BrowseFileLocation />
        <ThumbFileLocation />
        <SatOffNadir></SatOffNadir>
        <ImageGSD></ImageGSD>
        <L0DataTempDir></L0DataTempDir>
        <L0DataArchiveDir></L0DataArchiveDir>
        <SceneDataCount>1</SceneDataCount>
        <SceneDate></SceneDate>
        <AbsCeof>0.2148,0.1607,0.1317,0.1288</AbsCeof>
    </ProductMetaData>'''

    try:
        # Parse XML
        root = ET.fromstring(xml_data)

        # Extract all properties
        properties = {
            child.tag: child.text if child.text else None
            for child in root
        }

        # Extract and validate coordinates
        coordinate_pairs = [
            ('TopLeftLongitude', 'TopLeftLatitude'),
            ('TopRightLongitude', 'TopRightLatitude'),
            ('BottomRightLongitude', 'BottomRightLatitude'),
            ('BottomLeftLongitude', 'BottomLeftLatitude')
        ]

        coordinates = []
        for lon_tag, lat_tag in coordinate_pairs:
            lon = safe_get_float(root, lon_tag)
            lat = safe_get_float(root, lat_tag)
            if lon is not None and lat is not None:
                coordinates.append([lon, lat])

        # Validate we have enough coordinates
        if len(coordinates) < 4:
            raise ValueError("Insufficient valid coordinates to form a polygon")

        # Close the polygon
        coordinates.append(coordinates[0])

        # Create GeoJSON structure
        feature = {
            "type": "Feature",
            "geometry": {
                "type": "Polygon",
                "coordinates": [coordinates]
            },
            "properties": properties
        }

        feature_collection = {
            "type": "FeatureCollection",
            "features": [feature]
        }

        # Write to file
        output_path = Path("gf1_satellite_metadata.geojson")
        with output_path.open("w", encoding="utf-8") as f:
            json.dump(feature_collection, f, indent=2, ensure_ascii=False)

        print(f"Successfully generated GeoJSON file at: {output_path.resolve()}")

    except ET.ParseError as e:
        print(f"XML parsing error: {e}")
    except ValueError as e:
        print(f"Data validation error: {e}")
    except Exception as e:
        print(f"Unexpected error: {e}")

if __name__ == "__main__":
    main()
相关推荐
LitchiCheng20 小时前
还在改xml调相机?MuJoCo交互式可视化调整相机安装位置
xml·数码相机
richard_yuu1 天前
JSON vs XML vs 二进制:3种序列化终极选型
xml·c++·qt·学习·json
秋田君3 天前
QT_XML文件操作
xml·数据库·qt
数据知道4 天前
XXE 漏洞深度实战:XML 外部实体攻击与 OOB 带外
xml·网络·安全·网络安全
云水一下4 天前
零基础玩转bWAPP靶场(四十七):XSS - Reflected (AJAX/XML)
xml·web安全·ajax·xss·bwapp
爱敲键盘的猴子6 天前
深入理解 Spring IoC -- 基于 XML 的 Bean 配置详解
xml·java·spring
前网易架构师-高司机7 天前
带标注的羽毛球运动员,裁判,羽毛球识别数据集,识别率84.4%,2879张图,支持yolo,coco json,voc xml,文末有模型训练代码
xml·yolo·json·数据集·羽毛球·裁判
微微1笑抽了筋10 天前
xml中设置透明度
xml
Source.Liu11 天前
【Uppsala】入口模块(lib.rs)
xml·rust
Source.Liu11 天前
【Uppsala】介绍
xml·rust