Creating graph using OSMNX from geodataframe and shows error 'TypeError: cannot unpack non-iterable int object'
Question:
I used osmnx to download a map and export as geopackages so that I can edit it in QGIS.
After edit(mainly change CRS to GCJ-02) , I want to import the edited edges and nodes into osmnx as a graph to do some routing.
I imported them using
geopandas.read_file(),
and converted to graph using
osmnx.utils_graph.graph_from_gdfs(gdf_nodes, gdf_edges, graph_attrs=None)
Here’s the error :
road = ox.utils_graph.graph_from_gdfs(nodes, edges)
D:ProgramsAnacondaenvsmyenvlibsite-packagesosmnxutils_graph.py:155: UserWarning: discarding the gdf_nodes geometry column, though its values differ from the coordinates in the x and y columns
warnings.warn(
Traceback (most recent call last):
File "C:UsersRicedumplingsAppDataLocalTempipykernel_3412393169980.py", line 1, in <cell line: 1>
road = ox.utils_graph.graph_from_gdfs(nodes, edges)
File "D:ProgramsAnacondaenvsmyenvlibsite-packagesosmnxutils_graph.py", line 169, in graph_from_gdfs
for (u, v, k), attr_vals in zip(gdf_edges.index, gdf_edges.values):
File edge.gpkg looks like:
edges.iloc[1]
Out[51]:
u 436912662
v 436912681
key 0
osmid [337786597, 337786554, 337786537, 337786507, 3...
oneway True
lanes 3
ref G4202
name 四环路南段
highway motorway
length 1635.288
bridge yes
from 436912681
to 436912662
tunnel
width
maxspeed
access
junction
geometry LINESTRING (104.11850662686128 30.568117399805...
Name: 1, dtype: object
File nodes.gpkg looks like:
nodes.iloc[1]
Out[52]:
osmid 436912681
y 30.570557
x 104.115972
street_count 3
highway
ref
geometry POINT (104.11850662686128 30.568117399805935)
Name: 1, dtype: object
Anybody know what’s going wrong? And thank you!
I looked up on the net and saw some solutions, but they are all about changing the code. And since I am an amatuer, I’m hesitate to change the osmnx code, so I haven’t done anything.
Btw,here’s the error part from ‘utils_graph.py’:
# add edges and their attributes to graph, but filter out null attribute
# values so that edges only get attributes with non-null values
attr_names = gdf_edges.columns.to_list()
for (u, v, k), attr_vals in zip(gdf_edges.index, gdf_edges.values):
data_all = zip(attr_names, attr_vals)
data = {name: val for name, val in data_all if isinstance(val, list) or pd.notnull(val)}
G.add_edge(u, v, key=k, **data)
Answers:
Given what you describe, this warning is fully expected. If you have modified the geometry of the nodes and have not made x and y attributes consistent. Best illustrated by sample code below.
- first conversion back to a graph generates a warning
- second conversion after ensuring denormalised columns are consistent with geometry does not generate a warning
import osmnx as ox
# get a graph and geodataframes
G = ox.graph_from_address('Guangzhou, China', network_type= "drive")
gdf_nodes, gdf_edges = ox.graph_to_gdfs(G)
# this will make nodes inconsistent, x & y not equal to geometry
gdf_nodes["geometry"] = gdf_nodes.to_crs(gdf_nodes.estimate_utm_crs()).simplify(1000).to_crs(gdf_nodes.crs)
# hey presto - expected warning
ox.utils_graph.graph_from_gdfs(gdf_nodes, gdf_edges, graph_attrs=None)
# make nodes consistent...
gdf_nodes["x"] = gdf_nodes["geometry"].x
gdf_nodes["y"] = gdf_nodes["geometry"].y
ox.utils_graph.graph_from_gdfs(gdf_nodes, gdf_edges, graph_attrs=None)
You should change the index to be consistent with the format of geodataframe:
gdf_nodes.set_index(['osmid'])
gdf_edges.set_index(['u','v','key'])
I used osmnx to download a map and export as geopackages so that I can edit it in QGIS.
After edit(mainly change CRS to GCJ-02) , I want to import the edited edges and nodes into osmnx as a graph to do some routing.
I imported them using
geopandas.read_file(),
and converted to graph using
osmnx.utils_graph.graph_from_gdfs(gdf_nodes, gdf_edges, graph_attrs=None)
Here’s the error :
road = ox.utils_graph.graph_from_gdfs(nodes, edges)
D:ProgramsAnacondaenvsmyenvlibsite-packagesosmnxutils_graph.py:155: UserWarning: discarding the gdf_nodes geometry column, though its values differ from the coordinates in the x and y columns
warnings.warn(
Traceback (most recent call last):
File "C:UsersRicedumplingsAppDataLocalTempipykernel_3412393169980.py", line 1, in <cell line: 1>
road = ox.utils_graph.graph_from_gdfs(nodes, edges)
File "D:ProgramsAnacondaenvsmyenvlibsite-packagesosmnxutils_graph.py", line 169, in graph_from_gdfs
for (u, v, k), attr_vals in zip(gdf_edges.index, gdf_edges.values):
File edge.gpkg looks like:
edges.iloc[1]
Out[51]:
u 436912662
v 436912681
key 0
osmid [337786597, 337786554, 337786537, 337786507, 3...
oneway True
lanes 3
ref G4202
name 四环路南段
highway motorway
length 1635.288
bridge yes
from 436912681
to 436912662
tunnel
width
maxspeed
access
junction
geometry LINESTRING (104.11850662686128 30.568117399805...
Name: 1, dtype: object
File nodes.gpkg looks like:
nodes.iloc[1]
Out[52]:
osmid 436912681
y 30.570557
x 104.115972
street_count 3
highway
ref
geometry POINT (104.11850662686128 30.568117399805935)
Name: 1, dtype: object
Anybody know what’s going wrong? And thank you!
I looked up on the net and saw some solutions, but they are all about changing the code. And since I am an amatuer, I’m hesitate to change the osmnx code, so I haven’t done anything.
Btw,here’s the error part from ‘utils_graph.py’:
# add edges and their attributes to graph, but filter out null attribute
# values so that edges only get attributes with non-null values
attr_names = gdf_edges.columns.to_list()
for (u, v, k), attr_vals in zip(gdf_edges.index, gdf_edges.values):
data_all = zip(attr_names, attr_vals)
data = {name: val for name, val in data_all if isinstance(val, list) or pd.notnull(val)}
G.add_edge(u, v, key=k, **data)
Given what you describe, this warning is fully expected. If you have modified the geometry of the nodes and have not made x and y attributes consistent. Best illustrated by sample code below.
- first conversion back to a graph generates a warning
- second conversion after ensuring denormalised columns are consistent with geometry does not generate a warning
import osmnx as ox
# get a graph and geodataframes
G = ox.graph_from_address('Guangzhou, China', network_type= "drive")
gdf_nodes, gdf_edges = ox.graph_to_gdfs(G)
# this will make nodes inconsistent, x & y not equal to geometry
gdf_nodes["geometry"] = gdf_nodes.to_crs(gdf_nodes.estimate_utm_crs()).simplify(1000).to_crs(gdf_nodes.crs)
# hey presto - expected warning
ox.utils_graph.graph_from_gdfs(gdf_nodes, gdf_edges, graph_attrs=None)
# make nodes consistent...
gdf_nodes["x"] = gdf_nodes["geometry"].x
gdf_nodes["y"] = gdf_nodes["geometry"].y
ox.utils_graph.graph_from_gdfs(gdf_nodes, gdf_edges, graph_attrs=None)
You should change the index to be consistent with the format of geodataframe:
gdf_nodes.set_index(['osmid'])
gdf_edges.set_index(['u','v','key'])