library("dplyr")
library("sf")
library("ggplot2")
<- read_sf("datasets/rauman/gruental.gpkg", "wiesen")
wiesen <- read_sf("datasets/rauman/gruental.gpkg", "baeume") baeume
Rauman 2: Übung A
In der letzten Übung haben wir einen Spatial Join zwischen Bäumen und Wiesen durchgeführt um herauszufinden, ob sich der Baum in einer Wiese befindet oder nicht. Basis waren dafür die Daten vom Campus Grüental (gruental.gpkg)
Heute gehen wir einen Schritt weiter und wollen folgende Frage beantworten: Wie viel Wiese befinden sich in einem Umkreis von 20m um jeden Baum?
Lade dazu die benötigten Libraries und Datensätze in deine Session. Exploriere die Daten visualisiere Sie räumlich.
Um die Übung etwas zu vereinfachen arbeiten wir erstmals mit nur 10 Bäumen. Nutze nachstehenden Code um zufällig 10 Bäume auszuwählen. Wenn ihr den gleichen “Seed” wie ich benutzt (set.seed(100)
) habt ihr “zufällig” auch die gleichen Bäume wie ich.
set.seed(100)
<- sample_n(baeume, 10) baeume_sample
ggplot() +
geom_sf(data = wiesen) +
geom_sf(data = baeume_sample)
Aufgabe 1
Als erster Schritt müssen wir jeden Baum mit einem 20m Puffer verstehen. Nutze dazu st_buffer
um speichere den Output als baeume_20m
. Schau dir baeume_20m
nun genau an. Um welchen Geometrietyp handelt es sich dabei nun?
Code
<- st_buffer(baeume_sample, 20) baeume_20m
Code
ggplot() +
geom_sf(data = wiesen) +
geom_sf(data = baeume_sample) +
geom_sf(data = baeume_20m, fill = NA)
Aufgabe 2
Berechnen nun die Schnittmenge aus baeume_20m
und wiesen
mit der Funktion st_intersection
und speichere den Output als baeume_wiesen
. Exploriere nun baeume_wiesen
. Was ist passiert? Überprüfe die Anzahl Zeilen pro Datensatz. Haben die sich verändert? Wenn ja, warum?
Code
<- st_intersection(baeume_20m, wiesen)
baeume_wiesen
ggplot() +
geom_sf(data = wiesen, fill = "blue", alpha = .2) +
geom_sf(data = baeume_20m, fill = "red", alpha = .2) +
geom_sf(data = baeume_wiesen, fill = "green", alpha = 0.2)
Aufgabe 3
Berechnen nun die Flächengrösse pro Geometrie mit der Funktion st_area()
. Speichere den Output in einer neuen Spalte von baeume_wiesen
(z.B. mit dem Namen wiesen_flaeche
). Tipp: Konvertiere den Output aus st_area
in einen nummerischen Vektor mit as.numeric()
.
Code
$wiesen_flaeche <- as.numeric(st_area(baeume_wiesen)) baeume_wiesen
Aufgabe 4 (Optional)
Berechne nun aus wiesen_flaeche
den wiesen_anteil
. Tipp: 100% ist die Kreisfläche aus \(r^2\times \pi\), wobei in unserem Fall \(r = 20\) entspricht.
Code
<- 20^2 * pi
kreisflaeche $wiesen_anteil <- baeume_wiesen$wiesen_flaeche / kreisflaeche baeume_wiesen
Überführe anschliessend die berechneten Anteilswerte in den Datensatz baeume
mit einem left_join
zwischen baeume
und baeume_wiesen
. Welche Spalte wäre für diesen Join geeignet? Hinweis: Nutze st_drop_geometry()
um die Geometriespalte in baeme_wiesen
vor dem Join zu entfernen.
Code
<- st_drop_geometry(baeume_wiesen)
baeume_wiesen_df
<- left_join(baeume_sample, baeume_wiesen_df, by = "baum_id")
baeume_2
ggplot() +
geom_sf(data = wiesen) +
geom_sf(data = baeume_2, aes(colour = wiesen_anteil)) +
scale_color_binned("Wiesen Anteil", low = "blue", high = "red", limits = c(0, 1), label = scales::label_percent()) +
coord_sf(datum = 2056)
Aufgabe 5
Nun habt ihr ein paar Vektoroperationen wie st_buffer()
und st_intersection()
und st_area()
durchgeführt. Gewisse Fragen lassen sich aber besser in der Raster-Welt beantworten. Wollen wir beispielsweise für jeden Punkt im Raum wissen, wie weit der nächstgelegene Baum ist, lässt sich das besser in einem Raster darstellen.
Bevor wir die Frage aber beantworten können, müssen wir den Vektordatensatz in ein Rasterdatensatz konvertieren. Dafür wiederum braucht es ein Raster “Template”, damit R in etwa weiss, wie der Raster Output auszusehen hat.
# Um mit Raster arbeiten zu können brauchen wir das Package "terra"
library("terra")
# Um ein Vektor Datensatz zu vektorieren, brauchen wir ein Template.
# Für das Template nutzen wir "wiesen" und setzen eine Zellgrösse (resolution)
<- rast(wiesen, resolution = 20)
template
# Mit rasterize können wir "baeume" in einen Raster konvertieren
# Nutzt hier wieder alle bäume, nicht baeume_sample
<- terra::rasterize(baeume, template) baeume_rast
Der Unterschied zwischen Raster und Vektor kann sehr anschaulich dargestellt werden, wenn die beiden Datensätze übereinander gelagert werden.
plot(baeume_rast, col = "grey")
plot(baeume, add = TRUE, col = "red", pch = "x")
Mit baeume_rast
können wir nun mit der Funktion distance()
die Distanz zu jedem Baum berechnen:
<- distance(baeume_rast)
baeume_dist plot(baeume_dist)
plot(baeume, add = TRUE, pch = "x")