Как вставить полигон GeoJSON в таблицу PostGIS?

34

Мне нужно вставить многоугольник из GeoJSON в мою таблицу PostGIS. Вот так выглядит 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]
            ]
        }'
    )
)

К сожалению, я получаю сообщение об ошибке.

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

GeoJSON уже находится в правильной системе отсчета. Но это не указано. Как мне указать SRID в GeoJSON? Как должен выглядеть GeoJSON?

Обновление: Когда я обернуть геометрию , созданную ST_GeomFromGeoJSONс ST_SetSRID(..., 3857)его бросает другую ошибку. На мой взгляд, не похоже, что геометрия имеет размерность Z.

ERROR:  Geometry has Z dimension but column does not
Данияр
источник
Я думаю, что вам нужно указать, что таблица имеет srid: 4326, похоже, что ваша таблица имеет srid: 3857, но у вашего геойсона есть long / широта (т.е. srid: 4326 или WGS84)
Gery
Я хочу использовать 3857. Как тогда должен выглядеть GeoJSON?
Данияр

Ответы:

33

Взглянув на исходный код PostGIS, я узнал, как он анализирует SRID. Вот правильный способ указать SRID в GeoJSON.

В спецификации GeoJSON говорится, что координаты многоугольника представляют собой массив строк. Поэтому мне пришлось обернуть их дополнительными скобками.

{
    "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"}}
}
Данияр
источник
16

Есть несколько проблем с вашим JSON.

  1. Во-первых, координаты должны быть массивом массивов.
  2. Во-вторых, глядя на координаты, выглядело, как будто значения в латлонге в географической системе координат, наиболее вероятно, EPSG: 4326. Затем его необходимо преобразовать в EPSG: 3857.

Как только вы исправите эти две вещи, вы можете вставить строку, используя следующий 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));

Если это не работает (т.е. вы все еще получаете ошибку с Z diemsnion), пожалуйста, обновите вопрос с помощью версии PostGis и инструкции Create your table.

Девдатта Тенгше
источник
Как вы думаете, почему координаты не в EPSG: 3857?
Данияр
3
Потому что единицы EPSG: 3857 являются (псевдо) метрами, а их происхождение находится в Атлантическом океане. У вас не будет 6 десятичной точности с метрами, и эти данные будут лежать в Атлантическом океане недалеко от побережья Африки.
Девдатта Тенгше
Координаты взяты из ввода на карте и имеют много десятичных знаков. Для тестирования я нарисовал область в Атлантическом океане недалеко от Африки. Но благодаря вам я могу улучшить карту, чтобы округлить координаты до целых метров.
Данияр
@danijar: Тогда все в порядке. Если бы эти координаты были в EPSG: 4326, то они лежали бы над восточными штатами США.
Девдатта Тенгше
5

вместо этого ваш geojson должен иметь значения UTM, вы можете преобразовать его с помощью Proj или других онлайн-инструментов, но вы можете легко и напрямую сделать это с помощью postgis, прежде чем вставлять его в таблицу, попробуйте это (не проверено):

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));
Джери
источник
Итак, вы предлагаете преобразовать SRID через 4326 в 3857? Тогда я мог бы напрямую попробовать ST_Transform (ST_SetSRID (..., 4326), 3857), не так ли? Зачем нужен этот дополнительный шаг трансформации?
Данияр
Я думаю, что вы должны проверить то, что вы спрашиваете, вероятно, то, что вы предлагаете, - единственный шаг, который вам нужен, попробуйте сделать это и опубликуйте то, что вы получили
Gery
Это то, что я получаю. ERROR: transform: couldn't project point (9.25253e-302 6.08985e+159 1.18576e-322): latitude or longitude exceeded limits (-14)
Данияр
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]
            ]
        }'
    )
)

отсутствует "'"

Закария Джедди
источник
4
Не могли бы вы добавить больше контекста к этому ответу и объяснить, как он отвечает на вопрос OP, и отличается от существующих ответов
Devdatta Tengshe
Честно говоря, JSON действительно должен быть строкой, это не строка в этом вопросе , и это не строка , по крайней мере , один из ответов. Этот ответ может указывать на очевидное, но это не обязательно очевидно для всех, поэтому заслуживает некоторого доверия.
Forbesmyester