5. Erste Schritte mit ggmap, ggplot2 und osmdata
Arbeitsverzeichnis, Daten und Pakete
Die Daten für dieses Tutorial werden über GitHub bereitgestellt Github. Um den Code mit Ihren eigenen Daten nachzubilden, ersetzen Sie die URL durch Ihren lokalen Dateipfad
Wenn Sie lokal arbeiten, können Sie das Arbeitsverzeichnis entsprechnd anpassen
setwd("YOUR/FILEPATH")
# this will not work. if you want to use it, define a path on your computer
Dies sollte ihre Arbeitsumgebung darstellen, d.h. der Ort an dem ihre Ordner und dazugehörigen Daten abgespeichert sind. Weitere Informationen finden Sie unter hier
Codeabschnitte zum Speichern von Daten und Ergebnissen sind in diesem Tutorial (mit einer #) gekennzeichnet. Bitte ersetzen Sie (“YOUR/FILEPATH”) durch Ihren eigenen lokalen Dateipfad.
Der Code ist so geschrieben, dass Pakete automatisch installiert (wenn nicht bereits installiert) und geladen werden. Die Pakete werden am Standardspeicherort Ihres Computers abgelegt.
Laden Sie zunächst die benötigten Pakete:
if (!require(dplyr)){install.packages("dplyr"); library(dplyr)}
if (!require(ggplot2)){install.packages("ggplot2"); library(ggplot2)}
if (!require(tidyverse)){install.packages("tidyverse"); library(tidyverse)}
if (!require(sp)){install.packages("sp"); library(sp)}
if (!require(ggmap)){install.packages("ggmap"); library(ggmap)}
Das R-Paket “ggmap”
Das R Paket ggmap bietet Funktionen, um Geodaten in Verbindung mit Grundlagenkarten zu visualisieren. Dazu wird die die Grammatik des R-Paketes ggplot2 verwendet, die sich insbesondere dadurch auszeichnet, dass mehrer graphische Ebenen übereinander geplottet werden. Das Ergebnis ist eine Karte, die ausgewählte Geodaten und eine Grundlagenkarte mit orientierenden Kontextinformationen kombiniert (s. https://github.com/dkahle/ggmap).
Defniere einen Kartenauschnitt
Via Bounding Box (bbox) lowerleftlon (links), lowerleftlat (unten), upperrightlon (rechts), upperrightlat (oben) kann der Kartenausschnitt defniert .
myLocation<-c(7, 47.75, 8.5, 48.25) # ~Großraum Freiburg
Lade Raster Tiles
Mit Hilfe der Funktion “get_xymap” kann eine kostenfreie Quelle (get_stamenmap
oder get_openstreetmap
), den Typ und die Farbe der bestimmt werden. Siehe z.B. ?get_stamenmap
.
myMap <- get_stamenmap(bbox=myLocation, maptype="watercolor", crop=TRUE)
ggmap(myMap)
Skala
Je nach Bedarf kann anhand von fest definierten Zoomstufen (3-21) die SKala der Karte angepasst werden (3=Kontinent, 10=Stadt, 21=Gebäude).
myMap <- get_stamenmap(bbox=myLocation, maptype="watercolor", zoom=7)
ggmap(myMap)
Zeichne Datenpunkte auf einer Karte
Daten einlesen
Verwende die Funktion read_csv aus dem Pakte “readr”
urlfile <- "https://raw.githubusercontent.com/RafHo/teaching/master/angewandte_geodatenverarbeitung/datasource/weather_perceptions.csv" # get url from github repositury
# use "urlfile" to read data
data <- readr::read_csv(url(urlfile))
Bounding Box
Ermittel eine Bounding Box basierend auf der räumlichen Verteilung der eingelesenen Daten
bbox <- make_bbox(lon = data$longitude, lat = data$latitude, f = 0.25)
Datenpunkte zeichnen
Alle Datenpunkte werden auf dem Ausschnitt der Bounding Box gezeichnet.
myMap <- get_stamenmap(bbox=bbox, maptype="watercolor", zoom=14)
ggmap(myMap)+
geom_point(aes(x=longitude, y=latitude), data=data, alpha=0.5, color="darkred", size = 1)
Es kann auch ein Subset der Datenpunkte gezeichnet werden, dazu muss eine entsprechende Gruppe aus den Daten herausgefiltert werden, z.B. mit der Funktion “filter” aus dem Paket “dplyr”.
cloud_data <- dplyr::filter(data, node_label=="cloud cover")
ggmap(myMap)+
geom_point(aes(x=longitude, y=latitude), data=cloud_data, color="darkgrey", size = 1.5)
Zur Auswahl betsimmter Daten können auch verschiedene Filterkriterien bzw. logische Operatoren miteinander kombiniert werden:
&
AND|
OR (inklusive)!
NOT
tempcold_data <- dplyr::filter(data, scale_label=="temperature level" & value_index>=-3 & value_index<=-1)
ggmap(myMap)+
geom_point(aes(x=longitude, y=latitude), data=tempcold_data, color="blue", size = 1)
Symbologie
Die Datenpunkte können auch entsprechend einer Eigenschaft gezeichnet werden. Dazu können Werte eines beliebigen Attributes verwendet werden.
ggmap(myMap)+
geom_point(aes(x=longitude, y=latitude), data=tempcold_data, color="blue", size = tempcold_data$value_index*-1, alpha=0.4)
ggmap(myMap)+
geom_point(aes(x=longitude, y=latitude), data=tempcold_data, color=tempcold_data$end_day, size = tempcold_data$value_index*-1, alpha=.7)
Heatmaps
Vorhandene Datenpunkte können auch entsprechend einer Eigenschaft gezeichnet werden. Dazu können Werte eines beliebigen Attributes verwendet werden.
ggmap(myMap)+
stat_density2d(aes(x=longitude, y=latitude,fill=..level.., alpha=..level..), data=tempcold_data, geom="polygon")+
scale_fill_gradient(low = "green", high = "red")+
theme(axis.ticks = element_blank(),
axis.text = element_blank(),
legend.position="none")
Exkurs: ggplot2 Grundlagen
if (!require(ggplot2)){install.packages("ggplot2"); library(ggplot2)}
Ein Diagram oder eine Karte erstellen
ggplot bietet vielseitige Funktionen, um im Rahmen von vordefnierten Vorlagen Grafiken zu erzeugen. Die Basisvorlage lautet:
ggplot(data = <DATA>)
+
<GEOM_FUNCTION>(mapping = aes(<MAPPINGS>))
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy))
Diese Vorlage kann beliebig komplex erweitert werden.
Übung
Führen Sie folgendes aus:
ggplot(data = mpg)
Was sehen Sie da?
Wie viele Zeilen sind in mpg? Wie viele Spalten?
Was beschreibt die Variable drv? Lesen Sie die Hilfe zu ?mpg, um es herauszufinden.
Machen Sie einen Streudiagramm von hwy vs. cyl.
Was passiert, wenn du einen Streudiagramm von class vs. drv machst? Warum ist dies nicht nützlich?
Modifikationen
Um eine Modifikation einer Variablen zuzuordnen, ordnen Sie den Namen der Variablen innerhalb von aes() zu. ggplot2 weist jedem eindeutigen Wert der Variablen automatisch ein eindeutiges Niveau (hier eine eindeutige Farbe) zu. ggplot2 fügt auch eine Legende hinzu, die erklärt, welche Ebenen welchen Werten entsprechen.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, color = class))
Exkurs: Daten von OpenStreetMap laden
if (!require(sf)){install.packages("sf"); library(sf)}
## Warning: Paket 'sf' wurde unter R Version 4.1.3 erstellt
if (!require(osmdata)){install.packages("osmdata"); library(osmdata)}
Das R-Paket “osmdata”
Das R Paket osmdta bietet eine Reihe von Funktionen, um Geodaten des OSM-Projekts über ein API zu laden.
Download von OSM-Daten
Der Download von OSM-Daten erfolgt über Abfragen via Overpass API. Dazu wird in der Regel die Basisabfrage opq() mit der Abfrage von spezifischen Eigenschaften kombiniert.
Dazu werden map features (tags) bestehend aus einem key und einem dazugehörigen value verwendet. Eine vollständige Liste der map features (tags) finden Sie hier: https://wiki.openstreetmap.org/wiki/DE:Map_Features
map features (tags) beschreiben spezifische Merkmale von Kartenelementen (Knoten, Wege oder Beziehungen) oder Versionsnummern. Beide Elemente sind frei formatierte Textfelder (strings), stellen aber oft numerische oder andere strukturierte Elemente dar.
Die defnierten OSM-Objekte werden dann heruntergeladen und in R Simple Feature Objekt (sf) mit osmdata_sf () oder als R Spatial Objekt (sp) mit osmdata_sp () konvertiert.
Ein Download von OSM-Daten kann beispielsweise so erfolgen:
fr_cycleway <- opq(bbox = getbb("Freiburg, Germany")) %>% # either use bounding box or geocoding to define research area by ?getbb
add_osm_feature(key = "highway", value= "cycleway") # define required tags
fr_cycleway
## $bbox
## [1] "47.9035777,7.6620055,48.0710579,7.9308444"
##
## $prefix
## [1] "[out:xml][timeout:25];\n(\n"
##
## $suffix
## [1] ");\n(._;>;);\nout body;"
##
## $features
## [1] " [\"highway\"=\"cycleway\"]"
##
## attr(,"class")
## [1] "list" "overpass_query"
## attr(,"nodes_only")
## [1] FALSE
str(fr_cycleway) #Compactly Display the Structure of an Arbitrary R Object
## List of 4
## $ bbox : chr "47.9035777,7.6620055,48.0710579,7.9308444"
## $ prefix : chr "[out:xml][timeout:25];\n(\n"
## $ suffix : chr ");\n(._;>;);\nout body;"
## $ features: chr " [\"highway\"=\"cycleway\"]"
## - attr(*, "class")= chr [1:2] "list" "overpass_query"
## - attr(*, "nodes_only")= logi FALSE
Verwendung von OSM-Daten
Um die Daten zu verwenden, müssen sie vom Objekttyp osmdata in das sp-, sf- oder xml-Format konvertiert werden.
fr_cycleway_sp <- osmdata_sp(fr_cycleway)
fr_cycleway_sf <- osmdata_sf(fr_cycleway)
fr_cycleway_xml <- osmdata_xml(fr_cycleway)
Visualisierung von OSM-Daten
Jetzt können sie auch visualisiert werden. Für die Darstellung mittels ggplot müssen sie als sf-Objekt vorliegen:
ggplot()+
geom_sf(data=fr_cycleway_sf$osm_lines,
colour="#238443",
fill="#004529",
alpha=.5)+
labs(x="",y="")
Remeber to give credit to the OSM Contributors when you publish your data. Although Open street map is open data, it is licensed under the Open Data Commons Open Database License.
ggplot()+
geom_sf(data=fr_cycleway_sf$osm_lines,
colour="#238443",
fill="#004529",
alpha=.5)+
labs(x="",y="", caption = "© OpenStreetMap contributors")
Export von OSM-Daten
Um die Daten als Shapefiles zu speichern, sollte rgdal geladen sein, da es die notwendige Funktion writeOGR bereitstellt.
if (!require(rgdal)){install.packages("rgdal"); library(rgdal)}
writeOGR(fr_cycleway_sp$osm_lines, dsn="YOUR/FILEPATH", layer = "fr_shapefile", driver = "ESRI Shapefile", overwrite=TRUE)