r5r’s routing and accessibility functions are very
fast, but they return only the essential information, and only the
optimal route (minimizing travel time and/or monetary cost). Sometimes,
though, we would like to do more simple route planning analysis and
extract more information for each route. Also, we might be interested in
finding not only the fastest route but some other suboptimal route
alternatives too. This is where the detailed_itineraries()
function comes in. detailed_itineraries() returns, for each
origin/destination pair, a detailed route plan per leg, i.e. a part of
the trip on a single mode, such as walking to the bus stop (R5’s
documentation calls legs ‘segments’). Each leg has its mode, waiting
time, travel time, distance and geometry. The function can also return
suboptimal route alternatives.
obs. Use detailed_itineraries() only if
you need suboptimal alternative routes and/or route geometries. For
route information by trip segment alone, we strongly recommend
expanded_travel_time_matrix().
build_network()We use the Porto Alegre (Brazil) sample data included in
r5r.
# increase Java memory
options(java.parameters = "-Xmx2G")
# load libraries
library(r5r)
library(sf)
library(ggplot2)
library(data.table)
# build a routable transport network with r5r
data_path <- system.file("extdata/poa", package = "r5r")
r5r_network <- build_network(data_path)
# routing inputs
mode <- c('walk', 'transit')
max_trip_duration <- 60 # minutes
# departure time
departure_datetime <- as.POSIXct("13-05-2019 14:00:00",
format = "%d-%m-%Y %H:%M:%S")
# load origin/destination points
poi <- fread(file.path(data_path, "poa_points_of_interest.csv"))To get alternative routes between one origin/destination pair, set
shortest_path = FALSE. With
suboptimal_minutes = 8, r5r also keeps routes
arriving up to 8 minutes after the optimal one.
# set inputs
origins <- poi[10,]
destinations <- poi[12,]
mode <- c("WALK", "TRANSIT")
max_walk_time <- 60
departure_datetime <- as.POSIXct("13-05-2019 14:00:00",
format = "%d-%m-%Y %H:%M:%S")
# calculate detailed itineraries
det <- detailed_itineraries(
r5r_network,
origins = origins,
destinations = destinations,
mode = mode,
departure_datetime = departure_datetime,
max_walk_time = max_walk_time,
suboptimal_minutes = 8,
shortest_path = FALSE
)
head(det)The output is an sf data.frame, ready to map.
street_network_to_sf() extracts the OSM street network
used in routing, to give the map geographic context:
# extract OSM network
street_net <- r5r::street_network_to_sf(r5r_network)
# extract public transport network
transit_net <- r5r::transit_network_to_sf(r5r_network)
# plot
fig <- ggplot() +
geom_sf(data = street_net$edges, color='gray85') +
geom_sf(data = subset(det, option <4), aes(color=mode)) +
facet_wrap(.~option) +
theme_void()
figdetailed_itineraries() routes the 1st origin to the 1st
destination, the 2nd to the 2nd, and so on. Set
all_to_all = TRUE to route every origin to every
destination.drop_geometry = TRUE
to return results without the trip geometry. This makes the function
faster.detailed_itineraries() does not work with
frequency-based GTFS feeds. The workaround is to convert frequencies to
timetables with the gtfstools
package:
library(gtfstools)
# location of your frequency-based GTFS
freq_gtfs_file <- system.file("extdata/spo/spo.zip", package = "r5r")
# read GTFS data
freq_gtfs <- gtfstools::read_gtfs(freq_gtfs_file)
# convert from frequencies to time tables
stop_times_gtfs <- gtfstools::frequencies_to_stop_times(freq_gtfs)
# save it as a new GTFS.zip file
gtfstools::write_gtfs(gtfs = stop_times_gtfs,
path = tempfile(pattern = 'stop_times_gtfs', fileext = '.zip'))write_gtfs() saves the new feed to the path
you give it (a temporary file above). Put that file in your
data_path, in place of the frequency-based feed, and build
the network.
Stop the network and run Java’s garbage collector to free the memory it used:
If you have any suggestions or want to report an error, please visit the package GitHub page.