ArcGIS水文分析實戰教程(4)地形預處理
本章導讀: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),通常可將其視爲錯誤。隨着像元大小的增大,數據集中的匯數通常也隨之增多。
這一段話中包含了非常大的信息量:
- 產生匯的主要原因之一就是DEM數據製作的時候採樣效果和高程值設置爲整數時導致的。這就是筆者在上一章中詳細介紹製作適合於水文分析的DEM的原因。有些參數的設置在測繪行業上生成DEM基本上是無所謂的,但對水文分析來說就非常重要的。如果還有一些疑問,可以翻看上一章《ArcGIS水文分析實戰教程(3)DEM數據準備》。如果能在DEM製作一環上已經對DEM數據進行控制,那是效果最好的。
- 冰川和喀斯特地形不適合使用ArcGIS水文分析。這主要是D8算法的原因。
- 像元大小小於10米的DEM數據很少自然產生匯。如果這種精度的數據都產生了匯,一定要檢查這些匯是不是在現實中存在,通過疊加一些地形數據可以對比查看。否則就是數據中存在一些致命的錯誤。
- 像元大小增大,匯也隨之增加。所以精度太差的數據其實是不適合於做小河流或小流域的分析,因爲匯的大量存在基本上上會導致一部分的徑流斷流,由於匯入大江大河的徑流會比較多,所以,針對一定級別的河流,還是具有參考價值。
以下是匯的剖面圖
由於匯的地勢都低於周邊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 限制並非要填充的最大深度。
從描述來看,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 李遠祥