library(CRiSp)
library(sf)
source("utils.R")CRiSp - an overview
Introduction
CRiSp implements a spatial morphological method of delineation (Forgaci, 2018) that considers both the topography of the river valley and the configuration of the urban fabric.
CRiSp has as main dependencies the “core” geospatial libraries in the R ecosystem:
Other relevant CRiSp dependencies and libraries that are used in this notebook are:
- sfnetworks - (geo)spatial networks handling and manipulation;
- osmdata - access OpenStreetMap data via the Overpass API;
- (leaflet - interactive visualization of geospatial datasets.)
We load the libraries required to run this notebook, and source a separate module (utils.R) that implements a few auxiliary functions which we make use of here:
Delineate in one shot!
The three types of morphological delineations implemented in CRiSp - corridor, segments, and river space - can be carried out via the delineate function, which works as main access point to the package.
We define the name of the city and of the river that define our Area of Interest (AoI):
city_name <- "Bucharest"
river_name <- "Dâmbovița"We can run the three delineations by calling the delineate function:
delineations <- delineate(
city_name,
river_name,
corridor = TRUE,
segments = TRUE,
riverspace = TRUE
)
#> The default `network_buffer` of 2500 m is used for corridor delineation.
#> The default `buildings_buffer` of 100 m is used for riverspace delineation.
#> Calculating viewpoints from both river edge and river centerline.Done! Let us visualize the results. delineations is a list, which contains:
1. The urban corridor surrounding the river, delineated on the street network along a path that is closest to the valley edge:
visualize(delineations$corridor)2. The corridor segments, bounded by the main transversal streets:
visualize(delineations$segments)3. The river space, i.e. the space between the river and the first line of buildings:
visualize(delineations$riverspace)A number of optional arguments can be specified as input to the delineate function - see the documentation page. For even more custom setups, one can run each step of the delineation independently.
Step by step
Let us go through the steps that are internally run by CRiSp when calling delineate. These are:
- Downloading the relevant datasets;
- Delineating the river valley;
- Delineating the river corridor;
- Segmenting the corridor;
- Delineating the river space.
1. Getting the data
Default data sources in CRiSp are:
- OpenStreetMap (OSM) for city boundaries, street & rail network, river geometry, buildings;
- GLO-30 Copernicus Digital Elevation Model (DEM) for the representation of the topographic surface of the area.
but any other data sources could be used as well!
CRiSp has the following built in functions that allows one to retrieve the required data from OSM:
network_buffer <- 2500 # in meters
buildings_buffer <- 100 # in meters
osmdata <- get_osmdata(
city_name,
river_name,
network_buffer = network_buffer,
buildings_buffer = buildings_buffer,
)network_buffer and building_buffer
These parameters define the size of the buffer regions around the river to retrieve network data (i.e. streets and railways) and buildings, respectively.
The returned list osmdata contains the following assets:
names(osmdata)
#> [1] "bb" "boundary" "river_centerline" "river_surface"
#> [5] "aoi_network" "streets" "railways" "aoi_buildings"
#> [9] "buildings"Let us visualize e.g. the streets:
visualize(osmdata$streets)and the river surface and its center line:
visualize(osmdata$river_centerline, osmdata$river_surface)For the Copernicus DEM, we consider a slightly larger AoI than what used to retrieve the network data. This is because the valley boundary delineation can create some artifacts close to the DEM raster edges. It is “safer” to add some extra space around the actual AoI:
dem_buffer <- 2500 # in meters
crs <- st_crs(osmdata$river_centerline)
aoi_dem <- st_buffer(osmdata$aoi_network, dem_buffer)
dem <- get_dem(aoi_dem, crs = crs)Let us visualize the retrieved DEM, together with the river center line:
visualize(dem, osmdata$river_centerline)2. Valley delineation
In a typical CRiSp workflow, the valley delineation is used in the context of corridor delineation. First, the river valley is extracted from the DEM, and then the resulting valley edge is used to “guide” the delineation of the corridor on the street network.
The valley delineation is based on a cost distance analysis carried out on the DEM, variants of which have been used for the delineation of wet area mapping and valley bottom in non-urban contexts(Ågren et al., 2014; Murphy et al., 2009; White et al., 2012).
We use the combined geometry of the river surface and its center line as target geometry (where to compute cost-distance to), and run the valley delineation using delineate_valley:
river <- c(osmdata$river_centerline, osmdata$river_surface)
valley <- delineate_valley(dem, river)The resulting valley edge looks like the following:
visualize(dem, st_boundary(valley), osmdata$river_centerline)3. Corridor delineation
The valley boundary is used as a template to guide the delineation of the corridor on the street and railway network.
We first build the spatial network used for the delineation, using the street and the railway lines. Preparing the network involves some preprocessing (“cleaning”) steps: missing nodes are added, pseudo-nodes and disconnected components are dropped. We also make sure that the network is “flattened”, i.e. we add nodes at all apparent intersections (e.g. at overpasses/bridges). The network, in fact, serves the purpose of urban morphology delineation and might not reflect actual connectivity between nodes.
network_edges <- c(osmdata$streets$geometry, osmdata$railway$geometry)
network <- as_network(network_edges, clean = TRUE, flatten = TRUE)corridor <- delineate_corridor(
network,
river_centerline = osmdata$river_centerline,
river_surface = osmdata$river_surface,
dem = dem
)The function delineate_corridor actually runs the valley delineation internally, so only the DEM is required as input. CRiSp also implements a simpler approach based on a spatial buffer built around the river as an alternative method to guide the corridor delineation (initial_method = "buffer").
And here is the corridor:
visualize(corridor)4. Corridor segmentation
As the second step of the delineation based on the street and railway network, we subdivide the river corridor into segments. This analysis is focused on the river corridor area, and we can thus crop the spatial network using its boundary, leaving only a small buffer region around it (100 m):
network_filtered <- filter_network(network, corridor, buffer = 100)We then delineate segments in the corridor. The algorithm spits the corridor using river-crossing transversal edges that form continuous lines in the network:
segments <- delineate_segments(
corridor,
network_filtered,
osmdata$river_centerline
)rcoins
The continuous strokes in the spatial network are identified using the Continuity in Street Networks (COINS) method (Tripathy et al., 2020), which is implemented as a separate library: rcoins
This is the result of the corridor segmentation:
visualize(segments)5. River space delineation
River space delineation is a delineation step that uses the river and buildings as input to generate a polygon representing the space between the river and the first line of buildings.
We use again the combined geometry of the river surface and its center line as source for the visibility analysis:
riverspace <- delineate_riverspace(osmdata$river_surface, osmdata$buildings)visor
The river space is computed as an isovist using the river geometry as “viewpoint”. The algorithm that carries out this analysis is implemented in the visor package.
Here is the resulting river space geometry:
visualize(riverspace)