在ArcGIS中建立Python工具(二)
上一篇中我們瞭解到有兩種方式在 ArcGIS 中建立 Python工具,這一篇就來看看如何在標準工具箱中建立指令碼工具。
ArcGIS Help 中指令碼工具的幫助過於枯燥,在這裡,我以一個具體的例項來總結構建指令碼工具的過程,我要實現的需求是做個快速實現羽化邊界效果的小工具,預期得到如下的效果:
上面效果在ArcMap中完全可以手工執行幾個工具實現,但是過程稍微繁瑣,那麼需求來了,如何做個自定的一鍵生成羽化邊界的小工具?
1 準備Python指令碼檔案
第一步,先寫好指令碼工具的核心 —— python指令碼檔案。
指令碼中我希望根據指定環間距自動生成一個9環的緩衝面,然後新增一個欄位,用於儲存給各個緩衝面的透明度百分比。
看下圖就知道我想做什麼了:
寫一個py檔案,將要用到的工具串聯起來實現自己的需求,大致是下面的樣子。這不是最終要做成指令碼工具的版本,只是為了預先了解要如何實現,後面還要修改。
__author__ = 'kikita'
# FileName: EasyFeathering.py
import arcpy
# arcpy.env.workspace = "D:\something\Data.gdb"
# Script Tool Parameters
InputFeature = "InterestArea"
OutputFeature = "OutFeathering"
SingleRingWidth = 10000
# Some Predefined Parameters
distances = []
level = 9
bufferUnit = "meters"
NewField = "Percent"
# My Easy Feathering function
for i in range(level):
distances.append(SingleRingWidth*(i+1))
i = i+1
print str(distances)
print "Distance Complete!"
arcpy.MultipleRingBuffer_analysis(InputFeature, OutputFeature, distances, bufferUnit, "" , "ALL","OUTSIDE_ONLY")
print "Success to execute Multi Ring Buffer."
arcpy.AddField_management(OutputFeature,NewField,"double")
print "Success to add Transparency Percent Field."
arcpy.CalculateField_management(OutputFeature, NewField, "!OBJECTID! *10", "PYTHON", "")
print "Success to Calculate Transparency Percent Field."
2 指令碼工具引數配置
有了py檔案之後,如何把它塞進工具箱裡呢?
在ArcMap的Catalog視窗中,找一個自己喜歡的任意資料夾,新建一個Toolbox,然後右鍵 Add –> Script,進入嚮導,這些操作如果不瞭解,可以點 這裡 查查幫助,照著做即可,不贅述。
這裡我主要說說引數傳遞。
我希望做好的工具中,我只去指定三個引數,分別是:輸入的興趣區域面(input Feature ),多環緩衝的環間距(Single Ring width ),輸出結果(output Feature )。預覽下工具介面:
那麼問題又來了,這三個引數如何從工具介面傳給真正執行工具的 python 指令碼?我們需要對前面的指令碼引數定義部分做個修改,使用 arcpy 提供的 GetParameterAsText()
函式即可在工具介面和指令碼之間傳遞引數。用下面的程式碼替換前面對這三個引數的替換:
# Script Tool Parameters
InputFeature = arcpy.GetParameterAsText(0)
SingleRingWidth = arcpy.GetParameterAsText(1)
OutputFeature = arcpy.GetParameterAsText(2)
對應的指令碼工具引數配置:
為工具配置引數的時候,有2個原則需要遵守:
- 工具對話方塊中的引數順序必須與指令碼中的引數順序一致。
- 每個指令碼工具引數都有關聯的資料型別。ArcGIS的地理處理不會將值傳送給資料型別不正確的指令碼,從這點上看,指令碼工具比下一篇要說到的指令碼工具箱多了一個優勢,就是,在引數值傳送給指令碼之前會有資料型別檢驗。
修改Python指令碼檔案後,現在就執行工具,發現可以得到預期的結果:
但是有點不完美,就是在工具的執行過程中,工具給我返回的資訊並不充足,我只知道 “Running Script EasyFeathering …”,而不瞭解工具在做什麼,執行到了哪個步驟。這不是好的體驗。
3 訊息
工具和使用者之間的所有溝通均通過訊息來實現。接著上一步提出的問題,如何在工具進度視窗中傳遞訊息給使用者?
雖然在開始除錯指令碼的時候,如開頭程式碼所示,我加了些 Print 語句,方便我瞭解自己的指令碼獨立執行時的狀態,但是如果執行指令碼工具,這些print語句是看不到的。可以使用 ArcPy中提供的有關訊息的函式,AddMessage
、AddWarning
、AddError
等向工具進度條介面傳送訊息。這裡我做了個簡單的步驟的訊息性提示,以及,如果結果沒有記錄輸出,會提示警告。
__author__ = 'kikita'
# FileName: EasyFeathering.py
import arcpy
#arcpy.env.workspace = "D:\IncidentSupport2015\something\Data.gdb"
# Get the input values from tool UI
InputFeature = arcpy.GetParameterAsText(0)
SingleRingWidth = arcpy.GetParameterAsText(1)
OutputFeature = arcpy.GetParameterAsText(2)
# Some Predefined Parameters
distances = []
level = 9
bufferUnit = "meters"
NewField = "Percent"
# My Easy Feathering function
for i in range(level):
distances.append(int(SingleRingWidth)*(i+1))
i = i+1
arcpy.AddMessage("Step1 Distance list Complete!")
arcpy.MultipleRingBuffer_analysis(InputFeature, OutputFeature, distances, bufferUnit, "", "ALL","OUTSIDE_ONLY")
arcpy.AddMessage("Step2 Success to execute Multi Ring Buffer.")
arcpy.AddField_management(OutputFeature,NewField,"double")
arcpy.AddMessage("Step3 Success to add Transparency Percent Field.")
arcpy.CalculateField_management(OutputFeature, NewField, "!OBJECTID! *10", "PYTHON", "")
InputFeatureCount = int(arcpy.GetCount_management(OutputFeature).getOutput(0))
if InputFeatureCount == 0:
arcpy.AddWarning("{0} has no features.".format(OutputFeature))
else:
arcpy.AddMessage("Step4 Success to Calculate Transparency Percent Field.")
這樣在工具的執行過程中,我就收到了訊息:
到這裡,工具的功能部分就完成了。
4 顯示結果圖層
我進一步希望指令碼工具執行之後,自動顯示在當前的地圖文件中,從而避免重複設定透明度的操作。
- 為輸出引數配置模板圖層。
- 在處理設定中,啟用設定
這樣在執行工具之後,結果即自動新增顯示。
5 配置路徑
如果是在本機使用指令碼工具,一般我們會使用絕對路徑,但是如果希望分享自己的工具給別人,就要考慮路徑問題,也就是新使用者執行指令碼工具時,相關的指令碼檔案和其他用到的資源能否訪問到。我的工具按照如下的結構組織:
在指令碼工具的屬性中,可以配置儲存相對路徑引用 py 檔案:
PS:但是不要想太多,這個設定僅僅會將指令碼檔案所在位置按照相對路徑儲存,而不會將指令碼內部的路徑進行轉換。
這個示例中我還需要用到一個圖層檔案作為模板,如果希望使用相對路徑使用,就建議將符號化資訊寫在指令碼內部,而不是在引數視窗中配置。所以,要繼續修改下Python指令碼檔案。
在指令碼檔案的最後追加兩行程式碼,我這裡將獲取與Python指令碼檔案在相同目錄下的lyr檔案:
# Layer files are located in same folder as the .py file
PythonFilePath = os.path.dirname(__file__)
params = arcpy.GetParameterInfo()
params[2].symbology = os.path.join(PythonFilePath, "FeatheringEffectTemplate.lyr")
# Pass message
arcpy.AddMessage("Finding Feathering Effect Template Layer ..." +"/n"+ os.path.join(PythonFilePath, "FeatheringEffectTemplate.lyr"))
OK,路徑的問題就解決了。
6 幫助文件
還可以進一步為工具新增幫助文件,讓更多的人瞭解如何使用這個工具。
在ArcCatalog 或者ArcMap的Catalog 中,在指令碼工具上右鍵,點選 Item Description 選單,點選 Edit 就可以對工具的幫助文件進行編輯。
這樣當別人開啟你的工具時,就看到幫助嘍。
好啦,關於ArcGIS 中使用指令碼工具的過程就說到這裡。