Working with OpenStreetMap in Python
How to easily acquire, manipulate, and process OpenStreetMap data for your next geospatial data science project
OpenStreetMap (OSM) is an open-source database that allows virtually anyone to edit the underlying geospatial dataset. It can be a reliable source of data, especially since it is continually updated and validated by thousands of volunteers around the world. You can choose to download any OSM dataset on your own, but it will be time consuming and difficult. Not to mention the hassle of having to move back and forth between the data source and your development environment. With OSMnx Python library, however, you can acquire and process OSM dataset directly from your Notebook!
In this tutorial, we will be using OSMnx to perform OSM tasks that are otherwise inaccessible outside of our Python environment.
OSMnx is a Python package that lets you download spatial geometries and model, project, visualize, and analyze street networks and other spatial data from OpenStreetMap’s API.
Table of Content
1. Setup
2. Point-of-Interests (POIs)
3. Street
4. BuildingWithout further ado, let’s begin!
Setup
Install OSMnx via conda using the following command:
conda install osmnxWe will be importing osmnx using the following convention:
import osmnx as oxWe will then define our place to be in New York City instead of the entire world to reduce computational and memory costs.
place = 'Manhattan, New York, USA'
Do subscribe to my email newsletter where I regularly summarize programming tips and AI research papers in plain English and beautiful visualization.
Point-of-Interests (POIs)
First, let’s acquire some cafe points within Manhattan in New York City. We can easily do this by specifying tags dict object inside the geometries_from_place() function as follows:
tags = {'amenity': 'cafe'}
cafe = ox.geometries_from_place(place, tags=tags)cafe.head()
Here we see that some have incomplete addresses. This is the downside of OSM being community-driven where the data can be missing. However, the geometry is still intact, and so we can still derive some location-based information out of the dataset.
Now, we try plotting these cafes on the map using folium library.
import foliumAnd subsetting the first 100 cafes to speed up processing:
cafe_points = cafe[cafe.geom_type == 'Point'][:100]And specify the map object by drawing the point individually and saving the completed map as an html file.
m = folium.Map([40.754932, -73.984016], zoom_start=10)
locs = zip(cafe_points.geometry.y, cafe_points.geometry.x)for location in locs:
folium.CircleMarker(location=location).add_to(m)
m.save('cafes.html')If you open cafes.html you will be able to see the following illustration:

Looks good so far! Now we will deal with street network from our OSM dataset.
Street
Let’s acquire the graph data for our street network in Manhattan. We specify the network_type to be of type drive to reduce the number of roads we have to process.
graph = ox.graph_from_place(place, network_type='drive')The graph above is of NetworkX data format and we need to convert it to GeoDataframe format for easy manipulation. This can easily be done by calling the graph_to_gdfs() function as follows:
nodes, streets = ox.graph_to_gdfs(graph)streets.head()
Now our street data is in the familiar GeoDataframe format.
The last thing to do is to again draw the street network using folium . Fortunately for us, OSMnx provides us with this capability natively (as of now, this native support is only valid for NetworkX type of graph data).
ox.folium.plot_graph_folium(graph)And you will be able to see the streets in Manhattan of NYC!

Now the last geometry that OSM supports is that of building footprints.
Building
Similar to POIs and street objects, let’s acquire the building footprints of Manhattan by setting the building tag to True .
tags = {'building':True}
building = ox.geometries_from_place(place, tags)There are way too many columns for us to have a meaningful analysis. And so let’s reduce the number of columns by selecting key ones.
cols = ['amenity','building', 'name', 'tourism']
building[cols].head()We get the following information about our buildings in Manhattan.

Nicely done! Let us try visualizing how our building footprints will look like, again using folium . We will limit our building to 1000 for simplicity.
buildings = building[building.geom_type == 'Polygon'][:1000]And construct the map object:
m = folium.Map([40.754932, -73.984016], zoom_start=10, tiles='CartoDb dark_matter')folium.GeoJson(buildings[:1000]).add_to(m)Finally, display the map containing our building footprints.
mWe will be able to see some building footprints (albeit not completely) in Manhattan beautifully!

Conclusion
We have managed to acquire, manipulate, and visualize OSM dataset within a Python environment. We have used OSMnx library as an API interface that effectively connects with the OSM API layer, and folium to display the geospatial information derived from GeoDataframe . As always, if you have further feedback, please feel free to leave a response!






