ArcGIS Python編程案例(7)-創(chuàng)建自定義地理處理工具

第六章 使用腳本執(zhí)行地理處理工具 ||| 第八章 數(shù)據(jù)查詢和選擇


我們在本章介紹以下案例:

  • 創(chuàng)建一個自定義地理處理工具

引言

除了能夠訪問ArcGIS提供的系統(tǒng)工具,我們還可以創(chuàng)建自己的自定義工具。這些工具跟系統(tǒng)工具的工作模式相同,也可以在模型構造器,Python窗口以及獨立的Python腳本中使用。許多組織機構都會創(chuàng)建自定義工具集來專門處理自己的數(shù)據(jù)。

創(chuàng)建一個自定義地理處理工具

除了能夠在腳本中執(zhí)行所有可用的工具,你還可以在腳本中調用自己創(chuàng)建的自定義工具。許多自定義工具來專門用于執(zhí)行組織機構內特定需求的地理處理任務。而且這些工具也很方便共享。

Getting ready

在本案例中,你將學習如何將腳本添加到ArcToolbox下的自定義工具箱中創(chuàng)建自定義地理處理腳本工具。創(chuàng)建自定義腳本工具有很多優(yōu)點。創(chuàng)建完成后,腳本就變成了地理處理框架中的一部分,也就意味著該腳本可以在模型中,命令行或者其他腳本中使用。另外,腳本也就可以獲取ArcMap的環(huán)境設置以及幫助文檔。同時自定義腳本工具能夠提供一個簡單易用的用戶界面以及容錯機制(error-prevention capabilities)。容錯機制會提供一個對話框來通知用戶工具運行中出現(xiàn)的錯誤。
ArcToolbox提供的系統(tǒng)工具箱是只讀的,不能接受新的工具,因此這些自主開發(fā)的腳本工具只能添加到自定義工具箱中。在本案例中,你將會使用一個已編寫好的Python腳本,該腳本會從一個逗號分隔符文本文件(comma-delimited text file)中讀取野外火情數(shù)據(jù),之后將數(shù)據(jù)轉為一個FireIncidents的點要素文件。腳本中需要引用的數(shù)據(jù)集路徑已經(jīng)過硬編碼處理,你需要修改腳本能夠接受動態(tài)變量的輸入。之后將修改后的腳本添加到ArcToolbox中的一個自定義工具中,該工具會為最終用戶提供了一個可視化的界面來執(zhí)行腳本。

How to do it...

你編寫的Python地理處理腳本可以添加到ArcToolbox中的自定義工具箱中。你不能將腳本添加到任何一個系統(tǒng)工具箱中,比如AnalysisData Management。不過,你可以創(chuàng)建一個新的自定義工具箱來添加腳本。
1.打開ArcMap創(chuàng)建一個空白的地圖文檔并打開ArcToolbox窗口。
2.右鍵單擊ArcToolbox內的任何空白位置,選擇添加工具箱(Add Toolbox)。在Add Toolbox對話框中,點擊New Toolbox按鈕。系統(tǒng)會創(chuàng)建一個Toolbox.tbx的工具箱,在下一步中你可以重命名該工具箱:

3.轉到C:\ArcpyBook\Ch7文件夾,在該文件夾下創(chuàng)建一個Wildfire Tools的工具箱:

4.選中Wildfire Tools.tbx文件然后點擊打開(Open)按鈕。如下圖所示,該工具箱就出現(xiàn)在ArcToolbox窗口中了:

5.每一個工具箱都需要給定一個名稱和別名。別名可以用于唯一識別你的自定義工具。別名應該盡量簡短且不包含特殊字符。右鍵單擊新添加的工具箱選擇屬性(Properties)。如下圖所示添加一個wildfire的別名:

你還可以右鍵單擊工具箱選擇新建|工具集(New|Toolset)在工具箱中創(chuàng)建一個新的工具集。工具集可以按照功能來對腳本進行分組。在本案例中,你不需要這么做,不過如果在以后需要對腳本進行分組管理時,你就可以通過創(chuàng)建工具集來完成。

6.接下來,我們需要修改InsertWildfires.py腳本文件使其能夠接受用戶通過ArcToolbox界面提供的動態(tài)輸入?yún)?shù)。在IDLE中打開C:\ArcpyBook\Ch7\InsertWildfires.py文件。你會看到工作空間路徑和包含野火數(shù)據(jù)的逗號分隔文本文件的路徑都是硬編碼處理的:

arcpy.env.workspace = "C:/ArcpyBook/data/Wildfires/WildlandFires.mdb"
f=open("C:/ArcpyBook/data/Wildfires/NorthAmericaWildfires_2007275.txt","r")

7.刪除以上兩行代碼。另外,輸出要素類名稱也是使用硬編碼處理:

cur = arcpy.InsertCursor("FireIncidents")

硬編碼限制了腳本的靈活性。如果數(shù)據(jù)集移動或者刪除了,腳本也就無法運行。除此以外,硬編碼還會讓腳本缺少針對不同輸入和輸出數(shù)據(jù)集要求的靈活性。在下一步中,我們會移除這些硬編碼,讓腳本可滿足動態(tài)輸入?yún)?shù)要求。
8.我們會調用arcpy提供的GetParameterAsText()函數(shù)來接受用戶提供的動態(tài)輸入?yún)?shù)。如下所示,在try語句下添加以下腳本代碼:

try:
    outputFC = arcpy.GetParameterAsText(0)
    fClassTemplate = arcpy.GetParameterAsText(1)
    f = open(arcpy.GetParameterAsText(2),"r")
    arcpy.CreateFeatureclass_management(os.path.split(outputFC)[0],os.path.split(outputFC)[1],"point",fClassTemplate)

你會看到我們調用了Data Management工具箱中的CreateFeatureClass工具,并將outputFC變量和模板要素類(fClassTemplate)變量傳遞給該工具。該工具將會創(chuàng)建一個包含了用戶指定的輸出要素類的空要素類文件。
9.你還需要修改一行用于創(chuàng)建插入游標(InsertCursor)對象的代碼。如下所示:

cur = arcpy.InsertCursor(outputFC)

10.修改后的完整代碼如下:

import arcpy,os
try:
    outputFC = arcpy.GetParameterAsText(0)
    fClassTemplate = arcpy.GetParameterAsText(1)
    f = open(arcpy.GetParameterAsText(2),"r")
    arcpy.CreateFeatureclass_management(os.path.split(outputFC)[0],\
    os.path.split(outputFC)[1],"point",fClassTemplate)    
    lstFires = f.readlines()
    cur = arcpy.InsertCursor(outputFC)
    cntr = 1
    for fire in lstFires:
        if 'Latitude' in fire:
            continue
        vals = fire.split(",")
        latitude = float(vals[0])
        longitude = float(vals[1])
        confid = int(vals[2])
        pnt = arcpy.Point(longitude,latitude)
        feat = cur.newRow()
        feat.shape =pnt.shape
        feat.setValue("CONFIDENCEVALUE",confid)
        cur.insertRow(feat)
        arcpy.AddMessage("Record number: " + str(cntr) + "writen to feature class")
        cntr = cntr + 1
    del feat
    del cur
except:
    print arcpy.GetMessages()
finally:    
    f.close()

接下來,我們將腳本添加到剛剛創(chuàng)建的Wildfire Tools工具箱中。
11.在ArcToolbox中,右鍵單擊之前創(chuàng)建的Wildfire Tools工具箱,選擇添加|腳本(Add|Script)。如下圖所示彈出添加腳本(Add Script)對話框。填寫腳本名稱,標簽以及描述信息。名稱(Name)中不能包含空格以及特殊字符。標簽(Label)信息為腳本工具的顯示名稱。本案例中,標簽設置為Load Wildfires From Text文本。最后,添加一些描述信息來說明腳本執(zhí)行的細節(jié)等。
12.名稱,標簽描述的細節(jié)信息如下圖所示:

13.點擊下一步(Next)按鈕顯示添加腳本的下一個對話框。
14.在該對話框中,你需要制定需要添加到工具中的腳本文件。選擇InsertWildfires.py腳本文件。
15.你還需要勾選在進程中運行Python腳本(Run Python Script in process)。在進程中運行腳本會提高腳本執(zhí)行的速度。

進程外運行Python腳本需要ArcGIS創(chuàng)建一個單獨的進程來執(zhí)行腳本。開啟進程和執(zhí)行腳本的時間會導致腳本運行性能的問題。通常都選擇在進程中運行Python腳本。在進程中運行腳本意味著ArcGIS不需要開啟第二個進程來運行腳本,腳本與ArcGIS運行在同一個進程中。

16.點擊下一步(Next)顯示參數(shù)窗口,如下圖所示:

你在該對話框中輸入的每一個參數(shù)都要與一個單獨的GetParameterAsText()函數(shù)調用相關聯(lián)。在前面,我們已經(jīng)修改過腳本使其接受通過GetParameterAsText()函數(shù)獲取的動態(tài)參數(shù)。該對話框中參數(shù)的輸入的順序應該與腳本中指定接受的順序一致。比如,你在腳本中插入了下面的代碼:

outputFC = arcpy.GetParameterAsText(0)

那么你在參數(shù)對話框中添加的第一個參數(shù)就需要與該行代碼關聯(lián)。在腳本中,outputFC參數(shù)代表運行腳本后創(chuàng)建的要素類。你通過點擊顯示名稱(Display Name)下的第一行來添加參數(shù)。你可以在該位置輸入任意文本,該文本會顯示給用戶。你還需要選擇與該參數(shù)相關聯(lián)的數(shù)據(jù)類型。在本案例中,數(shù)據(jù)類型(Data Type)應該選擇要素類(Feature Class)。每一個參數(shù)都有一些屬性可以設置。其中比較重要的屬性包括類型(Type),方向(Direction)以及默認值(Default)。
17.如下圖所示在對話框中輸入輸出要素類的信息。確保方向(Direction)屬性設置為Output

18.接下來,我們需要添加一個作為輸出要素類屬性模板的要素類參數(shù)。如下圖所示輸入信息:

19.最后,我們還需要添加一個指定逗號分隔符文本文件的參數(shù),該文本文件用于創(chuàng)建要素類的輸入?yún)?shù)。如下圖所示輸入信息:

20.點擊完成(Finish)按鈕。如下圖所示,一個新的腳本工具就會添加到Wildfire Tools工具箱中:

21.現(xiàn)在我們來測試工具是否可用。雙擊腳本工具彈出如下圖所示對話框:

22.定義一個輸出要素類文件。點擊打開文件圖標找到C:\ArcpyBook\data\Wildfires中的WildlandFires.mdb個人數(shù)據(jù)庫。
23.你還需要指定一個輸出要素類的名稱。在本案例中,我們將輸出要素類命名為TodayWildfires,當然你可以命名為你喜歡的名稱。點擊保存(Save)按鈕。

24.對于屬性模板,你需要指向已經(jīng)創(chuàng)建好的FireIncidents要素類。該要素類包含了一個CONFIDENCEVAL的字段,該字段也會在輸出要素類中創(chuàng)建。點擊瀏覽(Browse)按鈕,選擇C:\ArcpyBook\data\Wildfires\WildlandFires.mdb中的FireIncidents要素類文件。點擊添加(Add)按鈕。
25.最后一個參數(shù)需要指向一個包含野外火情數(shù)據(jù)的逗號分隔符文本文件。點擊瀏覽(Browse)按鈕,選擇C:\ArcpyBook\data\Wildfires中的
NorthAmericaWildfire_2007275.txt文件。點擊添加(Add)按鈕。
以上參數(shù)選擇完成后,工具界面如下所示:

26.點擊確定(OK)按鈕。如下圖所示,消息會出現(xiàn)在對話框中。這是一個標準的地理處理工具對話框。如果所有參數(shù)設置正確,如下圖所示你將看到新的要素類創(chuàng)建完成的提示消息:

如下圖所示,新創(chuàng)建的要素類添加到ArcMap顯示窗口中:

How it works...

幾乎所有的腳本都帶有參數(shù),用戶需要在工具對話框中提供所需的參數(shù)值。工具執(zhí)行時,參數(shù)值傳遞給腳本。腳本讀取這些參數(shù)值后在進行處理。Python腳本可以將參數(shù)作為輸入值。參數(shù)可以讓腳本接受動態(tài)參數(shù)值。在這之前,我們所有的腳本都是采用硬編碼值。通過指定腳本的輸入?yún)?shù),你就可以在腳本運行時再獲取參數(shù)值。這一功能讓腳本變得更為靈活。
GetParameterAsText()函數(shù)用于獲取輸入?yún)?shù)值,該函數(shù)從零值開始索引參數(shù)在參數(shù)列表中的位置,即第一個參數(shù)占據(jù)索引位置0。每一個后續(xù)參數(shù)索引值遞增加1。輸出要素類是通過讀取逗號分隔符文本文件來創(chuàng)建并將其賦值給變量outputFC,該參數(shù)通過GetParameterAsText(0)語句獲取。使用語句GetParameterAsText(1),我們獲取了作為輸出要素類屬性模板的一個要素類參數(shù)。該模板要素類中的字段將會用于定義輸出要素類中的字段。最后GetParameterAsText(2)語句會創(chuàng)建一個變量f,該變量用于保存要讀取的逗號分隔符文本文件。

There's more...

arcpy.GetParameterAsText()函數(shù)并非獲取信息傳遞給腳本的唯一方式。當你從命令行調用Python腳本,你可以傳遞一組參數(shù)(argument)。當向腳本傳遞參數(shù)時,每個參數(shù)必須使用空格隔開。這些參數(shù)保存在一個基于sys.argv的列表對象中。使用sys.argv引用索引值0來引用列表中的第一個元素,該元素用于保存腳本名稱。每一個后續(xù)的參數(shù)索引值依次遞增加1。因此,第一個參數(shù)保存在sys.argv[1]中,第二個參數(shù)保存在sys.argv[2]。這些參數(shù)可以通過腳本來獲取。
建議大家使用GetParameterAsText()函數(shù),這是因為前者沒有字符數(shù)量的限制而后者則要求每個參數(shù)要小于1024個字符。不管使用哪種方式,參數(shù)讀入后,腳本會作為輸入值繼續(xù)執(zhí)行。


第六章 使用腳本執(zhí)行地理處理工具 ||| 第八章 數(shù)據(jù)查詢和選擇

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容