从OSM Overpass API下载数据转GeoJSON时遇多面体验证错误求助
OSM数据转GeoJSON时多面体验证失败的解决方法
问题说明
通过Python从OSM Overpass API下载boundary=protected_area类型的multipolygon数据,下载功能正常,但使用osm2geojson转换为GeoJSON时出现多面体验证错误。该多边形在前端可正常渲染,但无法完成格式转换。
错误信息
Failed to create multipolygon. Base shape with role "outer" is invalid. Group ids: [431444168, 431444172, 431444165, 431444166, 431444160, 431444162, 431444176, 1175053062, 431444159, 431444167, 431444173, 431444164, 431444155, 431444158, 431444156, 431444169, 431444163, 431444175, 431444174] Failed to convert computed shapes to multipolygon 6417656 Element not converted 6417656
现有实现代码
import osm2geojson import codecs import os import json import requests from pathlib import Path myinput_path = r"C:\tmp_geo" myinput_filename="IT2.json" myoutput_filename=myinput_filename.replace(".json",".geojson") os.makedirs(myinput_path, exist_ok=True) myinput=os.path.join(myinput_path,myinput_filename) myoutput=os.path.join(myinput_path,myoutput_filename) def download_osm_data(query, filepath_osm): useragent = 'YourAppName/ContactInfo' headers = {'User-Agent': useragent, 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'} data = {'data': query} try: response = requests.post('https://overpass-api.de/api/interpreter', headers=headers, data=data, verify=False) response.raise_for_status() with open(Path(filepath_osm), 'w', encoding='utf-8') as f: f.write(response.text) return True except requests.RequestException as e: raise RuntimeError(f"Download error: {e}") query = f""" [out:json][timeout:25]; ( relation["boundary"="protected_area"]["type"="multipolygon"](43.1851, 9.6689, 44.4386, 11.3216); ); out geom; """ download_osm_data(query, myinput) with codecs.open(myinput, 'r', encoding='utf-8') as data: inputdata = data.read() geojsondata=osm2geojson.json2geojson(inputdata, filter_used_refs=False, log_level='INFO') with open(myoutput, 'w', encoding='utf-8') as f: json.dump(geojsondata, f, ensure_ascii=False, indent=2)
解决方法
方法1:调整osm2geojson参数跳过无效多边形
osm2geojson提供了skip_invalid_multipolygons参数,开启后会跳过验证失败的多面,保证其他有效数据正常转换。修改转换代码如下:
geojsondata=osm2geojson.json2geojson( inputdata, filter_used_refs=False, log_level='INFO', skip_invalid_multipolygons=True # 新增参数跳过无效多面 )
方法2:使用兼容性更好的库处理数据
pyrosm或osmnx对OSM复杂几何的处理容错性更强,可以替换osm2geojson完成转换。以下是pyrosm的实现示例:
from pyrosm import OSM import geopandas as gpd # 加载下载好的OSM数据 osm = OSM(myinput) # 筛选目标类型的边界数据 protected_areas = osm.get_boundaries( custom_filter={"boundary": "protected_area", "type": "multipolygon"} ) # 保存为GeoJSON文件 protected_areas.to_file(myoutput, driver="GeoJSON", encoding="utf-8")
方法3:修复OSM原始数据的几何问题
错误根源是ID为6417656的multipolygon的outer环存在几何异常(比如不闭合、节点重复、方向不符合OSM规范)。可以:
- 手动在OSM编辑器中修改该多边形的outer环,确保其闭合且方向为逆时针
- 在Overpass查询中暂时排除该ID,单独处理:
修改查询语句,添加-relation(6417656);:[out:json][timeout:25]; ( relation["boundary"="protected_area"]["type"="multipolygon"](43.1851, 9.6689, 44.4386, 11.3216); -relation(6417656); ); out geom;
内容的提问来源于stack exchange,提问作者ziazo
相关产品推荐
相关产品推荐

