| build_graph | R Documentation |
Builds a frequency-based transit network from the trips that depart within
a time of day, and returns it as a set of tables in the General Modeling
Network Specification (GMNS) format or as an {igraph} or {tidygraph}
graph. The network can be used in transit assignment models and in graph
analyses, such as finding the shortest travel times between stops.
build_graph(
gtfs,
from,
to,
format = "gmns",
max_walk_dist = 300,
walk_speed = 5
)
gtfs |
A GTFS object, as created by |
from |
A string. The starting point of the time of day, in the "HH:MM:SS" format. |
to |
A string. The ending point of the time of day, in the "HH:MM:SS"
format. Must be later than |
format |
A string. The format of the graph: |
max_walk_dist |
A number. The maximum great-circle distance, in meters, between two stops connected by walking transfer links. Defaults to 300. |
walk_speed |
A number. The walking speed, in km/h, used to calculate the travel time of transfer links. Defaults to 5. |
With format = "gmns", a list with the data.tables node, link
and config, named after the GMNS files. With format = "igraph", a
directed igraph graph, and with format = "tidygraph", a directed
tbl_graph. Their vertices and edges have the columns of the node and
link tables as attributes, and the name of each vertex is its
node_id, as a string.
Nodes (node_type) are "stop" nodes, one per stop visited by the trips,
at the stop's coordinates, and "service" nodes, one per route and
direction at each of its stops, at the coordinates of the stop (their
parent_node_id). Links (link_type) are all directed:
"in_vehicle" links connect the service nodes of consecutive stops of
the trips. travel_time is the mean time from the departure at a stop to
the arrival at the next, over the trips with both times (decreasing times
are not used), weighted by their departures. departures is the number
of departures of the trips of the network that run through the link.
length is the great-circle distance between the stops, as in
get_stop_distances(), and free_speed the length divided by the travel
time (NA when the travel time is 0 or either is missing).
"boarding" links connect each stop to the service nodes from which
trips depart. departures is the number of departures from the stop of
the trips of the network, so it may include departures after to from
stops far along their routes. travel_time is half the mean headway (the
length of the time of day divided by departures).
"alighting" links connect each service node back to its stop, with a
travel_time of 0.
"transfer" links connect, in both directions, the stops at most
max_walk_dist apart. travel_time is the length divided by
walk_speed, which is also their free_speed.
Lengths are in meters, travel times in minutes and speeds in km/h.
Boarding and alighting links have a length of 0 and an NA free_speed;
alighting and transfer links have NA departures. route_id,
direction_id and inferred_direction are those of the link's service
node, and NA in transfer links.
The network includes the trips that depart from their first stop at or
after from and before to, as in get_route_frequency(), so trips
already running at from are not included. Trips listed in frequencies
are included once per departure generated within the time of day, with
their stop_times entries as templates. Trips without stop_times entries
are not included. The trips of every service_id are pooled, so the feed
should usually be filtered to a single day first, with filter_by_date()
or filter_by_weekday(). Departures after midnight have times past
"24:00:00", so use a time of day such as "24:00:00"-"26:00:00" for them.
Trips whose times wrongly go back to "00:00:00" after midnight are placed
by their earliest time.
Within a trip, consecutive stop_times entries at the same stop are one
visit, arriving at their first known time and departing at their last. A
trip that visits a stop more than once uses a different service node at
each visit (visit 1, 2, ...).
Directions come from the direction_id field of trips. Trips without it
(or with a blank direction_id) get an inferred_direction instead: trips
of a route that share a pair of consecutive stops, in the same order, are
in the same direction, and so are trips that share pairs with them. The
opposite directions of routes that share a pair of stops in the same order
(e.g. through a one-way loop or street) are thus inferred as a single
direction. Trips with a blank direction_id are never assigned the
direction of other trips of their route.
In-vehicle links whose trips all have blank or decreasing times have an
NA travel_time, with a warning; igraph::distances() doesn't accept it
as a weight, and blank times can be filled beforehand with
interpolate_stop_times(). Alighting links, in-vehicle links between stops
with the same times and transfer links between stops at the same
coordinates have a travel time of 0; igraph::closeness() and
igraph::betweenness() require positive weights.
Departures are counted at every visit but the last of each trip, even with
a blank departure time, unlike in get_stop_frequency(). The transfers
and pathways tables, parent_stations and the pickup_type and
drop_off_type fields are not used. Large values of max_walk_dist in
dense feeds raise a warning when comparing the pairs of stops may use a lot
of memory, or an error when there are too many pairs. Transfer links are
not created across the antimeridian.
In the GMNS format, node_id, x_coord, y_coord, node_type,
parent_node_id, link_id, from_node_id, to_node_id, directed,
length and free_speed are GMNS fields; the other columns are additional
fields, as allowed by GMNS. config lists the units, the coordinate
reference system (EPSG:4326), the GMNS version (0.96) and the time of day.
Stops not listed in stops or without coordinates have NA coordinates,
with a warning (GMNS requires them). Free speeds may exceed the 200 km/h
maximum checked by GMNS validators.
The "Building transit network graphs" vignette
(vignette("graphs", package = "gtfstools")), which shows how to
analyse and plot the network with {igraph}, {tidygraph},
{sfnetworks} and {ggraph}.
data_path <- system.file("extdata/spo_gtfs.zip", package = "gtfstools")
gtfs <- read_gtfs(data_path)
# the services of every day are pooled together, so only the services of a
# single weekday are kept
gtfs <- filter_by_weekday(gtfs, "wednesday")
graph <- build_graph(gtfs, from = "07:00:00", to = "08:00:00")
names(graph)
head(graph$node)
head(graph$link)
# the tables can be written to the csv files of a GMNS network
gmns_dir <- tempfile("gmns")
dir.create(gmns_dir)
for (table in names(graph)) {
gmns_file <- file.path(gmns_dir, paste0(table, ".csv"))
data.table::fwrite(graph[[table]], gmns_file)
}
list.files(gmns_dir)
# the shortest travel times, in minutes, from a stop to the other stops
graph <- build_graph(
gtfs,
from = "07:00:00",
to = "08:00:00",
format = "igraph"
)
stop_nodes <- igraph::V(graph)[igraph::V(graph)$node_type == "stop"]
travel_times <- igraph::distances(
graph,
v = stop_nodes[1],
to = stop_nodes,
mode = "out",
weights = igraph::E(graph)$travel_time
)
# stops that can't be reached have an infinite travel time
is_reachable <- is.finite(travel_times)
sum(is_reachable)
summary(travel_times[is_reachable])
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.