Creating a Traveling Distance Map for a Whole City With Python

Isochron mapping using graph networks and folium maps for multiple points simultaneously

Felix Ude
Better Programming

--

Availability of public transport in Hamburg | Image by the author

Calculating the distances to all the places you can reach from your location is called an isochron and is quite useful if you would like to find out what places you can reach within a specific time. But what if you want to do it the other way around and create a map that shows the travelling distances from a list of points of interest to all points in your city? This tutorial will show you how you can create such isochron maps yourself!

You can find an overview of the results on this streamlit application: Walking distances to Infrastructure in Hamburg.

Creating the Graph Network

Creating the graph network is rather easy. First, install and import the required libraries.

Next, we create the graph for our starting address, giving us a list of nodes, which are essentially simplified street intersections. Afterward, we convert it to a GeoPandas dataframe to plot the generated nodes.

dist is the distance from your starting location used to create the graph.

network_type is the type of transport you want to use, other options are: “all_private,” “all,” “bike,” “drive,” “drive_service.”

We can look at our network on a folium map using this code:

Folium map with the nodes created by us | Image by the author

Creating isochrons for each point of interest

Now for the interesting part: Creating the isochrons for each point of interest and calculating the distance to each of our freshly created nodes. In this case, we will use the locations of all subway stations in the city of Hamburg. To use the locations, we have to find the nearest node for each coordinate tuple. This is easily achieved with the help of the osmnx function nearest_nodes.

To calculate actual distances, we need to project the network on a map. The transformation varies depending on the latitude. (Wikipedia: Map projection) We will use the default setting of the project_graph function to do so.

Now, we could already create a distance array for a single point of interest (POI). If we use the networkx function shortest_path_length and only provide a source, it will calculate the shortest distance to all other nodes in the provided graph.

The structure of our dictionary would look like this:

We could already proceed with this and create a plot from it. This will require some work, though, as we need to create a color map ourselves to present the distance nicely in a visual way on the Folium map.

We create a color map ourselves with steps for each minute from one to 50. With the help of a small mapping function, we rewrite the dictionary function to include the color code instead of the distance. Now, we have a color for each node in our graph and can plot our folium map again.

Colored nodes depending on the distance to POI (brighter is closer) | Image by the author

Using all points of interest

Remember that we wanted to use several points of interest to create our maps? We are nearly there. To iterate over our list of POI, we want to make sure to always keep the smallest distance. For that reason, I wrote a small custom dictionary class that only updates values if it is smaller than the existing value or not yet existing.

With this, we can finally loop over all POI and create a dictionary with each node and the smallest distance to any POI.

With this new node_distances, we just repeat the steps above, i.e., mapping the colors and creating a folium plot, and voilà, we have our final plot:

Walking distance to the nearest subway station in Hamburg (15 km render distance) | Image by the author

I hope you liked this small tutorial! If you are interested, you can find the whole notebook here.

--

--