Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ch06 #1119

Merged
merged 1 commit into from
Sep 24, 2024
Merged

ch06 #1119

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions 06-raster-vector.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,28 @@ library(dplyr)
## Introduction

\index{raster-vector interactions}
This Chapter focuses on interactions between raster and vector geographic data models, introduced in Chapter \@ref(spatial-class).
This chapter focuses on interactions between raster and vector geographic data models, introduced in Chapter \@ref(spatial-class).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

It includes several main techniques:
raster cropping and masking using vector objects (Section \@ref(raster-cropping));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 wow they can remove semicolons : )

extracting raster values using different types of vector data (Section \@ref(raster-extraction));
raster cropping and masking using vector objects (Section \@ref(raster-cropping)),
extracting raster values using different types of vector data (Section \@ref(raster-extraction)),
and raster-vector conversion (Sections \@ref(rasterization) and \@ref(spatial-vectorization)).
The above concepts are demonstrated using data used in previous chapters to understand their potential real-world applications.
The above concepts are demonstrated using data from previous chapters to understand their potential real-world applications.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

These are good changes.


## Raster cropping

\index{raster!cropping}
Many geographic data projects involve integrating data from many different sources, such as remote sensing images (rasters) and administrative boundaries (vectors).
Often the extent of input raster datasets is larger than the area of interest.
In this case, raster **cropping** and **masking** are useful for unifying the spatial extent of input data.
Both operations reduce object memory use and associated computational resources for subsequent analysis steps, and may be a necessary preprocessing step before creating attractive maps involving raster data.
Both operations reduce object memory use and associated computational resources for subsequent analysis steps and may be a necessary preprocessing step when creating attractive maps involving raster data.

We will use two objects to illustrate raster cropping:

- A `SpatRaster` object `srtm` representing elevation (meters above sea level) in south-western Utah
- A `SpatRaster` object `srtm` representing elevation (meters above sea level) in southwestern Utah
- A vector (`sf`) object `zion` representing Zion National Park

Both target and cropping objects must have the same projection.
The following code chunk therefore not only reads the datasets from the **spDataLarge** package installed in Chapter \@ref(spatial-class), it also 'reprojects' `zion` (a topic covered in Chapter \@ref(reproj-geo-data)):
The following code chunk therefore not only reads the datasets from the **spDataLarge** package installed in Chapter \@ref(spatial-class), but it also 'reprojects' `zion` (a topic covered in Chapter \@ref(reproj-geo-data)):

```{r 06-raster-vector-2, results='hide'}
srtm = rast(system.file("raster/srtm.tif", package = "spDataLarge"))
Expand Down Expand Up @@ -77,7 +77,7 @@ Setting `inverse = TRUE` will mask everything *inside* the bounds of the park (s
srtm_inv_masked = mask(srtm, zion, inverse = TRUE)
```

```{r cropmask, echo = FALSE, fig.cap="Illustration of raster cropping and raster masking.", fig.asp=0.36, fig.width = 10, warning=FALSE}
```{r cropmask, echo = FALSE, fig.cap="Raster cropping and raster masking.", fig.asp=0.36, fig.width = 10, warning=FALSE}
#| message: FALSE
#| results: hide
library(tmap)
Expand Down Expand Up @@ -145,10 +145,10 @@ source("code/06-pointextr.R", print.eval = TRUE)
\index{raster!extraction lines}
Raster extraction also works with **line** selectors.
Then, it extracts one value for each raster cell touched by a line.
However, the line extraction approach is not recommended to obtain values along the transects as it is hard to get the correct distance between each pair of extracted raster values.
However, the line extraction approach is not recommended to obtain values along the transects, as it is hard to get the correct distance between each pair of extracted raster values.

In this case, a better approach is to split the line into many points and then extract the values for these points.
To demonstrate this, the code below creates `zion_transect`, a straight line going from northwest to southeast of the Zion National Park, illustrated in Figure \@ref(fig:lineextr)(A) (see Section \@ref(vector-data) for a recap on the vector data model):
To demonstrate this, the code below creates `zion_transect`, a straight line going from northwest to southeast of Zion National Park, illustrated in Figure \@ref(fig:lineextr)(A) (see Section \@ref(vector-data) for a recap on the vector data model):

```{r 06-raster-vector-11}
zion_transect = cbind(c(-113.2, -112.9), c(37.45, 37.2)) |>
Expand Down Expand Up @@ -197,7 +197,7 @@ zion_transect = cbind(zion_transect, zion_elev)

The resulting `zion_transect` can be used to create elevation profiles, as illustrated in Figure \@ref(fig:lineextr)(B).

```{r lineextr, echo=FALSE, message=FALSE, warning=FALSE, fig.cap="Location of a line used for raster extraction (left) and the elevation along this line (right).", fig.scap="Line-based raster extraction."}
```{r lineextr, echo=FALSE, message=FALSE, warning=FALSE, fig.cap="Location of a line used for (A) raster extraction and (B) the elevation along this line.", fig.scap="Line-based raster extraction."}
library(tmap)
library(grid)
library(ggplot2)
Expand Down Expand Up @@ -291,7 +291,7 @@ zion_nlcd |>
count()
```

```{r polyextr, echo=FALSE, message=FALSE, warning=FALSE, fig.cap="Area used for continuous (left) and categorical (right) raster extraction.", fig.width=7.5}
```{r polyextr, echo=FALSE, message=FALSE, warning=FALSE, fig.cap="Area used for (A) continuous and (B) categorical raster extraction.", fig.width=7.5}
rast_poly_srtm = tm_shape(srtm) +
tm_raster(col.scale = tm_scale_continuous(values = terrain_colors),
col.legend = tm_legend("Elevation (m)")) +
Expand All @@ -318,11 +318,11 @@ The **exactextractr** package offers a [significantly faster alternative](https:
The `exact_extract()` function also computes, by default, the fraction of each raster cell overlapped by the polygon, which is more precise (see note below for details).

```{block2 06-raster-vector-22, type='rmdnote'}
Polygons usually have irregular shapes, and therefore, a polygon can overlap only some parts of a raster's cells.
Polygons usually have irregular shapes, and, therefore, a polygon can overlap only some parts of a raster's cells.
To get more detailed results, the `terra::extract()` function has an argument called `exact`.
With `exact = TRUE`, we get one more column `fraction` in the output data frame, which represents a fraction of each cell that is covered by the polygon.
This could be useful to calculate, for example, a weighted mean for continuous rasters or more precise coverage for categorical rasters.
By default, it is `FALSE` as this operation requires more computations.
By default, it is `FALSE`, as this operation requires more computations.
The `exactextractr::exact_extract()` function always computes the coverage fraction of the polygon in each cell.
```

Expand Down Expand Up @@ -356,7 +356,7 @@ raster_template = rast(ext(cycle_hire_osm_projected), resolution = 1000,

Rasterization is a very flexible operation: the results depend not only on the nature of the template raster, but also on the type of input vector (e.g., points, polygons) and a variety of arguments taken by the `rasterize()` function.

To illustrate this flexibility we will try three different approaches to rasterization.
To illustrate this flexibility, we will try three different approaches to rasterization.
First, we create a raster representing the presence or absence of cycle hire points (known as presence/absence rasters).
In this case `rasterize()` requires no argument in addition to `x` and `y`, the aforementioned vector and raster objects (results illustrated Figure \@ref(fig:vector-rasterization1)(B)).

Expand All @@ -365,7 +365,7 @@ ch_raster1 = rasterize(cycle_hire_osm_projected, raster_template)
```

The `fun` argument specifies summary statistics used to convert multiple observations in close proximity into associate cells in the raster object.
By default `fun = "last"` is used but other options such as `fun = "length"` can be used, in this case to count the number of cycle hire points in each grid cell (the results of this operation are illustrated in Figure \@ref(fig:vector-rasterization1)(C)).
By default `fun = "last"` is used, but other options such as `fun = "length"` can be used, in this case to count the number of cycle hire points in each grid cell (the results of this operation are illustrated in Figure \@ref(fig:vector-rasterization1)(C)).

```{r 06-raster-vector-26}
ch_raster2 = rasterize(cycle_hire_osm_projected, raster_template,
Expand Down Expand Up @@ -398,7 +398,7 @@ raster_template2 = rast(ext(california), resolution = 0.5,
```

When considering line or polygon rasterization, one useful additional argument is `touches`.
By default it is `FALSE`, but when changed to `TRUE` -- all cells that are touched by a line or polygon border get a value.
By default it is `FALSE`, but when changed to `TRUE`, all cells that are touched by a line or polygon border get a value.
Line rasterization with `touches = TRUE` is demonstrated in the code below (Figure \@ref(fig:vector-rasterization2)(A)).

```{r 06-raster-vector-30}
Expand Down Expand Up @@ -443,7 +443,7 @@ source("code/06-raster-vectorization1.R", print.eval = TRUE)
```

\index{spatial vectorization!contours}
Another common type of spatial vectorization is the creation of contour lines representing lines of continuous height or temperatures (isotherms) for example.
Another common type of spatial vectorization is the creation of contour lines representing lines of continuous height or temperatures (isotherms), for example.
We will use a real-world digital elevation model (DEM) because the artificial raster `elev` produces parallel lines (task for the reader: verify this and explain why this happens).
Contour lines can be created with the **terra** function `as.contour()`, which is itself a wrapper around the built-in R function `filled.contour()`, as demonstrated below (not shown):

Expand All @@ -457,10 +457,10 @@ plot(cl, add = TRUE)

Contours can also be added to existing plots with functions such as `contour()`, `rasterVis::contourplot()`.
<!-- or `tmap::tm_iso()` (not yet implemented as of 2023-11-24) -->
As illustrated in Figure \@ref(fig:contour-tmap), isolines can be labelled.
As illustrated in Figure \@ref(fig:contour-tmap), isolines can be labeled.

\index{hillshade}
```{r contour-tmap, echo=FALSE, message=FALSE, fig.cap="DEM with hillshading, showing the southern flank of Mt. Mongón overlaid with contour lines.", fig.scap="DEM with hillshading.", warning=FALSE, fig.asp=0.56, fig.width=3.5}
```{r contour-tmap, echo=FALSE, message=FALSE, fig.cap="Digital elevation model with hillshading, showing the southern flank of Mt. Mongón overlaid with contour lines.", fig.scap="DEM with hillshading.", warning=FALSE, fig.asp=0.56, fig.width=3.5}
# hs = shade(slope = terrain(dem, "slope", unit = "radians"),
# aspect = terrain(dem, "aspect", unit = "radians"))
# plot(hs, col = gray(0:100 / 100), legend = FALSE)
Expand All @@ -483,7 +483,7 @@ grain_poly = as.polygons(grain) |>
st_as_sf()
```

```{r 06-raster-vector-40, echo=FALSE, fig.cap="Illustration of vectorization of raster (left) into polygons (dissolve = FALSE; center) and aggregated polygons (dissolve = TRUE; right).", warning=FALSE, message=FALSE, fig.asp=0.4, fig.scap="Illustration of vectorization."}
```{r 06-raster-vector-40, echo=FALSE, fig.cap="Vectorization of (A) raster into (B) polygons (dissolve = FALSE) and aggregated polygons (dissolve = TRUE).", warning=FALSE, message=FALSE, fig.asp=0.4, fig.scap="Illustration of vectorization."}
source("code/06-raster-vectorization2.R", print.eval = TRUE)
```

Expand Down
2 changes: 1 addition & 1 deletion _06-ex.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ plot(nz_raster2)
plot(st_geometry(nz_height3100), add = TRUE)
```

E4. Aggregate the raster counting high points in New Zealand (created in the previous exercise), reduce its geographic resolution by half (so cells are 6 by 6 km) and plot the result.
E4. Aggregate the raster counting high points in New Zealand (created in the previous exercise), reduce its geographic resolution by half (so cells are 6 x 6 km) and plot the result.

- Resample the lower resolution raster back to the original resolution of 3 km. How have the results changed?
- Name two advantages and disadvantages of reducing raster resolution.
Expand Down
Loading