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)
Asked By: Ricedumplings

||

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)
Answered By: Rob Raymond

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'])
Answered By: Gang Su
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.