GP的使用心得


在ArcEngine時,GP無疑是GIS開發者的神器。自ArcEngine9.2開始新增一個程序集ESRI.ArcGIS.Geoprocessor,它能調用包含擴展模塊在內的所有Geoprocessing工具。關於GP的使用問題,做如下總結:

1.許可問題

大家都知道,AE二次開發有兩種許可定義方式:一是直接拖放License控件,右鍵設置其屬性,另一種方式是使用IAoInitialize接口實現。但兩者只需一種即可,建議使用后者。Program.cs文件Main函數中初始代碼示例:

//綁定Runtime
if (!RuntimeManager.Bind(ProductCode.Engine))
{
    if (!RuntimeManager.Bind(ProductCode.Desktop))
    {
        MessageBox.Show("不能綁定ArcGIS Runtime,應用程序即將關閉!");
        return;
    }
}

//初始化Advanced許可,還有Standard,Engine,Basic等
esriLicenseStatus licenseStatus = esriLicenseStatus.esriLicenseUnavailable;
IAoInitialize m_AoInitialize = new AoInitialize();
licenseStatus = m_AoInitialize.Initialize(esriLicenseProductCode.esriLicenseProductCodeAdvanced);
//檢查擴展模塊功能
licenseStatus = m_AoInitialize.CheckOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeSpatialAnalyst);

  

2.概念區分

Geoprocessor與Geoprocessing有什么區別?

Geoprocessing是GIS三大視角之一,能夠通過分析處理已存在的數據,在新的數據集中產生結果。可以簡單地理解為ToolBoxs中的工具。

Geoprocessor是ArcEngine9.2新增的一個基於NET Framework2.0的托管類,所有的Geoprocessing工具,包括擴展工具,都是由Geoprocessor對象調用運行,Geoprocessor能夠通過設置不同的環境參數,簡化執行Geoprocessing工具的過程,並返回相應的處理結果。(來看《插件式GIS應用框架的設計與實現——基於C#和ArcGIS Engine9.2》,這是一本不錯的書!)

所以,一般地,在進行開發調用GP之前要添加Geoprocessor和Geoprocessing兩個引用:

using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.Geoprocessing;

  

3.尋找工具

在哪里去尋找我們需要的工具呢?

第一步,首先在ToolBox里找到要使用的工具,最好利用該工具測試一下實驗數據,確保其正確性。工具右鍵屬性可看到其英文名稱。

第二步,去ESRI幫助中查找工具參數。在其中我們可以看到有哪些參數,分別是什么類型、含義,如果不知道怎么填寫,可參考Python例子。

工具名稱及對應命名空間:

AE/AO開發工具與全名空間對應表

工具名稱

命名空間

3D Analyst tools

ESRI.ArcGIS.Analyst3DTools

Analysis tools

ESRI.ArcGIS.AnalysisTools

Conversion tools

ESRI.ArcGIS.ConversionTools

Data Management tools

ESRI.ArcGIS.DataManagementTools

Cartography tools

ESRI.ArcGIS.CartographyTools

Coverage tools

ESRI.ArcGIS.CoverageTools

Geocoding tools

ESRI.ArcGIS.GeocodingTools

Geostatistical Analyst tools

ESRI.ArcGIS.GeostatisticalAnalystTools

Linear Referencing tools

ESRI.ArcGIS.LinearReferencingAnalystTools

Multidimension tools

ESRI.ArcGIS.MultidimensionTools

Network Analyst tools

ESRI.ArcGIS.NetworkAnalystTools

Samples

ESRI.ArcGIS.SamplesTools

Spatial Analyst tools

ESRI.ArcGIS.SpatialAnalystTools

Spatial Statistics tools

ESRI.ArcGIS.SpatialStatisticsTools

第三步,查看它在哪個工具大類下,添加對應的引用,設置參數,調試運行即可。下表是EsriLicenseProduct,關於擴展許可詳見esriLicenseExtensionCode

許可

代碼

描述

esriLicenseProductCodeEngine

10

Engine Product Code

esriLicenseProductCodeEngineGeoDB

20

Engine Enterprise GeoDatabase

esriLicenseProductCodeArcServer

30

ArcServer Product Code

esriLicenseProductCodeBasic

40

Basic Product Code

esriLicenseProductCodeStandard

50

Standard Product Code

esriLicenseProductCodeAdvanced

60

Advanced Product Code

4.調用方式

以使用Buffer為例,調用GP實現緩沖區分析的方式:

方式一:實例化GP對象

//初始化GP
Geoprocessor GP = new Geoprocessor();
//初始化Buffer
ESRI.ArcGIS.AnalysisTools.Buffer buffer = new ESRI.ArcGIS.AnalysisTools.Buffer();
buffer.in_features = @"D\data\temp.gdb\road";
buffer.out_feature_class = @"D\data\temp.gdb\road_bf30";
buffer.buffer_distance_or_field = 30; //默認單位
//執行工具
GP.Execute(buffer, null);

  

方式二:VariantArray傳遞參數

Geoprocessor GP = new Geoprocessor();
GP.AddToolbox(@"C:\Program Files (x86)\ArcGIS\Desktop10.1\ArcToolbox\Toolboxes\Analysis Tools.tbx");
//使用IVariantArray傳遞參數
IVariantArray array = new VarArrayClass();
array.Add(@"D\data\temp.gdb\road");
array.Add(@"D\data\temp.gdb\road_bf30");
array.Add(30);
GP.Execute("Buffer", array, null);

  

當然,定義GP對象也有兩種方法:一是通過引用ESRI.ArcGIS.Geoprocessing命名空間,使用IGeoProcessor2接口定義,注意其中的P是大寫;二是使用Geoprocessor類。

private static IGeoProcessor2 GP = new GeoProcessorClass(); // using ESRI.ArcGIS.Geoprocessing;
private static Geoprocessor GP = new Geoprocessor(); // using ESRI.ArcGIS.Geoprocessor;

  

5.調試函數

如果參數設置正確,能夠輸出想要的結果,如果設置錯誤,則不能輸入結果,也不知哪里錯了,這是寫了一個調試的函數。

/// <summary>
/// 執行GP
/// </summary>
/// <param name="mGP">GP對象</param>
/// <param name="process">GP工具</param>
/// <param name="TC"></param>
/// <returns>處理結果</returns>
public static IGeoProcessorResult Execute(Geoprocessor mGP, IGPProcess process, ITrackCancel TC)
{
    tGeoResult = null;
    mGP.OverwriteOutput = true; // 是否覆蓋
    try
    {
       tGeoResult = (IGeoProcessorResult)mGP.Execute(process, null);
       ReturnMessages(mGP);
    }
    catch (System.Exception ex)
    {
        MessageBox.Show(ex.Message+"\n\n"+ex.StackTrace);
        ReturnMessages(mGP); //當調試正確后注釋本行
    }
    return tGeoResult;
}
 
private static void ReturnMessages(Geoprocessor gp)
{
    string ms = "";
    if (gp.MessageCount > 0)
    {
        for (int Count = 0; Count <= gp.MessageCount - 1; Count++)
        {
            ms +="$"+ gp.GetMessage(Count) + "\n\n";
        }
    }
    MessageBox.Show(ms);
}

  

修改GP的執行:

//執行工具
Execute(GP,buffer,null); // GP.Execute(buffer, null);

  

6.運行結果

除了使用IGeoProcessorResult接口獲取GP處理結果外,還可以直接將GP的輸出結果寫入FeatureClass中,方便進行使用。

IGeoProcessorResult的一個重要屬性是ReturnValue,用於返回執行結果,使用示例:

IGeoProcessorResult result=Execute(GP,buffer,null);
IFeatureClass mFeatureClass=GP.Open(result.ReturnValue);

  

7.設置環境

每個GP工具都有自己的執行參數,其中有些參數是很工具都有的,如容差、輸入、輸出位置都是有的,像ArcMap中一樣,在進行地理處理前要進行環境的設置。

使用setEnvironmentValue方法來設置環境變量的值,使用getEnvironmentValue方法來獲取當前環境變量的值。例如:

 

//獲取和設置環境:單元格大小
String env = (String) gp.getEnvironmentValue("cellsize");
GP.setEnvironmentValue("cellsize", Double.valueOf(10.0));
// 設置輸出坐標系統
gp.setEnvironmentValue("outputCoordinateSystem", "c:/Program Files/ArcGIS/Coordinate Systems/Projected Coordinate Systems/UTM/Nad 1983/NAD 1983 UTM Zone 21N.prj");
// 重置
GP.resetEnvironments();

8.批量處理

GeoProcessor類為我們提供了一些提取數據的方法,即通過list來獲取數據庫中數據名稱,結果是字符串,通過獲取的路徑再進行GP調用等操作:

listDatasets (string wildCard, string datasetType)

listFeatureClasses (string wildCard, string featureType, string dataset)

listRasters (string wildCard, string rasterType)

listTables (string wildCard, string tableType)

listToolboxes(string wildCard)

listWorkspaces (string wildCard, string workspaceType)

/// <summary>
/// 要素篩選
/// </summary>
/// <param name="filePath">數據庫位置</param>
/// <param name="featureType">文件類型,可填寫Point,Polyline,Polygon等</param>
/// <param name="wildCard">擴展通配符</param>
/// <param name="dataset">要素集</param>
/// <returns></returns>
public static List<string> FeatureClassFilter(string filePath,string wildCard, string featureType,string dataset)
{
    lstWorkspace.Clear();
    GP.SetEnvironmentValue("workspace", filePath);
    IGpEnumList featureClasses = GP.ListFeatureClasses(wildCard,featureType,dataset);
    string featureClass = featureClasses.Next();
    while(featureClass!="")
    {
        lstWorkspace.Add(featureClass.ToString());
        featureClass = featureClasses.Next();
    }
    return lstWorkspace;
}

  

調用方法:

FeatureClassFilter(@"D\data\temp.gdb", "P*", "poInt", "net");

  

此句的含義是遍歷獲取temp.gdb中net數據集下名為p開頭的點層要素。

當然也可以通過IGPUtilities類直接打開要素層或要素類等。

IFeatureClass mFeatureClass=gpUtilities.OpenFeatureClassFromString(dataPath);

  

9.注意事項

(1)數據的測試

GP工具對輸入、輸出參數要求嚴格,因此首先要保證數據沒有問題,可以先在ArcGIS中調用ArcToolBox進行操作,如果能正常執行,則說明數據基本沒有問題。除數據本身名,還要注意數據的命名(不要出現中文的符號)、使用權限等問題。

(2)參數有多個值的設置

有的GP工具有多個輸入,如聯合(Union),如將數據庫中的P1和P2進行聯合操作,其輸入要素要用分號隔開。

union.in_features = @"D\temp.gdb\P1;D\temp.gdb\P2";

  

如果已設置GP的默認數據庫,可直接寫成如下形式:

union.in_features = " P1; P2";

  

(3)"重分類"分類表設置

有的GP工具參數比較特殊,需要進行特別處理,可參考幫助文檔中Python示例,如重分類工具,其重分類表參數設置如下:

Reclassify rc = new Reclassify();
rc.reclass_field = "Value";
rc.remap = "0.0 2.0 1; 2.0 2.5 2; 2.5 3.0 3 ";
……

  

即將原來的0-2重分類為1,原來2-2.5重分類為2,原來2.5-3重分類為3,同一類別的上限和下限用空格隔開,不同類別用分號隔開。

(4)"添加XY數據"的查找

我們經常將文本文件中的坐標數據轉到ArcMap中的點,需要使用 "添加xy數據"工具,通常會選擇"文件"-"添加數據"-"添加XY數據",這時,它屬性哪個工具箱的呢?可以通過搜索的功能來查找它應該引用的類庫。它在ToolBox中叫"創建XY事件圖層"。當然,有些工具ToolBox是沒有的,再怎么搜索也找不到,如"文件"-"共享為"-"服務"。

(5)"添加XY數據"的輸出

工具"添加XY數據"的輸出比較特殊,由此工具創建的是臨時圖層,需要保存,在ArcMap中右鍵導出結果即可,在ArcEngine中調用GP工具CopyFeatures(復制要素),FeatureToPoint(要素轉點)或FeatureClassToFeatureClass(要素類轉要素類)可導出為對應的圖層。

(6)OpenRasterLayerFromString

IGPUtilities接口的OpenRasterLayerFromString函數總是不能得到結果,所以,只能使用IWorkspaceFactory接口來打開數據庫中的柵格數據。示例代碼:

/// <summary>
/// 打開柵格
/// </summary>
/// <param name="path">文件路徑</param>
/// <param name="name">文件名</param>
/// <returns>柵格圖層</returns>
public static IRasterLayer GetRater(string path, string name)
{
    IWorkspaceFactory mWSF = new RasterWorkspaceFactoryClass();
    IRasterWorkspace mRasterWorkspace = mWSF.OpenFromFile(path, 0) as IRasterWorkspace;
    IRasterDataset mRasterDataset = mRasterWorkspace.OpenRasterDataset(name);
 
    //創建rasterlayer從RasterDataset
    IRasterLayer mRasterLayer = new RasterLayerClass();
    mRasterLayer.CreateFromDataset(mRasterDataset);
    return mRasterLayer;
}

  

(7)參數值的靈活設置

在使用ArcMap中的工具時,有的工具參數需要靈活的設置,不能固化。

如做緩沖區分析,緩沖的半徑為圖層范圍最大值,不同的圖層,其值則不相同,所以,讀取到變量中,再進行緩沖區分析。

private void BufferBounding500()
{
     //讀取范圍,設置半徑
    IGeoDataset pGeodataset = gpUtilities.OpenFeatureClassFromString(gdbPath + filename+"_xy") as IGeoDataset;
    IEnvelope pEnvelope = pGeodataset.Extent;
    double distance = Max(pEnvelope.XMax - pEnvelope.XMin, pEnvelope.YMax - pEnvelope.YMin);
     //緩沖區分析
    ESRI.ArcGIS.AnalysisTools.Buffer bf = new ESRI.ArcGIS.AnalysisTools.Buffer();
    bf.in_features = gdbPath + fileName + "_sp";
    bf.buffer_distance_or_field = distance + " Degrees"; //注意設置緩沖半徑的單位
    bf.out_feature_class = gdbPath + fileName + "_bf500";
    RunGPTool(GP, bf, null);
}

  

再如,做Kriging插值時,其參數"輸出單元格大小"默認情況下是插值點范圍的最大值除以250,但在實際中,這樣的插值結果顯示效果不很理想,因此,一般都是改為除以2500才比較合適。當然輸出單元格大小越小,使用的內存和耗時就更多!

(8)裁剪柵格的范圍參數

裁剪柵格Clip的rectangle參數需要設置為輸出范圍圖層的四至。

 

private void ClipRaster()
{
    IGeoDataset pGeodataset = gpUtilities.OpenFeatureClassFromString(gdbPath + fileName + "_ clip") as IGeoDataset;
    IEnvelope pEnvelope = pGeodataset.Extent;
    //順序:X 最小值、Y 最小值、X 最大值和 Y 最大值
    string strEnvelope = pEnvelope.XMin.ToString() + "" + pEnvelope.YMin.ToString() + "" + pEnvelope.XMax.ToString() + "" + pEnvelope.YMax.ToString();
    ESRI.ArcGIS.DataManagementTools.Clip cp = new ESRI.ArcGIS.DataManagementTools.Clip();
    cp.in_raster = gdbPath + fileName + "_krg";
    cp.in_template_dataset = gdbPath + fileName + "_ clip";
    cp.rectangle = strEnvelope;
    cp.clipping_geometry = "true";
    cp.out_raster = gdbPath + fileName + "_re";
    RunGPTool(GP, cp, null);
}

(9)按位置選擇

按位置選擇工具的輸入必須是要素圖層;不可以是要素類。所在在調用工具之前,需要先使用MakeFeatureLayer來創建要素圖,詳見: GP開發示例:數據庫去重
 
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM