Context
I am trying to download some footway graph from OpenStreetMap (OSM) using osmnx.
Here is a piece of code:
import os, sys
import pandas as pd
import geopandas as gpd
import matplotlib.cm as cm
import matplotlib.colors as colors
import networkx as nx
import osmnx as ox
ox.config(log_console=True, use_cache=True)
ox.__version__
G_test = ox.osm_net_download(polygon=None,
north=46.95489, west=7.46006,
south=46.95335, east=7.46132,
network_type='walk'
)
The ox.osm_net_download()
method, is based on the Overpass API, so if I check what's in G_test
and search for this OSM way 295557051
I can see that the OSM tags are shipped with the data:
{'type': 'way',
'id': 295557051,
'nodes': [2992861879,
2992861880,
(...) # bunch of vertex coordinates here, skipped for clarity
2992864399],
'tags': {'footway': 'sidewalk', 'highway': 'footway', 'surface': 'paved'}
}
The tags
are of course the same as the one found by making a direct call to the Overpass API or the OSM API (on which the previous seems to rely) at this address for this way:
https://www.openstreetmap.org/way/295557051
Up to this point, everything is fine.
But the ox.osm_net_download()
method doesn't return a networkx graph object, it returns a Python list.
Therefore, to download a graph, I usually query the data through any of the proposed graph_from_*()
methods, for example a graph_from_bbox*()
as:
G = ox.graph_from_bbox(north=46.95490, west=7.46000,
south=46.95330, east=7.46230,
network_type='walk',
retain_all=True)
Issue
But when downloading the data using the latter method, the OSM tags no longer come with the data!
This is probably due the fact that the graph_from_*()
methods are not based on the Overpass API but rather on the Nominatim API.
This may be related to: Cannot get response from nominatim API on some OSM objects
If I explore the result of the G
graph, searching for the OSM way 295557051
:
G_raw.edges(keys=True, data=True)
One of the may results (as they are many edges composing this OSM feature) look like this:
(2992861879, 2992861880, 0, {'osmid': 295557051, 'highway': 'footway', 'oneway': False, 'length': 4.821}),
For a better comprehension, we can convert it to a GeoDataFrame using the ox.graph_to_gdfs()
method:
G_gdf = ox.graph_to_gdfs(G,
nodes=True,
edges=True,
node_geometry=True,
fill_edge_geometry=True)
And print its content:
G_gdf[1][G_gdf[1]['osmid']==295557051]
This problem is also propagated when saving the graph to an ESRI Shapefile using ox.save_graph_shapefile()
:
ox.save_graph_shapefile(G, filename=os.path.join('~/test_graph'))
Indeed, when I open the resulting Shapefile, for example in QGIS, a query on that same way doesn't show the OSM tags in the attribute table.
Question
I wonder where the tags are lost in the process and how to solve for this issue?
Note:
I was first thinking of converting the G
graph to a GeoDataFrame, merging it with G_test
which I also convert to a GeoDataFrame and then convert back that merged GeoDataFrame to a networkX graph, but I went into a strange error because the retrieved graph doesn't have the right structure:
TypeError: float() argument must be a string or a number, not 'NoneType'
Or to directly write the GeoDataFrame to PostGIS:
AttributeError: 'GeometryDtype' object has no attribute 'base'
But GeoPandas doesn't handle (yet) writing data to PostGIS:
https://github.com/geopandas/geopandas/pull/1248
So I'm stuck.
graph_from_*()
methods call Nominatim and not Overpass. Nominatim is not suited for obtaining data for a specific bounding box since it is mainly a geocoder. So I guess there must be something else which removes tags after downloading.