OSMNX graph from point and geometry information

10k Views Asked by At

I have been using osmnx for a while now, and doing: G = ox.graph_from_point(city_center, distance=distance, network_type='drive', simplify=False) was returning a graph

where an edge iteration for u, v, data in G.edges(keys=False, data=True)

would allow one to access the geographic coordinates of an edge in the following way: data['geometry'].coords

in the latest effort, unfortunately the geometry property was not there. Any chance how one could access the coordinates of a node or an edge now?

Thanks so much!

2

There are 2 best solutions below

4
On

Here is a code snippet but now even upon data retrieval I get

the following errors: File ../python3.7/site-packages/osmnx/core.py", line 931, in create_graph raise EmptyOverpassResponse('There are no data elements in the response JSON objects') osmnx.errors.EmptyOverpassResponse: There are no data elements in the response JSON objects

import osmnx as ox
import sys

newyork_center = (40.729630, -73.998835)
distance = 100.0  

G = ox.graph_from_point(newyork_center, distance=distance, network_type='drive', simplify=False) 

for u, v, data in G.edges(keys=False, data=True):
    try:
        print (data)
        print (data['geometry'].coords)
    except:
        print (sys.exc_info())
3
On

OSMnx only adds a geometry attribute to simplified edges. If an edge is unsimplified, its geometry is a trivial straight line between its incident nodes u and v. In your code, you parameterized graph_from_point with simplify=False, hence none of your edges are simplified and none of them have geometry attributes:

import osmnx as ox
ox.config(use_cache=True, log_console=True)

point = 40.729630, -73.998835
dist = 100
G = ox.graph_from_point(point, dist=dist, network_type='drive', simplify=False) 

for u, v, data in G.edges(keys=False, data=True):
    simp = '' if 'geometry' in data else 'not '
    print(f'edge {data["osmid"]} has {simp}been simplified')

If you simplify the graph, some or all of its edges will have geometry attributes, depending on whether or not a particular street segment linking two intersections spanned multiple OSM nodes originally. The topological simplification methodology is detailed in this paper. More details appear in the docs. Example:

import osmnx as ox
ox.config(use_cache=True, log_console=True)

point = 40.729630, -73.998835
dist = 100
G = ox.graph_from_point(point, dist=dist, network_type='drive', simplify=True) 

for u, v, data in G.edges(keys=False, data=True):
    simp = '' if 'geometry' in data else 'not '
    print(f'edge {data["osmid"]} has {simp}been simplified')

You can also manually add geometry attributes to each edge of a simplified or unsimplified graph by calling graph_to_gdfs with fill_edge_geometry=True then reconstructing your graph with graph_from_gdfs, like this:

import osmnx as ox
import pandas as pd
ox.config(use_cache=True, log_console=True)

point = 40.729630, -73.998835
dist = 100
G = ox.graph_from_point(point, dist=dist, network_type='drive', simplify=False)

# create nodes, edges GeoDataFrames and fill in all edge geometry attributes
# then re-create a MultiDiGraph from those GeoDataFrames
nodes, edges = ox.graph_to_gdfs(G, fill_edge_geometry=True)
G2 = ox.graph_from_gdfs(nodes, edges, graph_attrs=G.graph)

for u, v, data in G2.edges(keys=False, data=True):
    assert 'geometry' in data

Finally, in a comment above, you mentioned "I am using what is the latest version, which is osmnx 0.16.1." But, your code snippet can't be using v0.16.1 because the distance parameter was deprecated and eventually replaced with dist 5 or 6 versions ago. Try running print(ox.__version__) to see what version you're actually using.