【问题标题】:OSMNX graph_from_gdfs KeyError: 'x' when converting a Geopackage to a GraphOSMNX graph_from_gdfs KeyError: 'x' 将 Geopackage 转换为 Graph
【发布时间】:2020-12-29 18:30:00
【问题描述】:

我需要编辑 osmnx 以 geopackage 格式下载的数据,然后将其导入为用于计算距离、等时线等的图表。

当前进程:

  1. 使用 ox.graph_from_point 下载 osm 数据
  2. 使用 ox.io.save_graph_geopackage 保存到 Geopackage 边缘和节点,以允许用户通过数字化道路(使用捕捉)在 QGIS 中添加边缘和额外道路并保存编辑。
  3. 使用 ox.graph_from_gdfs 将已编辑的边转换回 OSMNX 作为图形。

此时“ox.graph_from_gdfs”返回一个空的 Graph 对象。似乎抱怨 x 属性不存在,但地理包节点层中确实存在 x 和 y 属性 - 所以我不明白这个错误。

错误:

coords = ((n, d["x"], d["y"]) for n, d in G.nodes(data=True))
KeyError: 'x'

有人可以帮忙吗?

代码:

import osmnx as ox
import networkx as nx
import geopandas as gpd
from shapely.geometry import Point, LineString, MultiLineString,Polygon,MultiPolygon
print("OX ver: {}".format(ox.__version__))
print("NX ver: {}".format(nx.__version__))

geopPath = "osmnx_roaddata.gpkg"
xG = -1.08762688688598
yG = 53.9547041755247

orig = (yG,xG)
print(orig)

gdf_edges = gpd.read_file(geopPath, layer='edges')
gdf_nodes = gpd.read_file(geopPath, layer='nodes')
## Test to see if x exists in geodataframe- looks fine
#for index, row in gdf_nodes.iterrows():
#    print("y: {}. x: {}".format(row['y'],row['x']))


print("######## Using Existing geopackage road edges and nodes")

### readthedocs: graph_attrs (dict) – the new G.graph attribute dict; if None, add crs as the only graph-level attribute
## don't know what the graph attribute dict should contain...or if providing the crs object is what is expected...

G = ox.graph_from_gdfs(gdf_nodes,gdf_edges) #, graph_attrs=gdf_nodes.crs)
print("G appears empty....: '{}'".format(G))

origin_node = ox.get_nearest_node(G, orig)
print("Roads geopackage now being used as variable 'G' graph object")

我知道我可能需要为已数字化的新道路计算任何缺失的节点。但是我仍然应该能够使用我在遇到该问题之前想到的“ox.graph_from_gdfs”创建一个有效的 G 图对象。我已经测试了另一个地理包,除了 osmnx 下载的路径或节点之外没有其他道路或节点并且结果相同。

使用 OSMnx 0.16.0、NetworkX 2.5。

geopPath Geopackage Download

【问题讨论】:

    标签: python-3.x networkx osmnx


    【解决方案1】:

    我将演示如何使用 OSMnx v1.0 执行此操作,因为它将在两天内发布,并为将 GeoPandas GeoDataFrames 转换为 NetworkX MultiDiGraph 提供更强大的支持。使用详情见the docs

    您的问题似乎是边缘 GeoDataFrame 中的 uvkey 列包含空值,大概是从您在 QGIS 中创建它们时开始的。这些是边的唯一标识符,应该是非空整数。两个 GeoDataFrames 索引都应该是唯一的。

    import geopandas as gpd
    import osmnx as ox
    
    # create a graph, save as a GeoPackage
    fp = 'graph.gpkg'
    G = ox.graph_from_point((53.956748, -1.081676))
    ox.save_graph_geopackage(G, fp)
    
    # do some stuff in QGIS
    # ensure the index attributes are non-null when you're finished
    pass
    
    # load GeoPackage as node/edge GeoDataFrames indexed as described in OSMnx docs
    gdf_nodes = gpd.read_file(fp, layer='nodes').set_index('osmid')
    gdf_edges = gpd.read_file(fp, layer='edges').set_index(['u', 'v', 'key'])
    assert gdf_nodes.index.is_unique and gdf_edges.index.is_unique
    
    # convert the node/edge GeoDataFrames to a MultiDiGraph
    graph_attrs = {'crs': 'epsg:4326', 'simplified': True}
    G2 = ox.graph_from_gdfs(gdf_nodes, gdf_edges, graph_attrs)
    

    【讨论】:

    • 谢谢,从 github 安装 v1.0 可以工作(pip install git+github.com/gboeing/osmnx.git),以便从图形到地理包来回切换,它现在可以计算最近的节点。对我来说,下一个问题是在 QGIS 中添加新边之后:我需要 1. 在新行的末尾添加具有唯一 osmid 的节点,2. 计算 u,v, 关键属性。是否已经存在执行其中任何一项的功能?如果不是,我可以看到 osm 'to' 和 'from' 对于 u, v 之间的关系,但我不明白 'key' 是如何产生的。
    • 好的,谢谢,这回答了密钥的形成方式。我是否应该收集到没有内置方法可以自动计算 osmnx/networkx 中缺少的 u、v、关键属性?
    • 如果你在networkx之外创建新的边,你需要自己分配u、v、key来定义边。
    • 好的,谢谢,将执行与 shapely 的交叉以获取丢失节点的坐标以及 To-Form 将属性/特征与 ogr(我希望)写入地理包边缘和节点层。然后我可以将其反馈回来进行分析。
    • 更新:即使在 v 1.0 中,我也无法成功使用 'ox.graph_from_gdfs' 功能。即使我只是使用从图表导出的原始地理包(没有编辑),它也会产生奇怪的结果,返回的节点来自:nx.ego_graph(G=G, n=origin_node, radius=trip_time, distance='time')' .当尝试为不同的行程时间生成等时线时,它会为所有行程创建相同的多边形,尽管行程行程时间增加,但仍会找到相同的节点。我将不得不发布第二个问题。
    猜你喜欢
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2016-09-13
    • 2011-07-20
    • 1970-01-01
    相关资源
    最近更新 更多