OSMnx — Handling Street Networks

Pratik Mahadik
6 min readNov 1, 2020
Pune City Area visualized in color gradient using OSMnx library

Introduction

Each of us are eagerly excited when we plan a trip. Whenever we go to a unknown place there is only one companion which everyone relies on for routes. Yes, you guessed it right! It’s Google Maps. Each time to search a location or finding route to the nearest food court we rely on Google Maps. Started in year 2005 Google Maps has been the top service provider for location based services. Google Maps has many rich features including satellite imagery, topographic data to 3D and street view images. Its routing and live traffic features help individuals to business for taking better decision and make optimal schedules.

Most popular apps survey by The Manifest, 2018

Google Maps API can be used in websites to show location and features as well as are used by many application for routing purposes. Example, Food Delivery Company as Swiggy, Zomato, etc. use Google Maps Routing API for their routing applications to efficiently deliver food in less time. But this power comes at a cost. Google Maps API is a proprietary software from Google and is very costly use. It costs around 0–10 USD per 1000 query made.

So what’s the alternative to this? As we know OSM (Open Street Maps) a community driven map service provider is open source i.e. free for use. Each individual in the community helps to gather data and feed it to the OSM Map Server. Even Google Maps takes data from OSM to use in there Map Services. Daily the data is being updated by crowd sourcing and made freely available to billions of people.

Here are some API and library which uses the OSM street network data for routing and other services as follows:

  1. OSMnx (Python)
  2. GraphHopper (JAVA)
  3. PyrouteLib (Python)
  4. Openrouteservice (JAVA)
  5. SimpleOsmRouter (Python)

OSMnx

Today we’ll discuss OSMnx which is a python library which can be used to analyze street network data for purpose based on graph theory. It uses networkx library which is a python library for studying graphs and networks. OSMnx lets you download road data in form of nodes and edges. This data is retrieved from OSM street networks which can be then modeled and visualized. Let’s start with installing the library and importing them.

!apt install python3-rtree --quiet 
!pip install osmnx
!pip install matplotlib

import geopandas as gpd
import networkx as nx
import osmnx as ox
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
location = (18.5204,73.8567) mode = "drive" ox.config(log_console=True, use_cache=True)

We will start with fetching data using latitude and longitude coordinates. We can fetch data of different transportation modes such as ‘walk’, ‘bike’, ‘drive’, ‘drive_service’, ‘all’, or ‘all_private’.

You can cache the retrieved data for loading the same data faster next time also you can turn logs on to get more information.

G = ox.graph_from_point(location, dist=2000, simplify=True, network_type=mode) 
nodes_proj, edges_proj = ox.graph_to_gdfs(G, nodes=True, edges=True) ox.plot_graph(G,node_color='r')
Street network data for selected area in Pune City

Using graph_from_point function street network data is retrieved in the form of nodes and edges. Nodes being junction or intersection and edges are lines (roads) connecting two nodes. You can specify distance from the coordinate given to fetch data for. Also to return simplified geometry you keep simplify as True. The plot_graph function will plot the street network and the nodes can be colourized using node_color parameter.

Finding shortest Path

origin_point = (18.515802, 73.846754) 
destination_point =(18.519423, 73.852966)
origin_node = ox.get_nearest_node(G, origin_point)
destination_node = ox.get_nearest_node(G, destination_point)
route = ox.shortest_path(G, origin_node,destination_node)
bbox = ox.utils_geo.bbox_from_point(point=(18.515802, 73.846754), dist=700)
fig, ax = ox.plot_graph_route(G, route, bbox = bbox, route_linewidth=6, node_size=0, bgcolor='k')
routes = ox.k_shortest_paths(G, origin_node, destination_node, k=5, weight='length')
bbox = ox.utils_geo.bbox_from_point(point=(18.515802, 73.846754), dist=700)
fig, ax = ox.plot_graph_routes(G, list(routes), bbox = bbox, route_colors='r', route_linewidth=2, node_size=0)
Left, Plot showing one shortest path between two points. Right, Plot showing 5 optimal shortest path. Thicker lines denotes most optimal path.

Now we will move forward to finding shortest path from one point to another point. First define origin point and destination point then find the nearest node from the graph. Then use the shortest_path function to find shortest route. But this function will only give one shortest route. To get more optiomal path use k_shortest_path function where parameter k denotes number of optimal roads required and you can state any column name to be used for weighing function.

To visualize one way we can use the oneway column from edges. Here we will visualize oneway roads in red and others in white and with plot them.

ec = ['r' if data['oneway'] else 'w' for u, v, key, data in G.edges(keys=True, data=True)] 
fig, ax = ox.plot_graph(G, node_size=0, edge_color=ec, edge_linewidth=1.5, edge_alpha=0.7)
Pune City oneway roads highlighted in red

Plot routes on folium

To plot routes and street networks on folium we should use plot_graph_folium and plot_route_folium function. First we will get any origin and destination nodes from the graph object retrieved from OSM server. Then we will find shortest route between them. While creating graph and route on folium we can specify which column values to be used for popup. We can save this web map as an html page for sharing.

origin_node = list(G.nodes())[0] 
destination_node = list(G.nodes())[-1]
route = nx.shortest_path(G, origin_node, destination_node)
graph_map = ox.plot_graph_folium(G, popup_attribute='name', edge_width=2)
route_graph_map = ox.plot_route_folium(G, route, route_map=graph_map, popup_attribute='length') route_graph_map.save('route.html')
route_graph_map
Street network dataset and route between origin and destination point visualized on web map

Saving network data to disk

Downloaded street network data can be saved in various format such as geopackage or shp format for using it with GIS softwares. And also can be saved as an svg image or as a graphml file.

ox.save_graph_geopackage(G, filepath='./data/street_network.gpkg') ox.save_graphml(G, filepath='./data/street_network.graphml') ox.save_graph_shapefile(G, filepath='./data/streets') ox.plot_graph(G, show=False, save=True, close=True, filepath='./images/street_network.svg')
ox.save_graph_xml(G, filepath='./data/street_network.osm')

Conclusion

OSMnx is a very feature rich and efficient library to retrieve, model, process and visualize street network data for various purposes. As this library also allows user to save the street network data in various format for future use and has various methods to create eye-catching plots or maps makes it more demanding. For handling large datasets it can also be used with multiprocessing to run the code faster by parallelization. Also it has a good documentation and pretty neatly explained notebook examples to cover up most of the good features which this library offers. OSMnx is a good alternative to use for creating route maps or modeling street network datasets.

--

--