本章導讀:ArcGIS的水文分析工具是基於DEM進行地表水流動的模擬,其自己不涉及到精確數值的水流流量。在造成徑流的過程當中考慮的全是地形因素,D8單流向算法決定了其必須針對無凹陷的DEM數據才能正確的分析出結果。在上一章中筆者已經就如何製做適合於ArcGIS水文分析的DEM數據。在本章中筆者將會介紹如何針對已有的DEM進行預處理,製做出適合水文分析的無凹陷DEM數據。BY 李遠祥算法
在ArcGIS原生的水文分析工具中包含兩個經常使用的地形分析工具:匯、填窪。微信
什麼是匯?ArcGIS的是根據其D8算法來解釋了。在第二章《ArcGIS水文分析實戰教程(2)ArcGIS水文分析工具的基本原理》是筆者不厭其煩的解釋過。
匯是指流向柵格中流向沒法被賦予八個有效值之一的一個或一組空間鏈接像元。匯被視爲具備未定義的流向,並被賦予等於其可能方向總和的值。例如,若是最陡下落及其產生的流向都是向右 (1) 和向左 (16),則會分配值 17 做爲該像元的流向。工具
在介紹ArcGIS流向分析算法的時候那個流向九宮格其定義是2的n次方,因此,經過匯的計算以後造成的柵格數據,能夠經過其值反演出匯所在的方位。對於分析人員來講沒什麼做用,但對於後續編寫程序的人員去改進水文分析是很是重要的。測試
下面這一段也是ArcGIS幫助的描述:
致使高程數據中出現匯的最多見緣由是數據內存在錯誤。採樣效果和將高程取捨爲整數一般是產生此類錯誤的緣由。除了在冰川和卡斯特意貌區,在像元大小爲 10 米或更大的高程數據中出現天然產生的匯極其罕見 (Mark 1988),一般可將其視爲錯誤。隨着像元大小的增大,數據集中的匯數一般也隨之增多。ui
這一段話中包含了很是大的信息量:編碼
產生匯的主要緣由之一就是DEM數據製做的時候採樣效果和高程值設置爲整數時致使的。這就是筆者在上一章中詳細介紹製做適合於水文分析的DEM的緣由。有些參數的設置在測繪行業上生成DEM基本上是無所謂的,但對水文分析來講就很是重要的。若是還有一些疑問,能夠翻看上一章《ArcGIS水文分析實戰教程(3)DEM數據準備》。若是能在DEM製做一環上已經對DEM數據進行控制,那是效果最好的。spa
冰川和喀斯特意形不適合使用ArcGIS水文分析。這主要是D8算法的緣由。code
像元大小小於10米的DEM數據不多天然產生匯。若是這種精度的數據都產生了匯,必定要檢查這些匯是否是在現實中存在,經過疊加一些地形數據能夠對比查看。不然就是數據中存在一些致命的錯誤。blog
像元大小增大,匯也隨之增長。因此精度太差的數據實際上是不適合於作小河流或小流域的分析,由於匯的大量存在基本上上會致使一部分的徑流斷流,因爲匯入大江大河的徑流會比較多,因此,針對必定級別的河流,仍是具備參考價值。教程
如下是匯的剖面圖
因爲匯的地勢都低於周邊8個區域,因此水流都會匯入其中,致使徑流最終斷流。但現實中就算出現一些小的窪地,只要降水充足,這些窪地都會被填平,填滿後徑流將會繼續往外流出。因此,D8算法就是假設有無限的降水,雨水不斷的在地表造成徑流。
填平匯的過程就是填窪。ArcGIS中的填窪工具,使用與焦點流、流向、匯、分水嶺和區域填充等工具等效的功能來定位和填充匯。該工具的執行過程會進行迭代,直到指定 z 限制內的全部匯均填充完畢。在填充匯的同時,可能會在填充區域的邊界處建立其餘匯,這些匯將在下個迭代中移除。
關於填窪工具,ArcGIS的幫助說明不算清楚。大概的原理仍是基本說清楚的,就是將凹陷處填平。這個過程是一個迭代的過程,就是不斷的檢測匯周邊的像元,填充完以後再次檢查,知道指定的Z值限制內全部的匯填充完成。但關於Z值,不少人不清楚其原理。
接下來看看填窪工具的一些參數,以下圖
填窪工具必填的兩個參數,其一是DEM,這個DEM有多是原始的DEM,還有多是通過填窪以後還發現匯的DEM(也就是n次填窪後的DEM),其二是輸出的路徑。關於Z值限制,是個可選項,估計大部分人都看不懂這個可選項到底表明什麼意思,到底怎麼設置。這個Z值限制在下面再作介紹。
先來看一張很是經典的水分分析的流程圖,這張圖彷佛被引用過無數次,但大部分人只是作了一個單向的操做。以下圖
這張流程圖左邊部分是製做無凹陷點DEM數據的流程。這個過程實際上是一個循環的過程,不斷的填窪並從新判斷是否存在匯,若是還存在匯,則繼續填窪,直到出現無凹陷點DEM。從圖上來看,這最起碼是個屢次填窪的過程,而大部分人的作法就是無論匯是否存在,作一次填窪後再進行後續的水文分析。
這種作法要兩面看。若是DEM數據很是精確,是不會天然產生匯的,填窪的算法是迭代的算法,很是耗時和耗計算機資源,只要檢查一下是否存在匯,若是沒有,則可將原始的DEM數據做爲無凹陷點DEM直接參與分析;若是存在匯,只是默認作一次填窪,且不設置任何的Z值限制的狀況下,會默認將全部的窪地填平(包括了真的匯和實際存在的窪地),會直接影響徑流的細節流向,即徑流的線形形狀(由於填窪周邊的地形也會被填充改變,但徑流的大體方向是不變的),對面積大的區域用做計算的時間很是長。使用Z值限制做爲填窪的條件,實際上是能夠大量下降計算機的運算量,實現精確的填充。
直接使用填窪工具對DEM數據進行填窪,無論匯的狀況,確實能夠造成無凹陷點的DEM。但前面也說起到,若是隻是負責填,但不是精確的填,大量的凹陷點被填平(這些凹陷點不必定就都是匯),會致使徑流的線形形狀與實際不符,在彎曲細節等會存在必定的損失。因此,若是水文分析人員要研究很是準確的地形與河流的關係,而不是單純的河網拓撲關係,精確填窪就很是重要了。
ArcGIS原生的水文分析工具就只有幾個,若是按照網上一些分析教程,只須要十來分鐘就能夠操做完。但這些教程,都只是涉及罪簡單的操做,甚至大部分都是在校學生的實驗報告,但從GIS實現角度上去闡述分析的過程,而不是從水文角度去思考,喪失了大量的原理和細節部分。而這些部分剛好就是水文研究人員須要去考慮的事情,一旦一些基本設置沒作對,會致使總體的分析結果出現誤差。這就是筆者爲何要花大量的時間和精力去闡述ArcGIS水文分析工具的原理以及細節參數對水文研究的影響。
無論是網上關於ArcGIS水文分析的教程仍是ArcGIS官方的幫助,都沒有具體說明使用【匯】工具以後找到匯後做什麼樣的處理。大部分人的處理更是簡單粗暴,有匯即填窪,也無論具體哪裏須要怎麼填窪,填窪完以後直接進入分析環節。
筆者花了很多時間來研究其匯和填窪的原理,總結出如下步驟:
尋找匯
尋找匯相對來講比較簡單,先經過DEM計算流向,而後直接使用【匯】工具進行查找,最終匯得出匯的柵格數據,以下圖,使用的是ArcGIS spatial中自帶的DEM數據進行分析。
圖上疊加了第一次查找匯的柵格,發亮部分的點就是凹陷點,若是放大一點顯示,那麼能夠清楚看到其像元形狀,以下圖
計算出Z值限制
限制指定凹陷點深度和傾瀉點間的最大容許差值並肯定要填充的凹陷點和保持不變的凹陷點。z 限制並不是要填充的最大深度。
從描述來看,Z值限制要作的事情就是確保填窪工具不要一刀切,不要把全部的低窪點都填充,由於有些不是真的凹陷點;另外一做用就是符合條件的窪地都會被指定填充。
例如,假設一個凹陷點區域中傾瀉點的高程爲 210 英尺,凹陷點的最深點爲 204 英尺(相差 6 英尺)。若是將 z 限制設置爲 8,則會填充該特殊凹陷點。可是,若是將 z 限制設置爲 4,則不會填充該凹陷點,由於該凹陷點的深度超過該限制值,將其視爲有效凹陷點。
填窪
填窪是地形處理中必不可少的一環。若是按照工具論,直接使用ArcGIS的填窪工具的默認配置,能夠對DEM數據進行無限量的填窪。但筆者不推薦這種方式,並且Esri也不推薦。
正確的填窪流程應該是先要計算出Z值限制,而後根據一個或者一組Z值限制進行精確填窪。關於Z值限制前面已經說得很清楚,在這個閾值範圍內匯纔會被填充。那麼Z值限制怎麼計算出來呢?在【匯】的原理裏面,幫助有具體說起到,但都是使用arcpy腳本的形式進行計算。如下引用ArcGIS幫助的Z值計算流程:
使用匯建立經過深度進行編碼的匯的柵格。
輸入流向柵格數據:flowdir
輸出柵格:匯點
使用分水嶺爲每一個匯建立匯流區域柵格。
輸入流向柵格數據:flowdir
輸入柵格數據或要素類傾瀉點數據:匯點
輸出柵格:sink_areas
將分區統計與最小值統計數據結合使用,以在每一個匯的分水嶺中建立最小高程的柵格。
輸入柵格數據或要素區域數據:sink_areas
區域字段:值
輸入賦值柵格:高程
輸出柵格:sink_min
統計類型:MINIMUM
使用區域填充在每一個匯的分水嶺中建立最大高程的柵格。
輸入區域柵格數據:sink_areas
輸入權重柵格數據:高程
輸出柵格:sink_max
使用減將最大值減去最小值以查找深度。
輸入柵格數據 1:sink_max
輸入柵格數據 2:sink_min
輸出柵格:sink_depth
ArcPy的代碼以下
sink_areas = Watershed(flowdir, sinks) sink_min = ZonalStatistics(sink_areas, "Value", elevation, "Minimum") sink_max = ZonalFill(sink_areas, elevation) sink_depth = Minus(sink_max, sink_min)
爲了與默認的填窪工具的結果進行對比,筆者特地針對該流程,使用modelbuilder進行了建模,以求出Z值限制。建模流程以下圖
最後求出的是一組Z值限制,最大的Z值爲32,最小是1,共有20處限制值。以下圖所示
這裏存在一個疑問,筆者尋遍整個官方幫助文檔都沒找到,就是若是出來的是一組的Z值限制,而不是一個Z值限制,那麼怎麼作?填窪工具只是提供一個Z值的輸入,並且是針對整個DEM區域,而不是分片區填窪。爲此筆者專門作了很多的測試,最後的結論是,直接使用這一組Z值限制裏面最大值+1。也就是說該例子中20個值最大爲32,那麼填窪工具中使用的限制值設置爲33。只要比地圖單位大1點就好了,但不要使用浮點型數據。
筆者作了兩組測試
測試1:
對原始DEM數據進行無Z值限制填窪,直接執行填窪工具,使用默認設置,不設置Z值;
利用填窪完以後的DEM數據計算流向,並執行【匯】工具,發現全部的匯已經被填充,再也沒有匯的存在了。以下圖
測試2
對原始DEM數據進行有Z值限制的填窪,將Z值設置爲33(以前已經計算出Z值最大值爲32)。一樣,對填窪過的DEM進行流向計算,並查找匯,發現存在匯,以下圖
若是按照幫助裏面的說明,只要設置了最大的Z值,應該會將全部的匯都填充掉,但事實上沒有。惟一的解釋了填充匯的同時又產生了新的匯。
測試3
使用筆者按流程作好的Z值計算工具,針對填窪限制值爲33的DEM數據從新計算Z值限制,以下圖
計算出來新的Z值爲60,以下圖
再利用61做爲Z值限制從新對填窪爲Z值爲33的DEM數據進行再次填窪,並從新查找一次匯。這一次的結果沒有再發現任何的匯,跟測試1一樣的結果,以下圖
測試4
流程與測試1同樣,直接使用原始DEM數據填窪,但填窪的Z值限制一步到位設置爲61,而後查找匯。結果跟預測的同樣,全部的匯都被填充,以下圖
測試5
該測試纔是最後的測試結論,分別都這個產生無匯結果的填窪過的DEM數據進行對比,用減法工具執行。若是這些DEM是同樣的話,減法的結果將會沒有任何的數據。論證的目的在於設置Z值和不設置Z值到底有多大的差異。
第一組對比爲測試1的無Z值填窪的DEM數據VS測試3的第二次填窪的DEM數據(Z值爲61的那次),減法結果以下
減法的結果爲0,也就是說這兩個填窪後的柵格無凹陷點DEM是如出一轍的。以下圖
第二組對比爲測試1的無Z值填窪的DEM數據VS測試4的直接使用Z值爲61填窪的DEM數據。一樣作減法,結果以下
結果一樣是0,不用作第三組測試也知道測試2與測試3的填窪後的DEM也是同樣的。
不知道是否是數據湊巧是這樣仍是ArcGIS軟件在填窪的時候會自動計算最大的Z值限制,但確實按照其無凹陷DEM製做的流程進行屢次填窪,知道無匯出現,跟沒設置Z值效果是同樣的。爲此筆者再作一次大膽的嘗試,就是將Z值限制調整爲300,遠遠超出以前二次計算的60。
測試6
對原始DEM數據進行Z值爲300的填窪,而後查找匯,結果顯然也是徹底被填充,再也不存在匯;而後用減法對填窪後的數據與無Z值填窪的DEM數據作減法對比,結果爲0。也就是說只要設定一個無限大的Z值,全部的匯都會被填充,而後構成無凹陷DEM數據前一步的填窪數據,與無Z值填窪結果是同樣的。
所以,筆者能夠大膽的猜想,無Z值填窪中應該使用了DEM數據最大高程減去最小高程的值做爲Z值,這樣可以確保在全部的匯的高差值全落在這個差值範圍內。
經過6個測試和3次對比,基本上能夠肯定,精確計算Z值屢次填窪與不設置Z值填窪效果是等價的。基本上能夠肯定若是要生成無凹陷DEM,直接使用填窪工具作一次無Z值填窪便可。ArcGIS的建立無凹陷DEM方法是從8.x時代就傳下來的,筆者的測試版本是10.5,估計填窪工具早已經實現了自動化計算Z值以及自動迭代操做,只是工具幫助上沒有做更新的說明罷了。所以,在使用ArcGIS水文分析以前能夠大膽的對原始DEM數據作無Z值限制的填窪操做。
本章信息量有點大,主要是筆者也想進一步查清楚建立無凹陷DEM的原理以及工具的效果,但願能對廣大的GIS和水文工做者有幫助。若是讀者對水文分析感興趣的話,能夠持續關注CSDN的GIS製圖樂園,以及微信公衆號【GIS製圖樂園】。BY 李遠祥