ArcGIS Engine使用GP工具

     在ArcGIS Engine的开发过程中也必不可少的会遇到调用GP工具的问题,调用GP工具的方式有两种:一种是使用Geoprocessing类;另一种是使用Geoprocessor托管类。两者也可能混合使用。

一、GP工具的调用方式

以调用系统工具Dissolve为例:

准备数据:

1、使用Geoprocessing类

   工具参数使用IVariantArray方式输入;且参数是有顺序的,其顺序以工具帮助中的参数顺序为准。 如果想要略过某个参数,则传入空字符串(即采用该参数的默认值),以保证参数的顺序是正确的。工具的名称也要按照语法中的写。例如Dissove工具的名称为"Dissolve_management"。顺序写错导致执行失败。

     

private void Dissolve(IFeatureClass sourceFClass)
{
    ESRI.ArcGIS.Geoprocessing.IGeoProcessor gp = new ESRI.ArcGIS.Geoprocessing.GeoProcessorClass();
    gp.OverwriteOutput = true;
    //除了使用IGeoProcessorResult接口获取GP处理结果外,还可以直接将GP的输出结果写入FeatureClass中,方便进行使用
    ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult result = new ESRI.ArcGIS.Geoprocessing.GeoProcessorResultClass();
    // Create a variant array to hold the parameter values.
    IVariantArray parameters = new VarArrayClass();
    object sev = null;
    try
    {
        // Populate the variant array with parameter values.用参数值填充变量数组
        parameters.Add("F:\\GIS测试数据\\新建文件地理数据库.gdb\\ABCD");//parameters.Add(sourceFClass);
        parameters.Add("F:\\GIS测试数据\\新建文件地理数据库.gdb\\diss");

        ESRI.ArcGIS.Geoprocessing.IGpValueTableObject pObject = new ESRI.ArcGIS.Geoprocessing.GpValueTableObjectClass();  //对多个字段进行融合添加
        pObject.SetColumns(1);
        pObject.AddRow("MC");
        pObject.AddRow("DM");
        parameters.Add(pObject);  //等同于parameters.Add("MC;DM");

        parameters.Add("");   //传入空值,保证顺序正确 
        parameters.Add("SINGLE_PART"); // 等同于parameters.Add("false");
        // Execute the tool.
        result = gp.Execute("Dissolve_management", parameters, null);
        IFeatureClass dealFclss = gp.Open(result.ReturnValue) as IFeatureClass;
    }
    catch (Exception ex)
    {
        // geoprocessing execution error messages.
        gp.GetMessages(ref sev);  //不知为什么返回一直为null
        ReturnMessages(gp);

    }
}

2、使用Geoprocessor托管类

   需要创建工具对象,参数作为该工具对象的属性输入。需要添加该工具的工具箱的引用,例如Dissolve工具需要添加ESRI.ArcGIS.DataManagementTools引用。

private void Dissolve(IFeatureClass sourceFClass)
{
    ESRI.ArcGIS.Geoprocessor.Geoprocessor gp = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
    gp.OverwriteOutput = true; //是否覆盖原文件
    try
    {
        ESRI.ArcGIS.DataManagementTools.Dissolve diss = new ESRI.ArcGIS.DataManagementTools.Dissolve();
        diss.in_features = "F:\\GIS测试数据\\新建文件地理数据库.gdb\\ABCD";//sourceFClass;   可以填写文件路径或则要素类
        diss.out_feature_class = "F:\\GIS测试数据\\diss2.SHP";//"F:\\GIS测试数据\\新建文件地理数据库.gdb\\AC";
        diss.multi_part = "false";  //Boolean只能填写"false"或"true"
        diss.dissolve_field = "MC;DM";

        gp.Execute(diss, null);

        //IGeoProcessorResult result = (IGeoProcessorResult)gp.Execute(diss,null);
        ////除了使用IGeoProcessorResult接口获取GP处理结果外,还可以直接将GP的输出结果写入FeatureClass中,方便进行使用
        //IFeatureClass dealFclss = gp.Open(result.ReturnValue) as IFeatureClass;  
    }
    catch
    {
        ReturnMessages(gp);
    }
}

工具执行后效果为:

二、GP工具参数写法的注意事项

1,如果GP工具的参数类型是要素类,要素图层,栅格数据,栅格图层的话,最好使用要素类或者栅格数据的绝对路径,这样最稳定。如果传入AO对象,比如IFeatureLayer、IFeatureClass、IRasterDataset、IRasterLayer等,不太稳定,有时可以成功,有时则失败,所以强烈推荐使用数据的绝对路径方式。还有一点需要注意就是要素类的路径中最好不要含有中文、空格等特殊字符、路径不要过长,并且需要对该数据具有读写权限。

2,如果要素类存储在SDE中,怎么写呢?可以使用该.sde连接文件的绝对路径+要素类名称的写法,比如: @”C:\Users\Feng\AppData\Roaming\ESRI\Desktop10.2\ArcCatalog\连接到 127.0.0.1.sde\SDE.diss”;当然这是使用的ArcCatalog中自动生成的.sde文件,如果没有或者不想使用该连接文件的话也可以使用IWorkspaceFactory.Create()方法或者GP工具Create ArcSDE Connection File根据参数来创建.sde连接文件。

3,GP工具的参数不会写或者写法有误的处理技巧:可以先在ArcMap中使用相同参数执行该GP工具成功后,然后在菜单栏–>Geoprocessing–>Results中打开Results窗口,查看刚才执行成功的GP历史,在Inputs项中查看或直接复制各参数的填写方式到代码中即可。

4,如果工具中需要输入多个要素类,参数怎么写?比如Intersect_analysis工具,如果对两个要素类求交可以这么写:intersect.in_features = @”C:\Users\a\Desktop\test\1.shp;C:\Users\a\Desktop\test\2.shp”; 
其实在Result界面有其分隔符的写法即分号。其它工具也类似,比如:Reclassify工具,其映射参数可以这样写reclassify.remap = “589 1070 1;1070 1555 2;1555 2169 3;2169 3311 4”; 不同类别用分号隔开,同一类别的最大最小值用空格隔开。再比如Clip_management工具,其范围可以这样写clip.rectangle = “-117.35334730268 33.8297125828826 -116.792366370644 34.4768962586111”;中间用空格隔开。再强调一下:最保险并且准确的就是ArcMap执行成功后,在Results界面复制其写法。

三、获取GP详细报错信息

      方法就是把执行GP的语句放进try-catch-finally的结构体中;尝试获取具体的报错信息,如许可级别不够、参数错误等。

/// <summary>
/// 获取GP工具执行后信息
/// </summary>
/// <param name="gp">gp对象(工具调用者)</param>
/// <returns></returns>
private string ReturnMessages(object gpr)
{
    string ms = "";
    if (gpr is ESRI.ArcGIS.Geoprocessor.Geoprocessor gp)
    {
        if (gp.MessageCount > 0)
        {
            for (int Count = 0; Count <= gp.MessageCount - 1; Count++)
            {
                ms += "$" + gp.GetMessage(Count) + "\n\n";
            }
        }
    }
    else if(gpr is ESRI.ArcGIS.Geoprocessing.IGeoProcessor gp2)
    {
        if (gp2.MessageCount > 0)
        {
            for (int Count = 0; Count <= gp2.MessageCount - 1; Count++)
            {
                ms += "$" + gp2.GetMessage(Count) + "\n\n";
            }
        }
    }
    return ms;
}

猜你喜欢

转载自blog.csdn.net/qq_33459369/article/details/88927228