-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathREADME.Rmd
232 lines (173 loc) · 8.54 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "80%",
warning = NA
)
```
# traveltime
<!-- badges: start -->
[![traveltime status badge](https://idem-lab.r-universe.dev/badges/traveltime)](https://idem-lab.r-universe.dev/traveltime)
[![R-CMD-check](https://github.com/idem-lab/traveltime/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/idem-lab/traveltime/actions/workflows/R-CMD-check.yaml)
![GitHub License](https://img.shields.io/github/license/geryan/traveltime)
![GitHub commit activity](https://img.shields.io/github/commit-activity/w/geryan/traveltime)
![GitHub last commit](https://img.shields.io/github/last-commit/geryan/traveltime)
![GitHub commits since latest release](https://img.shields.io/github/commits-since/geryan/traveltime/latest)
[![Codecov test coverage](https://codecov.io/gh/idem-lab/traveltime/graph/badge.svg)](https://app.codecov.io/gh/idem-lab/traveltime)
[![Lifecycle: stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable)
<!-- badges: end -->
`traveltime` enables a user to create a map of travel time over an area of interest from a user-specified set of geographic coordinates and friction surface. The package provides convenient access to global friction surfaces for walking and motorised travel for the year 2020. The final result is a raster of the area of interest where the value in each cell is the lowest travel time in minutes to any of the specified locations.
![Walking travel time from rail transport in Singapore](man/figures/README-fig-result-1.png){width=60% fig-align="right"}
## Installation
``` r
install.packages("traveltime", repos = c("https://idem-lab.r-universe.dev"))
```
or
```r
remotes::install_github("idem-lab/traveltime")
```
## Documentation
### Website
<https://idem-lab.github.io/traveltime/>
### Paper
Ryan, G.E., Tierney, N., Golding, N., and Weiss, D.J (2025). [traveltime: an R package to calculate travel time across a landscape from user-specified locations](https://doi.org/10.31223/X56M74){target="_blank"}. **EarthArXiv** 10.31223/X56M74
## What does this thing do?
The `traveltime` workflow starts with:
- a set of points you are interested in,
and either
- you supply a friction surface for the area you are interested in, or
- you supply your area of interest and use `get_friction_surface` to retrieve a pre-prepared walking or motorised travel friction surface from Weiss et al. (2020) [^1] --- this will probably be the case in most applications.
Then, running `calculate_travel_time` produces a raster as a `terra` `SpatRaster` with the travel time to the (temporally) nearest of the supplied points over the area of interest.
### A practical example: walking from public transport in Singapore
Here we will calculate the walking travel time from the nearest mass transit station across the island nation of Singapore --- specifically Mass Rapid Transit (MRT) and Light Rail Transit (LRT) stations --- and create a map of this.
#### Prepare the data
For this exercise, we need two items of data:
- our points to calculate travel time from --- here the locations of Singapore's MRT and LRT stations, and
- our area of interest --- in this case a map of Singapore.
##### Points
Our points of interest will be the `stations` data set included in `traveltime`; a 563 row, 2 column `matrix` containing the longitude (`x`) and latitude (`y`) of all LRT and MRT station exits in Singapore from [^2]:
```{r}
#| label: show-stations
library(traveltime)
head(stations)
```
##### Area of interest
To obtain our area of interest, we download a national-level polygon boundary of Singapore using the `geodata` package. Here we download only the national boundary (`level = 0`) at a low resolution (`resolution = 2`). Our boundary `singapore_shapefile` is a `SpatVector` class object from the package `terra`.
```{r}
#| label: get-basemap
library(terra)
library(geodata)
singapore_shapefile <- gadm(
country = "Singapore",
level = 0,
path = tempdir(),
resolution = 2
)
singapore_shapefile
```
##### Friction surface
Now that we have the two items of data that we require initially, the next step is to prepare a friction surface for our area of interest.
We will use the friction surface from Weiss et al (2020) that can be downloaded by `traveltime` with the function `get_friction_surface()`. This function takes extents in a variety of formats and returns the surface for that extent only.
We can pass in our basemap `singapore_shapefile`, a `SpatVector`, directly as the `extent`. We're interested in walking time from a station, so we'll download the walking friction surface by specifying `surface = "walk2020"`.
(Alternatively, we could use `surface = "motor2020"` for motorised travel).
We're only interested in walking *on land*, so we then mask out areas outside of the land boundary of `singapore_shapefile`:
```{r}
#| label: download-friction-surface
#| echo: true
#| output: false
friction_singapore <- get_friction_surface(
surface = "walk2020",
extent = singapore_shapefile
)|>
mask(singapore_shapefile)
```
Thus we have our friction surface as a `SpatRaster`:
```{r }
#| label: show-friction-surface-raster
#| echo: true
friction_singapore
```
##### Input data
Below we plot the friction surface raster `friction_singapore`, with the vector boundary `singapore_shapefile` as a grey line, and `stations` as grey points. `traveltime` takes resistance values of friction (see paper for more details), so higher values of friction indicate more time travelling across a given cell.
```{r}
#| label: fig-data
#| echo: true
#| fig-cap: "Friction surface raster of Singapore, showing Singapore boundary
#| in grey, and station locations as grey points."
library(tidyterra)
library(ggplot2)
ggplot() +
geom_spatraster(
data = friction_singapore
) +
geom_spatvector(
data = singapore_shapefile,
fill = "transparent",
col = "grey50"
) +
geom_point(
data = stations,
aes(
x = x,
y = y
),
col = "grey60",
size = 0.5
) +
scale_fill_viridis_c(
option = "A",
na.value = "transparent",
direction = -1
) +
labs(
fill = "Resistance",
x = element_blank(),
y = element_blank()
) +
theme_minimal()
```
#### Calculate travel time
With all the data collected, the function `calculate_travel_time()` takes the friction surface `friction_singapore` and the points of interest in `stations`, and returns a `SpatRaster` of walking time in minutes to each cell from the nearest station:
```{r}
#| label: calculate-result
#| echo: true
trave_time_singapore <- calculate_travel_time(
friction_surface = friction_singapore,
points = stations
)
trave_time_singapore
```
##### Plot results
We present the resulting calculated travel times below where (as expected) the travel times are lowest near station exits and progressively higher further away. Note that the results in `trave_time_singapore` include infinite values (`Inf` above). The islands to the south and north-east are shown as filled cells in the figure above, i.e., they are not masked out by `singapore_shapefile`. But because those islands they are not connected to any cells with a station, the calculated travel time is infinite, and so these cells do not appear in the figure below.
```{r}
#| label: fig-result
#| echo: true
#| fig-cap: "Map of walking travel time in Singapore, in minutes from
#| nearest MRT or LRT station."
ggplot() +
geom_spatraster(
data = trave_time_singapore
) +
scale_fill_viridis_c(
option = "A",
direction = -1,
na.value = "transparent"
) +
theme_minimal() +
labs(fill = "Minutes") +
geom_spatvector(
data = singapore_shapefile,
fill = "transparent",
col = "grey20"
)
```
[^1]: D. J. Weiss, A. Nelson, C. A. Vargas-Ruiz, K. Gligoric, S., Bavadekar, E. Gabrilovich, A. Bertozzi-Villa, J. Rozier, H. S. Gibson, T., Shekel, C. Kamath, A. Lieber, K. Schulman, Y. Shao, V. Qarkaxhija, A. K. Nandi, S. H. Keddie, S. Rumisha, P. Amratia, R. Arambepola, E. G. Chestnutt, J. J. Millar, T. L. Symons, E. Cameron, K. E. Battle, S. Bhatt, and P. W. Gething. Global maps of travel time to healthcare facilities. (2020) Nature Medicine. <https://doi.org/10.1038/s41591-020-1059-1>
[^2]: Land Transport Authority. (2019). LTA MRT Station Exit (GEOJSON) (2024)
[Dataset]. data.gov.sg. Retrieved December 10, 2024 from
<https://data.gov.sg/datasets/d_b39d3a0871985372d7e1637193335da5/view>.