Çizgi özelliklerini bağlama ve en uzun çizginin uzunluğunu belirleme


12

Stream_to_Feature aracını kullanarak oluşturduğum bir nehri temsil eden bir çizgi özelliği (resme bakın) var. Özellik tablosu, farklı satırları temsil eden birkaç kayıt içerir - sorun en uzun satırdır (görsel olarak kolayca ayırt edilebilir) tablodaki tek bir satır olarak temsil edilmez, aslında birçok küçük satırdan oluşur. Çizgiler birbirine temas etmemelerine rağmen dokunuyor gibi görünüyor.

Bu satırları birleştirip ArcObjects veya ArcObjects'e dönüştürebileceğim manuel yöntemleri kullanarak en uzun satırın uzunluğunu nasıl belirleyebilirim? Daha da iyi bir çözüm, tüm kollardan kurtulmayı ve beni sadece nehir kanalı ile bir çizgi olarak bırakmayı içerir.

Çizgi özelliği - nehir


1
Hiç bağlanıyorlar mı? Çaprazlamadıklarını söylediniz, ama bu bir tepe noktasını paylaşmadıkları anlamına mı geliyor?
Nathanus

1
Üzgünüm - Daha açık olmalıydım. Köşeleri paylaşırlar, ancak birbirlerini tamamen geçmezler.
Radar

Nehrin ağzının nerede olduğunu biliyor musun? Nehir her zaman bir ağaç mıdır (her ana su noktasından ağzına kadar eşsiz bir yol)?
Kirk Kuykendall

3
Aslında, yok uzunluğunu istiyoruz "en uzun hattı." Bu, bir yukarı akış erişiminden başka bir yukarı akış erişimine kadar bir rota olabilir. Bu, akarsuyun iki ana dalı ağzının yakınında birleştiğinde olur. Bunun yerine, ağız ile akıştaki diğer uç noktalar arasındaki en uzun yolu istersiniz . (Bu karakterizasyon, akışın bir ağaç olarak temsil edilmesini bile gerektirmez: örgü yapabilir ve adalara sahip olabilir.)
whuber

@whuber - değerlendirmeniz doğru - rotaları kullanarak bunu nasıl başarabileceğim hakkında bir fikriniz var mı?
Radar

Yanıtlar:


18

İlk olarak, bunun neden zor bir sorun olmadığını gösteren küçük bir arka plan . Bir nehirden geçen akış, doğru şekilde dijitalleştirilirse, segmentlerinin her zaman yönlendirilmiş bir asiklik grafik (DAG) oluşturmak üzere yönlendirilebileceğini garanti eder . Buna karşılık, bir grafik, topolojik sıralama olarak bilinen bir teknik kullanılarak sadece ve eğer bir DAG ise doğrusal olarak sıralanabilir . Topolojik sıralama hızlıdır: zaman ve alan gereksinimleri hem O (| E | + | V |) 'dir (E = kenar sayısı, V = köşe sayısı). Böyle doğrusal bir düzen oluşturmak, büyük dere yatağını bulmayı kolaylaştıracaktır.

İşte burada, bir algoritmanın taslağı . Derenin ağzı ana yatağı boyunca uzanır. Ağza bağlı her dal boyunca yukarı doğru hareket edin (ağız bir konflunsa sahipse birden fazla olabilir) ve dalına giden ana yatağı tekrar tekrar bulun. Toplam uzunluğun en büyük olduğu dalı seçin: ana yatak boyunca "geri bağlantınız" budur.

Bunu daha net hale getirmek için, bazı (test edilmemiş) sahte kod teklif ediyorum . Giriş , her biri iki ayrı uç nokta başlangıç ​​(S) ve uç (S) ve pozitif bir uzunluk, uzunluk (S) olan bir dizi çizgi parçası (veya yay) S'dir (sayısallaştırılmış akışı içerir ); ve bir nokta olan nehir ağzı p . Çıktı, ağzı en uzak yukarı akış noktasıyla birleştiren bir segment dizisidir.

"İşaretli segmentler" (S, p) ile çalışmamız gerekecek. Bunlar, S segmentlerinden biriyle birlikte iki uç noktasından birinden oluşur, s . Prob noktası q ile bir uç noktayı paylaşan , bu segmentleri diğer uç noktalarıyla işaretleyen ve seti döndüren S segmentlerini bulmamız gerekecek :

Procedure Extract(q: point, A: set of segments): Set of marked segments.

Böyle bir segment bulunamadığında, Ayıkla boş kümeyi döndürmelidir. Bir yan etki olarak, Ekstrakt A setinden döndüğü tüm segmentleri kaldırmalı , böylece A'nın kendisini değiştirmelidir .

Extract uygulaması vermiyorum: CBS'niz q ile bir uç noktayı paylaşan S segmentlerini seçebilmenizi sağlayacaktır . Bunları işaretlemek, hem başlangıç ​​(S) hem de bitiş (S) 'yi q ile karşılaştırmak ve iki uç noktadan hangisinin eşleşmediğini döndürmektir.

Şimdi sorunu çözmeye hazırız.

Procedure LongestUpstreamReach(p: point, A: set of segments): (Array of segments, length)
    A0 = A                        // Optional: preserves A
    C = Extract(p, A0)            // Removes found segments from the set A0!
    L = 0; B = empty array
    For each (S,q) in C:          // Loop over the segments meeting point p
        (B0, M) = LongestUpstreamReach(q, A0)
        If (length(S) + M > L) then
            B = append(S, B0)
            L = length(S) + M
        End if
    End for
    Return (B, L)
End LongestUpstreamReach

Prosedür "Ekleme (S B0)" çubukları kademeli S dizi sonunda B0 ve yeni bir dizi döner.

(Akım gerçekten bir ağaç ise: hayır adalar, göller, örgü, vb - o zaman kopyalama aşaması uygulamasından vazgeçilmesi olabilir A içine A0 .)

Orijinal soru, LongestUpstreamReach tarafından döndürülen segmentlerin birleşimi oluşturularak cevaplanır.

Açıklamak için orijinal haritadaki akışı ele alalım. Varsayalım ki yedi yay koleksiyonu olarak dijitalleştirildi. Ark a , nokta 1'deki ilk izdihamın akış yukarısında, 0 noktasından (haritanın üst kısmı, aşağıdaki şekilde sağa döndürülür) ağızdan gider. 8 birim uzunluğunda uzun bir yay. Ark b sola (haritada) dallanır ve kısa, yaklaşık 2 birim uzunluğundadır. Ark c sağa doğru dallar ve yaklaşık 4 birim uzunluğundadır, vb. "B", "d" ve "f" harfleri, haritanın yukarıdan aşağıya doğru gittikçe sol taraftaki dalları ve "a" yı gösterirken, "c", "e" ve diğer dalları "g" ve 0'dan 7'ye kadar olan köşeleri numaralandırarak, grafiği soyut olarak yay koleksiyonu olarak gösterebiliriz

A = {a=(0,1), b=(1,2), c=(1,3), d=(3,4), e=(3,5), f=(5,6), g=(5,7)}

Onlar uzunlukları 8, 2, 4, 1, 2, için 2, 2 olduğunu varsayalım olacak bir içinden g , sırasıyla. Ağız köşe 0'dır.

şekil

İlk örnek, Çıkar (5, {f, g}) çağrısıdır. İşaretli segment kümesini {(f, 6), (g, 7)} döndürür. Köşe 5'in f ve g yaylarının (haritanın altındaki iki yay) birleştiği ve (f, 6) ve (g, 7) bu yayların her birini yukarı akış uç noktalarıyla işaretlediğine dikkat edin.

Bir sonraki örnek LongestUpstreamReach (0, A) çağrısıdır. Yaptığı ilk eylem, Çıkar (0, A) çağrısıdır. Bu döner belirgin bir bölümü (a, 1) ihtiva eden bir dizi ve bunun kademeli kaldırır a kümesinden A0 artık {b, c, d, e, f, g} eşittir. Döngünün bir tekrarı vardır, burada (S, q) = (a, 1). Bu yineleme sırasında LongestUpstreamReach (1, A0) çağrısı yapılır. Yinelemeli olarak, (g, e, c) veya (f, e, c) dizisini döndürmelidir: her ikisi de eşit derecede geçerlidir. Uzunluk (M) ya da döner 4 + 2 + = 8. 2 (Not LongestUpstreamReach yapmasıdır değildir ve değişiklikler A0 .) Döngü sonunda, kademeli birakış yatağına eklenmiştir ve uzunluk 8 + 8 = 16'ya çıkarılmıştır. Dolayısıyla, ilk geri dönüş değeri (g, e, c, a) veya (f, e, c, a) dizisinden oluşur, ikinci dönüş değeri için her iki durumda da 16 uzunluğundadır. Bu, LongestUpstreamReach'in ağızdan nasıl yukarı doğru hareket ettiğini gösterir, her bir konfluyonda henüz gidilecek en uzun mesafeye sahip dalı seçer ve rotası boyunca çapraz olan segmentleri takip eder.

Birçok örgüler ve adalar olduğunda daha verimli bir uygulama mümkündür, ancak çoğu amaç için LongestUpstreamReach tam olarak gösterildiği gibi uygulanırsa çok az harcanan çaba olacaktır, çünkü her bir birleşmede çeşitli dallardaki aramalar arasında çakışma yoktur: bilgi işlem zaman (ve yığın derinliği) toplam segment sayısı ile doğru orantılı olacaktır.


+1 Şimdi bunu Missouri Nehri adını vermeden önce bilselerdi.
Kirk Kuykendall

1
@Kirk 1800'lü yılların başlarında Amerikan Batı'nın tekrarlanan keşfi kolay değildi :-).
whuber

Bu inanılmaz faydalı! Bu kurulumu CBS'mde alıp alamayacağımı ve işe yarar hale geldiğimde bazı yararlı kodları paylaşıp paylaşamayacağımı göreceğim. Şerefe!
Radar

Güzel cevap whuber
Ragi Yaser Burhum

2

Bölünmemiş Hattı Eğer (erimesi alan için) birbirinden ayırt etme bir dere dalına bazı yöntem tanrısal etmek gerekir ancak aracı yapmaya çalışıyorsun ne için yararlı olabilir. Bu yine de bir ArcInfo lisansına sahip olduğunuzu varsayar.

Böyle bir lisansa sahip değilseniz, ArcObjects yaklaşımını her bir tepe noktasının XY'sini alarak, IPointCollectiononlarla bir doldurarak ve sonra IGeometrya olarak oluşturabilirsiniz PolyLineClass.


1

Sen kullanabilirsiniz RivEX bir 9.1 ArcGIS aracı (yani 9.3 ve 10 çalışacak) bulunuyor. Nehir ağları ve birçok işleme aracıyla ilgili topolojik sorunları tanımlamak için araçlara sahiptir. Böyle bir araç ana gövdeyi bulur .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.