Sofort für GIS: GeoJSON in PostGIS importieren, Befehle, SQL, Tests

Sofort für GIS: GeoJSON in PostGIS importieren, Befehle, SQL, Tests

GeoJSON in eine PostGIS-Datenbank importierenSymbolbild, KI-generiert

Für Bulk-GeoJSON-Dateien nehmen Sie ogr2ogr, für einzelne Einfügungen oder API-gesteuerte Importe arbeiten Sie mit ST_GeomFromGeoJSON in Kombination mit jsonb_array_elements. Beide Wege scheitern regelmäßig an derselben Stelle: fehlendes SRID und fehlender Spatial Index. Setzen Sie beides von Anfang an, sonst zahlen Sie später mit langsamen Abfragen und kaputten Joins.


Kurz gesagt:

  • Beim Bulk-GeoJSON-Import mit ogr2ogr ist es essenziell, SRID und Spatial Index sofort zu setzen, um später langsame Abfragen und fehlerhafte Joins zu vermeiden.
  • Die Verarbeitung einer FeatureCollection in SQL erfordert die Extraktion der Features mit jsonb_array_elements und das Zuweisen des SRID mit ST_SetSRID, um Geometrie-Fehler zu verhindern.
  • Nach dem Import sollten die Geometrietypen, Geometriefelben, Validität und das Koordinatensystem geprüft sowie bei Bedarf mit ST_MakeValid korrigiert werden.
  • Für große Datenmengen ist der GIST-Index die Standardwahl, während SPGIST oder BRIN bei speziellen Verteilungen oder vor-sortierten Daten Vorteile bieten können.
  • Der wichtigste Schritt nach dem Import ist die kontinuierliche Validierung der Datenqualität und das ordnungsgemäße Setzen des SRID, um langlebige und performante Geodatenbanken sicherzustellen.

Nefino
Geodaten besser planen und analysieren
Nefino unterstützt Energieprojekte mit präzisen Flächenanalysen, aktuellen Marktdaten und geoinformationsbasierten Lösungen.

Inhaltsverzeichnis

Bulk-Import mit ogr2ogr: Befehle, Optionen und Beispiele

Für große GeoJSON-Dateien ist ogr2ogr die zuverlässigste Methode für den PostGIS-GeoJSON-Import. Das Grundkommando sieht so aus:

ogr2ogr -f "PostgreSQL" PG:"dbname=mydb user=postgres" source.geojson -nln target_table -lco GEOMETRY_NAME=geom -lco FID=id

Jede Option hat einen klaren Zweck:

  1. -f "PostgreSQL" legt das Zielformat fest, alles andere ist für dieses Kommando irrelevant.
  2. PG:"dbname=mydb user=postgres" ist die Verbindungszeichenfolge, hier können Sie auch Host und Passwort ergänzen.
  3. -nln target_table bestimmt den Zieltabellennamen, unabhängig vom Dateinamen der Quelle.
  4. -lco GEOMETRY_NAME=geom und -lco FID=id steuern, wie die Geometriespalte und der Primärschlüssel heißen.
  5. -append fügt Daten einer bestehenden Tabelle hinzu, -overwrite löscht und erstellt sie neu.
  6. -t_srs EPSG:4326 transformiert die Koordinaten während des Imports, -nlt erzwingt einen bestimmten Geometrietyp wie MULTIPOLYGON.

Achten Sie auf absolute Pfadangaben, besonders bei Cron-Jobs, und stellen Sie sicher, dass der Datenbankbenutzer Schreibrechte auf das Zielschema hat. Bei sehr großen Dateien empfiehlt es sich, den Import in einer einzigen Transaktion laufen zu lassen statt zeilenweise zu committen. Die vollständige Optionsliste liefert die GDAL-Dokumentation zu ogr2ogr, inklusive aller unterstützten Treiber.

Profi-Tipp: Bauen Sie den Spatial Index erst nach dem Bulk-Import, nicht vorher. Ein Index, der während tausender Inserts mitwächst, kostet deutlich mehr I/O als ein einmaliger Index-Build danach.

Wie verarbeitet man eine FeatureCollection direkt in SQL?

Wer keine Kommandozeile nutzen will oder GeoJSON aus einer API direkt in die Datenbank schreiben muss, geht über jsonb_array_elements. ST_GeomFromGeoJSON erwartet allerdings nur ein Geometry-Fragment, niemals ein komplettes GeoJSON-Dokument. Übergeben Sie eine ganze FeatureCollection direkt, bricht die Funktion mit einem Fehler ab. Sie müssen die Features zuerst extrahieren:

WITH features AS (
  SELECT jsonb_array_elements(data->'features') AS feature
  FROM staging_geojson
)
INSERT INTO target_table (name, geom)
SELECT
  feature->'properties'->>'name',
  ST_SetSRID(ST_GeomFromGeoJSON(feature->'geometry'), 4326)
FROM features;

Wichtige Punkte für dieses Muster:

  • jsonb_array_elements iteriert über das Array unter dem Schlüssel features, jede Zeile wird zu einem eigenen Feature.
  • feature->'properties'->>'name' greift auf beliebige Attribute zu und mappt sie auf Spalten Ihrer Zieltabelle.
  • ST_SetSRID ist hier kein Kosmetikschritt, sondern Pflicht, weil manche PostGIS-Versionen beim JSON-Input kein SRID zuweisen.
  • Bei heterogenen Geometrietypen (Punkte und Polygone in derselben Collection) empfiehlt sich eine geometry-Spalte ohne festen Subtyp statt geometry(Point,4326).
Schritt Funktion Zweck
Zerlegen jsonb_array_elements Iteration über das Feature-Array
Umwandeln ST_GeomFromGeoJSON Geometry-Fragment zu PostGIS-Geometrie
SRID setzen ST_SetSRID Referenzsystem explizit definieren

Kapseln Sie den gesamten Import in eine Transaktion. Schlägt eine Zeile fehl, etwa wegen eines leeren Geometry-Objekts, rollen Sie lieber komplett zurück, statt eine halb gefüllte Tabelle zu debuggen.

Wie behebt man falsche SRID- und Geometrie-Fehler?

Ein häufiger Fehler nach dem Import: Abfragen liefern leere Ergebnisse, obwohl die Tabelle Daten enthält. Meist liegt es am SRID. Fehlendes oder falsches SRID verhindert die Nutzung von Index und Joins, weil PostGIS zwei Geometrien mit unterschiedlichem Referenzsystem nicht sinnvoll vergleichen kann.

Prüfen Sie nach jedem Import diese Punkte:

  • SRID kontrollieren: SELECT DISTINCT ST_SRID(geom) FROM target_table; sollte genau einen Wert liefern, meist 4326.
  • Validität prüfen: SELECT COUNT(*) FROM target_table WHERE NOT ST_IsValid(geom); findet defekte Geometrien, etwa sich selbst überschneidende Polygone.
  • Reparieren statt neu importieren: UPDATE target_table SET geom = ST_MakeValid(geom) WHERE NOT ST_IsValid(geom); behebt die meisten Fälle ohne Datenverlust.
  • Koordinatenordnung checken: GeoJSON speichert immer Lon/Lat, nicht Lat/Lon. Liegen Ihre Punkte auf der falschen Seite der Karte, wurde die Reihenfolge vertauscht.
  • Transformieren bei Bedarf: Stammen die Quelldaten aus einem anderen Koordinatensystem, wandeln Sie mit ST_Transform(geom, 4326) um, nicht mit ST_SetSRID allein, das ändert nur das Label, nicht die Werte.

Profi-Tipp: Ein typischer Anfängerfehler ist, ST_SetSRID auf Koordinaten anzuwenden, die eigentlich transformiert werden müssten. Das Ergebnis sieht in ST_AsText unauffällig aus, landet auf der Karte aber tausende Kilometer daneben.

Welcher Spatial Index passt zu welcher Datenmenge?

Ohne Index wird aus jeder räumlichen Abfrage ein sequentieller Scan über die gesamte Tabelle. Ein GIST-Index ist die Standardempfehlung für praktisch jede PostGIS-Tabelle:

CREATE INDEX mytable_geom_idx ON mytable USING GIST (geom);

Für die meisten Projekte reicht das. Bei sehr speziellen Datenmustern lohnt sich ein Blick auf Alternativen:

  1. GIST ist der Allrounder, funktioniert mit jedem Geometrietyp und jeder Abfrageart.
  2. SPGIST kann bei bestimmten, ungleichmäßig verteilten Punktmustern schneller sein als GIST.
  3. BRIN eignet sich, wenn Ihre Daten bereits räumlich sortiert vorliegen, etwa nach einem Hilbert-Wert vorsortiert. Der Index ist deutlich kleiner, aber empfindlicher gegenüber unsortierten Daten.

Nicht jede Funktion nutzt den Index automatisch. ST_Intersects, ST_DWithin und ST_Contains sind index-aware, während manche Distanzberechnungen ohne den richtigen Operator den Index umgehen. Ob eine Abfrage den Index tatsächlich nutzt, zeigt EXPLAIN ANALYZE direkt im Ausführungsplan. Fehlt der Index-Scan dort, hilft oft nur eines: ANALYZE mytable; nachträglich ausführen, damit der Query-Planer aktuelle Statistiken hat.

Fehlerbehebung und Verifikation nach dem Import

Nach jedem Import lohnen sich drei schnelle Prüfungen, bevor Sie die Daten produktiv nutzen. Erstens, die Geometrietypen kontrollieren:

  • SELECT DISTINCT GeometryType(geom) FROM target_table; zeigt, ob wirklich nur die erwarteten Typen vorliegen.
  • SELECT COUNT(*) FROM target_table WHERE geom IS NULL; findet Zeilen, bei denen der Import stillschweigend keine Geometrie erzeugt hat.
  • SELECT ST_AsText(geom) FROM target_table LIMIT 5; gibt eine lesbare Textdarstellung, gut zum schnellen Gegenlesen mit der Quelldatei.

Typische Fehlermeldungen weisen meist auf denselben Grundproblemkreis hin: JSON-Parsing-Fehler bedeuten oft, dass ein komplettes GeoJSON-Dokument statt eines Geometry-Fragments an ST_GeomFromGeoJSON übergeben wurde. Leere Geometrien entstehen häufig durch null-Werte im Quell-GeoJSON, die ogr2ogr klaglos durchlässt.

Für produktive Systeme ist eine Staging-Tabelle sinnvoller als der direkte Import in die Zieltabelle:

  1. Import in staging_import ohne Constraints.
  2. Validierung und Bereinigung dort, inklusive ST_MakeValid.
  3. Erst danach INSERT INTO target_table SELECT ... mit allen Constraints aktiv.
  4. Staging-Tabelle abschließend leeren oder droppen.

So bleibt die Zieltabelle jederzeit konsistent, selbst wenn ein Import mitten im Lauf abbricht.

Wann ein spezialisiertes Geodaten-Tool sinnvoller ist als eine eigene Pipeline

ogr2ogr und die gezeigten SQL-Muster lösen den technischen Teil zuverlässig: Datei rein, Geometrie raus, Index drauf. Bei wiederkehrenden Importen aus vielen Quellen, unterschiedlichen GeoJSON-Versionen und wechselnden Attributschemata wächst der Wartungsaufwand aber schnell über das hinaus, was eine einzelne Pipeline leisten sollte.

Für Projektentwickler und Energieunternehmen, die Flächen- und Standortdaten nicht nur importieren, sondern laufend aktuell halten müssen, bietet Nefinos Data-as-a-Service eine Alternative zur eigenen ETL-Pipeline:

  • Geprüfte Geodatensätze statt selbst zusammengeführter Rohdaten aus verschiedenen Quellen.
  • Exportfunktionen, die mit gängigen GIS-Formaten kompatibel sind.
  • Flächenanalysen, die auf validierten und indizierten Datenbeständen aufsetzen.

Wer nur einmalig eine Handvoll GeoJSON-Dateien importieren muss, kommt mit ogr2ogr weiter. Wer Flächenbewertung, Planungsstatus und Marktdaten dauerhaft aktuell halten muss, spart mit einer geeigneten Plattformlösung vor allem eines: Zeit, die sonst in Datenpflege statt in Projektentscheidungen fließt.

Schnelle Referenz für den täglichen Gebrauch

Aufgabe Kommando oder Funktion
Bulk-Import GeoJSON ogr2ogr -f "PostgreSQL" PG:"dbname=mydb" datei.geojson -nln tabelle
FeatureCollection zerlegen jsonb_array_elements(data->'features')
Geometrie umwandeln ST_GeomFromGeoJSON(feature->'geometry')
SRID setzen ST_SetSRID(geom, 4326)
Validität prüfen ST_IsValid(geom)
Index anlegen CREATE INDEX idx ON tabelle USING GIST (geom);
Ausführungsplan prüfen EXPLAIN ANALYZE SELECT ...

Profi-Tipp: Speichern Sie sich dieses Cheatsheet als Snippet in Ihrem SQL-Client. Die Kombination aus ST_SetSRID und ST_IsValid direkt nach jedem Import erspart Ihnen die meisten Debugging-Sessions später.

Was beim GeoJSON-Import wirklich zählt

Die meisten Anleitungen zu diesem Thema behandeln ogr2ogr und die SQL-Methode als konkurrierende Ansätze, als müsse man sich für eines entscheiden. Das greift zu kurz. In der Praxis nutzen erfahrene Teams beides parallel, je nach Datenquelle und Häufigkeit des Imports.

Die eigentliche Schwachstelle liegt selten im Importbefehl selbst, sondern in dem, was danach passiert oder eben nicht passiert: SRID nicht gesetzt, Index vergessen, Validität nie geprüft. Ein Import, der technisch durchläuft, ist noch kein korrekter Import. Genau da unterscheidet sich robuste Datenarbeit von einem Skript, das einmal funktioniert hat und dann nie wieder angefasst wurde.

Wer regelmäßig aus wechselnden Quellen importiert, sollte Validierung und Indexbau als festen Bestandteil der Pipeline behandeln, nicht als optionalen letzten Schritt. Genau dort liegt auch der Punkt, an dem sich eine selbst gebaute Lösung von einer gepflegten Plattform unterscheidet: Nicht im Importbefehl, sondern in der Frage, wer die Datenqualität über Monate hinweg garantiert.

, Christian

Quellen

Empfehlungen

Nach oben