Memotret titik awal dan akhir dari garis ke baris lain di PostGIS
9
Ada banyak contoh yang menunjukkan cara mengambil garis ke titik, tapi saya belum bisa menemukan cara (cepat!) Untuk menjepret simpul awal dan akhir dari string baris ke node dari garis lain.
Pada dasarnya saya ingin "membersihkan" lapisan saya di postgis (2.0), memindahkan titik-titik yang hampir sama, dan menjahit celah kecil di antara string garis.
Tidak masalah apakah saya menambahkan node lain, memindahkan node pertama / terakhir dari kedua baris, atau memindahkan kedua titik ke tengah.
Saya telah menemukan dua opsi, tetapi saya tidak yakin bagaimana memulainya dengan keduanya:
Saya sudah berhasil menyelesaikan ini, tanpa menggunakan alat GRASS yang disebutkan atau fungsi topologi.
Pada dasarnya saya mengambil semua start dan endnodes, meletakkannya di tabel sementara yang baru, meletakkan buffer di sekitar mereka, menyatukan objek buffer, dan memindahkan semua node yang ditemukan di setiap buffer ke centroid buffer.
Setelah selesai, saya memindahkan titik awal dan akhir yang asli ke lokasi baru.
Lebih mudah dari yang diharapkan, dan masih cepat, tetapi saya berharap PostGIS memiliki beberapa fungsi bawaan untuk ini - itu akan lebih cepat.
Sunting: untuk kepentingan memberikan kembali kepada komunitas, ini adalah kode saya (cukup jelek) untuk saat ini.
droptableifexists nodes;droptableifexists nodes2;droptableifexists buffers;-- Get Start and End nodesselect ST_StartPoint(wkb_geometry) startnode, ST_EndPoint(wkb_geometry) endnode, ogc_fid into nodes from sourceTable;-- Combine all nodes into one table for easier queriesselect startnode node, ogc_fid into nodes2 from nodes;insertinto nodes2 select endnode node, ogc_fid from nodes;-- Some indexes to speed everything upCREATEINDEX nodesstart_idx ON nodes USING gist (startnode);CREATEINDEX nodesend_idx ON nodes USING gist (endnode);CREATEINDEX nodes2_idx ON nodes2 USING gist (node);CREATEINDEX nodes_ogcfid_idx ON nodes USING btree (ogc_fid ASC NULLS LAST);-- Create buffers, combine them, split combined objects againselect(ST_Dump(ST_Union(ST_Buffer(node,1)))).geom geom into buffers from nodes2;CREATEINDEX buffers_idx ON buffers USING gist (geom);-- Update start/end nodes tableUPDATE nodes SET startnode = ST_Centroid((select geom from buffers WHERE geom && startnode));UPDATE nodes SET endnode = ST_Centroid((select geom from buffers WHERE geom && endnode));-- Update original pointsupdate sourceTable set wkb_geometry = ST_SetPoint(
ST_SetPoint(wkb_geometry,0,(select startnode from nodes where ogc_fid=sourceTable.ogc_fid)),
ST_NumPoints(wkb_geometry)-1,(select endnode from nodes where ogc_fid=sourceTable.ogc_fid));DROPTABLE nodes;DROPTABLE nodes2;DROPTABLE buffers;
Jawaban ini agak mirip dengan saran "non-topologis" dari jawaban saya. Akan lebih baik jika Anda memberi jawaban atau memilih jawabannya. Itulah yang memberi makan komunitas di sini :)
katahdin 8'13
Kamu benar. Saya telah meningkatkan jawaban Anda, dan akan mengedit respons saya untuk memasukkan kode saya.
Jelmer Baas
4
Berikut ini tiga opsi. Semoga orang akan membantu.
v.clean
Menggunakan alat GRASS di QGIS Anda dapat membersihkan topologi objek spasial. Pengguna @RK memberikan serangkaian instruksi yang baik tentang bagaimana melakukan ini dalam jawaban untuk pertanyaan yang berbeda . Keuntungan yang diberikan GRASS adalah ia akan menyimpulkan topologi shapefile. Kerugian untuk situasi Anda adalah bahwa data Anda tidak ada dalam shapefile. Tentu saja Anda dapat mengekspor data dari Postgres ke shapefile menggunakan alat "Add PostGIS Layer", tapi itu langkah tambahan.
Fungsi PostGIS non-topologis
Di PostGIS Anda dapat menggunakan fungsi ST_EndPoint dan ST_StartPoint untuk mendapatkan titik akhir dan mulai untuk linestring. Kemudian, menggunakan kombinasi ST_DWithi dan ST_Distance , Anda dapat menemukan titik awal atau akhir terdekat pada geometri terdekat. Jika Anda memiliki banyak poin maka ST_DWithin akan mempercepat permintaan banyak - dengan asumsi Anda memiliki indeks di tempat. Dari sana, Anda perlu membuat aturan yang menentukan titik mana yang harus dimodifikasi, dan mana yang diperbaiki.
Keuntungannya di sini adalah Anda tidak perlu mengirim data ke GRASS untuk dibersihkan, tetapi ada beberapa perangkap yang harus diperhatikan.
Fungsi PostGIS topologis
Pertanyaan itu merujuk fungsi topologi PostGIS. Ini berfungsi dengan baik, tetapi, seperti yang dijelaskan oleh wiki , Anda harus secara eksplisit menentukan tepi, simpul dan wajah. Jelas ini akan menjadi masalah untuk set data Anda karena Anda telah mengetahui masalah dengan topologi.
Terima kasih, saya mengetahui fungsi-fungsi ini. ST_Snap menjepret SEMUA node, saya hanya ingin simpul start dan end. ST_SnapToGrid tidak benar-benar cocok karena memodifikasi semua geometri yang ada, dan memiliki peluang untuk memindahkan node yang berada lebih dekat, karena mereka hampir tidak jatuh ke segmen lain.
Berikut ini tiga opsi. Semoga orang akan membantu.
v.clean
Menggunakan alat GRASS di QGIS Anda dapat membersihkan topologi objek spasial. Pengguna @RK memberikan serangkaian instruksi yang baik tentang bagaimana melakukan ini dalam jawaban untuk pertanyaan yang berbeda . Keuntungan yang diberikan GRASS adalah ia akan menyimpulkan topologi shapefile. Kerugian untuk situasi Anda adalah bahwa data Anda tidak ada dalam shapefile. Tentu saja Anda dapat mengekspor data dari Postgres ke shapefile menggunakan alat "Add PostGIS Layer", tapi itu langkah tambahan.
Fungsi PostGIS non-topologis
Di PostGIS Anda dapat menggunakan fungsi ST_EndPoint dan ST_StartPoint untuk mendapatkan titik akhir dan mulai untuk linestring. Kemudian, menggunakan kombinasi ST_DWithi dan ST_Distance , Anda dapat menemukan titik awal atau akhir terdekat pada geometri terdekat. Jika Anda memiliki banyak poin maka ST_DWithin akan mempercepat permintaan banyak - dengan asumsi Anda memiliki indeks di tempat. Dari sana, Anda perlu membuat aturan yang menentukan titik mana yang harus dimodifikasi, dan mana yang diperbaiki.
Keuntungannya di sini adalah Anda tidak perlu mengirim data ke GRASS untuk dibersihkan, tetapi ada beberapa perangkap yang harus diperhatikan.
Fungsi PostGIS topologis
Pertanyaan itu merujuk fungsi topologi PostGIS. Ini berfungsi dengan baik, tetapi, seperti yang dijelaskan oleh wiki , Anda harus secara eksplisit menentukan tepi, simpul dan wajah. Jelas ini akan menjadi masalah untuk set data Anda karena Anda telah mengetahui masalah dengan topologi.
sumber
PostGIS memiliki fungsi gertakan .. mungkin mereka akan membantu?
ST_Snap
: Segmen snap dan simpul geometri input ke simpul geometri referensi.ST_SnapToGrid
: Pasang semua titik geometri input ke kisi biasa.sumber