ArcGIS Havza aracı tarafından hangi Algoritma kullanılır?


10

ArcGIS Havza aracında (Uzamsal Analist paketinde) ne tür bir algoritmanın kullanıldığını bilen var mı?

Esri'nin web sitesinde çok az bilgi ... ama bunun bir tür derinlik / genişlik arama olabileceğinden şüpheleniyorum.

Bu ArcGIS Çevrimiçi Yardım sayfalarına baktım:

Yani evet, akış yönü rasterini kullanıyor, ancak rasterden geçmek için hangi algoritmayı kullanıyor?

Lütfen unutmayın, 'D8 kullanıyor ...' satırları boyunca cevap aramıyorum. D8 gerçekten bir algoritma değil, kullanacağınız algoritmayı tanımlamaya yardımcı olacak bir model. IE, D8 şemasını derinlik ilk arama algoritması ve / veya genişlik ilk arama algoritması içinde uygulayabilirsiniz


James, ben de aynı şeyi yapmaya çalışıyorum, yani kararlı bir koordinat alıp bize havza tasviri veren bir uygulama yarat. Python kullanıyorum. İlerlememiz hakkında konuşalım.

Ayrıca Python kullanıyorum. Bir akış yönü ızgarası hesaplamak ve oradan devam etmek gibi basit bir problemle başlıyorum.
James

Yanıtlar:


6

Birkaç dilde uyguladığım ve ESRI'nın kullandığına (üzgünüm, bu sayfada başka bir yerde adı geçen Jenson ve Domingue dışında referans yok) inanıyorum, kullanıcı tarafından sağlanan bir "akma noktası" hücresinde veya hücresinde başlamak akış yönü ızgarasının (fdr) kenarında, mevcut hücreye doğrudan akıştan hangisinin olduğunu bulmak için sekiz komşusunu inceleyin ve bu hücreleri çıktı ızgarasındaki mevcut "havzaya" atayın. Daha sonra fonksiyon, her bir komşu için kendini tekrar tekrar çağırır. Bu işlem, sızan tüm hücreler bir akma noktası için tükenene kadar tekrarlanır ve daha sonra tüm akma noktaları için tekrarlanır.

Özyinelemeli algoritma tasarımı oldukça pahalı olabilir, çünkü bellekte çok fazla veri tutmaya, diske takas / sayfa yerleştirmeye ve bu nedenle genellikle g / ç yavaşlamalarına maruz kalabilir.

(RYO yapacaksanız, farklı özyineleme yöntemleri hakkında aşağıdaki whuber'in yorumuna bakın)

_____________ DÜZENLE _____________

Örnek olarak eski C kodumu kazdık (not: Çoğu piton odadan kaçmak isteyebilir, ancak çok kötü olmamalıdır). Örneklemenin ilgi çekici olabileceğini düşündüm. Artık sadece w / genişliğine birinci derinliği ilk özyineleme vs yüzeysel tanıdık olmama rağmen, benim rutin gerçekten derinliği ilk (ve benim doğal dil açıklaması yukarıda yanıltıcı olduğunu) dayalı olduğunu düşünüyorum bu stackoverflow gönderme umarım (@ whuber veya benden daha akıllı başka bir kişi onaylayabilir / reddedebilir).

Kod: açıklama: idirakış yönü değerlerinin rasteridir. offset"Hücre" terimi, halihazırda analiz edilen merkez hücreyi ifade offeder ve bu hücrenin komşularının her birini kontrol eder. Bu does_it_flow_into_me, komşu hücrenin flowdir değerinin geçerli hücreyi gösterip göstermediğine dair bir boole döndüren başka bir işlev çağırır . Bir komşu için doğruysa, o yere gidebilirsiniz.

void shed(int init_x, int init_y, int basin_id){

int i, j, offset, off, flow_dir;

offset = ((init_y - 1) * nc) + (init_x - 1);
*(basin + offset) = basin_id;


/* kernel analysis */
for (i = -1; i <  2; i++) {
    for (j = -1; j <  2; j++) {
        if ((i) || (j)) {

            off = offset + (j * nc +  i);
            flow_dir = *(idir + off);


            if (does_it_flow_into_me(i,j,flow_dir)){
                shed(init_x+i, init_y+j,basin_id);
            }
        } /*not center */
    } /* do - j */
} /* do - i */
}

Önce genişlik yinelemesini tanımlarsınız. Küçük bir yığın sayesinde, çok az bellek gerektiren etkili derinlik-ilk özyineleme uygulayabilirsiniz. Ana performans sorunu, ızgara döşemelerinin tekrar tekrar RAM'a girip çıkması gereken büyük havzaları ilgilendirir. Bununla birlikte, diğer cevapların yorumlarında tartışıldığı gibi, asıl mesele, benzersiz bir şekilde belirlenmiş bir D8 yönü olmayan hücrelerle, özellikle geniş düz yatay yamalarda (ön lavabo doldurma rutinleri tarafından oluşturulanlar gibi) yatan hücrelerle başa çıkmakla ilgilidir.
whuber

Kesinlikle bir çöp in-çöp dışarı sorunu. Ben ve çoğu GIss ne yaptığımız girişi temizlemeyecek! Görünüşe göre hackime biraz cila koymak için önce derinlemesine özyinelemeye bakmam gerekiyor.
Roland

Bunun çöp olduğunu düşünmüyorum - hatırlayın, uygulamanın nasıl bozulduğuna bakılmaksızın, orijinal girdi birisinin D8 kodlamasından ziyade DEM'in kendisidir - ama kesinlikle bir meydan okumadır. Gerçek dünyanın, akış yönünün belirlenmesi zor olacak kadar düz olan birçok yeri vardır: herhangi bir statik su kütlesi iyi bir örnektir. Aslında , göllerin ve diğer düz alanların çıkışlarını bulmanız ve birden fazla çıkışı olan düz alanlarla başa çıkmanız gerekir . Bu , yapılması zor yerel olmayan aramalar gerektirir .
whuber

Muhtemelen kafam karıştı. Ben bizler tartışırken düşünüyorum help.arcgis.com/en/arcgisdesktop/10.0/help../index.html#//... girdi olarak flowdir alır. Gerisini yeterince yakından okumazsam bizi yabani otların içine çekmek istemiyorum!
Roland

Hayır, bence haklısın: Soruyu yeniden okuduğumda, aklıma geldiğim daha genel durumdan ziyade özellikle akış yönü rasterini girdi olarak işlemeye odaklandığını görüyorum. Bu yüzden doğrudan ve içgörü ve yardımcı işaretçilerle yanıtlamak için cevabınızı + 1'leyin.
whuber

4

ArcGIS yardım diyor ki:

Su havzaları, akış yönünü hesaplayıp Su Havzası aracında kullanarak bir DEM'den tanımlanabilir. Katkı alanını belirlemek için, önce Akış Yönü aracıyla akış yönünü temsil eden bir raster oluşturulmalıdır.

Akış Yönü, D8 yöntemi kullanılarak hesaplanır , Burada 8 komşusu olan her bir hücre için akışın soyutlandığı durumlarda, bu hücreden gelen su akacaktır.

D8'e Rho8, Froh8 ve Akış Tüpleri gibi birçok alternatif var, ancak ArcGIS dahil olmak üzere çoğu GIS Yazılımı, diğerlerinden daha basit ve daha az hesaplama açısından yoğun olduğu için D8'i kullanma eğilimindedir.


Birkaç yıl önce bir Havza Tasfiyesi projesi üzerinde çalışıyordum ve D8 yöntemini kullanarak ArcGIS nedeniyle çeşitli sorunlarla karşılaşıyorduk. İki temel sorun

  • D8 yalnızca Tek Yönlü Akışa izin verir. Su bir hücreden sadece bir yönde akabilir.
  • Üretilen Akım akışları, diyagonal eksen boyunca büyük bir sapmaya sahipti. Bu garip görünümlü akışlara yol açtı.

Verilerimizden, bu iki sorunun büyük problemler olduğunu biliyorduk, bu yüzden hibrit yöntemleri kullanarak akış yönleri oluşturmak için bazı araçlar geliştirmiştim.

En eski görevlerimden biri Catchment hesaplama aracını tersine mühendislik yapmaktı. Mantıken oldukça basit olduğunu gördüm. Belirli bir noktaya (akma noktası da denir) için havzayı bulmak istiyorsanız, önce ait olduğu hücreyi bulursunuz. Genellikle belirli bir toleransta en yüksek akış birikimine sahip noktaya tutturmaya çalışacaksınız.

Bu hücre için mahallede ona katkıda bulunan tüm hücreleri bulacaksınız. Bu mahalle hücrelerinin her biri için, onlara katkıda bulunan hücreleri vb. Bulursunuz. Yeni hücre bulana kadar bu yinelemeli sürece devam edersiniz. İşte o zaman sırt hatlarına veya havza sınırına ulaştınız.

Bunu ASCII rasterleri için yapan basit kodumun ArcGIS'in Havza aracına kıyasla neredeyse benzer bir çıktı verdiğini gördüm. Bazen sınırda birkaç hücre farkı vardı, bu yüzden ArcGIS'in değiştirilmemiş bir D8 algoritmasını izlediğine inanıyorum.


Ayrıntılarınız için teşekkür ederim. Ancak havzaları bulmak için D8 yönlerini kullanma algoritması nedir? Lütfen dmahr'un cevabını takip eden yorumlara bakınız .
whuber

Merhaba, teşekkürler ama bu soruya gerçekten cevap vermiyor. "Bu hücre için mahallede ona katkıda bulunan tüm hücreleri bulacaksınız. Bu mahalle hücrelerinin her biri için, onlara katkıda bulunan hücreleri bulursunuz" cümlesiyle vurursunuz. Bu aramayı uygulamak için birçok farklı algoritma vardır. Soru hangisi
James

4

Bu belki de biraz farklı bir bağlamda daha önce sorulmuştu . Mekansal Analistin Hidrolojik araç setindeki tüm coğrafi işleme araçları, Akış Yönü Nasıl Çalışır sayfasında belirtildiği gibi D8 akış yönü modelini kullanır :

Akışın geçebileceği sekiz bitişik hücre ile ilgili sekiz geçerli çıkış yönü vardır. Bu yaklaşım genellikle sekiz yönlü (D8) bir akış modeli olarak adlandırılır ve Jenson ve Domingue'de (1988) sunulan bir yaklaşımı izler.

Jenson and Domingue (1988) belgesinin bir kopyasını burada bulabilirsiniz .

Akış Yönü rasterlerini girdi olarak kullanan tüm araçlar bu akış yönü modelini ilişkilendirmeye göre kullanır. Bu Havza, Akış Birikimi, Akış Uzunluğu, Dolgu vb.


Bu yüzden bir soru takip olacağını varsayalım, bu algoritma havzayı iade etmek için nasıl değiştirildi?
James

Havza aracı akış yönü rasterini akma noktalarından yukarı doğru hareket ettirir. Akış Biriktirme aracının tersidir, ancak hücre sayısını tanımlayan çıkış rasterinin yerine, akma noktasının kimliğini rapor etmesi dışında.
dmahr

1
Tamam, sanırım biraz daha spesifik olmalıyım. Ne yaptığını biliyorum. Hangi algoritmanın uygulandığını bilmiyorum. Yani bir çeşit arama algoritması olduğunu varsayıyorum, ama yine de olabilir; önce genişlik, önce derinlik, yinelemeli derinleşen derinlik vb ...
James

1
teşekkürler dmahr. @whuber: Bildiğim kadarıyla, farklı arama algoritmaları biraz farklı sonuçlar verebilir mi? Ve evet, genel bir algoritma bulmak sorun değil, ancak ESRI'nin havzaya özgü alanları (bir DTM'nin düz kısımları gibi) nasıl ele aldığını öğrenmek yararlıdır.
James

1
James Lütfen bu konuyu son noktayı açıklığa kavuşturmak için düzenleyin. (Ne olduğunu D8 yorumlarla ilgili faydalı benzersiz bir akış yönü grafiğine o D8 yol kabul ederseniz, o zaman bir olmasıdır eşsiz su havzası grafiğin kendisinin aittir çünkü dönüm tarif sorunun doğru çözüm. Orada Böylece eğer yalan söylemeleri gereken belirsizlikler (a) "havza" tanımı, (b) D8 yönlerinin nasıl hesaplandığı veya (c) yatay hücrelerin (yani benzersiz bir D8 yönü olmadan) nasıl ele alındığı.)
whuber

0

Bu soruya daha fazla düşünmek için, ark içinde bir havza analizi yaptım: (Doldurulmuş) bir DEM aldım, akış yönünü hesapladım ve daha önce hesaplanmış bir akış ağındaki konumlara karşılık gelen birkaç nokta yerleştirdim. 'Havza' aracını çalıştırdım ve bana birkaç güzel havza verdi, neredeyse 'yukarı akış' alanın çoğunu kapsıyor (beklediğiniz gibi):

havza görüntü

Daha sonra Python'da (yukarıdaki cevap gibi) hızlı bir arama algoritması kodladım, bu da akış yönü ızgarasını inceler ve akış yollarını 'takip eder'. Her düğüm için 8 komşuyu inceliyorum ve bir komşu mevcut düğüme akarsa, aynı işlevi komşu düğümle giriş olarak özyineli olarak çağırırım.

Yalancı (ish) kodu:

class d8():
    def __init__(self, arr):
       self.catchment = set()
       self.arr = arr

    def search(self, node):
        """ Searches all neighbouring nodes to find flow paths """ 

        # add the current node to the catchment
        self.catchment.add(node)

        # search the neighbours, ignore ones we already visited
        for each_neighbour:
            if neighbour is in self.catchment:
               do nothing

            # if the neighbour flows into the current node, visit that neighbour
            elif neighbour_flows_into_me:
               self.search(neighbour)

Bu fonksiyonu aynı akış yönü giriş ızgarasını ve aynı noktalardan birini kullanarak çalıştırdım. Sorun, arkın bu nokta için yaklaşık 40000 hücre yakalaması döndürdüğü, algoritmamın sadece 72 hücre döndürdüğü.

Ne yaptığımı bilen var mı?

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.