The in this repo is intended to demonstrate how to use
od2net
to generate route networks and to compare the workflow, and results,
with the R-based approach currently used in the NPT project.
The following is based on od2net
’s
docs
and the code in the examples/edinburgh folder.
Setup the files in the input folder as follows:
source("R/setup.R")
main()
Run the tool with Docker as follows:
# Time it:
docker run -v $(pwd):/app ghcr.io/urban-analytics-technology-platform/od2net:main /app/config.json
# Summary:
# - Load network took 100.799767ms
# - Loading origins took 175.604547ms
# - Loading destinations took 174.229604ms
# - Loading zones from /app/input/zones.geojson took 714.082µs
# - Matching points to zones took 54.914894ms
# - Generating requests from /app/input/od.csv took 659.614µs
# - Loading or generating requests took 406.16771ms
# - Building RTree for matching request points to OSM nodes took 16.235263ms
# - Routing took 56.808164ms
# - Writing output CSV took 18.805512ms
# - Writing output GJ took 125.66129ms
# - Converting to pmtiles for rendering took 7.733441909s
# - everything took 8.441747553s
After that you should see the following in the output folder:
fs::dir_tree("output")
output
├── counts.csv
├── output-r.geojson
├── output.geojson
└── rnet.pmtiles
library(tidyverse)
od = readr::read_csv("input/od.csv")
zones = sf::read_sf("input/zones.geojson")
desire_lines = od::od_to_sf(od, zones)
# Requires API key:
system.time({
routes = cyclestreets::batch(desire_lines, username = "robinlovelace", wait = TRUE)
})
# 133 seconds
rnet = stplanr::overline(routes, attrib = "count")
sf::write_sf(rnet, "output/output-r.geojson")
output_od2net = sf::read_sf("output/output.geojson")
output_r = sf::read_sf("output/output-r.geojson")
sum(sf::st_length(output_od2net))
2432481 [m]
sum(sf::st_length(output_r))
1192642 [m]
names(output_od2net)
[1] "backward_cost" "count" "destination_count"
[4] "forward_cost" "length" "lts"
[7] "nearby_amenities" "node1" "node2"
[10] "origin_count" "osm_tags" "slope"
[13] "way" "geometry"
names(output_r)
[1] "count" "geometry"
summary(output_od2net$way)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
1.370e+02 5.368e+06 7.098e+07 2.546e+08 3.613e+08 1.313e+09 13596
sum(output_od2net$count * sf::st_length(output_od2net), na.rm = TRUE) |>
units::set_units("km")
34685.34 [km]
sum(output_r$count * sf::st_length(output_r), na.rm = TRUE) |>
units::set_units("km")
83155.09 [km]
# Vs flow implied from desire lines (expectation: ~1.3 x this amount):
sum(desire_lines$count * sf::st_length(desire_lines), na.rm = TRUE) |>
units::set_units("km")
30394.87 [km]
output_combined = bind_rows(
output_od2net |>
filter(!is.na(way)) |>
# Only large counts:
filter(count > 5) |>
mutate(source = "od2net"),
output_r |>
mutate(source = "R") |>
filter(count > 5)
)
central_edinburgh = zonebuilder::zb_zone("Edinburgh", n_circles = 2)
output_combined = output_combined |>
sf::st_intersection(central_edinburgh)
output_combined |>
ggplot() +
geom_sf(aes(colour = count)) +
scale_colour_viridis_c() +
facet_wrap(~source) +
theme_void()
Run the code on a computer with Ubuntu 22.04 after running the setup outlined in the link above.
gh repo clone Urban-Analytics-Technology-Platform/od2net
# Copy the example to this folder:
cp -r od2net/examples/edinburgh/* .
cp -r od2net/
# Setup quarto-publish: