¿Almacenar GeoJSON FeatureCollection en PostgreSQL con PostGIS?

21

Soy nuevo en GeoJSON. Tengo una colección de características GeoJSON como se muestra y me gustaría almacenarla en la tabla postgres (testtable). Mi tabla de postgres tiene una columna de geometría e identificación de serie.

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

Me gustaría insertar los datos de GeoJSON en la tabla testtable.

¿Cómo lo hago?

Estoy usando postgres versión 9.3.5 con postgis versión 2.1.3


Me han dirigido a preguntas anteriores que responden sobre cómo almacenar una sola característica, por ejemplo, un punto o polígono. Mi pregunta es cómo guardar múltiples funciones en el archivo GeoJSON. Por características múltiples me refiero a una mezcla de puntos, líneas y tipos de características poligonales en un archivo.

Arrendajo
fuente
posible duplicado de Cómo insertar un polígono GeoJSON en una tabla PostGIS?
Ricardo Oliveira
Hola Ricardo, he visto esa pregunta pero no aborda mi problema. Quiero guardar una lista de características, no solo un tipo de característica. Echa un vistazo a mi colección de características GeoJSON en mi pregunta.
Jay
@ Jay Entonces, ahora su pregunta es "¿Cómo divido una colección de geojson en características individuales o si necesita agregar más información (tal vez almacenar información de que esas geometrías pertenecen a algún tipo de colección?)
Jakub Kania
1
Gracias @ John por tu respuesta. Como soy nuevo en GIS y GeoJSON, quería algunos consejos con mi problema en mente. Antecedentes de la pregunta: un usuario dibuja las características en un mapa y yo capturo la colección de características dibujadas. Me gustaría guardar esta colección en una base de datos con una identificación única. Más tarde, los datos guardados se pueden recuperar para una identificación proporcionada. El comprobable en postgres tiene 2 columnas. columna gid que es un tipo de serie, para contener el id, y columna geom que es del tipo de geometría.
Jay
1
@ Jay Sí, puede almacenar el JSON, pero no será una geometría, por lo que no podrá consultar el vecino más cercano, etc.
Jakub Kania

Respuestas:

26

Suponiendo que tiene al menos PostgreSQL versión 9.3, puede usar algunas funciones y operadores JSON para extraer las partes relevantes de la especificación GeoJSON requerida por ST_GeomFromGeoJSON para crear geometrías.

Pruebe lo siguiente, donde puede reemplazar el JSON en la parte superior:

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;

Encuentra tres geometrías. La geomcolumna tiene el objeto de geometría, y gides el número de entidad. La ST_AsTextfunción muestra el equivalente WKT de cada geometría. También he incluido los propertiesatributos o que se pueden definir para cada geometría, como se muestra en la especificación.

 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)

Debe asignar un SRID para la geometría, utilizando ST_SetSRID.

O si simplemente necesita una única GEOMETRYCOLLECTION heterogénea, puede hacerla compacta de esta manera:

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

Consulte también Creación de colecciones de características GeoJSON con funciones JSON y PostGIS del Postgres OnLine Journal, que hace lo contrario.

Mike T
fuente