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()
相关推荐
Blue桃之夭夭14 小时前
Python进阶【四】:XML和JSON文件处理
xml·python·json
米粉030521 小时前
Ajax(Asynchronous JavaScript and XML)
xml·javascript·ajax
ecoolper2 天前
maven项目编译时复制xml到classes目录方案
xml·java·maven
王有品3 天前
Spring 核心配置文件(spring.xml)构建指南
xml·java·spring
几道之旅5 天前
配置文件,xml,json,yaml,我该选哪个?
xml·python·json
biubiubiu07065 天前
SpringBoot返回xml
xml·java·spring boot
信计小白5 天前
xml双引号可以不转义
android·xml
浩浩测试一下5 天前
Apache OFBiz 17.12.01 的远程命令执行漏洞 -Java 反序列化 + XML-RPC 请求机制
xml·java·安全·web安全·网络安全·apache·安全架构
珹洺5 天前
MyBatis实战指南(三)MyBatis常用配置详解(XML配置,环境配置,类型别名,属性与映射器)
xml·java·运维·数据库·sql·tomcat·mybatis
A1-296 天前
QT之INI、JSON、XML处理
xml·c++·qt·json