我的github

如果希望创建一个ArcToolbox GP工具

http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#//00010000049w000000

在创建自己的自定义工具之前,请考虑以下备选方案:

(1)查看现有的系统工具。您所需的功能可能已经存在于现有的地理处理工具中。

(2)如果可以使用多个现有工具完成工作流,请使用ModelBuilder将这些工具链接在一起。

(3)使用Python脚本创建脚本工具。Python是一种功能强大的脚本语言,大多数地理处理任务都可以在Python中完成。还可以使用Python以编程方式自定义工具行为。

(4)在ModelBuilder创建的模型中嵌入脚本工具。

(5)编写一个独立的.NET应用程序,并将可执行文件用作脚本工具的源代码。

脚本工具和模型工具是自定义工具,您可以使用ArcGIS for Desktop graphical user interfaces(GUI)创建它们,如向导和ModelBuilder。功能工具也是自定义工具,但它们是通过扩展ArcGIS for Desktop的功能来创建的。

https://www.cnblogs.com/GISQZC/p/5318141.html

Creating a custom geoprocessing function tool如何创建自定义的GP工具
There are, of course, scenarios for which you must create your own tool using ArcObjects. This requires implementing the IGPFunction2 and IGPFunctionFactory interfaces. The Building a custom geoprocessing function tool topic provides detailed information and examples. The following steps summarize the process:
当然,在某些情况下,您必须使用ArcObjects创建自己的工具。这需要实现IGPFunction2和IGPFunctionFactory接口。“构建自定义地理处理功能工具”主题提供了详细信息和示例。以下步骤总结了该过程:
  1. In a .NET application, create two classes (one will implement IGPFunction2 and the other will implement IGPFunctionFactory). You can create two separate files or keep them in a single file.在.NET应用程序中,创建两个类(一个将实现IGPFunction2,另一个将实现IGPFunctionFactory)。可以创建两个单独的文件,也可以将它们保存在一个文件中。
  2. Set the parameter properties (parameter type, direction, and acceptable values) in the ParameterInfo property of IGPFunction2.在IGPFunction2的ParameterInfo属性中设置参数属性(参数类型、方向和可接受值)。
  3. Leave the Validation method of IGPFunction2 as an empty stub—the geoprocessing framework automatically performs the validation.将IGPFunction2的验证方法保留为空存根,geoprocessing框架将自动执行验证。
  4. The Execute method of IGPFunction is the most important part of your tool. This is where you write your code to implement the specific algorithm.IGPFunction的Execute方法是工具中最重要的部分。这是您编写代码以实现特定算法的地方。
  5. Implement IGPFunctionFactory. This makes your custom function tool accessible to users.实现IGPFunctionFactory。这使得用户可以访问自定义函数工具
The custom function tool does not automatically become a part of ArcGIS. To use the tool, you need to complete a custom registration of the dynamic-link library (DLL) as follows:
  1. Use the ESRIRegAsm utility to register (and unregister) the DLL.使用ESRIRegAsm Utility来注册DLL
  2. Add the tool to a custom toolbox.添加工具到toolbox
The tool is now ready to be used as any other geoprocessing tool.
Include the toolbox when you share the DLL. When you share the function DLL with someone, all they have to do is register the DLL, and the tool in the toolbox is ready to go. You do not have to register the DLL in the component category or add the tool to a toolbox.当你分享toolbox中的工具时,他们只需要注册就好了。不再需要其他的步骤。

 

 

 

 

 

我们做gptool的话,不需要选择add-in types了。直接点finish就可以。

gptool可以被认为是一种操作,它接受一个输入或一组输入,并生成一个或多个输出。这些输入称为参数。地理处理工具位于工具箱中,并按功能分类。ESRI提供的大多数地理处理工具都是作为组件对象模型(COM)功能工具实现的。函数工具至少需要实现两个对象:实现IGPFunction2的函数对象和实现IGPFunctionFactory的函数工厂对象。
下图显示了工具关系、ESRI实现的类以及为扩展地理处理框架而提供的类。有四种类型的地理处理工具:GPModelTool、GPFunctionTool、GPCustomTool和GPScriptTool。

在开始创建地理处理工具之前,请阅读创建脚本工具的快速教程。通过使用脚本工具向导,您可以通过创建参数和实现工具验证来初步构建工具原型。这个原型可以用来帮助设计和实现一个功能工具。

规则

在构建地理处理函数工具时,需要记住一些非正式规则。这些规则有助于开始或结束有关编写函数的讨论,如下所示:

  • 始终在ParameterInfo()中创建新数组
  • 总是有一个输出
  • 不本地化关键字
  • 对布尔参数使用编码值域

属性和方法

创建地理处理函数工具时需要许多IGPFunction2属性和方法,但以下方法是本主题的主要重点:

  • 参数信息()ParameterInfo()
  • 更新参数()UpdateParameters()
  • 更新消息()UpdateMessages()
  • 执行()Execute()

IGPFunction2接口

IGPFunction2接口位于ESRI地理处理库中。列出了每个IGPFunction2属性和方法:

  • Name property—The name of the function tool. This name appears when executing the tool at the command line or in scripting. This name should be unique to each toolbox and cannot contain spaces.属性
  • DisplayName property—The display name of the function tool. The user interface (UI) utilizes this property to display the name of the tool in ArcToolbox. This name is a user-friendly description of the function tool. The display name can be internationalized.属性
  • FullName property—The function name object for the geoprocessing function tool. This name object is created and returned by a function factory. A function factory must be created before implementing this property.属性
  • ParameterInfo property—The location where the parameters to the function tool are defined. This property returns an IArray of parameter objects (IGPParameter). These objects define the characteristics of the input and output parameters.属性
  • UpdateParameters() method—Called each time a parameter is changed in the tool dialog box or command line. This updates the output data of the tool, which is useful for building models. After returning from UpdateParameters(), geoprocessing calls its internal validation routine, checking that a given set of parameter values are of the appropriate number, data type, and value.方法
  • UpdateMessages() method—Called after returning from the internal validation routine. You can examine the messages created from internal validation and change them if desired.方法
  • Validate() method—Validate is an IGPFunction method and no longer needs to be implemented. You stub it out in your class, but you don't have to provide code for it.方法
  • Execute() method—Executes the tool given the array of parameter values.方法
  • IsLicensed method—Returns whether the function tool is licensed to execute.方法
  • HelpFile property (optional)—The path to a .chm file, which is used to describe and explain the function and its operation.属性(可选)
  • HelpContext property (optional)—The unique context identifier in a [MAP] file (.h).属性(可选)
  • MetadataFile property (optional)—The name of the .xml file containing the default metadata for this function object. The metadata file is used to supply the parameter descriptions in the help panel on the dialog box. If no .chm file is provided, the help is based on the metadata file. See Create documentation for custom Geoprocessing tools that are not models or scripts for details.属性(可选)
  • GetRenderer method (optional)—Used to set a custom renderer for the output of the function tool.方法(可选)
  • DialogCLSID property (not for external use)—For ESRI internal use only. DO NOT IMPLEMENT.属性(可选)

IGPParameter3接口

在设计地理处理功能工具时,第一步是定义参数并设置其属性。IGPParameter3对象用于创建和定义参数的属性。ParameterInfo属性返回参数对象的数组。IGPParameter3属性如下:

  • Name—The name of the parameter, for example, input_featureclass. It must not contain spaces.
  • DisplayName—The UI uses this name to display the parameter name, for example, Input Features. This can be internationalized.
  • Enabled—Controls whether this parameter is enabled or disabled on the UI.
  • ParameterType—The enumeration for setting the type of geoprocessing parameter. There are three parameter types: esriGPParameterTypeRequired, esriGPParameterTypeOptional, and esriGPParameterTypeDerived.
  • Direction—The enumeration for setting the direction of the parameter. The options are esriGPParameterDirectionInput or esriGPParameterDirectionOutput.
  • DataType—Defines the type of data for this parameter. Examples include FeatureClass, Raster, Table, String, and so on. DataType manages the value for the parameter. If the data type is a feature class, a raster cannot be entered as input.
  • Schema—The structure or design of the feature class or table, raster, and workspace container. The design can be field information, geometry information, or extent.
  • Value—This property defines the default value for a parameter. For every data type, there is an associated value. If the data type is a feature class, the default value for the parameter is a feature class. Values are used as the inputs to the tool containing scalars or a path to the data. For a complete list of value objects, see IGPValue.
  • Domain (optional)—The Domain property can be specified to limit or filter a set of values. An example is a domain for a simple value object, limiting an integer to a range of 1 to 100 (RangeDomain).
  • ParameterDependencies (optional)—Used to set one parameter dependent on another parameter. For example, a field parameter is commonly dependent on another table or feature class parameter, and a list of fields is dependent on the input table.
  • ControlCLSID (optional)—A class identifier can be used to override the default control for the DataType.
  • Category (optional)—Creates a collapsible section on the tool dialog box. This is useful for tools with many optional parameters.
  • ChoiceList (optional)—Supplies a choice list for the command line.
  • DefaultEnvironmentName (optional)—Initializes the environment value to use as the default environment for a parameter.
  • DisplayOrder (optional)—The order in which the parameters are listed on the dialog box. The display order is always the order in the array. In the ParameterInfo property, the parameters should be in this order: required, optional, and derived.
  • Altered—Indicates whether the parameter has been explicitly set by the user.
  • HasBeenValidated—Indicates whether the parameter value has been modified since the last time the parameter was validated.

Parameters参数

The following illustration shows part of the Add Field function and how a function’s dialog box is created using an array of GPParameter objects. A function publishes an array of its parameters via ParameterInfo(). The array of GPParameter objects is all that is needed to completely define the tool dialog box.

下图显示了Add Field函数的一部分,以及如何使用GPParameter对象数组创建函数的对话框。函数通过ParameterInfo()发布其参数数组。GPParameter对象数组是完整定义工具对话框所需的全部内容。

Parameters also define the command line syntax for the function as shown in the following illustration:

参数还定义函数的命令行语法,如下图所示:

You must always create a new array in ParameterInfo(); never copy or clone an existing array. The following code example shows the general flow of ParameterInfo():

必须始终在ParameterInfo()中创建新数组;切勿复制或克隆现有数组。下面的代码示例显示了ParameterInfo()的一般流程:

Public IArray Parameterinfo
{
    get
    {
        // Array to hold the parameters. Always create a new array.新建Array,用于存储参数
        IArray parameters = new ArrayClass();

        // Create a parameter and insert it into the parameter array.创建一个参数,并将它注入参数数组
        IGPParameterEdit3 inputParameter = new GPParameterClass();
        parameters.Add(inputParameter);

        // Create and insert more parameters as needed.创建更多参数
        // <Insert any required parameters following the steps shown with inputParameter above.>

        // Return the parameter array.返回参数数组
        return parameters;
    }
}

Direction and ParameterType

Direction是输入或输出。ParameterType是必需的、可选的或派生的。必需和可选可以应用于输入或输出参数。“派生”仅适用于输出参数。请参见以下代码示例:

// Required input parameter.
IGPParameterEdit3 inputParameter = new GPParameterClass();
... inputParameter.Direction =
    esriGPParameterDirection.esriGPParameterDirectionInput;
inputParameter.ParameterType = esriGPParameterType.esriGPParameterTypeRequired;//该参数设置为必选参数

数组中参数的优先顺序是先要求(required),后可选(optional)。在每个参数类型(无论是必需或可选)中,输入参数列在输出参数之前。在命令行和脚本中,所需(required)参数自动用尖括号(<>)显示,可选(optional)参数用花括号({})显示。在“工具”对话框中,未填写的必需参数以绿点显示。

  • 参数类型(派生derived)-派生参数用于指示工具何时更新输入参数。例如,示例工具Calculate area geoprocessing function tool包含一个派生参数。此工具可将字段添加到输入要素类并计算该字段的值。它不需要用户交互,也不显示在工具对话框或命令行上。它在ModelBuilder中用于指示值的更改状态并提供正确的链接。派生参数通常依赖于输入表或要素类参数。如果将“添加字段”拖放到模型中,则派生参数是一个输出变量,如下图所示:

另一个派生参数的例子是getcount工具,它计算表中的行数并输出一个整数值。getcount工具通常用于模型中,以确定选择逻辑的应用程序是否会生成特性或行。Get Count工具的参数包含一个整数输出参数,其ParameterType设置为derived。另一个例子是“创建要素类”工具,它将工作空间和字符串(要素类名称)作为输入,并输出一个新的衍生要素类,该要素类是工作空间和字符串的串联。

下面的示例演示如何创建派生参数:

// Output parameter is derived and data type is same as input.
IGPParameterEdit3 outParameter = new GPParameterClass();
... 

// Set output parameter properties.
outParameter.Direction = esriGPParameterDirection.esriGPParameterDirectionOutput;
outParameter.DisplayName = "Output Feature Class";
outParameter.Name = "output_featureclass";
outParameter.ParameterType = esriGPParameterType.esriGPParameterTypeDerived;
parameters.Add(outParameter);

函数工具可以有任意数量的输出,并且可以使用参数类型的组合。例如,可以具有必需的输出要素类、衍生表、衍生值和可选要素类。但是,函数工具必须始终有一个输出。至少,您的函数应该输出一个包含成功或失败的布尔值。

Name and DisplayName

Name is the language-independent name for the parameter (not localized); DisplayName is the localized name (as it appears in the dialog box) and is contained in resource strings.
A name must not contain spaces and must be unique within a function. As shown in the code example for derived parameters, name can be hard-coded within the function since it is never changed once the function is distributed to users. In code, you are allowed to reference parameters by name. For this reason, do not put the name in a resource file (as is common with DisplayName) since it may be inadvertently localized, which could break your code. Rules for naming parameters are listed as follows:

  • Name parameters are based on the data type (for example, in_features or in_table)
  • Input parameters start with in_, followed by a reference to their data type (for example, in_features or in_table)
  • Output parameters start with out_, followed by a reference to their data type (for example, out_feature_class or out_view)
You can research other functions for parameter naming precedence.

Category

A category is used to group parameters together in the dialog box as shown in the following illustration. Categories are useful when you have many parameters. Using categories can save screen space and allow the user to focus on the primary arguments. Never put required arguments in a category, since the user will not immediately see that they are required.

 

 

DisplayOrder

The default is to show the parameters in the order they appear in the array returned by ParameterInfo(). For legacy support, you can override this by providing a DisplayOrder. If you override, provide a DisplayOrder for each parameter. You are not building legacy functions, so you do not need to use display order; instead, use the order of the parameters in the array, since they match the scripting and command line usage.

Enabled

False means the control is disabled (unavailable). You can set the initial enabled state when building a parameter; however, it’s not necessary because you may be setting the enabled state in UpdateParameters() based on the contents of other parameters. See the following illustration:

Parameter DataTypes

This section describes a number of parameter DataTypes.

Supporting layers and tables

To support layers and table views in ArcMap and ArcGlobe, the DataType for the parameter must be a FeatureLayer, RasterLayer, or TableView. For a complete list of layer DataType objects, see IGPLayerType.
The following code defines the DataType of an input parameter to support feature layers:
// Define input DataType as GPFeatureLayerType to support layers.
IGPParameterEdit3 inputParameter = new GPParameterClass();
inputParameter.DataType = new GPFeatureLayerTypeClass();

Multiple values

Tools such as those that perform batch conversion between different formats can have parameters that allow multiple inputs. The following code example shows how to create a parameter that allows for multiple input feature layers:
// Multivalue parameter of Feature Layers/Feature Classes.
IGPParameterEdit3 inputFeatures = new GPParameterClass();
IGPDataType inputType = new GPFeatureLayerTypeClass();

IGPMultiValueType mvType = new GPMultiValueTypeClass();
mvType.MemberDataType = inputType;

IGPMultiValue mvValue = new GPMultiValueClass();
mvValue.MemberDataType = inputType;

inputFeatures.Name = "input_features";
inputFeatures.DisplayName = "Input Features";
inputFeatures.ParameterType = esriGPParameterType.esriGPParameterTypeRequired;
inputFeatures.Direction = esriGPParameterDirection.esriGPParameterDirectionInput;
inputFeatures.DataType = (IGPDataType)mvType;
inputFeatures.Value = (IGPValue)mvValue;

parameters.Add(inputFeatures);

Lists

In some cases, the parameter may be a table of one or more DataTypes. This DataType is referred to as a ValueTable. An example of this is the Union tool. The input parameter for this tool is a table with two columns. The DataType of the first column is a FeatureLayer and the DataType of the second column is a Long. The following code defines a ValueTable DataType:
// DataType and value.
IGPValueTableType valueTableType = new GPValueTableTypeClass();
IGPValueTable valueTable = new GPValueTableClass();

// First DataType is GPFeatureLayerType.
IGPDataType inputLayerType = new GPFeatureLayerTypeClass();
valueTableType.AddDataType(inputLayerType, "input_features", 75, null);
valueTable.AddDataType(inputLayerType);

// Second DataType is GPLongType.
IGPDataType inputLongType = new GPLongTypeClass();
valueTableType.AddDataType(inputLongType, "Rank", 25, null);
valueTable.AddDataType(inputLongType);

// Set input parameter.
IGPParameterEdit3 inParameter = new GPParameterClass();
inParameter.DataType = (IGPDataType)valueTableType;
inParameter.Value = (IGPValue)valueTable;
...... parameters.Add(inParameter);

Composite

In other cases, the input value for the parameter allows different DataTypes. This is referred to as a Composite DataType. This DataType is used when the parameter can be more than one DataType. An example of this is the Append tool. The input can be a raster, a table, or a feature class. The following code defines a Composite DataType:
// Create the GPCompositeDataType.
IGPCompositeDataType compositeType = new GPCompositeDataTypeClass();

// Create the DataTypes that are permitted as input.
IGPDataType dataType1 = new GPTableViewTypeClass();
IGPDataType dataType2 = new GPRasterLayerTypeClass();

// Add DataTypes.
compositeType.AddDataType(dataType1);
compositeType.AddDataType(dataType2);

// Set the input parameter.
IGPParameterEdit3 inputParameter = new GPParameterClass();
inputParameter.DataType = compositeType;
inputParameter.Value = new GPTableViewClass();

Updating output data descriptions

All tools should update the description of the output data for use in ModelBuilder. By updating the description, subsequent processes in ModelBuilder can recognize changes to the data before a process is run.
The following illustrations show how subsequent processes recognize pending changes. The first illustration shows a model that contains the Add Field and Calculate Field tools. The output data variable for Add Field, Parks (2), is updated to contain the new field, TrackingID. Because the output is updated, the Calculate Field dialog box shows TrackingID in the list of field names.

 

 The next illustration shows a model where the output of the Clip tool is used as input to the Polygon to Raster tool. Since the Clip tool "cookie cuts" the input features, the output feature class has the same properties as the input feature class with one notable exception: its geographic extent. The geographic extent of the output feature class is the geometric intersection of the input features and clip features geographic extents. The Polygon to Raster tool uses the new geographic extent to determine a default cell size.

 

 

With IGPFunction2.ParameterInfo(), you can use a Schema object to set rules for building the description of the output. For example, you can set rules such as the following:
  • Make a copy of the input dataset description and add a new field to its list of fields (such as Add Field), or add a list of fixed fields (such as Add XY Coordinates).
  • Set the list of output fields to be all the fields in a collection of datasets and, optionally, add fields to contain the feature IDs from the collection of datasets (such as Union and Intersect).
  • Set the extent to that of a dataset in another parameter, or the union or intersection (such as Clip) of datasets in a list of parameters.
  • Set a specific geometry type (point, line, or polygon), or set the geometry type to that of a dataset in another parameter, or to minimum or maximum type in a list of parameters. The definition of minimum and maximum geometry type is: points = 0, polylines = 1, and polygons = 2. Consequently, the minimum geometry type in the set (point, polyline, polygon) is point and the maximum is polygon.
The Schema property on the IGPParameterEdit3 interface controls the generation and population of outputs providing you control without having to write validation code as was required prior to ArcGIS 9.3. Not all functions can fully populate the output data; however, there is a list of those properties that must be set. For feature data, feature type, geometry type, field schema, and extent are important. For table data, field schema is important. For raster data, extent, cell size, raster format, and raster type are important. For each group, there is a schema object. These objects all support the IGPSchema interface, which is used to update the output parameter’s value. Each object in the following diagram has its own interface that can be used to set the behavior of how the output parameter value is updated:

 

 

Parameter dependency

You can declare that a parameter is dependent on the value in another parameter. The most common use of parameter dependency is for listing fields in a table. When listing fields, the field parameter is dependent on the input table parameter as shown in the following code example:
// Create the field parameter.
IGPParameterEdit3 fieldParameter = new GPParameterClass();
fieldParameter.DataType = new FieldTypeClass();
... 
// Add dependency to the input feature class parameter by name.
fieldParameter.AddDependency("input_features");
When you create a rule such as "copy the fields of the dataset in parameter 3, then add a field", you have to tell the Schema object what parameter you want to copy from (parameter 3 in this case). This is done by adding dependencies to the parameter object.

Updating output data and using dependencies

This section gives two examples of updating output data and using dependencies.

Add field

Add field copies the definition of an input parameter then adds the user-specified field as shown in the following code:
public IArray ParameterInfo
{
    get
    {
        //Array to hold the parameters.
        IArray parameters = new ArrayClass();
        ... 

        // Output parameter (derived) and data type is DEFeatureClass.
        IGPParameterEdit3 outputParameter = new GPParameterClass();
        outputParameter.DataType = new GPFeatureLayerTypeClass();

        // Value object is DEFeatureClass.
        outputParameter.Value = new DEFeatureClassClass();

        // Set output parameter properties.
        outputParameter.Direction =
            esriGPParameterDirection.esriGPParameterDirectionOutput;
        outputParameter.DisplayName = "Output FeatureClass";
        outputParameter.Name = "out_featureclass";
        outputParameter.ParameterType =
            esriGPParameterType.esriGPParameterTypeDerived;

        // Create a schema object. Schema means the structure or design of the feature class 
        // (field  information, geometry information, extent).
        IGPFeatureSchema outputSchema = new GPFeatureSchemaClass();
        IGPSchema schema = (IGPSchema)outputSchema;

        // Clone the schema from the dependency.
        //This means update the output with the same schema by copying the definition of an input parameter.
        schema.CloneDependency = true;

        // Set the schema on the output, because this tool adds an additional field.
        outputParameter.Schema = outputSchema as IGPSchema;
        outputParameter.AddDependency("input_features");
        parameters.Add(outputParameter);

        return parameters;
    }
}

// This method updates the output parameter value with the additional field.
public void UpdateParameters(IArray paramvalues, IGPEnvironmentManager pEnvMgr)
{
    m_Parameters = paramvalues;

    // Retrieve the input parameter value.
    IGPValue parameterValue = m_GPUtilities.UnpackGPValue(m_Parameters.get_Element(0)
        );

    // Get the derived output feature class schema and empty the additional fields. This ensures 
    // that you don't get dublicate entries. 
    // Derived output is the third parameter, so use index 2 for get_Element.
    IGPParameter3 derivedFeatures = (IGPParameter3)paramvalues.get_Element(2);
    IGPFeatureSchema schema = (IGPFeatureSchema)derivedFeatures.Schema;
    schema.AdditionalFields = null;

    // If you have an input value, create a field based on the field name entered.            
    if (parameterValue.IsEmpty() == false)
    {
        // Area field name is the second parameter, so use index 1 for get_Element.
        IGPParameter3 fieldNameParameter = (IGPParameter3)paramvalues.get_Element(1);
        string fieldName = fieldNameParameter.Value.GetAsText();

        // Check if the input field already exists.
        IField areaField = m_GPUtilities.FindField(parameterValue, fieldName);
        if (areaField == null)
        {
            IFieldsEdit fieldsEdit = new FieldsClass();
            IFieldEdit fieldEdit = new FieldClass();
            fieldEdit.Name_2 = fieldName;
            fieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;
            fieldsEdit.AddField(fieldEdit);

            // Add the additional field to the derived output.
            IFields fields = fieldsEdit as IFields;
            schema.AdditionalFields = fields;
        }
    }
}

Clip

Clip makes a copy of the input feature's definition, then sets the extent to the intersection of the input features and the clip features. The following code example shows how this rule is implemented in ParameterInfo():
public IArray ParameterInfo
{
    get
    {
        //Array to hold the parameters.
        IArray parameters = new ArrayClass();
        ... 
        // New output features.
        outParameter = new GPParameterClass();
        outParameter.DataType = new DEFeatureClassTypeClass();
        outParameter.Value = new DEFeatureClassClass();
        outParameter.Direction =
            esriGPParameterDirection.esriGPParameterDirectionOutput;
        outParameter.ParameterType = esriGPParameterType.esriGPParameterTypeRequired;
        outParameter.Name = "Output_Feature_Class";
        outParameter.DisplayName = "Output Feature Class";

        // Set the dependencies for the output and its schema properties.
        outParameter.AddDependency("input_features");
        outParameter.AddDependency("clip_features");

        // Feature type, geometry type, and fields all come from the first dependent—the input features.
        IGPFeatureSchema outSchema = new GPFeatureSchemaClass();
        outSchema.FieldsRule =
            esriGPSchemaFieldsType.esriGPSchemaFieldsFirstDependency;
        outSchema.FeatureTypeRule =
            esriGPSchemaFeatureType.esriGPSchemaFeatureFirstDependency;
        outSchema.GeometryType = esriGeometryType.esriGeometryPolygon;
        outSchema.ExtentRule = esriGPSchemaExtentType.esriGPSchemaExtentIntersection;

        IGPSchema schema = outSchema as IGPSchema;
        // Generate the default output path.
        schema.GenerateOutputCatalogPath = true;
        outParameter.Schema = (IGPSchema)outSchema;

        parameters.Add(outParameter);

        return parameters;
    }
}
The previous Clip example modifies Schema in ParameterInfo(), but UpdateParameters() does nothing in return. Add Field, however, modifies Schema in UpdateParameters() because it doesn't know the definition of the field to add until you provide the information and UpdateParameters() is called.
Think of these two examples as static versus dynamic. Clip doesn't rely on anything other than the datasets in the dependent parameters (static case), whereas Add Field needs to examine other parameters (such as field name and field type) that are not dependent parameters (dynamic case).
This static and dynamic behavior is evident in the way a tool validation is performed as shown in the following steps:
  1. When the tool dialog box is opened, ParameterInfo() is called. You set the static rules for describing the output. No output description is created since you haven't specified values for the parameters.
  2. Once you interact with the tool dialog box, UpdateParameters() is called. UpdateParameters() can modify Schema to account for dynamic behavior that can't be determined from the parameter dependencies, such as adding a new field (Add Field) for example.
  3. After returning from UpdateParameters(), the internal validation routines are called, and the rules in the Schema object are applied to update the description of the output data.
  4. UpdateMessages() is called. You can examine the warning and error messages that internal validation may have created and modify them, or add warnings and errors based on the interaction of actual parameter values.
When you set the IGPSchema.CloneDependency property to true, you are instructing geoprocessing to make an exact copy (clone) of the description in the first dependent parameter in the parameter dependency list. You set IGPSchema.CloneDependency to true in the ParameterInfo() property, not in the UpdateParameters() method.
If the ParameterType of the output parameter is set to derived, an exact copy is made. This is the behavior of the Add Field tool.
If the ParameterType is set to required, an exact copy is also made, but the catalog path to the dataset is changed. Since most tools create new data, this is the most common behavior. Clone can be thought of as setting the initial state of the output.

Domains

Domains are used to supply a fixed set of values for a parameter or to filter values for a parameter. The most common uses for domains are as follows:
  • Defining input feature types (point, line, polygon)
  • Creating a fixed list of string keywords (point, multipoint, polygon, polyline)
  • Defining a Boolean choice
  • Filtering field types (text, long, double, object ID, and so on)

Feature type

If the input features can only be points, geoprocessing uses a domain to build the choice list of layers or features in the catalog minibrowser. The filtering occurs when the data type validates the value. In ParameterInfo(), the input feature class parameter is built where a domain is used to filter the input feature classes to only polygon features as shown in the following code example:
// Filter the input features to polygon features only.
IGPFeatureClassDomain fcDomain = new GPFeatureClassDomainClass();
fcDomain.AddFeatureType(esriFeatureType.esriFTSimple);
fcDomain.AddType(esriGeometryType.esriGeometryPolygon);
... 

inputParameter.Domain = (IGPDomain)fcDomain;

String keywords

The following code example is from the Add Field function and shows how to build a coded value domain containing keywords for field type (that is, text, float, double, and so on). These keywords are all hard coded in the function since they are never changed once the function is released to users. You can use these hard-coded strings in code, such as in if/then/else logic. For this reason, do not put the keywords in a resource file since they can be inadvertently localized, which could break your code. Do not localize keywords. Keywords should appear in all capital letters. Syntactically, they must be listed with the default keyword first. In documentation, the default keyword is followed by all other keywords separated with a vertical bar (|). (For example, POINT | LINE | POLYGON).
// Create a fixed list of string values. 
IGPCodedValueDomain cvDomain = new GPCodedValueDomainClass();
cvDomain.AddStringCode("TEXT", "TEXT");
cvDomain.AddStringCode("FLOAT", "FLOAT");
... inputParameter.Domain = IGPDomain(cvDomain);

Boolean parameters

Boolean parameters contain a coded value domain with Boolean values and corresponding string codes. In a dialog, Boolean parameters show as a check box, but in command line and scripting, they show as a choice between two strings. You should always use a coded value domain for a Boolean parameter as shown in the following code example:
// Always create a coded value domain for Boolean parameters.
IGPParameterEdit3 pContinueCompare = new GPParameterClass();
... IGPCodedValueDomain pContinueDomain = new GPCodedValueDomainClass();
IGPBoolean pVal1 = new GPBooleanClass();
pVal1.Value = true;
IGPBoolean pVal2 = new GPBooleanClass();
pVal2.Value = false;

pContinueDomain.AddCode((IGPValue)pVal1, "CONTINUE_COMPARE");
pContinueDomain.AddCode((IGPValue)pVal2, "NO_CONTINUE_COMPARE");
... pContinueCompare.Domain = (IGPDomain)pContinueDomain;

Dynamic domains

Domains can be dynamic—their values are set in UpdateParameters()—as opposed to static—the CodedValue domain of keywords constructed in ParameterInfo(). For example, you have a parameter containing keywords, but you want the keywords to change depending on another parameter; that is, you want one set of keywords if point features are input, and another set if line features are input. This is not unusual, and the pattern you’ll see most often is to populate the domain of the parameter in UpdateParameters(). Another example is a coded value domain of SDE configuration keywords. The list changes based on the workspace selected. The UpdateParameters() section provides an example of updating dynamic domains.

ControlCLSID

GPDataType has a default UI control named ControlCLSID. For many parameters, the data type’s default control is all you'll use. With other parameters, especially strings, you may want to use another UI control. String parameters are ubiquitous, and there are two methods by which you can change the UI for string input. You can use a domain, as previously described, to create a drop-down list of strings, or, you can use a different (non-default) control. The following illustration shows the default string control and the multivalue control for the same set of strings:

 

 The following code example shows how the multiple value control is used to present a checklist of strings:

// Create Accumulators parameters.
IGPParameterEdit3 pAccumulators = new GPParameterClass();

IGPDataType pGPDataType2 = new GPStringTypeClass();
IGPMultiValue pMultiValue2 = new GPMultiValueClass();
pMultiValue2.MemberDataType = pGPDataType2;

IGPCodedValueDomain pAccumulatorsDomain = new GPCodedValueDomainClass();
pAccumulatorsDomain.AddStringCode("Minutes", "Minutes");
pAccumulatorsDomain.AddStringCode("Meters", "Meters");

IGPMultiValueType pMultiValueType2 = new GPMultiValueTypeClass();
pMultiValueType2.MemberDataType = pGPDataType2;

pAccumulators.Name = "accumulators";
pAccumulators.DisplayName = "Accumulators";
pAccumulators.ParameterType = esriGPParameterType.esriGPParameterTypeOptional;
pAccumulators.Direction = esriGPParameterDirection.esriGPParameterDirectionInput;
pAccumulators.Domain = (IGPDomain)pAccumulatorsDomain;
pAccumulators.DataType = (IGPDataType)pMultiValueType2;
pAccumulators.Value = (IGPValue)pMultiValue2;

// MdList Control's GUID—Use OLE Object view to get this.
UID pUID = new UIDClass();
pUID.Value = "{38C34610-C7F7-11D5-A693-0008C711C8C1}";
pAccumulators.ControlCLSID = pUID;

m_pParameters.Add(pAccumulators);

Methods

This section describes a number of geoprocessing methods.

UpdateParameters()

This method has been previously discussed and demoed. Additional use cases of UpdateParameters() are described as follows:
  • Parameter interaction—For some tools, it may be necessary to set rules for parameters. For example, when adding a field to an input table, one rule may be to limit the length of the field name by setting a maximum number of allowable characters. Another parameter interaction is enabling and disabling parameters. For instance, when using Add Field and selecting TEXT as the type of field to add, the field length parameter is enabled. The following code is an example of enabling and disabling a parameter based on user input:
// Get the Boolean parameter value (second parameter for this tool).
IGPBoolean val1 = (IGPBoolean)pGPUtilities.UnpackGPValue(m_Parameters.get_Element(1))
    ;

// Get the string parameter (third parameter for this tool).
IGPParameterEdit3 stringParam = (IGPParameterEdit3)m_Parameters.get_Element(2);

if (val1.Value == true)
{
    stringParam.Enabled = false;
}

else
{
    stringParam.Enabled = true;
}

Domains can also change based on user inputs and can be dynamic as explained previously. The following code is an example of updating a coded value domain in UpdateParameters():

// Get the Boolean parameter value (second parameter for this tool).
IGPBoolean val1 = (IGPBoolean)pGPUtilities.UnpackGPValue(m_Parameters.get_Element(1))
    ;

// Get the coded value parameter.
IGPParameter3 cvParam = (IGPParameter3)m_Parameters.get_Element(3);
IGPParameterEdit3 cvParamEdit = cvParam as IGPParameterEdit3;

IGPCodedValueDomain cvDomain;

// If the Boolean parameter value is true, update the domain with new values.
if (val1.Value == true)
{
    stringParam.Enabled = true;
    cvDomain = new GPCodedValueDomainClass();
    cvDomain.AddStringCode("Seconds", "Seconds");
    cvDomain.AddStringCode("Feet", "Feet");
    cvParamEdit.Domain = cvDomain as IGPDomain;
}
  • Setting a default value—The following code is an example of setting a default value for a parameter. This default value will be set if the parameter has not been altered or is blank.
//  Set a default distance value if the user has not set a specific distance (Altered is true).
IGPParameter3 distParam = (IGPParameter3)m_Parameters.get_Element(7);
if (distParam.Altered == false)
{
    distParam.Value.SetAsText("100");
}

UpdateMessages()

This method is called after returning from the internal validation routine performed by the geoprocessing framework. This method is where you can examine the messages created from internal validation and change them if desired. Only change existing messages; do not add new messages. The following code is an example of updating an error message for a parameter:
// Check if the distance is greater than zero.
IGPLinearUnit distVal = (IGPLinearUnit)pGPUtilities.UnpackGPValue
    (paramvalues.get_Element(7));

if (distVal.Value <= 0)
{
    Messages.ReplaceError(7, 2, 
        "Zero or a negative distance is invalid when using a fixed distance band. Use a positive value greater than zero.");
}

Validate()

The Validate() method no longer needs to be implemented.
Validate() is used to perform a lightweight verification that a given set of parameter values were of the appropriate number, data type, and value. At ArcGIS 9.3, this method was replaced by UpdateParameters() and UpdateMessages() and no longer needs to be implemented. It must be stubbed out in the function class, but no coding is required, and it can be set as shown in the following code:
public IGPMessages Validate(IArray paramvalues, bool updateValues,
    IGPEnvironmentManager envMgr)
{
    return null;
}

Execute()

Internally, the geoprocessing framework calls the internal validate process before performing Execute(). If the validation passes, only then is Execute() called.
The arguments to the Execute() method include an array of parameter values, a GPMessages object, a TrackCancel object, and GPEnviromentManager. The GPMessages object is used for returned messages that indicate if the function failed. The TrackCancel object is used to allow the functions to cancel the operation and track its progress. The GPEnvironmentManager provides access to current environments and geoprocessing settings.
Execute() has the following roles:
  • Opens datasets and verifies all inputs are valid—Opening the input datasets means creating objects from the inputs. For example, if the input value is a path to a feature class, create an IFeatureClass object. This ensures that this data still exists and is not locked by another application. The same is true for other inputs, such as Fields.
  • Checks if the Overwrite Output setting is true or false—If your tool creates new output data, you must check if the OverwriteOutput setting is true of false. If the setting is true, then it is necessary to delete the existing output before performing the operation. The following code example shows how to check for the OverwriteOutput setting:
// Check the overwrite output option.
IGeoProcessorSettings gpSettings = (IGeoProcessorSettings)envMgr;
if (gpSettings.OverwriteOutput == true)
{
    // Check if the output exists.
    if (m_GPUtilities.Exists(outputValue))
    {
        m_GPUtilities.Delete(outputValue);
    }
}

else
{
    if (m_GPUtilities.Exists(outputValue))
    {
        message.AddError(2, "Output already exists: " + outputValue.GetAsText());
    }
}
  • Executes the function—Executes the code to perform the operation.

Objects

This section describes a number of geoprocessing objects.

GPEnvironmentManager

GPEnvironmentManager is the managing object for environments and settings used by the geoprocessing tools. GPEnvironmentManager is passed to each tool for use during UpdateParameters(), UpdateMessages(), and Execute(). The tool then has access to current environments and settings of the current application. The following code shows how to get the extent environment by name for a list of environment names:
IGPEnvironment gpExtent = pEnvMgr.FindEnvironment("extent");

GPMessages

The GPMessages object manages an array of GPMessage objects. This object contains methods to generate and replace message objects. The UpdateMessags() method is passed an existing GPMessages object and replaces or updates messages as needed. The Execute() method is passed an existing GPMessages object and adds new messages as needed.

GPMessage

The GPMessage object is composed of a message type, error code, and description. The message type can be an error, a warning, or informative.

GPUtilities

The GPUtilities object contains many useful helper methods for the function writer. For a complete list of helper methods, see IGPUtilities and IGPUtilites2. In the sample tool provided, many helper methods are used including the following:
  • UnPackGPValue()—Gets the value from the parameter and creates a GPValue object.
  • PackGPValue()—Places the GPValue object into the parameter.
  • Exists()—Returns whether or not the input value exists.
  • Delete()—Deletes the data.
  • Open()—Opens the data source associated with the value.
  • DecodeFeatureLayer—Returns the feature class and query filter specified by the given geoprocessing value object. This should be used when the input is a GPFeatureLayerType. This ensures you open the feature class and retrieve any existing query filter.
  • DecodeTableView—Returns the table and query filter specified by the given geoprocessing value object. This ensures you open the table and retrieve any existing query filter.

Implementing IGPFunctionFactory

Once the GPFunction tool is created, it must be made accessible. This is accomplished by creating a GPFunctionFactory. The factory is responsible for handing out the function name objects for each function. This factory is registered to the component category CATID_GPFunctionFactories. In most cases, a function factory is a logical grouping of tools. Thus, a single Dynamic Link Library (DLL) can contain one factory with multiple functions. The IGPFunctionFactory properties and methods are as follows:
  • CLSID property—The class ID of the factory.
  • Name property—Name of the function factory. This is used when generating the toolbox containing the factory function. This can be internationalized.
  • Alias property—Alias name of the factory. This is used when specifying the functions contained in the factory from the command line or scripting.
  • GetFunction() method—Creates and returns a function object based on the input name.
  • GetFunctionName() method—Creates and returns a function name object based on the input name.
  • GetFunctionNames() method—Creates and returns an enumeration of function names that the factory supports.
  • GetFunctionEnvironments() method (optional)—Creates and returns an enumeration of GPEnvironment objects. If tools published by this function factory require new environment settings, define additional environment settings here. This is similar to how parameters are defined.



See Also:

Sample: Calculate area geoprocessing function tool

 

posted on 2020-11-17 11:54  XiaoNiuFeiTian  阅读(1078)  评论(0编辑  收藏  举报