Bantuan dengan geometri poligon PostGIS - dering tidak tertutup

10

Saya telah mengambil salinan buku super-fasik 'Python Geospatial Development' oleh Erik Westra ( tautan Amazon ), dan saya sedang mengerjakannya. Saat ini, ini mengajarkan saya untuk memuat data garis pantai GSHHS dari shapefile ke dalam database PostGIS, dalam persiapan untuk membangun aplikasi web geospasial.

Masalah saya adalah ini: ketika saya mencoba untuk mengimpor data GSHHS ke PostGIS, itu ditolak karena garis pantai poligon tidak dianggap 'valid'. Khususnya, saya diberi pesan kesalahan yang menggambarkan beberapa (tetapi tidak semua) poligon garis pantai sebagai 'cincin tidak tertutup'.

Saya mengerti bahwa kesalahan ini mencoba untuk memberitahu saya bahwa poin pertama dan terakhir dari poligon tidak sama. Namun, ini tidak benar. Saya telah memeriksa representasi WKT dari banyak poligon, dan mereka benar. Mereka pasti memulai dan mengakhiri dengan koordinasi yang sama.

Poligon diekstraksi dari shapefile menggunakan pustaka OGR, dan mengekspor setiap fitur poligon ke WKT. Saya sudah mencoba menyusun kembali poligon melalui Shapely, dan bereksperimen dengan WKB, tetapi tidak berhasil. Saya telah dapat memuat data yang sama ke dalam PostGIS sebagai tabel MULTIPOLYGON, menggunakan loader shp2pgsql.

Saya bertanya-tanya apakah ada orang di luar sana yang:
(a) mungkin menggunakan buku yang sama, terjebak pada masalah yang sama, dan punya jawaban untuk saya?
(B) telah mengalami masalah yang sama, dan menemukan solusi?
(c) gagal itu, apakah ada saran 'praktik terbaik' untuk memastikan geometri yang valid sebelum memuat ke PostGIS?

UPDATE: seorang kolega telah menyarankan bahwa masalah 'cincin tidak tertutup' mungkin hanya merupakan gejala dari masalah lain. Mungkin saja konfigurasi PostGIS / PostgreSQL saya memiliki batas ukuran (pada transaksi penyisipan, paket yang diterima, string teks, dll).

Karena saya menggunakan poligon WKT yang sangat panjang sebagai input, PostGIS mungkin memotongnya terlalu dini untuk menyelesaikan setiap poligon. Saya akan mengujinya besok, tetapi sepertinya memang benar. Masukkan batas negara saya hanya menerima beberapa catatan dan bukan yang lain. Dari ingatan, geometri yang diterima adalah untuk negara-negara pulau kecil seperti Antigua (dan karenanya mungkin memiliki representasi WKT pendek).

Jadi ini bisa berakhir menjadi lebih dari utas admin basis data PostGIS, bukan utas geometri yang tidak valid.

timmy
sumber
dapatkah Anda memberikan contoh file shp?
Mario Miler
jangan khawatir. Data garis pantai GSHHS yang saya gunakan adalah unduhan 96MB dari sini . Data perbatasan dunia yang saya gunakan adalah World Borders Dataset dari thematicmapping.org
timmy

Jawaban:

6

Saya telah melihat data Anda dan contoh buku, masalahnya adalah bahwa ada tiga poligon yang tidak valid dalam data yang diproses dalam buku:

GSHHS_l_L1.shp

ID = 92-W

POLYGON ((-180.0 71.514793999999995,-179.69008299999999 71.577888999999999,-178.648889 71.577416999999997,-178.40644399999999 71.549916999999994,-177.406306 71.244167000000004,-177.877444 71.022889000000006,-179.500111 70.863749999999996,-179.93011100000001 70.979583000000005,-180.0 70.962072000000006))

ID = 486-W

POLYGON ((-180.0 -16.799126,-179.84419399999999 -16.691278,-179.80041700000001 -16.789193999999998,-179.850472 -16.878361000000002,-180.0 -16.959561))

GSHHS_l_L2.shp

ID = 7333-W

POLYGON ((-180.0 65.393473,-179.76583299999999 65.428332999999995,-179.95416700000001 65.385555999999994,-179.90972199999999 65.316389,-180.0 65.321635))

Karena ini adalah contoh, akan lebih mudah untuk menghapus poligon-poligon itu dari dataset atau hanya menambahkan satu jika pernyataan dalam kode Anda

if geometry.IsValid():
       cursor.execute("INSERT INTO gshhs (level, geom) VALUES (%s, ST_GeomFromText(%s, 4326))", (level, wkt))
Mario Miler
sumber
Terima kasih Mario, sepertinya saya semakin maju, alih-alih memvalidasi SEMUA poligon input dengan benar. Jawaban Anda benar - poligon ini dinyatakan tidak valid saat diuji dengan OGR. Menariknya, tampak baik-baik saja di QGis, tetapi ArcMap menunjukkan mereka tidak memiliki cincin lengkap. Ketiga poligon ini semuanya jatuh pada dateline, dan saya kira geometri shapefile tidak menghitung ujung poligon di sepanjang dateline. Solusi Anda adalah cara yang bagus dan mudah untuk mendeteksi poligon yang tidak valid. Saya akan menandai pos sebagai dijawab.
timmy
Jika Anda merasa beramal, apakah Anda punya solusi bagus untuk langkah selanjutnya dalam proses ini, yaitu mengoreksi poligon yang tidak valid? Saya mencoba menggunakan fungsi .CloseRing () OGR, tetapi tidak berhasil. Itu hanya mengabaikan pemanggilan fungsi, saya pikir.
timmy
Saya mencoba menggunakan "trik penyangga" ( workshop.opengeo.org/postgis-intro/validity.html ) dengan bentuk dan gambar tetapi tanpa hasil. Rupanya tidak akan membaca poligon yang tidak valid dan tidak akan melakukan operasi penyangga, saat ini saya tidak tahu mengapa. Jika saya menemukan jawabannya, saya akan memberi tahu Anda. Mungkin orang lain lebih sukses dengan masalah ini. Maaf.
Mario Miler
Saya pikir saya sudah mendapatkan validasi poligon saya bekerja sekarang. Saya pikir saya menggunakan fungsi .CloseRings () OGR dengan cara yang salah. Saya dipanggil sebagai metode poligon (yaitu poly.CloseRings ()). Sebaliknya, saya harus mengekstrak Linear Ring dari poligon, dan kemudian menjalankannya pada itu (yaitu lr = poly.GetGeometryRef (0); lr.CloseRings ()). Hasilnya berhasil dimasukkan ke dalam PostGIS, dan saya bisa menggunakan 3 poligon masalah di QG tanpa khawatir. Hanya ada sedikit biaya komputasi dalam memeriksa validitas untuk SETIAP poligon.
timmy