ArcGIS Pro SDK 003 如何呼叫Toolbox

mytudousi發表於2023-02-22

1、如何呼叫普通的Tool

ArcGIS中的Toolbox非常強大,做二次開發的時候,必不可少的會呼叫,在ArcObjects SDK中,每個Tool都會有自定義的類對應,例如柵格轉向量資料,定義在ESRI.ArcGIS.ConversionTools.dll程式集中,對用的類為RasterToPolygon。而在ArcGIS Pro SDK中就沒這樣的類定義了,就需要傳入字串格式的工具名稱,指定執行哪個工具。引數也無法使用物件.屬性的方式設定,而是以陣列的方式設定。

我們在ArcObjects SDK中,呼叫柵格轉向量工具的程式碼如下。

var myRasterToPolygon = new RasterToPolygon
{
    in_raster = myWatershed.out_raster,
    out_polygon_features = FilePathHelper.GetTempShapeFilePath("RasterToPolygon_")
};
myGPEx.Execute(myRasterToPolygon);

在ArcGIS Pro SDK中,呼叫該工具的方法如下所示。

myParameters = Geoprocessing.MakeValueArray(myWatershedOutFile, myWatershedPolygonOutFile, "Value");
myGPResult = await Geoprocessing.ExecuteToolAsync("conversion.RasterToPolygon", myParameters);

Geoprocessing.MakeValueArray用來設定引數,Geoprocessing.ExecuteToolAsync函式用來執行工具。該函式的第一個引數就是工具的名稱,第二個引數是執行工具設定的引數資訊,還有第三個引數是對環境的設定,如果不需要對環境進行特殊設定,忽略該引數即可。

因為沒有類定義,並不好確認要傳入的工具名稱、到底要設定哪些引數、引數的順序以及是否要進行環境設定等資訊。此時我們就要藉助ArcGIS Pro桌面軟體、幫助甚至ArcObjects SDK中對應工具的定義。

還是以RasterToPolygon為例,我們可以先在ArcGIS Pro桌面軟體上找到該工具,並開啟,如下圖所示。

截圖.png

點選右上角?號,可以進入該工具的幫助頁面,如下圖所示。

截圖.png

其中紅框中的內容就是工具的名稱,我們透過ArcGIS Pro sdk呼叫的時候,傳入該名即可。引數以及設定的順序可以透過函式引數獲取。其中{}內的引數為可選引數。在下面表格中,還有一些引數說明,寫的也比較清晰。這樣我們就能明白如何設定引數了。

2、不能設定輸出檔案引數的特殊情況

有些工具是有特殊情況的,例如柵格掩膜工具ExtractByMask。在ArcGIS Pro桌面軟體下,其介面如下圖所示。

截圖.png

引數包括輸入柵格、掩膜資料以及輸出柵格等。點選幫助,切換到Python下,看到的程式碼如下所示。

ExtractByMask(in_raster, in_mask_data, {extraction_area}, {analysis_extent})

這個就比較特殊了,感覺也有可能是幫助沒有寫好,缺引數,輸出柵格資料在哪設定?並且工具名稱前也沒有加模組的名稱,這樣我們就不知道怎麼呼叫了。

再接著看下面的python例子程式碼,如下所示。

import arcpy
from arcpy import env
from arcpy.sa import *
env.workspace = "C:/sapyexamples/data"
outExtractByMask = ExtractByMask("elevation", "mask.shp", "INSIDE")
outExtractByMask.save("C:/sapyexamples/output/maskextract")

這樣就清楚一些了,ExtractByMask工具輸入sa模組,我們呼叫的時候,工具名稱寫sa.ExtractByMask。執行的時候,並沒有設定輸出檔案儲存的目錄,而是返回輸出結果,呼叫輸出結果的save函式儲存處理的結果資料。這不太符合我們的使用習慣,獲取在ArcGIS Pro SDK中,也這樣設定引數,最後用GPResult可以把輸出結果儲存起來。

但我沒有做這樣的測試,是否可行也不清楚。

我感覺還是可以在引數裡面設定輸出結果檔案路徑的,於是我去ArcObjects SDK中去查詢ExtractByMask類的定義,如下圖所示。

截圖.png

ArcObjects SDK中的ExtractByMask只有三個引數,看來ArcGIS Pro對該工具進行了擴充套件,增加了一些引數。既然第三個引數是輸出的柵格資料,那麼我們也在ArcGIS Pro SDK中的ExtractByMask第三個引數設定輸出柵格資料試試。程式碼如下。

string myExtractByMaskOutFile = this._TempFolder.GetTempFilePath(".tif", "ExtractByMask_");
myParameters = Geoprocessing.MakeValueArray(this.DEMFilePath, this.ClipFile, myExtractByMaskOutFile);
myGPResult = await Geoprocessing.ExecuteToolAsync("sa.ExtractByMask", myParameters);

執行了一下,可以正確執行,輸出結果也出來了。這就感覺比較奇怪,看幫助的話,第三個引數應該是可選引數extraction_area,感覺幫助和實際功能有些不一致,不過出來就可以了,沒再深究問題出在哪裡。

如果實在出不來的話,估計我就要想辦法看怎麼透過GPResult把結果儲存成檔案,或者直接寫pothon程式碼去執行了。

3、輸出資料只能設定名稱的情況

這種情況是我在呼叫MakeXYEventLayer時候遇到的,其在ArcGIS Pro中的介面如下圖所示。

截圖.png

這個地方是設定圖層名稱,而不是儲存的資料路徑。但實際上,我是想把XY資料,匯出成Shape檔案儲存下來的。如果在ArcGIS pro中操作,預設會把結果作為圖層新增到地圖上,我們再把該圖層匯出成Shape檔案就可以了。

如果在SDK中,該如何處理呢?

該工具python相關的幫助中的python程式碼如下。

import arcpy
arcpy.env.workspace = "C:/data"
arcpy.MakeXYEventLayer_management("firestations.dbf", "POINT_X", "POINT_Y","firestations_points", "", "POINT_Z")

我在測試的時候,後面是跟了一個CopyFeatures工具,就是把MakeXYEventLayer輸出的圖層,儲存到指定目錄下,並且為.shp格式。沒注意到底是否生成成功。

後面檢查的時候,發現我在MakeXYEventLayer工具中指定輸出的檔案並沒有生成成功,但CopyFeatures的輸出確是存在的。後來發現只要把設定一個隨機的圖層名稱,在CopyFeatures呼叫的時候,輸入這個隨機名稱,就可以執行成功,程式碼如下所示。

string myOutLyrName = "XY_" + Guid.NewGuid().ToString();
myParameters = Geoprocessing.MakeValueArray(myOutTableFile, "NEAR_X", "NEAR_Y", myOutLyrName);
myGPResult = await Geoprocessing.ExecuteToolAsync("management.MakeXYEventLayer", myParameters);
if (myGPResult.IsFailed)
{
    throw new ArgumentException("生成圖層," + myGPResult.ErrorMessages.First().Text);
}
//複製要素
pProcessInfo.SetProcess(98, "正在複製結果資料...");
myParameters = Geoprocessing.MakeValueArray(myOutLyrName, this.OutputPointFile);
myGPResult = await Geoprocessing.ExecuteToolAsync("management.CopyFeatures", myParameters);
if (myGPResult.IsFailed)
{
    throw new ArgumentException("複製結果," + myGPResult.ErrorMessages.First().Text);
}

對這個問題,我沒太往下深入研究,感覺應該是系統把資料生成到了一個預設工作空間下,CopyFeatures的輸出指定了這個名稱,從預設工作空間下去找這個資料,但我再預設的gdb下並沒有找到。

也可能是,該結果圖層資料以記憶體的形式存在了ArcGIS pro當前預設的地圖資料來源中,CopyFeatures的輸入指定了這個名稱,會從該資料來源中取資料。

具體什麼原因,目前還不是太清楚,但確實這麼處理是成功的。

相關文章