1. 程式人生 > >在ArcGIS中建立Python工具(二)

在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中提供的有關訊息的函式,AddMessageAddWarningAddError等向工具進度條介面傳送訊息。這裡我做了個簡單的步驟的訊息性提示,以及,如果結果沒有記錄輸出,會提示警告。

__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 顯示結果圖層

我進一步希望指令碼工具執行之後,自動顯示在當前的地圖文件中,從而避免重複設定透明度的操作。


  1. 為輸出引數配置模板圖層。

這裡寫圖片描述

  1. 在處理設定中,啟用設定

這裡寫圖片描述

這樣在執行工具之後,結果即自動新增顯示。

這裡寫圖片描述



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 中使用指令碼工具的過程就說到這裡。