OGC JSON转换到shape

发布于:2025-08-13 ⋅ 阅读:(11) ⋅ 点赞:(0)

import json
import geopandas as gpd
from shapely.geometry import shape
from shapely.validation import make_valid

def convert_ogc_json_to_shape(ogc_json_path, output_shape_path):
    """
    将OGC JSON(GeoJSON)文件转换为Shapefile
    
    参数:
        ogc_json_path: OGC JSON文件路径
        output_shape_path: 输出Shapefile路径(不含扩展名)
    """
    try:
        # 读取OGC JSON文件
        with open(ogc_json_path, 'r', encoding='utf-8') as f:
            data = json.load(f)
        
        # 验证是否为有效的GeoJSON
        if data.get('type') not in ['FeatureCollection', 'Feature', 'GeometryCollection']:
            raise ValueError("无效的OGC JSON格式,必须是FeatureCollection、Feature或GeometryCollection")
        
        features = []
        # 处理FeatureCollection类型
        if data['type'] == 'FeatureCollection':
            for feature in data.get('features', []):
                processed_feature = process_feature(feature)
                if processed_feature:
                    features.append(processed_feature)
        # 处理单个Feature
        elif data['type'] == 'Feature':
            processed_feature = process_feature(data)
            if processed_feature:
                features.append(processed_feature)
        # 处理GeometryCollection
        elif data['type'] == 'GeometryCollection':
            for idx, geom in enumerate(data.get('geometries', [])):
                features.append({
                    'geometry': create_valid_geometry(geom),
                    'properties': {'id': idx}  # 为几何对象添加简单属性
                })
        
        if not features:
            print("没有有效要素可转换")
            return
        
        # 创建GeoDataFrame
        # 从数据中获取CRS信息,默认为WGS84 (EPSG:4326)
        crs = data.get('crs', {}).get('properties', {}).get('name', 'EPSG:4326')
        gdf = gpd.GeoDataFrame(features, crs=crs)
        
        # 导出为Shapefile
        gdf.to_file(output_shape_path, driver='ESRI Shapefile', encoding='utf-8')
        print(f"成功转换 {len(features)} 个要素到Shapefile: {output_shape_path}")
        
    except Exception as e:
        print(f"转换过程中出错: {str(e)}")

def process_feature(feature):
    """处理单个Feature,验证并修复几何"""
    try:
        geom = feature.get('geometry')
        if not geom:
            return None
            
        # 创建并验证几何对象
        valid_geom = create_valid_geometry(geom)
        if not valid_geom:
            return None
            
        return {
            'geometry': valid_geom,
            'properties': feature.get('properties', {})
        }
    except Exception as e:
        print(f"处理要素时出错: {str(e)}")
        return None

def create_valid_geometry(geom_dict):
    """创建几何对象并确保其有效性"""
    try:
        # 从字典创建几何对象
        geom = shape(geom_dict)
        
        # 检查并修复几何有效性
        if not geom.is_valid:
            print(f"修复无效几何: {geom_dict.get('type')}")
            geom = make_valid(geom)
            
        return geom
    except Exception as e:
        print(f"创建几何对象时出错: {str(e)}")
        return None

# 使用示例
if __name__ == "__main__":
    # 输入OGC JSON文件路径
    input_json = "input.geojson"
    # 输出Shapefile路径(不含扩展名)
    output_shape = "output_shape"
    
    # 执行转换
    convert_ogc_json_to_shape(input_json, output_shape)