The abstr
package was originally developed as part of
the ActDev project, which involved the development of a prototype web
application that provides evidence on active travel provision and
potential in and around planned and proposed development sites, as
outlined in a paper describing the
tool. The ActDev website
demonstrates the potential for new developments to support walking and
cycling by visualising data generated using reproducible R code. A key
challenge was to create a simulation for each of the case study sites
based on the input origin-destination datasets. To overcome this
challenge, A/B Street developers were commissioned to extend the ActDev
tool to enable real time simulation of scenarios of change. At the time
there was no way to get the OD data we had in the R world into the A/B
Street world. This was motivation for creating the abstr
R
package. As outlined in the package’s README, the package’s main job is
to take origin-destination data from .csv
files (and other
tabular file types) and outputs .json
files that can be
imported and visualised in A/B Street.
Given you have all of the above, you are ready to start transforming data-frames into simulations! So lets set an aim for the vignette
####
####
#### AIM: Use PCT data to create scenario of change where commuting cycling levels increase and car journeys decrease which can be imported
#### into A/B Street city simulation software. This method should be fully reproducible for all other pct_regions.
####
####
While the PCT is a powerful and popular tool for strategic cycleway planning it has some key limitations that are addressed by A/B Street:
This vignette aims to demonstrate how data from the PCT, which
provides evidence-based visions of how cycling could become the natural
choice for urban travel, can be visualised in A/B Street to overcome the
limitations outlined above. The first stage is to install the necessary
packages (see the abstr
vignette for a detailed introduction to software requirements).
To begin with, you need to install and load the necessary packages for this vignette.
Data in the PCT for England and Wales is divided into regions, which can be seen below.
To run the example below, replace devon
with a different
region from the list above (warning, this may not work for large
regions).
You can select a specific local authority of interest from those available in the region of interest. You can check which are available in your region of interest as follows:
For the purposes of this article we will use Exeter as the case study:
Next you want to fetch two types of PCT data. Firstly, zone data,
which is gathered using the get_pct_zones()
function and is
filtered to only include a local authority of choice, in this example we
use Exeter. Secondly, commute data, which is gathered using the
get_pct_lines()
function and is also filtered to only
include trips within the local authority.
#### READ DATA ####
devon_zones = get_pct_zones(region = region_name, geography = "msoa") # get zone data
# filter for exeter
exeter_zones = devon_zones %>% filter(lad_name == lad_name) %>%
select(geo_code)
# get commute od data
exeter_commute_od = get_pct_lines(region = region_name, geography = "msoa") %>%
filter(lad_name1 == lad_name & lad_name2 == lad_name) # filter for exeter
Now you have your data, its time to clean and transform it. In fact,
you only need to transform the exeter_commute_od
dataframe
as the exeter_zones
is already in abstr
format. The first step in cleaning the data requires renaming variables
so that we can clearly see the difference between the base scenario and
the scenario of change. Next, you calculate the scenario of change, in
this example we use the uptake_pct_godutch_2020()
function
which takes two arguments of distance
and
gradient
in its model calculation. The results from this
PCT function allow you to calculate the mode shift from driving to
cycling. Finally, we subset the data to only include the columns which
are needed to progress.
exeter_commute_od = exeter_commute_od %>%
mutate(cycle_base = bicycle) %>%
mutate(walk_base = foot) %>%
mutate(transit_base = bus + train_tube) %>% # bunch of renaming -_-
mutate(drive_base = car_driver + car_passenger + motorbike + taxi_other) %>%
mutate(all_base = all) %>%
mutate(
# create new columns
pcycle_godutch_uptake = uptake_pct_godutch_2020(distance = rf_dist_km, gradient = rf_avslope_perc),
cycle_godutch_additional = pcycle_godutch_uptake * drive_base,
cycle_godutch = cycle_base + cycle_godutch_additional,
pcycle_godutch = cycle_godutch / all_base,
drive__godutch = drive_base - cycle_godutch_additional,
across(c(drive__godutch, cycle_godutch), round, 0),
all_go_dutch = drive__godutch + cycle_godutch + transit_base + walk_base
) %>%
select(
# select variables for new df
geo_code1,
geo_code2,
cycle_base,
drive_base,
walk_base,
transit_base,
all_base,
all_go_dutch,
drive__godutch,
cycle_godutch,
cycle_godutch_additional,
pcycle_godutch
)
As a quick sanity check we can make sure our model has not generated any new commutes and we still have the same base number of commuters as before.
Now, you need to download OSM building data to populate the AB Street
simulation map. In this example we use the osmextract
package to fetch a PBF (protocolbuffer binary format) file hosted on
GeoFabrik. You then need to filter the contents of the PBF file to only
include the defined building types and subset the data to only include
osm_way_id, name, building
columns. Following this, you
should ensure you only include valid sf buildings and then aggregate the
building data against the zone boundary.
#### DOWNLOAD OSM BUILDING DATA ####
osm_polygons = osmextract::oe_read(
"https://download.geofabrik.de/europe/great-britain/england/devon-latest.osm.pbf",
# download osm buildings for region using geofabrik
layer = "multipolygons"
)
building_types = c(
"yes",
"house",
"detached",
"residential",
"apartments",
"commercial",
"retail",
"school",
"industrial",
"semidetached_house",
"church",
"hangar",
"mobile_home",
"warehouse",
"office",
"college",
"university",
"public",
"garages",
"cabin",
"hospital",
"dormitory",
"hotel",
"service",
"parking",
"manufactured",
"civic",
"farm",
"manufacturing",
"floating_home",
"government",
"bungalow",
"transportation",
"motel",
"manufacture",
"kindergarten",
"house_boat",
"sports_centre"
)
osm_buildings = osm_polygons %>%
filter(building %in% building_types) %>%
select(osm_way_id, name, building)
osm_buildings_valid = osm_buildings[sf::st_is_valid(osm_buildings), ]
exeter_osm_buildings_all = osm_buildings_valid[exeter_zones, ]
Subsequently, you can join the OSM buildings data with the
exeter_zones
geography in order to create the complete
building table. This table is filtered to not include any
NA's
and is aggregated to only include
#### JOIN OSM BUILDINGS WITH ZONE DATA ####
exeter_osm_buildings_all_joined = exeter_osm_buildings_all %>%
sf::st_join(exeter_zones)
exeter_osm_buildings_sample = exeter_osm_buildings_all_joined %>%
filter(!is.na(osm_way_id))
exeter_osm_buildings_tbl = exeter_osm_buildings_all %>%
filter(osm_way_id %in% exeter_osm_buildings_sample$osm_way_id)
You now have everything in place to generate AB Street scenarios for
both our base commute rate and our go_active commute rate. However,
abstr
takes a strict column name definition as to adhere to
the AB street documentation. This means you need to rename mode columns
for scenario generation. In order to make things easy, we can create a
simple logic gate that renames our mode columns depending on the boolean
value go_active
.
set.seed(2021) # for reproducible builds
#### LOGIC GATE ####
# Logic gate for go_dutch scenario of change, where cycling levels increase to a proportion reflecting the Netherlands.
# Switch to FALSE if you want census commuting OD
go_dutch = TRUE
if (go_dutch == TRUE) {
exeter_od = exeter_commute_od %>%
mutate(All = all_go_dutch) %>%
mutate(Bike = cycle_godutch) %>%
mutate(Transit = transit_base) %>%
mutate(Drive = drive_base) %>%
mutate(Walk = walk_base) %>%
select(geo_code1, geo_code2, All, Bike, Transit, Drive, Walk,geometry)
} else {
exeter_od = exeter_commute_od %>%
mutate(All = all_base) %>%
mutate(Bike = cycle_base) %>%
mutate(Drive = drive_base) %>%
mutate(Transit = transit_base) %>%
mutate(Walk = walk_base) %>%
select(geo_code1, geo_code2, All, Bike, Transit, Drive, Walk, geometry)
}
Voila, you are ready to generate simulation files from your
data-frames. Lets start by using the ab_scenario()
function
with our exeter_od
, exeter_zones
and
exeter_osm_buildings_tbl
data-frames.
#### GENERATE A/B STREET SCENARIO ####
output_sf = ab_scenario(
od = exeter_od,
zones = exeter_zones,
zones_d = NULL,
origin_buildings = exeter_osm_buildings_tbl,
destination_buildings = exeter_osm_buildings_tbl,
pop_var = 3,
time_fun = ab_time_normal,
output = "sf",
modes = c("Walk", "Bike", "Drive", "Transit")
)
To conclude you will need to generate a JSON
format
using the ab_json()
function and then save the json file to
your local machine using the ab_save()
function. (You can
download this file
from the repo’s releases.)
Now that you’ve generated a scenario, you can simulate it. First install the latest build of A/B Street for your platform. Run the software, and choose “Sandbox” on the title screen.
You can then change the default map to other cities across the world. A/B Street contains over 40 sites in England from the ActDev project. If the local authority you have generated a scenario for is not included, you can also import a new city from the user interface.
After loading the correct map, change the traffic scenario from the
default “weekday” or “none” pattern. Choose “import JSON scenario,” then
select your dutch
file.
After selecting your scenario, you should see something like this, a Go Dutch scenario of cycling taking place before your eyes, making the OD data frames come to life in a real time simulation!
Then let your eyes wonder on the simulation you have created and let your imagination explore the possibilities of transforming your local area into an active travel utopia.
This vignette is by no means simple, and if you get stuck please
raise an issue in the Github. If you
succeed in generating a simulation for chosen city please share it on
social media tagging the authors abstr
so we can see how
you have used the methods/data. If you are looking to extend this work
presented in this vignette, why not try:
getting
vignette from the pct
R package)