ArcObjects SDK开发 017 在ArcObjects SDK 中使用Toolbox

1、Geoprocessor和IGPProcess

Geoprocessor是ArcObjects SDK中定义Tool执行器。IGPProcess接口是ArcObjects SDK中定义的ArcTool接口。也就是说ArcObjects SDK定义的ArcTool都会继承该接口实现。理论上,在ArcToolbox的出现的系统工具都应该可以在SDK中找到。

Geoprocessor如何使用呢?参考下面的代码。

private static Geoprocessor _Geoprocessor = null; /// <summary> /// 实际的地理处理器 /// </summary> public Geoprocessor Geoprocessor {     get     {         if (_Geoprocessor == null)         {             _Geoprocessor = new Geoprocessor             {                 OverwriteOutput = true             };         }         return _Geoprocessor;     } } public object ExecuteByGP(IGPProcess pGPProcess) {     try     {         return Geoprocessor.Execute(pGPProcess, null);     }     catch     {         object mySeverity = null;         string myMessage = Geoprocessor.GetMessages(ref mySeverity);         throw new Exception(myMessage);     } }

2、以Buffer为例

ArcToolBox的对应的类在SDK中找不到,我们一般从ArcMap上着手。首先先在ArcMap上的Toolbox中找到Buffer工具,并打开。如下图所示。

ArcObjects SDK开发 017 在ArcObjects SDK 中使用Toolbox

我们可以通过点击Tool Help按钮,查看该工具的具体用法。特别是参数说明部分。通过帮助中的信息,分析出属于那个dll文件,如果没有引用的话,引用下。如下图所示。

ArcObjects SDK开发 017 在ArcObjects SDK 中使用Toolbox

后面有个Analysis,那么该功能在ArcObjects SDK中是被定义在ESRI.ArcGIS.AnalysisTools.dll中的。例如Dissolve工具,后面的括号内是Data Management,那么该工具被定义到了ESRI.ArcGIS.DataManagementTools.dll中。

我们到SDK中看下Buffer是怎么定义的。

using System.IO; using System.Reflection; using System.Xml; using ESRI.ArcGIS.Geoprocessor;  namespace ESRI.ArcGIS.AnalysisTools {     public class Buffer : IGPProcess     {         private object[] m_gpParameters;          private string m_ToolboxDirectory;          public object in_features         {             get             {                 return m_gpParameters[0];             }             set             {                 m_gpParameters[0] = value;             }         }          public object out_feature_class         {             get             {                 return m_gpParameters[1];             }             set             {                 m_gpParameters[1] = value;             }         }          public object buffer_distance_or_field         {             get             {                 return m_gpParameters[2];             }             set             {                 m_gpParameters[2] = value;             }         }          public string line_side         {             get             {                 return m_gpParameters[3] as string;             }             set             {                 m_gpParameters[3] = value;             }         }          public string line_end_type         {             get             {                 return m_gpParameters[4] as string;             }             set             {                 m_gpParameters[4] = value;             }         }          public string dissolve_option         {             get             {                 return m_gpParameters[5] as string;             }             set             {                 m_gpParameters[5] = value;             }         }          public object dissolve_field         {             get             {                 return m_gpParameters[6];             }             set             {                 m_gpParameters[6] = value;             }         }          public string ToolboxDirectory         {             get             {                 return m_ToolboxDirectory;             }             set             {                 m_ToolboxDirectory = value;             }         }          public string ToolboxName => "Analysis Tools.tbx";          public string ToolName => "Buffer";          public string Alias => "analysis";          public object[] ParameterInfo => m_gpParameters;          public Buffer()         {             m_gpParameters = new object[7];             m_ToolboxDirectory = ResolveDirectory();         }          public Buffer(object in_features, object out_feature_class, object buffer_distance_or_field)         {             m_gpParameters = new object[7];             m_ToolboxDirectory = ResolveDirectory();             this.in_features = in_features;             this.out_feature_class = out_feature_class;             this.buffer_distance_or_field = buffer_distance_or_field;         }          private string ResolveDirectory()         {             string result = "[SYSTEMTOOLBOXLOCATION]";             Assembly executingAssembly = Assembly.GetExecutingAssembly();             string text = executingAssembly.Location + ".config";             FileInfo fileInfo = new FileInfo(text);             if (fileInfo.Exists)             {                 XmlDocument xmlDocument = new XmlDocument();                 xmlDocument.Load(text);                 XmlNode xmlNode = xmlDocument.SelectSingleNode("configuration/toolbox");                 if (xmlNode != null)                 {                     result = xmlNode.Attributes["directory"].Value;                 }             }              return result;         }     } }

有些参数设置比较好理解,例如in_features,可以设置一个shape文件路径、IFeatureClass对象、IFeatureLayer对象或者.Lyr文件路径等。但为了运行稳定,保险起见,我一般都设置文件路径。

out_feature_class参数也比较好理解,设置一个输出的Shape文件路径即可。

后面的line_side、line_end_type、dissolve_option都是字符串类型的可选参数,这种一般还比较简单写,看帮助中的参数列表部分,基本上可以解决我们的问题。

ArcObjects SDK开发 017 在ArcObjects SDK 中使用Toolbox

还有两个参数buffer_distance_or_field和dissolve_field,这两个比较难设置。dissolve_field还好,是一个可选参数,我之前也没用过,可以先不管。但buffer_distance_or_field参数,看到这个名字就知道这个参数非常重要。按正常理解的话,这个参数应该是一个数字类型的参数,用来设置缓冲距离。我们再看下帮助是如何描述这个参数的。

ArcObjects SDK开发 017 在ArcObjects SDK 中使用Toolbox

这个字段可识别的类型有字段和线性单位,通过描述可以知道,参数可以传数字+单位以及字段名称。如果只传一个数字,那么就按照该数字以及数据本身的单位进行缓冲区分析;如果传数字+单位,就按照传入的数字和单位进行缓冲区分析;如果传字段名称,就按照该字段的值进行缓冲区分析。就是说,我们设置数字100、字符串”100 Meters”或者一个数字类型的字段名称均是可以的。

但如果传字段,字段类型是字符串,里面的值为数字+单位的格式是否识别?或者该参数传一个IField对象是不是可以识别?再或者字段是数字类型,我们传字段名称+单位是不是也可以?因为这些在实际应用中,没有应用过,所以并没有进行验证。如果有需要这么处理的,可以去验证下。

如果还不知道这个参数如何参数,那么还有一个更直观的办法。先用自己想设置的参数在ArcMap中运行一下。如下图所示。

ArcObjects SDK开发 017 在ArcObjects SDK 中使用Toolbox

点击OK按钮执行,之后后,去Toolbox的Result模块查看执行的py脚本。如下图所示。

ArcObjects SDK开发 017 在ArcObjects SDK 中使用Toolbox

拷贝后,可以把脚本放到记事本里。如下图所示。

ArcObjects SDK开发 017 在ArcObjects SDK 中使用Toolbox

这样我们是不是就可以知道buffer_distance_or_field参数要怎么设置了?dissolve_field参数更复杂,但通过这样的方法,也可以获取该参数的设置格式。

3、ArcObject SDK 调用Toolbox的技巧

熟练使用ArcToolbox以及会看Toolbox的帮助;

善于能把各类Tool串起来,完成一个完整的业务模块

先用数据在ArcMap的ArcToolbox上做验证;

Tool设置参数的时候,数据尽量用路径,路径尽量不要有汉字、空格等,传入的参数路径名称尽量以字母开头;

在代码中调用报错,用同样的数据、同样的参数,在ArcMap里面去运行一下,一般两者是没什么差别的,在ArcMap找到什么原因后,再去修改代码;

设置参数的时候,结合Arcpy去分析可接受参数的格式。

发表评论

相关文章