本章導讀:河流比降指的是河流任意兩端點間的高程差與兩點間的水平距離之比值,簡單的歸納爲單位河長內的落差,其單位通常都是‰ 。 河流(縱)比降對地質災害、水運、水電、礦砂和新構造運動研究有實用價值。比降是水文學上重要的一項指標。在絕大部分的GIS通用平臺上,都沒有實現平均比降的計算,緣由在於計算比降的條件比較苛刻,不符合通用GIS的要求。本章一樣是一個實操章節,筆者將會利用ArcGIS軟件,結合其ArcPy編寫一個平均比降計算的工具,在通用GIS軟件上實現河流平均比降計算。 BY 李遠祥python
河流比降是不少水文研究者研究的內容,其水文意義很是的大。這裏研究的河流比降指的是河流的縱比降,是河流任意兩端點間的高程差與兩點間的水平距離之比值,即單位河長的落差。算法
正是由於直接表達的是單位河長的落差,因此在水文學上其最直接的影響就是流速,帶來更多的水動力引起的能量轉移,如勢能與動能的轉化(涉及到水電站的建設);河水對河牀和河岸的沖刷,影響泥沙量;大面積持續降雨時,洪峯到來的時間和強度等。因此,比降在水文學上歷來就不缺乏話題。數組
河流的比降分爲牀面比降和水面比降。牀面比降,用以表示河牀縱斷面地形的變化;水面比降即河流中任意兩端點間的瞬時水面高程差與其相應水平距離之比,用以代表河流全程或分段的水面坡度,故又稱水力坡度,一般說的河流比降就是河流水面比降。微信
在恆定均勻流狀況下,水面坡度剛好等於河底坡度。因此,在沒有大量斷面數據支撐的狀況下,根據地形和河流線型去研究的河流比降都是牀面比降。app
筆者在這裏研究的都是牀面比降,由於只考慮地形與河流自己的幾何形狀,沒有任何的站點數據支撐。但在非洪水狀況下,這個牀面比降與水面比降基本上是吻合的。工具
在河流相距較短的兩個點上計算河流比降,意義不是十分大。通常須要計算的是整個河流或者某一河段的平均比降,這對於空間跨度較大的河流來講纔有研究價值。學習
本章研究的內容也就是河流(段)的平均比降。研究河流平均比降的方法有幾種,比較流行的是【約翰斯通-克羅斯】法。其原理是根據比降大體均勻的原則,將河段劃分爲若干個子河段,而後去計算總體的平均比降。其公式以下:測試
公式中個參數以下
S---- 河段平均河底比降
Li----第i個子河段長度
Si----第i個子河段河底比降
N---- 子河段數量spa
另外一種方法是【勞倫斯】法,其須要經驗係數和流速,相對來講比較複雜,須要結合測站的一些數據。因爲筆者沒有這些數據,就不做論述。.net
本章考慮的是在ArcGIS中實現【約翰斯通-克羅斯】法的計算。
利用GIS手段來研究水文,其核心方式是使用DEM數據去模擬水文過程。GIS的空間疊加能力很是的管用,很是簡單的就能獲取到河流線對應的DEM像元值,也就是河流對應的高程值,這樣用於計算比降是很是有用的。最起碼解決了河流高程點獲取的問題。
河流沿線高程的獲取,不能直接使用原始的DEM數據。緣由有兩點:
若是河流數據與DEM數據不是同一份數據,那麼像元點與河流線的重合程度有待商榷。
若是河流數據與DEM數據吻合(或者河流數據直接從DEM數據提取出來的),其高程的獲取所依賴的DEM必須是填窪後的無凹陷點DEM。
河流線屬於一維數據,DEM在平面上屬於二維數據,其相交以後會產生一個像元點的連續像元。若是瞭解過D8單流向算法的話,就能夠很容易理解,若是直接從原始DEM中獲取像元值,其值有多是一個匯點(凹陷點)。然而使用填窪後的DEM,能夠確保該點與周邊一點的高程持平。
下圖是一個測試數據,黃色部分爲河流線,點爲河流的節點。包含兩份DEM,一份是原始的DEM,一份是填窪過的DEM(Fill_DEM) 。河流是使用了前面章節介紹到的河流提取方法提取出來的線狀河流。讀者能夠參考《ArcGIS水文分析實戰教程(6)河流提取與河網分級》的作法去提取。
測試的主要內容是分兩種狀況打印河流各節點的高程值。一是獲取原始DEM的高程值,而是獲取填窪後的DEM的高程值。經過高程值進行對比選用不一樣數據引發的差別。
第一張圖是原始DEM的沿河高程值,第二張圖是填窪後的DEM的沿河高程值。能夠看到使用原始DEM的時候,有可能出現下游高程比上游高程還要高的狀況,也就是說這個上游地勢低的點恰好就是一個匯(凹陷點)。而填窪後的DEM則會將這個點給填平,確保不會斷流,從而使得下游高程最少不會高於上游高程。對比其餘高程值,是沒有變化的,變化的部分就只是出現【匯】的點。
若是原始DEM的精度足夠高的話,這種狀況通常不多碰到。但爲了穩妥起見,筆者仍是建議對原始DEM作填窪,生成無凹陷點的DEM。讀者能夠參考以前章節 《ArcGIS水文分析實戰教程(4)地形預處理》
若是所使用的河流是從DEM中提取出來的,那麼在矢量河流提取的時候使用【柵格河流矢量化】時是否須要使用【簡化折線】參數,這個參數是默認選上的,以下圖所示:
不選擇簡化折線,河流線會基本上就是按照流量線走向,河流折點密度會比較高;選擇簡化的話,河流線的折點會被抽希一部分。這個怎麼取捨?若是在地形變化比較大的狀況下,不建議簡化;若是地勢趨平,那就直接簡化線。這種方式會直接影響到最終的比降數值。
下圖黃線部分是簡化節點後的河流線,紅線是沒有簡化節點的河流線,其形狀基本上是重合的,並且在關鍵的河流節點上,也是徹底重合。
也就是說,簡化與不簡化,其參與計算的河段數量是不同的。上圖數據中簡化後的子河段數爲32,不簡化子河段的數量是92 。若是人爲計算的話,那麼可定是後者的計算量比較大了。
ArcGIS 除了前面章節說起到的水文分析工具及其相關工具以外,還有很是龐大的工具集對空間計算進行支撐。因爲沒有斷面數據的支撐,這裏只考慮經過地形和河流線型進行計算,也就是說實現【約翰斯通-克羅斯】法。
根據【約翰斯通-克羅斯】法的計算公式,能夠推導出其分析流程
經過河流線提取河流折點,利用這些折點與DEM數據疊加,獲取高程值
利用河流折點,獲取其座標值,根據兩點距離公式,計算每一段子河段的長度
根據每一個點的高程值,計算出相鄰兩點之間的高差
根據高差與子河段長度,計算出各子河段的河底比降
彙總這些數據計算出整個河段的平均河底比降
在這5各步驟中,只有第1步與ArcGIS工具備關。河流的折點提取,可使用【數據管理】--【要素】--【要素折點轉點】工具來實現,以下圖所示:
至於利用折點與DEM數據疊加,獲取其高程值,可使用【數據管理】--【柵格】--【柵格屬性】--【獲取像元值】工具來獲取。這個工具每次只能實現一個座標點與DEM數據疊加查詢。以下圖
因此,爲了方便計算,筆者採用ArcPy去寫一個腳本工具,實現參數的靈活輸入。其中heightList就是用來保存高程值的數組。
# 獲取河流的節點,以用做計算高差和河長 for row in arcpy.da.SearchCursor(outLine1, ["SHAPE@XY"]): # 從點圖層數據獲取全部的點的XY x, y = row[0] #從地形數據中獲取其高程的象元值 pointStr = str(x) +" "+str(y) result = arcpy.GetCellValue_management(dem,pointStr) riverPoints.append(row[0]) heightList.append(str(result))
第2-5步基本上就是一些數學的運算,利用python就很好實現了。爲了讓廣大水文研究者用起來,筆者將這段代碼公開,而且製做成爲工具。在代碼中筆者已經預留了ArcGIS的工具參數,方便製做成爲腳本工具。
河流平均比降【約翰斯通-克羅斯】法的實現代碼以下
############################################################# # # # 該工具利用【約翰斯通-克羅斯】方法計算河底平均比降 # # 在使用的時候必須先選擇一條河流,工具會判斷輸入的河流數量 # # 大於一條河流時不予以計算 # # 用於計算的DEM爲無凹陷點DEM # # BY 李遠祥 # # # ############################################################## # -*- coding: gbk -*- import arcpy import math inputLine =arcpy.GetParameterAsText(0) #河流圖層 dem = arcpy.GetParameterAsText(1) #無凹陷點DEM riverLen = 7873.232038 arcpy.AddMessage(u'..................') arcpy.AddMessage(u'......開始執行...........') # 記錄高程值的數據 heightList = [] iputCout=0 mmCursor = arcpy.da.SearchCursor(inputLine, ["SHAPE@LENGTH"]) for row1 in mmCursor: riverLen = row1[0] #順便獲取河流長度 iputCout=iputCout+1 arcpy.AddMessage(u'......獲取了河流長度......') #若是選中的是一個線要素,則執行計算,否者不計算多條河流 if iputCout==1: ##先將線轉爲折點 outLine1 = arcpy.FeatureVerticesToPoints_management(inputLine, "in_memory/outline") arcpy.AddMessage(u'......河流線已經轉換爲點集.......') #河流節點 riverPoints = [] # 獲取河流的節點,以用做計算高差和河長 for row in arcpy.da.SearchCursor(outLine1, ["SHAPE@XY"]): # 從點圖層數據獲取全部的點的XY x, y = row[0] #從地形數據中獲取其高程的象元值 pointStr = str(x) +" "+str(y) result = arcpy.GetCellValue_management(dem,pointStr) riverPoints.append(row[0]) heightList.append(str(result)) arcpy.AddMessage(u'......已經獲取了折點的高程值......') #子河段長度 subRiverList = [] hDiffList = [] # 計算每個子河段的長度 for i in range(0,len(riverPoints)-1): x,y = riverPoints[i] x1,y1 = riverPoints[i+1] #計算河段長度 dis =math.sqrt(pow((x1-x),2)+pow((y1-y),2)) subRiverList.append(dis) arcpy.AddMessage(u'......河流子河段長度計算完成完成.......') # 計算從高程從低到高部分的差距 listLen = len(heightList) for j in range(0,listLen-1): h1 = float(heightList[j]) h2 = float(heightList[j+1]) xheight = 0 xheight = h1-h2 hDiffList.append(xheight) arcpy.AddMessage(u'......各折點的高程差計算完成......') # 計算每一個河段的比降 subbijiang = [] for i in range(len(hDiffList)): Si= hDiffList[i]/subRiverList[i] subbijiang.append(Si) arcpy.AddMessage(u'......子河段比降計算完成......') # 計算最終的比降 # 計算分子 sumUp = 0 for i in range(len(hDiffList)-1): sumUp = sumUp + subRiverList[i]*pow(subbijiang[i],0.5) S = pow((sumUp/riverLen),2) arcpy.AddMessage(u'......該河流的總長爲: ' + str(riverLen)+u' 平均比降爲: ' +str(S)) arcpy.AddMessage(u'......計算完畢.......') else: arcpy.AddMessage(u'......您選中了 '+str(iputCout) + u' 條河流......') arcpy.AddMessage(u'......工具已經中止計算,沒有算出您想要的結果......') arcpy.AddMessage(u'......由於您目前選中了多條河流。只能選中一條河流進行計算!......')
從代碼中能夠看到,這個工具針對的是一條河流進行計算的。若是想指定河流的某一段進行計算,那麼就須要將河流轉爲折點,選擇對應的折點,生成新的河段才能參與計算。這個過程須要用到【點集轉線】工具進行重構要分析的河段。
能夠將上面的python代碼製做成爲腳本工具,方便在ArcGIS中進行可視化的調用。工具的製做能夠參考筆者另外一篇博文《ArcMap自定義腳本工具製做》,裏面有詳細的論述。
該工具用到的ArcGIS工具涉及到ArcInfo級別 和 Spatial 擴展模塊,請先確保ArcGIS軟件具有相應的受權。
製做好工具以後能夠雙擊調用該工具了,【約翰斯通-克羅斯】法須要用到無凹陷點DEM和河流線型數據。
從上面代碼能夠看到,工具會判斷選中的河流數量,若是數量大於1,就不做計算,確保計算的是某一河段。ArcGIS的交互性很是的優秀,只要選中某一條河流,就會將選中的部分做爲參數輸入。
對應工具的流程,這裏第一步須要選中要分析的一條河流。以下圖
接着雙擊調用工具,兩個參數分別是河流圖層和無凹陷點DEM。必定要注意,這個DEM是填窪過的DEM,不是原始DEM數據。以下圖
點擊肯定就能夠執行計算結果,結果會在最終的提示框中找到,以下圖所示:
至此,複雜的河流平均比降就計算完畢了!
水文分析是一個複雜的過程,須要有深厚的水文學基礎做爲背景。而GIS是一個通用工具,提供很是龐大的分析功能。兩者要結合起來,不但須要學習兩個專業的知識,還須要具有知識整合的能力。
代碼和製做ArcGIS工具的方法已經在文中貼出來了。讀者能夠自行參考製做。固然想省事的話,筆者也已經上傳製做好的工具,能夠點擊跳轉到 下載頁面 。爲了增強交流,防止伸手,多動手操做,筆者已經將下載分值設置爲最高分10分。 積分不夠的讀者請多動手製做 ^_^
若是讀者對水文分析感興趣的話,能夠持續關注CSDN的GIS製圖樂園,以及微信公衆號【GIS製圖樂園】。BY 李遠祥