Ilustrasi di bawah ini menunjukkan masalahnya :
seperti pada (a) Saya punya satu set poligon terpisah, seperti geometri di PostGIS. Saya memerlukan sesuatu seperti (b) , "mosaik" dari rangkaian poligon ini, membangunnya dengan kriteria "wilayah pengaruh" ... Seperti konstruksi Voronoi (diilustrasikan oleh (c) ): pada kenyataannya, jika poligon itu adalah Poin, pengaruh daerah adalah Voronoi.
Meringkas: Saya membutuhkan algoritma SQL (atau spesifik untuk PostGIS) yang menghasilkan "mosaik" dari serangkaian poligon terpisah. (mungkin loop operasi ST_Buffer kecil dan ST_Difference)
PS: Saya perlu, seperti Voronoi, bahwa pembatasan ruang (bingkai kuadrat dalam (b) ) diabaikan.
Masalah ini mirip dengan ini tentang garis lainnya .
EDIT (setelah komentar @FelixIP)
Saya lebih suka tinggal di alam semesta vektor , untuk tidak kehilangan presisi (mis. Menggunakan ST_DelaunayTriangles dan menambah dan mengurangi interior dengan poligon asli, mereka mengadaptasi solusi grafik ganda ) ... Beberapa paket sederhana dan otomatis seperti pprepair (dibantu seperti alat topologi QGIS tidak otomatis). Tetapi raster mungkin lebih sederhana dan lebih sedikit memakan CPU.
Ilustrasi "proses GRID" ini juga berlaku sebagai solusi, dengan asumsi bahwa hal itu dapat memungkinkan ketepatan yang sama dan "pertumbuhan pengaruh wilayah euclidean".
Dalam ARCGIS terdapat alat analisis spasial yang dikenal sebagai Alokasi Euclidean , jadi, mungkin ada solusi serupa PostGIS , dimulai dengan set poligon (mengklasifikasikan, merasterisasi dan membuat kembali poligon).
sumber
Jawaban:
Jadi, saya akan menyiapkan kue untuk Anda - piring buah, menggunakan alat PostGis, seperti yang Anda minta, jika saya benar memahami pertanyaan itu, dan seperti yang saya sebutkan, tanggung jawab untuk pengoperasian oven PostGIS ditanggung oleh tim kreatifnya.
Saya akan meminta untuk tidak tersinggung oleh siapa pun dengan gaya lucu saya dan memahaminya sebagai permainan!
File aslinya adalah irisan buah dan bentuk sederhana (selanjutnya disebut buah), lihat Gambar 1 di bawah ini.
Ini resep saya, dan saya akan dibantu oleh programmer-programmer terkasih, yang akan Anda pelajari nanti. Mari kita mulai, dan untuk ini kita akan membuat adonan di mana buah-buahan kita akan diletakkan, untuk yang menjalankan skrip:
create table poly_extent as SELECT ST_SetSRID(ST_Buffer(ST_Envelope(ST_Extent(geom)),0.05),4326) as geom FROM poly;
Lihat hasilnya pada Gambar 2 di bawah ini
Sekarang, jika ada beberapa buah, seperti dalam gambar saya, buat batas buffer eksternal pada buah, atau jika ada banyak buah, buat perbatasan buffer negatif, untuk yang menjalankan skrip:
create table poly_buff_dump as SELECT ((ST_Dump(ST_Boundary(ST_Union(ST_Buffer((geom),0.01, 'join=mitre mitre_limit=5.0'))))).geom) geom FROM poly;
Dan iris garis penyangga di sekitar masing-masing buah
UPDATE poly_buff_dump SET geom=ST_RemovePoint(geom, ST_NPoints(geom)-1) WHERE ST_IsClosed(geom)=true;
Lihat hasilnya pada Gambar 3 di bawah ini(Sebenarnya, saya berpikir bahwa sebagai hasilnya saya akan mendapatkan garis putus-putus (seperti dalam lingkaran), tetapi jika angka-angka itu sulit, kadang-kadang angka diperoleh, yang salah, misalnya, satu sisi persegi panjang jatuh, dll. )
Maka Anda perlu membagi garis yang diperoleh dengan cara yang nyaman bagi Anda menjadi segmen yang sama dan mengekstrak poin dari mereka
create table poly_buff_dump_pt as SELECT (ST_DumpPoints((geom))).geom geom FROM poly_buff_segm;
Hasilnya, lihat Gambar 4 di bawah ini
Sekarang jalankan alat Voronoi, di tempat ini saya menggunakan alat yang disarankan oleh tautan MickyT: /gis//a/172246/120129 , sebagai hasilnya Anda akan membuat tabel dengan nama “voronoi ”Untuk fakta bahwa“ asisten pertamaku ”terpisah dari koki, terima kasih dari koki! :-).
Cara kedua dalam langkah ini adalah menjalankan fungsi ST_VoronoiPolygons.
Hasilnya, lihat Gambar 5 di bawah ini
Sekarang, potong bagian tambahan dengan menjalankan skrip:
create table poly_voronoi_cut as SELECT ST_Intersection(a.geom, b.geom) geom FROM voronoi a INNER JOIN poly_extent b ON ST_Intersects(a.geom, b.geom);
Hasilnya, lihat Gambar 6 di bawah ini.Sekarang jalankan skrip untuk menyelaraskan tipe geodata di LineString:
create table poly_voronoi_dump as SELECT (ST_Dump(geom)).geom as geom FROM poly_voronoi_cut;
Dan sekarang saya akan meminta "teman kedua saya" untuk mengambil tugas saya dan mencampur kue dengan baik (Jeff - /gis//a/785/120129 ), meratakannya dalam satu lapisan, dan untuk itu terima kasih untuk itu!CREATE TABLE poly_overlay_cut AS SELECT geom FROM ST_Dump(( SELECT ST_Polygonize(geom) AS geom FROM ( SELECT ST_Union(geom) AS geom FROM ( SELECT ST_ExteriorRing(geom) AS geom FROM poly_voronoi_dump) AS lines ) AS noded_lines ) );
Sekarang saatnya bagi saya untuk mulai bekerja, di mana saya menjalankan skrip:create table poly_voronoi_union as SELECT b.id, (ST_ConvexHull(ST_Union(a.geom, b.geom))) geom FROM poly_overlay_cut a INNER JOIN poly_buff_dump b ON ST_Intersects(a.geom, b.geom) GROUP BY b.id, a.geom, b.geom;
dan skrip lain:create table poly_voronoi_union_area as SELECT ST_Union(ST_ConvexHull(ST_BuildArea(geom))) as geom FROM poly_voronoi_union GROUP BY id;
lihat gambar 7 di bawah iniSeperti yang Anda lihat dalam gambar, potongan kami memiliki lapisan kecil, yang dapat dihapus, sebagai opsi menggunakan ST_SnapToGrid (atau dengan cara lain):
Dan akhirnya, kita akan memotong buah panggang kita dari pai kita, aku bahkan sedikit lelah berdiri di dekat oven, :-)
create table polygon_voronoi_result as SELECT (ST_Dump(ST_Difference(a.geom, b.geom))).geom as geom FROM poly_voronoi_union_area_snap as a JOIN poly b ON ST_Intersects(a.geom, b.geom);
Hasilnya lihat gambar 8Semuanya mulai hari ini, sekarang semua orang akan belajar memanggang pai lezat - piring buah. Bantu dirimu Semua, dan pilih bagianmu, cukup untuk semua orang.
(Sayang sekali saya benar-benar tidak bisa memberi makan semua orang, tidak dengan kue elektronik, tetapi dengan kue asli, mungkin kelaparan akan berakhir di Bumi ...)
Sunting: Ceri pada pai bisa terlihat seperti ini :-):
atau
Dengan Anda baik dan adil Mr.Baker, terima kasih semua dan semoga sukses,: -) ...
Solusi asli.
Script ini disebut: ST_VoronoiDiagramsFromPolygons.
sumber
ST_Buffer
danST_ConvexHull
? Ada algoritma alternatif?ST_ConvexHull
, hanya rasa ingin tahu, hasil apa yang bisa kita peroleh setelah Gambar 6,poly_voronoi_union
tanpa ST_ConvexHull.Postgis tidak memiliki fungsi khusus untuk voronoi, tetapi Qgis berisi fungsi vornoi yang dapat membuat poligon voronoi dari poin, jadi menggunakan qgis saya telah mengikuti langkah-langkah berikut untuk mendapatkan hasil ini:
-membuat poin dari poligon menggunakan
extract nodes
fungsi.-membuat poligon vornoi menggunakan fungsi voroi di Qgis.
-membuat gabungan spasial di Qgis.
Hasil -dolve.
sumber
OK - Pikirkan tentang ini sedikit dan menemukan itu seperti sesuatu yang saya lihat belakangan ini.
Ambil polis awal Anda:
Hasilkan atribut baru dengan angka (100 dalam kasus saya) Gunakan alat Vector-> Research -> Poin acak di dalam alat poligon ini akan menghasilkan (100) poin di dalam setiap poligon:
Kemudian Vector-> Geometry tools -> Voronoi untuk menghasilkan polys berdasarkan pada layer titik tersebut.
Sekarang, Anda dapat menggunakan alat Vektor -> Kueri Spasial: Pilih titik-titik yang dimiliki oleh satu poligon (atau salah satu poligon) Gunakan alat kueri spasial untuk menghasilkan pilihan poligon voronoi Anda yang berlaku untuk poligon itu. Tambahkan atribut ke poligon voroni yang sesuai dengan poligon yang menarik. (Saya hanya menggunakan 1,2,3,4)
Sekarang Anda dapat Vector-> Geoprocessing Tools-> larut berdasarkan atribut baru Anda.
sumber
Poin acak adalah ide yang baik untuk menghasilkan poligon voronoi dari poligon, itu bekerja dengan cukup baik, tetapi cukup buruk untuk poligon yang berdekatan:
ST_ApproximateMedialAxis adalah alternatif lain yang baik jika menggunakan PostGIS: Menghitung Diagram Voronoi untuk poligon
sumber