Armazenando GeoJSON FeatureCollection para PostgreSQL com PostGIS?

21

Eu sou novo no GeoJSON. Eu tenho uma coleção de recursos do GeoJSON como mostrado e gostaria de armazená-la na tabela do postgres (testtable). Minha tabela do postgres possui uma identificação serial e uma coluna de geometria.

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

Gostaria de inserir os dados do GeoJSON na tabela de teste.

Como proceder?

Estou usando o postgres versão 9.3.5 com o postgis versão 2.1.3


Fui direcionado para perguntas anteriores que respondem como armazenar um único recurso, por exemplo, um ponto ou polígono. Minha pergunta pergunta como salvar vários recursos no arquivo GeoJSON. Por vários recursos, quero dizer uma mistura de pontos, linhas e tipos de recursos de polígono em um arquivo.

Jay
fonte
possível duplicata de Como inserir um polígono GeoJSON em uma tabela PostGIS?
Ricardo Oliveira
Oi Ricardo, eu vi essa pergunta, mas ela não resolve o meu problema. Quero salvar uma lista de recursos, não apenas um único tipo de recurso. Dê uma olhada na minha coleção de recursos do GeoJSON na minha pergunta.
Jay,
@Jay Então agora quer sua pergunta é "Como faço para acabar com uma coleção GeoJSON em características únicas ou você precisa adicionar mais informações (talvez armazenar informações que essas geometrias pertencer a algum tipo de coleção?)
Jakub Kania
1
Obrigado @ John pela sua resposta. Como sou novo no GIS e no GeoJSON, queria algumas dicas com o meu problema em mãos. Antecedentes da pergunta: um usuário desenha os recursos em um mapa e eu capturo a coleção de recursos desenhados. Gostaria de salvar esta coleção em um banco de dados com um ID exclusivo. Posteriormente, os dados salvos podem ser buscados para um ID fornecido. O testável no postgres possui 2 colunas. coluna gid que é um tipo de série, para conter o id, e a coluna geom que é do tipo geometria.
Jay
1
@ Jay Sim, você pode armazenar o JSON, mas como não será uma geometria, você não poderá consultar o vizinho mais próximo facilmente, etc.
Jakub Kania

Respostas:

26

Supondo que você tenha pelo menos o PostgreSQL versão 9.3, você pode usar algumas funções e operadores JSON para extrair as partes relevantes da especificação GeoJSON exigida por ST_GeomFromGeoJSON para criar geometrias.

Tente o seguinte, onde você pode substituir o JSON na 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;

Localiza três geometrias. A geomcoluna possui o objeto de geometria e gidé o número do recurso. A ST_AsTextfunção mostra o equivalente WKT de cada geometria. Também incluí os propertiesatributos ou que podem ser definidos para cada geometria, como é mostrado na especificação.

 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)

Você deve atribuir um SRID para a geometria, usando ST_SetSRID.

Ou, se você simplesmente precisar de uma única GEOMETRYCOLLECTION heterogênea, poderá compactá-la assim:

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 também Criando coleções de recursos GeoJSON com funções JSON e PostGIS no Postgres OnLine Journal, que faz o contrário.

Mike T
fonte