Comment insérer un polygone GeoJSON dans une table PostGIS?


34

Je dois insérer un polygone de GeoJSON dans ma table PostGIS. Voici à quoi ressemble la requête SQL.

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]
            ]
        }'
    )
)

Malheureusement, je reçois un message d'erreur.

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

Le GeoJSON est déjà dans le bon système de référence. Mais ce n'est pas spécifié. Comment spécifier le SRID dans le GeoJSON? À quoi doit ressembler le GeoJSON?

Mise à jour: Quand j'Enveloppez la géométrie créée par ST_GeomFromGeoJSONavec ST_SetSRID(..., 3857)elle lance une autre erreur. À mon avis, il ne semble pas que la géométrie ait une dimension Z.

ERROR:  Geometry has Z dimension but column does not

Je pense que vous devez spécifier que la table a srid: 4326, il semblerait que votre table a srid: 3857 mais votre geojson a long / latitude (ie. Srid: 4326 ou WGS84)
Gery

Je veux utiliser le 3857. À quoi doit ressembler le GeoJSON?
danijar

Réponses:


33

En regardant le code source de PostGIS, j'ai découvert comment il analyse les SRID. Voici la manière correcte de spécifier le SRID dans GeoJSON.

La spécification GeoJSON indique que les coordonnées d'un polygone sont un tableau de lignes. Par conséquent, je devais les emballer avec des supports supplémentaires.

{
    "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"}}
}

16

Il y a quelques problèmes avec votre JSON.

  1. Premièrement, les coordonnées devraient être un tableau de tableaux.
  2. Deuxièmement, en regardant les coordonnées, il semble que les valeurs sont Latlong dans un système de coordonnées géographiques, très probablement EPSG: 4326. Cela doit ensuite être transformé en EPSG: 3857.

Une fois ces deux choses corrigées, vous pouvez insérer la ligne à l’aide de la requête SQL suivante:

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));

Si cela ne fonctionne pas (c'est-à-dire que vous obtenez toujours l'erreur avec Z diemsnion), veuillez mettre à jour la question avec la version PostGis et la déclaration Create de votre table.


Pourquoi pensez-vous que les coordonnées ne sont pas en EPSG: 3857?
Jour

3
Parce que les unités de EPSG: 3857 sont des (pseudo) mètres, et que l’origine se trouve dans l’océan Atlantique. Vous ne disposez pas d'une précision de 6 décimales avec les compteurs, et ces données se situeraient dans l'océan Atlantique, près des côtes africaines.
Devdatta Tengshe

Les coordonnées proviennent d'une entrée sur une carte et ont beaucoup de décimales. Pour tester, j'ai dessiné une zone dans l'océan Atlantique, près de l'Afrique. Mais grâce à vous, je peux améliorer la carte pour arrondir les coordonnées en mètres entiers.
danijar

@danijar: Alors tout va bien. Si ces coordonnées étaient en EPSG: 4326, elles se trouveraient dans les États de l’est des États-Unis.
Devdatta Tengshe

5

votre geojson doit plutôt avoir des valeurs UTM, vous pouvez le transformer avec Proj ou d'autres outils en ligne, mais vous pouvez le faire facilement et directement avec postgis avant de l'insérer dans votre tableau, essayez ceci (non testé):

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));

Vous proposez donc de convertir le SRID de plus de 4326 en 3857? Ensuite, je pourrais directement essayer ST_Transform (ST_SetSRID (..., 4326), 3857), n'est-ce pas? Pourquoi cette étape de transformation supplémentaire serait-elle nécessaire?
danijar

Je pense que vous devriez tester ce que vous demandez, probablement ce que vous suggérez est la seule étape dont vous avez besoin, essayez-le et postez ce que vous avez obtenu
Gery

C'est ce que je reçois. 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]
            ]
        }'
    )
)

manquant "'"


4
Pourriez-vous ajouter un contexte à cette réponse et expliquer comment elle répond à la question d'OP, et est différente des réponses existantes
Devdatta Tengshe

Honnêtement, le JSON doit être une chaîne, ce n'est pas une chaîne dans la question et ce n'est pas une chaîne dans au moins une des réponses. Cette réponse pourrait mettre en évidence l'évidence, mais ce n'est pas forcément évident pour tout le monde, elle mérite donc un crédit.
Forbesmyester
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.