Vous stockez GeoJSON FeatureCollection dans PostgreSQL avec PostGIS?

21

Je suis nouveau sur GeoJSON. J'ai une collection de fonctionnalités GeoJSON comme indiqué et je voudrais la stocker dans le tableau postgres (table de test). Ma table postgres a un identifiant série et une colonne de géométrie.

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

Je voudrais insérer les données GeoJSON dans la table de test de la table.

Comment dois-je procéder?

J'utilise la version 9.3.5 de postgres avec la version 2.1.3 de postgis


J'ai été dirigé vers des questions posées précédemment qui répondent à la façon de stocker une seule entité, par exemple un point ou un polygone. Ma question demande comment enregistrer plusieurs fonctionnalités dans le fichier GeoJSON. Par plusieurs entités, j'entends un mélange de points, de lignes et de types d'entités surfaciques dans un seul fichier.

Geai
la source
Salut Ricardo, j'ai vu cette question mais elle ne règle pas mon problème. Je souhaite enregistrer une liste de fonctionnalités, pas seulement un seul type de fonctionnalité. Veuillez jeter un œil à ma collection de fonctionnalités GeoJSON dans ma question.
Jay
@Jay Alors maintenant, votre question est "Comment puis-je diviser une collection geojson en fonctionnalités uniques ou vous devez ajouter plus d'informations (peut-être stocker des informations sur l'appartenance de ces géométries à une sorte de collection?)
Jakub Kania
1
Merci @John pour votre réponse. Étant donné que je suis nouveau dans les SIG et GeoJSON, je voulais quelques conseils avec mon problème à portée de main. Contexte de la question: un utilisateur dessine les entités sur une carte et je capture la collection d'entités dessinées. Je voudrais enregistrer cette collection dans une base de données avec un identifiant unique. Plus tard, les données enregistrées peuvent être récupérées pour un identifiant fourni. Le testable en postgres a 2 colonnes. colonne gid de type série pour contenir l'id et colonne geom de type géométrie.
Jay
1
@Jay Oui, vous pouvez stocker le JSON, mais ce ne sera pas une géométrie, vous ne pourrez donc pas interroger facilement le plus proche voisin, etc.
Jakub Kania

Réponses:

26

En supposant que vous avez au moins PostgreSQL version 9.3, vous pouvez utiliser quelques fonctions et opérateurs JSON pour extraire les parties pertinentes de la spécification GeoJSON requises par ST_GeomFromGeoJSON pour créer des géométries.

Essayez ce qui suit, où vous pouvez remplacer le JSON dans la partie supérieure:

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;

Trouve trois géométries. La geomcolonne contient l'objet géométrique et le gidnuméro d'entité. La ST_AsTextfonction affiche l' équivalent WKT de chaque géométrie. J'ai également inclus les propertiesattributs ou qui peuvent être définis pour chaque géométrie, comme indiqué dans la spécification.

 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)

Vous devez attribuer un SRID à la géométrie, à l'aide de ST_SetSRID.

Ou si vous avez simplement besoin d'une seule GEOMETRYCOLLECTION hétérogène, vous pouvez la rendre compacte comme ceci:

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

Voir aussi Création de collections d'entités GeoJSON avec les fonctions JSON et PostGIS du Postgres OnLine Journal, qui fait le contraire.

Mike T
la source