<!-- class: inverse, center, title-slide, middle --> class: center, middle <style> g { color: rgb(0,130,155) } r { color: rgb(174,77,41) } y { color: rgb(177,148,40) } </style> # Lecture 05: Geospatial Data Sciences # and Economic Spatial Models ## <img src="figs/bse_primary_logo.png" style="width: 35%" /><br><br>Bruno Conte ## 04-05/Feb/2026 --- # Geospatial Data and Spatial Models: Schedule 1. ~~Introduction to (spatial) data and programming in `R`~~ **[08/Jan/2026]** 2. ~~Week 2-4: Vector spatial data~~ **[14 - 29/Jan/2026]** 3. Week 5-7: Raster spatial data + (basic) interactive tools **[05 - 19/Feb/2026]** - Week 5: Raster basics and unary operations using `sf` and `terra` - Week 6: Vector-raster operations - Week 7: Interactive tools with `leaflet` and APIs 4. Week 8-10: Spatial models and applications with data **[25/Feb - 12 Mar/2026]**<br> <br> 5. <span style="color: rgb(177,148,40)">Take-home exam</span> **[27/Mar/2026]** --- # Main references for this class 1. Lovelace, R., Nowosad, J. and Muenchow, J., 2019. <g>**Geocomputation with R.**</g> Chapman and Hall/CRC. - Chapters 2.3, 3.3, 4.3, 5.3, and 6 2. Pebesma, E., 2018. Simple Features for R: Standardized Support for Spatial Vector Data. The R Journal 10 (1), 439-446 3. Wickham, H. and Grolemund, G., 2016. R for data science: import, tidy, transform, visualize, and model data. " O'Reilly Media, Inc.". --- # Raster data: basics - GIS systems represent <g>raster data</g> as an "image": - Geography as continuum of pixels (gridcells) with associated values - Normally represents <r>high resolution</r> features of the geography (like an image) .center[ <img src="https://r.geocompx.org/figures/raster-intro-plot-1.png" style="width: 70%" /> ] --- # Raster data: basics - Normally represents <r>high resolution</r> features of the geography (like an image) .center[ <img src="https://r.geocompx.org/figures/raster-intro-plot2-1.png" style="width: 70%" /> ] --- # Raster data (and other operations with rasters) in R Requires **additional libraries** on top of `sf`<sup>1</sup> 1. `terra`: contains most of the <r>raster-related functions</r> 2. `exactextractr`: performs high-performance <y>zonal statistics</y> 3. `gdistance`: used to calculate <g>distances over raster</g> .footnote[[1] Note that this is not an exhaustive list of libraries. Advanced users might want to check `stars`.] --- # Raster basics: data structure with terra - **Raster data:** represented with `terra`'s `SpatRaster` object .center[<img src="figs/raster01.png" style="width: 90%" />] --- # Raster basics: data structure with terra .pull-left[ - Prevous example: one-layer raster - Rasters can also be <y>**multidimensional**</y> (also called a *raster stack* or *brick*) - **Examples:** - <r>Imagery:</r> combination of 3 RGB layers (red, green, blue) - <g>Time varying</g> data (e.g., temperatures, precipitation, ...) ] .pull-right[ .center[<img src="figs/rast_multilayer_1.png" style="width: 85%" />] ] --- # Raster basics: data structure with terra .pull-left[ - Prevous example: one-layer raster - Rasters can also be <y>**multidimensional**</y> (also called a *raster stack* or *brick*) - **Examples:** - <r>Imagery:</r> combination of 3 RGB layers (red, green, blue) - <g>Time varying</g> data (e.g., temperatures, precipitation, ...) ] .pull-right[ .center[<img src="figs/rast_multilayer_2.png" style="width: 85%" />] ] --- # Raster basics: data structure with terra .pull-left[ - **Data formats:** - `.tif` is the <g>most usual</g> - Other image formats (`.jpeg`, `.png`) - NetCDF format `.nc` for <r>multi-layer rasters</r> (optimized for disk space!) - The function `terra::rast()` is versatile (works with all types)! ] .pull-right[ .center[<img src="figs/rast_multilayer_2.png" style="width: 85%" />] ] --- # Raster basics: loading, creating, and operations with rasters Further details in `01_class05.R` and `01_class06.R`, covering: .pull-left[ - Creating and loading rasters with `terra` - <r>Unary</r> operations: - Cropping - Vectorization ] .pull-right[ - <g>Vector-raster</g> operations (next class!): - Data extraction - Zonal statistics - Rasterize - Distances over networks using rasters ] --- # Raster basics: loading, creating, and operations with rasters - Creating an empty raster with `terra::rast()` ```r library(terra) r <- rast() *r ``` ``` ## class : SpatRaster ## dimensions : 180, 360, 1 (nrow, ncol, nlyr) ## resolution : 1, 1 (x, y) ## extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax) ## coord. ref. : lon/lat WGS 84 ``` - **Default empty raster:** covers the <g>Earth surface</g> with `\(1 \times 1\)` resolution - It also uses the standard long/lat projection --- # Raster basics: loading, creating, and operations with rasters - Creating an empty raster with `terra:rast()` ```r library(terra) r <- rast() *head(values(r)) ``` ``` ## lyr.1 ## [1,] NaN ## [2,] NaN ## [3,] NaN ## [4,] NaN ## [5,] NaN ## [6,] NaN ``` - **Default empty raster:** comes with <g>missing values</g> - Retrieved with `terra::values()` as a matrix (<r>column = layer</r>) --- # Raster basics: loading, creating, and operations with rasters .pull-left[ - Assigning raster values: `terra::values()` - Watch out the dimension: use `ncell()` - <g>Plotting</g> rasters: - Use `plot()` - `ggplot` later! ] .pull-right[ ```r library(terra) r <- rast() *values(r) <- 1:ncell(r) *plot(r) ``` <!-- --> ] --- # Raster basics: loading, creating, and operations with rasters .pull-left[ - <g>Cropping rasters</g> with `terra::crop()` - Crop a raster around a `sf` object - **Example with Brazil**'s polygon - <r>Vectorizing</r> rasters: - Transform a raster into a `sf` object (point, polygon) ] .pull-right[ ```r sf.brazil <- world %>% filter(iso_a2=='BR') *plot(r) *plot(st_geometry(sf.brazil), * add=T) # add layer ``` <!-- --> ] --- # Raster basics: loading, creating, and operations with rasters .pull-left[ - <g>Cropping rasters</g> with `terra::crop()` - Crop a raster around a `sf` object - **Example with Brazil**'s polygon - <r>Vectorizing</r> rasters: - Transform a raster into a `sf` object (point, polygon) ] .pull-right[ ```r *r.crop <- crop(r,sf.brazil) # cropping plot(r.crop) plot(st_geometry(sf.brazil), add=T) ``` <!-- --> ] --- # Raster basics: loading, creating, and operations with rasters .pull-left[ - <g>Cropping rasters</g> with `terra::crop()` - Crop a raster around a `sf` object - Example with Brazil's polygon - <r>Vectorizing</r> rasters: - Transform a raster into a `sf` object - **For points:** use `as.points() %>% st_as_sf()` - Attention with `lyr.1` attribute (what is it?) ] .pull-right[ ```r r.crop <- crop(r,sf.brazil) sf.point <- as.points(r.crop) %>% st_as_sf() *sf.point ``` ``` ## Simple feature collection with 1521 features and 1 field ## Geometry type: POINT ## Dimension: XY ## Bounding box: xmin: -73.5 ymin: -33.5 xmax: -35.5 ymax: 4.5 ## Geodetic CRS: WGS 84 ## First 10 features: ## lyr.1 geometry ## 1 30707 POINT (-73.5 4.5) ## 2 30708 POINT (-72.5 4.5) ## 3 30709 POINT (-71.5 4.5) ## 4 30710 POINT (-70.5 4.5) ## 5 30711 POINT (-69.5 4.5) ## 6 30712 POINT (-68.5 4.5) ## 7 30713 POINT (-67.5 4.5) ## 8 30714 POINT (-66.5 4.5) ## 9 30715 POINT (-65.5 4.5) ## 10 30716 POINT (-64.5 4.5) ``` ] --- # Raster basics: loading, creating, and operations with rasters .pull-left[ - <g>Cropping rasters</g> with `terra::crop()` - Crop a raster around a `sf` object - Example with Brazil's polygon - <r>Vectorizing</r> rasters: - Transform a raster into a `sf` object - **For points:** use `as.points() %>% st_as_sf()` - Attention with `lyr.1` attribute (what is it?) ] .pull-right[ ```r r.crop <- crop(r,sf.brazil) sf.point <- as.points(r.crop) %>% st_as_sf() plot(r.crop) *plot(st_geometry(sf.point),add=T) ``` <!-- --> ] --- # Raster basics: loading, creating, and operations with rasters .pull-left[ - <g>Cropping rasters</g> with `terra::crop()` - Crop a raster around a `sf` object - Example with Brazil's polygon - <r>Vectorizing</r> rasters: - Transform a raster into a `sf` object - **For polygons:** use `as.polygons()` instead! - Excellent for building <y>equally sized grids</y>! ] .pull-right[ ```r r.crop <- crop(r,sf.brazil) sf.pol <- as.polygons(r.crop) %>% st_as_sf() plot(r.crop) *plot(st_geometry(sf.pol),add=T) ``` <!-- --> ] --- class: center, middle # Your turn: Hands-on --- # Hands-on: your turn! (1/1) .pull-left[ Dividing Italy in **gridcells** - Create a 1 x 1 degree raster - Convert it to polygon (i.e. create the grid) - Use `world` data filtered to Italy, keep gridcells that **intersect** with Italy - Visualize it: ] .pull-right[ .center[<img src="figs/raster02.png" style="width: 85%" />] ]