| Title: | Reconstruct and Visualize Transit Vehicle Trajectories |
| Version: | 1.0.0 |
| Date: | 2026-08-11 |
| Description: | Today's public transit vehicles produce a large amount of automatic vehicle location (AVL) data. This data is very useful for planning and performance studies, but can be noisy, error-prone, and sparse. This package provides tools for cleaning AVL point data and turning it into continuous, differentiable, monotonic, and invertible vehicle trajectory functions, based on the work of Robbennolt et al. (2025) <doi:10.48550/arXiv.2509.00119> and Huang et al. (2023) <doi:10.1109/ITSC57777.2023.10422524>. |
| License: | GPL (≥ 3) |
| Encoding: | UTF-8 |
| RoxygenNote: | 7.3.3 |
| URL: | https://utel-uiuc.github.io/transittraj/ |
| BugReports: | https://github.com/UTEL-UIUC/transittraj/issues |
| Imports: | data.table, dplyr, gganimate, ggnewscale, ggplot2, ggspatial, hms, ivs, leaflet, magrittr, purrr, rlang, sf, slider, tidyr, tidytransit, viridis |
| Depends: | R (≥ 3.5) |
| LazyData: | true |
| Suggests: | knitr, prettymapr, rmarkdown, spelling, testthat (≥ 3.0.0) |
| VignetteBuilder: | knitr |
| Config/Needs/website: | rmarkdown, vembedr |
| Config/testthat/edition: | 3 |
| Language: | en-US |
| NeedsCompilation: | no |
| Packaged: | 2026-08-21 16:20:22 UTC; obrie |
| Author: | Benjamin O'Brien [aut, cre, cph], Lewis Lehe [aut] |
| Maintainer: | Benjamin O'Brien <obrienbenjaminj@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-08-31 14:00:02 UTC |
Pipe operator
Description
See magrittr::%>% for details.
Usage
lhs %>% rhs
Arguments
lhs |
A value or the magrittr placeholder. |
rhs |
A function call using the magrittr semantics. |
Value
The result of calling rhs(lhs).
Filter out entire trips which do not meet distance or duration requirements
Description
This function identifies trips that do not meet some acceptable duration and distance traveled ranges, or that have large time or distance gaps in the middle. Violating trips are removed.
Usage
clean_incomplete_trips(
distance_df,
max_trip_distance = Inf,
min_trip_distance = -Inf,
max_trip_duration = Inf,
min_trip_duration = -Inf,
max_distance_gap = Inf,
max_time_gap = Inf,
return_removals = FALSE
)
Arguments
distance_df |
A dataframe of linearized AVL data. Must include
|
max_trip_distance |
Optional. The maximum distance traveled over one
trip, in units of input |
min_trip_distance |
Optional. The minimum distance traveled over one
trip, in units of input |
max_trip_duration |
Optional. The maximum duration
of one trip, in seconds. Default is |
min_trip_duration |
Optional. The minimum duration
of one trip, in seconds. Default is |
max_distance_gap |
Optional. The maximum change in distance between two
observations, in units of input |
max_time_gap |
Optional. The maximum time between two observations, in
seconds. Default is |
return_removals |
Optional. A boolean, should the function return
a dataframe of trips removed and why? Default is |
Value
The input distance_df, with violating trips removed.
If return_removals = TRUE, a dataframe of trips removed and why.
Examples
# Set my parameters
my_min_dist <- 1000
my_max_gap <- 1000
# Get input data
lineE_no_jumps <- new_transittraj_data("clean_jumps")
dim(lineE_no_jumps)
# Run function
lineE_clean_trips <- clean_incomplete_trips(distance_df = lineE_no_jumps,
min_trip_distance = my_min_dist,
max_distance_gap = my_max_gap)
dim(lineE_clean_trips)
head(lineE_clean_trips)
Apply median filters to detect large jumps (i.e., outliers) in trajectories.
Description
Noise in GPS trajectories can manifest itself as one or more points lying far
away from points recorded at a similar time. This function identifies these
points using median filters. By default, outliers are removed. See Details
for a discussion of removal methodologies.
Usage
clean_jumps(
distance_df,
neighborhood_width = 7,
t_cutoff = 3,
min_median_deviation = -Inf,
max_median_deviation = Inf,
evaluate_tails = FALSE,
evaluate_implosions = FALSE,
replace_outliers = FALSE,
return_removals = FALSE
)
Arguments
distance_df |
A dataframe of linearized AVL data. Must include
|
neighborhood_width |
Optional. An integer representing the total sliding window width around each observation. Default is 7 (3 on either side). |
t_cutoff |
Optional. For Hampel filters, number of standardized MADs away to consider an outlier. Default is 3. |
min_median_deviation |
Optional. A numeric, the minimum allowed
deviation of an observation from its window median, in units of distance.
Default is |
max_median_deviation |
Optional. A numeric, the maximum allowed
deviation of an observation from its window median, in units of distance.
Default is |
evaluate_tails |
Optional. A boolean, should the beginning and ending
observations, before a complete window can be formed, be evaluated? Default
is |
evaluate_implosions |
Optional. A boolean, should points in implosion
sequences be evaluated? "Implosions" occur when more than half of a window is
constant. Default is |
replace_outliers |
Optional. A boolean, should points identified as
outliers be replaced by their window median? Default is |
return_removals |
Optional. A boolean, should the function return
a dataframe of points removed and why? Default is |
Details
There are many different types of median filters. In general, these filters
create a sliding window around each point (here, controlled by
neighborhood_width) and treats a point based on its deviation from the
median of that window. This function supports two main ways of classifying
outliers based on their deviation:
Raw deviation:
min_median_deviationandmax_median_deviationset bounds for an acceptable deviation between a point and the median of the window around it, in units of the inputdistancecolumn.Hampel filter: Uses the median absolute deviation (MAD), the median of deviations from the median. With a conversion factor (
s = 1.48), this is analogous to a standard error. Thet_cutoff, then, is analogous to an acceptable window oftvalues.
Both of these can be used at the same time. If multiple criteria are set, a point will be removed if it violates any criterion.
A Hampel filter is generally considered highly robust, and is the recommended approach. There are, however, two main limitations to be aware of:
It can struggle at the beginnings and ends of trips, before a complete window can be formed. Use
evaluate_tailsto skip these.When more than hald of a window has the same value, the MAD is 0 and an observation is guaranteed to be flagged as an outlier. This is known as an "implosion". As we expect noise in GPS data, even when a vehicle is standing still, this is unlikely. It can occur, however, near trip terminals, where many GPS points snap to the exact same point on the route alignment. Use
evaluate_implosionsto identify and skip points in an implosion.
Once a point has been identified as an outlier, there are two possible
treatments, controlled by replace_outliers:
Replacement with the window median. This is the most common approach to median filters, but is likely not appropriate for AVL data. Replacement may introduce non-monotonicities.
Removal of the point. This is a less common approach, but may be a more sensible for this application, given that interpolating curves will be fit later in the cleaning process.
Value
The input distance_df with violating points removed. If
return_removals = TRUE, a dataframe with observations removed and why.
References
Pearson, Ronald K., Yrjö Neuvo, Jaakko Astola, and Moncef Gabbouj. 2016. “Generalized Hampel Filters.” EURASIP Journal on Advances in Signal Processing 2016 (1): 87. https://doi.org/10.1186/s13634-016-0383-6.
Examples
# Set my parameters
my_cutoff = 2.5
my_neighborhood = 9
# Get input data
lineE_no_overlaps <- new_transittraj_data("clean_overlapping_subtrips")
dim(lineE_no_overlaps)
# Run function
lineE_no_jumps <- clean_jumps(distance_df = lineE_no_overlaps,
neighborhood_width = my_neighborhood,
t_cutoff = my_cutoff)
dim(lineE_no_jumps)
head(lineE_no_jumps)
Remove trips with multiple operators or vehicles assigned to the same trip ID
Description
In some AVL systems, multiple vehicles or operators may be logged to the same trip ID at the same time. This may be acceptable in some scenarios (e.g., a vehicle/operator tradeoff mid-trip). Other times, it may be an error, with these distinct (trip, vehicle, operator) truples running simulataneously. This function identifies both scenarios, and gives the option to remove either.
Usage
clean_overlapping_subtrips(
distance_df,
check_operator = FALSE,
remove_single_observations = TRUE,
remove_non_overlapping = FALSE,
return_removals = FALSE
)
Arguments
distance_df |
A dataframe of linearized AVL data. Must include
|
check_operator |
Optional. A boolean, should the function check for
overlaps of multiple |
remove_single_observations |
Optional. A boolean, should subtrips with
only one observation be removed? Default is |
remove_non_overlapping |
Optional. A boolean, should trips with multiple
vehicles or operators that do not overlap be removed? Default is |
return_removals |
Optional. A boolean, should the function return a
dataframe of trips removed and why? Default is |
Value
The input distance_df, with violating trips removed. If
return_removals = TRUE, a dataframe with trip IDs removed and why.
Examples
# Get input data
lineE_dists <- new_transittraj_data("get_linear_distances")
dim(lineE_dists)
# Run function
lineE_no_overlaps <- clean_overlapping_subtrips(distance_df = lineE_dists)
dim(lineE_no_overlaps)
head(lineE_no_overlaps)
Corrects speeds to Fristch-Carlson constraints, recursively.
Description
Internal function. Not intended for external use.
Usage
correct_speeds_fun(m_0, deltas)
Arguments
m_0 |
A numeric vector of initial slopes (observed velocities) |
deltas |
A numeric vector of initial FC delta values |
Value
A numeric vector of m_0 adjusted to FC constraints
Save an animation at a desired quality
Description
This function is a helepr for gganimate's anim_save(), providing a
simplified, though less feature-rich, version of these functions. Animations
are saved as .gifs at the desired path. With this function,
publication-quality (high-resolution and smooth) animations are possible,
but take a long time to render.
Usage
export_animation(
anim_object,
path,
duration = 30,
fps = 10,
width = 7.5,
height = 5.5,
dpi = 100
)
Arguments
anim_object |
A |
path |
A string representing the desired path and name at which to save animation. |
duration |
Optional. A numeric, in seconds, representing the length of
the animation. Default is |
fps |
Optional. The frames per second of the saved animation. Default
is |
width |
Optional. The width of the exported image, in inches. Default
is |
height |
Optional. The height of the exported image, in inches. Default
is |
dpi |
Optional. The resolution, in dots per inch, of the image. Default
is |
Value
File saved to the desired directory.
Examples
lineE_traj <- new_transittraj_data("get_trajectory_fun")
# Set my parameters
my_features <- data.frame(name = c("Metro Center"),
distance = c(24556))
my_dist_range <- c(24000, 25000)
# Create `gganimate` object
anim_line <- plot_animated_line(trajectory = lineE_traj,
feature_distances = my_features,
route_color = "firebrick4",
label_field = "name",
label_alpha = 0.8,
label_pos = "right",
distance_lims = my_dist_range,
center_vehicles = TRUE,
timestep = 1)
# Create a place to store your file
my_file_name <- tempfile("my_animation", fileext = ".gif")
print(my_file_name)
# Run function: save animation locally
if (interactive()) {
# Note: Due to long processing times, animations will only be rendered &
# displayed if run during an interactive session. See `example()`.
export_animation(anim_object = anim_line,
path = my_file_name,
width = 4, height = 8, dpi = 150,
fps = 10, duration = 10)
}
Filter GTFS to a desired route(s) and direction(s)
Description
This function returns a new tidygtfs object with only the information
relevant to your desired routes and directions. All fields included in the
input gtfs will be filtered. See Details for more information about
required files and fields
Usage
filter_by_route(gtfs, route_ids, dir_id = NULL)
Arguments
gtfs |
A |
route_ids |
A vector containing the desired route ID(s). |
dir_id |
Optional. A vector containing the desired direction ID(s). |
Details
The following files and fields are required for this function:
-
routes: withroute_idandagency_id -
agency: withagency_id -
trips: withroute_id,direction_id,shape_id,service_id, andtrip_id -
stop_times: withstop_idandtrip_id
The following files are optional. If included, they must include the listed fields:
-
stops: withstop_id -
shapes: withshape_id -
calendar: withservice_id -
calendar_dates: withservice_id -
transfers: withtrip_idandstop_id -
frequencies: withtrip_id -
fare_rules: withroute_id -
feed_info
For these optional files, the function will detect whether they are present.
If so, they will be filtered; if not, they will be left NULL in the new
GTFS. If any required file or field is missing, an error will be thrown
describing what is missing.
Value
A tidygtfs object containing only information relevant to the desired route and direction.
Examples
# Set my parameters
my_route <- "804"
my_dir <- 0
# Filter WMATA GTFS
lineE_gtfs <- filter_by_route(gtfs = lacmta_gtfs,
route_ids = my_route,
dir_id = my_dir)
summary(lineE_gtfs)
Get a dataframe of all service dates and their service IDs from a GTFS
Description
This function returns a dataframe with each date covered by a GTFS and the
service_id run on that date. This data is extracted from the calendar.txt
and calendar_dates.txt files, depending on how the GTFS is structured. See
Details for a discussion.
Usage
get_gtfs_service_dates(
gtfs,
date_min = NULL,
date_max = NULL,
use_calendar_table = "calendar"
)
Arguments
gtfs |
A tidygtfs object. |
date_min |
Optional. The starting (earliest possible) |
date_max |
Optional. The ending (latest possible) |
use_calendar_table |
Optional. Should the GTFS's |
Details
The GTFS standard allows for two different structurings of calendar.txt
and calendar_dates.txt:
Standard service in
calendar.txt, with exceptions incalendar_dates.txt. Here,calendar.txtwill list the standard service ID by weekday (e.g., Monday, Tuesday, etc.), andcalendar_dates.txtlists specific dates which are exceptions to this. In this scenario,get_gtfs_service_dates()will get enumerate all weekdays and dates incalendar.txt, and assign the correctservice_idto it, depending on if the date is listed as an exception incalendar_dates.txt.All dates of service are enumerated in
calendar_dates.txt, andcalendar.txtis not used. In this scenario,get_gtfs_service_dates()will simply filter, clean, and return this table.
Use the input parameter use_calendar_table to control which method to use.
If use_calendar_table = "calendar", the former method will be used; if
use_calendar_table = "calendar_dates", the latter will be used. To
restrict the date enumeration to only a specific window, set date_min
and date_max.
This function is also intended for GTFS feeds with only one service ID per
day. Some GTFS providers (including lacmta_gtfs) have unique service_ids
by route, and thus service dates do not have unique service_ids.
Consider filtering your GTFS to a single route before using this function
(see filter_by_route()). If there are multiple service IDs on a given
day, the first appearing will be returned.
Value
A dataframe with Date column date and character column
service_id.
Examples
# Set parameters
study_date <- as.Date("2026-05-27")
# Get needed input data
lineE_gtfs <- filter_by_route(gtfs = lacmta_gtfs, route_ids = "804",
dir_id = 0)
# Run function: get service ID by day in date range
study_service_ids <- get_gtfs_service_dates(gtfs = lineE_gtfs,
date_min = study_date,
date_max = study_date,
use_calendar_table = "calendar")
print(study_service_ids)
Fit continuous trajectory interpolating curves from GTFS schedule data
Description
This function fits a continuous vehicle trajectory function to scheduled GTFS
stop_times. This function
operates as a "function factory", returning a function (closure) which
takes a timestamp and returns each trip's position. A separate curve is
fit for each trip, and stored in a special trajectory object class.
The default interpolating method is linear, but
spline-based techniques are also supported. See Details for a discussion.
Usage
get_gtfs_trajectory_fun(
gtfs,
shape_geometry = NULL,
project_crs = 4326,
date_min = NULL,
date_max = NULL,
use_calendar_table = "calendar",
agency_timezone = NULL,
use_stop_time = "departure",
add_stop_dwell = 0,
add_distance_error = 0,
interp_method = "linear",
find_inverse_function = TRUE,
return_group_function = TRUE,
inv_tol = 0.01
)
Arguments
gtfs |
A |
shape_geometry |
Optional. The SF object to project onto. Must include
the field |
project_crs |
Optional. A numeric EPSG identifer indicating the coordinate system to use for spatial calculations. Consider setting to a Euclidian projection, such as the appropriate UTM zone. Default is 4326 (WGS 84 ellipsoid). |
date_min |
Optional. The starting (earliest possible) |
date_max |
Optional. The ending (latest possible) |
use_calendar_table |
Optional. Should the GTFS's |
agency_timezone |
Optional. A timezone string (see |
use_stop_time |
Optional. A string, which stop time column should be
used for the timepoint? Must be one of |
add_stop_dwell |
Optional. A numeric. If |
add_distance_error |
Optional. If non-zero, each "flat" observation will
be adjusted by this amount forwards, in units of input |
interp_method |
Optional. The type of interpolation function to be fit.
Either |
find_inverse_function |
Optional. A boolean, should the numeric inverse
function (time ~ distance) be calculated? Default is |
return_group_function |
Optional. A boolean, should the returned
trajectory object be grouped into a single function? If FALSE, will return a
list (indexed by |
inv_tol |
Optional. A numeric in the units of input |
Details
Stops, Dwells, and Monotonicity
To fit an interpolating trajectory function, each observation must include
distance and timestamp pairs throughout each trip. While stop_times does
include a shape_dist_traveled field, this is optional and often left
empty by agencies. Additionally, small distortions in spatial projections
mean that projected GPS points may not align perfectly with the agency's
calculated shape_dist_traveled. As such, this function uses
get_stop_distances() to get the distance of each stop along each shape for
each trip. Alternatively, all stops and trips can be referenced to the
same spatial feature using shape_geometry. Consider setting project_crs
to the same spatial projection used to linearize AVL GPS points.
The trajectory functions are fit using the times a trip is scheduled to
serve each stop. There is some ambiguity here: should a stop's timestamp
be when the vehicle arrives, or departs? This can be controlled using
use_stop_time, set to "departure" for departure_time, "arrival" for
arrival_time, or "both" to include both departure_time and
arrival_time as distinct observations (i.e., distance & timestamp pairs).
Often times, however, a GTFS schedule will not have different arrival_time
and departure_time values, especially if the timetable was not developed
considering stop-level dwell times. In this scenario, it may be best to use
only one of departure_time or arrival_time. If a dwell is desired, use
add_stop_dwell to simulate a dwell time at each stop. This will increase
the departure_time by the number of seconds specified.
Adding dwells opens a new consideration, however: the trajectory will no
longer be strictly monotonic, as the vehicle will hold at a constant distance
for some period of time. This is only a concern if
find_inverse_function = TRUE, which requires strictly monotonic input data.
If both dwell times and an inverse function are desired, consider setting
add_distance_error > 0 to restore strict monotonicity. See
make_monotonic() for more details.
Interpolating Methods
The goal of this function is to fit a continuous function representing a GTFS trip's scheduled distance traveled as a function of time. This function supports two types of interpolating curves:
Linear interpolation, for
interp_method = "linear". This will fit a simple linear function between stops.Spline interpolation, for
interp_methodset to any method supported bystats::splinefun()(i.e.,"fmm","natural","periodic","monoH.FC", or"hyman".)
By default, interp_method = linear, and linear interpolation is the
recommended method for schedule trajectories. This is because timetable
development typically assumes a constant running speed over a corridor, so
linearly connecting stop times will best reflect a trip's scheduled
trajectory.
Inverse Functions
Often times, we are concerned not with the position of a vehicle at a
particular time, but the time at which a vehicle crosses a specific point
in space. This can be accomplished by computing an inverse trajectory
function. If find_inverse_function = TRUE (the default), a numeric
inverse to the fit trajectory function will be found, with a tolerance
controlled by inv_tol.
Because the inverse function is numerical, it can be found for any type of
interpolating curve (linear or spline). However, the input data must be
strictly monotonic for the trajectory curve to be invertible. If
find_inverse_function = TRUE, this will be verified before proceeding (see
validate_monotonicity()).
The Trajectory Object
A trajectory function does not exist by itself; rather, it requires the
context about the trip it describes, as well as its inverse function. As
such, get_trajectory_fun() returns an AVL trajectory object. If
return_group_function = TRUE (the default), the function will return a
single object containing:
A vector of
trip_id_performeds present indistance_df.A list of fit trajectory functions (closures), one per trip, indexed by their
trip_id_performed.A list of fit inverse trajectory functions (closures), one per trip, indexed by their
trip_id_performed.Information about how the trajectory and inverse trajectory functions were fit, including
interp_method,use_speeds, andinv_tol.A vector each for the minimum distances, maximum distances, minimum times, and maximum times of each trip. These inform the domain and range of the trajectory function and its inverse, preventing extrapolation beyond the time or distance range actually served by a trip.
The agency's timezone (see
OlsonNames()), as extracted from theevent_timestampcolumn.
Alternatively, if return_group_function = FALSE, a separate trajectory
object will be returned for each trip, as a list of objects indexed by
their trip_id_performed.
More information about the trajectory object classes and how to use them is
available at vignette("articles/intro-trajectories-la").
Value
If return_group_function = TRUE, a grouped trajectory object. If
FALSE, a list of single trajectory objects, indexed by their
trip_id_performed.
Examples
# Set my parameters
my_crs <- 32611
my_start_date <- as.Date("2026-05-27")
my_end_date <- as.Date("2026-05-27")
# Get input data
lineE_gtfs <- new_transittraj_data("filter_by_route")
lineE_shape <- new_transittraj_data("get_shape_geometry")
# Run function: build trajectory
lineE_scheduled_traj <- get_gtfs_trajectory_fun(gtfs = lineE_gtfs,
project_crs = my_crs,
date_min = my_start_date,
date_max = my_end_date)
# Show trajectory: summary
summary(lineE_scheduled_traj)
# Show trajectory: plot (just a handful of trips)
ordered_trips <- get_trip_extremes(lineE_scheduled_traj) %>%
dplyr::arrange(min_time) %>%
dplyr::pull(trip_id_performed)
plot_trajectory(trajectory = lineE_scheduled_traj,
plot_trips = ordered_trips[20:25],
traj_color = "indianred3")
Calculates numerical inverse of a trajectory function
Description
Not intended for external use
Usage
get_inverse_traj(f, lower, upper, inv_tol)
Arguments
f |
Direct traj function |
lower |
lower distance range |
upper |
upper distance range |
inv_tol |
tolerance for numeric inverse |
Value
function for inverse trajectory
Linearize latitude-longitude GPS points on a provided route shape
Description
This functions projects raw AVL data, as GPS latitude-longitude points, onto a provided route geometry, returning each point's distance of that point along the shape its the beginning terminal.
Usage
get_linear_distances(
avl_df,
shape_geometry,
clip_buffer = NULL,
original_crs = 4326,
project_crs = 4326
)
Arguments
avl_df |
A dataframe of raw AVL data. Must include at least |
shape_geometry |
The SF object to project onto. Must be only one shape.
See |
clip_buffer |
Optional. The distance, in units of the chosen spatial
projection, to clip the GPS points. Only points within this distance of the
|
original_crs |
Optional. A numeric EPSG identifier. If a dataframe is
provided for |
project_crs |
Optional. A numeric EPSG identifer indicating the coordinate system to use for spatial calculations. Consider setting to a Euclidian projection, such as the appropriate UTM zone. Default is 4326 (WGS 84 ellipsoid). |
Value
The input avl_df with latitude and longitude columns replaced
by a distance column, in the units of the spatial projection used (e.g.,
meters if using WGS UTM).
Examples
# Set my parameters
my_buffer <- 50 # meters
my_crs <- 32611
# Get input data
lineE_avl <- new_transittraj_data("lineE_avl")
lineE_shape <- new_transittraj_data("get_shape_geometry")
dim(lineE_avl)
# Run function
lineE_dists <- get_linear_distances(avl_df = lineE_avl,
shape_geometry = lineE_shape,
clip_buffer = my_buffer,
project_crs = my_crs)
dim(lineE_dists)
head(lineE_dists)
Get the geometry of a route shape
Description
This function returns an SF multilinestring of the route alignments from
GTFS shapes. Similar to tidytransit::get_geometry(), but allows filtering
by shape_id and projection to a new coordinate system. See Details for
requirements on the input GTFS.
Usage
get_shape_geometry(gtfs, shape = NULL, project_crs = 4326)
Arguments
gtfs |
A |
shape |
Optional. A vector of GTFS |
project_crs |
Optional. A numeric EPSG identifer indicating the coordinate system to use for spatial calculations. Consider setting to a Euclidian projection, such as the appropriate UTM zone. Default is 4326 (WGS 84 ellipsoid). |
Details
A shapes file must be present in your GTFS object. This file must contain
at least the following fields:
-
shape_id -
shape_pt_lat -
shape_pt_lon -
shape_pt_sequence
Value
An SF multilinestring, with one multilinestring object per
shape_id.
Examples
# Set my parameters
my_shape <- "804EB_RC_221121"
my_crs = 32611
# Get shape from WMATA GTFS
lineE_shape <- get_shape_geometry(gtfs = lacmta_gtfs,
shape = my_shape,
project_crs = my_crs)
print(lineE_shape)
Get the distances of stops along routes
Description
This function returns the linear distance of each stop along a route shape,
starting from the route's beginning terminal. Unless a shape_geometry is
provided, stops will be project onto all shape_ids that serve them. If a
shape_geometry is provided, the function will look only for stops served
by that shape.
Usage
get_stop_distances(gtfs, shape_geometry = NULL, project_crs = 4326)
Arguments
gtfs |
A |
shape_geometry |
Optional. The SF object to project onto. Must include
the field |
project_crs |
Optional. A numeric EPSG identifer indicating the coordinate system to use for spatial calculations. Consider setting to a Euclidian projection, such as the appropriate UTM zone. Default is 4326 (WGS 84 ellipsoid). |
Value
A dataframe containing stop_id, the shape_id it was projected
onto, and distance, in units of the spatial projection (e.g., meters if
using WGS UTM).
Examples
# Set my parameters
my_shape <- "804EB_RC_221121"
my_crs <- 32611
my_route <- "804"
my_dir <- 0
# Get needed GTFS data
lineE_gtfs <- filter_by_route(gtfs = lacmta_gtfs, route_ids = my_route,
dir_id = 0)
lineE_shape <- get_shape_geometry(gtfs = lacmta_gtfs, shape = my_shape,
project_crs = my_crs)
# Run stop distances function
lineE_stop_dists <- get_stop_distances(gtfs = lineE_gtfs,
shape_geometry = lineE_shape,
project_crs = my_crs) %>%
dplyr::select(-c(stop_desc, stop_url, tpis_name, location_type))
head(lineE_stop_dists)
Get a single trajectory object based on an index.
Description
From a grouped trajectory object and given index number, will return the single trajectory object at that index. Internal function. Not intended for external use.
Usage
get_traj_index(
group_traj,
index_num,
new_traj_type,
new_inv_tol,
new_max_deriv,
new_used_speeds,
new_agency_tz
)
Arguments
group_traj |
A transittraj avltrajectory_group object. |
index_num |
Number indicating index to pull trajectory from |
new_traj_type |
Interp method character string |
new_inv_tol |
Tolerance used in numeric inverse |
new_max_deriv |
Max derivative allowed |
new_used_speeds |
Whether speeds were used |
new_agency_tz |
Agency's timezone as Olson name |
Value
Single trajectory object
Fit continuous trajectory interpolating curves from AVL data
Description
This function fits a continuous vehicle trajectory to cleaned AVL
points (see vignette("articles/data-workflow-la")). This function
operates as a "function factory", returning a function (closure) which
takes a timestamp and returns each trip's position. A separate curve is
fit for each trip, and stored in a special trajectory object class.
The default interpolating method is a velocity-informed piecewise
cubic interpolating polynomial, but linear interpolation and other
spline-based techniques are also supported. See Details for a discussion.
Usage
get_trajectory_fun(
distance_df,
interp_method = "monoH.FC",
use_speeds = TRUE,
find_inverse_function = TRUE,
inv_tol = 0.01,
return_group_function = TRUE
)
Arguments
distance_df |
A dataframe of linearized AVL data. Must include
|
interp_method |
Optional. The type of interpolation function to be fit.
Either |
use_speeds |
Optional. A boolean, should curves be constrained by
observed AVL speeds? Should only be used with |
find_inverse_function |
Optional. A boolean, should the numeric inverse
function (time ~ distance) be calculated? Default is |
inv_tol |
Optional. A numeric in the units of input |
return_group_function |
Optional. A boolean, should the returned
trajectory object be grouped into a single function? If FALSE, will return a
list (indexed by |
Details
Interpolating Methods
The goal of this function is to fit a continuous function representing a vehicle's distance traveled as a function of time, for each trip. This function supports to types of interpolating curves:
Linear interpolation, for
interp_method = "linear". This will fit a simple linear function, ignorant to recordedspeedvalues.Spline interpolation, for
interp_methodset to any method supported bystats::splinefun()(i.e.,"fmm","natural","periodic","monoH.FC", or"hyman".) Onlyinterp_method = "monoH.FC"supports use of recordedspeedvalues.
By default, interp_method = "monoH.FC" and use_speeds = TRUE. This will
yield a continuous, differentiable, and invertible trajectory.
If the input distance and speed values satisfy Fritsch-Carlson,
the interpolating function is guaranteed to be montonic.
See make_monotonic(). This is equivalent to the velocity-informed
monotonic peicewise cubic Hermite interpolating polynomials with
monotonic enforcement (VCHIP-ME) technique proposed by
Robbennolt et al. (2026), and is our recommended approach.
Note that use_speeds = TRUE requires interp_method = "monoH.FC", but
interp_method = "monoH.FC" does not require use_speeds = TRUE. In the
latter scenario, a "velocity-ignorant' Fritsch-Carlson interpolating function
can be created (Huang et al., 2023). If input distance values are
monotonic, this curve is guaranteed to be monotonic.
Inverse Functions
Often times, we are concerned not with the position of a vehicle at a
particular time, but the time at which a vehicle crosses a specific point
in space. This can be accomplished by computing an inverse trajectory
function. If find_inverse_function = TRUE (the default), a numeric
inverse to the fit trajectory function will be found, with a tolerance
controlled by inv_tol.
Because the inverse function is numerical, it can be found for any type of
interpolating curve (linear or spline). However, the input data must be
strictly monotonic for the trajectory curve to be invertible. If
find_inverse_function = TRUE, this will be verified before proceeding (see
validate_monotonicity()).
The Trajectory Object
A trajectory function does not exist by itself; rather, it requires the
context about the trip it describes, as well as its inverse function. As
such, get_trajectory_fun() returns an AVL trajectory object. If
return_group_function = TRUE (the default), the function will return a
single object containing:
A vector of
trip_id_performeds present indistance_df.A list of fit trajectory functions (closures), one per trip, indexed by their
trip_id_performed.A list of fit inverse trajectory functions (closures), one per trip, indexed by their
trip_id_performed.Information about how the trajectory and inverse trajectory functions were fit, including
interp_method,use_speeds, andinv_tol.A vector each for the minimum distances, maximum distances, minimum times, and maximum times of each trip. These inform the domain and range of the trajectory function and its inverse, preventing extrapolation beyond the time or distance range actually served by a trip.
The agency's timezone (see
OlsonNames()), as extracted from theevent_timestampcolumn.
Alternatively, if return_group_function = FALSE, a separate trajectory
object will be returned for each trip, as a list of objects indexed by
their trip_id_performed.
More information about the trajectory object classes and how to use them is
available at vignette("articles/intro-trajectories-la").
Value
If return_group_function = TRUE, a grouped trajectory object. If
FALSE, a list of single trajectory objects, indexed by their
trip_id_performed.
References
Robbennolt, Jake, Sirajum Munira, and Stephen D. Boyles. 2026. “A Comparative Study of Spline-Based Trajectory Reconstruction Methods Across Varying Automatic Vehicle Location Data Densities.” Paper presented at 2026 Transportation Research Board Annual Meeting, January 11. http://arxiv.org/abs/2509.00119.
Huang, Yuzhu, Awad Abdelhalim, Anson Stewart, Jinhua Zhao, and Haris Koutsopoulos. 2023. “Reconstructing Transit Vehicle Trajectory Using High-Resolution GPS Data.” 2023 IEEE 26th International Conference on Intelligent Transportation Systems (ITSC), September 24, 5247–53. https://doi.org/10.1109/ITSC57777.2023.10422524.
Examples
# Get input data
lineE_mono <- new_transittraj_data("make_monotonic")
# Run function: grouped trajectory object
lineE_traj_grouped <- get_trajectory_fun(distance_df = lineE_mono)
summary(lineE_traj_grouped)
# Run function: list of single trajectory objects
lineE_traj_singles <- get_trajectory_fun(distance_df = lineE_mono,
return_group_function = FALSE)
length(lineE_traj_singles)
summary(lineE_traj_singles[[2]])
Get the distance and time range of each trip in a trajectory object
Description
This function extracts the time and distance ranges stored in a trajectory
object and formats them into a dataframe. The dataframe can
be filtered to a desired set of trip_id_performeds.
Usage
get_trip_extremes(trajectory, filter_trips = NULL)
Arguments
trajectory |
A trajectory object. |
filter_trips |
Optional. A vector of |
Value
A dataframe with the columns trip_id_performed, min_time,
max_time, min_dist, and max_dist.
Examples
# Get input data
lineE_traj <- new_transittraj_data("get_trajectory_fun")
# Run function
lineE_extremes <- get_trip_extremes(lineE_traj)
print(lineE_extremes)
Group existing trajectory objects or split them apart
Description
Trajectory objects hold the trajectory functions, and related information,
from one or more trip IDs. This function groups the fit trajectories from
multiple trips into one object, or splits a grouped object into many single
trajectory objects, one for each trip. See help(get_trajectory_fun) for
more information.
Usage
group_trajectories(trajectories, grouping)
Arguments
trajectories |
A trajectory object to operate on. Can be a list of single trajectories, a list of grouped trajectories, or one grouped trajectory. |
grouping |
A character string, either |
Value
If grouping = "group", a group trajectory object; if
grouping = "split", a list of single trajectory objects.
Examples
# Get input data
lineE_mono <- new_transittraj_data("make_monotonic")
# Fit a list of single trajectory functions
lineE_traj_singles <- get_trajectory_fun(distance_df = lineE_mono,
return_group_function = FALSE)
# Show sample singles
print(length(lineE_traj_singles))
print(lineE_traj_singles[[2]])
# Run function: group singles
lineE_traj_grouped <- group_trajectories(trajectories = lineE_traj_singles,
grouping = "group")
summary(lineE_traj_grouped)
# Run function: split apart again
lineE_traj_singles_2 <- group_trajectories(trajectories = lineE_traj_grouped,
grouping = "split")
print(length(lineE_traj_singles_2))
print(lineE_traj_singles_2[[2]])
Internal generic for performing interpolation of distances from times.
Description
Performs interpolation of distance values from a DF of times & trip IDs. A generic function, dispatches depending on whether trajectory is grouped or single.
Usage
interpolate_distances(trajectory, new_times_trips, ...)
## S3 method for class 'avltrajectory_single'
interpolate_distances(trajectory, new_times_trips, ...)
## S3 method for class 'avltrajectory_group'
interpolate_distances(trajectory, new_times_trips, ...)
Arguments
trajectory |
Single or grouped trajectory object |
new_times_trips |
DF with trip_id_performed event_timestamp, and deriv |
... |
other inputs, not used |
Value
A DF with appended column "interp" of distance (or deriv) values
Internal generic for performing interpolation of times from distances.
Description
Performs interpolation of time values from a DF of distances & trip IDs. A generic function, dispatches depending on whether trajectory is grouped or single.
Usage
interpolate_times(trajectory, new_dist_trips, ...)
## S3 method for class 'avltrajectory_single'
interpolate_times(trajectory, new_dist_trips, ...)
## S3 method for class 'avltrajectory_group'
interpolate_times(trajectory, new_dist_trips, ...)
Arguments
trajectory |
Single or grouped trajectory object |
new_dist_trips |
A DF with trip_id_performed and distance |
... |
other inputs, not used |
Value
A DF with appended column "interp" of event_timestamp values
LA Metro AVL Data
Description
This dataset contains TIDES-formatted automatic vehicle location (AVL)
data from the Los Angeles
County Metropolitan Transportation Authority (LACMTA), or Metro. Pings
for all Lines A and E trips starting between 6:00 and 8:00 AM on May 27,
2026 are included. The data was accessed via Caltrans's open-source bucket of TIDES vehicle_locations
tables. This dataset is inteded to be used alongside the static GTFS
feed provided in lacmta_gtfs.
Usage
lacmta_avl
Format
lacmta_avl
A dataframe with 14,179 rows and 11 columns.
- location_ping_id
A unique ID for each row.
- service_date
The date of the trip's beginning.
- trip_id_performed
Trip IDs, matching those in GTFS.
- latitude, longitude
The GPS ping longitude and latitude.
- speed
The recorded speed, in meters per second.
- vehicle_id
An ID corresponding to each vehicle.
- event_timestamp
POSIXct time objects, including the day, time, and local timezone.
- direction_id
Direction IDs, matching those in GTFS. For Line A,
0is northbound and1is soutbound; for Line E,0is eastbound and1is westbound.- shape_id
Shape IDs, matching those in GTFS. Each route and direction has one shape ID.
- route_id
Route IDs, matching those in GTFS.
"801"is Line A, and"804"is Line E.
Details
The dataset contains two light rail routes, with two directions for each:
Line A: Pomona North to Downtown Long Beach
Line E: Downtown Santa Monica to Atlantic
Source
Examples
# Print the header
head(lacmta_avl)
# Filter the data
lineE_avl <- lacmta_avl %>%
dplyr::filter((route_id == "804") & (direction_id == 0))
print(unique(lineE_avl$shape_id))
# Use in the AVL cleaning workflow
lineE_shape <- get_shape_geometry(gtfs = lacmta_gtfs,
shape = "804EB_RC_221121",
project_crs = 32611)
lineE_dists <- get_linear_distances(avl_df = lineE_avl,
shape_geometry = lineE_shape,
clip_buffer = 50,
project_crs = 32611)
head(lineE_dists)
LA Metro GTFS
Description
This dataset is a portion of the rail General Transit Feed
Specification (GTFS) from the Los Angeles County Metropolitan
Transportation Authority (LACMTA), or Metro. This feed version was first
published on May 27, 2026, and was valid through May 28, 2026. This
dataset is intended to be used alongside the TIDES AVL data provided
in lacmta_avl.
Usage
lacmta_gtfs
Format
lacmta_gtfs
A tidytransit tidygtfs object (list) with 8 files.
- agency
The GTFS
agency.txtfile.- routes
The GTFS
routes.txtfile.- trips
The GTFS
trips.txtfile.- stop_times
The GTFS
stop_times.txtfile.- stops
The GTFS
stops.txtfile.- shapes
The GTFS
shapes.txtfile.- calendar
The GTFS
calendar.txtfile.- calendar_dates
The GTFS
calendar_dates.txtfile.- fare_rules
The GTFS
fare_rules.txtfile.
Details
The GTFS feed has been filtered to two light rail routes, with two directions for each, on one service date (May 27, 2026):
Line A: Pomona North to Downtown Long Beach
Line E: Downtown Santa Monica to Atlantic
Source
https://www.transit.land/feeds/f-9q5-metro~losangeles~rail
Examples
# Print the tidytransit summary
summary(lacmta_gtfs)
# Filter by route & direction
my_route <- "804"
my_dir <- 0
lineE_gtfs <- filter_by_route(gtfs = lacmta_gtfs,
route_ids = my_route,
dir_id = my_dir)
summary(lineE_gtfs)
# Extract route alignments
lineE_shapes <- get_shape_geometry(gtfs = lineE_gtfs)
print(lineE_shapes)
Correct distance observations, and optionally speeds, to be weakly or strictly monotonic
Description
Due to error in GPS position and speed measurements, raw AVL data is often
not monotonic, creating difficulties for advanced analyses. This function
presents a variety of options to correct data, resulting in distance values,
and optionally speeds, which form a strictly or weakly monotonic curve. See
Details for more information.
Usage
make_monotonic(
distance_df,
correct_speed = FALSE,
add_distance_error = 0,
return_changes = FALSE
)
Arguments
distance_df |
A dataframe of linearized AVL data. Must include
|
correct_speed |
Optional. A boolean, should speeds be corrected to meet
adjusted distances and Fritsch-Carlson conditions? Default is |
add_distance_error |
Optional. If non-zero, each "flat" observation will
be adjusted by this amount forwards, in units of input |
return_changes |
Optional. Should a dataframe of each observation
changed be returned? Default is |
Details
There are two primary types of monotonicity:
Weak monotonicity: The trajectory is increasing or constant. To make points weakly monotonic, this function replaces each point with the cumulative maximum
distancevalue at that point in the trip. This means that backtracking points will be "pulled up."Strict monotonicity: The trajectory is increasing only, never constant. To make points strictly monotonic, we first begin with a weakly monotonic trajectory. Then, constant portions (adjacent points with equal
distancevalues) are identified, andadd_distance_erroris added to each point. The function identifies and prevents "overshoots," ensuring that an adjusted point never moves past an observed point sometime after it. Effectively, this gives flat portions of the trajectory a slight upward slope.
Weak monotonicity most accurately describes real transit vehicle trajectories:
we expect the vehicle to either move forwards, or stand still at a stop.
However, strict monotonicity is a convenient mathematical property that
allows us to find the inverse trajectory (i.e., retrieve time as a
function of distance). Choose between these two options by setting
add_distance_error. If add_distance_error = 0 (the default), a weakly
monotonic trajectory is returned; otherwise, the trajectory will be
strictly monotonic.
In addition to distance corrections, some applications (e.g., fitting a
velocity-informed interpolation spline) require speeds to satisfy certain
monotonic conditions. If correct_speed = TRUE, the following corrections
will be made:
For strict monotonicity (
add_distance_error > 0), speeds must be non-zero. At each point where the recordedspeed == 0, the speed will be replaced byadd_distance_errordivided by the time between that point and the previous point.For both strict and weak monotonicity, speeds will be adjusted to meet the Fritsch-Carlson (1980) constraints. Often, only a handful of input
speedvalues will be adjusted.
If recorded speed values are not present, set correct_speed = FALSE.
However, if you are interested in later fitting a velocity-informed
interpolating curve, such as Fritsch-Carlson's piecewise cubic polynomials,
consider setting correct_speed = TRUE to guarantee a monotonic
interpolating curve.
After using this function to perform corrections, use
validate_monotonicity() to check if weak, strict, and Fritsch-Carlson
speed conditions are met.
Value
The input distance_df with distances and speeds adjusted. If
return_changes = TRUE, a dataframe with observations changed.
References
Fritsch, F. N., and R. E. Carlson. 1980. “Monotone Piecewise Cubic Interpolation.” SIAM Journal on Numerical Analysis. https://doi.org/10.1137/0717021.
Robbennolt, Jake, Sirajum Munira, and Stephen D. Boyles. 2026. “A Comparative Study of Spline-Based Trajectory Reconstruction Methods Across Varying Automatic Vehicle Location Data Densities.” Paper presented at 2026 Transportation Research Board Annual Meeting, January 11. http://arxiv.org/abs/2509.00119.
Examples
# Set my parameters
my_dist_err = 0.001
# Get input data
lineE_trimmed <- new_transittraj_data("trim_trips")
# Run function
lineE_mono <- make_monotonic(distance_df = lineE_trimmed,
add_distance_error = my_dist_err,
correct_speed = TRUE)
head(lineE_mono)
Constructor for grouped trajectory class
Description
This superclass holds a single, combined trajectory function. Plus vectors of all trip IDs described by that function, and vectors of the time & distance ranges of those trips. Not intended for external use.
Usage
new_avltrajectory_group(
trip_id_performed = character(),
traj_fun,
inv_traj_fun = NULL,
min_dist,
max_dist,
min_time,
max_time,
traj_type,
inv_tol = NULL,
max_deriv = 0,
used_speeds = FALSE,
agency_tz,
...,
class = character()
)
Arguments
trip_id_performed |
Character if trip ids. |
traj_fun |
List or single trajectory functions. |
inv_traj_fun |
List or single inverse trajectory functions. |
min_dist |
Vector if minimum distance values. |
max_dist |
Vector of maximum distance values. |
min_time |
Vector of minimum time values. |
max_time |
Vector of maximum time values. |
traj_type |
Interp method character string |
inv_tol |
Tolerance used in numeric inverse |
max_deriv |
Max derivative allowed |
used_speeds |
Whether speeds were used |
agency_tz |
Timezone of agency |
... |
Other inputs |
class |
Object class |
Value
Grouped trajectory object
Constructor for single trajectory class
Description
This is a subclass (special case) of a grouped trajectory, in which there is only one trip. Trajectory function is inteded to describe only one trip. Associated trip properties (ID & ranges) should describe only that trip. Not intended for external use.
Usage
new_avltrajectory_single(
trip_id_performed = character(),
traj_fun,
inv_traj_fun = NULL,
min_dist,
max_dist,
min_time,
max_time,
traj_type,
inv_tol = NULL,
max_deriv = 0,
used_speeds = FALSE,
agency_tz
)
Arguments
trip_id_performed |
Character if trip ids. |
traj_fun |
List or single trajectory functions. |
inv_traj_fun |
List or single inverse trajectory functions. |
min_dist |
Vector if minimum distance values. |
max_dist |
Vector of maximum distance values. |
min_time |
Vector of minimum time values. |
max_time |
Vector of maximum time values. |
traj_type |
Interp method character string |
inv_tol |
Tolerance used in numeric inverse |
max_deriv |
Max derivative allowed |
used_speeds |
Whether speeds were used |
agency_tz |
Timezone of agency |
Value
Single trajectory object
Retrieve an object from a particular step of transittraj's workflow
Description
This function runs transittraj's AVL cleaning and trajectory reconstruction
workflow up until a certain point (as defined by func_output), then returns
the object at that point. A subset of the lacmta_avl dataset is used.
This is primarily intended for use in testing and examples. The workflow
applied here is the same as what is in
vignette("articles/data-workflow-la").
Usage
new_transittraj_data(func_output = NULL)
Arguments
func_output |
The |
Value
The object returned by the specified function.
Examples
# Get AVL data after projection onto route
lineE_dists <- new_transittraj_data("get_linear_distances")
head(lineE_dists)
# Get a full, fit trajectory
lineE_traj <- new_transittraj_data("get_trajectory_fun")
summary(lineE_traj)
Quickly plot an AVL trajectory
Description
This function generates a quick plot of a single or grouped trajectory
object. Using the trajectory function, the entire trajectory will be plotted
at a temporal resolution of 10 seconds. For grouped trajectories, a maximum
of 50 trips will be plotted. For more control over plotting and
formatting, see plot_trajectory().
Usage
## S3 method for class 'avltrajectory_group'
plot(x, ...)
## S3 method for class 'avltrajectory_single'
plot(x, ...)
Arguments
x |
A trajectory object. |
... |
Other parameters (not used). |
Value
A ggplot2 object.
Examples
# Get input data
lineE_traj_grouped <- new_transittraj_data("get_trajectory_fun")
lineE_traj_singles <- new_transittraj_data("get_trajectory_fun_single")
# Plot: Grouped trajectory object
plot(lineE_traj_grouped)
# Plot: Single trajectory object
plot(lineE_traj_singles[[2]])
Animate vehicle trajectory or AVL data
Description
These functions use the input trajectory object or TIDES AVL data to animate vehicles progressing along their routes. This can be visualized in two ways:
-
plot_animated_line()simplifies the route alignment into a single straight line and shows the vehicles moving down this line. -
plot_animated_map()plots the full route's alignment and shows the vehicles moving through space.
Both functions allow the plotting of spatial features and labels for these
features. A gganimate object is returned, which can be further modified
and customized as desired.
Usage
plot_animated_line(
trajectory = NULL,
distance_df = NULL,
plot_trips = NULL,
timestep = 5,
distance_lims = NULL,
center_vehicles = FALSE,
feature_distances = NULL,
transition_style = "linear",
convert_to_timezone = TRUE,
route_color = "coral",
route_width = 3,
route_alpha = 1,
feature_shape = 21,
feature_outline = "black",
feature_fill = "white",
feature_size = 2,
feature_stroke = 1.25,
feature_alpha = 1,
feature_legend = NULL,
veh_shape = 23,
veh_outline = "grey30",
veh_fill = "white",
veh_size = 3,
veh_stroke = 2,
veh_alpha = 0.8,
veh_legend = NULL,
label_field = NULL,
label_size = 3,
label_alpha = 0.6,
label_pos = "left"
)
plot_animated_map(
shape_geometry,
trajectory = NULL,
distance_df = NULL,
plot_trips = NULL,
timestep = 5,
distance_lims = NULL,
center_vehicles = FALSE,
feature_distances = NULL,
background = "cartolight",
background_zoom = 0,
bbox_expand = NULL,
transition_style = "linear",
convert_to_timezone = TRUE,
route_color = "coral",
route_width = 3,
route_alpha = 1,
feature_shape = 21,
feature_outline = "black",
feature_fill = "white",
feature_size = 2,
feature_stroke = 1.25,
feature_alpha = 1,
feature_legend = NULL,
veh_shape = 23,
veh_outline = "grey30",
veh_fill = "white",
veh_size = 3,
veh_stroke = 2,
veh_alpha = 0.8,
veh_legend = NULL,
label_field = NULL,
label_size = 3,
label_alpha = 0.6,
label_pos = "out"
)
Arguments
trajectory |
Optional. A trajectory object, either a single trajectory
or grouped trajectory. If provided, |
distance_df |
Optional. A dataframe of time and distance points. Must
include at least |
plot_trips |
Optional. A vector of |
timestep |
Optional. If |
distance_lims |
Optional. A vector with |
center_vehicles |
Optional. A boolean, should all vehicle points be
centered to start at the same time (0 seconds)? Default is |
feature_distances |
Optional. A dataframe with at least numeric
|
transition_style |
Optional. A |
convert_to_timezone |
Optional. Should numeric epoch times be converted
back to readable hour-minute-second time values, using the agency timezone?
Default is |
route_color |
Optional. A color string for the color of the route
alignment. Default is |
route_width |
Optional. A numeric, the linewidth of the route
alignment. Default is |
route_alpha |
Optional. A numeric, the opacity of the route alignment.
Default is |
feature_shape |
Optional. A numeric specifying the |
feature_outline |
Optional. A color string, or a dataframe mapping an
attribute in |
feature_fill |
Optional. A color string, the inside fill of feature
points. Default is |
feature_size |
Optional. A numeric, the size of the feature point.
Default is |
feature_stroke |
Optional. A numeric, the linewidth of the feature point
outline. Default is |
feature_alpha |
Optional. A numeric, the opacity of the feature point.
Default is |
feature_legend |
Optional. A boolean, should a legend be shown for
feature formatting? Default is |
veh_shape |
Optional. A numeric specifying the |
veh_outline |
Optional. A color string, or a dataframe mapping an
attribute in |
veh_fill |
Optional. A color string, the inside fill of the vehicle
point. Default is |
veh_size |
Optional. A numeric, the size of the vehicle point. Default
is |
veh_stroke |
Optional. A numeric, the linewidth of the vehicle point
outline. Default is |
veh_alpha |
Optional. A numeric, the opacity of the vehicle point.
Default is |
veh_legend |
Optional. A boolean, should a legend be shown for
vehicle formatting? Default is |
label_field |
Optional. A string specifying the column in
|
label_size |
Optional. The font size of the feature labels. Default is
|
label_alpha |
Optional. The opacity of the feature labels. Default is
|
label_pos |
Optional. A string specifying the label position on the graph. Options include:
|
shape_geometry |
An SF object representing the route alignment. See
|
background |
Optional. The OSM background (basemap) for the animation.
See |
background_zoom |
Optional. The zoom, relative to the "correct" level,
for the background basemap. Default is |
bbox_expand |
Optional. The distance by which to expand the plotting
window in both directions. Default is |
Details
Input Trajectory Data
There are two ways to provide data for these plotting functions:
A single or grouped trajectory object. This will use the direct trajectory function at a resolution controlled by
timestep. This is simplest, and looks best when zooming in usingdistance_lims. The only attribute that can be mapped to if using a trajectory istrip_id_performed.A
distance_dfof TIDES AVL data. This will use the distance and time point pairs for plotting, and draw linearly between them. This will look similar to a plot usingtrajectorywhen zoomed out. It is most useful if you want to map formatting to attributes other thantrip_id_performed, such as a vehicle or operator ID. If starting with atrajectory, but the additional control over formatting is desired, consider usingpredict()to generate distance and time points to plot, then joining the desired attributes to thetrip_id_performedcolumn.
Note that only one of trajectory and distance_df can be used. If both
(or neither) are provided, an error will be thrown.
Features and Labels
Often it is useful to plot the features of a route, such as its
stops/stations or the traffic signals it passes through. Use
feature_distances to provide information about spatial features to plot.
Each row in feature_distances should include at least a distance column.
Each of these rows will be plotted as a point on the route line.
These features can also be labeled. Set label_name to a character string
corresponding to a field in feature_distances to generate labels with
this field as their text. The color of the label will automatically match
that of the feature they describe. The label placement is controlled by
label_pos, which has the following options available:
-
plot_animated_line(): Either"left"or"right"of the route line. The y-value will be that of the feature it describes. -
plot_animated_map(). A cardinal or intermediate compass direction ("N","SE", etc.) relative to the feature point. Or,"in"/"out", relative to the center of the plot.
Note that for plot_animated_map() the feature_distances must still be
linear distances, not a spatial datatype. To retrieve distance values for
spatial features, see get_stop_distances() and project_onto_route().
Formatting Options
Once a layer is created on a ggplot2 object, it is difficult to change its
formatting. As such, this function attempts to provide as much flexibility
in formatting its layers as possible. The resulting plot includes four
layers in the following order:
Route line, controlled by
route_color,route_width, androute_alpha.Features, controlled by
feature_fill,feature_outline,feature_shape,feature_size,feature_alpha, andfeature_stroke.Labels, controlled by
label_size,label_alpha, andlabel_pos.Vehicles, controlled by
veh_fill,veh_outline,veh_shape,veh_size,veh_alpha, andveh_stroke.
All of these formats can be controlled by inputting a single string or numeric. The following attributes can also be modified using a dataframe, mapping them to attributes of the layer:
-
veh_shapeandfeature_shape: A dataframe with one column namedshape, and another column sharing a name with a column indistance_dforfeature_distances(or, if usingtrajectory, a column namedtrip_id_performed). The values inshapeshould be validggplot2point shapes, and the values in the mapping column should match the values in feature or trip column. -
veh_outlineandfeature_outline: A dataframe with one column namedoutline, and another column sharing a name with a column indistance_dforfeature_distances(or, if usingtrajectory, a column namedtrip_id_performed). The values inoutlineshould be valid color strings, and the values in the mapping column should match the values in feature or trip column.
Note that if inputting trajectory, instead of distance_df, veh_shape
and veh_outline can only be mapped to trip_id_performed. If using
distance_df, they may be mapped to any column in distance_df (e.g.,
vehicle or operator IDs).
Basemaps
The function plot_animated_map() has one additional layer to format: the
basemap beneath the route alignment. OpenStreetMaps basemaps are used here.
See a full list of available basemaps using rosm::osm.image().
In addition to the map itself, the zoom level on the map can be
adjusted using background_zoom. This will describe a zoom level relative
to the "correct" level of your bounding box (i.e., what you what see if
you looked at that data in an online mapping platform). Setting to a
negative value (zooming out) will substantially speed up rendering, but will
give a much lower resolution may.
Finally, the bounding box of the basemap can also be set. The bounding
box is defined relative to the spatial range of trajectory or
distance_df. The default is expansion is 0.05% (0.0025% for
distance_lims != NULL) of the larger dimension (northing or easting) of the
vehicle location bounding box. To customize, det bbox_expand to some
numeric in the distance units of the shape_geometry's spatial
projection (e.g., meters if using a WGS UTM projection).
Value
A gganimate object.
Examples
# Get input data
lineE_traj <- new_transittraj_data("get_trajectory_fun")
lineE_shape <- new_transittraj_data("get_shape_geometry")
# Set my parameters
my_features <- data.frame(name = c("Metro Center"),
distance = c(24556))
my_dist_range <- c(24000, 25000)
# Run function: Line animation
anim_line <- plot_animated_line(trajectory = lineE_traj,
feature_distances = my_features,
route_color = "firebrick4",
label_field = "name",
label_alpha = 0.8,
label_pos = "right",
distance_lims = my_dist_range,
center_vehicles = TRUE,
timestep = 1)
# Run function: Map animation
anim_map <- plot_animated_map(trajectory = lineE_traj,
shape_geometry = lineE_shape,
feature_distances = my_features,
route_color = "firebrick4",
label_field = "name",
label_alpha = 0.8,
distance_lims = my_dist_range,
center_vehicles = TRUE,
timestep = 1,
bbox_expand = 40)
if (interactive()) {
# Note: Due to long processing times, animations will only be rendered &
# displayed if run during an interactive session. See `example()`.
anim_line
anim_map
}
Set up feature distances DF
Description
Filters features DF down to desired limit, and checks that it meets necessary conditions.
Usage
plot_feature_df_setup(feature_distances, distance_lims)
Arguments
feature_distances |
DF of features & their distances |
distance_lims |
Vector of min & max distances |
Value
A DF of filtered & validated feature distances
Function to set up plot formats.
Description
Intended for internal use only.
Usage
plot_format_setup(
plotting_df,
attribute_input,
attribute_type,
attribute_name,
user_show_legend
)
Arguments
plotting_df |
DF for plotting, either trips or features |
attribute_input |
The user input value for the attribute (e.g., outline_input = veh_outline) |
attribute_type |
The type of attribute being constructed (e.g., "outline") |
attribute_name |
The name of the attribute (e.g., "veh_outline") |
user_show_legend |
Boolean, user input for if legend should be shown. |
Value
List with: 1) new plotting_df, 2) show_legend, 3) attribute_by, and 4) attribute_vals
Generate a Leaflet viewer of GTFS routes and stops
Description
This function generates a simple Leaflet-based interactive map viewer of a GTFS. This function is intended for quick and easy visualization of a GTFS feed. As such, formatting options are relatively limited.
Usage
plot_interactive_gtfs(
gtfs,
background = "Esri.WorldGrayCanvas",
color_palette = "Dark2"
)
Arguments
gtfs |
A tidytransit GTFS object. |
background |
Optional. A string for the background of the transit map,
from Leaflet's provider library (see |
color_palette |
Optional. A string for the Leaflet color palette to
color routes. If |
Details
Route Shapes and Stops
The primary goal of this function is to visualize and explore each GTFS
shape, including its associated route_id and direction_id. This function
will plot all shapes and stops present in the input gtfs. To plot only
a specific route or direction, first filter the feed using
filter_by_route().
Routes have both pop-ups and hover labels. The hover label shows the
shapes's route_id (from the trips file). The pop-up will show the
route_id, direction_id, and shape_id.
Stops also have both pop-ups and hover labels. The hover label will show the
point's stop_id (from the stops file). The pop-up will show the
stop_name and stop_id.
Formatting
Two formatting options are available through this function: basemaps and route color palettes.
The background parameter allows you to customize the background basemap.
Esri's light grey canvas is the default, as it
is excellent for providing geographic context while still allowing the
routes to stand out. To see the available options, type
leaflet::providers$ into your console.
The route colors can be customized in two different ways:
Using the
gtfs's colors. Typically, theroutesfile in a GTFS feed will contain a fieldroute_color; this is the color you see in most public-facing mapping/navigation applications (e.g., Google Maps, Transit App, etc.). If this is present in the inputgtfsfeed, settingcolor_palette = "gtfs"will use this field to color each shape.Using a named color palette. Without
gtfscolors, this function assigns colors categorically (usingleaflet::colorFactor()). To set the palette, input a string corresponding to a palette name fromRColorBrewer, a palette name fromviridis, a vector of color names (with the same length as the number of shapes), or some other color function. See Leaflet's colors vignette for more information.
Value
A Leaftlet object.
Examples
plot_interactive_gtfs(gtfs = lacmta_gtfs,
color_palette = "gtfs")
Sets up plotting DF is trajectory is provided.
Description
This function uses a trajectory object to create a DF of time, distance points for each trip. If inverse function is present, this will be used to interpolate only over the appropriate distance range of each trip. If not, interpolation will occur over the entire time range of the requested trips. Internal function.
Usage
plot_traj_df_setup(trajectory, has_inv, plot_trips, timestep, distance_lims)
Arguments
trajectory |
A trajectory object |
has_inv |
a boolean, does the traj object have inv fun? |
timestep |
A numeric, time interval between interpolated poitns |
distance_lims |
A vector of (minimum, maximum) distance to interpolate |
Validates input to trajectory plotting functions.
Description
This function validates that an appropriate combination of trajectory and distance_df are provided, and that they have the necessary features. If a trajectory's inverse function is not present, the user will be warned that interpolation may be time consuming. Internal function.
Usage
plot_traj_input_validation(trajectory, distance_df, has_inv)
Arguments
trajectory |
A trajectory objcet |
distance_df |
a DF with columns distance, event_timestamp, and trip_id_performed |
has_inv |
a boolean, does the traj object have inv fun? |
Value
Error if requirements not met.
Plot vehicle trajectories or AVL data
Description
This function uses the input trajectory object or TIDES AVL data to draw a
trajectory plot (i.e., linear distance versus time) for each trip. This
function allows for the plotting of spatial features and labels for these
features. A ggplot2 object is returned, which can be further modified
and customized as desired.
Usage
plot_trajectory(
trajectory = NULL,
distance_df = NULL,
plot_trips = NULL,
timestep = 5,
distance_lims = NULL,
center_trajectories = FALSE,
feature_distances = NULL,
convert_to_timezone = TRUE,
traj_color = "coral",
traj_type = "solid",
traj_width = 1,
traj_alpha = 1,
traj_legend = NULL,
feature_color = "grey30",
feature_type = "dashed",
feature_width = 0.8,
feature_alpha = 0.8,
feature_legend = NULL,
label_field = NULL,
label_size = 3,
label_alpha = 0.6,
label_pos = "left"
)
Arguments
trajectory |
Optional. A trajectory object, either a single trajectory
or grouped trajectory. If provided, |
distance_df |
Optional. A dataframe of time and distance points. Must
include at least |
plot_trips |
Optional. A vector of |
timestep |
Optional. If |
distance_lims |
Optional. A vector with |
center_trajectories |
Optional. A boolean, should all trajectories be
centered to start at the same time (0 seconds)? Default is |
feature_distances |
Optional. A dataframe with at least numeric
|
convert_to_timezone |
Optional. Should numeric epoch times be converted
back to readable hour-minute-second time values, using the agency timezone?
Default is |
traj_color |
Optional. A color string, or a dataframe mapping an
attribute in |
traj_type |
Optional. A string specifying the |
traj_width |
Optional. A numeric, the width of the trajectory line.
Default is |
traj_alpha |
Optional. A numeric, the opacity of the trajectory line.
Default is |
traj_legend |
Optional. A boolean, should a legend be shown for
trajectory formatting? Default is |
feature_color |
Optional. A color string, or a dataframe mapping an
attribute in |
feature_type |
Optional. A string specifying the |
feature_width |
Optional. A numeric, the width of the feature line.
Default is |
feature_alpha |
Optional. A numeric, the opacity of the feature point.
Default is |
feature_legend |
Optional. A boolean, should a legend be shown for
feature formatting? Default is |
label_field |
Optional. A string specifying the column in
|
label_size |
Optional. The font size of the feature labels. Default is
|
label_alpha |
Optional. The opacity of the feature labels. Default is
|
label_pos |
Optional. A string specifying the label position on the
graph. Must be either |
Details
Input Trajectory Data
There are two ways to provide data to this function:
A single or grouped trajectory object. This will use the direct trajectory function at a resolution controlled by
timestep. This is simplest, and looks best when zooming in usingdistance_lims. The only attribute that can be mapped to if using a trajectory istrip_id_performed.A
distance_dfof TIDES AVL data. This will use the distance and time point pairs for plotting, and draw linearly between them. This will look similar to a plot usingtrajectorywhen zoomed out. It is most useful if you want to map formatting to attributes other thantrip_id_performed, such as a vehicle or operator ID. If starting with atrajectory, but the additional control over formatting is desired, consider usingpredict()to generate distance and time points to plot, then joining the desired attributes to thetrip_id_performedcolumn.
Note that only one of trajectory and distance_df can be used. If both
(or neither) are provided, an error will be thrown.
Features and Labels
Often it is useful to plot the features of a route, such as its
stops/stations or the traffic signals it passes through. Use
feature_distances to provide information about spatial features to plot.
Each row in feature_distances should include at least a distance column.
Each of these rows will be plotted as a horizontal line across the graph.
These features can also be labeled. Set label_name to a character string
corresponding to a field in feature_distances to generate labels with
this field as their text. The color of the label will automatically match
that of the feature they describe. The label placement is controlled by
label_pos, which can be set to "left" or "right".
Formatting Options
Once a layer is created on a ggplot2 object, it is difficult to change its
formatting. As such, this function attempts to provide as much flexibility
in formatting its layers as possible. The resulting plot includes three
layers:
Vehicle trajectories, controlled by
traj_color,traj_type, andtraj_width, andtraj_alpha.Features, controlled by
feature_color,feature_type,feature_width, andfeature_alpha.Labels, controlled by
label_size,label_alpha, andlabel_pos.
All of these formats can be controlled by inputting a single string or numeric. The following attributes can also be modified using a dataframe, mapping them to attributes of the layer:
-
traj_typeandfeature_type: A dataframe with one column namedlinetype, and another column sharing a name with a column indistance_dforfeature_distances(or, if usingtrajectory, a column namedtrip_id_performed). The values inlinetypeshould be validggplot2linetypes, and the values in the mapping column should match the values in feature or trip column. -
traj_colorandfeature_color: A dataframe with one column namedcolor, and another column sharing a name with a column indistance_dforfeature_distances(or, if usingtrajectory, a column namedtrip_id_performed). The values incolorshould be valid color strings, and the values in the mapping column should match the values in feature or trip column.
Note that if inputting trajectory, instead of distance_df,
traj_color and traj_type can only be mapped to trip_id_performed.
If using distance_df, they may be mapped to any column in distance_df
(e.g., vehicle or operator IDs).
Value
A ggplot2 object.
Examples
# Get input data
lineE_traj <- new_transittraj_data("get_trajectory_fun")
# Set my parameters
my_features <- data.frame(name = c("Metro Center"),
distance = c(24556))
my_dist_range <- c(24000, 25000)
# Run function
plot_trajectory(trajectory = lineE_traj,
feature_distances = my_features,
label_field = "name",
label_alpha = 0.8,
distance_lims = my_dist_range,
traj_color = "indianred3",
center_trajectories = TRUE,
timestep = 1)
Set up dataframe & validate of point objects for vehicle animations
Description
Intended for internal use only.
Usage
plot_trips_df_setup(
trajectory,
distance_df,
plot_trips,
timestep,
distance_lims,
center_vehicles,
convert_to_timezone
)
Arguments
trajectory |
Single or grouped trajectory object. |
distance_df |
AVL distance DF. |
plot_trips |
Vector of trip_id_performed to plot. |
timestep |
Time in seconds for interpolation. |
distance_lims |
Vector of (minimum, maximum) distance to plot. |
center_vehicles |
Should vehicles be centered |
convert_to_timezone |
Should times be converted to timezones |
Value
plotting dataframe (trips_df)
Interpolate time or distance points using AVL trajectories
Description
This function uses a fit interpolating curve stored in a grouped or single
trajectory object to find new points along each trip's trajectory.
Depending on whether new_times or
new_distances is provided, the function will utilize the direct or inverse
trajectory function.
Usage
## S3 method for class 'avltrajectory_group'
predict(
object,
new_times = NULL,
new_distances = NULL,
distance_lims = NULL,
timestep = NULL,
deriv = 0,
trips = NULL,
...
)
Arguments
object |
The single or grouped trajectory object. |
new_times |
Optional. A vector of numeric timepoints, or a dataframe
with at least the column |
new_distances |
Optional. A vector of numeric distances, or a dataframe
with at least the column |
distance_lims |
Optional. A vector of |
timestep |
Optional. A single numeric indicating the time interval
between successive interpolating steps when defining |
deriv |
Optional. The vector of numeric derivative degrees to
calculate at. May only be set if |
trips |
Optional. A vector of |
... |
Other parameters (not used). |
Details
This function is the recommended way to use a fit trajectory function. It has a few key features:
Interpolation
There are three ways to interpolate: finding distance from times (direct
trajectory function), times from distance (inverse trajectory function),
or timesteps over a distance range (both inverse and direct trajectory
function). For the former two, either a vector or dataframe of
new_times or new_distances may be provided. If a dataframe is
provided, it must contain the column event_timestamp or distance,
and all additional columns will be preserved through the interpolation.
Distances from Times
If new_times is provided, the function will find the distance of each
trip at each point in time. If a dataframe is provided, it must contain
the column event_timestamp. This will use the trajectory's direct function.
When using new_times, a deriv value can also be set greater than 0.
See below for a more detailed discussion.
Times from Distances
If new_distances is provided, the function will find the event_timestamp
of each trip at each point in space. If a dataframe is provided, it must
contain the column distance. This will use the trajectory's
inverse function. When using new_distances, a deriv value cannot
be set greater than 0. See below for a more detailed discussion.
Time & Distance Pairs from Distance Bounds
Oftentimes, you may want to interpolate by small timesteps over a defined
region of space. This can be done by setting distance_lims and
timestep. The function will use the trajectory's inverse function to find
each trip's entrance and exit time through distance_lims, then create
a sequence between these entrance and exit times with a step of timestep.
Finally, the trajectory's direct function is used to find the distance
at each of these timepoints. A deriv value can also be set greater
than 0 for the final direct interpolation.
If you have a well-defined region of space, this approach allows you to
interpolate vehicle positions at a very tight timescale over a large
number of trips efficiently. You could alternatively use new_times to
interpolate over the entire time range of all trips (which wouldn't
require an inverse function), though this may require orders of magnitude
more points and would be substantially less efficient.
Finding Derivatives
Depending on the interp_method used when fitting the trajectory object,
a derivative may be able to be found:
-
interp_method = "linear": This will not allow derivatives. This is because, at each observation, the piecewise linear function is not differentiable. -
interp_methodis a spline fromstats::splinefun(): This will typically be differentiable up to the third degree (i.e.,deriv = 0is position,deriv = 1is speed, etc.).
The derivative returned (as column interp) is the derivative of distance
with respect to time. This means the first derivative is velocity, second is
acceleration, and third is jerk. The derivative is taken from the direct
trajectory, not the inverse, and the inverse trajectory cannot be used to
find derivatives. This means that if new_distances is provided, deriv
must equal 0. If starting from distance values, but derivatives are desired,
consider interpolating for timepoints first, then using these as new_times
to find the derivative.
Prevents Extrapolation
By default, many interpolating curves provided by R and stats will allow
extrapolation (i.e., the input of an event_timestamp or distance beyond
the original time or space domain of the
trip). In general, this will not be reasonable for transit vehicles:
time points should be constrained by the time that a trip has actually
been observed, and distances should be constrained to the part of a route
a trip actually ran.
This function uses the maximum and minimum time and distance values stored
in the trajectory object to identify if an input new_times or
new_distances is beyond the domain/range of each trip individually. The
returned output will only include interp values for trips within the
domain/range of the input.
Accessing the Raw Trajectory Function
Because of the above features and protections, it is recommend that these
predict() functions are used to access the fit trajectory and inverse
trajectory functions. However, if the raw function itself is desired,
it can be accessed using attr(trajectory, "traj_fun") or
attr(trajectory, "inv_traj_fun"). For a group trajectory object, these
will return lists of individual trip functions indexed by
trip_id_performed; for single trajectory objects, these will return the
single function for that trip.
Value
The input dataframe, with an additional column interp of the
interpolated values requested, and an additional trip_id_performed
column will all trips for which that point is within range. If new_times
or distance_lims/timestep are used, a column deriv will also be
included, indicating which derivative degree each interpolated row
corresponds to.
Examples
# Set my parameters
my_times = seq(from = 1779890000,
to = 1779893600,
by = 180)
my_distances = seq(from = 100,
to = 35000,
by = 5000)
my_distance_lims = c(500, 600)
my_timestep = 10
# Get input data
lineE_traj <- new_transittraj_data("get_trajectory_fun")
# Run function: get distances from times
interp_dists <- predict(object = lineE_traj,
new_times = my_times)
dim(interp_dists)
head(interp_dists)
# Run function: get speeds from times
interp_speeds <- predict(object = lineE_traj,
new_times = my_times,
deriv = 1)
dim(interp_speeds)
head(interp_speeds)
# Run function: get times from distances
interp_times <- predict(object = lineE_traj,
new_distances = my_distances)
dim(interp_times)
head(interp_times)
# Run function: get time & distance pairs given distance bounds
interp_time_dist_pairs <- predict(object = lineE_traj,
distance_lims = my_distance_lims,
timestep = my_timestep)
dim(interp_time_dist_pairs)
head(interp_time_dist_pairs)
# Run function: vectorized derivatives
interp_vec <- predict(object = lineE_traj,
new_times = my_times,
deriv = c(0, 1, 2))
dim(interp_vec)
head(interp_vec)
Internal function to validate inputs to trajectory prediction methods.
Description
Checks that the proper combination of inputs is provided. Should be one of: new_times; new_distances; distance_lims AND timestep. If latter or new_distances, trajectory must also have inverse function. Derivative is also checked against maximum allowed.
Usage
predict_traj_input_validation(
new_times,
new_distances,
distance_lims,
timestep,
has_inv,
deriv,
max_deriv
)
Arguments
new_times |
A DF or vector of new time values, or |
new_distances |
A DF or vector of new distance values, or |
distance_lims |
A vector of min, max distance, or |
timestep |
An integer for interpolation timestep, or |
has_inv |
Boolean, does traj have inv fun? |
deriv |
vector of numeric derivs to interpolate at |
max_deriv |
Maximum derivative supported by traj fun |
Value
Throws error only if not all OK
Internal function to set up dataframe for interpolating timesteps between distance limits.
Description
Internal function to set up dataframe for interpolating timesteps between distance limits.
Usage
predict_traj_setup_dist_lims(
trajectory,
trip_extremes,
distance_lims,
timestep,
deriv
)
Arguments
trajectory |
trajectory object |
trip_extremes |
DF of trip time & distance extremes |
distance_lims |
a vector of (min, max) distance |
timestep |
time interval for interpolation |
deriv |
vector of numeric derivs to interpolate at |
Value
DF of trip IDs & times to interpolate at
Internal function to set up dataframe for interpolating times from distances
Description
Internal function to set up dataframe for interpolating times from distances
Usage
predict_traj_setup_new_dists(new_distances, trip_extremes)
Arguments
new_distances |
new distances to interpolate at |
trip_extremes |
DF of trip time & distance extremes |
Value
DF of trip IDs & distances to interpolate at
Internal function to set up dataframe for interpolating distances from times
Description
Internal function to set up dataframe for interpolating distances from times
Usage
predict_traj_setup_new_times(new_times, trip_extremes, deriv)
Arguments
new_times |
new event_timestamps to interpolate at |
trip_extremes |
DF of trip time & distance extremes |
deriv |
vector of numeric derivs to interpolate at |
Value
DF of trip IDs & times to interpolate at
Print an AVL trajectory object
Description
This function prints a one-line report for grouped or single trajectory objects. For a single trajectory, the trip ID will be printed. For grouped trajectories, the number of trips will be printed.
Usage
## S3 method for class 'avltrajectory_group'
print(x, ...)
## S3 method for class 'avltrajectory_single'
print(x, ...)
Arguments
x |
A single or grouped trajectory object. |
... |
Other parameters (not used). |
Value
A printing character string.
Examples
# Get input data
lineE_traj_grouped <- new_transittraj_data("get_trajectory_fun")
lineE_traj_singles <- new_transittraj_data("get_trajectory_fun_single")
# Print: Grouped trajectory object
print(lineE_traj_grouped)
# Print: Single trajectory object
print(lineE_traj_singles[[2]])
Print a trajectory summary.
Description
Internal functions for printing group and single trajectory summaries.
Usage
## S3 method for class 'summary.avltrajectory_group'
print(x, ...)
## S3 method for class 'summary.avltrajectory_single'
print(x, ...)
Arguments
x |
A single or trajectory summary object, returned by summary(). |
... |
Other parameters (not used). |
Value
Prints summary to console, invisibly returns input object.
Examples
lineE_traj <- new_transittraj_data("get_trajectory_fun")
lineE_summ <- summary(lineE_traj)
print(lineE_summ)
Project points to linear distances along a route
Description
This function takes spatial points and projects them onto a route (i.e., "snaps" them to the nearest point on the shape), returning the linear distance of each point along the route shape, starting from the route's beginning terminal.
Usage
project_onto_route(
shape_geometry,
points,
original_crs = 4326,
project_crs = 4326
)
Arguments
shape_geometry |
The SF object to project onto. Must include the field
|
points |
Can be either: a dataframe representing point coordinates,
with fields |
original_crs |
Optional. A numeric EPSG identifier. If a dataframe is
provided for |
project_crs |
Optional. A numeric EPSG identifer indicating the coordinate system to use for spatial calculations. Consider setting to a Euclidian projection, such as the appropriate UTM zone. Default is 4326 (WGS 84 ellipsoid). |
Value
The points input (either dataframe or SF) with an appended column
for the linear distance along the route. If points is an SFC, a vector of
numeric distances is returned. Units are those of the spatial projection
set in project_crs (e.g., meters if using WGS UTM).
Examples
# Set my parameters
my_crs <- 32611
# Get shape data
lineE_shape <- new_transittraj_data("get_shape_geometry")
# Set points of interest
my_points <- data.frame(longitude = c(-118.270924, -118.230056),
latitude = c(34.033895, 34.047884),
poi_name = c("Flower & Washington",
"1st St Viaduct"))
# Run project_onto_route
my_points_proj <- project_onto_route(shape_geometry = lineE_shape,
points = my_points,
project_crs = my_crs)
head(my_points_proj)
Set global variables to use throughout, silencing notes during check.
Description
These variables are generally those expected in the standard data formats used, such as GTFS and TIDES. Whenever one of these variable names must be used, checks are performed to ensure they are present in the input data.
Summarize an AVL trajectory object
Description
This function creates and prints a list summarizing a single or grouped trajectory object. If the input is a single trajectory, the trip's ID and distance & time range will be printed. If the input is a grouped trajectory, the number of trips and the distance & time range across all trips will be printed. For both, the interpolating curve methods will be printed.
Usage
## S3 method for class 'avltrajectory_group'
summary(object, ...)
## S3 method for class 'avltrajectory_single'
summary(object, ...)
Arguments
object |
A single or grouped trajectory object. |
... |
Other parameters (not used). |
Value
A list summarizing the attributes of a fit trajectory.
Examples
# Get input data
lineE_traj_grouped <- new_transittraj_data("get_trajectory_fun")
lineE_traj_singles <- new_transittraj_data("get_trajectory_fun_single")
# Run function: grouped trajectory object
summary(lineE_traj_grouped)
# Run functions: store summary object
lineE_summ <- summary(lineE_traj_grouped)
print(lineE_summ$num_trips)
# Run function: single trajectory object
summary(lineE_traj_singles[[2]])
Remove observations occurring before a trip's minimum distance, or after a trip's maximum distance
Description
Sometimes AVL pings can be recorded under a trip ID while a vehicle is still traveling in the opposite direction. Conversely, a trip may continue recording as it begins traversing the opposite direction. This function attempts to remove these observations by identifying each trip's minimum (beginning) and maximum (ending) distance, then filtering to only observations between these points. For both ends, the first occurrence of the beginning/ending value is used.
Usage
trim_trips(distance_df, trim_type = "both", return_removals = FALSE)
Arguments
distance_df |
A dataframe of linearized AVL data. Must include
|
trim_type |
Optional. A string, indicating whether the beginning of
trips, end of trips, or both beginning and end of trips should be trimmed.
Must be one of |
return_removals |
Optional. A boolean, should the function return
a dataframe of points removed and why? Default is |
Value
The input distance_df with violating points removed. If
return_removals = TRUE, a dataframe with observations removed and why.
Examples
# Get input data
lineE_clean_trips <- new_transittraj_data("clean_incomplete_trips")
dim(lineE_clean_trips)
# Run function
lineE_trimmed <- trim_trips(distance_df = lineE_clean_trips)
dim(lineE_trimmed)
head(lineE_trimmed)
Function to quickly validate whether input GTFS has required tables and fields within those tables.
Description
Not intended for external use.
Usage
validate_gtfs_input(gtfs, table, needed_fields)
Arguments
gtfs |
tidygtfs. |
table |
The gtfs table to look for. |
needed_fields |
fields in that table to look for. |
Value
Throws error if not satisfied
Uses validate_tides and an input vector of needed fields to check whether
an AVL DF meets the requirements of a given function.
Description
Intended for internal use only.
Usage
validate_input_to_tides(needed_fields, avl_df)
Arguments
needed_fields |
Vector of fields desired |
avl_df |
DF of TIDES AVL data |
Value
boolean for each field
Check if AVL data satisfies assumptions of monotonicity
Description
This function checks whether the provided AVL dataframe of linearized distances satisfies three conditions:
Weak monotonicity, either flat or increasing
Strict monotonicty, increasing only
Fritsch-Carlson constraints for speeds
See make_monotonic() for more information.
Usage
validate_monotonicity(distance_df, check_speed = FALSE, return_full = FALSE)
Arguments
distance_df |
A dataframe of linearized AVL data. Must include
|
check_speed |
Optional. A boolean, should the Fritsch-Carlson conditions
for slopes be checked? Default is |
return_full |
Optional. Should a dataframe of each point checked be
returned? Default is |
Value
A named vector of booleans indicating whether each of the three conditions are satisfied.
Examples
# Get & test non-monotonic dataset
lineE_dists <- new_transittraj_data("get_linear_distances")
lineE_dists_val <- validate_monotonicity(lineE_dists, check_speed = TRUE)
print(lineE_dists_val)
# Get & test monotonic dataset
lineE_mono <- new_transittraj_data("make_monotonic")
lineE_mono_val <- validate_monotonicity(lineE_mono, check_speed = TRUE)
print(lineE_mono_val)
Function to quickly validate whether an input shape_geometry meets needs
Description
Checks:
Class (should be SF, not SFC)
Geometry type (i.e., is multilinestring)
Presence of shape_id column, if desired
Number of shapes present, if desired
Correct CRS, if desired
Usage
validate_shape_geometry(
shape_geometry,
max_length = Inf,
require_shape_id = TRUE,
match_crs = NULL
)
Arguments
shape_geometry |
SF multilinestring |
max_length |
numeric of max number of objects in SF |
require_shape_id |
should shape ID be required in SF? |
match_crs |
CRS that SF should have |
Details
Not intended for external use.
Value
Throws error if not satisfied
Check if AVL data meets TIDES standards
Description
The transit integrated data exchange standard (TIDES) specifies columns that
should be present in AVL data tables and the data types of these columns.
This function verifies if those columns are present in the input avl_df
are of the correct data type. See Details for more information.
Usage
validate_tides(avl_df)
Arguments
avl_df |
A dataframe of AVL data, either in GPS (longitude/latitude) form or linearized distance form. |
Details
The AVL cleaning functions in this package generally require the input
dataframes to adhere to the TIDES vehicle_locations
table schema. The
following columns and data types are checked by this validator:
-
location_ping_id: Should be acharacterstring. -
trip_id_performed: Should be acharacterstring. -
event_timestamp: Should be aPOSIXctdate-time. -
vehicle_id: Should be acharacterstring. -
operator_id: Should be acharacterstring. This field is not standard in TIDESvehicle_locations, and is not a strict requirement for any AVL processing functions. -
longitudeandlatitude: Should benumeric. These fields are required only to linearize AVL data, and not used afterwards. -
distance: Should benumeric. This field is not standard in TIDESvehicle_locations, and is generated byget_linear_distances(). It is required by most other AVL processing functions. -
speed: Should benumeric. This field is not a strict requirement for any AVL processing functions.
Each AVL processing function in transittraj uses specific fields. Each
function verifies that the required fields and data types are present before
proceeding.
Value
A dataframe of each required field, required data type, whether the field is present, and whether the data type matches expectations.
Examples
lacmta_val <- validate_tides(avl_df = lacmta_avl)
print(lacmta_val)