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

如何优化OSMnx旅行时间多边形计算效率?

高效生成荷兰境内500个点位15分钟旅行时间多边形的优化方案

问题描述

我持有荷兰境内500个带经纬度坐标的点位,需要为每个点位生成15分钟驾车旅行时间范围的多边形。目前基于OSMnx、NetworkX和GeoPandas实现了功能,但每个点位都需下载25×25km的bounding box并转换为Multigraph,计算速度极慢。

曾尝试将荷兰路网分割为小块下载并存储为.graphml,合并后文件达2GB,处理时出现内存等问题。现寻求以下方向的解决方案:

  • 如何避免重复下载路网?
  • 有没有更优的旅行时间多边形计算方法?
  • 推荐合适的替代工具库。

现有实现代码

# 选择数据集中的目标行
start = infra_dataframe[i-1:i]

# 设置坐标系
start.crs = "EPSG:4326"

# 设置旅行时间阈值(秒)
distance_value = 900  # 900秒 = 15分钟

# 生成点位缓冲区域(7855为米制坐标系)
buffer_value = distance_value*25  # 放大倍数确保覆盖所有可达区域
buffer_home = start.to_crs(epsg=7855).buffer(buffer_value).to_crs(epsg=4326)

# 获取缓冲区域的边界框
bounds = buffer_home.bounds.loc[i-1]

# 自定义道路过滤规则
cf = '["highway"~"motorway|motorway_link|trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|residential|unclassified|living_street|service"]'

# 下载边界框内的路网
region = ox.graph_from_bbox(bounds['maxy'], bounds['miny'], bounds['minx'], bounds['maxx'], network_type='drive', custom_filter=cf)

# 为路网添加速度和旅行时间属性
G = ox.add_edge_speeds(region)
G = ox.add_edge_travel_times(region)

# 找到离起点最近的路网节点
center_node = ox.nearest_nodes(G, start['infra.lon'].iloc[0], start['infra.lat'].iloc[0])

# 计算从中心节点到所有节点的最短旅行时间
distances = nx.shortest_path_length(G, source=center_node, weight="travel_time")

# 筛选出15分钟内可达的节点
drivable_nodes = {node: dist for node, dist in distances.items() if dist < distance_value}

# 生成可达子图
G_reachable = G.subgraph(drivable_nodes.keys())

# 将子图转换为GeoDataFrame
gdf_nodes, gdf_edges = ox.graph_to_gdfs(G_reachable)

# 自定义函数生成可达区域多边形
reachable_polygon = create_polygon(gdf_nodes)

# 将多边形存入GeoDataFrame
gdf_reachable = gpd.GeoDataFrame(index=[0], crs='epsg:4326', geometry=[reachable_polygon])

优化方案

一、避免重复下载路网

  • 预下载分区路网:不要按单个点位的buffer下载,而是下载覆盖所有500个点位的最小外接区域路网,或按荷兰行政区(如省份)划分成多个子区域,存储为.graphml文件。计算时直接加载对应子区域的路网,而非重复调用OSMnx下载接口。若全荷兰路网过大,可按点位分布划分重叠子区域,每个子区域覆盖部分点位。
  • 添加路网缓存逻辑:用点位的buffer范围作为缓存key,将下载好的graph对象通过pickle序列化存储。后续遇到相同或重叠的buffer时,直接读取缓存文件,跳过重复下载步骤。

二、优化旅行时间多边形计算流程

  • 批量执行可达性计算:若使用全区域路网,利用NetworkX的nx.multi_source_dijkstra_path_length函数,一次性传入所有点位对应的中心节点列表,批量计算所有节点到这些源点的最短旅行时间,再分别提取每个源点的可达节点,避免逐个点位重复计算。
  • 复用路网预处理结果:对加载的路网仅执行一次add_edge_speeds和add_edge_travel_times操作,不要每个点位都重复处理。
  • 优化多边形生成逻辑:自定义create_polygon函数可能是性能瓶颈,可替换为更高效的实现:
    • 先用gdf_nodes.unary_union.convex_hull快速生成凸包,再通过buffer(0)修复拓扑、simplify()简化形状;
    • 若不需要高精度,可使用可达节点的Voronoi图或Delaunay三角剖分生成多边形,比自定义函数更高效。
  • 缩小缓冲区域范围:当前distance_value*25的buffer值(22500米)过大,可根据荷兰道路平均车速调整:按最高限速120km/h计算,15分钟最多行驶30km,但实际驾车不会全程高速,设置15km的buffer已足够覆盖所有可达区域,减少路网规模。

三、替代工具库推荐

  • Pyrosm:直接从OSM PBF文件读取路网,支持按区域过滤,下载和加载速度比OSMnx更快,内存占用更低,适合预下载大规模路网并批量处理。
  • GraphHopper:可本地部署的路由引擎,支持批量点位的等时线计算,生成旅行时间多边形的效率远高于NetworkX,适合处理500个点位的大规模计算需求。
  • Valhalla:开源高性能路由引擎,专门优化了大规模路网的可达性计算,支持批量生成等时线,性能远超纯Python实现的工具。

内容的提问来源于stack exchange,提问作者jmt_r

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:47:07