OSMNX graph_from_gdfs KeyError: 'x' when converting a Geopackage to a Graph

OSMNX graph_from_gdfs KeyError: 'x' when converting a Geopackage to a Graph

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

当前进程:

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

此时'ox.graph_from_gdfs'returns一个空的Graph对象。它似乎抱怨 x 属性不存在,但 x 和 y 属性确实存在于 geopackage 节点层中 - 所以我不明白这个错误。

错误:

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。

地理路径Geopackage Download

我将演示如何使用 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)