Skip to content

Commit efa1105

Browse files
committed
finished rastertemplate
1 parent f89c345 commit efa1105

File tree

67 files changed

+34308
-3391
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+34308
-3391
lines changed
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
---
2+
title: "Raster Operations"
3+
description: |
4+
Learn how to 1) obtain a template raster from the `{d6geodata}` package, 2) expand the raster in different ways, 3) rasterize vector data, and 4) extract information from a raster using vector data.
5+
The methods described involve the use of packages like `{terra}` and `{sf}`, and include examples and plots to illustrate the processes. Additionally, we show how to use the `{tidyterra}` package for plotting raster data with `{ggplot2}`.
6+
7+
preview: ./img/wiki/preview-rastertemplate.png
8+
categories:
9+
- tutorial
10+
- spatial
11+
- sf
12+
- terra
13+
author:
14+
- name: Moritz Wenzler-Meya
15+
affiliation: IZW Berlin
16+
affiliation_url: https://ecodynizw.github.io/
17+
date: 2024-03-05
18+
output:
19+
distill::distill_article:
20+
self_contained: false
21+
toc: true
22+
draft: false
23+
---
24+
25+
```{r setup, include=FALSE}
26+
knitr::opts_chunk$set(echo = TRUE) ## keep this, add other settings if needed
27+
```
28+
29+
## Setup {#setup}
30+
31+
Install the `{d6geodata}` library and load all necessary libraries.
32+
33+
```{r}
34+
#remotes::install_github("EcoDynIZW/d6geodata")
35+
library(d6geodata)
36+
library(terra)
37+
library(ggplot2)
38+
library(sf)
39+
library(patchwork)
40+
library(dplyr)
41+
42+
theme_set(
43+
theme(axis.text.x = element_text(size = 8),
44+
axis.text.y = element_text(size = 8))
45+
)
46+
```
47+
48+
49+
## Raster Template {#template}
50+
51+
First get the template raster. The origin is the extent of Berlin with the projection LAEA (EPSG:3035).
52+
53+
```{r template}
54+
temp <- d6geodata::temp_ras(1000) # resolution is 1000m
55+
values(temp) <- 1 # set a dummy value for visualization purposes
56+
57+
temp
58+
```
59+
60+
We load Berlin districts data set from our cloud to show the borders of Berlin.
61+
62+
```{r berlin borders}
63+
berlin <- d6geodata::get_geodata(data_name = "districs_berlin_2022_poly_03035_gpkg",
64+
path_to_cloud = "E:/PopDynCloud",
65+
download_data = FALSE) %>%
66+
st_union() %>% # using `st_union()` to combine geometries
67+
st_cast("POLYGON")
68+
69+
p_berlin <- geom_sf(data = berlin, alpha = 0, color = "black", lwd = 0.7)
70+
```
71+
72+
Now we plot the map.
73+
74+
```{r plot template}
75+
p1 <- d6geodata::plot_qualitative_map(temp) # you can use this build-in plot function from the `{d6geodata}` package
76+
77+
p1 + p_berlin
78+
```
79+
80+
81+
## Expand Raster {#expand}
82+
83+
### Expand On All Sides
84+
85+
If you want to expand the raster (similar to a buffer around a polygon) you can just add cells to all sides. You can do this by adding an integer number in the y argument in the function `extend` of the `{terra}` package.
86+
87+
```{r}
88+
# expand the map
89+
temp_exp_all <- terra::extend(x = temp, # template raster as input
90+
y = 10, # number of cells to add
91+
fill = 2) # value for new cells
92+
93+
# plot the map again
94+
p2 <- d6geodata::plot_qualitative_map(temp_exp_all)
95+
p2 + p_berlin
96+
```
97+
98+
### Expand On Two Sides
99+
100+
You can also expand the raster in one or two different directions only by adding cells on two opposite sides.
101+
102+
```{r}
103+
temp_exp_tb_sides <- terra::extend(x = temp,
104+
y = c(10, 0), # add 10 cells on top and below
105+
fill = 2,)
106+
p3 <- d6geodata::plot_qualitative_map(temp_exp_tb_sides)
107+
p3 + p_berlin
108+
```
109+
110+
### Expand On One Side With A Custom Extent
111+
112+
In this case we use a workaround by using a custom extent. Here we are adding cells on the left (western) side by using the *xmin* of the larger extend. Xmax, ymin, ymax are from the given extent.
113+
114+
```{r}
115+
temp_exp_1_sides <- terra::extend(x = temp,
116+
y = ext(ext(temp_exp_all)[1], # xmin
117+
ext(temp)[2], # xmax
118+
ext(temp)[3], # ymin
119+
ext(temp)[4]),# ymax
120+
fill = 2)
121+
122+
p4 <- d6geodata::plot_qualitative_map(temp_exp_1_sides)
123+
p4 + p_berlin
124+
```
125+
126+
### Combined Plot
127+
128+
Here you see a combination of all plots made to compare them directly.
129+
130+
```{r, preview = TRUE}
131+
# arrange plots in a 2x2 grid
132+
(p1 + p_berlin + theme(legend.position="none") + p2 + p_berlin) / (p3 + p_berlin + p4 + p_berlin) +
133+
plot_layout(guides = "collect") +
134+
plot_annotation(tag_levels = "1", tag_prefix = "(P", tag_suffix = ")") # add tag to every plot
135+
```
136+
137+
## Rasterize Vector Data {#rasterize}
138+
139+
With `vect()` you can make a spatVector (similar to a shapefile) from an extent object.
140+
Afterwards, we can use this spatVector to rasterize the data. This works similar with an sf object.
141+
142+
```{r plot}
143+
# create spatVector
144+
temp_vec <- terra::vect(ext(temp), crs(temp)) # spatVector out of smallest raster extent
145+
146+
# rasterize spatVector
147+
temp_rast <- rasterize(temp_vec, # vector data
148+
temp_exp_all %>% disagg(10),
149+
# raster data with larger extent, disaggregated to 100m
150+
background = 2) # set to 2 to visualize the difference
151+
152+
temp_rast
153+
```
154+
155+
156+
### Rasterized Plot
157+
158+
View the results.
159+
160+
```{r}
161+
d6geodata::plot_qualitative_map(temp_rast)
162+
```
163+
164+
## Extract With Vector Data {#extract}
165+
166+
Imagine you have a track of an animal and you want to know what information lays in this track. In this case, you can use your line and extract the values from a raster below. There are several ways to this but the easiest way is to use the `extract()` function form the `{terra}` package to get the values laying under the vector data.
167+
168+
For this, you can use any vector data (points, lines, polygons) with the same projection and extent to extract values from a raster. The `extract()` function uses the raster as first input and the vector data as second. Depending on the type of data you are using you can define a function for the extraction like min, max or mean. 'Cells' gives you the call ID, 'xy' the coordinates and 'ID' the row number of your extraction.
169+
As mentioned, it is important that both the vector and the raster have the same projection.
170+
171+
### Line For Extraction
172+
173+
For this we are just creating a dummy line with coordinates laying within the raster
174+
175+
```{r}
176+
# create points
177+
pts <- tibble(x = c(4528790, 4576890), # a point out of two coordinates from the raster
178+
y = c(3271740, 3272140))
179+
180+
# create line from points
181+
dummy_line <- st_as_sf(pts, # a line made out of the point data
182+
coords = c("x", "y"), # specify columns of xy coordinates
183+
crs = st_crs(temp)$wkt, # using the same projection as for the template raster
184+
sf_column_name = "geometry",
185+
remove = FALSE) %>%
186+
summarise(do_union = FALSE) %>% # this part is for creating the lines out of the points
187+
st_cast("LINESTRING") %>% # this as well
188+
mutate(id = 1:n()) # add an id
189+
```
190+
191+
### Plot Of Raster And Line
192+
193+
```{r}
194+
p5 <- d6geodata::plot_qualitative_map(temp_rast) + # first plot raster
195+
geom_sf(data = dummy_line) # plot line on top of the raster
196+
197+
p5
198+
199+
```
200+
201+
### Extraction From Line
202+
203+
Here we finally extract the data and view the result with a table.
204+
205+
```{r}
206+
ext_tab <- terra::extract(x = temp_rast, # template raster as first input
207+
y = dummy_line, # dummy line as second input
208+
fun=NULL, # here you can set a function to summarise the data directly
209+
method="simple",
210+
cells=FALSE, # here you can get the cell number as well if cell = TRUE
211+
xy=FALSE, # here the xy coordinates if xy = TRUE
212+
ID=TRUE # and the id in front of each row
213+
)
214+
```
215+
216+
As you already can see on the plot, the largest part of the line lays within the purple area (value = 1). This function can be used to know on which land use class your track lays, for example.
217+
218+
```{r}
219+
table(ext_tab$layer)
220+
```
221+
222+
## Visualize Data With Tidyterra {#tidyterra}
223+
224+
There are several ways to plot raster data with ggplot and one relatively new way is to do it with the package `{tidyterra}`. It has some well developed `{ggplot}` functions, but it cannot always be combined with the base functions of `{ggplot}`. If you use this package you may have to stay within the package functions.
225+
226+
227+
```{r}
228+
library(tidyterra)
229+
230+
ggplot() +
231+
geom_spatraster(data = temp_rast) + # use geom_spatraster() to plot the raster data with {tidyterra}
232+
p_berlin # add vector data of Berlin
233+
234+
# same a before, but add some color to the plot
235+
ggplot() +
236+
geom_spatraster(data = temp_rast) +
237+
scale_fill_whitebox_c(palette = "purple") +
238+
p_berlin
239+
240+
```
241+
242+
243+
## Summary {#summary}
244+
245+
You learned how to extend a raster and how to extract data from a raster by using `{sf}` and `{terra}`. Of course there are several ways to do this, but this the most convenient way!!!

0 commit comments

Comments
 (0)