Làm cách nào để chèn đa giác GeoJSON vào bảng PostGIS?


33

Tôi cần chèn một đa giác từ GeoJSON vào bảng PostGIS của mình. Đây là cách truy vấn SQL trông như thế nào.

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

Thật không may, tôi nhận được một thông báo lỗi.

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

GeoJSON đã có trong hệ thống tham chiếu phù hợp. Nhưng điều này không được chỉ định. Làm cách nào để chỉ định SRID trong GeoJSON? GeoJSON cần trông như thế nào?

Cập nhật: Khi tôi quấn hình học được tạo ra bởi ST_GeomFromGeoJSONvới ST_SetSRID(..., 3857)nó throws lỗi khác. Theo quan điểm của tôi, dường như hình học không có kích thước Z.

ERROR:  Geometry has Z dimension but column does not

Tôi nghĩ rằng bạn cần xác định rằng bảng có srid: 4326, có vẻ như bảng của bạn có srid: 3857 nhưng Geojson của bạn có dài / vĩ độ (ví dụ: srid: 4326 hoặc WGS84)
Gery

Tôi muốn sử dụng 3857. GeoJSON phải trông như thế nào sau đó?
danijar

Câu trả lời:


32

Nhìn vào mã nguồn của PostGIS tôi đã tìm ra cách nó phân tích cú pháp SRID. Đây là cách chính xác để chỉ định SRID trong GeoJSON.

Đặc tả GeoJSON nói rằng tọa độ của đa giác là một chuỗi các chuỗi dòng. Vì vậy, tôi đã phải bọc chúng với dấu ngoặc bổ sung.

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

Có một vài vấn đề với JSON của bạn.

  1. Đầu tiên, tọa độ phải là một mảng các mảng.
  2. Thứ hai, nhìn vào tọa độ, có vẻ như các giá trị là Latlong trong hệ tọa độ Địa lý, rất có thể là EPSG: 4326. Điều đó sau đó cần phải được chuyển đổi thành EPSG: 3857.

Khi bạn sửa hai điều này, bạn có thể chèn hàng, sử dụng Truy vấn SQL sau:

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

Nếu điều này không hoạt động, (tức là bạn vẫn gặp lỗi với Z diemsnion), vui lòng cập nhật câu hỏi với phiên bản PostGis và Tạo tuyên bố của bảng của bạn.


Tại sao bạn nghĩ tọa độ không có trong EPSG: 3857?
danijar

3
Bởi vì các đơn vị của EPSG: 3857 là (giả) và nguồn gốc là ở Đại Tây Dương. Bạn sẽ không có độ chính xác 6 thập phân với mét và dữ liệu này sẽ nằm ở Đại Tây Dương gần bờ biển châu Phi.
Devdatta Tengshe

Các tọa độ là từ đầu vào trên bản đồ và có rất nhiều số thập phân. Để thử nghiệm, tôi đã vẽ một khu vực ở Đại Tây Dương gần Châu Phi. Nhưng nhờ có bạn mà tôi có thể cải thiện bản đồ để làm tròn tọa độ thành toàn bộ mét.
danijar

@danijar: Không sao đâu. Nếu các tọa độ này nằm trong EPSG: 4326, thì nó sẽ nằm trên các tiểu bang phía đông của Hoa Kỳ.
Devdatta Tengshe

5

Geojson của bạn phải có các giá trị UTM thay vào đó, bạn có thể chuyển đổi nó bằng Proj hoặc các công cụ trực tuyến khác, nhưng bạn có thể thực hiện dễ dàng và trực tiếp với postgis trước khi chèn nó vào bảng của mình, hãy thử điều này (chưa được kiểm tra):

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

Vì vậy, bạn đề nghị chuyển đổi SRID trên 4326 thành 3857? Sau đó, tôi có thể trực tiếp thử ST_Transform (ST_SetSRID (..., 4326), 3857), tôi có thể không? Tại sao bước chuyển đổi thêm này là cần thiết?
danijar

Tôi nghĩ bạn nên kiểm tra những gì bạn đang hỏi, có lẽ những gì bạn đề xuất là bước duy nhất bạn cần, hãy thử và đăng những gì bạn nhận được
Gery

Đây là những gì tôi nhận được. 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]
            ]
        }'
    )
)

còn thiếu "'"


4
Bạn có thể thêm nhiều ngữ cảnh cho câu trả lời này và giải thích cách nó trả lời câu hỏi của OP không, và khác với câu trả lời hiện có
Devdatta Tengshe

Thành thực mà nói, JSON không phải là một chuỗi, nó không phải là một chuỗi trong câu hỏi và nó không phải là một chuỗi trong ít nhất một trong những câu trả lời. Câu trả lời này có thể chỉ ra điều hiển nhiên, nhưng nó không nhất thiết phải rõ ràng với mọi người, vì vậy xứng đáng với một số tín dụng.
Forbesmyester
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.