ArcGIS Engine中如何调用GP工具(一)

相信用过ArcGIS的用户都会有这样一个感受,那就是功能太强大了!尤其是其提供了超过900个地理处理(Geoprocessing,简称GP)工具,可以快速地实现数据分析、数据管理以及数据转换等功能。在ArcGIS Engine的开发过程中也必不可少的会遇到调用GP工具的问题,这也是用户问的最多的一类问题,那么ArcGIS Engine中如何调用GP工具?参数怎么写?有哪些注意事项?如何获取报错信息?今天,就把Engine中调用GP工具的相关问题总结一下,相信一定会让你有所收获。

一、如何调用GP工具?

调用GP工具的方式有两种:一种是使用Geoprocessing类,工具参数使用IVariantArray方式输入;另一种是使用Geoprocessor托管类,创建工具对象,参数作为该工具对象的属性输入。下面就分别来看下这两种调用方式的具体实现。

使用Geoprocessing类:

主要分为以下几步:

1,添加ESRI.ArcGIS.Geoprocessing引用,仅需要引用该类库
2,创建geoprocessor对象,注意这里的P是大写
3,如果调用自定义工具,需要添加自定义工具箱的路径
4,创建IVariantArray对象,用于存放工具参数
5,调用geoprocessor的Execute方法

下面来看具体代码(以调用Buffer工具为例):

A,调用系统工具:

IGeoProcessor2 gp = new GeoProcessorClass();
//设置gp.OverwriteOutput是指可以用一个输出执行多次工具
            gp.OverwriteOutput = true;
            IGeoProcessorResult result = new 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(FileGDBPath + "\\LotIds");
                parameters.Add(FileGDBPath + "\\LotIds_Buffer");
                parameters.Add("100 Feet");

                // Execute the tool.
                result = gp.Execute("Buffer_analysis", parameters, null);
                // Print geoprocessring messages.
                Console.WriteLine(gp.GetMessages(ref sev));
            }
            catch (Exception ex)
            {
                // Print a generic exception message.
                Console.WriteLine(ex.Message);
                // Print geoprocessing execution error messages.
                Console.WriteLine(gp.GetMessages(ref sev));
            }

B,调用自定义工具(Model中添加Buffer工具):

// Initialize the geoprocessor.
            IGeoProcessor2 gp = new GeoProcessorClass();
            // Add the BestPath toolbox.
            gp.AddToolbox(tbxPath);
            // Generate the array of parameters.
            IVariantArray parameters = new VarArrayClass();
            parameters.Add(FileGDBPath + "\\LotIds");
            parameters.Add("100 Feet");
            parameters.Add(FileGDBPath + "\\LotIds_Buffer2");            
            object sev = null;
            try
            {
                // Execute the model tool by name.
                gp.Execute("Model2", parameters, null);
                Console.WriteLine(gp.GetMessages(ref sev));
            }
            catch (Exception ex)
            {
                // Print geoprocessing execution error messages.
                Console.WriteLine(gp.GetMessages(ref sev));
            }

总结下使用IVariantArray的注意事项:

1,执行工具时,传入的第一个参数Name为工具的语法名称,语法名称是工具名称_工具箱别名方式,以便唯一确定该工具。举个例子,比如Clip工具,Analysis和Data Management工具箱中都有Clip,这时通过工具的语法名称就可以区别,前者是Clip_analysis,后者是Clip_management。再比如用到的Buffer工具,不是直接传入”Buffer”,而是输入”Buffer_analysis”,具体可以打开该工具的Tool Help,Synatx关键字下面显示的即为工具的语法名称。

这里写图片描述

2,参数是有顺序的。其顺序以工具帮助中的参数顺序为准。因为ArcMap中有的工具界面的参数显示顺序与该Tool Help中的不一致。比如Buffer工具,工具界面如下:

这里写图片描述

其Tool Help中的参数顺序如下:

这里写图片描述

Method参数的顺序与工具界面中是不同的。再看下ArcMap中执行该工具成功后Results界面的内容,如图:

这里写图片描述

也验证了其顺序是与Tool Help中相一致的。

3,如果必写参数前有可选参数,那么可选参数也是要赋值的,如果想要略过该参数,则传入空字符串(即采用该参数的默认值),以保证参数的顺序是正确的。

4,调用自定义工具时,注意自定义工具的执行名称是Name而非Label,如下图:显示的名称为custom_BufferTool,但需要使用Name,即Model2,这是很多用户容易犯的错误,需要注意。

这里写图片描述

说完第一种方式的实现方法和注意事项,下面来看第二种调用方式:

使用Geoprocessor托管类:

主要分为以下几步:

1,添加ESRI.ArcGIS.Geoprocessor引用,如果想要获取执行结果result或者list datasets还需要引用ESRI.ArcGIS.Geoprocessing
2,除此之外,需要添加该工具所在工具箱的引用。比如使用Buffer工具,则需要添加ESRI.ArcGIS.AnalysisTools引用,使用IDW工具,则需要添加ESRI.ArcGIS.SpatialAnalystTools引用,以此类推。
3,创建geoprocessor对象
4,如果调用自定义工具,需要添加自定义工具箱的路径
5,创建工具对象(tool process object)并且设置参数
6,调用geoprocessor的Execute方法

下面来看具体代码(同样以调用Buffer工具为例):

A,调用系统工具:

// Create the geoprocessor. 
            Geoprocessor GP = new Geoprocessor();
            GP.OverwriteOutput = true;
            // Create the tool process object.
            ESRI.ArcGIS.AnalysisTools.Buffer bufferTool = new
                ESRI.ArcGIS.AnalysisTools.Buffer();
            // Set parameter values.
            bufferTool.in_features = FileGDBPath + "\\LotIds";
            bufferTool.out_feature_class = FileGDBPath + "\\LotIds_BufferSystem";
            bufferTool.buffer_distance_or_field = "100 Feet";
            object sev = null;
            try
            {
                // Execute the tool.
                GP.Execute(bufferTool, null);
                Console.WriteLine(GP.GetMessages(ref sev));
            }
            catch (Exception ex)
            {
                // Print geoprocessing execution error messages.
                Console.WriteLine(GP.GetMessages(ref sev));
            }

        }

B,调用自定义工具:

由于自定义工具箱没有任何托管类,因此,最简单的方式就是使用IVariantArray根据工具的Name执行(Geoprocessor对象的Execute方法实现了该重载)。

// Initialize the geoprocessor.
            Geoprocessor GP = new Geoprocessor();
            GP.OverwriteOutput = true;
            // Add the BestPath toolbox.
            GP.AddToolbox(tbxPath);
            // Generate the array of parameters.
            IVariantArray parameters = new VarArrayClass();
            parameters.Add(FileGDBPath + "\\LotIds");
            parameters.Add("100 Feet");
            parameters.Add(FileGDBPath + "\\LotIds_BufferCustomArray2");
            object sev = null;
            try
            {
                // Execute the model tool by name.
                GP.Execute("Model2", parameters, null);
                Console.WriteLine(GP.GetMessages(ref sev));
            }
            catch (Exception ex)
            {
                // Print geoprocessing execution error messages.
                //Console.WriteLine(GP.GetMessages(ref sev));
                for (int i = 0; i < GP.MessageCount; i++)
                    Console.WriteLine(GP.GetMessage(i));
            }

        }

顺便提一下,如果就想用调用系统工具(比如工具变量.参数)的方法调用自定义工具,可以使用ArcGIS ToolBox Reference(如下图),将该自定义工具箱生成为dll,然后添加该引用后就可以正常使用了,不过10.4版本之后貌似没有ArcGIS Toolbox Reference了。

这里写图片描述

详细信息参考How to run a geoprocessing tool

Tips:调用GP工具时使用的是相同的框架,只需要改变其中的具体的工具及参数即可。

下面总结下各自的优缺点:

第一种方式:

优点:只需要添加Geoprocessing引用,所有工具都可以使用工具的语法名称来执行,无需添加该工具所在工具箱的引用,参数统一使用IVariantArray方式输入;

缺点:参数有严格顺序,必写参数前有可选参数也需要设置,顺序写错经常导致执行失败。

第二种方式:

优点:参数无顺序,仅根据工具对象的属性输入即可,可以只输入必写参数,参数环节不容易出错;

缺点:除添加Geoprocessor引用外,还需要知道工具所在的工具箱名称,添加其工具箱的引用,如果调用工具较多,可能需要添加很多引用。

介绍完调用GP工具的两种方式,接下来就是用户最关注的两部分内容了,一个是GP工具的参数如何写?有哪些注意事项;另一个就是假如工具执行失败了,如何获取详细的报错信息,比如怎么判断是参数错误还是许可错误。

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

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

2,如果要素类存储在SDE中,怎么写呢?可以使用该.sde连接文件的绝对路径+要素类名称的写法,比如: @”C:\Users\Xinying\AppData\Roaming\ESRI\Desktop10.3\ArcCatalog\Connection to 192.168.220.131.sde\SDE.polygon”;当然这是使用的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界面复制其写法。

5,如果涉及到空间参考的话也可以直接复制:

这里写图片描述


Project.Output_Coordinate_System = "PROJCS['CGCS2000_3_Degree_GK_CM_108E',GEOGCS['GCS_China_Geodetic_Coordinate_System_2000',DATUM['D_China_2000',SPHEROID['CGCS2000',6378137.0,298.257222101]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Gauss_Kruger'],PARAMETER['False_Easting',500000.0],PARAMETER['False_Northing',0.0],PARAMETER['Central_Meridian',108.0],PARAMETER['Scale_Factor',1.0],PARAMETER['Latitude_Of_Origin',0.0],UNIT['Meter',1.0]]";

三、如何获取详细报错信息

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

举个例子,比如上面执行Buffer工具时,不小心把bufferTool.buffer_distance_or_field = “100 Feet”; 参数写成了“‘100 Feet’”,如果通过最开始那种写法是获取不了任何报错信息的,如下图,输出错误信息为null:

这里写图片描述

但是如果这样写:

try
            {
                IGeoProcessorResult2 result = GP.Execute(bufferTool, null) as IGeoProcessorResult2;
            }   
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "GP Error");
            }
            finally
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                for (int i = 0; i < GP.MessageCount; i++)
                    sb.AppendLine(GP.GetMessage(i));
                if (sb.Capacity > 0) MessageBox.Show(sb.ToString(), "GP Messages");
            }

则可以获取下面信息:

这里写图片描述

会提示用户是参数无效,并且告诉用户是 ‘100 Feet’ 这个参数有误,有了这个信息就很方便我们回去查找到这个参数进而进行修改了。

再比如说如果对线要素类做缓冲区,ArcMap中可以设置在线的左侧或右侧缓冲以及端点处是圆头还是平头缓冲,这样的话Engine许可就用不了了,具体见该工具的Tool Help:

这里写图片描述

那如果程序中初始化的Engine许可,就会报没有license错误,如下图:

这里写图片描述

很方便定位问题所在。

Demo

使用ArcGIS Engine 10.5,Visual Studio 2013编写,界面为:

这里写图片描述

工程下载地址:

GP_ArcGISEngine

  • 25
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,关于在C#开发调用ArcGISGP工具Erase、SymDiff,您可以使用ArcObjectsGeoprocessor对象来调用这些工具。以下是示例代码: ```csharp using ESRI.ArcGIS.Geoprocessor; using ESRI.ArcGIS.AnalysisTools; using ESRI.ArcGIS.Carto; // 获取当前地图文档 IMapDocument mapDocument = new MapDocumentClass(); mapDocument.Open(@"C:\data\map.mxd"); IMap map = mapDocument.ActiveView.FocusMap; // 创建Geoprocessor对象 Geoprocessor gp = new Geoprocessor(); // 设置工作空间 gp.SetEnvironmentValue("workspace", @"C:\data"); // 定义输入要素和擦除要素 string in_features = @"C:\data\input.shp"; string erase_features = @"C:\data\erase.shp"; // 定义输出要素 string out_features = @"C:\data\output.shp"; // 创建Erase工具对象 Erase erase = new Erase(); erase.in_features = in_features; erase.erase_features = erase_features; erase.out_feature_class = out_features; // 执行Erase工具 gp.Execute(erase, null); // 定义输入要素 string in_features1 = @"C:\data\input1.shp"; string in_features2 = @"C:\data\input2.shp"; // 定义输出要素 string out_features2 = @"C:\data\output2.shp"; // 创建SymDiff工具对象 SymDiff symDiff = new SymDiff(); symDiff.in_features = in_features1 + ";" + in_features2; symDiff.out_feature_class = out_features2; // 执行SymDiff工具 gp.Execute(symDiff, null); ``` 以上代码,我们首先获取当前地图文档,然后创建Geoprocessor对象并设置工作空间。接着,我们分别定义输入要素和擦除要素,以及输出要素,并创建Erase工具对象和SymDiff工具对象。最后,我们通过执行Geoprocessor对象的Execute方法来执行这些工具。 希望这个示例代码可以帮助您完成在C#开发调用ArcGISGP工具Erase、SymDiff的任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值