Speichern von GeoJSON FeatureCollection in PostgreSQL mit PostGIS?

21

Ich bin neu bei GeoJSON. Ich habe eine GeoJSON-Features-Sammlung wie gezeigt und möchte sie in einer Postgres-Tabelle (Testtabelle) speichern. Meine postgres-Tabelle enthält eine Seriennummer und eine Geometriespalte.

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    2565453.1826721914,
                    -3835048.659760314
                ]
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "LineString",
                "coordinates": [
                    [
                        2727584.7219710173,
                        -3713449.1942418693
                    ],
                    [
                        2732476.691781269,
                        -3992291.473426192
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            2442627.9025405287,
                            -3705499.954308534
                        ],
                        [
                            2425506.008204649,
                            -3886502.837287831
                        ],
                        [
                            2425506.008204649,
                            -3886502.837287831
                        ],
                        [
                            2555143.2081763083,
                            -3910962.686339088
                        ],
                        [
                            2442627.9025405287,
                            -3705499.954308534
                        ]
                    ]
                ]
            }
        }
    ]
}

Ich möchte die GeoJSON-Daten in die Tabelle testtable einfügen.

Wie gehe ich vor?

Ich benutze die postgres Version 9.3.5 mit der postgis Version 2.1.3


Ich bin auf zuvor gestellte Fragen verwiesen worden, die beantworten, wie ein einzelnes Feature, z. B. ein Punkt oder ein Polygon, gespeichert wird. Meine Frage lautet, wie mehrere Features in der GeoJSON-Datei gespeichert werden sollen. Mit mehreren Features meine ich eine Mischung aus Punkten, Linien und Polygon-Feature-Typen in einer Datei.

Jay
quelle
mögliches Duplikat von Wie füge ich ein GeoJSON-Polygon in eine PostGIS-Tabelle ein?
Ricardo Oliveira
Hallo Ricardo, ich habe diese Frage gesehen, aber sie geht mein Problem nicht an. Ich möchte eine Liste von Features speichern, nicht nur einen einzelnen Feature-Typ. Bitte werfen Sie einen Blick auf meine GeoJSON-Features-Sammlung in meiner Frage.
Jay
@Jay Nun lautet Ihre Frage entweder "Wie teile ich eine Geojson-Sammlung in einzelne Features auf?" Oder Sie müssen weitere Informationen hinzufügen (möglicherweise Informationen speichern, die zu einer Art Sammlung gehören?)
Jakub Kania,
1
Vielen Dank @ John für Ihre Antwort. Da ich neu bei GIS und GeoJSON bin, wollte ich einige Hinweise zu meinem Problem haben. Hintergrund der Frage: Ein Benutzer zeichnet die Features auf einer Karte und ich zeichne die Sammlung der Features auf. Ich möchte diese Sammlung in einer DB mit einer eindeutigen ID speichern. Die gespeicherten Daten können später für eine angegebene ID abgerufen werden. Das in postgres testbare hat 2 Spalten. gid-Spalte, die ein serieller Typ ist, um die ID aufzunehmen, und geom-Spalte, die ein Geometrietyp ist.
Jay
1
@Jay Ja, Sie können den JSON-Code speichern, es handelt sich dann jedoch nicht um eine Geometrie, sodass Sie problemlos nach dem nächsten Nachbarn usw. suchen können.
Jakub Kania

Antworten:

26

Vorausgesetzt, Sie haben mindestens PostgreSQL Version 9.3, können Sie einige JSON-Funktionen und -Operatoren verwenden , um die relevanten Teile der GeoJSON-Spezifikation zu extrahieren, die von ST_GeomFromGeoJSON zum Erstellen von Geometrien benötigt werden.

Versuchen Sie Folgendes, wo Sie den JSON im oberen Teil ersetzen können:

WITH data AS (SELECT '{ "type": "FeatureCollection",
    "features": [
      { "type": "Feature",
        "geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
        "properties": {"prop0": "value0"}
        },
      { "type": "Feature",
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
            ]
          },
        "properties": {
          "prop0": "value0",
          "prop1": 0.0
          }
        },
      { "type": "Feature",
         "geometry": {
           "type": "Polygon",
           "coordinates": [
             [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
               [100.0, 1.0], [100.0, 0.0] ]
             ]
         },
         "properties": {
           "prop0": "value0",
           "prop1": {"this": "that"}
           }
         }
       ]
     }'::json AS fc)

SELECT
  row_number() OVER () AS gid,
  ST_AsText(ST_GeomFromGeoJSON(feat->>'geometry')) AS geom,
  feat->'properties' AS properties
FROM (
  SELECT json_array_elements(fc->'features') AS feat
  FROM data
) AS f;

Findet drei Geometrien. Die geomSpalte enthält das Geometrieobjekt und dasgid ist die Feature-Nummer. Die ST_AsTextFunktion zeigt das WKT- Äquivalent jeder Geometrie. Ich habe auch die propertiesAttribute oder hinzugefügt, die für jede Geometrie definiert werden können, wie in der Spezifikation gezeigt.

 gid |                   geom                   |              properties
-----+------------------------------------------+--------------------------------------
   1 | POINT(102 0.5)                           | {"prop0": "value0"}
   2 | LINESTRING(102 0,103 1,104 0,105 1)      | {                                   +
     |                                          |           "prop0": "value0",        +
     |                                          |           "prop1": 0.0              +
     |                                          |           }
   3 | POLYGON((100 0,101 0,101 1,100 1,100 0)) | {                                   +
     |                                          |            "prop0": "value0",       +
     |                                          |            "prop1": {"this": "that"}+
     |                                          |            }
(3 rows)

Sie sollten mit ST_SetSRID eine SRID für die Geometrie zuweisen.

Oder wenn Sie nur eine einzige heterogene GEOMETRYCOLLECTION benötigen, können Sie diese so kompakt gestalten:

SELECT ST_AsText(ST_Collect(ST_GeomFromGeoJSON(feat->>'geometry')))
FROM (
  SELECT json_array_elements('{ ... put JSON here ... }'::json->'features') AS feat
) AS f;

GEOMETRYCOLLECTION(POINT(2565453.18267219 -3835048.65976031),LINESTRING(2727584.72197102 -3713449.19424187,2732476.69178127 -3992291.47342619),POLYGON((2442627.90254053 -3705499.95430853,2425506.00820465 -3886502.83728783,2555143.20817631 -3910962.68633909,2442627.90254053 -3705499.95430853)))

Siehe auch Erstellen von GeoJSON-Feature-Sammlungen mit JSON- und PostGIS-Funktionen aus dem Postgres OnLine-Journal.

Mike T
quelle