Wichtige Features von Geo Engine sind Datenschnittstellen, mit der Nutzer Datenquellen oder Berechnungen (Workflows) in anderen Programmen oder Umgebungen weiternutzen können. Wir setzen hierbei auch auf Standardschnittstellen der OGC, z.B. dem Web Coverage Service (WCS). Mit diesem Dienst lassen sich Rasterdaten in weiterverarbeitbaren Formaten abrufen und so problemlos in Data-Science-Workflows oder GIS-Tools integrieren.
Ein Machine-Learning-Beispiel im Jupyter Notebook
Geo Engine bietet eine Python-Bibliothek, mit der Workflows einfach programmatisch abrufbar sind. Auch hier nutzen wir die OGC-Standardschnittstelle WCS, um Rasterdaten als numpy-Array zugreifbar zu machen und weiterzuverarbeiten.
In diesem Beispiel speisen wir NDVI-Daten von MODIS¹ in das Machine-Learning-Framework scikit-learn ein. NDVI ist ein Vegetationsindex, der Rückschlüsse auf die Menge und Vitalität von Pflanzen zulässt. Wir nutzen hierbei Geo Engine für den temporalen Datenzugriff, bei dem wir verschiedene Zeitschritte des Datensatzes in unseren Prozess integrieren.
Zunächst importieren wir das geoengine-Paket sowie scikit-learn in unsere Jupyter-Notebook-Umgebung.
from sklearn.cluster import KMeans
from datetime import datetime
import matplotlib.pyplot as plt
import geoengine as ge
Anschließend initialisieren wir die Verbindung zu einer Geo-Engine-Instanz.
ge.initialize("http://localhost:3030")
ge.get_session()
Server: http://localhost:3030
Session Id: 4565bdfa-956e-4dcf-8be6-56c6b02ec1b5
Wir registrieren den NDVI-Workflow und erhalten ein Workflow-Objekt zurück, auf dem wir im Folgenden den Datenzugriff starten können.
workflow = ge.register_workflow({
"type": "Raster",
"operator": {
"type": "GdalSource",
"params": {
"dataset": {
"type": "internal",
"datasetId": "36574dc3-560a-4b09-9d22-d5945f2b8093"
}
}
}
})
workflow
8df9b0e6-e4b4-586e-90a3-6cf0f08c4e62
Zunächst möchten wir uns einen Überblick über die Daten machen und starten einen WMS-Zugriff für April 2014, der uns ein georeferenziertes Bild zurückliefert.
time = datetime.strptime(
'2014-04-01T12:00:00.000Z', "%Y-%m-%dT%H:%M:%S.%f%z")
workflow.plot_image(
ge.QueryRectangle(
[-180.0, -90.0, 180.0, 90.0],
[time, time]
)
);

Wir erkennen verschiedene Schattierungen der NDVI-Werte, wobei in diesem Fall heller für mehr Vegetation steht. Es gibt also verschiedene Bereiche, die wir je nach Vegetationsgrad in Klassen aufteilen können.
Um die Rohdaten für Machine-Learning nutzen zu können, fragen wir ab jetzt die Daten mittels WCS an. In unserer Python-Bibliothek geschieht dies mit der Funktion get_array. Die Rückgabe erfolgt als numpy-Array, welches dem de-facto-Standard in Python für Datenhandling von Array-Daten entspricht.
width = 128
time = datetime.strptime(
'2014-04-01T12:00:00.000Z', "%Y-%m-%dT%H:%M:%S.%f%z")
wcs_array = workflow.get_array(
ge.QueryRectangle(
[-180.0, -90.0, 180.0, 90.0],
[time, time],
resolution=[360./width, 180./width],
)
)
plt.imshow(wcs_array)

Hier haben wir die Daten mit einer Auflösung von 128×128 Pixeln angefragt und dargestellt. Für die Unterteilung in Klassen verwenden wir den Clustering-Algorithmus k-Means, der eine einfache Aufteilung für k Klassen anhand derer Werte vornehmen kann. Für das Training verwenden wir weiterhin den Monat April 2014 und betrachten Ergebnisse für mehrere Anzahlen von Klassen k.
fig, axes = plt.subplots(2, 2, figsize=(10, 10))
axes = [ax for row in axes for ax in row]
for k, ax in zip(range(2, 6), axes):
kmeans = KMeans(n_clusters=k, random_state=0).fit(wcs_array.reshape(width**2, 1))
ax.imshow(kmeans.labels_.reshape(width, width))
ax.set_title(f'k = {k}')
fig.suptitle('k-Means Clustering Results')
fig.tight_layout()
plt.show()

Wir erkennen verschiedene Aufteilungen, die grob ähnlich zu unserer ersten Einschätzung des Datensatzes sind. Es gibt Unterschiede zwischen Wasserflächen (keine Vegation), wenig Vegetation (Nordafrika) und viel Vegetation (Ostasien). In diesem Beispiel entscheiden wir uns für die Aufteilung in vier Klassen (k=4) und möchten damit weiterarbeiten und die anderen Zeitpunkte entsprechend in Klassen unterteilen.
Hierfür starten wir denselben Datenzugriff mittels Geo Engine, jedoch ändern wir jeweils die angefragte Zeit um einen Monat. Das bedeutet, dass wir ein Modell für April 2014 und vier Klassen trainieren und es jeweils für andere Zeitschritte anwenden. Dies erfolgt im Folgenden mit einer Schleife.
k = 4
kmeans = KMeans(n_clusters=k, random_state=0).fit(wcs_array.reshape(width**2, 1))
fig, axes = plt.subplots(3, 2, figsize=(10, 15))
axes = [ax for row in axes for ax in row]
for month, ax in zip(range(1, 7), axes):
time = datetime.strptime(f'2014-{month:02d}-01T12:00:00.000Z', "%Y-%m-%dT%H:%M:%S.%f%z")
wcs_array = workflow.get_array(
ge.QueryRectangle(
[-180.0, -90.0, 180.0, 90.0],
[time, time],
resolution=[360./width, 180./width],
)
)
ax.imshow(
kmeans.predict(wcs_array.reshape(width**2, 1)).reshape(width, width)
)
ax.set_title(time.date())
fig.suptitle('4-Means Predictions')
fig.tight_layout()
plt.show()

Man erkennt gut die Verschiebung von Klassen über den zeitlichen Verlauf. Auffällig ist dies beispielsweise in Zentralasien und Europa.
Fazit
Mittels Geo Engine ist es einfach Daten über Standardschnittstellen in eine Programmierumgebung wie Jupyter Notebooks zu bekommen und diese in Machine-Learning-Workflows zu verwenden. Dabei bietet unsere Python-Bibliothek einen sehr einfachen Zugriff, der genauso auch in anderen GIS-Programmen funktioniert. Diese Prozessintegration ist uns sehr wichtig, da Geodatenverarbeitung und Analyse ein vielschichtiger Prozess sein kann, bis das gewünschte Ergebnis erlangt wird.
Dieser Anwendungsfall zeigt eine Reihe von Features der Geo Engine:
- Den Datenzugriff von Rasterdaten
- Die Nutzung der OGC-Standardschnittstelle WCS
- Die Verwendung der Python-Bibliothek der Geo Engine
- Die Einbindung von Geo-Engine-Worfklows in Prozesse des Machine-Learnings
Daten-Zitierung
- MODIS Vegetation Index Products (NDVI and EVI): https://modis.gsfc.nasa.gov/data/dataprod/mod13.php