You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:15:22