OSMNX自行车路网中oneway:bicycle=no标签的路径规划问题问询
问题:OSMnx自行车路径规划未识别单行道双向通行权限
我正在开展欧洲城市常用路线的自行车基础设施评估工作,遇到了以下问题:
- 欧洲普遍存在允许自行车双向通行的单行道(不确定北美是否有这类情况),在OpenStreetMap(OSM)中这类道路会被标记为
oneway=yes和oneway:bicycle=no。 - 使用设置
network_type='bike'的图调用osmnx.k_shortest_paths函数时,即便自行车反向通行合法,路径规划仍会避开单行道的反向。
测试场景:德国卡尔斯鲁厄的Marienstraße北段对机动车仅允许向北通行,但自行车可双向通行。规划向南路径时,路由函数会绕路;向北路径则正常使用该街道,且已验证道路边的标签正确。
测试代码:
import osmnx as ox add_tags = ['oneway:bicycle'] ox.settings.useful_tags_way = ox.settings.useful_tags_way + add_tags G = ox.graph_from_place("Karlsruhe, Germany", network_type='bike') start = ox.nearest_nodes(G, 8.408005310258606, 49.003891115254056, return_dist=False) # Kommödchen dest = ox.nearest_nodes(G, 8.408489900323096, 48.99637841654651, return_dist=False) # Yuki Sushi # 向南路径规划(会绕路) test = ox.k_shortest_paths(G, start, dest, 1, weight='length') test_list = list(test) test_nodes = test_list[0] test_edges = ox.utils_graph.route_to_gdf(G, test_nodes, weight='length') fig, ax = ox.plot_graph_route(G, test_nodes, route_color='r', route_linewidth=5, node_size=20) # 向北路径规划(正常使用目标街道) test_backwards = ox.k_shortest_paths(G, dest, start, 1, weight='length') back_list = list(test_backwards) back_nodes = back_list[0] back_edges = ox.utils_graph.route_to_gdf(G, back_nodes, weight='length') fig_b, ax_b = ox.plot_graph_route(G, back_nodes, route_color='r', route_linewidth=5, node_size=20) # 验证边标签 for index, row in back_edges.iterrows(): print(row["oneway"], row["oneway:bicycle"])
解决方法:根据oneway:bicycle标签添加反向边
可以通过遍历图中所有边,筛选出机动车单向但自行车可双向通行的路段,手动为其添加反向边,让路径规划算法识别到合法的反向通行选项。具体实现如下:
import osmnx as ox # 添加需要的OSM标签 add_tags = ['oneway:bicycle'] ox.settings.useful_tags_way = ox.settings.useful_tags_way + add_tags # 加载自行车路网 G = ox.graph_from_place("Karlsruhe, Germany", network_type='bike') # 收集需要添加的反向边 edges_to_add = [] for u, v, key, data in G.edges(keys=True, data=True): # 匹配机动车单向、自行车双向的条件 if data.get('oneway') == 'yes' and data.get('oneway:bicycle') == 'no': # 复制原边属性,反转起点/终点节点 reversed_data = data.copy() reversed_data['bicycle_reversed'] = True # 标记为手动添加的自行车反向边(可选) # 为反向边设置唯一key(避免与原边冲突) edges_to_add.append((v, u, key + 10000, reversed_data)) # 批量添加反向边到图中 G.add_edges_from(edges_to_add) # 重新进行路径规划 start = ox.nearest_nodes(G, 8.408005310258606, 49.003891115254056, return_dist=False) dest = ox.nearest_nodes(G, 8.408489900323096, 48.99637841654651, return_dist=False) # 向南路径规划(现在会使用Marienstraße的反向) test = ox.k_shortest_paths(G, start, dest, 1, weight='length') test_list = list(test) test_nodes = test_list[0] fig, ax = ox.plot_graph_route(G, test_nodes, route_color='r', route_linewidth=5, node_size=20) # 验证反向边属性 route_gdf = ox.utils_graph.route_to_gdf(G, test_nodes, weight='length') for index, row in route_gdf.iterrows(): print(row["oneway"], row["oneway:bicycle"], row.get("bicycle_reversed"))
关键说明
- 为反向边设置偏移后的
key(如原key加10000)是为了避免与原边的唯一标识冲突 bicycle_reversed属性是可选标记,方便后续区分原边和手动添加的反向边- 该逻辑严格匹配OSM的标签规则,仅对自行车合法的反向通行路段生效
内容的提问来源于stack exchange,提问作者FesterShinetop
相关产品推荐
相关产品推荐

