GeoJSON & (SQL) Spatial Data … am Ende war’s eigentlich ganz einfach


Kürzlich, im Rahmen eines kleinen Testprojekts, wurde ich mit der Verarbeitung von Geodaten konfrontiert. Kurz zusammengefasst, die Kernkomponente des Programms sollte feststellen können ob ich mich (genauer gesagt ob sich meine Position) innerhalb eines definierten Bereichs befinde. Ein (für heutige Verhältnisse und Möglichkeiten) an sich “triviales” Problem; dennoch stieß ich hier und da auf ein paar Hürden. Die Erkenntnisse habe ich in diesem Artikel zusammengefasst.

Schritt #1: Die passenden Daten. Woher nehmen und nicht stehlen.

Glücklicherweise finden sich im Internet div. Plattformen, die unterschiedliche Geodaten, u.a. kostenfrei anbieten. Open Data ist im Vormarsch; vor allem im öffentlichen Bereich! In meinem Fall war die Lösung schnell gefunden. Für mein Testprojekt konnte ich auf Daten aus dem österreichischen “Open Government Wien” Fundus zurückgreifen. Dort findet man eine Vielzahl von interessanten Daten. Für alle die diese Plattform bis dato noch kannten – ein Besuch lohnt sich!

Schritt #2: Das passende Datenformat.

Open Government Data bietet die Daten in unterschiedlichen Formaten an. Darunter auch in JSON. Hierbei wird das GeoJSON Format verwendet. Wenn man einen Blick in die JSON Daten wirft, erwarten einem meist (natürlich abhängig von den repräsentierten geometrischen Elementen) eine Vielzahl von geschachtelten und oft großen Arrays.

 

Ich bin ein persönlicher Fan von guter Datenvisualisierung. Das hilft mir die Strukturen und die einzelnen Elemente besser zu verstehen. Arbeitet man mit Geodaten ist dieser Schritt relativ einfach. Man muss die Daten nur auf einer Karte darstellen. Hierbei helfen (Web) Plattformen wie z.B. GeoJSON.io. Einfach die GeoJSON Daten in GeoJSON.io hochladen und man bekommt eine anschauliche Darstellung von Geo Elementen wie Punkten, Polygonen und Multipolygone. Ein Klick auf z.B. ein Polygon öffnet ein kleines Fenster, welches die spezifischen Metadaten des jeweiligen Elements anzeigt. Nicht uninteressant für die weitere Entwicklung.

55

(Bild: Screenshot von GeoJSON.io. Daten stammen von Open Government Wien. Stand 05.2016)

Schritt #3: Die Datenhaltung. NoSQL Stores? Relationale Datenbanksysteme?

Nachdem ich einen Überblick über die Daten erhalten habe, bestand der nächste Schritt darin eine passende Datenablage für diese Daten zu finden (die Daten nur im Applikationsspeicher zu halten war für mich keine Option). Aber welcher ist der “Richtige”? Nun ja, ein Analyse bis ins kleinste Detail habe ich mich an der Stelle erspart. Ich konzentrierte mich auf folgende Kriterien:

  • Infrastruktur Overhead und Kosten auf ein Minimum reduzieren.
  • Der Datencontainer soll Funktionen zur Verarbeitung von Geodaten (Spatial Types) anbieten (z.B. befindet sich ein Punkt innerhalb eines Polygons, wie weit sind zwei Punkte voneinander entfernt, etc.)

Beide Punkte werden von den Microsoft Azure Plattform-as-a-Service (PaaS) Services Azure DocumentDB und Azure SQL Database erfüllt.

Meine Favoriten waren identifiziert. Aus reiner Neugier habe ich mich dann auch entschlossen beide Varianten auszuprobieren.

GeoJSON und Azure DocumentDB (NoSQL)

Seit August 2015 unterstützt Azure DocumentDB Geospatial Daten (Announcing Geospatial support in Azure DocumentDB bzw. Working with Geospatial data in Azure DocumentDB) und bietet sich als NoSQL Store für die vorhandenen JSON Daten an. Wer sich unsicher ist und die Funktionalität vorab testen möchte, wird im Azure DocumentDB Query Playground fündig werden. Dort gibt es eine separate Sektion um die Geospatial Funktionen (ST_DISTANCE und ST_WITHIN) testen zu können.

Der Import der vorhandenen GeoJSON Daten war Dank des Azure DocumentDB Migration Tools ein Kinderspiel. Das Tool runterladen, installieren, starten, die GeoJSON Datei, welche importiert werden soll, als Datenquelle angeben, die Ziel DocumentDB Collection spezifizieren und schon kann es losgehen. Das Tool übernimmt den Rest. Und bereits nach kurzer Zeit sind die Daten in der DocumentDB Instanz abgelegt.

Um den Start zu erleichtern, gibt es auf Github auch einige Azure DocumentDB Spatial Code Samples.

GeoJSON und Azure SQL Database

Ich ging davon aus, dass es sich hierbei (GeoJSON –> SQL Spatial Types) um ein geläufiges Problem handelt und bereits eine wiederverwendbare Lösung (z.B. ein Import-/Migrationstool) existiert. Fehlanzeige. Meine erste Recherche war ernüchternd. Ich fand einige Artikel, die beschreiben wie man SQL Spatial Types nach JSON konvertieren kann; die gefundenen Informationen, die sich mit der Konvertierung in die andere Richtung beschäftigen waren doch sehr “überschaubar”.

Es sah so aus, dass ich an einer “Custom” Import/Parsing Lösung nicht herumkommen würde (vor allem auch weil die Geodaten ein Dictionary mit Custom Daten beinhalten). Obwohl es möglich ist dies direkt mit T-SQL umzusetzen (JSON Data (SQL Server)), entschied ich mich diese Logik in eine C# Applikation packen. Da ich ohnehin beabsichtigte den Datenbankzugriff mittels Entity Framework (EF) zu abstrahieren (EF Provider Support for Spatial Types), schien diese Option durchaus naheliegend (mittels EF Code-First Ansatz). Glücklicherweise gibt es das Nuget Paket “GeoJSON.NET”, welches neben den entsprechenden .NET Typen auch Json.Net GeoJSON (De)Serializer zur Verfügung stellt.

Die Implementierung ist einfach:

GeoJSON.Net.Feature.FeatureCollection featureCollectionZones =
    JsonConvert.DeserializeObject<GeoJSON.Net.Feature.FeatureCollection>("<YOUR GEOJSON>");
foreach (GeoJSON.Net.Feature.Feature item in featureCollectionZones.Features)
{ }

 

Im Anschluss müssen die eingelesenen Daten noch in einen SQL Spatial Data Type überführt und dem Entity Framework in einer interpretierbaren Form zur Verfügung gestellt werden.

foreach (GeoJSON.Net.Feature.Feature item in featureCollectionZones.Features)
{
    var geoFromJson = item.ToSqlGeometry();
    var geography = DbGeography.FromText(geoFromJson.ToString());
}

Fazit

Liegen Geodaten im GeoJSON Format vor, so können diese schnell in die eigene Applikation integriert werden um interesante Abfragen durchzuführen. Dank diverser Tools ist es zudem einfach die Daten in die Azure Services Azure DocumentDB und Azure SQL Database zu übernehmen und damit sowohl die NoSQL als auch SQL User zu bedienen.