knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
library(rcrisp) library(dplyr) library(sf) library(sfnetworks) bucharest_osm <- get_osm_example_data() bucharest_dem <- get_dem_example_data()
In this article we show how to set up the spatial network for a city before using it for urban river corridor delineation. We work with the OSM data for the city of Bucharest provided in rcrisp example data. See how to get your own OSM data in vignette("getting-osm-data")
.
We start by loading the OSM data. According to the delineation method, all persistent physical structures need to be considered. Therefore, the network will contain both streets and railways from OSM.
streets <- bucharest_osm$streets railways <- bucharest_osm$railways
Note: If the city in question contains other surface-level structures that need to be included in the network, such as above-ground metro lines, retrieve them with the appropriate OSM tags following the instructions in vignette("getting-osm-data")
and include them here in the network.
After combining the streets and railway lines, we create a network object.
network <- bind_rows(streets, railways) |> as_sfnetwork(directed = FALSE) |> activate("nodes") |> mutate(node_id = row_number())
To be able to use the network for delineation, we need to flatten it (that is, project bridges to the ground surface) and add nodes at all intersections between edges.
network_new <- flatten_network(network)
The function above first identifies unique apparent intersections between edges. Then it injects those points within the edge geometries (linestrings), so that they can be raised as network nodes in the cleaning step.
Note: sfnetworks::st_network_blend
cannot be used for this purpose, because this function only adds external points to one edge (the closest one).
We now perform standard cleaning tasks on the network: subdividing edges by adding missing nodes, removing pseudo-nodes and keeping only the main component of the network.
network_cleaned <- clean_network(network_new)
Visualize cleaned network:
network_new_nodes <- network_cleaned |> activate("nodes") |> filter(is.na(node_id)) |> activate("edges") |> filter(is.na(from) & is.na(to)) network_removed_nodes <- network |> activate("nodes") |> filter(!node_id %in% (activate(network_cleaned, "nodes") |> pull(node_id))) |> activate("edges") |> filter(is.na(from) & is.na(to)) par(mfrow = c(1, 2)) plot(network, col = "grey50", xlim = c(425100, 425400), ylim = c(4922400, 4923000), main = "Network before preprocessing") plot(network_cleaned |> activate("nodes"), col = "grey50", xlim = c(425100, 425400), ylim = c(4922400, 4923000), main = "Network after preprocessing") plot(network_new_nodes, col = "darkgreen", xlim = c(425100, 425400), ylim = c(4922400, 4923000), main = "Network after preprocessing", add = TRUE) plot(network_removed_nodes, col = "red", pch = 4, xlim = c(425100, 425400), ylim = c(4922400, 4923000), main = "Network after preprocessing", add = TRUE)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.