Saya memiliki fitur garis (lihat gambar) yang mewakili sungai yang saya buat menggunakan alat Stream_to_Feature. Tabel atribut berisi beberapa catatan yang mewakili garis yang berbeda - masalahnya adalah garis terpanjang (mudah dibedakan secara visual) tidak direpresentasikan sebagai satu baris dalam tabel, sebenarnya terdiri dari banyak garis yang lebih kecil. Garis-garis itu tampak menyentuh, meskipun tidak saling bersilangan.
Bagaimana saya bisa menggabungkan garis-garis ini dan kemudian menentukan panjang garis terpanjang menggunakan ArcObjects atau metode manual yang dapat saya konversi ke ArcObjects? Solusi yang lebih baik lagi adalah menyingkirkan semua anak sungai dan meninggalkan saya hanya dengan saluran sungai sebagai garis.
Jawaban:
Pertama, sedikit latar belakang untuk menunjukkan mengapa ini bukan masalah yang sulit. Aliran melalui sungai menjamin bahwa segmennya, jika terdigitasi dengan benar, selalu dapat berorientasi untuk membentuk grafik asiklik terarah (DAG). Pada gilirannya, grafik dapat dipesan secara linier jika dan hanya jika itu adalah DAG, menggunakan teknik yang dikenal sebagai semacam topologi . Penyortiran topologis cepat: persyaratan waktu dan ruang keduanya O (| E | + | V |) (E = jumlah tepi, V = jumlah simpul), yang sama baiknya dengan yang didapat. Membuat urutan linier seperti itu akan membuatnya mudah untuk menemukan aliran utama.
Di sini, kemudian, adalah sketsa dari suatu algoritma . Mulut sungai itu terletak di sepanjang tempat tidur utamanya. Bergerak hulu sepanjang setiap cabang yang melekat pada mulut (mungkin ada lebih dari satu, jika mulut adalah pertemuan) dan secara rekursif menemukan tempat tidur utama mengarah ke cabang itu. Pilih cabang yang panjang totalnya paling besar: itulah "backlink" Anda di sepanjang ranjang utama.
Untuk memperjelas ini, saya menawarkan beberapa pseudocode (belum diuji) . Input adalah seperangkat segmen garis (atau busur) S (terdiri dari aliran digital), masing-masing memiliki dua titik akhir yang berbeda mulai (S) dan ujung (S) dan panjang positif, panjang (S); dan p muara sungai , yang merupakan titik. Outputnya adalah urutan segmen yang menyatukan mulut dengan titik hulu yang paling jauh.
Kita perlu bekerja dengan "segmen bertanda" (S, p). Ini terdiri dari salah satu segmen S bersama dengan salah satu dari dua titik akhir, hal . Kita perlu menemukan semua segmen S yang berbagi titik akhir dengan titik pemeriksaan q , tandai segmen tersebut dengan titik akhir lainnya , dan mengembalikan set:
Ketika tidak ada segmen tersebut dapat ditemukan, Ekstrak harus mengembalikan set kosong. Sebagai efek samping, Ekstrak harus menghapus semua segmen yang dikembalikan dari set A, sehingga memodifikasi A itu sendiri.
Saya tidak memberikan implementasi Ekstrak: GIS Anda akan memberikan kemampuan untuk memilih segmen S berbagi titik akhir dengan q . Menandai mereka hanyalah masalah membandingkan mulai (S) dan akhir (S) dengan q dan mengembalikan mana dari dua titik akhir yang tidak cocok.
Sekarang kita siap untuk menyelesaikan masalah.
Prosedur "append (S, B0)" menempel segmen S di akhir array B0 dan mengembalikan array baru.
(Jika alirannya benar-benar pohon: tidak ada pulau, danau, kepang, dll - maka Anda dapat membuang langkah menyalin A ke A0 .)
Pertanyaan asli dijawab dengan membentuk penyatuan segmen yang dikembalikan oleh LongestUpstreamReach.
Untuk mengilustrasikannya , mari pertimbangkan aliran di peta asli. Misalkan itu didigitalkan sebagai koleksi tujuh busur. Busur a bergerak dari mulut di titik 0 (di atas peta, di kanan pada gambar di bawah, yang diputar) ke arah hulu ke pertemuan pertama di titik 1. Ini busur panjang, katakanlah 8 unit panjang. Arc b bercabang ke kiri (di peta) dan pendek, sekitar 2 unit. Arc c bercabang ke kanan dan panjangnya sekitar 4 unit, dll. Membiarkan "b", "d", dan "f" menunjukkan cabang sisi kiri saat kita pergi dari atas ke bawah pada peta, dan "a", "c", "e", dan "g" cabang lainnya, dan penomoran simpul 0 hingga 7, kita dapat secara abstrak menggambarkan grafik sebagai kumpulan busur
Saya akan kira mereka memiliki panjang 8, 2, 4, 1, 2, 2, 2 untuk sebuah melalui g , masing-masing. Mulutnya adalah simpul 0.
Contoh pertama adalah panggilan untuk Mengekstrak (5, {f, g}). Ini mengembalikan set segmen yang ditandai {(f, 6), (g, 7)}. Perhatikan bahwa simpul 5 berada pada pertemuan busur f dan g (dua busur di bagian bawah peta) dan bahwa (f, 6) dan (g, 7) menandai masing-masing busur ini dengan titik akhir hulu .
Contoh berikutnya adalah panggilan ke LongestUpstreamReach (0, A). Tindakan pertama yang dilakukan adalah panggilan untuk Mengekstrak (0, A). Ini mengembalikan set yang berisi segmen bertanda (a, 1) dan menghapus segmen a dari set A0 , yang sekarang sama dengan {b, c, d, e, f, g}. Ada satu iterasi dari loop, di mana (S, q) = (a, 1). Selama iterasi ini panggilan dilakukan ke LongestUpstreamReach (1, A0). Secara rekursif, ia harus mengembalikan urutan (g, e, c) atau (f, e, c): keduanya sama-sama valid. Panjang (M) yang dikembalikan adalah 4 + 2 + 2 = 8. (Perhatikan bahwa LongestUpstreamReach tidak mengubah A0 .) Di akhir loop, segmen atelah ditambahkan ke dasar aliran dan panjangnya telah ditingkatkan menjadi 8 + 8 = 16. Dengan demikian nilai pengembalian pertama terdiri dari urutan (g, e, c, a) atau (f, e, c, a), dengan panjang 16 dalam kedua kasus untuk nilai pengembalian kedua. Ini menunjukkan bagaimana LongestUpstreamReach hanya bergerak ke hulu dari mulut, memilih pada setiap pertemuan cabang dengan jarak terpanjang yang belum pergi, dan melacak segmen yang dilalui di sepanjang rute.
Implementasi yang lebih efisien dimungkinkan ketika ada banyak kepang dan pulau, tetapi untuk sebagian besar tujuan akan ada sedikit usaha yang sia-sia jika LongestUpstreamReach dilaksanakan persis seperti yang ditunjukkan, karena pada setiap pertemuan tidak ada tumpang tindih di antara pencarian di berbagai cabang: komputasi waktu (dan kedalaman tumpukan) akan berbanding lurus dengan jumlah total segmen.
sumber
Alat Unsplit Line dapat membantu untuk apa yang Anda coba lakukan, meskipun Anda perlu untuk ilahi beberapa metode untuk membedakan satu cabang aliran dari yang lain (untuk bidang yang larut). Ini mengasumsikan Anda memiliki lisensi ArcInfo.
Jika Anda tidak memiliki lisensi seperti itu, Anda dapat mempertimbangkan pendekatan ArcObjects mengambil XY dari setiap titik, mengisi
IPointCollection
dengan mereka, dan kemudian membuatIGeometry
sebagaiPolyLineClass
.sumber
Anda dapat menggunakan RivEX itu alat 9.1 ArcGIS (yang akan bekerja di 9.3 dan 10). Ini memiliki alat untuk mengidentifikasi masalah topologi dengan jaringan sungai dan banyak alat pemrosesan. Salah satu alat tersebut menemukan batang utama .
sumber