Wie füge ich ein GeoJSON-Polygon in eine PostGIS-Tabelle ein?

33

Ich muss ein Polygon aus GeoJSON in meine PostGIS-Tabelle einfügen. So sieht die SQL-Abfrage aus.

INSERT INTO tablename (name, polygon)
VALUES (
    'Name',
    ST_GeomFromGeoJSON(
        '{
            "type": "Polygon",
            "coordinates": [
                [7.734375,51.835777520452],
                [3.8671875,48.341646172375],
                [7.20703125,43.580390855608],
                [18.6328125,43.834526782237],
                [17.9296875,50.289339253292],
                [13.7109375,54.059387886624],
                [7.734375,51.835777520452]
            ]
        }'
    )
)

Leider erhalte ich eine Fehlermeldung.

ERROR:  Geometry SRID (0) does not match column SRID (3857)

Der GeoJSON befindet sich bereits im richtigen Referenzsystem. Dies ist jedoch nicht spezifiziert. Wie gebe ich die SRID im GeoJSON an? Wie muss der GeoJSON aussehen?

Aktualisieren: Wenn ich die Geometrie wickeln erstellt von ST_GeomFromGeoJSONmit ST_SetSRID(..., 3857)ihm einen weiteren Fehler wirft. Meiner Ansicht nach scheint die Geometrie keine Z-Dimension zu haben.

ERROR:  Geometry has Z dimension but column does not
danijar
quelle
Ich denke, Sie müssen angeben, dass die Tabelle srid hat: 4326, es sieht so aus, dass Ihre Tabelle srid hat: 3857, aber Ihr Geojson hat Long / Latitude (dh srid: 4326 oder WGS84)
Gery
Ich möchte 3857 verwenden. Wie muss der GeoJSON dann aussehen?
Danijar

Antworten:

32

Als ich mir den Quellcode von PostGIS anschaute, fand ich heraus, wie er SRIDs analysiert. Hier ist die richtige Methode, um die SRID in GeoJSON anzugeben.

Die GeoJSON-Spezifikation besagt, dass die Koordinaten eines Polygons ein Array von Strings sind. Deshalb musste ich sie mit zusätzlichen Klammern umwickeln.

{
    "type":"Polygon",
    "coordinates":
    [
        [
            [-91.23046875,45.460130637921],
            [-79.8046875,49.837982453085],
            [-69.08203125,43.452918893555],
            [-88.2421875,32.694865977875],
            [-91.23046875,45.460130637921]
        ]
    ],
    "crs":{"type":"name","properties":{"name":"EPSG:3857"}}
}
danijar
quelle
16

Es gibt einige Probleme mit Ihrem JSON.

  1. Erstens sollten die Koordinaten ein Array von Arrays sein.
  2. Zweitens sieht es in Bezug auf die Koordinaten so aus, als wären die Werte in einem geografischen Koordinatensystem Latlong, höchstwahrscheinlich EPSG: 4326. Das muss dann in EPSG umgewandelt werden: 3857.

Sobald Sie diese beiden Dinge korrigiert haben, können Sie die Zeile mit der folgenden SQL-Abfrage einfügen:

INSERT INTO "Parcels"("Name", the_geom)
    VALUES ('Corrected_Shape', 
    ST_TRANSFORM(ST_GeomFromGeoJSON('{
    "type":"Polygon",
    "coordinates":[[
        [-91.23046875,45.460130637921],
        [-79.8046875,49.837982453085],
        [-69.08203125,43.452918893555],
        [-88.2421875,32.694865977875],
        [-91.23046875,45.460130637921]
    ]],
    "crs":{"type":"name","properties":{"name":"EPSG:4326"}}
}'),3857));

Wenn dies nicht funktioniert (dh Sie erhalten immer noch den Fehler mit Z diemsnion), aktualisieren Sie die Frage mit der PostGis-Version und der Create-Anweisung Ihrer Tabelle.

Devdatta Tengshe
quelle
Warum sind die Koordinaten Ihrer Meinung nach nicht in EPSG: 3857?
Danijar
3
Weil die Einheiten von EPSG: 3857 (Pseudo) Meter sind und der Ursprung im Atlantik liegt. Mit Metern hätten Sie keine Genauigkeit von 6 Dezimalstellen, und diese Daten würden im Atlantik nahe der afrikanischen Küste liegen.
Devdatta Tengshe
Die Koordinaten stammen von Eingaben auf einer Karte und haben viele Dezimalstellen. Zum Testen habe ich ein Gebiet im Atlantik in der Nähe von Afrika gezeichnet. Aber dank dir kann ich die Karte verbessern, um die Koordinaten auf ganze Meter zu runden.
Danijar
@danijar: Dann ist alles in Ordnung. Wenn diese Koordinaten in EPSG: 4326 wären, dann würde es über den östlichen Bundesstaaten der USA liegen.
Devdatta Tengshe
5

Ihr Geojson muss stattdessen UTM-Werte haben. Sie können dies mit Proj oder anderen Online-Tools umwandeln. Sie können dies jedoch einfach und direkt mit postgis tun, bevor Sie es in Ihre Tabelle einfügen. Versuchen Sie Folgendes (ungetestet):

SELECT ST_AsText(ST_Transform(ST_GeomFromGeoJSON
    (
        {
            "type":"Polygon",
            "coordinates":[
                [7.734375,51.835777520452],
                [3.8671875,48.341646172375],
                [7.20703125,43.580390855608],
                [18.6328125,43.834526782237],
                [17.9296875,50.289339253292],
                [13.7109375,54.059387886624],
                [7.734375,51.835777520452]
            ]
        }
    ),4326),3857));
Gery
quelle
Sie schlagen also vor, die SRID über 4326 in 3857 umzuwandeln? Dann könnte ich ST_Transform (ST_SetSRID (..., 4326), 3857) direkt ausprobieren, oder? Warum sollte dieser zusätzliche Transformationsschritt notwendig sein?
Danijar
Ich denke, du solltest testen, was du fragst. Vermutlich ist das, was du vorschlägst, der einzige Schritt, den du brauchst. Probiere es aus und poste, was du hast
Gery,
Das bekomme ich. ERROR: transform: couldn't project point (9.25253e-302 6.08985e+159 1.18576e-322): latitude or longitude exceeded limits (-14)
Danijar
3
INSERT INTO tablename (name, polygon)
VALUES
(
    'Name',
    ST_GeomFromGeoJSON
    (
        '{
            "type":"Polygon",
            "coordinates":[
                [7.734375,51.835777520452],
                [3.8671875,48.341646172375],
                [7.20703125,43.580390855608],
                [18.6328125,43.834526782237],
                [17.9296875,50.289339253292],
                [13.7109375,54.059387886624],
                [7.734375,51.835777520452]
            ]
        }'
    )
)

fehlendes "'"

Zakaria Jaddy
quelle
4
Könnten Sie mehr Kontext zu dieser Antwort hinzufügen und erklären , wie es OPs Frage beantwortet, und unterscheidet sich von bestehenden Antworten
Devdatta Tengshe
Ehrlich gesagt, die JSON ist eine Zeichenfolge sein, es ist kein String in der Frage und es ist kein String in mindestens eine der Antworten. Diese Antwort mag auf das Offensichtliche hinweisen, aber es ist nicht notwendigerweise für jeden offensichtlich, und verdient etwas Anerkennung.
Forbesmyester