ArcGIS Pro SDK 003 如何調用Toolbox

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的輸入指定了這個名稱,會從該數據源中取數據。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章