Skip to content

Commit cd37e70

Browse files
committed
Lesson 1 updated by replacing calls to raster and rgdal packages with terra. #368
1 parent 231af26 commit cd37e70

File tree

1 file changed

+55
-41
lines changed

1 file changed

+55
-41
lines changed

episodes/01-raster-structure.Rmd

Lines changed: 55 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ knitr::opts_chunk$set(fig.height = 6)
1414

1515
- Describe the fundamental attributes of a raster dataset.
1616
- Explore raster attributes and metadata using R.
17-
- Import rasters into R using the `raster` package.
17+
- Import rasters into R using the `terra` package.
1818
- Plot a raster file in R using the `ggplot2` package.
1919
- Describe the difference between single- and multi-band rasters.
2020

@@ -29,8 +29,7 @@ knitr::opts_chunk$set(fig.height = 6)
2929
::::::::::::::::::::::::::::::::::::::::::::::::::
3030

3131
```{r load-libraries, echo=FALSE, results="hide", message=FALSE, warning=FALSE}
32-
library(raster)
33-
library(rgdal)
32+
library(terra)
3433
library(ggplot2)
3534
library(dplyr)
3635
```
@@ -53,11 +52,10 @@ data values as stored in a raster and how R handles these elements.
5352

5453
We will continue to work with the `dplyr` and `ggplot2` packages that were introduced
5554
in the [Introduction to R for Geospatial Data](https://datacarpentry.org/r-intro-geospatial/) lesson. We will use two additional packages in this episode to work with raster data - the
56-
`raster` and `rgdal` packages. Make sure that you have these packages loaded.
55+
`raster` and `sf` packages. Make sure that you have these packages loaded.
5756

5857
```{r load-libraries-2, eval=FALSE}
59-
library(raster)
60-
library(rgdal)
58+
library(terra)
6159
library(ggplot2)
6260
library(dplyr)
6361
```
@@ -86,14 +84,14 @@ data before we read that data into R. It is ideal to do this before importing
8684
your data.
8785

8886
```{r view-attributes-gdal}
89-
GDALinfo("data/NEON-DS-Airborne-Remote-Sensing/HARV/DSM/HARV_dsmCrop.tif")
87+
describe("data/NEON-DS-Airborne-Remote-Sensing/HARV/DSM/HARV_dsmCrop.tif")
9088
```
9189

9290
If you wish to store this information in R, you can do the following:
9391

9492
```{r}
9593
HARV_dsmCrop_info <- capture.output(
96-
GDALinfo("data/NEON-DS-Airborne-Remote-Sensing/HARV/DSM/HARV_dsmCrop.tif")
94+
describe("data/NEON-DS-Airborne-Remote-Sensing/HARV/DSM/HARV_dsmCrop.tif")
9795
)
9896
```
9997

@@ -104,7 +102,7 @@ episode. By the end of this episode, you will be able to explain and understand
104102
## Open a Raster in R
105103

106104
Now that we've previewed the metadata for our GeoTIFF, let's import this
107-
raster dataset into R and explore its metadata more closely. We can use the `raster()`
105+
raster dataset into R and explore its metadata more closely. We can use the `rast()`
108106
function to open a raster in R.
109107

110108
::::::::::::::::::::::::::::::::::::::::: callout
@@ -123,7 +121,7 @@ First we will load our raster file into R and view the data structure.
123121

124122
```{r}
125123
DSM_HARV <-
126-
raster("data/NEON-DS-Airborne-Remote-Sensing/HARV/DSM/HARV_dsmCrop.tif")
124+
rast("data/NEON-DS-Airborne-Remote-Sensing/HARV/DSM/HARV_dsmCrop.tif")
127125
128126
DSM_HARV
129127
```
@@ -138,16 +136,13 @@ summary(DSM_HARV)
138136

139137
but note the warning - unless you force R to calculate these statistics using
140138
every cell in the raster, it will take a random sample of 100,000 cells and
141-
calculate from that instead. To force calculation on more, or even all values,
142-
you can use the parameter `maxsamp`:
139+
calculate from that instead. To force calculation all the values, you can use
140+
the function `values`:
143141

144142
```{r}
145-
summary(DSM_HARV, maxsamp = ncell(DSM_HARV))
143+
summary(values(DSM_HARV))
146144
```
147145

148-
You may not see major differences in summary stats as `maxsamp` increases,
149-
except with very large rasters.
150-
151146
To visualise this data in R using `ggplot2`, we need to convert it to a
152147
dataframe. We learned about dataframes in [an earlier
153148
lesson](https://datacarpentry.org/r-intro-geospatial/04-data-structures-part2/index.html).
@@ -164,8 +159,12 @@ dataframe format.
164159
str(DSM_HARV_df)
165160
```
166161

167-
We can use `ggplot()` to plot this data. We will set the color scale to `scale_fill_viridis_c`
168-
which is a color-blindness friendly color scale. We will also use the `coord_quickmap()` function to use an approximate Mercator projection for our plots. This approximation is suitable for small areas that are not too close to the poles. Other coordinate systems are available in ggplot2 if needed, you can learn about them at their help page `?coord_map`.
162+
We can use `ggplot()` to plot this data. We will set the color scale to
163+
`scale_fill_viridis_c` which is a color-blindness friendly color scale. We will
164+
also use the `coord_quickmap()` function to use an approximate Mercator
165+
projection for our plots. This approximation is suitable for small areas that
166+
are not too close to the poles. Other coordinate systems are available in
167+
ggplot2 if needed, you can learn about them at their help page `?coord_map`.
169168

170169
```{r ggplot-raster, fig.cap="Raster plot with ggplot2 using the viridis color scale"}
171170
@@ -189,7 +188,7 @@ More information about the Viridis palette used above at
189188

190189
## Plotting Tip
191190

192-
For faster, simpler plots, you can use the `plot` function from the `raster` package.
191+
For faster, simpler plots, you can use the `plot` function from the `terra` package.
193192

194193
::::::::::::::: solution
195194

@@ -222,7 +221,7 @@ We can view the CRS string associated with our R object using the`crs()`
222221
function.
223222

224223
```{r view-resolution-units}
225-
crs(DSM_HARV)
224+
crs(DSM_HARV, proj = TRUE)
226225
```
227226

228227
::::::::::::::::::::::::::::::::::::::: challenge
@@ -254,7 +253,8 @@ and datum (`datum=`).
254253

255254
### UTM Proj4 String
256255

257-
Our projection string for `DSM_HARV` specifies the UTM projection as follows:
256+
A projection string (like the one of `DSM_HARV`) specifies the UTM projection
257+
as follows:
258258

259259
`+proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0`
260260

@@ -281,9 +281,11 @@ Raster statistics are often calculated and embedded in a GeoTIFF for us. We
281281
can view these values:
282282

283283
```{r view-min-max}
284-
minValue(DSM_HARV)
284+
minmax(DSM_HARV)
285+
286+
min(values(DSM_HARV))
285287
286-
maxValue(DSM_HARV)
288+
max(values(DSM_HARV))
287289
```
288290

289291
::::::::::::::::::::::::::::::::::::::::: callout
@@ -300,8 +302,8 @@ DSM_HARV <- setMinMax(DSM_HARV)
300302

301303
::::::::::::::::::::::::::::::::::::::::::::::::::
302304

303-
We can see that the elevation at our site ranges from `r raster::minValue(DSM_HARV)`m to
304-
`r raster::maxValue(DSM_HARV)`m.
305+
We can see that the elevation at our site ranges from `r min(terra::values(DSM_HARV))`m to
306+
`r max(terra::values(DSM_HARV))`m.
305307

306308
## Raster Bands
307309

@@ -316,7 +318,7 @@ function to import one single band from a single or multi-band raster. We can
316318
view the number of bands in a raster using the `nlayers()` function.
317319

318320
```{r view-raster-bands}
319-
nlayers(DSM_HARV)
321+
nlyr(DSM_HARV)
320322
```
321323

322324
However, raster data can also be multi-band, meaning that one raster file
@@ -343,7 +345,7 @@ did not collect data in these areas.
343345
# no data demonstration code - not being taught
344346
# Use stack function to read in all bands
345347
RGB_stack <-
346-
stack("data/NEON-DS-Airborne-Remote-Sensing/HARV/RGB_Imagery/HARV_RGB_Ortho.tif")
348+
rast("data/NEON-DS-Airborne-Remote-Sensing/HARV/RGB_Imagery/HARV_RGB_Ortho.tif")
347349
348350
# aggregate cells from 0.25m to 2m for plotting to speed up the lesson and
349351
# save memory
@@ -389,19 +391,25 @@ ggplot() +
389391
390392
```
391393

392-
If your raster already has `NA` values set correctly but you aren't sure where they are, you can deliberately plot them in a particular colour. This can be useful when checking a dataset's coverage. For instance, sometimes data can be missing where a sensor could not 'see' its target data, and you may wish to locate that missing data and fill it in.
394+
If your raster already has `NA` values set correctly but you aren't sure where
395+
they are, you can deliberately plot them in a particular colour. This can be
396+
useful when checking a dataset's coverage. For instance, sometimes data can be
397+
missing where a sensor could not 'see' its target data, and you may wish to
398+
locate that missing data and fill it in.
393399

394-
To highlight `NA` values in ggplot, alter the `scale_fill_*()` layer to contain a colour instruction for `NA` values, like `scale_fill_viridis_c(na.value = 'deeppink')`
400+
To highlight `NA` values in ggplot, alter the `scale_fill_*()` layer to contain
401+
a colour instruction for `NA` values, like `scale_fill_viridis_c(na.value = 'deeppink')`
395402

396403
```{r, echo=FALSE}
397404
# demonstration code
398405
# function to replace 0 with NA where all three values are 0 only
399-
RGB_2m_nas <- calc(RGB_2m,
400-
fun = function(x) {
401-
x[rowSums(x == 0) == 3, ] <- rep(NA, nlayers(RGB_2m))
402-
x
403-
})
404-
RGB_2m_nas <- as.data.frame(RGB_2m_nas, xy = TRUE)
406+
RGB_2m_nas <- app(RGB_2m,
407+
fun = function(x) {
408+
if (sum(x == 0, na.rm = TRUE) == length(x))
409+
return(rep(NA, times = length(x)))
410+
x
411+
})
412+
RGB_2m_nas <- as.data.frame(RGB_2m_nas, xy = TRUE, na.rm = FALSE)
405413
406414
ggplot() +
407415
geom_raster(data = RGB_2m_nas, aes(x = x, y = y, fill = HARV_RGB_Ortho_3)) +
@@ -436,14 +444,15 @@ of `NA` will be ignored by R as demonstrated above.
436444

437445
## Challenge
438446

439-
Use the output from the `GDALinfo()` function to find out what `NoDataValue` is used for our `DSM_HARV` dataset.
447+
Use the output from the `describe()` and `sources()` functions to find out what
448+
`NoDataValue` is used for our `DSM_HARV` dataset.
440449

441450
::::::::::::::: solution
442451

443452
## Answers
444453

445454
```{r}
446-
GDALinfo("data/NEON-DS-Airborne-Remote-Sensing/HARV/DSM/HARV_dsmCrop.tif")
455+
describe(sources(DSM_HARV))
447456
```
448457

449458
`NoDataValue` are encoded as -9999.
@@ -482,15 +491,20 @@ elevation values over 400m with a contrasting colour.
482491

483492
```{r demo-bad-data-highlighting, echo=FALSE, message=FALSE, warning=FALSE}
484493
# reclassify raster to ok/not ok
485-
DSM_highvals <- reclassify(DSM_HARV, rcl = c(0, 400, NA_integer_, 400, 420, 1L), include.lowest = TRUE)
494+
DSM_highvals <- classify(DSM_HARV,
495+
rcl = matrix(c(0, 400, NA_integer_, 400, 420, 1L),
496+
ncol = 3, byrow = TRUE),
497+
include.lowest = TRUE)
486498
DSM_highvals <- as.data.frame(DSM_highvals, xy = TRUE)
499+
487500
DSM_highvals <- DSM_highvals[!is.na(DSM_highvals$HARV_dsmCrop), ]
488501
489502
ggplot() +
490503
geom_raster(data = DSM_HARV_df, aes(x = x, y = y, fill = HARV_dsmCrop)) +
491504
scale_fill_viridis_c() +
492505
# use reclassified raster data as an annotation
493-
annotate(geom = 'raster', x = DSM_highvals$x, y = DSM_highvals$y, fill = scales::colour_ramp('deeppink')(DSM_highvals$HARV_dsmCrop)) +
506+
annotate(geom = 'raster', x = DSM_highvals$x, y = DSM_highvals$y,
507+
fill = scales::colour_ramp('deeppink')(DSM_highvals$HARV_dsmCrop)) +
494508
ggtitle("Elevation Data", subtitle = "Highlighting values > 400m") +
495509
coord_quickmap()
496510
@@ -532,7 +546,7 @@ no bad data values in this particular raster.
532546

533547
> ## Challenge: Explore Raster Metadata
534548
>
535-
> Use `GDALinfo()` to determine the following about the `NEON-DS-Airborne-Remote-Sensing/HARV/DSM/HARV_DSMhill.tif` file:
549+
> Use `describe()` to determine the following about the `NEON-DS-Airborne-Remote-Sensing/HARV/DSM/HARV_DSMhill.tif` file:
536550
>
537551
> 1. Does this file have the same CRS as `DSM_HARV`?
538552
> 2. What is the `NoDataValue`?
@@ -547,7 +561,7 @@ no bad data values in this particular raster.
547561
> > ```{r challenge-code-attributes}
548562
> > ```
549563
550-
GDALinfo("data/NEON-DS-Airborne-Remote-Sensing/HARV/DSM/HARV\_DSMhill.tif")
564+
describe("data/NEON-DS-Airborne-Remote-Sensing/HARV/DSM/HARV\_DSMhill.tif")
551565
552566
::::::::::::::::::::::::::::::::::::::: challenge
553567

0 commit comments

Comments
 (0)