In this topic
- About creating a custom function tool class
- Define tool, display, and function names
- Define parameters
- Define the tool operation
- Implement parameter interaction
- Verify parameters and update messages
- Check for license
- Populate the help panel
- What's next
About creating a custom function tool class
A function tool defines the input and output parameters of the tool and the tool's geographic information system (GIS) operation. To create a custom function tool, you need to create a Java class that extends the BaseGeoprocessingTool abstract class and override its methods to suit your custom function tool. These steps to override the are explained in the following subsections.
Define tool, display, and function names
To define the tool name of your custom tool, you need to override the getName() method. The tool name appears when executing the tool at the command line and in scripting. The name must be unique to each toolbox and cannot contain spaces.
You can also define a user-friendly display name to identify the custom tool in ArcToolbox by overriding the getDisplayName() method. The display name can also be localized.
You also need to override the getFullName() method to specify the full name of the tool. Unlike the tool name and display name, the full name of the tool is not a string variable; it is a FunctionName object. The getFullName() method must return a FunctionName object created by its custom function factory. A FunctionName object is a utility object created by the tool's function factory to manage the tool. The properties of a FunctionName object include the tool's name, its description, and a reference to the function factory.
For more information about the FunctionName object, see Creating a custom function factory class.
The following code snippet shows how to implement the methods described here:
[Java]
class GPCalculateArea extends BaseGeoprocessingTool{
private String toolName = "JavaCalculateArea";
private String displayName = "Java Calculate Area";
/**
* This is the name of the function tool.
* The tool name appears when executing the tool at the command line and in scripting.
* The tool name should be unique to each toolbox and must not contain spaces.
*/
public String getName()throws IOException, AutomationException{
return toolName;
}
/**
* This is the display name of the function tool.
* The user interface uses this property to display the name of the tool in
* ArcToolbox. The display name is a user-friendly description of the function tool.
* The display name can be localized.
*/
public String getDisplayName()throws IOException, AutomationException{
return displayName;
}
/**
* This is the FunctionName object of the geoprocessing function tool.
* The FunctionName object is created and returned by the function factory. A function factory must
* be created before implementing this method.
*/
public IName getFullName()throws IOException, AutomationException{
return (IName)new CustomFunctionFactory().getFunctionName(toolName);
}
//Implement other methods.
}
Create the function factory class before you create the function tool class.
Define parameters
Tool parameters are the data on which the tool operates during its execution. A tool parameter can be an input or output parameter. An input parameter is the data on which the tool is executed and an output parameter stores the result from the tool's execution. There can be any number of input and output parameters for a tool. However, a function tool must define at least one input and one output parameter.
Custom tool parameters are provided to the geoprocessing framework by the getParameterInfo() method. The getParameterInfo() method returns an array of parameters for the tool.
Each tool parameter in the parameter array is represented by a GPParameter object. The state of the tool parameters is defined by the properties of the GPParameter object. The following illustration shows part of the Add Field tool dialog box and how a tool's dialog is created using an array of GPParameter objects:
To define the parameter of your custom tool, override the getParameterInfo() method. The method implementation must create a GPParameter object for each input as well as output parameters required for the tool. The initial state of the GPParameter object's properties must also be set. Essential properties that must be set initially are described in the following table:
Property
|
Method
|
Description
|
Notes
|
Name
|
The name of the parameter, for example, in_featureclass.
|
A name must not contain spaces and must be unique within a function. A parameter name can be hard-coded within the function since it is never changed once the function is distributed to the user. You can reference parameters by name in the code. 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. The rules for naming parameters are as follows:
|
|
DisplayName
|
The geoprocessing UI uses the display name to display the parameter name in the tool dialog box, for example, Input Features.
|
This can be localized as needed.
|
|
Direction
|
An enumeration that distinguishes between the input and output parameters. The enumerated values are esriGPParameterDirectionInput (for the input parameter) and esriGPParameterDirectionOutput (for the output parameter).
|
A geoprocessing tool must have at least one parameter defined as output. At a minimum, your function tool must output a Boolean value to communicate success or failure.
|
|
ParameterType
|
An enumeration that indicates to the geoprocessing framework the importance of the parameter for the successful execution of the tool. The parameter types are as follows:
|
esriGPParameterTypeDerived applies only to output parameters and does not appear in the tool dialog box or in the command line.
|
|
DataType
|
In geoprocessing, the data type of a tool parameter is identified by a GPDatatype object. A GPDatatype object defines the type of data that is acceptable for the parameter. Examples of GPDataType objects include the following:
Assigning a GPDatatype object enables the geoprocessing framework to create an appropriate UI dialog in the tool dialog box that does not accept parameters of any other data type. A GPDatatype object also enables the framework to validate the parameter input entered by the user and raise appropriate warnings and errors.
|
All implementing classes of IGPDataType are considered GPDataType objects.
For more information on data types, see Geoprocessing tool parameter data types.
For a complete list of GPDataTypeArcObjects, see IGPDataType.
|
|
Value
|
Assigns a GPValue object for a parameter. For each geoprocessing parameter data type, there is a corresponding value object. For example, if the data type is GPFeatureLayerType, the value object for the parameter is GPFeatureLayer.
|
All implementing classes of IGPValue are considered GPValue objects.
For a complete list of GPValue objects, see IGPValue.
|
|
Enabled
|
Controls whether the parameter is enabled or disabled on the UI dialog.
|
The following code snippet shows how to create input and output parameters for a custom function tool in the getParameterInfo() method as previously discussed. The tool described in the code snippet adds a new field to the polygon feature class and assigns the corresponding area of the polygon as its value.
The following parameters are defined in the getParameterInfo() method of the tool's Java class:
-
in_features—A feature layer for which the area should be calculated.
-
in_fieldName—The name of the new field.
-
out_features—The output feature layer. (A new feature layer must not be created; rather, the input feature layer must be modified. ParameterType must be derived)
// Returns an array of parameters for execution of the tool.
public IArray getParameterInfo()throws IOException, AutomationException{
//Create an array for parameter objects.
IArray parameters = new Array();
GPParameter inputParameter = new GPParameter();
//Define parameter 1 (the input feature class)
inputParameter.setName("in_features");
inputParameter.setDisplayName("Input Features");
//The parameter is defined as an input parameter.
inputParameter.setDirection
(esriGPParameterDirection.esriGPParameterDirectionInput);
//The parameter is required for execution of the tool.
inputParameter.setParameterType(esriGPParameterType.esriGPParameterTypeRequired);
//Define the data type and value for the parameter.
inputParameter.setDataTypeByRef(new GPFeatureLayerType());
inputParameter.setValueByRef(new GPFeatureLayer());
//Add parameter 1 to the array.
parameters.add(inputParameter);
//Define parameter 2 (the field name parameter).
inputParameter = new GPParameter();
inputParameter.setName("in_fieldName");
inputParameter.setDisplayName("Area Field Name");
//The parameter is defined as an input parameter.
inputParameter.setDirection
(esriGPParameterDirection.esriGPParameterDirectionInput);
//The parameter is required for execution of the tool.
inputParameter.setParameterType(esriGPParameterType.esriGPParameterTypeRequired);
//Define the data type of the parameter.
inputParameter.setDataTypeByRef(new GPStringType());
// Define the value of the parameter.
IGPString gpStringValue = new GPString();
inputParameter.setValueByRef((IGPValue)gpStringValue);
//Add parameter 2 to the array.
parameters.add(inputParameter);
//Define parameter 3 (the output feature class).
IGPParameterEdit outputParameter = new GPParameter();
outputParameter.setName("out_features");
outputParameter.setDisplayName("Output FeatureClass");
//The parameter is defined as an output parameter.
outputParameter.setDirection
(esriGPParameterDirection.esriGPParameterDirectionOutput);
//The parameter type is defined as derived, since the input feature class will be modified, and a
// new feature class will not be created.
//When defined as derived, the parameter does not appear in the tool dialog box.
outputParameter.setParameterType(esriGPParameterType.esriGPParameterTypeDerived);
//The parameter data type and value are defined.
outputParameter.setDataTypeByRef(new GPFeatureLayerType());
outputParameter.setValueByRef(new GPFeatureLayer());
//Add parameter 3 to the array.
parameters.add(outputParameter);
//Return the parameter array.
return parameters;
}
The code snippet above creates a tool dialog box as shown in the following screen shot (in this case, the Calculate Area tool). The green dots indicate the parameters are required for operation of the tool.
The derived output parameter is not shown.
The recommended order of precedence for parameters in the array is those that are required are first, those that are optional are last. Within each parameter type (required or optional), input parameters are listed before output parameters. In the command line and scripting, required parameters are automatically shown in angle brackets (<>), while optional parameters are shown in curly brackets ({}). In the tool dialog box, required parameters that are not filled in are shown with a green dot.
Two additional methods of the GPParameter object are shown in the following table:
Property
|
Method
|
Description
|
Notes
|
altered
|
Indicates whether the parameter has been explicitly set or altered by the user.
|
Programmatically changing a value with a validation code does not change the altered state. That is, if you set a default value for a parameter programmatically, the altered state does not change.
|
|
HasBeenValidated
|
Indicates whether the parameter value has been modified since the last time the parameter was validated by the geoprocessing framework.
|
|
Define the tool operation
The geoprocessing framework invokes the BaseGeoprocessingTool.execute() method to operate the tool. You must override the execute() method to define your tool's operation. To implement the execute() method, perform the following steps:
- Open the datasets of the corresponding input parameters and verify 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.
- Confirm whether the Overwrite Output setting is true or false—If the tool creates output data, you must check if the OverwriteOutput property is true or false. If the setting is true, you must delete the existing output before performing the operation.
- Implement operation of the tool
The geoprocessing framework exposes the following objects as arguments of the execute() method for implementation:
- GPMessages—Delivers appropriate errors, warnings, and messages about parameters. GPMesages also enables you to add errors, warnings, or messages about ToolProcessing and its success or failure. ToolProcessing messages are flushed to the console or the corresponding output during the tool's execution.
- TrackCancel—The execute() method must monitor this object, and must cancel the tool's operation based on user action.
- GPEnviromentManager—Provides access to current environments and geoprocessing settings of the geoprocessing framework.
Internally, the geoprocessing framework calls the internal validate process before performing execute(). If the validation fails, the execute() method is not invoked.
The following code snippet illustrates the execute() method of the Calculate Area tool whose GIS operation adds a new field to the polygon feature class and populates it with the area of the corresponding feature shape:
[Java]
public void execute(IArray paramvalues, ITrackCancel trackcancel,
IGPEnvironmentManager envMgr, IGPMessages message)throws IOException,
AutomationException{
//Open the datasets.
// Get the first input parameter.
IGPParameter parameter = (IGPParameter)paramvalues.getElement(0);
// UnPackGPValue. This ensures you get the value from either the data element or GpVariable (ModelBuilder).
IGPValue parameterValue = this.gpUtilities.unpackGPValue(parameter);
// Open the input dataset.
IDataset inputDataset = this.gpUtilities.openDataset(parameterValue);
IFeatureClass inputFeatureClass = new FeatureClass(inputDataset);
//Check the overwrite output since you'll modify the input feature class.
GeoProcessor geoprocessor = new GeoProcessor();
if geoprocessor.isOverwriteOutput(){
//Implement the tool operation.
// 1. Add the new field.
int indexA;
parameter = (IGPParameter)paramvalues.getElement(1);
String field = parameter.getValue().getAsText();
indexA = inputFeatureClass.findField(field);
if (indexA < 0){
IFieldEdit fieldEdit = new Field();
fieldEdit.setType(esriFieldType.esriFieldTypeDouble);
fieldEdit.setName(field);
inputFeatureClass.addField(fieldEdit);
indexA = inputFeatureClass.findField(field);
}
//2. Calculate the area and populate the new field.
IFeatureCursor updateCursor = inputFeatureClass.IFeatureClass_update(null,
false);
IFeature updateFeature = updateCursor.nextFeature();
IGeometry geometry;
IArea area;
double dArea;
while (updateFeature != null){
geometry = updateFeature.getShape();
area = (IArea)geometry;
dArea = area.getArea();
updateFeature.setValue(indexA, dArea);
updateCursor.updateFeature(updateFeature);
updateFeature.store();
updateFeature = updateCursor.nextFeature();
}
//Add message
messages.addMessage("\tArea Calculated");
}
}
Implement parameter interaction
Parameter interaction enables you to filter or set values for a parameter based on values of other parameters entered by the user in the tool dialog box. For example, you can enable or disable specific parameters or change a parameter's default value based on user input of other parameter values.
The following screen shots show the Add Field tool dialog box. The Add Field tool adds a new field to a feature class. Initially, the Field Length input parameter is enabled (as shown in the screen shot on the left). When the user inputs the Field Type value as Long, the Field Length input is disabled (as shown in the screenshot on the right). The Filed Length value is enabled only if the Field Type value is Text.
Parameter interaction in a tool is achieved by overriding the BaseGeoprocessingTool.updateParameters() method. The updateParameters() method is invoked by the geoprocessing framework each time a parameter value in the tool dialog box or in the command line is entered or modified. This provides an opportunity to alter the state of the parameters based on the input parameter values.
Another example of parameter interaction is setting the default value of a parameter that has not been altered or left blank by the user based on other parameters. In the case of the GPCalculateArea function tool, the field name parameter is initially left blank. When the user enters the inputFeatureClass parameter, the GPCalculateArea tool examines the field names of the feature class entered by the user. If there is no field in the feature class named Area, the field name value is automatically set to Area.
The following code snippet shows this scenario implemented by the updateParameters() method of the GPCalculateArea tool:
[Java]
//Set the default value as Area if there is no other field named Area.
public void updateParameters(IArray paramvalues, IGPEnvironmentManager pEnvMgr){
IGPParameter3 input_feature = (IGPParameter3)paramvalues.getElement(0);
try{
//Check whether the parameter has been altered by the user.
if (input_feature.isAltered()){
//Get the feature class value for the parameter.
IGPValue parameterValue = this.gpUtilities.unpackGPValue(input_feature);
IDataset inputDataset = this.gpUtilities.openDataset(parameterValue);
IFeatureClass inputFeatureClass = new FeatureClass(inputDataset);
int fieldno = inputFeatureClass.findField("Area");
//Confirm there is no other field named Area.
if (fieldno < 1){
IGPParameterEdit3 input_fieldname = (IGPParameterEdit3)
paramvalues.getElement(1);
IGPString fieldName = new GPString();
fieldName.setValue("Area");
//The value of the field name parameter is set as Area.
input_fieldname.setValueByRef((IGPValue)fieldName);
}
}
}
catch (Exception e){
System.out.println(e);
}
}
Verify parameters and update messages
It is critical to verify the values of the tool parameters entered by the user. The geoprocessing framework validates parameters based on data type. However, special conditions and restrictions for the parameters, if any, need to be explicitly implemented. For example, in the GPCalculateArea custom function tool, tool execution fails if the feature shape type is not polygon. The geoprocessing framework verifies that the input parameter value is a feature class; however, the feature's geometry type is not verified by the geoprocessing framework.
You can override the BaseGeoprocessingTool.updateMessages() method to examine the parameter values for special conditions and to inform the user about possible errors and warnings. When the user alters a tool's parameter value, the geoprocessing framework validates the input data and invokes the updateParameters() and updateMessages() methods. In the updateMessages() method implementation, you can verify the parameter values and update the error and warning messages as required. You can also examine and change the messages created by the geoprocessing framework regarding data validation.
The following screen shot shows an example of feature geometry type verification of the GPCalculateArea tool. The updateMessages() method is implemented to verify the feature geometry type of the feature class entered by the user and to flag appropriate error messages.
This scenario is shown in the following code snippet of the GPCalculateArea custom function tool:
[Java]
public void updateMessages(IArray paramvalues, IGPEnvironmentManager pEnvMgr,
IGPMessages messages){
IGPParameter3 input_feature = (IGPParameter3)paramvalues.getElement(0);
try{
//Check if the parameter value has been changed by the user.
if (input_feature.isAltered()){
//Get the feature class.
IGPValue parameterValue = this.gpUtilities.unpackGPValue(input_feature);
IDataset inputDataset = this.gpUtilities.openDataset(parameterValue);
IFeatureClass inputFeatureClass = new FeatureClass(inputDataset);
//Verify the shape type. If it's not polygon, set error message.
if (inputFeatureClass.getShapeType() !=
esriGeometryType.esriGeometryPolygon){
messages.replaceError(0,
esriGPMessageSeverity.esriGPMessageSeverityError,
"Feature Type not a polygon");
}
}
catch (Exception e){
System.out.println(e);
}
}
The updateParameters() and updateMessages() methods are invoked by the framework each time a user interacts with the dialog box. If you include time consuming operations in your implementation of these methods, it may affect the response time of the tool dialog.
Check for license
If the operation of your custom geoprocessing tool requires specific ArcGIS licenses, you must check the existing license level by overriding the isLicensed() method.
The following code snippet checks the ArcView product license and informs the user of the status:
[Java]
public boolean isLicensed()throws IOException, AutomationException{
AoInitialize aoInit = new AoInitialize();
String licensedProductName = aoInit.getLicenseProductName
(esriLicenseProductCode.esriLicenseProductCodeArcInfo);
//Check the product license level.
if (licensedProductName.equalsIgnoreCase("ArcInfo")){
System.out.println(toolName + ": licensedProductName: " +
licensedProductName);
//Check out extensions here if required.
return true;
}
else{
System.out.println(toolName + ": licensedProductName: " +
licensedProductName + " ArcInfo License level required");
return false;
}
return true;
}
Populate the help panel
The geoprocessing framework allows you to provide information about the tool's operation and its parameters in the help panel of the tool dialog box. In the following screen shot, the help panel provides information about the XY Tolerance parameter of the Clip tool:
To open the help panel, click the Show Help button; to close the help panel, click the Hide Help button.
The parameter descriptions of a function tool are derived from a metadata file (in Extensible Markup Language [XML] file format) that resides in the %ArcGISHOME%/help/gp folder. In the case of a custom function tool, you need to create a metadata file in the %ArcGISHOME%/help/gp folder, and ensure that the getMetaDataFile() method provides the name of the metadata file for the tool as shown in the following code.
The metadata file name must be the custom function tool name concatenated with the name of the custom function factory.
//Define the class variable for the tool name.
private String toolName = "JavaCalculateArea";
public String getMetadataFileName(){
return this.getName() + ".xml";
}
public String getName()throws IOException, AutomationException{
return toolName;
}
What's next
Once the custom function tool class and the custom function factory class are created, their corresponding Java .class files must be bundled in a Java Archive (JAR) file and deployed to ArcGIS by placing the JAR file in the <ArcGIS Install Dir>/java/lib/ext folder. After deployment, the custom geoprocessing function tool can be accessed as follows:
- In ArcToolbox, the custom geoprocessing function tool can be accessed in the same manner as other ArcGIS geoprocessing tools.
- In ArcGIS Engine applications, the tool must be wrapped in a toolbox.
- In ArcGIS Server applications, the toolbox containing the custom geoprocessing tool must be published to ArcGIS Server. The custom tool can then be accessed in the same manner as other ArcGIS geoprocessing tools.
For more information about accessing and consuming custom geoprocessing tools in ArcToolbox and in ArcGIS Engine and ArcGIS Server applications, see the following topics:
- How to consume custom tools in ArcToolbox
- How to consume custom geoprocessing tools in Java applications
An ArcGIS application (ArcGIS Engine, ArcMap, ArcCatalog, and ArcGIS Server) recognizes the custom geoprocessing function tool when the application is started. If the ArcGIS application is already running, then it needs to be restarted after deployment. While testing the tool, if you modify the code in the Java classes bundled in the JAR file, the JAR file must be recreated and redeployed. You also need to restart the ArcGIS application after redeployment.
See Also:
How to build custom geoprocessing toolsCreating a custom function factory class
Development licensing | Deployment licensing |
---|---|
Engine Developer Kit | Engine |
Server | Server |
ArcGIS for Desktop Basic | ArcGIS for Desktop Basic |
ArcGIS for Desktop Standard | ArcGIS for Desktop Standard |
ArcGIS for Desktop Advanced | ArcGIS for Desktop Advanced |