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

基于OSMnx与Python筛选东京涩谷不同距离道路节点求助

问题排查:OSMnx筛选涩谷4度道路节点异常

我用Python的OSMnx工具获取东京涩谷的驾车道路网络,需求是筛选出两类4度道路节点:

  • 与相邻节点的最短路径距离小于30米的节点
  • 与相邻节点的最短路径距离大于100米的节点

但编写的代码无法得到预期结果,以下是原代码:

import osmnx as ox
import geopandas as gpd
import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import math
import networkx as nx
from colorspacious import cspace_converter

ward_names = [
    "Shibuya",
]

graph = ox.graph_from_place(ward_names, network_type="drive")

nodes = ox.graph_to_gdfs(graph, nodes=True, edges=False)
edges = ox.graph_to_gdfs(graph, nodes=False, edges=True)

print("Number of nodes:", len(nodes))
print("Number of edges:", len(edges))
ox.plot_graph(graph)

gdf_nodes, gdf_edges = ox.graph_to_gdfs(graph)

# Find nodes that are separated by a distance of less than 30 meters and lead to 4 edges
# s_cross = Small crossing

s_cross = []
for node in graph.nodes():
    if len(list(graph.neighbors(node))) == 4:
        # distance
        distances = nx.shortest_path_length(graph, node)
        if max(distances.values()) <= 30:
            s_cross.append(node)
s_cross


# Find nodes that are separated by a distance of more than 100 meters and lead to 4 edges
# b_cross = Big crossing

b_cross = []
for node in graph.nodes():
    if len(list(graph.neighbors(node))) == 4:
        # distance
        distances = nx.shortest_path_length(graph, node)
        if max(distances.values()) >= 100:
            b_cross.append(node)
b_cross

问题根源分析

  1. 最短路径长度计算逻辑错误:nx.shortest_path_length默认返回路径经过的节点数量,而非实际道路距离。必须指定weight='length'参数,调用OSMnx边属性中存储的实际道路长度(单位:米)。
  2. 不必要的全局计算:原代码计算当前节点到所有节点的最短路径,而需求只关注相邻节点的距离,完全不需要遍历整个图。
  3. 判断条件偏差:原代码取所有节点到目标节点的最大距离,这和“相邻节点距离”的需求完全不符,应该只检查当前节点与直接邻居的边长度。

修正后的代码

import osmnx as ox
import networkx as nx

ward_names = ["Shibuya"]
graph = ox.graph_from_place(ward_names, network_type="drive")

# 筛选4度节点并分类
s_cross = []  # 所有相邻节点距离<30米的4度节点
b_cross = []  # 存在相邻节点距离>100米的4度节点

for node in graph.nodes():
    neighbors = list(graph.neighbors(node))
    if len(neighbors) != 4:
        continue
    
    # 获取当前节点与每个邻居的边长度(取最短边)
    neighbor_distances = []
    for neighbor in neighbors:
        edge_data = graph.get_edge_data(node, neighbor)
        lengths = [d['length'] for d in edge_data.values()]
        neighbor_distances.append(min(lengths))
    
    # 根据需求分类
    if all(d <= 30 for d in neighbor_distances):
        s_cross.append(node)
    if any(d >= 100 for d in neighbor_distances):
        b_cross.append(node)

print(f"短距离4度节点数量:{len(s_cross)}")
print(f"长距离4度节点数量:{len(b_cross)}")

# 可视化验证结果
nx.set_node_attributes(graph, False, 'is_s_cross')
nx.set_node_attributes(graph, False, 'is_b_cross')
for node in s_cross:
    graph.nodes[node]['is_s_cross'] = True
for node in b_cross:
    graph.nodes[node]['is_b_cross'] = True

node_color = []
for node in graph.nodes():
    if graph.nodes[node]['is_s_cross']:
        node_color.append('red')
    elif graph.nodes[node]['is_b_cross']:
        node_color.append('blue')
    else:
        node_color.append('gray')

ox.plot_graph(graph, node_color=node_color, node_size=30)

修正说明

  • 直接读取节点与邻居的边属性length,避免冗余的全局最短路径计算,提升效率。
  • 按需调整判断逻辑:
    • 若需求为“存在相邻节点距离小于30米”,可将all改为any
    • 若需求为“所有相邻节点距离大于100米”,可将any改为all
  • 增加可视化代码,直观验证筛选结果的正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 12:23:36