小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

搜羅全網(wǎng)!ArcGIS二次開發(fā)Python(arcpy)指南(七):你也可以制作ArcGIS工具箱

 GIS薈 2021-12-07

前言:讓自定義工具箱變得簡單如喝水一樣。

1.自定義工具箱是什么

就像名字一樣,自定義工具箱是由個人創(chuàng)建的工具箱,就像下面這樣,可以理解成一個 .tbx 后綴的壓縮包,每一個工具箱中都可以添加多個工具集、腳本工具甚至模型構(gòu)建器工具。

一大堆工具箱

1.1如何添加自定義工具箱(熟悉可跳過)

第一步:右鍵點(diǎn)擊 ArcToolbox -> 添加工具箱

第二步:在打開的添加工具箱窗口中選中需要添加的工具,然后點(diǎn)擊下角的打開即可。

添加工具箱到 Arcmap

1.2如何創(chuàng)建自定義工具箱

點(diǎn)擊右上角的紅色工具箱符號,可以新建并重命名一個工具箱。

我們這里新創(chuàng)建了一個海怪工具箱,用于之后的教程演示。

新建工具箱

1.3添加一個腳本工具

新創(chuàng)建的工具箱就像一個大箱子,箱子呢是用來裝工具的,你可以直接在工具箱中右鍵,然后點(diǎn)擊添加,再點(diǎn)擊腳本,進(jìn)而創(chuàng)建一個腳本工具;

亦或是右鍵,點(diǎn)擊新建,再點(diǎn)擊工具集,創(chuàng)建一個可以自定義名稱的工具集,然后在工具集里新建一個腳本工具。

這里添加的腳本工具只是一個空殼,我們后面會繼續(xù)完善。

新建的工具箱位于 ../Chapter7/海怪工具箱.tbx。

2.工具箱的封裝

工具箱由三部分組成,其中有兩部分需要我們來控制:

  • 一是輸入界面:確定工具箱輸入界面的參數(shù)定義和設(shè)置;

  • 二是 Python 源代碼:功能的實(shí)現(xiàn),為 .py 后綴的腳本文件;

  • 三是對參數(shù)行為提供額外控制的可選驗(yàn)證代碼,其位于工具箱中(這部分自帶,基本上不用修改)。

所以下面的重點(diǎn)就是輸入界面和 Python 源代碼。

2.1工具箱輸入界面

工具箱輸入界面,或者說圖形交互界面(GUI),就像下面的幾張圖一樣,從該界面我們可以控制工具的行為,自定義輸入界面然后配合 Python 腳本,可以實(shí)現(xiàn)多種客制化的功能。

簡單來說,你可以認(rèn)為輸入界面是依托于 Arcmap 的“前端”,腳本代碼就是負(fù)責(zé)運(yùn)行的“后端”。

導(dǎo)入導(dǎo)出工具:

為方便演示,制作一個非常簡單的工具箱,它的功能呢就是把輸入的要素類(數(shù)據(jù)庫或者 shp )再導(dǎo)出來而已,是完全沒有用的導(dǎo)入導(dǎo)出功能啦,不過作為演示還是非常不錯的。

制作完成后的導(dǎo)入導(dǎo)出工具的界面

第一步:

在工具箱中,右鍵點(diǎn)擊添加,再點(diǎn)擊腳本,然后修改名稱,修改成你想要的名字,勾選存儲相對路徑名,然后點(diǎn)擊下一頁。

修改名稱

第二步:

然后添加腳本文件,添加該腳本文件 ../Chapter7/toolscript/input_and_output.py,讀者可以在最后的下載包中找到該文件。

然后點(diǎn)擊下一頁。

鏈接python腳本

第三步:

控制用戶交互界面。ArcGIS 在這里內(nèi)置了一整套簡單但是實(shí)用的圖形控件,比如輸入菜單、下拉框、多選框、單選等,借由這些圖形控件我們可以控制腳本工具的圖形交互界面。

我們這里使用的腳本功能非常簡單,上面也有說到:輸入一個矢量要素類,不做任何處理,然后輸出一個矢量要素類。

為了匹配這個腳本,我們需要設(shè)置一個輸入圖層的控件,同時為了能順利的輸出,也需要一個輸出圖層的控件,注意一個是輸入一個是輸出。

從下圖可以看到,左邊(左邊的橙色框)是顯示名稱,其中輸入輸出控件的名稱以及輸入控件的名稱,這里命名為輸入要素和輸出要素;然后在右邊(右邊的橙色框)的數(shù)據(jù)類型下拉框中,我們選擇要素圖層,這里只能做選擇,不能任意輸入。

設(shè)置名稱和數(shù)據(jù)類型

那么輸入輸出是如何區(qū)分的呢?

選中輸入要素(變成藍(lán)色),然后可以看到下方(下方橙色框)的參數(shù)屬性設(shè)置選項(xiàng)卡,這里可以對參數(shù)進(jìn)行調(diào)整。

參數(shù)選項(xiàng)

類型:有三種,一般只會用到 Required 和 Optional,表示必須和可選,用于控制參數(shù)是否可以忽略不填;

方向:兩種,Input 和 Output,表示輸入和輸出,大部分情況都是使用 Input 來獲得參數(shù),Output 用于獲得最后的成果數(shù)據(jù),像是矢量、柵格或者圖表;

多值:Yes 或者 No,用于輸入多個相同類型的數(shù)據(jù),工具打開后就是下面這樣,在輸入要素中可輸入多個要素類;

默認(rèn):設(shè)置一個控件的默認(rèn)值,直接輸入即可。可配合多值一同使用,使用 ; (英文的分號)分開,

結(jié)果如下,可以看到一打開該工具就已經(jīng)填充上了預(yù)設(shè)的多個默認(rèn)值(報(bào)錯是因?yàn)閿?shù)據(jù)類型不是要素圖層);

環(huán)境:工具箱的環(huán)境設(shè)置,比如膜、容差范圍、默認(rèn)數(shù)據(jù)庫位置等,一般不預(yù)先設(shè)置;

過濾器:選擇文件類型可以在選擇文件時只顯示特定格式的文件;

獲取自:指定數(shù)據(jù)的獲取源。這是個什么意思呢?比如我們想要獲取圖層A的某個字段,獲取源就是圖層A。

以下面這種圖作為例子,新增名為字段的控件(上方的橙色框),數(shù)據(jù)類型也是字段,然后參數(shù)屬性中獲取自選擇輸入要素(下方橙色框)。

設(shè)置字段控件

點(diǎn)擊完成后,打開腳本工具。在輸入要素框中選擇一個圖層,然后再點(diǎn)擊獲取字段,如下就可以選擇圖層中的字段了。

獲取圖層的字段

符號系統(tǒng):在最下面還有一個符號系統(tǒng),通常只能作用于輸出的矢量圖層(方向:Output),可為輸出圖層指定設(shè)置好的 lyr 文件樣式。

設(shè)置符號系統(tǒng)

第四步:

點(diǎn)擊右下方的完成,那么腳本工具的輸入界面就完成了。

2.2 Python 腳本

工具箱輸入界面和 Python 代碼要相互配合才行,工具箱界面中的輸入、輸出以及各種各樣的參數(shù),在 Python 腳本文件中都得一一對應(yīng)上,將輸入界面中的各個參數(shù)傳給 Python 腳本,這樣才能讓 Python 腳本按照預(yù)期的效果正常運(yùn)行。

看上去有點(diǎn)麻煩,但實(shí)際上 arcpy 中提供了現(xiàn)成的函數(shù)就可以直接獲得參數(shù)。

①參數(shù)對接(獲?。?/strong>

至于如何對接參數(shù),我們使用剛剛的那個腳本文件舉例:

../Chapter7/toolscript/input_and_output.py

# -*- coding:utf-8 -*-import arcpy#?1?input_lyr = arcpy.GetParameterAsText(0)output = arcpy.GetParameterAsText(1)if __name__ == '__main__':    lyr = arcpy.mapping.Layer(input_lyr)    arcpy.CopyFeatures_management(lyr, output)

?1?:arcpy 提供了 GetParameterAsText(index) 函數(shù),該函數(shù)根據(jù)輸入界面的排序號碼獲得指定的參數(shù)。比如  GetParameterAsText(0) 獲得的就是輸入圖層參數(shù), GetParameterAsText(1)  獲得的就是第二個參數(shù),也就是輸出圖層參數(shù)。

如果有更多參數(shù),以此類推。

②參數(shù)對接中應(yīng)該注意的情況

GetParameterAsText(index) 從輸入界面獲得的參數(shù)都會轉(zhuǎn)變成字符串,沒錯都是字符串。

如果你只是輸入輸出地址這種,那么沒有問題,因?yàn)榈刂繁緛砭褪亲址侨绻阍O(shè)置了一個選擇長度范圍的長整型的控件、亦或是某種布爾值選擇,最后輸入到 python 腳本這里都會變成字符串。

  • 整數(shù)變成字符串,使用 int(str) 規(guī)避;

  • 布爾型變成字符串,True 變成了 "True",F(xiàn)alse 變成了 "False",這樣就不能判斷真假了,需要寫一個判斷語句或者隨便你,方法很多;

  • 還有就是一個輸入控件多值的情況,所有值根據(jù)先后連接成一個字符串,中間由 、(英文分號)間隔,可以使用 split 函數(shù)分開;

  • ...更多的情況都是大同小異,多試幾次就會了。

③更好的參數(shù)獲取寫法

上面例子是一個一個的獲取參數(shù),但是如果參數(shù)很多呢?10個參數(shù)難道寫10遍 GetParameterAsText(index)

# -*- coding:utf-8 -*-def in_and_out(in_lyr, out_lyr):    lyr = arcpy.mapping.Layer(in_lyr)    arcpy.CopyFeatures_management(lyr, out_lyr)if __name__ == '__main__':    #?2?    argv = tuple(arcpy.GetParameterAsText(i)                 for i in range(arcpy.GetArgumentCount()))    in_and_out(*argv)

?2?:使用 GetArgumentCount() 函數(shù)獲取一個有幾個參數(shù),然后一次性把所有參數(shù)拿到,最后在函數(shù)中使用 *argv 解包即可。

使用這種方法可以顯得比較厲害,同時精簡代碼。

④信息輸出

難免想要在代碼中打 print,不管是作為臨時的“斷點(diǎn)”檢查一下,還是作為長期的信息輸出。

那么在工具箱中如何向外面輸出信息呢?

arcpy 提供了 AddMessage(str) 方法向外界傳遞消息。

# -*- coding:utf-8 -*-def in_and_out(in_lyr, out_lyr):    lyr = arcpy.mapping.Layer(in_lyr)    #?3?        arcpy.AddMessage("Hello World")    arcpy.CopyFeatures_management(lyr, out_lyr)if __name__ == '__main__':        argv = tuple(arcpy.GetParameterAsText(i)                 for i in range(arcpy.GetArgumentCount()))    in_and_out(*argv)

?3?:我們在這里使用  AddMessage("Hello World"), 然后運(yùn)行腳本工具,在完成界面可以看到輸出的 Hello World 信息。

⑤導(dǎo)入腳本

到這里基本上工具就完成了,只不過 Python 腳本和自定義工具箱是分開,創(chuàng)建的工具在運(yùn)行的時候會根據(jù)相對路徑位置(如果你一開始勾選了存儲相對路徑名)尋找 Python 腳本,找到并運(yùn)行。

不過你愿意的話,也可以把 Python 腳本文件導(dǎo)入到工具箱中,這樣帶著一個工具箱就行了。

3. 工具箱的各種錯誤和注意事項(xiàng)

3.1“限定”的錯誤

讓我如此苦惱、如此害怕的,就是把寫好的 Python 腳本封裝成 ArcGIS 的工具箱。

ArcGIS 工具箱

每次我把程序代碼寫好,也能正常的運(yùn)行,然后將其導(dǎo)入自定義工具箱中,點(diǎn)擊運(yùn)行之前還得沐浴更衣好好的祈禱一番,愿天公助我。

然而事與愿違,剛剛還好好的程序報(bào)錯了,錯誤可謂是千奇百怪,大部分時候都在說謎語,明明顯示第100行有什么什么錯,結(jié)果一看,100行是空行...

顯然,ArcGIS 工具箱有一些特別的魔法,擁有一些專屬自己的“限定”錯誤,這種錯誤只有在這里才能品味到。

還不快跟著我嘗一嘗新鮮的魔法shit。

Note:以下所有錯誤均是將腳本封裝成工具箱后,運(yùn)行才可能會出現(xiàn)的錯誤,請注意。
Note:我一直使用的10.3版本,以下的所有錯誤不對非10.3的版本負(fù)責(zé),當(dāng)然其他版本也差不多。

3.2工具箱名字導(dǎo)致的錯誤

我們先從最簡單的錯誤開始。

工具箱名稱導(dǎo)致的錯誤:

由于輸出路徑會自動填入工具箱的名字,中間有特殊符號的話,比如:“-”,就會報(bào)錯。

3.2縮進(jìn)錯誤

詭異的錯誤來了,報(bào)錯顯示如下。我都不知道是說的什么鬼話,怎么還有縮進(jìn)錯誤?

鎖定到報(bào)錯提示的地方,是這樣的:

看上去非常正常,100%正常,開始我不信是這里的問題,我開始折騰,狂寫 print 語句,使勁打斷點(diǎn),使勁測試,最后機(jī)緣巧合之下,我把中文注釋移到了上方,然后就順利運(yùn)行了。

# ...# 存在該字段else:    # ...

好吧,由于把 else 和中文注釋寫到一行,導(dǎo)致 else 被莫名其妙被跳過了,所以導(dǎo)致錯誤。

3.3兩種“變量”錯誤

第一種:

global name xx is not defined

第二種:

name xx is not defined

這個錯是纏繞我最久的,每次出這種錯誤我都到處測試,偶爾莫名其妙就好了,但是一直不知道原因,直到后來我懷疑是不是也是中文字符造成的錯誤,結(jié)果發(fā)現(xiàn),嘿,還真是!

比如錯誤處的代碼是這樣的,在變量 pta2 的上面是一行中文注釋:

# ...# 二象限pta2 = (oX - length * 2, pta[1])# ...

我們使用空行將報(bào)錯的變量和中文注釋隔開:

# ...# 二象限pta2 = (oX - length * 2, pta[1])# ...

于是乎,程序順利運(yùn)行了,原來如果在變量的上一行是中文注釋,有可能會導(dǎo)致下面那一行被工具箱里面的神奇魔法規(guī)則跳過。

自此,困擾我很久、經(jīng)常讓我折騰到深夜的各種暗坑終于有了解決方法。

個人的經(jīng)驗(yàn),希望能對你有所幫助和啟發(fā)。

4.最后和總結(jié)

總結(jié):

  • 工具箱只是一個箱子,其中需要你自己創(chuàng)建腳本工具來實(shí)現(xiàn)各種功能;

  • 腳本工具和 Python 代碼(腳本)兩位一體的,互相配合,腳本工具負(fù)責(zé)圖形界面,Python 腳本專注于功能的實(shí)現(xiàn),最后在工具箱中將兩者結(jié)合起來;

  • 腳本工具添加的圖形界面控件也有多種屬性,最重要的有控制輸入輸出的方向屬性、是否必須的類型屬性,以及其他的偶爾使用的多值默認(rèn)等屬性;

  • GetParameterAsText(index) 方法可從圖形輸入界面獲取參數(shù),不過需要注意的是,返回的結(jié)果全部都是字符串,記得轉(zhuǎn)換如果有必要;

  • 腳本封裝進(jìn)工具箱報(bào)錯多半是由中文引起的,謹(jǐn)記,解決方法參考上文的第三大點(diǎn)。

使用版本:

  • Windows 10

  • PyCharm 2021.2.3

  • ArcGIS 10.3

  • Python 2.7.8

源代碼、教學(xué)文檔離線小冊子下載:

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章