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

OSMNX与NetworkX升级后代码报错求助:NetworkXError节点不在有向图

解决OSMNX与NetworkX版本升级后「节点不在有向图」的错误

嘿,这个问题我太熟了——你遇到的NetworkXError: The node osmid is not in the digraph,本质是拿合并后的新图节点去原始图里找邻居,这俩图的节点ID完全不搭边,原始图肯定找不到啊!

问题根源

ox.consolidate_intersections()这个函数会生成一个全新的路网图,它会把原始图里距离很近的交点合并成新节点,所以新图inter的节点ID和原始图G的节点ID是完全不同的两个体系。你遍历inter的节点,却去G里调用nx.neighbors(),自然会报错。

最直接的解决方案:用合并后的图操作

既然你已经生成了合并交点的图,直接用它来获取邻居和边数据就好,修改后的代码如下:

import osmnx as ox
import networkx as nx

# 获取原始路网图
G = ox.graph_from_place('Piedmont, CA, USA', network_type='drive')
# 投影后合并交点,得到新图
inter = ox.consolidate_intersections(ox.project_graph(G))
# 获取新图的节点GeoDataFrame(注意节点ID在index里)
nodes = ox.graph_to_gdfs(inter, edges=False)

connections = {}
# 遍历新图的节点ID(从index取)
for n in nodes.index:
    connections[n] = set()
    # 在合并后的图inter里找邻居
    for nbr in nx.neighbors(inter, n):
        # NetworkX有向图的边数据是嵌套字典,需要遍历边ID
        edge_entries = inter.get_edge_data(n, nbr)
        for edge_id in edge_entries:
            edge_name = edge_entries[edge_id].get('name')
            if edge_name:  # 过滤空的道路名称
                connections[n].add(str(edge_name))

如果必须用原始图G:获取节点映射关系

要是你确实需要基于原始图做操作,那得让consolidate_intersections()返回节点的映射字典,这样就能知道新节点对应哪些原始节点:

import osmnx as ox
import networkx as nx

G = ox.graph_from_place('Piedmont, CA, USA', network_type='drive')
projected_G = ox.project_graph(G)
# 开启return_dicts参数,获取新旧节点的映射关系
inter, node_mappings = ox.consolidate_intersections(projected_G, return_dicts=True)
nodes = ox.graph_to_gdfs(inter, edges=False)

connections = {}
for new_node in nodes.index:
    connections[new_node] = set()
    # 找到这个新节点对应的所有原始节点
    original_nodes = [old_n for old_n, new_n in node_mappings['old_to_new'].items() if new_n == new_node]
    # 遍历每个原始节点,在原始图G里找邻居
    for old_node in original_nodes:
        for nbr in nx.neighbors(G, old_node):
            edge_entries = G.get_edge_data(old_node, nbr)
            for edge_id in edge_entries:
                edge_name = edge_entries[edge_id].get('name')
                if edge_name:
                    connections[new_node].add(str(edge_name))

版本升级后的小提醒

OSMNX 1.0+和NetworkX 2.6+的API有不少变化:

  • ox.graph_to_gdfs()返回的节点GeoDataFrame,节点ID是存在index里的,不是单独的列,所以遍历的时候要用nodes.index
  • NetworkX的有向图中,get_edge_data(u, v)返回的是{edge_id: 属性字典}的结构,必须遍历edge_id才能拿到每条边的属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:07:36