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 下载的地理包格式的数据,然后将其导入为计算距离、等时线等的图表。
当前进程:
- 使用ox.graph_from_point
下载osm数据
- 使用 ox.io.save_graph_geopackage 保存到 Geopackage 边和节点,以允许用户通过数字化道路(通过捕捉)在 QGIS 中添加边和额外道路并保存编辑。
- 使用 ox.graph_from_gdfs.
将编辑边转换回 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。
我将演示如何使用 OSMnx v1.0 执行此操作,因为它将在两天内发布,并为将 GeoPandas GeoDataFrames 转换为 NetworkX MultiDiGraph 提供稍微更强大的支持。有关使用详情,请参阅 the docs。
您的问题似乎是边缘 GeoDataFrame 中的 u
、v
和 key
列包含空值,大概是您在 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)
我需要编辑由 osmnx 下载的地理包格式的数据,然后将其导入为计算距离、等时线等的图表。
当前进程:
- 使用ox.graph_from_point 下载osm数据
- 使用 ox.io.save_graph_geopackage 保存到 Geopackage 边和节点,以允许用户通过数字化道路(通过捕捉)在 QGIS 中添加边和额外道路并保存编辑。
- 使用 ox.graph_from_gdfs. 将编辑边转换回 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。
我将演示如何使用 OSMnx v1.0 执行此操作,因为它将在两天内发布,并为将 GeoPandas GeoDataFrames 转换为 NetworkX MultiDiGraph 提供稍微更强大的支持。有关使用详情,请参阅 the docs。
您的问题似乎是边缘 GeoDataFrame 中的 u
、v
和 key
列包含空值,大概是您在 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)