---
title: 'Intro to r5r: Rapid Realistic Routing with R5 in R'
author: "Rafael H. M. Pereira, Marcus Saraiva, Daniel Herszenhut, Carlos Kaue Braga"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
abstract: "`r5r` is an R package for rapid realistic routing on multimodal transport networks (walk, bike, public transport and car) using R<sup>5</sup>. The package allows users to generate detailed routing analysis or calculate travel time matrices using seamless parallel computing on top of the R<sup>5</sup> Java machine <https://github.com/conveyal/r5>"
urlcolor: blue
vignette: >
  %\VignetteIndexEntry{Intro to r5r: Rapid Realistic Routing with R5 in R} 
  %\VignetteEngine{knitr::rmarkdown} 
  \usepackage[utf8]{inputenc}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

# removes files created by 'setup_r5()'
data_path <- system.file("extdata/poa", package = "r5r")
existing_files <- list.files(data_path)
files_to_keep <- c(
  "poa_hexgrid.csv", 
  "poa_osm.pbf", 
  "poa_points_of_interest.csv", 
  "poa.zip"
)
files_to_remove <- existing_files[! existing_files %in% files_to_keep]
invisible(file.remove(file.path(data_path, files_to_remove)))
```

# Introduction 

**r5r** is an [R package for rapid realistic routing on multimodal transport networks](https://github.com/ipeaGIT/r5r) (walk, bike, public transport and car). It provides a simple and friendly interface to R<sup>5</sup>, a really fast and open source Java-based routing engine developed separately by [Conveyal](https://www.conveyal.com/). R<sup>5</sup> stands for [Rapid Realistic Routing on Real-world and Reimagined networks](https://github.com/conveyal/r5).



# Installation

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:

- [OpenJDK](http://jdk.java.net/java-se-ri/11)

- [Oracle](https://www.oracle.com/java/technologies/javase-jdk11-downloads.html)

You can install `r5r` from CRAN, or the development version from github.

```{r, eval = FALSE}
# CRAN
install.packages('r5r')

# github
devtools::install_github("ipeaGIT/r5r", subdir = "r-package")
```

# Usage

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:

```{r, message = FALSE, eval = FALSE}
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:

```{r, message = FALSE, warning = FALSE}
library(r5r)
library(sf)
library(data.table)
library(ggplot2)
library(mapview)
mapviewOptions(platform = 'leafgl')
```

The `r5r` package has 3 fundamental functions.

1. `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;

2. `travel_time_matrix()` for fast computation of travel time estimates between origin/destination pairs;

3. `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.

# Demonstration on sample data

## Data

To illustrate functionality, the package includes a small sample data for the city of Porto Alegre (Brazil). It includes four files:

* An Open Street Map network in `.pbf` format (*mandatory*);
* A public transport feed in `GTFS.zip` format;
* A *points of interest* file, in `.csv` format, containing the names and spatial coordinates of 15 places within Porto Alegre;
* The spatial coordinates of a regular hexagonal grid covering the sample area, in a `.csv` file, which can be used as origin/destination pairs in a travel time matrix calculation.


```{r}
data_path <- system.file("extdata/poa", package = "r5r")
list.files(data_path)
```

The points of interest data can be seen below.  In this example, we will be looking at transport alternatives between some of those places.

```{r}
poi <- fread(file.path(data_path, "poa_points_of_interest.csv"))
head(poi)
```

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.

```{r}
points <- fread(file.path(data_path, "poa_hexgrid.csv"))
points <- points[ c(sample(1:nrow(points), 10, replace=TRUE)), ]
head(points)
```

## Build routable transport network with `setup_r5()`

The first step is to build the multimodal transport network used for routing in R<sup>5</sup>. This is done with the `setup_r5` function. This function does two things: (1) downloads/updates a compiled JAR file of R<sup>5</sup> 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.

```{r, message = FALSE, eval = FALSE}
# Indicate the path where OSM and GTFS data are stored
r5r_core <- setup_r5(data_path = data_path, verbose = FALSE)
```

## Routing analysis

For fast routing analysis, **r5r** currently has two core functions: `travel_time_matrix` and `detailed_itineraries`.

### Fast many to many travel time matrix

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.

```{r, message = FALSE, eval = FALSE}
# set inputs
mode <- c("WALK", "TRANSIT")
max_walk_dist <- 5000
max_trip_duration <- 120
departure_datetime <- as.POSIXct("13-05-2019 14:00:00",
                                 format = "%d-%m-%Y %H:%M:%S")

# calculate a travel time matrix
ttm <- travel_time_matrix(r5r_core = r5r_core,
                          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)
```

```{r ttm head, echo=FALSE, message=FALSE, out.width='100%'}
knitr::include_graphics("https://github.com/ipeaGIT/r5r/blob/master/r-package/inst/img/vig_output_ttm.png?raw=true")
```


### Detailed itineraries

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.

```{r, message = FALSE, eval = FALSE}
# set inputs
origins <- poi[10,]
destinations <- poi[12,]
mode <- c("WALK", "TRANSIT")
max_walk_dist <- 10000
departure_datetime <- as.POSIXct("13-05-2019 14:00:00",
                                 format = "%d-%m-%Y %H:%M:%S")

# calculate detailed itineraries
dit <- detailed_itineraries(r5r_core = r5r_core,
                            origins = origins,
                            destinations = destinations,
                            mode = mode,
                            departure_datetime = departure_datetime,
                            max_walk_dist = max_walk_dist,
                            shortest_path = FALSE,
                            verbose = FALSE)

head(dit)
```
```{r detailed head, echo = FALSE, out.width='100%', message = FALSE}
knitr::include_graphics("https://github.com/ipeaGIT/r5r/blob/master/r-package/inst/img/vig_output_detailed.png?raw=true")
```

The output is a `data.frame sf` object, so we can easily visualize the results.

#### Visualize 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.

```{r, message = FALSE, eval = FALSE}
# extract OSM network
street_net <- street_network_to_sf(r5r_core)

# plot
ggplot() +
  geom_sf(data = street_net$edges, color='gray85') +
  geom_sf(data = dit, aes(color=mode)) +
  facet_wrap(.~option) + 
  theme_void()

```

```{r ggplot2 output, echo = FALSE, out.width='100%', message = FALSE}
knitr::include_graphics("https://github.com/ipeaGIT/r5r/blob/master/r-package/inst/img/vig_detailed_ggplot.png?raw=true")
```

**Interactive visualization** with `mapview`:

```{r, message = FALSE, eval = FALSE}
mapview(dit, zcol = 'option')
```

```{r mapview output, echo = FALSE, out.width='80%', message = FALSE}
knitr::include_graphics("https://github.com/ipeaGIT/r5r/blob/master/r-package/inst/img/vig_detailed_mapview.png?raw=true")
```

### Cleaning up after usage

`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:

```{r, message = FALSE, eval = FALSE}
stop_r5(r5r_core)
rJava::.jgc(R.gc = TRUE)
```

If you have any suggestions or want to report an error, please visit [the package GitHub page](https://github.com/ipeaGIT/r5r).
