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()
相关推荐
Catfood_Eason17 小时前
XML简介
xml·java·前端
胖大和尚17 小时前
Linux C++ xercesc xml 怎么判断路径下有没有对应的节点
xml·linux·c++
大飞pkz3 天前
【Unity】使用XML进行数据读存的简单例子
xml·unity·c#·游戏引擎·游戏开发·数据读写
奕维哥3 天前
数电发票整理:免费实用工具如何高效解析 XML 发票数据
xml
IT利刃出鞘3 天前
CSS--图片链接水平居中展示的方法
xml·css·html
知识分享小能手3 天前
JavaScript学习教程,从入门到精通,Ajax数据交换格式与跨域处理(26)
xml·开发语言·前端·javascript·学习·ajax·css3
浅陌sss5 天前
C#中实现XML解析器
xml·c#
Catfood_Eason5 天前
面向对象的XML综合练习
xml
爱编程的小庄5 天前
Maven 4.0.0 模式-pom.xml配置详解
xml·java·maven