Routing in R Using the Open Source Routing Machine (OSRM)
I often find myself needing to establish the travel time or distance between arrays of addresses from R. Here we describe how we can use a local install of Open Source Routing Machine as a solution which is highly performant, and relatively easy to implement.
R
geospatial
OSRM
Author
Chris Hansen
Published
November 27, 2016
Overview
Edit 2020-07-16: The original version of this post included a bespoke decoder for geometries encoded as Google polylines. The post has been updated to use the googlePolylines package instead.
I often find myself needing to establish the travel time or distance between arrays of addresses. In the past I have used ArcMap’s Network Analyst tool, but have found the syntax to be clunky at best, and the performance to be very mediocre. And, besides, I am often working in R and sometimes it’s nice to be able to do everything in the one environment, rather than doing the routing in Python, say, and then using the results in R.
The open source routing machine is a very fast routing engine which can be accessed via an HTTP API, which means it can be queried relatively easy from most languages, including R. And while public servers are available for use, it is also relatively easy to set up locally resulting in excellent throughput due to the lack of latency.
Prerequisites
The following R packages are required:
rjson for reading web service results in JSON format
bitops used to decode polylines (has convenient bitshift operators, etc.)
googlePolylines for converting routes returned from OSRM to sp-compatible paths
Geocoding addresses
The HERE Geocoding & Search API is used to geocode addresses. Usage is free, but the free license is limited to 1000 requests per day, at a rate no faster than 5 per second. There are free alternatives, but I’ve not found any that are satisfactorally accurate for New Zealand addresses. That said, interesting alternatives worth keeping an eye on are:
Open Source Routing Machine is an open source route solver. It is written in C++ and runs on Linux (maybe other platforms, but stick with Linux), and is very fast. There is a nice web demo which uses the service as a back-end here. The back-end service is available to the public at https://router.project-osrm.org. Details, including usage policy, is available here.
The code below shows how to find a route between the origin and destination locations found above:
Again, assuming a route was successfully found, route will now contain a list including, among other things, time in seconds to traverse the route, distance in metres, and the route geometry stored in encoded polyline algorithm format.
It is relatively easy to make a nice interactive map. Here we draw a simple leaflet map, and overlay the origin and destination points, as well as the route between.
library(leaflet)#make a string to nicely label the routes <- route$routes[[1]]$durationkms <-round(route$routes[[1]]$distance/1000, 1)routelabel <-paste0(s%/%60, "m ", s%%60, "s , ", kms, "kms")#create a basic mapm <-leaflet(width="100%") %>%addTiles() %>%addPolylines(lng = path$lon,lat = path$lat,popup = routelabel, color ="#000000", opacity =1, weight =3 ) %>%addMarkers(lng=o$lng, lat=o$lat, popup=o$address) %>%addMarkers(lng=d$lng, lat=d$lat, popup=d$address)
It’s also relatively straight forward to use different base maps, and a nice demo of some other providers can be found here. For example: