Python OSMNX:如何为道路边获取更贴合实际的行驶速度?
解决OSMNX驾驶时间与实际偏差的问题
问题描述
我正在开展一项基于驾驶时间的研究(例如,人们愿意从居住地驱车多久前往特定服务场所等)。但OSMNX计算得出的驾驶时间远快于实际情况,核心原因是它默认使用道路的maxspeed(最高限速)计算行驶时间,未考虑路口启停、短路段无法达到限速等现实场景的耗时。对比谷歌地图结果,相同距离下,OSMNX算出6分钟,实际需要10-11分钟。
示例代码:
import numpy as np import osmnx as ox import networkx as nx G = ox.graph_from_address( "50 North Temple, Salt Lake City, UT 84150", dist=10000, network_type="drive", truncate_by_edge=True, ) G = ox.add_edge_speeds(G) G = ox.add_edge_travel_times(G) origin = (40.741630,-111.862470) destination = (40.768860,-111.837560) origin_node = ox.distance.nearest_nodes(G, origin[1], origin[0]) destination_node = ox.distance.nearest_nodes(G, destination[1], destination[0]) route = ox.shortest_path(G, origin_node, destination_node,weight="travel_time") route_length = int(sum(ox.utils_graph.route_to_gdf(G, route, "length")["length"])) route_time = int(sum(ox.utils_graph.route_to_gdf(G, route, "travel_time")["travel_time"])) print("Route is", route_length/1609.34, "miles and takes", route_time/60, "minutes.") fig, ax = ox.plot_graph_route(G, route, route_color="c", node_size=0)
解决方案
1. 自定义道路平均速度计算
OSMNX默认用maxspeed直接计算时间,但现实中短路段无法达到最高限速,需要结合路段长度调整平均速度。可以通过公式自定义每条边的行驶速度,再重新计算行驶时间。
比如,结合路段长度设置不同的速度折扣(可根据研究需求调整):
- 路段长度小于50米:平均速度设为20km/h(无法高速行驶)
- 路段长度50-200米:取
maxspeed的70% - 更长路段:取
maxspeed的90%(考虑路况干扰)
修改代码如下:
import numpy as np import osmnx as ox import networkx as nx G = ox.graph_from_address( "50 North Temple, Salt Lake City, UT 84150", dist=10000, network_type="drive", truncate_by_edge=True, ) # 先获取默认限速 G = ox.add_edge_speeds(G) # 自定义每条边的平均速度与行驶时间 for u, v, key, data in G.edges(keys=True, data=True): max_speed = data['speed_kph'] length = data['length'] if length < 50: data['custom_speed_kph'] = 20 elif 50 <= length < 200: data['custom_speed_kph'] = max_speed * 0.7 else: data['custom_speed_kph'] = max_speed * 0.9 # 计算自定义行驶时间(秒):长度(米) / 速度(米/秒) data['custom_travel_time'] = length / (data['custom_speed_kph'] / 3.6) origin = (40.741630,-111.862470) destination = (40.768860,-111.837560) origin_node = ox.distance.nearest_nodes(G, origin[1], origin[0]) destination_node = ox.distance.nearest_nodes(G, destination[1], destination[0]) # 使用自定义行驶时间作为权重找最优路径 route = ox.shortest_path(G, origin_node, destination_node, weight="custom_travel_time") # 计算路径总长度和总时间 route_length = int(sum(ox.utils_graph.route_to_gdf(G, route, "length")["length"])) route_time = int(sum(ox.utils_graph.route_to_gdf(G, route, "custom_travel_time")["custom_travel_time"])) print("Route is", route_length/1609.34, "miles and takes", route_time/60, "minutes.") fig, ax = ox.plot_graph_route(G, route, route_color="c", node_size=0)
2. 添加路口启停延误
路口的停车、等待、转向耗时是OSMNX忽略的关键因素,可以给路径中的每个路口(除起点和终点)添加固定或动态的延误时间。
比如,每个路口添加15秒延误(可根据路口复杂度调整,如主干道交叉口加20秒,支路加10秒):
# 在计算完自定义路径时间后,添加路口延误 num_intersections = len(route) - 2 # 减去起点和终点节点 intersection_delay = 15 # 每个路口延误15秒 total_route_time = route_time + num_intersections * intersection_delay print("Route is", route_length/1609.34, "miles and takes", total_route_time/60, "minutes.")
3. 结合两种方法优化
将自定义路段速度和路口延误结合,能更贴近实际驾驶时间。可以根据研究区域的交通特征,调整速度系数和延误时间——比如在拥堵城区提高延误时长,在郊区降低速度折扣。
内容的提问来源于stack exchange,提问作者PAnderton
相关产品推荐
相关产品推荐

