Skip to content

Commit

Permalink
Merge branch 'main' into claudiu/bb-in-part4
Browse files Browse the repository at this point in the history
  • Loading branch information
cforgaci authored May 17, 2024
2 parents 902dc44 + 55f94da commit cb6dd2b
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/sandpaper-version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.16.2
0.16.4
16 changes: 8 additions & 8 deletions .github/workflows/workshop-setup.yml
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
# A workflow for testing the workshop setup in different operating systems

name: Test Workshop Setup
name: Test Workshop Setup

# Controls when the action will run. Workflow runs when manually triggered using the UI
on:
workflow_dispatch:

jobs:
workshop_setup:
runs-on: ${{matrix.os}}
strategy:
matrix:
# list of Os's
R: ['4.3.3']
R: ['4.4.0']
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- name: Setup R
uses: r-lib/actions/setup-r@v2
with:
r-version: ${{matrix.R}}
rtools-version: '43'
rtools-version: '44'
- run: Rscript -e 'print("R was installed successfully")'
- name: Install GDAL, GEOS, and PROJ.4 (macOS)
if: matrix.os == 'macos-latest'
run: |
run: |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew update
brew tap osgeo/osgeo4mac && brew tap --repair
Expand All @@ -34,7 +34,7 @@ jobs:
shell: bash
- name: Install GDAL, GEOS, and PROJ.4 (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
run: |
sudo add-apt-repository ppa:ubuntugis -y
sudo apt-get update
sudo apt-get install libgdal-dev libgeos-dev libproj-dev -y
Expand All @@ -50,10 +50,10 @@ jobs:
with:
cache-version: 2
packages: |
any::sessioninfo
any::sessioninfo
any::tidyverse
any::terra
any::sf
- name: Test Lessons
run: |
run: |
Rscript -e 'nc <- sf::st_read(system.file("shape/nc.shp", package="sf"), quiet = TRUE); if (sf::st_crs(sf::st_transform(nc, 4326))$epsg == 4326) print("`sf` works as expected"); if (nrow(dplyr::filter(nc, AREA > 0.2)) == 11) print("`tidyverse` works as expected")'
44 changes: 18 additions & 26 deletions episodes/18-import-and-visualise-osm-data.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ assign("has_internet_via_proxy", TRUE, environment(curl::has_internet))

### Bounding box

The first thing to do is to define the area within which you want to retrieve data, aka the *bounding box*. This can be defined easily using a place name to access the free Nominatim API provided by OpenStreetMap.
The first thing to do is to define the area within which you want to retrieve data, aka the *bounding box*. This can be defined easily using a place name and the package `osmdata` to access the free Nominatim API provided by OpenStreetMap.

We are going to look at *Brielle* together.

Expand All @@ -58,21 +58,19 @@ Beware that downloading and analysing the data for larger cities might be long,

::::::::::::::::::::::::::::::::::::::::::::::::

We first geocode our spatial text search and extract the corresponding bounding box (`getbb`).

We first geocode our spatial text search and extract the corresponding polygon (`geo_lite_sf`) and then extract its bounding box (`st_bbox`).
```{r nominatim}
library(osmdata)
```{r}
bb <- getbb("Brielle")
bb <- osmdata::getbb("Brielle")
bb
### OR
#install.packages("osmdata")
# library(osmdata)
# bb <- getbb("Brielle")
```

::::::::::::::::::::::::::::::::::::: callout

### Overpass query unavailable without internet

If you encounter an error linked to your internet proxy ("Error: Overpass query unavailable without internet R"), run this line of code. It might not be needed, but ensures that your machine knows it has internet.

```{r}
Expand All @@ -93,7 +91,7 @@ For example: Brielle (Netherlands) and Brielle (New Jersey)

By default, `getbb()` from the `osmdata` package returns the first item. This means that regardless of the number of returned locations with the given name, the function will return a bounding box and it might be that we are not looking for the first item. We should therefore try to be as unambiguous as possible by adding a country code or district name.

```{r}
```{r bbox}
bb <- getbb("Brielle, NL")
bb
```
Expand Down Expand Up @@ -130,11 +128,7 @@ It appears that there is a function to extract features, using the Overpass API.
On this page we can read about the arguments needed for each function: a bounding box for `opq()` and some `key` and `value` for `add_osm_feature()`. Thanks to the examples provided, we can assume that these keys and values correspond to different levels of tags from the OSM classification. In our case, we will keep it at the first level of classification, with "buildings" as `key`, and no value. We also see from the examples that another function is needed when working with the `sf` package: `osmdata_sf()`. This ensures that the type of object is suited for `sf`. With these tips and examples, we can write our feature extraction function as follows:


```{r}
#install.packages("osmdata")
library(osmdata)
```{r osm}
x <- opq(bbox = bb) %>%
add_osm_feature(key = 'building') %>%
osmdata_sf()
Expand All @@ -148,7 +142,7 @@ What is this `x` object made of? It is a data frame of all the buildings contain



```{r}
```{r strbuildings}
str(x$osm_polygons)
```

Expand All @@ -164,7 +158,7 @@ Let's map the building age of post-1900 Brielle buildings.

First, we are going to select the polygons and reproject them with the Amersfoort/RD New projection, suited for maps centred on the Netherlands. This code for this projection is: 28992.

```{r}
```{r transform}
buildings <- x$osm_polygons %>%
st_transform(.,crs=28992)
```
Expand All @@ -183,7 +177,7 @@ Then we create a new variable using the threshold at 1900. Every date before 190

Then we use the `ggplot()` function to visualise the buildings by age. The specific function to represent information as a map is `geom_sf()`. The rest works like other graphs and visualisation, with `aes()` for the aesthetics.

```{r}
```{r map}
start_date <- as.numeric(buildings$start_date)
buildings$build_date <- if_else(start_date < 1900, 1900, start_date)
Expand Down Expand Up @@ -236,22 +230,20 @@ extract_buildings("Naarden, NL")

::::::::::::::::::::::::::::::::::::: challenge

## Challenge: import an interactive basemap layer under the buildings with `Leaflet` (20min)
## Challenge: import an interactive basemap layer under the buildings with 'Leaflet' (20min)

Leaflet is a ["open-source JavaScript library for mobile-friendly interactive maps"](https://leafletjs.com/). Within R, the `leaflet` package allows you to build such interactive maps. As with `ggplot2`, you build a map with a collection of layers. In this case, you will have the leaflet basemap, some tiles, and shapes on top (such as markers, polygons, etc.).

- Check out the [leaflet package documentation](https://rstudio.github.io/leaflet/) and GDCU cheatsheet.
- Plot a basemap using `leaflet`
- Add a layer of tiles, for instance provider tiles [basemap documentation](https://rstudio.github.io/leaflet/basemaps.html)
- Transform the buildings into WGS84 projection
- Add the building layer to your leaflet map using the `addPolygons()` function.
- Use the `fillColor` of these polygons represent the `build_date` variable. See the [choropleth documentation](https://rstudio.github.io/leaflet/choropleths.html) DCU cheatsheet for how to use of colors in polygons.
- Check out the [leaflet package documentation](https://rstudio.github.io/leaflet/) and [GDCU cheatsheet](https://github.com/ClementineCttn/r-geospatial-urban/blob/main/instructors/cheatsheet/GDCU_cheatsheet.pdf).
- Plot a basemap in Leaflet and try different tiles in the [basemap documentation](https://rstudio.github.io/leaflet/basemaps.html)
- Transform the buildings into WGS84 projection and add them to the basemap layer with the `addPolygons()` function.
- Have the `fillColor` of these polygons represent the `build_date` variable. See the [choropleth documentation](https://rstudio.github.io/leaflet/choropleths.html) and [GDCU cheatsheet](https://github.com/ClementineCttn/r-geospatial-urban/blob/main/instructors/cheatsheet/GDCU_cheatsheet.pdf) for how use to use fill colors in polygons. Tip: use the examples given in the documentation and replace the variable names where needed.

:::::::::::::::::::::::: solution

## One solution

```{r}
```{r leaflet}
#install.packages("leaflet")
library(leaflet)
Expand Down
24 changes: 14 additions & 10 deletions episodes/19-basic-gis-with-r-sf.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ knitr::opts_chunk$set(warning = FALSE, message = FALSE)
```


```{r message=FALSE}
```{r packages, message=FALSE}
library(tidyverse)
library(sf)
library(osmdata)
library(leaflet)
library(lwgeom)
assign("has_internet_via_proxy", TRUE, environment(curl::has_internet))
```
Expand All @@ -48,8 +49,9 @@ Let's focus on old buildings and imagine we're in charge of their conservation.

Let's select them and see where they are.

```{r}
bb <- getbb("Brielle, NL")
```{r recap}
bb <- osmdata::getbb("Brielle, NL")
x <- opq(bbox = bb) %>%
add_osm_feature(key = 'building') %>%
osmdata_sf()
Expand All @@ -75,6 +77,8 @@ old_buildings <- buildings %>%

::::::::::::::::::::::::::::::::::::: callout

### Overpass query unavailable without internet

If you encounter an error linked to your internet proxy ("Error: Overpass query unavailable without internet R"), run this line of code. It might not be needed, but ensures that your machine knows it has internet.

```{r}
Expand All @@ -89,7 +93,7 @@ As conservationists, we want to create a zone around historical buildings where

Let's say the conservation zone should be 100 meters. In GIS terms, we want to create a _buffer_ around polygons. The corresponding `sf` function is `st_buffer()`, with 2 arguments: the polygons around which to create buffers, and the radius of the buffer.

```{r}
```{r buffer}
distance <- 100 # in meters
#First, we check that the "old_buildings" layer projection is measured in meters:
Expand All @@ -109,7 +113,7 @@ ggplot(data = buffer_old_buildings) +

Now, we have a lot of overlapping buffers. We would rather create a unique conservation zone rather than overlapping ones in that case. So we have to fuse the overlapping buffers into one polygon. This operation is called _union_ and the corresponding function is `st_union()`.

```{r}
```{r union}
single_old_buffer <- st_union(buffer_old_buildings) %>%
st_cast(to = "POLYGON") %>%
st_as_sf()
Expand All @@ -128,7 +132,7 @@ We create unique IDs to identify the new polygons.
## Centroids
For the sake of visualisation speed, we would like to represent buildings by a single point (for instance: their geometric centre) rather than their actual footprint. This operation means defining their _centroid_ and the corresponding function is `st_centroid()`.

```{r}
```{r centroids}
sf::sf_use_s2(FALSE) # s2 works with geographic projections, so to calculate centroids in projected CRS units (meters), we need to disable it.
centroids_old <- st_centroid(old_buildings) %>%
Expand All @@ -144,7 +148,7 @@ ggplot() +
Now, we would like to distinguish conservation areas based on the number of historic buildings they contain. In GIS terms, we would like to know how many centroids each fused buffer polygon contains. This operation means _intersecting_ the layer of polygons with the layer of points and the corresponding function is `st_intersection()`.


```{r}
```{r intersection}
centroids_buffers <-
st_intersection(centroids_old,single_old_buffer) %>%
mutate(n = 1)
Expand Down Expand Up @@ -175,7 +179,7 @@ We aggregate them by ID number (`group_by(ID)`) and sum the variable `n` to know

Let's map this layer over the initial map of individual buildings, and save the result.

```{r}
```{r mapping}
p <- ggplot() +
geom_sf(data = buildings) +
geom_sf(data = single_buffer, aes(fill=n_buildings), colour = NA) +
Expand All @@ -202,7 +206,7 @@ The historical threshold now applies to all pre-war buildings, but the distance

:::::::::::::::::::::::: solution

```{r}
```{r parameters}
old <- 1939
distance <- 10
Expand Down Expand Up @@ -263,7 +267,7 @@ ggsave(filename = "fig/ConservationBrielle_newrules.png",

## Area

```{r}
```{r area}
single_buffer$area <- sf::st_area(single_buffer) %>%
units::set_units(., km^2)
Expand Down
Binary file added instructors/cheatsheet/GDCU_cheatsheet.pdf
Binary file not shown.
Binary file added instructors/cheatsheet/GDCU_cheatsheet.pptx
Binary file not shown.
Binary file added instructors/cheatsheet/fig/Rbanism.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added instructors/cheatsheet/fig/sf.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added instructors/cheatsheet/~$GDCU_cheatsheet.pptx
Binary file not shown.
Loading

0 comments on commit cb6dd2b

Please sign in to comment.