August 27, 2026
I enjoy long road trips. I have done many of these trips across North America. My friend and I are only able to embark on these trips during the short week-long periods of time we have off from work, school, etc. We often want to travel to places very far away, but our trips' distance is usually constrained by travel time.
Estimation of travel time is trivial these days; any internet-based routing service outputs a very accurate travel time estimation; an average speed of 55-80mph can also usually be assumed can combined with driving distance. Still, these point-to-point routing services/method lack the ability to show travel time to every place at once, which is useful for exploring the possible destinations, comparing them, and general decision-making. I want to make an isochrone map showing travel time from a certain point.
An inspiration for this project is Charles O. Paullin's “Rates of travel.”
Paullin, Charles Oscar. Atlas of the historical geography of the United States (1932), plate 138. Page 366. Most likely public domain.
The objective of this map is to show expected driving time from a certain starting point to the contiguous US, northern Mexico, and southern Canada. Of course, dataset can be easily replaced to generate a map for any continent. The assignment of speed can also be modified to reflect a non-scheduled mode of highway travel like biking, walking, or speed-limited motorized vehicle.
The highway dataset is OpenStreetMaps processed by and downloaded from Geofabrik.
The entire North America OpenStreetMap dataset is downloaded via wget, the file is about 17GB large. This file is then processed by the Osmium Tool to extract only major highways and links from the dataset. Only motorways, trunks, and primary highways (and associated links) are kept. Keeping smaller highways results in unacceptably long processing time and very large memory usage.
The Osmium-processed file is loaded into Python using Pyrosm and represented as a NetworkX graph. Then, speed and travel time is assigned using OSMnx. With travel time of edges, the graph and a predefined origin is fed into NetworkX's single_source_dijkstra function to find travel time between the origin node and every other node.
After pathfinding, the graph is converted into a GeoDataFrame and the travel time between nodes is interpolated using scipy.interpolate.griddata so that every pixel on the map image has a defined time. To reduce nonsensical results from interpolation (e.g. driving time to the middle of the ocean or desert), a K-D tree is used to filter out pixels that are too far from a node. The pixels are then plotted using matplotlib.pyplot.contour and a basemap is added using contextily. The basemap I used is Stadia's StamenTonerLite. Using it requires an API key, but it's free for minor uses.
Data download and pre-processing:
wget https://download.geofabrik.de/north-america-latest.osm.pbf
osmium tags-filter north-america-latest.osm.pbf w/highway=motorway,motorway_link,trunk,trunk_link,primary,primary_link -o na-maj-highways-only.osm.pbf --overwrite
The main Python code. You need a Stadia API key or use a different basemap provider. There are serveral free ones built into contextily.
The entire process takes about an hour, downloading map data may take a long time depending on network bandwidth. Most of time is spent extracting highways, loading the graph, and generating the image. Pathfinding, thanks to Djikstra and later contributions, is extremely fast and only takes serveral seconds even when the code is completely untuned.
This code is very memory intensive and unoptimized. Please make sure you have enough memory. On the North American dataset with highways primary and more major, all of my 32 GB of physical memory and ~60 GB of virtual memory is used at peak.
The contour interval is one hour of driving.
The map with Brunswick, GA as an origin is shown here: Printable map PDF
The map with I-70 WB exit 216 in Colorado (@ US-6, Loveland Pass) is shown here:
I invite you to explore these maps. The images linked are Jpeg compressed and downscaled from the original.
The contour lines in the contiguous US appears fairly concentric about the origin. An artifact of an effective and robust highway system. Despite this, there are still interesting oddities. Finding them will be left as an exercise for the reader.
All locations mentioned in this section is in California. There are essentially no crossings of the Sierras between Yosemite and Bakersfield/Lake Isabella. Driving between Independence and Kanawyers, despite being 21 miles apart, is a 350 mile route taking 6.5 hours.
Setting the Isochrone map's origin to the intersection of CA-245 and CA-180, near Cedarbrook, east of Fresno, the Sierra's barrier becomes apparent.
I'm sure there are many more examples of this, the Sierra Nevada is just the first example I can think of.
Obviously, the map is intended for general planning purposes only and only routes to nodes on major highways. In the United States, only Interstates, US highways, and major state and local highways are included.
On the printed version the map, the following notice is included:
Estimated travel time from Glynn Ave (US-17) & Gloucester St (US-25) in Brunswick, GA, USA to nodes (typ. intersection, crossroad, ends of ramp) on a highway. Values represent constant travel at speed limit. Does not consider border crossing delay, intersection and traffic control delay, congestion delay, road closures including seasonal, etc.
Recommended for use for long-distance motor vehicle travel planning. THIS IS NOT A LEGAL DOCUMENT, BOUNDRIES MAY BE INACCURATE. DRIVE SAFELY. DO NOT USE FOR NAVIGATION
At the end, the map shows you how much freewill you have as long as you have a car and some gas.
Map data
Basemap
Python, libraries, and dependencies including Osmium, OSMnx, NetworkX, Pryosm, etc.
If you have any questions or comments, please contact me.