方壽軍
摘 要:天然河道水位-流量關(guān)系曲線計(jì)算方法和計(jì)算過程都比較簡(jiǎn)單,主要是采用曼寧公式進(jìn)行計(jì)算,其關(guān)鍵工作是量取不同水位下的面積和濕周,通過面積和濕周計(jì)算出天然河槽的水力半徑。傳統(tǒng)計(jì)算過程中需要每個(gè)水位量取一次過水面積和對(duì)應(yīng)的濕周,人工量取過程比較繁瑣,工作量和計(jì)算密度有很大關(guān)系,人工量取過程都是重復(fù)的機(jī)械式操作,利用當(dāng)下比較流行的Python語言結(jié)合pyautocad庫,將這個(gè)繁瑣過程交給計(jì)算機(jī)來處理,實(shí)現(xiàn)水位-流量關(guān)系曲線的自動(dòng)計(jì)算。
關(guān)鍵詞:水位;流量;水力半徑;Python
引言:天然河道水位流量關(guān)系曲線計(jì)算比較簡(jiǎn)單,主要就是量取不同水位下的面積和濕周,但是過程比較繁瑣,工作量和計(jì)算密度有很大關(guān)系,傳統(tǒng)計(jì)算過程中需要每個(gè)水位量取一次過水面積和濕周[1],利用計(jì)算機(jī)編程可以將這個(gè)繁瑣過程交給計(jì)算機(jī)來處理,本文采用當(dāng)下較流行的Python語言來實(shí)現(xiàn)這個(gè)過程,和C#語言做比較,更簡(jiǎn)單、更高效、更實(shí)用。
Python是由荷蘭數(shù)學(xué)和計(jì)算機(jī)科學(xué)研究學(xué)會(huì)的吉多·范羅蘇姆于1990 年代初設(shè)計(jì)。Python語法和動(dòng)態(tài)類型,以及解釋型語言的本質(zhì),使它成為多數(shù)平臺(tái)上寫腳本和快速開發(fā)應(yīng)用的編程語言 2021年10月,語言流行指數(shù)的編譯器Tiobe將Python加冕為最受歡迎的編程語言,20年來首次將其置于Java、C和JavaScript之上,Python廣泛開源的第三方庫是其開發(fā)效率高的主要原因[2]。
此次天然河道水位流量關(guān)系曲線計(jì)算的開發(fā)語言選擇也是由于Python語言的熱度以及其開發(fā)的高效性。采用Python對(duì)CAD進(jìn)行二次開發(fā),可用的庫不多,主要有pyautocad、pywin32、ezdxf、dxfgrabber、dxfwrite以及gdal,其中pyautocad通用性、易用性較好一些,pyautocad庫由俄羅斯工程師Roman Haritonov開發(fā),用于簡(jiǎn)化使用 Python 語言書寫 AutoCAD ActiveX Automation 腳本,但是,這個(gè)庫從2015年至今沒有更新過。
天然河道水位流量關(guān)系曲線計(jì)算采用的是重繪法進(jìn)行計(jì)算,主要思路是先讀取已知的河槽斷面,然后根據(jù)河槽判斷最高點(diǎn)和最低點(diǎn)以及倒數(shù)第二高點(diǎn),從最低點(diǎn)開始計(jì)算,直到計(jì)算至倒數(shù)第二高點(diǎn),這樣保證河槽有效斷面上都能循環(huán)到,然后判斷河槽寬度,按照河槽寬度來確定重繪河槽的范圍[3]。
獲取已知河槽的坐標(biāo)信息采用pyautocad庫也很簡(jiǎn)單,拾取河槽線,這個(gè)線可以是多段線(Polyline),也可以是三維多段線(AcDb3dPolyline),通過線的屬性O(shè)bjectName獲取其類型進(jìn)行判別和過濾,然后通過Coordinates屬性獲取其頂點(diǎn)集合,Polyline和AcDb3dPolyline不同之處在于前者的每一個(gè)點(diǎn)只有兩個(gè)元素(X坐標(biāo)和Y坐標(biāo)),而后者每一個(gè)點(diǎn)只有三個(gè)元素(X坐標(biāo)、Y坐標(biāo)和Z坐標(biāo))。
值得一提是采用C#、VB等語言編程時(shí),線段沒有ObjectName屬性,其類型的判別需要用DxfCode編碼組的邏輯運(yùn)算來實(shí)現(xiàn)選擇集過濾,線段沒有Coordinates屬性,用C#語言編寫時(shí),多段線(Polyline)可通過GetPoint3dAt()方法獲取點(diǎn)坐標(biāo)集合,但是三維多段線(AcDb3dPolyline)就沒有GetPoint3dAt()方法,需要先得到三維多段線的Position點(diǎn)集合,然后把集合放進(jìn)一個(gè)新的列表里面,下文提到的直線或線段的IntersectWith方法在C#、VB等語言里面也是沒有的[4]。所以pyautocad庫能把多段線、三維多段線(直線也可以)的頂點(diǎn)屬性統(tǒng)一,從頂層引用,確實(shí)簡(jiǎn)化了很多代碼工作量,邏輯上更符合我們的慣性思維。
單河槽河道判斷很簡(jiǎn)單,從左岸到右岸,順序重繪就行,但是多河槽河道需要判斷哪些河槽是有效河道斷面,需要判斷河槽斷面的上凸或下凹,只有下凹并且左右兩岸都能跟水平面閉合才是有效河槽斷面,河槽有效斷面的判斷是重點(diǎn),首先根據(jù)pyautocad提供的方法IntersectWith求取兩條線的交點(diǎn),獲得計(jì)算水平面和河槽交點(diǎn)(得到的交點(diǎn)是一個(gè)點(diǎn)集合,每個(gè)點(diǎn)有三個(gè)元素,后續(xù)使用需要按順序取用),根據(jù)交點(diǎn)數(shù)量初步判斷河槽是單河槽還是多河槽,不大于三個(gè)交點(diǎn)就是單河槽。
多河槽的另外一個(gè)難點(diǎn)是判斷有效河槽范圍,按點(diǎn)依次判斷當(dāng)前點(diǎn)的X坐標(biāo)是否在第i個(gè)和第i+1個(gè)點(diǎn)中間,如果在,那么這一段必定是一個(gè)河槽,但是不一定是有效河槽,然后再判斷當(dāng)前點(diǎn)是否低于當(dāng)前計(jì)算高程,低于的話當(dāng)前點(diǎn)一定處于下凹的河槽斷面上,這個(gè)點(diǎn)就是有效河槽的點(diǎn),否則就是上凸的無效河槽或河灘。通過循環(huán),得到所有的有效河槽原河槽坐標(biāo),加上之前求得的前后兩個(gè)交點(diǎn)進(jìn)行重繪,得到有效河槽新斷面,利用線段的length屬性,得到河槽的濕周,然后利用線段的Closed()方法將重繪得到的線段閉合,閉合后的線段就有了準(zhǔn)確的面積屬性,通過線段的area屬性得到河槽的過水面積,這兩個(gè)機(jī)械性的重復(fù)工作完成后,其他就簡(jiǎn)單了,采用曼寧公式進(jìn)行河道流量計(jì)算,將計(jì)算結(jié)果寫入excel文件即可(寫入Excel這里用openpyxl庫,Excel可用的庫很多,根據(jù)實(shí)際選用)[5]。
Python在程序編寫方面確實(shí)有著獨(dú)特優(yōu)勢(shì),效率高是公認(rèn)的,但是其在運(yùn)行速度上的弊端也是很明顯的,因?yàn)镻ython屬于解釋型語言,另外,GIL鎖(全局解釋器鎖,全稱GlobalInterpreterLock) 限制并發(fā),對(duì)多處理器支持不好[6]。當(dāng)python的默認(rèn)解釋器要執(zhí)行字節(jié)碼時(shí),都需要先申請(qǐng)這個(gè)鎖。如果試圖通過多線程擴(kuò)展應(yīng)用程序,將總是被這個(gè)全局解釋器鎖限制。所以其在運(yùn)行速度上和其他語言對(duì)比起來要慢得多,特別是循環(huán)次數(shù)較多時(shí)候更突出,也有很多提高Python運(yùn)行速度的方法,例如使用多進(jìn)程、使用Cpython、數(shù)據(jù)處理時(shí)盡量使用csv替代xlsx、使用Numba編譯、使用哈希表的數(shù)據(jù)結(jié)構(gòu)、矢量化取代循環(huán)等等,但是小型項(xiàng)目對(duì)運(yùn)行速度要求不高時(shí)候其實(shí)也沒必要花那么多心思去提高運(yùn)行速度,大型項(xiàng)目或者對(duì)運(yùn)行速度要求較高時(shí)可以選擇其他語言。另一方面,Python代碼不能加密,對(duì)于想要實(shí)現(xiàn)代碼加密的也只能選擇其他語言。
通過采用不同編程語言對(duì)天然河道水位-流量關(guān)系曲線的自動(dòng)化計(jì)算實(shí)現(xiàn)過程的對(duì)比,Python在小型項(xiàng)目中運(yùn)用具有開發(fā)效率高,開發(fā)周期短的特性[7],對(duì)工程設(shè)計(jì)人員實(shí)現(xiàn)自動(dòng)化輔助設(shè)計(jì)有著較大幫助。
參考文獻(xiàn):
[1]王衡,劉啟和.水位流量關(guān)系曲線表批量計(jì)算[J].東北水利水電,2007,25(9).
[2]張楠.Python語言及其應(yīng)用領(lǐng)域研究[J].科技創(chuàng)新導(dǎo)報(bào),2019,16(17).
[3]胡艷嬌,黃琦,田長(zhǎng)濤.水位流量關(guān)系曲線繪制方法實(shí)例分析[J].科技創(chuàng)新與應(yīng)用,2019(21).
[4]王月明,宮帥良,呂曉琪,等.基于AutoCAD二次開發(fā)實(shí)現(xiàn)測(cè)繪橫斷面處理的方法.
[5]曾晨,沈?qū)m新.基于Python的線性回歸性能分析[J].大眾科技,2019,21(11).
[6]王學(xué)慶.基于Python的計(jì)算機(jī)軟件應(yīng)用技術(shù)研究[J].2022(4).
[7]孫運(yùn)平,高玉春.AutoCAD二次開發(fā)及應(yīng)用研究[J].商場(chǎng)現(xiàn)代化,2012(10):2.