Bagaimana cara memasukkan poligon GeoJSON ke dalam tabel PostGIS?


34

Saya perlu memasukkan poligon dari GeoJSON ke tabel PostGIS saya. Beginilah tampilan query 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]
            ]
        }'
    )
)

Sayangnya, saya mendapat pesan kesalahan.

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

GeoJSON sudah ada di sistem referensi yang tepat. Tapi ini tidak ditentukan. Bagaimana cara menentukan SRID di GeoJSON? Seperti apa bentuk GeoJSON?

Pembaruan: Ketika saya membungkus geometri yang dibuat ST_GeomFromGeoJSONdengan ST_SetSRID(..., 3857)itu melemparkan kesalahan lain. Dalam pandangan saya sepertinya tidak ada geometri yang memiliki dimensi Z.

ERROR:  Geometry has Z dimension but column does not

Saya pikir Anda perlu menentukan bahwa tabel memiliki srid: 4326, tampaknya tabel Anda memiliki srid: 3857 tetapi geojson Anda memiliki panjang / garis lintang (mis. Srid: 4326 atau WGS84)
Gery

Saya ingin menggunakan 3857. Bagaimana GeoJSON harus terlihat seperti itu?
danijar

Jawaban:


33

Melihat kode sumber PostGIS saya menemukan bagaimana mem-parsing SRID. Berikut adalah cara yang benar untuk menentukan SRID di GeoJSON.

Spesifikasi GeoJSON mengatakan bahwa koordinat poligon adalah larik string baris. Karena itu saya harus membungkusnya dengan tanda kurung tambahan.

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

Ada beberapa masalah dengan JSON Anda.

  1. Pertama, koordinat harus berupa array array.
  2. Kedua, melihat koordinatnya, nampaknya nilai-nilai tersebut adalah Latlong dalam sistem koordinat geografis, kemungkinan besar EPSG: 4326. Itu kemudian perlu diubah ke EPSG: 3857.

Setelah Anda memperbaiki dua hal ini, Anda bisa menyisipkan baris, menggunakan SQL Query berikut:

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

Jika ini tidak berhasil, (yaitu Anda masih mendapatkan kesalahan dengan Z diemsnion), harap perbarui pertanyaan dengan versi PostGis, dan Buat Pernyataan di tabel Anda.


Menurut Anda mengapa koordinatnya tidak ada di EPSG: 3857?
danijar

3
Karena satuan EPSG: 3857 adalah (semu) meter, dan asalnya di Samudra Atlantik. Anda tidak akan memiliki akurasi 6 desimal dengan meter, dan data ini akan terletak di Samudra Atlantik dekat pantai Afrika.
Devdatta Tengshe

Koordinat berasal dari input pada peta dan memiliki banyak desimal. Untuk pengujian saya menggambar suatu daerah di Samudra Atlantik dekat Afrika. Tapi terima kasih, saya bisa meningkatkan peta untuk mengitari koordinat ke meter penuh.
danijar

@danijar: Maka tidak apa-apa. Jika koordinat ini dalam EPSG: 4326, maka itu akan terletak di negara bagian AS bagian timur.
Devdatta Tengshe

5

geojson Anda harus memiliki nilai UTM, Anda dapat mengubahnya dengan Proj atau alat online lainnya, tetapi Anda dapat melakukannya dengan mudah dan langsung dengan postgis sebelum memasukkannya ke dalam tabel Anda, coba ini (belum diuji):

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

Jadi Anda menyarankan untuk mengubah SRID lebih dari 4326 ke 3857? Maka saya bisa langsung mencoba ST_Transform (ST_SetSRID (..., 4326), 3857), bukan? Mengapa langkah transformasi ekstra ini diperlukan?
danijar

Saya pikir Anda harus menguji apa yang Anda minta, mungkin apa yang Anda sarankan adalah satu-satunya langkah yang Anda butuhkan, coba dan posting apa yang Anda dapatkan
Gery

Inilah yang saya dapatkan. 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]
            ]
        }'
    )
)

hilang "'"


4
Bisakah Anda menambahkan lebih banyak konteks untuk jawaban ini dan menjelaskan bagaimana ia menjawab pertanyaan OP, dan berbeda dari jawaban yang ada
Devdatta Tengshe

Jujur, JSON memang harus berupa string, itu bukan string dalam pertanyaan dan itu bukan string di setidaknya salah satu jawaban. Jawaban ini mungkin menunjukkan yang sudah jelas, tetapi itu belum tentu jelas bagi semua orang, jadi patut mendapat pujian.
Forbesmyester
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.