osmnx: ValueError: Geometry must be a shapely Polygon or MultiPolygon

If we run this code:

import osmnx as ox
ox.config(log_console=True)
G = ox.graph_from_place('Baltimore, Maryland, USA', network_type='drive')

We get this error:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-1-afb511cf7347> in <module>()
      1 import osmnx as ox
      2 ox.config(log_console=True)
----> 3 G = ox.graph_from_place('Baltimore, Maryland, USA', network_type='drive')

C:\Anaconda\lib\site-packages\osmnx\osmnx.py in graph_from_place(query, network_type, simplify, retain_all, truncate_by_edge, name, which_result, buffer_dist, timeout, memory, max_query_area_size, clean_periphery)
   1815     # create graph using this polygon(s) geometry
   1816     G = graph_from_polygon(polygon, network_type=network_type, simplify=simplify, retain_all=retain_all, 
-> 1817                            truncate_by_edge=truncate_by_edge, name=name, timeout=timeout, memory=memory, max_query_area_size=max_query_area_size, clean_periphery=clean_periphery)
   1818 
   1819     log('graph_from_place() returning graph with {:,} nodes and {:,} edges'.format(len(G.nodes()), len(G.edges())))

C:\Anaconda\lib\site-packages\osmnx\osmnx.py in graph_from_polygon(polygon, network_type, simplify, retain_all, truncate_by_edge, name, timeout, memory, max_query_area_size, clean_periphery)
   1730         raise ValueError('Shape does not have a valid geometry')
   1731     if not isinstance(polygon, (Polygon, MultiPolygon)):
-> 1732         raise ValueError('Geometry must be a shapely Polygon or MultiPolygon')
   1733 
   1734     if clean_periphery and simplify:

ValueError: Geometry must be a shapely Polygon or MultiPolygon

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 2
  • Comments: 28 (15 by maintainers)

Commits related to this issue

Most upvoted comments

OSMnx is behaving correctly. The API returns a point for the query ‘Baltimore, Maryland, USA’ but graph_from_place and graph_from_polygon require a geometry that is a Polygon or MultiPolygon to proceed – as the error message explains.

OSMnx passes the query string ‘Baltimore, Maryland, USA’ to OSM’s nominatim API to get a polygon representing the boundaries of the place. It then collects the street network within these boundaries. But if you pass ‘Baltimore, Maryland, USA’ to nominatim directly yourself, you can see the result.

Nominatim successfullly geocodes it and returns 2 results. The first’s geometry is simply a point representing the center of the city. The 2nd result’s geometry is the city’s administrative boundary. The API usually prioritizes the latter result with a higher importance score, but for whatever reason, in Baltimore’s case it doesn’t. By default OSMnx uses the first result and tries to create a street network from it. But with a point, it (obviously) can’t find any network data within the geometry.

If one of the geocoding results contains polygon geometry:

We can point OSMnx at the nth result (in this example, the 2nd) that correctly includes the boundary data by using the which_result function argument, as demonstrated in the tutorial:

G = ox.graph_from_place('Baltimore, Maryland, USA', network_type='drive', which_result=2)

If none of the geocoding results contain polygon geometry:

That is, if OpenStreetMap does not have a boundary polygon for your place: you can still get the local street network using graph_from_address(place_name, distance), or the graph_from_point function passing in a lat-long point, or the graph_from_polygon function passing in your own polygon (from a shapefile, etc.) of the place’s boundaries.

Another example:

G = ox.graph_from_place('Beijing, China', network_type='drive')
G_proj = ox.project_graph(G)
fig, ax = ox.plot_graph(G_proj)

…throws the error described above because the first geocode result for “Beijing, China” returns a point as the geometry. The second geocode result returns a polygon so this error is fixed by passing which_result=2:

G = ox.graph_from_place('Beijing, China', which_result=2, network_type='drive')
G_proj = ox.project_graph(G)
fig, ax = ox.plot_graph(G_proj)

…produces:

If OSM had no polygon for this place query in any of the geocoding results, we could have used graph_from_address instead, like:

G = ox.graph_from_address('Beijing, China', distance=10000, network_type='drive')

See the documentation for more info.

No worries. It’s just easier for everyone to respond usage questions on StackOverflow than here in the issue tracker. Good luck.

@scottishbee the Nominatim geocoder that resolves place names has changed since then. Try to provide an explicit query, and it should work, as seen in this example:

place_query = {'city':'San Francisco', 'state':'California', 'country':'USA'}
G = ox.graph_from_place(place_query, network_type='drive')

The graph_from_place docstring has been updated to reflect this.