使用ArcEngine自定义GP Tool
目录
概述
GP 工具是ArcGIS中的一个重要组成部分,用户可以使用ArcGIS提供的数百个GP 工具进行各种分析,并且提供了工具可以自由的组合这些工具,进行更复杂的分析。ArcGIS提供的GP 工具如下:
如果想执行一个GP 工具,可以双击该工具,系统会弹出该工具的界面,如下图所示:
除了可以执行单个的GP 工具,还可以使用ArcGIS提供的Model Builder来组合现有的GP工具,界面如下:
既然ArcGIS预警提供了那么丰富的GP工具以及GP工具组合方式,那么为什么还需要自定义GP工具呢?
为什么需要自定义GP工具?
- 某个行业中如果要有针对该行业的一些分析方法,可能ArcGIS提供GP工具满足不了要求,就需要自定义。
- 从ArcGIS10.0开始,使用ArcEngine编写的代码已经不能通过WebService发布了,所以自定义ArcEngine功能要想发布出来给Web使用的话只能用ArcServer,ArcServer也提供了GPServer和SOE Server两种方式,其中GPServer一直都存在,SOE服务是新增的,但在arcGIS10.0种使用还比较麻烦,ArcGIS 10.1中就方便一些了。所以自定义的GP工具可以发布成服务。
但我一般自定义GP还是因为第二个原因。有些对数据复杂的操作,可以通过在服务器端发布自定义GP工具的方式实现。因为是ArcEngine代码,里面的操作就可以很灵活。安装ArcEngine开发包后,在安装目录下也会有自定义GP工具的例子。路径如下:
C:\Program Files (x86)\ArcGIS\DeveloperKit10.1\Samples\ArcObjectsNet\GPCustomCalculateAreaFunctionTool
自定义GP工具
上面的gp工具就是我们自定义的工具,通过输入一个FeatureClass获取FeatureClass中元素的个数。
下面就说面下,该工具如何定义。
要想自定义GP工具,需要使用到重要的接口,IGPFunction2和IGPFunctionFactory。
IGPFunction2是定义GP工具要实现的接口。
IGPFunctionFactory是创建GP工具的工厂接口,当我们把我们编译后的dll注册到ArcGIS中时,ArcGIS就是识别该接口,来确定该dll中有哪些GP工具。
代码如下:
//定义gp工具
public class GetFeatureCountGPFunction:IGPFunction2
{
//工具的名称
public static string ToolName = "GetFeatureCount";
private IGPUtilities m_GPUtilities;
public GetFeatureCountGPFunction()
{
m_GPUtilities=new GPUtilitiesClass();
}
<pre name="code" class="csharp"> //应该是对话框的一个标识,不重要,返回null,即可
public ESRI.ArcGIS.esriSystem.UID DialogCLSID
{
get { return null; }
}
//重要,工具的名称
public string Name
{
get { return GetFeatureCountGPFunction.ToolName; }
}
//工具显示的名称
public string DisplayName
{
get { return "Get Feature Count From FeatureClass"; }
}
//工具的全部名称,包括内容看下面的属性就很容易理解
public IName FullName
{
get
{
IGPFunctionName myGPFunctionName = new GPFunctionNameClass();
myGPFunctionName.MinimumProduct = esriProductCode.esriProductCodeAdvanced;
IGPName myGPName= (IGPName)myGPFunctionName;
myGPName.Name = this.Name;
myGPName.Category = "BM_0";
myGPName.Description = "Get Feature Count From FeatureClass";
myGPName.DisplayName =this.DisplayName;
BMGPFunctionFactory myBMGPFunctionFactory = new BMGPFunctionFactory();
myGPName.Factory = myBMGPFunctionFactory;
return myGPFunctionName as IName;
}
}
//目前还不命该该函数的作用,但如果用不到 返回null即可
public object GetRenderer(IGPParameter pParam)
{
return null;
}
//帮助的上下文标识 返回0即可
public int HelpContext
{
get { return 0; }
}
//帮助文件,如果没有 返回空字符串即可
public string HelpFile
{
get { return ""; }
}
//验证许可
public bool IsLicensed()
{
IAoInitialize myAoInitialize = new AoInitializeClass();
ILicenseInformation myLicenseInformation = (ILicenseInformation)myAoInitialize;
string myLicenseProductName = myLicenseInformation.GetLicenseProductName(myAoInitialize.InitializedProduct());
if (myLicenseProductName == "Advanced")
{
return true;
}
else
{
return false;
}
}
//元数据文件 这个返回空字符串也可以
public string MetadataFile
{
get
{
string myFilePath;
myFilePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
myFilePath = System.IO.Path.Combine(myFilePath, this.Name+".xml");
return myFilePath;
}
}
//重要,定义参数列表,包括输入和输出参数都在此定义
public IArray ParameterInfo
{
get
{
ArrayClass myParameterArray= new ArrayClass();
IGPParameterEdit3 myGPParameterClass = new GPParameterClass();
myGPParameterClass.DataType = new GPFeatureLayerTypeClass();
myGPParameterClass.Direction = esriGPParameterDirection.esriGPParameterDirectionInput;
myGPParameterClass.DisplayName = "In_FeatureClass";
myGPParameterClass.Name = "In_FeatureClass";
myGPParameterClass.ParameterType = esriGPParameterType.esriGPParameterTypeRequired;
myGPParameterClass.Value = new GPFeatureLayerClass();
myParameterArray.Add(myGPParameterClass);
myGPParameterClass = new GPParameterClass();
myGPParameterClass.DataType = new GPDoubleTypeClass();
myGPParameterClass.Direction = esriGPParameterDirection.esriGPParameterDirectionOutput;
myGPParameterClass.DisplayName = "Out_FeatureCount";
myGPParameterClass.Name = "Out_FeatureCount";
myGPParameterClass.ParameterType = esriGPParameterType.esriGPParameterTypeDerived;
myParameterArray.Add(myGPParameterClass);
return myParameterArray;
}
}
//执行函数
public void Execute(IArray paramvalues, ITrackCancel TrackCancel, IGPEnvironmentManager envMgr, IGPMessages message)
{
IGPParameter parameter = (IGPParameter)paramvalues.get_Element(0);
IGPValue parameterValue = m_GPUtilities.UnpackGPValue(parameter);
// Open Input Dataset
IFeatureClass myInputFeatureClass;
IQueryFilter qf;
m_GPUtilities.DecodeFeatureLayer(parameterValue, out myInputFeatureClass, out qf);
if (myInputFeatureClass == null)
{
message.AddError(2, "Could not open input dataset.");
return;
}
IGPParameterEdit3 myOutFeatureCountGPParameter = paramvalues.get_Element(1) as IGPParameterEdit3;
GPDoubleClass myGPValue = new GPDoubleClass();
myGPValue.Value = myInputFeatureClass.FeatureCount(null);
}
//更新进度信息,因为我们这个比较简单,也没有什么进度信息,如果需要可以查看帮助和示例看如何定义
public void UpdateMessages(IArray paramvalues, IGPEnvironmentManager pEnvMgr, IGPMessages Messages)
{
}
//更新参数,有些工具需要设置好一个参数后,才能设置下一个参数,例如需要选择一个矢量数据之后,才能选择数据中的字段,这样的工作可在该代码中定义,如何定义还需要查看帮助和示例
public void UpdateParameters(IArray paramvalues, IGPEnvironmentManager pEnvMgr)
{
}
//验证合法性、如果不需要验证就直接返回new GPMessagesClass()
public IGPMessages Validate(IArray paramvalues, bool updateValues, IGPEnvironmentManager envMgr)
{
return new GPMessagesClass();
}
}
FunctionFactory的代码如下:
[
Guid("f4d75962-a8ba-43f6-b3c2-fa06ba7d8680"),
ComVisible(true)
]
public class BMGPFunctionFactory:IGPFunctionFactory
{
[ComRegisterFunction()]
static void Reg(string regKey)
{
GPFunctionFactories.Register(regKey);
}
[ComUnregisterFunction()]
static void Unreg(string regKey)
{
GPFunctionFactories.Unregister(regKey);
}
public string Name
{
get { return "BM"; }
}
public string Alias
{
get { return "BM"; }
}
public UID CLSID
{
get
{
UID myUID = new UIDClass();
myUID.Value = this.GetType().GUID.ToString("B");
return myUID;
}
}
public IGPFunction GetFunction(string Name)
{
if (Name == GetFeatureCountGPFunction.ToolName)
{
return new GetFeatureCountGPFunction();
}
return null;
}
public IEnumGPEnvironment GetFunctionEnvironments()
{
return null;
}
public IGPName GetFunctionName(string Name)
{
IGPName myGPName=null;
if (Name == GetFeatureCountGPFunction.ToolName)
{
GetFeatureCountGPFunction myGetFeatureCountGPFunction = new GetFeatureCountGPFunction();
myGPName = myGetFeatureCountGPFunction.FullName as IGPName;
myGPName.Factory = this;
}
return myGPName;
}
public IEnumGPName GetFunctionNames()
{
IArray myNameArray = new EnumGPNameClass();
GetFeatureCountGPFunction myGetFeatureCountGPFunction = new GetFeatureCountGPFunction();
IGPName myGPName = myGetFeatureCountGPFunction.FullName as IGPName;
myGPName.Factory = this;
myNameArray.Add(myGPName);
return (IEnumGPName)myNameArray;
}
}
写完这些代码之后,编译成dll。
在ArcGIS中使用自定义GP
右键点击生成的dll文件,在最上面有个注册按钮,点击注册COM组件。
点击注册后,弹出的界面:
点击注册按钮即可。
接下来打开ArcCatalog工具。
在[My Tooloxes]中新建一个自己的工具集,点击右键,[Add]-[Tool]。弹出选择GP Tool对话框。
弹出的对话框如下:
选择我们自定义的工具,其中的工具的目录、分类名称、工具名称等都是可以在代码定义的时候设置的。点击[OK]按钮。
这样工具就被添加进来了,双击该工具,就可以使用了。
转载自:https://blog.csdn.net/mytudousi/article/details/31388607