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

调用pyrosm.get_network获取驾驶路网时触发TypeError求助

问题描述

原本可通过pyrosm读取OpenStreetMap的PBF文件生成驾驶路网,但运行以下代码时突然失败:

osm = pyrosm.OSM(f)
area = osm.get_network(network_type="driving")

触发TypeError,提示输入的MULTILINESTRING不是有效几何对象,完整报错栈如下:

TypeError                                 Traceback (most recent call last)
Cell In[17], line 38
     35     os.makedirs(mypath_shp)
     37 osm = pyrosm.OSM(f)
---> 38 area = osm.get_network(network_type="driving")
     39 print("Created network - OK")
     41 # subset = subsetting(area)
     42 # print("Created subset - OK")
     43 
   (...)
     53 # subset.to_file(path_shape, driver="ESRI Shapefile")
     54 # print(" Shapefile - OK")

File ~\AppData\Local\miniconda3\envs\for_osm\lib\site-packages\pyrosm\pyrosm.py:205, in OSM.get_network(self, network_type, extra_attributes, nodes)
    202     self._read_pbf()
    204 # Filter network data with given filter
---> 205 edges, node_gdf = get_network_data(
    206     self._node_coordinates,
    207     self._way_records,
    208     tags_as_columns,
    209     network_filter,
    210     self.bounding_box,
    211     slice_to_segments=nodes,
    212 )
    214 if edges is not None:
    215     # Add metadata
    216     edges._metadata.append(network_type)

File ~\AppData\Local\miniconda3\envs\for_osm\lib\site-packages\pyrosm\networks.py:37, in get_network_data(node_coordinates, way_records, tags_as_columns, network_filter, bounding_box, slice_to_segments)
     34     return None, None
     36 # Prepare GeoDataFrame
---> 37 edges, nodes = prepare_geodataframe(
     38     nodes,
     39     node_coordinates,
     40     ways,
     41     relations,
     42     relation_ways,
     43     tags_as_columns,
     44     bounding_box,
     45     parse_network=True,
     46     calculate_seg_lengths=slice_to_segments,
     47 )
     49 return edges, nodes

File ~\AppData\Local\miniconda3\envs\for_osm\lib\site-packages\pyrosm\frames.pyx:134, in pyrosm.frames.prepare_geodataframe()

File ~\AppData\Local\miniconda3\envs\for_osm\lib\site-packages\pyrosm\frames.pyx:141, in pyrosm.frames.prepare_geodataframe()

File ~\AppData\Local\miniconda3\envs\for_osm\lib\site-packages\pyrosm\frames.pyx:71, in pyrosm.frames.prepare_way_gdf()

File ~\AppData\Local\miniconda3\envs\for_osm\lib\site-packages\geopandas\geodataframe.py:188, in GeoDataFrame.__init__(self, data, geometry, crs, *args, **kwargs)
    180     if (
    181         hasattr(geometry, "crs")
    182         and geometry.crs
    183         and crs
    184         and not geometry.crs == crs
    185     ):
    186         raise ValueError(crs_mismatch_error)
---> 188     self.set_geometry(geometry, inplace=True, crs=crs)
    190 if geometry is None and crs:
    191     raise ValueError(
    192         "Assigning CRS to a GeoDataFrame without a geometry column is not "
    193         "supported. Supply geometry using the 'geometry=' keyword argument, "
    194         "or by providing a DataFrame with column name 'geometry'",
    195     )

File ~\AppData\Local\miniconda3\envs\for_osm\lib\site-packages\geopandas\geodataframe.py:346, in GeoDataFrame.set_geometry(self, col, drop, inplace, crs)
    343     level.crs = crs
    345 # Check that we are using a listlike of geometries
---> 346 level = _ensure_geometry(level, crs=crs)
    347 frame[geo_column_name] = level
    348 frame._geometry_column_name = geo_column_name

File ~\AppData\Local\miniconda3\envs\for_osm\lib\site-packages\geopandas\geodataframe.py:59, in _ensure_geometry(data, crs)
     57 else:
     58     if isinstance(data, Series):
---> 59         out = from_shapely(np.asarray(data), crs=crs)
     60         return GeoSeries(out, index=data.index, name=data.name)
     61     else:

File ~\AppData\Local\miniconda3\envs\for_osm\lib\site-packages\geopandas\array.py:154, in from_shapely(data, crs)
    138 def from_shapely(data, crs=None):
    139     """
    140     Convert a list or array of shapely objects to a GeometryArray.
    141 
   (...)
    152 
    153     """
---> 154     return GeometryArray(vectorized.from_shapely(data), crs=crs)

File ~\AppData\Local\miniconda3\envs\for_osm\lib\site-packages\geopandas\_vectorized.py:145, in from_shapely(data)
    143         out.append(None)
    144     else:
---> 145         raise TypeError("Input must be valid geometry objects: {0}".format(geom))
    147 if compat.USE_PYGEOS:
    148     return np.array(out, dtype=object)

TypeError: Input must be valid geometry objects: MULTILINESTRING ((7.646 47.633, 7.646 47.633), (7.646 47.633, 7.646 47.633), (7.646 47.633, 7.646 47.633), (7.646 47.633, 7.646 47.633), (7.646 47.633, 7.647 47.633), (7.647 47.633, 7.647 47.633))
解决思路
  • 清理无效几何对象:报错中的MULTILINESTRING包含零长度线段(重复坐标点组成的线段),属于无效几何。可以先读取原始数据再手动过滤修复:
    import pyrosm
    from shapely.validation import make_valid
    import geopandas as gpd
    
    # 读取所有way数据,不做网络过滤
    osm = pyrosm.OSM(f)
    ways = osm.get_ways()
    
    # 修复无效几何并过滤空值
    ways['geometry'] = ways['geometry'].apply(lambda geom: make_valid(geom) if geom.is_valid else None)
    ways = ways.dropna(subset=['geometry'])
    
    # 手动筛选驾驶路网对应的OSM标签
    driving_tags = ['motorway', 'trunk', 'primary', 'secondary', 'tertiary', 'unclassified', 'residential']
    area = ways[ways['highway'].isin(driving_tags)]
    
  • 调整依赖库版本:该错误可能是pyrosm或geopandas版本更新后几何验证逻辑变严格导致的,回退到之前能正常运行的版本:
    # 回退pyrosm到指定稳定版本
    pip install pyrosm==0.7.0
    # 或回退geopandas版本
    pip install geopandas==0.12.0
    
  • 预处理PBF文件:用osmium-tool提前过滤驾驶路网并清理无效要素:
    # 提取驾驶路网并输出为新的PBF文件
    osmium tags-filter input.osm.pbf w/highway=motorway,trunk,primary,secondary,tertiary,unclassified,residential -o filtered.osm.pbf
    
  • 临时修改pyrosm源码绕过验证:找到pyrosm安装目录下的frames.pyx文件,在prepare_way_gdf函数中添加无效几何过滤逻辑,比如在生成几何列表后加入:
    # 过滤无效几何
    valid_geometries = []
    for geom in geometries:
        if geom.is_valid:
            valid_geometries.append(geom)
        else:
            valid_geometries.append(None)
    geometries = valid_geometries
    

内容的提问来源于stack exchange,提问作者i.i.k.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:15:53