Skip to content

Commit

Permalink
Merge pull request #30 from CityRiverSpaces/22-osm-vignette-cf
Browse files Browse the repository at this point in the history
  • Loading branch information
cforgaci authored Oct 10, 2024
2 parents 1ad731b + 6d79a02 commit 206ce61
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 25 deletions.
11 changes: 6 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,26 @@ Description: CRiSp (City River Spaces) provides tools to automate the
License: Apache License (>= 2)
URL: https://cityriverspaces.github.io/CRiSp/
BugReports: https://github.com/CityRiverSpaces/crisp/issues
Depends:
R (>= 2.10)
Imports:
dplyr,
lwgeom,
osmdata,
rlang,
sf,
sfnetworks,
stringr,
tidygraph,
rlang
tidygraph
Suggests:
ggplot2,
knitr,
rmarkdown,
testthat (>= 3.0.0)
VignetteBuilder:
knitr
Config/testthat/edition: 3
Encoding: UTF-8
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.2
Depends:
R (>= 2.10)
LazyData: true
13 changes: 8 additions & 5 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ articles:
navbar: ~
contents:
- method
- getting-osm-data
- corridor-delineation
- corridor-segmentation
- riverspace-delineation
Expand All @@ -21,15 +22,17 @@ navbar:
menu:
- text: 1. The method
href: articles/method.html
- text: 2. Corridor delineation
- text: 2. Getting OSM data for delineation
href: articles/getting-osm-data.html
- text: 3. Corridor delineation
href: articles/corridor-delineation.html
- text: 3. Corridor segmentation
- text: 4. Corridor segmentation
href: articles/corridor-segmentation.html
- text: 4. Riverspace delineation
- text: 5. Riverspace delineation
href: articles/riverspace-delineation.html
- text: -------
- text: Use cases
- text: 5. Multiple delineations
- text: 7. Multiple delineations
href: articles/multiple-cities.html
- text: 6. Study area around a POI
- text: 8. Study area around a POI
href: articles/poi-study-area.html
19 changes: 18 additions & 1 deletion data-raw/bucharest.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,20 @@ bbox_buffer <- 2000

city_boundary <- get_osm_city_boundary(city_name) |>
st_transform(epsg_code)
st_crs(city_boundary)$wkt <- gsub("°|º", "\\\u00b0",
st_crs(city_boundary)$wkt)

bb <- getbb(city_name)
aoi <- define_aoi(bb, epsg_code, bbox_buffer)
bbox_expanded <- aoi |> st_transform(4326) |> st_bbox()

river_centerline <- osmdata_as_sf("waterway", "river", bb)$osm_multilines |>
filter(name == river_name) |>
st_transform(epsg_code) |>
st_geometry() |>
st_intersection(st_buffer(aoi, bbox_buffer))
st_crs(river_centerline)$wkt <- gsub("°|º", "\\\u00b0",
st_crs(river_centerline)$wkt)

river_surface <- osmdata_as_sf("natural", "water", bb)
river_surface <- river_surface$osm_multipolygons |>
Expand All @@ -27,18 +32,30 @@ river_surface <- river_surface$osm_multipolygons |>
st_filter(river_centerline, .predicate = st_intersects) |>
st_geometry() |>
st_union()
st_crs(river_surface)$wkt <- gsub("°|º", "\\\u00b0",
st_crs(river_surface)$wkt)

highway_values <- c("motorway", "primary", "secondary", "tertiary")
streets <- osmdata_as_sf("highway", highway_values, bb)
streets <- merge_streets(streets) |>
select("highway")
st_crs(streets)$wkt <- gsub("°|º", "\\\u00b0", st_crs(streets)$wkt)

railways <- osmdata_as_sf("railway", "rail", bbox_expanded)
railways_lines <- railways$osm_lines |>
select("railway") |> # only keep "railway" column
rename(type = `railway`) |> # rename it to "type"
st_transform(epsg_code)
st_crs(railways_lines)$wkt <- gsub("°|º", "\\\u00b0",
st_crs(railways_lines)$wkt)

bucharest <- list(
bb = bb,
boundary = city_boundary,
river_centerline = river_centerline,
river_surface = river_surface,
streets = streets
streets = streets,
railways_lines = railways_lines
)

usethis::use_data(bucharest, overwrite = TRUE)
Binary file modified data/bucharest.rda
Binary file not shown.
8 changes: 0 additions & 8 deletions tests/testthat/test-osm_bb.R

This file was deleted.

4 changes: 2 additions & 2 deletions vignettes/corridor-delineation.Rmd
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: "2. Corridor delineation"
title: "3. Corridor delineation"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{2. Corridor delineation}
%\VignetteIndexEntry{3. Corridor delineation}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
Expand Down
4 changes: 2 additions & 2 deletions vignettes/corridor-segmentation.Rmd
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: "3. Corridor segmentation"
title: "4. Corridor segmentation"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{3. Corridor segmentation}
%\VignetteIndexEntry{4. Corridor segmentation}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
Expand Down
181 changes: 181 additions & 0 deletions vignettes/getting-osm-data.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
---
title: "2. Getting OSM data for delineation"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{2. Getting OSM data for delineation}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
eval = FALSE
)
library(CRiSp)
city_boundary <- bucharest$boundary
railways_lines <- bucharest$railways_lines
highways_lines <- bucharest$streets
waterbody <- bucharest$river_surface
waterway <- bucharest$river_centerline
```

```{r packages, eval=TRUE, message=FALSE}
library(CRiSp)
library(dplyr)
library(ggplot2)
library(osmdata)
library(sf)
library(purrr)
```

In this notebook we download OSM data needed for urban river corridor delineation in Bucharest, Romania. We focus on one of the rivers and use a specific projected CRS for the analysis. Also, we make sure that we include a given area around the city boundaries.

```{r}
city_name <- "Bucharest"
river_name <- "Dâmbovița"
epsg_code <- 32635 # UTM zone 35N
bbox_buffer <- 2000 # in m, expand bbox for street network
```

We start by getting the bounding box for the study area, and expand it using the provided buffer:

```{r}
# bounding box
bbox <- getbb(city_name) |> as.vector()
names(bbox) <- c("xmin", "ymin", "xmax", "ymax")
bbox <- st_bbox(bbox, crs = 4326)
# bbox expanded
bbox_expanded <- bbox |>
st_as_sfc() |>
st_transform(crs = epsg_code) |> # transform to projected CRS
st_buffer(bbox_buffer) |>
st_transform(crs = 4326) |> # transform back to lat/lon
st_bbox()
```

## 1. City boundary

```{r}
# get city boundary
city_boundary <- osmdata_as_sf("place", "city", bbox)
city_boundary <- city_boundary$osm_multipolygons |>
st_transform(epsg_code) |>
st_geometry()
```

## 2. Waterways

Querying the Overpass API for `waterway:river`. OSM multilines include river lines grouped by the river name. We extract the relevant waterway and transform to the projected CRS:

```{r}
# waterways (linestrings)
waterways <- osmdata_as_sf("waterway", "river", bbox)
waterway <- waterways$osm_multilines |>
filter(name == river_name) |>
st_intersection(st_as_sfc(bbox_expanded)) |>
st_transform(epsg_code) |>
st_geometry()
```

We also query the Overpass API for `natural:water`. The results also include features such as fountains. The geometries are not contiguous and some part of the water bodies are actually represented as lines instead of polygons. We determine and keep the only features that intersect the relevant waterway:

```{r}
# water area (polygons)
water <- osmdata_as_sf("natural", "water", bbox)
waterbody <- bind_rows(water$osm_polygons, water$osm_multipolygons) |>
st_transform(epsg_code) |>
st_filter(waterway, .predicate = st_intersects) |>
st_union() |>
st_geometry()
```

## 3. Street network

Querying the Overpass API for the `highway` key, using the expanded bounding box to include relevant streets close to the edge of the city:

```{r}
highways_value <- c("motorway", "trunk", "primary", "secondary", "tertiary")
links_value <- sapply(X = highways_value,
FUN = \(x) sprintf("%s_link", x),
USE.NAMES = FALSE)
highways <- osmdata_as_sf("highway",
c(highways_value, links_value),
bbox_expanded)
```

As some of elements are returend as polygons (see e.g. [this tutorial](https://geospatial-community.netlify.app/post/2022-03-31-spatial-networks/)) we cast those too into lines and combine them with the rest of the street network:

```{r}
# cast polygons (closed streets) into lines
poly_to_lines <- highways$osm_polygons |>
st_cast("LINESTRING")
# combine all features in one data frame
highways_lines <- highways$osm_lines |>
bind_rows(poly_to_lines) |>
select("highway") |> # only keep "highway" column
rename(type = `highway`) |> # rename it to "type"
st_transform(epsg_code)
```

## 4. Rail network

Querying the Overpass API for the `railway:rail` key:tag, also using the expanded bounding box to include relevant ways close to the edge of the city:

```{r}
railways <- osmdata_as_sf("railway", "rail", bbox_expanded)
railways_lines <- railways$osm_lines |>
select("railway") |> # only keep "railway" column
rename(type = `railway`) |> # rename it to "type"
st_transform(epsg_code)
```

## Write OSM data to file

```{r}
st_write_list <- list(
city_boundary = bucharest$boundary,
waterway = bucharest$river_centerline,
waterbody = bucharest$river_surface,
highways = bucharest$streets,
railways = railways_lines
)
walk(
st_write_list,
~ st_write(
.x,
dsn = sprintf("%s_%s.gpkg",
names(st_write_list)[map_lgl(st_write_list,
identical,

Check warning on line 157 in vignettes/getting-osm-data.Rmd

View workflow job for this annotation

GitHub Actions / lint

file=vignettes/getting-osm-data.Rmd,line=157,col=54,[indentation_linter] Hanging indent should be 47 spaces but is 54 spaces.
.x)], city_name),
append = FALSE,
quiet = TRUE
)
)
```


## Visualise OSM data

```{r, eval=TRUE, fig.alt="All layers combined", fig.cap="All layers combined"}
if (requireNamespace("ggplot2", quietly = TRUE)) {
library(ggplot2)
ggplot() +
geom_sf(data = city_boundary, fill = "grey", color = "black") +
geom_sf(data = railways_lines, color = "orange") +
geom_sf(data = highways_lines, color = "black") +
geom_sf(data = waterbody, fill = "blue", color = "blue") +
geom_sf(data = waterway, color = "blue")
} else {
message("ggplot2 not available; skipping plot examples.")
}
```

4 changes: 2 additions & 2 deletions vignettes/riverspace-delineation.Rmd
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: "4. Riverspace delineation"
title: "5. Riverspace delineation"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{4. Riverspace delineation}
%\VignetteIndexEntry{5. Riverspace delineation}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
Expand Down

0 comments on commit 206ce61

Please sign in to comment.