ArcGIS Waters มีการใช้อัลกอริทึมใด?


10

ไม่มีใครรู้ว่าอัลกอริทึมชนิดใดที่ใช้ในเครื่องมือ ArcGIS Watershed (ในแพ็คเกจ Spatial Analyst)?

ข้อมูลที่ได้รับน้อยมากในเว็บไซต์ของ Esri ... แต่ฉันคิดว่ามันอาจเป็นการค้นหาเชิงลึก / กว้าง

ฉันได้ดูหน้าช่วยเหลือออนไลน์ ArcGIS เหล่านี้แล้ว:

ใช่แล้วมันใช้แรสเตอร์ทิศทางการไหล แต่ใช้อัลกอริทึมแบบใดในการสำรวจแรสเตอร์?

โปรดทราบว่าฉันไม่ได้มองหาคำตอบตามเส้นของ 'มันใช้ D8 .. ' ... D8 ไม่ใช่อัลกอริทึมจริงๆ แต่เป็นแบบจำลองที่ช่วยกำหนดอัลกอริทึมที่คุณจะใช้ IE คุณสามารถใช้รูปแบบ D8 ภายในอัลกอริทึมการค้นหาความลึกแรกและ / หรืออัลกอริทึมการค้นหาที่กว้างเป็นอันดับแรก


เจมส์ฉันกำลังพยายามทำสิ่งเดียวกันคือสร้างแอปที่ใช้การประสานงานที่กำหนดและให้การพรรณนาในลุ่มน้ำ ฉันใช้หลาม มาพูดเกี่ยวกับความก้าวหน้ากันเถอะ

ฉันใช้ Python ด้วย ฉันเริ่มต้นด้วยปัญหาที่ง่ายขึ้นในการคำนวณกริดทิศทางการไหลและย้ายจากที่นั่น
James

คำตอบ:


6

วิธีที่ฉันใช้ในสองภาษาและเชื่อว่า ESRI ใช้ (ขออภัยไม่มีการอ้างอิงอื่นนอกเหนือจาก Jenson และ Domingue ที่อ้างถึงที่อื่นในหน้านี้) คือการเริ่มต้นที่เซลล์ "pour-point" หรือเซลล์ ที่ขอบของตารางทิศทางการไหล (fdr) ตรวจสอบแปดเพื่อนบ้านเพื่อค้นหาว่าการไหลโดยตรงเหล่านั้นเข้าสู่เซลล์ปัจจุบันและกำหนดเซลล์เหล่านั้นให้กับ "ลุ่มน้ำ" ในตารางผลลัพธ์ จากนั้นฟังก์ชั่นนี้จะเรียกซ้ำตัวเองหนึ่งครั้งสำหรับแต่ละเพื่อนบ้านที่ไหลเข้ามา กระบวนการนี้ซ้ำจนกว่าเซลล์ไหลเข้าทั้งหมดจะหมดลงสำหรับจุดไหลและจากนั้นจะทำซ้ำสำหรับจุดไหลทั้งหมด

การออกแบบอัลกอริธึมแบบเรียกซ้ำอาจค่อนข้างแพงเพราะสามารถพยายามเก็บข้อมูลจำนวนมากในหน่วยความจำได้โดยต้องสลับ / หน้าไปยังดิสก์ดังนั้นโดยทั่วไปแล้วจะทำให้ i / o ช้าลง

(ดูความคิดเห็นของ whuber ด้านล่างเกี่ยวกับวิธีการเรียกซ้ำแบบต่าง ๆ ถ้าคุณจะ RYO)

_____________ แก้ไข _____________

ขุดรหัส C เก่าของฉันเป็นตัวอย่าง (หมายเหตุ: ถึงแม้ว่าไพ ธ อนส่วนใหญ่อาจต้องการเรียกใช้จากห้อง แต่ก็ไม่ควรเลวร้ายเกินไป) คิดว่าน่าจะเป็นตัวอย่างที่น่าสนใจ ถึงแม้ว่าผมก็แค่ตอนนี้เผินๆคุ้นเคย w / กว้างแรก VS recursion ลึกแรกฉันคิดว่ากิจวัตรประจำวันของฉันคือความลึกแรก (และที่คำอธิบายภาษาของฉันธรรมชาติดังกล่าวข้างต้นเป็นความเข้าใจผิด) ตามจริงโพสต์ StackOverflow นี้ (หวังว่า @ whuber หรือบุคคลอื่นที่ฉลาดกว่าที่ฉันสามารถยืนยัน / ปฏิเสธ)

รหัส: คำอธิบาย: idirเป็นแรสเตอร์ของค่าทิศทางการไหล offsetอ้างถึงเซลล์กลางที่กำลังวิเคราะห์อยู่และoffตรวจสอบเพื่อนบ้านของเซลล์นั้น ๆ สิ่งนี้จะเรียกฟังก์ชันอื่นdoes_it_flow_into_meซึ่งส่งกลับบูลีนว่า flowdir ของเซลล์ข้างเคียงชี้ไปที่เซลล์ปัจจุบันหรือไม่ หากเป็นจริงสำหรับเพื่อนบ้านให้เรียกเก็บเงินจากตำแหน่งนั้น

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 */
}

คุณอธิบายการเรียกซ้ำแบบกว้างแรก ด้วยกองเล็ก ๆ คุณสามารถใช้การเรียกซ้ำครั้งแรกในเชิงลึกอย่างมีประสิทธิภาพซึ่งต้องการหน่วยความจำน้อย ปัญหาประสิทธิภาพหลักจะเกี่ยวข้องกับแหล่งต้นน้ำขนาดใหญ่ซึ่งอาจต้องสลับไทล์ของกริดในและนอก RAM ซ้ำ ๆ กัน ดังที่กล่าวไว้ในความคิดเห็นต่อคำตอบอื่น ๆ แต่ปัญหาที่แท้จริงเกี่ยวข้องกับการรับมือกับเซลล์ที่ไม่มีทิศทาง D8 ที่ไม่ซ้ำกันโดยเฉพาะอย่างยิ่งเซลล์ที่อยู่ในแพทช์แนวนอนแนวราบที่กว้างขวาง (เช่นที่สร้างขึ้น
whuber

ปัญหาขยะในถังขยะ สิ่งที่ฉันและ GIss ส่วนใหญ่จะไม่ทำความสะอาดอินพุต! ดูเหมือนว่าฉันจะต้องค้นหาการเรียกซ้ำครั้งแรกในเชิงลึกเพื่อขัดเงาบางส่วนในแฮ็คของฉัน
Roland

ฉันไม่คิดว่านี่เป็นขยะ - โปรดจำไว้ว่าไม่ว่าการใช้งานจะถูกทำลายไปอย่างไรข้อมูลดั้งเดิมคือ DEM แทนที่จะเป็นรหัส D8 ของใครบางคน - แต่มันเป็นความท้าทายอย่างแน่นอน โลกแห่งความจริงมีหลาย ๆ สถานที่ที่ราบเรียบจนยากต่อการกำหนดทิศทางการไหล: waterbody ใด ๆ ที่เป็นตัวอย่างที่ดี ด้วยเหตุนี้คุณจึงต้องหาทางออกของทะเลสาบและพื้นที่ราบอื่น ๆ และคุณต้องรับมือกับพื้นที่ราบที่มีร้านค้าหลายแห่ง สิ่งนี้ต้องการการค้นหาที่ไม่ใช่ในท้องที่ซึ่งยากที่จะทำ
whuber

ฉันอาจสับสนแล้ว ฉันคิดว่าเรากำลังพูดถึงhelp.arcgis.com/en/arcgisdesktop/10.0/help../index.html#//…ซึ่งใช้ flowdir เป็นอินพุต ไม่ต้องการที่จะดึงเราเข้าสู่วัชพืชถ้าฉันไม่ได้อ่านส่วนที่เหลืออย่างใกล้ชิดพอ!
Roland

ไม่ฉันคิดว่าคุณพูดถูก: เมื่อฉันอ่านคำถามอีกครั้งฉันเห็นว่ามันเน้นไปที่การประมวลผลทิศทางการไหลแบบแรสเตอร์เป็นอินพุตมากกว่าในสถานการณ์ทั่วไปที่ฉันนึกภาพมากขึ้น ดังนั้น +1 ถึงคำตอบของคุณสำหรับการจัดการกับมันโดยตรงและด้วยข้อมูลเชิงลึกและตัวชี้ที่เป็นประโยชน์
whuber

4

ความช่วยเหลือ ArcGISพูดว่า:

ลุ่มน้ำสามารถแยกออกจาก DEM ได้โดยการคำนวณทิศทางการไหลและใช้ในเครื่องมือลุ่มน้ำ ในการกำหนดพื้นที่สนับสนุนคุณจะต้องสร้างแรสเตอร์ที่แสดงทิศทางการไหลก่อนด้วยเครื่องมือ Flow Direction

ทิศทางการไหลถูกคำนวณจากDEM โดยใช้วิธี D8โดยที่การไหลจะถูกสรุปโดยการคำนวณสำหรับแต่ละเซลล์ซึ่งมันคือ 8 เพื่อนบ้านน้ำจากเซลล์นี้จะไหลไป

มีทางเลือกมากมายสำหรับ D8 เช่น Rho8, Froh8 & Stream Tubes แต่ซอฟต์แวร์ GIS ส่วนใหญ่รวมถึง ArcGIS มักจะใช้ D8 เนื่องจากง่ายกว่าและมีความเข้มข้นในการคำนวณน้อยกว่าผู้อื่น


ไม่กี่ปีที่ผ่านมาฉันกำลังทำงานในโครงการการแยกลุ่มน้ำและเรากำลังเผชิญกับปัญหาหลายประการเนื่องจาก ArcGIS ใช้วิธี D8 ปัญหาหลักสองประการคือ

  • D8 อนุญาตการไหลแบบทิศทางเดียวเท่านั้น น้ำสามารถไหลออกได้ในทิศทางเดียวจากเซลล์เดียว
  • กระแสที่สร้างขึ้นมีอคติอย่างมากตามแนวแกนในแนวทแยง สิ่งนี้ก่อให้เกิดลำธารที่ดูแปลก

จากข้อมูลของเราเรารู้ว่าปัญหาทั้งสองนี้เป็นปัญหาใหญ่ดังนั้นฉันจึงได้พัฒนาเครื่องมือบางอย่างเพื่อสร้างทิศทางการไหลโดยใช้วิธีไฮบริด

หนึ่งในภารกิจแรกของฉันคือการทำวิศวกรรมย้อนกลับเครื่องมือการคำนวณปริมาณน้ำฝน ฉันพบว่ามันค่อนข้างเรียบง่ายตามหลักเหตุผล หากคุณต้องการหาที่เก็บกักน้ำสำหรับจุดที่กำหนด (หรือเรียกอีกอย่างว่าจุดไหล) คุณจะต้องหาเซลล์ที่เป็นของมันก่อน บ่อยครั้งที่คุณจะพยายามสแน็ปอินไปยังจุดที่มีการสะสมการไหลสูงสุดในความอดทนที่กำหนด

สำหรับเซลล์นี้คุณจะพบเซลล์ทั้งหมดในละแวกที่มีส่วนร่วม สำหรับเซลล์เพื่อนบ้านแต่ละแห่งคุณจะพบเซลล์ที่มีส่วนร่วมและอื่น ๆ คุณทำกระบวนการวนซ้ำต่อไปจนกว่าคุณจะไม่พบเซลล์ใหม่ นั่นคือเมื่อคุณมาถึงแนวสันเขาหรือแนวเขตต้นน้ำ

ฉันพบว่ารหัสง่าย ๆ ของฉันซึ่งทำเช่นนี้สำหรับ raster ASCII ให้ผลลัพธ์เกือบคล้ายกันเมื่อเปรียบเทียบกับเครื่องมือ Watershed ของ ArcGIS บางครั้งก็เคยมีความแตกต่างของเซลล์บางอย่างในขอบเขตดังนั้นฉันจึงเชื่อว่า ArcGIS ทำตามอัลกอริทึม D8 ที่ไม่ได้แก้ไข


ขอบคุณสำหรับการทำอย่างประณีต แต่อัลกอริทึมสำหรับการใช้เส้นทาง D8 เพื่อค้นหาแหล่งต้นน้ำคืออะไร? โปรดดูความเห็นดังต่อไปนี้คำตอบของ dmahr
whuber

สวัสดีขอบคุณ แต่นี่ไม่ได้ตอบคำถามจริงๆ คุณกดมันด้วยประโยค "สำหรับเซลล์นี้คุณจะพบเซลล์ทั้งหมดในละแวกนั้นที่มีส่วนในเซลล์แต่ละเซลล์เหล่านี้คุณจะพบเซลล์ที่มีส่วนร่วมและอื่น ๆ " มีอัลกอริทึมต่าง ๆ มากมายในการใช้การค้นหานั้น คำถามคือคำถามข้อใด
James

4

สิ่งนี้เคยถูกถามมาก่อนแต่บางทีในบริบทที่แตกต่างกันเล็กน้อย เครื่องมือการประมวลผลทางภูมิศาสตร์ทั้งหมดในชุดเครื่องมือทางอุทกวิทยาของนักวิเคราะห์เชิงพื้นที่ใช้โมเดลทิศทางการไหลของ D8ดังที่ระบุไว้ในหน้าวิธีการทำงานของทิศทางการไหล :

มีเอาต์พุตที่ถูกต้องแปดทิศทางที่เกี่ยวข้องกับเซลล์แปดเซลล์ที่อยู่ติดกันซึ่งไหลได้ วิธีการนี้มักเรียกกันว่าแบบจำลองการไหลแปดทิศทาง (D8) และเป็นไปตามแนวทางที่นำเสนอใน Jenson และ Domingue (1988)

สำเนาของเจนสันและ Domingue (1988) กระดาษสามารถใช้ได้ที่นี่

เครื่องมือทั้งหมดที่ใช้ rasters ทิศทางการไหลเป็นอินพุตใช้แบบจำลองทิศทางการไหลนี้โดยการเชื่อมโยง ซึ่งรวมถึงลุ่มน้ำการสะสมการไหลความยาวการไหลการเติมเป็นต้น


ดังนั้นฉันคิดว่าคำถามต่อไปนี้จะเป็นวิธีการที่อัลกอริทึมที่มีการแก้ไขเพื่อกลับไปเก็บกักน้ำ?
James

เครื่องมือลุ่มน้ำจะนำทางแรสเตอร์ทิศทางการไหลจากจุดไหล มันเป็นสิ่งที่ตรงกันข้ามกับเครื่องมือการสะสมของการไหลยกเว้นว่าแทนที่จะเป็นเอาท์พุทแรสเตอร์ที่อธิบายจำนวนของเซลล์มันจะรายงาน ID ของจุดเท
dmahr

1
โอเคฉันคิดว่าฉันต้องเจาะจงมากกว่านี้หน่อย ฉันรู้แนวคิดของสิ่งที่มันทำ ฉันไม่รู้ว่าจะใช้อัลกอริทึมใด คือฉันคิดว่ามันเป็นอัลกอริธึมการค้นหาบางอย่าง แต่มันก็อาจจะเป็นเช่นนั้น กว้างแรกลึกแรกซ้ำลึกที่ลึกลงไปเป็นต้น
James

1
ขอบคุณ dmahr @whuber: เท่าที่ฉันรู้ขั้นตอนวิธีการค้นหาที่แตกต่างกันอาจให้ผลลัพธ์ที่แตกต่างกันเล็กน้อย และใช่การค้นหาอัลกอริทึมทั่วไปไม่ใช่ปัญหา แต่การเรียนรู้ว่า ESRI จัดการกับพื้นที่เฉพาะของลุ่มน้ำ (เช่นส่วนแบนของ DTM) มีประโยชน์อย่างไร
James

1
James โปรดแก้ไขคำถามของคุณเพื่อชี้แจงว่าจุดสุดท้ายเพื่อที่กระทู้นี้จะหยุดการรวบรวมคำตอบ "เป็น D8" ที่ไร้ประโยชน์ (สิ่งที่มีประโยชน์เกี่ยวกับความคิดเห็น D8 คือถ้าคุณยอมรับว่า D8 นำไปสู่กราฟทิศทางการไหลที่ไม่ซ้ำกันแล้วจะมีวิธีการแก้ไขที่ไม่ซ้ำกันสำหรับปัญหาการกำหนดเขตลุ่มน้ำเนื่องจากลุ่มน้ำเป็นคุณสมบัติของกราฟเองดังนั้นหากมี ความคลุมเครือใด ๆ ที่พวกเขาจะต้องอยู่ใน (a) คำจำกัดความของ "ลุ่มน้ำ" (b) วิธีคำนวณทิศทางของ D8 หรือ (c) วิธีจัดการเซลล์แนวนอน (กล่าวคือไม่มีทิศทาง D8 ที่ไม่ซ้ำกัน)
whuber

0

เพื่อให้คิดเพิ่มเติมเกี่ยวกับคำถามนี้ฉันได้ทำการวิเคราะห์สันปันน้ำในส่วนโค้ง: ฉันใช้ DEM (เต็ม) คำนวณทิศทางการไหลและวางจุดสองสามจุดที่ตรงกับตำแหน่งในเครือข่ายสตรีมที่คำนวณไว้ก่อนหน้านี้ ฉันใช้เครื่องมือ 'สันปันน้ำ' และมันให้แอ่งน้ำเล็ก ๆ น้อย ๆ แก่ฉันซึ่งครอบคลุมพื้นที่ส่วนใหญ่ที่เหลือ 'ต้นน้ำ' (ตามที่คุณคาดหวัง):

ภาพสันปันน้ำ

จากนั้นฉันก็เขียนอัลกอริธึมการค้นหาอย่างรวดเร็วใน Python (เช่นคำตอบข้างต้น) ซึ่งตรวจสอบกริดทิศทางการไหลและ 'ติดตาม' เส้นทางการไหล สำหรับแต่ละโหนดฉันตรวจสอบ 8 เพื่อนบ้านและถ้าเพื่อนบ้านไหลเข้าสู่โหนดปัจจุบันฉันเรียกใช้ฟังก์ชันเดียวกันซ้ำกับโหนดเพื่อนบ้านเป็นอินพุต

รหัสเทียม (ish):

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)

ฉันวิ่งฟังก์ชั่นนั้นโดยใช้กริดอินพุตทิศทางการไหลเดียวกันและหนึ่งในจุดเดียวกัน ปัญหาคือเมื่ออาร์คส่งคืนเซลล์ 40000 เซลล์สำหรับจุดนั้นอัลกอริธึมของฉันจะคืน 72 เซลล์

มีใครรู้บ้างว่าฉันทำผิดอะไร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.