Retrieving OpenStreetMap data¶
What is OpenStreetMap?¶
OpenStreetMap (OSM) is a global collaborative (crowd-sourced) dataset and project that aims at creating a free editable map of the world containing a lot of information about our environment. It contains data for example about streets, buildings, different services, and landuse to mention a few.
OSM has a large userbase with more than 4 million users that contribute actively on OSM by updating the OSM database with 3 million changesets per day. In total OSM contains more than 4 billion nodes that form the basis of the digitally mapped world that OSM provides (stats from November 2017.
OpenStreetMap is used not only for integrating the OSM maps as background maps to visualizations or online maps, but also for many other purposes such as routing, geocoding, education, and research. OSM is also widely used for humanitarian response e.g. in crisis areas (e.g. after natural disasters) and for fostering economic development (see more from Humanitarian OpenStreetMap Team (HOTOSM) website.
Osmnx¶
This week we will explore a new and exciting Python module called osmnx that can be used to retrieve, construct, analyze, and visualize street networks from OpenStreetMap. In short it offers really handy functions to download data from OpenStreet map, analyze the properties of the OSM street networks, and conduct network routing based on walking, cycling or driving.
There is also a scientific article available describing the package:
- Boeing, G. 2017. “OSMnx: New Methods for Acquiring, Constructing, Analyzing, and Visualizing Complex Street Networks.” Computers, Environment and Urban Systems 65, 126-139. doi:10.1016/j.compenvurbsys.2017.05.004
Download and visualize OpenStreetMap data with osmnx¶
As said, one the most useful features that osmnx provides is an easy-to-use way of retrieving OpenStreetMap data (using OverPass API ).
Let’s see how we can download and visualize street network data from a district of Kamppi in Helsinki, Finland. Osmnx makes it really easy to do that as it allows you to specify an address to retrieve the OpenStreetMap data around that area. In fact, osmnx uses the same Nominatim Geocoding API to achieve this which we tested during the Lesson 2.
- Let’s retrieve OpenStreetMap (OSM) data by specifying
"Kamppi, Helsinki, Finland"
as the address where the data should be downloaded.
In [1]: import osmnx as ox
In [2]: import matplotlib.pyplot as plt
In [3]: place_name = "Kamppi, Helsinki, Finland"
In [4]: graph = ox.graph_from_place(place_name)
In [5]: type(graph)
Out[5]: networkx.classes.multidigraph.MultiDiGraph
Okey, as we can see the data that we retrieved is a special data object called networkx.classes.multidigraph.MultiDiGraph
. A DiGraph is a data type that stores nodes and edges with optional data, or attributes.
What we can see here is that this data type belongs to a Python module called networkx
that can be used to create, manipulate, and study the structure, dynamics, and functions of complex networks.
Networkx module contains algorithms that can be used to calculate shortest paths
along networks using e.g. Dijkstra’s or A* algorithm.
- Let’s see how our street network looks like. It is easy to visualize the graph with osmnx with
plot_graph()
function. The function utilizes Matplotlib for visualizing the data,
hence as a result it returns a matplotlib figure and axis objects.
In [6]: fig, ax = ox.plot_graph(graph)
In [7]: plt.tight_layout()
Great! Now we can see that our graph contains the nodes (blue circles) and the edges (gray lines) that connects those nodes to each other.
It is also possible to retrieve other types of OSM data features with osmnx.
- Let’s download the buildings with
buildings_from_place()
function and plot them on top of our street network in Kamppi. Let’s also plot the Polygon that represents the area of Kamppi,
Helsinki that can be retrieved with gdf_from_place
function.
In [8]: area = ox.gdf_from_place(place_name)
In [9]: buildings = ox.buildings_from_place(place_name)
In [10]: type(area)
Out[10]: geopandas.geodataframe.GeoDataFrame
In [11]: type(buildings)