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

第六章 使用腳本執行地理處理工具 ||| 第八章 數據查詢和選擇


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

  • 創建一個自定義地理處理工具

引言

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

創建一個自定義地理處理工具

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

Getting ready

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

How to do it...

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

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

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

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

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

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

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

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

cur = arcpy.InsertCursor("FireIncidents")

硬編碼限制了腳本的靈活性。如果數據集移動或者刪除了,腳本也就無法運行。除此以外,硬編碼還會讓腳本缺少針對不同輸入和輸出數據集要求的靈活性。在下一步中,我們會移除這些硬編碼,讓腳本可滿足動態輸入參數要求。
8.我們會調用arcpy提供的GetParameterAsText()函數來接受用戶提供的動態輸入參數。如下所示,在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)變量傳遞給該工具。該工具將會創建一個包含了用戶指定的輸出要素類的空要素類文件。
9.你還需要修改一行用于創建插入游標(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()

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

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

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

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

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

outputFC = arcpy.GetParameterAsText(0)

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

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

19.最后,我們還需要添加一個指定逗號分隔符文本文件的參數,該文本文件用于創建要素類的輸入參數。如下圖所示輸入信息:

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

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

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

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

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

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

How it works...

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

There's more...

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


第六章 使用腳本執行地理處理工具 ||| 第八章 數據查詢和選擇

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內容