A Mini Tour of Open-source tools for Transportation Planning & Engineering
ITE UWindsor Chapter
November 30th, 2023
Photo by Norali Nayla on Unsplash and snowflakes by Emil Hvitfeldt
Routing, Accessibility, and Transit
Tools for transport planning with an emphasis on spatial transport data and non-motorized modes
departure_datetime <- as.POSIXct("29-11-2023 14:00:00",
format = "%d-%m-%Y %H:%M:%S")
# calculate accessibility
access <- accessibility(r5r_core = r5r_core,
origins = points,
destinations = points,
opportunities_colnames = c("schools", "healthcare"),
mode = c("WALK", "TRANSIT"),
max_walk_time = 30,
departure_datetime = departure_datetime,
decay_function = "step",
cutoffs = 20
)
access_sf_schools <- access_sf |>
dplyr::filter(opportunity == "schools")
pal <- colorNumeric(
palette = "magma",
domain = access_sf_schools$accessibility)
access_sf_schools |>
leaflet() |>
addTiles() |>
addCircles(color = ~pal(accessibility), group = "Points") |>
addLegend("bottomright", pal = pal, values = ~accessibility,
title = "Access within 20 min.",
opacity = 1
) |>
addLayersControl(overlayGroups = c("Points"),
options = layersControlOptions(collapsed = FALSE))
# Install with: install.packages("tidytransit")
library(tidytransit)
library(sf)
gtfs <- read_gtfs("https://opendata.citywindsor.ca/Uploads/google_transit.zip")
names(gtfs)
[1] "agency" "shapes" "trips" "stops"
[5] "stop_times" "routes" "calendar" "calendar_dates"
[9] "feed_info" "fare_attributes" "fare_rules" "."
# get all service_ids for mondays
all_mondays <- gtfs$calendar %>%
filter(monday == 1) %>%
pull(service_id)
# select trips on mondays
selected_trips <- gtfs$routes %>%
left_join(gtfs$trips, by = "route_id") %>%
filter(service_id %in% all_mondays) # only take trips on mondays
# get linestrings for routes
selected_shapes <- gtfs$shapes %>%
filter(shape_id %in% unique(selected_trips$shape_id) )
shapes <- shapes_as_sf(selected_shapes)
# df with linestring, start and end time
windsor_transit <- selected_trips %>%
left_join (gtfs$stop_times, by = "trip_id") %>%
arrange(trip_id, stop_sequence) %>%
select(trip_id, route_id, shape_id, route_short_name, departure_time) %>%
group_by(trip_id, route_id, route_short_name, shape_id) %>%
summarise(starttime = first(departure_time),
endtime = last(departure_time)) %>%
left_join(shapes, by = "shape_id") %>%
st_as_sf() %>%
mutate(start_timestamp = as.numeric(as.POSIXct(starttime, format="%H:%M:%S"))) %>%
mutate(end_timestamp = as.numeric(as.POSIXct(endtime, format="%H:%M:%S"))) %>%
filter(!is.na(start_timestamp)) %>%
filter(!is.na(end_timestamp)) # for simlicity dates greater than 24h are ignored
windsor_transit