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)