Skip to content

Latest commit

 

History

History
175 lines (137 loc) · 4.14 KB

README.md

File metadata and controls

175 lines (137 loc) · 4.14 KB

Demo of od2net

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.

od2net minimum example

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

R minimum example

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")

Comparison

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()

Setup

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: