Como inserir um polígono GeoJSON em uma tabela PostGIS?

33

Preciso inserir um polígono do GeoJSON na minha tabela PostGIS. É assim que a consulta SQL se parece.

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

Infelizmente, recebo uma mensagem de erro.

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

O GeoJSON já está no sistema de referência correto. Mas isso não está especificado. Como especifico o SRID no GeoJSON? Como é o visual do GeoJSON?

Update: Quando eu embrulhar a geometria criado por ST_GeomFromGeoJSONcom ST_SetSRID(..., 3857)ele lança outro erro. Na minha opinião, não parece que a geometria tenha uma dimensão Z.

ERROR:  Geometry has Z dimension but column does not
danijar
fonte
Acho que você precisa para especificar que a tabela tem srid: 4326, parece que a sua tabela tem srid: 3857, mas o seu GeoJSON tem long / latitude (ie srid:. 4326 ou WGS84)
Gery
Eu quero usar 3857. Como é que o GeoJSON deve ser então?
Danijar

Respostas:

32

Analisando o código fonte do PostGIS, descobri como ele analisa os SRIDs. Aqui está a maneira correta de especificar o SRID no GeoJSON.

A especificação GeoJSON diz que as coordenadas de um polígono são uma matriz de cadeias de linhas. Portanto, eu tive que envolvê-los com colchetes adicionais.

{
    "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
fonte
16

Existem alguns problemas com o seu JSON.

  1. Em primeiro lugar, as coordenadas devem ser uma matriz de matrizes.
  2. Em segundo lugar, olhando para as coordenadas, parece que os valores são Latlong em um sistema de coordenadas geográficas, provavelmente EPSG: 4326. Isso precisa ser transformado em EPSG: 3857.

Depois de corrigir essas duas coisas, você pode inserir a linha, usando a seguinte consulta SQL:

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

Se isso não funcionar, (ou seja, você ainda está recebendo o erro com o Z diemsnion), atualize a pergunta com a versão do PostGis e a instrução Create da sua tabela.

Devdatta Tengshe
fonte
Por que você acha que as coordenadas não estão no EPSG: 3857?
Danijar 17/05
3
Porque as unidades de EPSG: 3857 são (pseudo) metros e a origem está no Oceano Atlântico. Você não teria precisão de 6 decimais com metros, e esses dados estariam no Oceano Atlântico, perto da costa da África.
Devdatta Tengshe
As coordenadas são da entrada em um mapa e têm muitas casas decimais. Para testar, desenhei uma área no Oceano Atlântico perto da África. Mas, graças a você, posso melhorar o mapa para arredondar as coordenadas para metros inteiros.
Danijar 17/05
@danijar: Então está tudo bem. Se essas coordenadas estivessem no EPSG: 4326, estariam sobre os estados do leste dos EUA.
Devdatta Tengshe
5

seu geojson deve ter valores UTM; você pode transformá-lo com o Proj ou outras ferramentas on-line, mas pode fazê-lo facilmente e diretamente com o postgis antes de inseri-lo na sua tabela, tente o seguinte (não testado):

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
fonte
Então você sugere converter o SRID sobre 4326 para 3857? Então eu poderia tentar diretamente ST_Transform (ST_SetSRID (..., 4326), 3857), não poderia? Por que essa etapa extra de transformação seria necessária?
Danijar
Eu acho que você deve testar o que está pedindo, provavelmente o que você sugere é a única etapa que você precisa, experimentá-lo e postar o que você tem
Gery
É isso que eu recebo. 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]
            ]
        }'
    )
)

ausência de "'"

Zakaria Jaddy
fonte
4
Você pode adicionar mais contexto para esta resposta e explicar como ele responde à pergunta do OP, e é diferente de respostas existentes
Devdatta Tengshe
Honestamente, o JSON não tem que ser uma string, ela não é uma string na questão e não é uma string em pelo menos uma das respostas. Essa resposta pode indicar o óbvio, mas não é necessariamente óbvio para todos, por isso merece algum crédito.
Forbesmyester