ArcGIS二次开发基础教程(05):GP工具的使用

ArcGIS二次开发基础教程(05):GP工具的使用

GP工具实在过于强大,比赛不一定能用,但从开发的角度来看,实在必不可少。又恰巧看到一篇博客很详细地阐述了GP工具的用法,我觉得我再写也不会比这更好了,于是稍作修改,搬过来了。还有一篇写的也还行,这里附上链接:https://blog.csdn.net/xxf813/article/details/82011950

相信用过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、调用自定义工具(在ArcMap中叫模型)

			// 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关键字下面显示的即为工具的语法名称。

    img

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

    img

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

    img

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

    img

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

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

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

    img

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

使用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了。
img

详细信息参考

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:

img

但是如果这样写:

			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错误,如下图:

这里写图片描述
历届GIS应用技能大赛开发题答案点这里,尚在不定期更新中

你可能感兴趣的:(ArcGIS二次开发,AE+C#)