Abstract
r5r
is an R package for rapid realistic routing on
multimodal transport networks (walk, bike, public transport and car)
using R5. The package allows users to generate detailed
routing analysis or calculate travel time matrices using seamless
parallel computing on top of the R5 Java machine https://github.com/conveyal/r5
r5r is an R package for rapid realistic routing on multimodal transport networks (walk, bike, public transport and car). It provides a simple and friendly interface to R5, a really fast and open source Java-based routing engine developed separately by Conveyal. R5 stands for Rapid Realistic Routing on Real-world and Reimagined networks.
To use r5r
, you need to have Java SE Development Kit
11 installed on your computer. No worries, you don’t have to pay
for it. The jdk 11 is freely available from the options below:
You can install r5r
from CRAN, or the development
version from github.
# CRAN
install.packages('r5r')
# github
::install_github("ipeaGIT/r5r", subdir = "r-package") devtools
Before we start, we need to increase the memory available to Java.
This is necessary because, by default, R
allocates only
512MB of memory for Java processes, which is not enough for large
queries using r5r
. To increase available memory to 2GB, for
example, we need to set the java.parameters
option at the
beginning of the script, as follows:
options(java.parameters = "-Xmx2G")
Note: It’s very important to allocate enough memory before attaching
r5r
or any other Java-based package, since
rJava
starts a Java Virtual Machine only once for each R
session. It might be useful to restart your R session and execute the
code above right after, if you notice that you haven’t succeeded in your
previous attempts.
Then we can load the packages used in this vignette:
library(r5r)
library(sf)
library(data.table)
library(ggplot2)
library(mapview)
mapviewOptions(platform = 'leafgl')
The r5r
package has 3 fundamental functions.
setup_r5()
to initialize an instance of
r5r
, that also builds a routable transport network given an
Open Street Map street network and public transport feeds in GTFS
format;
travel_time_matrix()
for fast computation of travel
time estimates between origin/destination pairs;
detailed_itineraries()
to get detailed information
on one or multiple alternative routes between origin/destination
pairs.
Let’s have a quick look at how these functions work using a sample data set.
To illustrate functionality, the package includes a small sample data for the city of Porto Alegre (Brazil). It includes four files:
.pbf
format
(mandatory);GTFS.zip
format;.csv
format,
containing the names and spatial coordinates of 15 places within Porto
Alegre;.csv
file, which can be used as
origin/destination pairs in a travel time matrix calculation.<- system.file("extdata/poa", package = "r5r")
data_path list.files(data_path)
#> [1] "poa.zip" "poa_hexgrid.csv"
#> [3] "poa_osm.pbf" "poa_points_of_interest.csv"
The points of interest data can be seen below. In this example, we will be looking at transport alternatives between some of those places.
<- fread(file.path(data_path, "poa_points_of_interest.csv"))
poi head(poi)
#> id lat lon
#> 1: public_market -30.02756 -51.22781
#> 2: bus_central_station -30.02329 -51.21886
#> 3: gasometer_museum -30.03404 -51.24095
#> 4: santa_casa_hospital -30.03043 -51.22240
#> 5: townhall -30.02800 -51.22865
#> 6: piratini_palace -30.03363 -51.23068
The data with origin destination pairs is shown below. In this example, we will be building a travel time matrix between ten random points in this data set.
<- fread(file.path(data_path, "poa_hexgrid.csv"))
points <- points[ c(sample(1:nrow(points), 10, replace=TRUE)), ]
points head(points)
#> id lon lat population schools
#> 1: 89a90128c2fffff -51.24280 -30.03831 0 0
#> 2: 89a9012ae6bffff -51.23225 -30.07804 159 0
#> 3: 89a9012857bffff -51.21075 -30.07295 760 0
#> 4: 89a90129d27ffff -51.20266 -30.02371 785 0
#> 5: 89a9012a153ffff -51.23039 -30.10731 617 0
#> 6: 89a901291afffff -51.16122 -30.05220 833 0
setup_r5()
The first step is to build the multimodal transport network used for
routing in R5. This is done with the setup_r5
function. This function does two things: (1) downloads/updates a
compiled JAR file of R5 and stores it locally in the
r5r
package directory for future use; and (2) combines the
osm.pbf and gtfs.zip data sets to build a routable network object.
# Indicate the path where OSM and GTFS data are stored
<- setup_r5(data_path = data_path, verbose = FALSE) r5r_core
For fast routing analysis, r5r currently has two
core functions: travel_time_matrix
and
detailed_itineraries
.
The travel_time_matrix
function is a really simple and
fast function to compute travel time estimates between one or multiple
origin/destination pairs. The origin/destination input can be either a
spatial sf POINT
object, or a data.frame
containing the columns id, lon, lat
. The function also
receives as inputs the max walking distance, in meters, and the
max trip duration, in minutes. Resulting travel times are also
output in minutes.
# set inputs
<- c("WALK", "TRANSIT")
mode <- 5000
max_walk_dist <- 120
max_trip_duration <- as.POSIXct("13-05-2019 14:00:00",
departure_datetime format = "%d-%m-%Y %H:%M:%S")
# calculate a travel time matrix
<- travel_time_matrix(r5r_core = r5r_core,
ttm origins = points,
destinations = points,
mode = mode,
departure_datetime = departure_datetime,
max_walk_dist = max_walk_dist,
max_trip_duration = max_trip_duration,
verbose = FALSE)
head(ttm)
Most routing packages only return the fastest route. A key advantage
of the detailed_itineraries
function is that is allows for
fast routing analysis while providing multiple alternative routes
between origin/destination pairs. The output also brings detailed
information for each route alternative at the trip segment level,
including the transport mode, waiting times, travel time and distance of
each trip segment.
In this example below, we want to know some alternative routes between one origin/destination pair only.
# set inputs
<- poi[10,]
origins <- poi[12,]
destinations <- c("WALK", "TRANSIT")
mode <- 10000
max_walk_dist <- as.POSIXct("13-05-2019 14:00:00",
departure_datetime format = "%d-%m-%Y %H:%M:%S")
# calculate detailed itineraries
<- detailed_itineraries(r5r_core = r5r_core,
dit origins = origins,
destinations = destinations,
mode = mode,
departure_datetime = departure_datetime,
max_walk_dist = max_walk_dist,
shortest_path = FALSE,
verbose = FALSE)
head(dit)
The output is a data.frame sf
object, so we can easily
visualize the results.
Static visualization with ggplot2
package: To provide a geographic context for the visualization of the
results in ggplot2
, you can also use the
street_network_to_sf
function to extract the OSM street
network used in the routing.
# extract OSM network
<- street_network_to_sf(r5r_core)
street_net
# plot
ggplot() +
geom_sf(data = street_net$edges, color='gray85') +
geom_sf(data = dit, aes(color=mode)) +
facet_wrap(.~option) +
theme_void()
Interactive visualization with
mapview
:
mapview(dit, zcol = 'option')
r5r
objects are still allocated to any amount of memory
previously set after they are done with their calculations. In order to
remove an existing r5r
object and reallocate the memory it
had been using, we use the stop_r5
function followed by a
call to Java’s garbage collector, as follows:
stop_r5(r5r_core)
::.jgc(R.gc = TRUE) rJava
If you have any suggestions or want to report an error, please visit the package GitHub page.