Calculating distances and time for the travel cost variable: the OSRM package

I have previously shown how to calculate travel distances and times using the Google Maps API query in two blog posts: here and here. In these blog posts, I used the Google maps platform and their services. Getting travel distances and times can be useful in a variety of applications. In my case, after obtaining distances and times between a recreational destination and the postal codes of people’s residences, I could calculate the travel cost.

While useful, using the Google maps API tool has some limitations. First, one is not allowed to freely use it: there is a monthly credit of 200 USD, after which users have to pay for the service. Second, the Google Maps platform has updated their Terms of Service to disallow scraping and similar activities:

3.2.3 Restrictions Against Misusing the Services.

(a)  No Scraping. Customer will not export, extract, or otherwise scrape Google Maps Content for use outside the Services. For example, Customer will not: (i) pre-fetch, index, store, reshare, or rehost Google Maps Content outside the services; (ii) bulk download Google Maps tiles, Street View images, geocodes, directions, distance matrix results, roads information, places information, elevation values, and time zone details; (iii) copy and save business names, addresses, or user reviews; or (iv) use Google Maps Content with text-to-speech services.

If I try to bulk download distance matrix results in R, I might violate these terms of service. Which means that the Google maps API is not a viable alternative if I need the distances and times from a lot postal codes to a certain location(s), to then calculate travel costs. (I would still recommend it for a small number of distances to be calculated)

Today I will explore an alternative: the OSRM package. OSRM stands for Open Source Routing Machine. It is free and open-source. It does exactly the same as the Google maps API: find distances from origin coordinates to a certain destination. We are also not allowed to scrape according to their terms of service, so it is a good idea to run codes with a small amount of requests from this server. The R package is called “osrm” and developed by Timothée Giraud et al.:

install.packages("osrm")
library(osrm)
library(sf)

In this blog post, I will show how it works with one simple example. Let me illustrate how to find the travel distance and time between the CAU University of Kiel (where I work) and a beach at Eckenforde (Südstrand Eckernförde).

In order to find distance between point A and B, I need the corresponding coordinates. Unlike the Google maps API, this package works with coordinates: first longitude and then latitude. The coordinates of the beach (destination) are: 54.449771, 9.856126 (latitude and longitude). The coordinates of the university (the origin) are: 54.341682, 10.121435.

The syntax of the code is pretty straightforward. “src” is a vector with the coordinates of the origin and “dst” is a vector containing the coordinates of the destination. The code should look something like this, wherein we use the function osrmRoute:

osrmRoute(src = c(10.121435, 54.341682), dst = c(9.856126, 54.449771),returnclass="sf")

The returnclass=”sf” object specifies how the result will look like (a linestring or a dataframe). The result itself does not change whether a linestring or a dataframe is specified. The result from running the code above looks like this:

> osrmRoute(src = c(10.121435, 54.341682), dst = c(9.856126, 54.449771),returnclass="sf")
Simple feature collection with 1 feature and 4 fields
Geometry type: LINESTRING
Dimension:     XY
Bounding box:  xmin: 9.85615 ymin: 54.34159 xmax: 10.12888 ymax: 54.44978
Geodetic CRS:  WGS 84
        src dst duration distance                       geometry
src_dst src dst    18.62  22.9713 LINESTRING (10.12148 54.341...

You can see in the bottom of the code that it takes almost 19 minutes and 23 kilometers to travel from my university to the beach of my choice. The default is to show distances (in kilometers) and times (in minutes) by driving, but other modes of transport can be specified.

I can also visualize the route using plot and st_geometry functions:

plot(st_geometry(osrmRoute(src = c(10.121435, 54.341682), dst = c(9.856126, 54.449771),returnclass="sf")))

Althought it is missing a base map, you can visualize the route of your choice.

After conducting my surveys, I usually have samples of individuals. Unless other type of information is given about the origin of the trip, I usually use the individuals’ residence postal codes as the trip’s origin and calculate distances and times to a (recreational) destination. To save time, I advise practitioners to include in a .csv or .xls file the list of postal codes with longitude and latitude from the sample, and then run the code by taking lines from this .csv or .xls file. For example, if I had the coordinates of each postal code in an object called data_CSV:

osrmRoute(src = data_CSV[1,], dst = c(9.856126, 54.449771),returnclass="sf")

Then I can estimate the distances and time from several postal codes to this beach in Eckenforde. If the end goal is to estimate a travel cost model, one could then use these distances and times to then calculate the travel cost variable.

This OSRM package might be a more viable option than its Google Maps counterpart. This code does not require any key or credential to work, whereas the Google maps API needs a key to be specified. However, I have noticed slight differences in the times and distances calculated with Google Maps and OSRM. Practitioners should be aware that there might be substantial differences and it is a good idea to double-check the results they get.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s