使用osmnx.plot_graph_folium()出现几何数据缺失错误的原因及处理方案
AttributeError: No geometry data set yet (expected in column 'geometry'
边缺少geometry属性的原因
- OSMNX 0.11.4版本的
graph_from_address()等路网生成函数默认采用轻量化存储逻辑:仅当道路边在两个端点之间存在额外的中间采样点(即道路不是直线连接两个路口)时,才会为边生成geometry属性存储LineString几何对象 - 对于两个端点直接直线连接的短边,默认不会额外存储
geometry属性,常规计算场景会默认用两点坐标直接生成直线,但plot_graph_folium()在转GeoDataFrame的内置逻辑中没有兼容这种缺省情况,因此抛出属性缺失错误
兼容处理方案
方案1:生成路网时强制补全所有边几何属性(推荐)
该方案一劳永逸,补全后的路网可直接适配所有OSMNX内置的绘图、空间计算逻辑,不会修改原有路网的其他属性:
import osmnx as ox # 生成原始路网 G = ox.graph_from_address('目标地址', dist=1000) # 为所有缺少geometry属性的边补全直线几何对象 G = ox.utils_graph.add_edge_geometries(G) # 直接调用绘图接口即可正常运行 m = ox.plot_graph_folium(G)
方案2:临时补全属性,不修改原始路网
如果需要保留原始路网的轻量化存储结构,可封装兼容版本的绘图函数,仅在绘图时临时补全属性:
import osmnx as ox import geopandas as gpd from shapely.geometry import LineString def compatible_plot_graph_folium(G, **kwargs): # 导出边GeoDataFrame,暂不自动填充几何属性 edges_gdf = ox.graph_to_gdfs(G, nodes=False, fill_edge_geometry=False) # 筛选缺少geometry的边,用起止节点坐标生成直线补全 miss_geo_mask = edges_gdf['geometry'].isna() edges_gdf.loc[miss_geo_mask, 'geometry'] = edges_gdf.loc[miss_geo_mask].apply( lambda row: LineString([ (G.nodes[row['u']]['x'], G.nodes[row['u']]['y']), (G.nodes[row['v']]['x'], G.nodes[row['v']]['y']) ]), axis=1 ) # 将补全的几何属性写回路网边对象 for _, edge in edges_gdf.iterrows(): G.edges[edge['u'], edge['v'], edge['key']]['geometry'] = edge['geometry'] # 调用原生绘图接口 return ox.plot_graph_folium(G, **kwargs) # 调用兼容函数即可正常绘图 m = compatible_plot_graph_folium(G)
额外说明
如果项目允许升级依赖,OSMNX 1.0及以上版本已优化该逻辑:graph_to_gdfs接口默认会自动补全所有缺失的边几何属性,plot_graph_folium()不会再触发该报错。
内容的提问来源于stack exchange,提问作者eecharlie
相关产品推荐
相关产品推荐

