Jak wstawić wielokąt GeoJSON do tabeli PostGIS?

33

Muszę wstawić wielokąt z GeoJSON do mojej tabeli PostGIS. Tak wygląda zapytanie 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]
            ]
        }'
    )
)

Niestety pojawia się komunikat o błędzie.

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

GeoJSON jest już w odpowiednim systemie odniesienia. Ale nie jest to określone. Jak określić SRID w GeoJSON? Jak powinien wyglądać GeoJSON?

Aktualizacja: Kiedy owinąć geometrii utworzonej przez ST_GeomFromGeoJSONz ST_SetSRID(..., 3857)rzuca kolejny błąd. Moim zdaniem nie wydaje się, aby geometria miała wymiar Z.

ERROR:  Geometry has Z dimension but column does not
danijar
źródło
Myślę, że musisz określić, że tabela ma srid: 4326, wygląda na to, że twoja tabela ma srid: 3857, ale twój geojson ma długą / szerokość geograficzną (tj. Srid: 4326 lub WGS84)
Gery
Chcę użyć 3857. Jak powinien wyglądać GeoJSON?
danijar

Odpowiedzi:

32

Patrząc na kod źródłowy PostGIS, dowiedziałem się, jak analizuje on identyfikatory SRID. Oto poprawny sposób określenia SRID w GeoJSON.

Specyfikacja GeoJSON mówi, że współrzędne wielokąta są tablicą ciągów linii. Dlatego musiałem owinąć je dodatkowymi wspornikami.

{
    "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
źródło
16

Istnieje kilka problemów z JSON.

  1. Po pierwsze, współrzędne powinny być tablicą tablic.
  2. Po drugie, patrząc na współrzędne, wygląda na to, że wartości są Długie w układzie współrzędnych geograficznych, najprawdopodobniej EPSG: 4326. Następnie należy go przekształcić w EPSG: 3857.

Po poprawieniu tych dwóch rzeczy możesz wstawić wiersz, używając następującego zapytania 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));

Jeśli to nie zadziała (tzn. Nadal pojawia się błąd związany z Z diemsnion), zaktualizuj pytanie w wersji PostGis i Utwórz instrukcję dla swojej tabeli.

Devdatta Tengshe
źródło
Jak myślisz, dlaczego współrzędne nie są w EPSG: 3857?
danijar
3
Ponieważ jednostki EPSG: 3857 to (pseudo) metry, a ich źródłem jest Ocean Atlantycki. Mierniki nie miałyby dokładności 6 miejsc po przecinku, a dane te leżą na Oceanie Atlantyckim w pobliżu wybrzeży Afryki.
Devdatta Tengshe
Współrzędne pochodzą z danych wejściowych na mapie i mają wiele miejsc po przecinku. Do testów narysowałem obszar na Oceanie Atlantyckim w pobliżu Afryki. Ale dzięki tobie mogę ulepszyć mapę, aby zaokrąglić współrzędne do pełnych metrów.
danijar
@danijar: W porządku. Gdyby te współrzędne były w EPSG: 4326, to leżałyby nad wschodnimi stanami USA.
Devdatta Tengshe
5

twój geojson musi mieć zamiast tego wartości UTM, możesz to przekształcić za pomocą Proj lub innych narzędzi online, ale możesz to zrobić łatwo i bezpośrednio za pomocą postgis przed wstawieniem go do stołu, wypróbuj to (niesprawdzone):

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
źródło
Więc sugerujesz przekonwertować SRID z 4326 na 3857? Wtedy mógłbym bezpośrednio wypróbować ST_Transform (ST_SetSRID (..., 4326), 3857), prawda? Dlaczego ten dodatkowy etap transformacji byłby konieczny?
danijar
Myślę, że powinieneś przetestować to, o co pytasz, prawdopodobnie to, co sugerujesz, to jedyny potrzebny krok, spróbuj i opublikuj to, co masz
Gery
Właśnie to dostaję. 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]
            ]
        }'
    )
)

brakuje „”

Zakaria Jaddy
źródło
4
Czy możesz dodać więcej kontekstu do tej odpowiedzi i wyjaśnić, w jaki sposób odpowiada ona na pytanie OP i różni się od istniejących odpowiedzi
Devdatta Tengshe
Szczerze mówiąc, JSON ma być ciąg, nie jest ciągiem znaków w pytaniu i to nie jest ciągiem w co najmniej jednej z odpowiedzi. Ta odpowiedź może wskazywać na oczywiste, ale niekoniecznie oczywiste dla wszystkich, więc zasługuje na uznanie.
Forbesmyester