For an overview of the ToolValidator class and use of parameter methods, see Customizing script tool behavior.
Parameter object
Access the tool parameters
Every tool parameter has an associated parameter object with properties and methods that are useful in tool validation. Parameters are contained in a list. The standard practice is to create the list of parameters in the ToolValidator class __init__ method, as shown in the code below.
def __init__(self):
self.params = arcpy.GetParameterInfo()
You can also access parameters in a script (as opposed to the ToolValidator class) as shown below. The only reason to access the parameter list in a script is to set the symbology property.
params = arcpy.GetParameterInfo()
Parameter order
A tool's parameters and their order are defined on the Parameters tab of the tool's properties, as illustrated below.
Note:
The list of parameters is zero based, so the first parameter is at position zero in the list. To access the third parameter, you would enter p3 = self.params[2].
Methods
Method name | Usage description |
---|---|
setErrorMessage(message) | Marks the parameter as having an error () with the supplied message. Tools do not execute if any of the parameters have an error. |
setWarningMessage(message) | Marks the parameter as having a warning () with the supplied message. Unlike errors, tools do execute with warning messages. |
setIDMessage(messageType, messageID, {AddArgument1}, {AddArgument2}) | Allows you to set a system message. The arguments are the same as the AddIDMessage function. |
clearMessage() | Clears out any message text and sets the status to informative (no error or warning). |
hasError() | Returns true if the parameter contains an error. |
hasWarning() | Returns true if the parameter contains a warning. |
isInputValueDerived() | Returns true if the tool is being validated inside a model and the input value is the output of another tool in the model. |
Properties
Property name | Read/Write | Value | Description |
---|---|---|---|
name | Read-only | String | Parameter name as defined on the Parameters tab of the tool's properties. |
direction | Read-only | String: "Input", "Output" | Input/Output direction of the parameter as defined on the Parameters tab of the tool's properties. |
datatype | Read-only | String | Data type as defined on the Parameters tab of the tool's properties. |
Read-only | String: "Required", "Optional", "Derived" | Type as defined on the Parameters tab of the tool's properties. | |
Read/write | List | A list of indexes of each dependent parameter. | |
Read/write | Value object | The value of the parameter. | |
defaultEnvironmentName | Read-only | String | The default environment setting as defined on the Parameters tab of the tool's properties. |
enabled | Read/write | Boolean | False if the parameter is unavailable. |
Read-only | Boolean | True if the user modified the value. | |
Read-only | Boolean | True if the internal validation routine has checked the parameter. | |
Read/write | String | The category of the parameter. | |
Read-only | Schema object | The schema of the output dataset. | |
Read/write | Filter object | The filter to apply to values in the parameter. | |
Read/write | String | The path to a layer file (.lyrx) used for drawing the output. | |
message | Read-only | String | The message to be displayed to the user. See setErrorMessage and setWarningMessage above. |
Although many Parameter object properties are read/write, most of these properties can only be set or modified when you initially create or modify the object. Several properties, including name, displayName, datatype, direction, and parameterType, establish the characteristics of a tool and cannot be modified during validation methods (such as updateMessages and updateParameters).
Some code examples are shown below. For other coding examples, see Customizing script tool behavior.
ToolValidator properties versus script tool properties
You can set a parameter's default value, filter, symbology, and dependencies on the Parameters tab of the script tool's properties dialog box or in the ToolValidator class.
Properties that you set in the ToolValidator class override those set on the script tool properties dialog box and often provide additional customization options. For example, if you set the default value of a parameter to "BLUE" on the script tool properties dialog box, and reset it to "RED" in initializeParameters, the default value becomes "RED". Once initializeParameters has been called, the script tool properties dialog box will display "RED" as the default value. If you (or your users) get into the situation where changes you make to one of these four parameter properties on the script's properties dialog box are not saved, it may be because the property was overridden in the ToolValidator class.
parameterDependencies
Typically you'll set parameter dependencies for use by the Schema object. In the following two cases, the dependencies may already be set on the Parameters tab of the tool's properties dialog box:
- For an output dataset parameter with a derived type, the dependency is the index of the parameter from which the output is derived.
- For certain input data types, the dependency is the index of the parameter containing the information used by the control, as shown in the table below.
Parameter data type | Dependent parameter data type |
---|---|
Area Unit | A geographic dataset used to determine the default units. For example, the Feature Layer, Raster Layer, Feature Set, or Record Set data type can be used. |
Field | The table containing the fields. For example, the Table View, Feature Layer, Raster Layer, Feature Set, or Record Set data type can be used. |
Field Mappings | A collection of fields in one or more input tables. For example, the Table View, Feature Layer, Raster Layer, Feature Set, or Record Set data type can be used. |
Geostatistical Value Table | A table of datasets and fields to be used in Geostatistical Analyst tools. Use the Geostatistical Layer data type. |
Linear Unit | A geographic dataset used to determine the default units. For example, the Feature Layer, Raster Layer, Feature Set, or Record Set data type can be used. |
Network Analyst Hierarchy Settings | The network dataset containing hierarchy information. Use the Network Dataset data type. |
Network Travel Mode | A list of travel modes. Use the Network Data Source, Network Dataset, or Network Dataset Layer data type. |
SQL Expression | The table containing the fields. For example, the Table View, Feature Layer, Raster Layer, Feature Set, or Record Set data type can be used. |
Dependencies are typically set in the initializeParameters method:
def initializeParameters(self):
# Set the dependencies for the output and its schema properties
self.params[2].parameterDependencies = [0, 1]
parameterType
The parameterType property can be required, optional, or derived.
- Required—A value is required for the tool to run.
- Optional—A value is not required for the tool to run.
- Derived—An output value that is not provided as an input parameter. Derived parameters are always output parameters.
In validation, the parameterType value cannot be dynamically modified. However, it may be necessary for a parameter to behave as a required parameter or an optional parameter depending on other parameter settings. If this is the case, set the parameter as optional. Then, in the validation updateMessages method, use the Parameter setIDMessage method with message ID 530 or 735. Using message ID 530 or 735 will cause an optional parameter to behave as a required parameter.
# Force a parameter to be required using setIDMessage, if the preceding
# parameter does not have a value.
if not self.params[4].valueAsText:
self.params[5].setIDMessage('ERROR', 735)
value
This is the value of the parameter that the user entered or you set programmatically. You can set the value in initializeParameters in which case it serves as the initial default value for the parameter. You can also set values in updateParameters in response to user input as shown below.
def updateParameters(self):
# Set the default distance threshold to 1/100 of the larger of the width
# or height of the extent of the input features. Do not set if there is no
# input dataset yet, or the user has set a specific distance (altered is true).
if self.params[0].valueAsText:
if not self.params[6].altered:
extent = arcpy.Describe(self.params[0]).extent
if extent.width > extent.height:
self.params[6].value = extent.width / 100
else:
self.params[6].value = extent.height / 100
return
A parameter's value property returns an object unless the parameter isn't populated in which case value returns None. To ensure that a parameter is populated, use an if check prior to using its value.
The code snippet below tests whether the value is equal to the string "Get Spatial Weights From File". This test works because the parameter data type is a string.
# If the option to use a weights file is selected, enable the
# parameter for specifying the file, otherwise disable it
if self.params[3].value: # check that parameter has a value
if self.params[3].value == "Get Spatial Weights From File":
self.params[8].enabled = True
else:
self.params[8].enabled = False
Since a Value object does not support string manipulation, use the Value object's value property whenever a string is to be manipulated or parsed. The code sample below uses the os.path.dirname method to return the directory from a dataset.
if self.params[0].value:
workspace = os.path.dirname(self.params[0].value.value)
Caution:
With the exception of Describe, don't use methods that take a catalog path—such as ListFields—in validation. The dataset may not exist when the tool is validated in ModelBuilder, and the method may fail or produce unexpected results.
Describe can be used on a Parameter object directly instead of using the parameter's value property. Using the value property is valid but is slower when working with layer inputs.
In the specific case of ListFields, the Describe object's fields property will provide the equivalent information.
Caution:
Don't set a parameter value in updateMessages since the value will not be validated by the internal validation routine.
altered
altered is true if the value of a parameter is changed—by entering an output path, for example. Once a parameter has been altered, it remains altered until the user empties (removes) the value in which case it returns to an unaltered state. Programmatically changing a value with validation code will change the altered state. That is, if you set a value for a parameter, the altered state of the parameter will be updated.
altered is used to determine whether you can change the value of a parameter. As an example, suppose a tool has a feature class parameter and a keyword parameter. If the feature class contains points or polygons, the keywords are RED, GREEN, and BLUE, and if lines, ORANGE, YELLOW, PURPLE, and WHITE.
Suppose the user enters a point feature class. If the keyword parameter is unaltered, you set the value to RED, since it's the default value.
If a line feature class is entered, you set the default value to ORANGE as long as the keyword parameter is unaltered.
However, if the keyword parameter has been altered by the user (that is, the keyword is set to GREEN), do not reset the keyword. The user has made their choice (GREEN) and you don't know their intention. They may change the feature class so that GREEN is valid or they may change the keyword (to PURPLE, for example). Since GREEN isn't a member of the set of keywords you created for lines, internal validation flags the parameter an error. Then the user has two options: change the input feature class or change the keyword.
if not self.params[2].altered:
self.params[2].value = "POINT"
hasBeenValidated
hasBeenValidated is false if a parameter's value has been modified by the user since the last time updateParameters and internal validate were called. Once internal validate has been called, geoprocessing automatically sets hasBeenValidated to true for every parameter.
hasBeenValidated is used to determine whether the user has changed a value since the last call to updateParameters. You can use this information when deciding whether to check the parameter yourself.
# Set the default distance threshold to 1/100 of the larger of the width
# or height of the extent of the input features. Do not set if there is no
# input dataset yet, or if the input features have already been validated,
# or the user has set a specific distance (Altered is true).
if self.params[0].valueAsText and not self.params[0].hasBeenValidated:
if not self.params[6].altered:
extent = arcpy.Describe(self.params[0]).extent
width = extent.width
height = extent.height
if width > height:
self.params[6].value = width / 100
else:
self.params[6].value = height / 100
category
Parameters can be grouped into categories in the Geoprocessing pane to minimize the size of the parameters or to group related parameters that will be infrequently used. Several ArcGIS Network Analyst extension tools use categories, as shown below.
Since you can only set the category once, set it in initializeParameters. Setting categories in updateParameters has no effect. The code below shows putting parameters 4 and 5 into the Options category and parameters 6 and 7 into the Advanced category.
def initializeParameters(self):
self.params[4].category = "Options"
self.params[5].category = "Options"
self.params[6].category = "Advanced"
self.params[7].category = "Advanced"
Categories are always shown after noncategorized parameters. Do not put required parameters into categories, since the user may not see them in the Geoprocessing pane.
symbology
The symbology property associates a layer file (.lyrx) with an output parameter.
params[2].symbology = "E:/tools/extraction/ToolData/ClassByDist.lyrx"
schema object
Every output parameter of type feature class, table, raster, or workspace has a schema object. Only output feature classes, tables, rasters, and workspaces have a schema; other types do not. The schema object is created automatically through geoprocessing. You access this schema through the parameter object and set the rules for describing the output of the tool. After you set the schema rules, and on return from the ToolValidator class, the geoprocessing internal validation code examines the rules you set and updates the description of the output.
To review, the flow of control is as follows:
- When the tool is first opened in the Geoprocessing pane, initializeParameters is called. You set up the static rules (rules that don't change based on user input) for describing the output. No output description is created at this time, since the user hasn't specified values for any of the parameters (unless you've provided default values).
- Once the user interacts with the tool in the Geoprocessing pane, updateParameters is called.
- updateParameters can modify the schema object to account for dynamic behavior that can't be determined from the parameter dependencies (for example, adding a new field such as Add Field).
- After returning from updateParameters, the internal validation routines are called and the rules found in the schema object are applied to update the description of the output data.
- updateMessages is then called. You can examine the warning and error messages that internal validation may have created and modify them or add custom warning and error messages.
All schema properties are read and write except type, which is read-only.
Property name | Value |
---|---|
type | String: "Feature", "Table", "Raster" , "Container" (for workspaces and feature datasets) |
clone | Boolean |
featureTypeRule | String: "AsSpecified", "FirstDependency" |
featureType | String: "Simple", "Annotation", "Dimension" |
geometryTypeRule | String: "Unknown", "FirstDependency", "Min", "Max", "AsSpecified" |
geometryType | String: "Point", "Multipoint", "Polyline", "Polygon" |
extentRule | String: "AsSpecified", "FirstDependency", "Intersection", "Union", "Environment" |
extent | Extent object |
fieldsRule | String: "None", "FirstDependency", "FirstDependencyFIDs", "All", "AllNoFIDs", "AllFIDsOnly" |
additionalFields | List of Field objects |
cellSizeRule | String: "AsSpecified", "FirstDependency", "Min", "Max", "Environment" |
cellSize | Double |
rasterRule | String: "FirstDependency", "Min", "Max", "Integer", "Float" |
rasterFormatRule | String: "Img", "Grid" |
additionalChildren | List of datasets to add to a workspace schema |
Use FirstDependency
Several of the rules can be set to "FirstDependency", which means the value of the first parameter found in the parameter dependency array set will be used with parameter.parameterDependencies. In the code example below, parameter 2 has two dependent parameters, 0 and 1, and the first dependency is parameter 0.
# Set the dependencies for the output and its schema properties
self.params[2].parameterDependencies = [0, 1]
If any dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used.
type
The type property is read-only and is set by geoprocessing.
clone
If true, the geoprocessing process will make an exact copy (clone) of the description in the first dependent parameter. The default value is false. Typically, you set clone to true in the initializeParameters method. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is cloned.
- If parameter.parameterType is "Derived", an exact copy is made. This is the behavior of the Add Field tool.
- If parameter.parameterType is "Required", an exact copy is made, but the catalog path to the dataset is changed. Catalog paths consist of two parts: the workspace and the base name, for example, E:/Data/TestData/netcity.gdb/infrastructure/roads.
- Workspace = E:/Data/TestData/netcity.gdb/infrastructure
- Base name = roads
- The base name is the same as the base name of the first input parameter containing a dataset (not the first dependency but the first parameter) appended with the name of the script tool (for example, roads_MyTool).
- The workspace is set to the scratch workspace environment setting. If this is empty, the current workspace environment setting is used. If this is empty, the workspace of the first input parameter containing a dataset is used. If this workspace is read-only, the system temp directory is used.
After setting clone to true, all rule-based methods, such as featureTypeRule, geometryTypeRule, and extentRule, are set to "FirstDependency".
The two code examples below do equivalent work. Both examples are based on how the Clip tool creates the output schema.
def initializeParameters(self):
# Set the dependencies for the output and its schema properties
# The two input parameters are feature classes.
self.params[2].parameterDependencies = [0, 1]
# Feature type, geometry type, and fields all come from the first
# dependency (parameter 0), the input features
self.params[2].schema.featureTypeRule = "FirstDependency"
self.params[2].schema.geometryTypeRule = "FirstDependency"
self.params[2].schema.fieldsRule = "FirstDependency"
# The extent of the output is the intersection of the input features
# and the clip features (parameter 1)
self.params[2].schema.extentRule = "Intersection"
return
def initializeParameters(self):
# Set the dependencies for the output and its schema properties
# The two input parameters are feature classes.
self.params[2].parameterDependencies = [0, 1]
self.params[2].schema.clone = True
return
def updateParameters(self):
# The only property of the clone that changes is that the extent
# of the output is the intersection of the input features
# and the clip features (parameter 1)
self.params[2].schema.extentRule = "Intersection"
return
featureTypeRule
This setting determines the feature type of the output feature class. This rule has no effect on output rasters or tables.
Value | Description |
---|---|
"AsSpecified" | The feature type will be determined by the featureType property. |
"FirstDependency" | The feature type will be the same as the first parameter in the dependencies. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used. |
featureType
When featureTypeRule is "AsSpecified", the value for featureType is used to specify the feature type of the output.
Value | Description |
---|---|
"Simple" | The output will contain simple features. The geometry type of the features is specified with geometryTypeRule. |
"Annotation" | The output will contain annotation features. |
"Dimension" | The output will contain dimension features. |
geometryTypeRule
This setting determines the geometry type (such as point or polygon) of the output feature class.
Value | Description |
---|---|
"Unknown" | This is the default setting. Typically, you should be able to determine the geometry type in updateParameters based on the values of other parameters. You only set the rule to "Unknown" if you don't have enough information to determine the geometry type. |
"FirstDependency" | The geometry type is the same as the first dependent parameter. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used. |
"Min", "Max" | The geometries of all dependent parameters are examined and the output geometry type is set to the minimum or maximum type found. "Min" and "Max" are defined as follows:
|
"AsSpecified" | The geometry type will be determined by the value of the geometryType property. |
geometryType
Set this to the geometry type to use ("Point", "Multipoint", "Polyline", or "Polygon") when geometryTypeRule is "AsSpecified".
extentRule
Value | Description |
---|---|
"AsSpecified" | The output extent will be specified in the extent property. |
"FirstDependency" | The output extent is the same as the first dependent parameter. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used. |
"Intersection" | The output extent will be the geometric intersection of all dependent parameters. (This is what the Clip tool uses, as shown below.) |
"Union" | The output extent will be the geometric union of all dependent parameters. |
"Environment" | The output extent will be calculated based on the Extent environment setting. |
Example
# The extent of the output is the intersection of the input features
# and the clip features (the dependent parameters)
self.params[2].schema.extentRule = "Intersection"
extent
Set this to the extent to use when extentRule is "AsSpecified". You can set the extent with either a space-delimited string or a list with four values. The sequence is xmin, ymin, xmax, ymax.
Example
self.params[2].schema.extentRule = "AsSpecified"
self.params[2].schema.extent = "123.32 435.8 987.3 567.9"
# Alternatively use a list, as follows:
# self.params[2].schema.extent = [123.32, 435.8, 987.3, 567.9]
fieldsRule
fieldsRule determines the fields that will exist in the output feature class or table.
In the table below, FID stands for Feature ID but actually refers to the ObjectID field in every feature class or table.
Value | Description |
---|---|
"None" | No fields will be output except ObjectID. |
"FirstDependency" | Output fields will be the same as the first dependent parameter. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used. |
"FirstDependencyFIDs" | Only the ObjectID of the first dependent input will be written to the output. |
"All" | All fields in the list of dependent parameters will be output. |
"AllNoFIDs" | All fields except ObjectIDs will be written to the output. |
"AllFIDsOnly" | All ObjectID fields will be written to the output, but no other fields from the inputs will be written. |
The following is an example of Clip using fieldsRule of "FirstDependency":
def initializeParameters(self):
# Set the dependencies for the output and its schema properties
# The two input parameters are feature classes.
self.params[2].parameterDependencies = [0, 1]
# Feature type, geometry type, and fields all come from the first
# dependency (parameter 0), the input features
self.params[2].schema.featureTypeRule = "FirstDependency"
self.params[2].schema.geometryTypeRule = "FirstDependency"
self.params[2].schema.fieldsRule = "FirstDependency"
# The extent of the output is the intersection of the input features
# and the clip features (parameter 1)
self.params[2].schema.extentRule = "Intersection"
return
additionalFields
Along with the fields that are added by the application of fieldsRule, you can add more fields to the output. additionalFields takes a list of field objects.
cellSizeRule
This determines the cell size of output rasters or grids.
Value | Description |
---|---|
"AsSpecified" | The output cell size is specified in the cellSize property. |
"FirstDependency" | The cell size is calculated from the first dependent parameter. If the dependent parameter is a raster, its cell size is used. For other types of dependent parameters, such as feature classes or feature datasets, the extent of the data is used to calculate a cell size. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used. |
"Min", "Max" | "Min" means the output cell size is the smallest cell size of the dependent parameters. "Max" means it is the largest cell size of the dependent parameters. |
"Environment" | The output cell size is calculated based on the Cell Size environment setting. |
cellSize
Set this to the cell size to use when cellSizeRule is "AsSpecified".
rasterRule
This determines the data type—integer or float—contained in the output raster.
Value | Description |
---|---|
"FirstDependency" | The data type (integer or float) is the same as the first dependent parameter. If the first dependent parameter is a multivalue (a list of values), the first value in the multivalue list is used. |
"Min", "Max" | Integer is considered smaller than float. For example, if there are two dependent parameters, one containing integers and the other containing floats, "Min" creates an integer output, and "Max" creates a float output. |
"Integer" | The output raster contains integers (whole numbers). |
"Float" | The output raster contains floats (fractional numbers). |
rasterFormatRule
This determines the output raster format, either "Grid" or "Img". The default is "Img", which is ERDAS IMAGINE format. "Grid" is an Esri format.
additionalChildren
A workspace is a container for datasets (features, tables, and rasters). These datasets are children of the workspace (think of the workspace as the parent). If the tool adds datasets to a new or existing workspace, you can update the description of the workspace by adding descriptions of the children. For example, you may have a tool that takes a list of feature classes (a multivalue), modifies them in some way, and writes the modified feature classes to an existing workspace. When the tool is used in ModelBuilder, the workspace is the derived output of the tool, and you can use this workspace as input to the Select Data tool. Select Data allows you to select a child dataset found in a container and use it as input to another tool.
The input to additionalChildren is one or more descriptions of the children. There are two forms of child descriptions:
Form | Description |
---|---|
value object | A feature class, table, raster, dimension, or annotation value as returned by the value property. |
List object of the form [type, name, fields, extent, spatial reference] | A list containing a description of the child to be added. Only the first two entries in the list, type and name, are required. The remaining arguments are optional. |
When adding more than one child, provide a list of child descriptions. If you're adding the children in list form, create a list of lists for additionalChildren.
The list form has five arguments, as described in the following table.
Argument | Type | Description |
---|---|---|
type | Required | One of the following: "Point", "Multipoint", "Polyline", "Polygon", "Table", "Raster", "Annotation", "Dimension" |
name | Required | The name of the dataset. It can be the base name of the dataset (streets) or the full catalog path (E:\mydata\test.gdb\infrastructure\streets). When a full catalog path is provided, all but the base name (streets) is ignored. |
fields | Optional | A list of field objects. This contains the fields appearing on the child, if known. |
extent | Optional | A string or list containing the spatial extent of the child. |
spatial reference | Optional | A spatial reference object. |
These arguments must be supplied in the order shown. To skip an optional argument, use None or '#'.
Examples of setting a workspace schema are below. The examples are based on a script tool that has the following arguments:
Parameter index | Parameter name | Property |
---|---|---|
0 | Input feature class | Feature class—input. |
1 | Input table | Table—input. |
2 | Input workspace | Workspace—input (an existing workspace that contains the results of the tool). |
3 | Derived workspace | Workspace—Derived output obtained from input workspace. The schema of this workspace is modified to contain additional children. |
The tool takes the input feature class and table, copies both to the workspace, adds a new field to the feature class, and creates a polygon feature class in the workspace. (The actual work of the tool isn't important as it only serves to illustrate setting a workspace schema.) The code examples below build on one another, starting with simple usage of additionalChildren.
In initializeParameters, the output workspace is cloned from its dependent parameter (parameter 2). This dependency is set in the tool properties but can also be set in initializeParameters to prevent removal of the dependency in the tool's properties.
class ToolValidator:
def __init__(self):
self.params = arcpy.GetParameterInfo()
def initializeParameters(self):
self.params[3].parameterDependencies = [2] # input workspace
self.params[3].schema.clone = True # Copy all existing contents to output
return
def updateParameters(self):
inFC = self.params[0].value # input feature class
inTable = self.params[1].value # input table
inWS = self.params[2].value # input workspace
if inFC and inTable and inWS:
self.params[3].schema.additionalChildren = [inFC, inTable]
return
The only properties known about this new feature class (when validating) are the name ("SummaryPolygon") and type ("polygon").
children = [] # New empty list
children.append(inFC)
children.append(inTable)
children.append(["polygon", "SummaryPolygon"])
self.params[3].schema.additionalChildren = children
# Create a field object with the name "Category" and type "Long".
newField = arcpy.Field()
newField.name = "Category"
newField.type = "Long"
# Describe the input feature class in order to get its list of fields. The 9.3
# version of the geoprocessing object returns fields in a list, unlike previous
# versions, which returned fields in an enumerator.
desc = arcpy.Describe(inFC)
fieldList = desc.fields
# Add the new field to the list
fieldList.append(newField)
# Create a new child based on the input feature class, but with the
# additional field added.
newChild = [desc.shapeType, desc.catalogPath, fieldList,
desc.extent, desc.spatialReference]
# Now create our list of children and add to the schema.
children = []
children.append(newChild)
children.append(inTable)
children.append(["polygon", "SummaryPolygon"])
self.params[3].schema.additionalChildren = children
To create fields for SummaryPolygon (the new polygon feature class), create a list of field objects similar to the pattern shown in the above example.
In this example, the first parameter is a multivalue of feature classes. Each feature class in the multivalue is copied to the derived workspace. A new field, ProjectID, is added to each of the copied feature classes.
# 0 - input features (multivalue)
# 1 - input workspace
# 2 - derived workspace
import arcpy
class ToolValidator:
def __init__(self):
self.params = arcpy.GetParameterInfo()
def initializeParameters(self):
self.params[2].parameterDependencies = [1]
self.params[2].schema.clone = True
return
def updateParameters(self):
inVT = self.params[0].value # multivalue ValueTable
inWS = self.params[1].value # WorkSpace
# Add each feature class to the output workspace. In addition,
# add a new field "ProjectID" to each feature class.
if inVT and inWS:
rowCount = inVT.rowCount # Number of rows in the MultiValue table
children = []
newField = arcpy.Field()
newField.name = "ProjectID"
newField.type = "Long"
for row in range(0, rowCount):
value = inVT.getValue(row, 0)
if value:
d = arcpy.Describe(value)
fieldList = d.fields
# Note -- not checking if field already exists
fieldList.append(newField)
# Create new child with additional ProjectID field and
# add child to list of children.
child = [d.shapeType, d.catalogPath, fieldList]
children.append(child)
self.params[2].schema.additionalChildren = children
return
def updateMessages(self):
return
Filter object
The Filter object allows you to specify the choices available to the user for a parameter. For example, you can set up a field filter that limits choices to text fields. A filter does three jobs:
- A filter only presents the user with valid choices when browsing for data. If you set a filter for point feature classes, only point feature classes are shown when the user browses for data. If you set a filter for text fields, the drop-down list of fields only shows text fields.
- If a user types a parameter value (rather than choosing a value from the list or file browser), the value is compared to the filter. If the user enters an invalid value (a numeric field instead of a text field, for example), a warning or error occurs.
- Because values are compared to their filter by internal validation, you don't have to program custom validation in the ToolValidator class.
There are two ways to specify filters:
- On the Parameters tab of the tool's properties dialog box, click the parameter, click the cell next to Filter, and choose the filter type from the drop-down list. After choosing the filter type, a dialog box appears where you specify the values for the filter.
- You can set the values programmatically in a ToolValidator class (examples are below). This provides some customization options that are not possible using the tool's properties dialog box, including defining dynamic filters based on other parameter values, filters for composite data types, and multiple filter types on the same parameter. Geoprocessing creates filters automatically for parameters of type string, long, double, feature class, file, field, and workspace. If you don't choose a filter on the tool's properties dialog box, a filter is still associated with the parameter—it's just empty. An empty filter is the same as no filter. By adding values to an empty filter, you activate the filter, and the user's choices are limited by the contents of the filter.
There are seven kinds of filters, as shown in the table below:
Filter type | Value |
---|---|
ValueList | A list of string or numeric values used with String, Long, Double, Boolean, Linear Unit, Areal Unit, and Time Unit data types. For String or numeric filters, provide a list of values and only those values will be considered valid and shown in a drop-down list on the tool dialog box. For Linear Unit, Areal Unit, and Time Unit ValueList filters, provide a list of unit keyword strings and only values using those units will be considered valid and shown in the unit drop-down list on the tool dialog box. |
Range | A minimum and maximum value used with Long, Double, Linear Unit, Areal Unit, and Time Unit data types. For Long and Double filters provide a list with two items: the minimum and maximum value. Only numbers specified between the minimum and maximum will be considered valid. For Linear Unit, Areal Unit, and Time Unit Range filters, provide a list with two items: the minimum and maximum value including a unit. For example, ["1 Meters", "100 Meters"]. |
FeatureClass | A list of allowable feature class types specified by the values "Point", "Multipoint", "Polyline", "Polygon", "MultiPatch", "Annotation", and "Dimension". More than one value can be supplied to the filter. |
File | A list of file suffixes, for example, ".txt" or ".xml". |
Field | A list of allowable field types specified by the values "Short", "Long", "Single", "Double", "Text", "Date", "OID", "Geometry", "Blob", "Raster", "GUID", "GlobalID", and "XML". More than one value can be supplied to the filter. |
Workspace | A list of allowable workspace types specified by the values "FileSystem", "LocalDatabase", and "RemoteDatabase". More than one value can be supplied. |
Travel Mode Unit Type | A list of allowable travel mode's impedance attribute: "Time", "Distance", and "Other". |
Properties
Property | Description |
---|---|
type | The type of filter (ValueList, Range, FeatureClass, File, Field, and Workspace). You can set the type of filter when dealing with Long, Double, Linear Unit, Areal Unit, and Time Unit parameters (see the note below). For other types of parameters, there is only one valid type of filter, so setting the type on these parameters is ignored. If you do not want to filter values, set the list property to an empty list. |
list | A list of values for the filter. If you do not want to filter values, set the list property to an empty list. |
ValueList
ValueList for String parameters
For a string parameter, the list can contain any number of strings. An example of setting the list of string values in initializeParameters is shown below. The parameter contains two choices: "NEW_FORMAT" and "OLD_FORMAT".
def initializeParameters(self):
# Set the fixed list of "file format type" parameter choices and its
# default value.
self.params[1].filter.list = ["OLD_FORMAT", "NEW_FORMAT"]
self.params[1].value = "OLD_FORMAT"
return
In the example above, you could set the list of values on the Parameter tab of the tool's properties dialog box instead. If you set the list of values to something else (such as "OLD" and "NEW") in the tool's properties, these values would be replaced by "OLD_FORMAT" and "NEW_FORMAT" when initializeParameters is called. The same is true for the default value—it can be set on the tool's properties dialog box, and reset in ToolValidator.
Note:
The list of values you provide in ToolValidator replaces the values set on the tool's properties dialog box. This allows you to update the values based on other parameters.
Continuing with this example, the following code shows updateParameters changing a list of values in another parameter based on whether the user chose "OLD_FORMAT" or "NEW_FORMAT":
def updateParameters(self):
# Update the value list filter of the "feature type in file" parameter
# depending on the "file format type" parameter.
if self.params[1].value.upper() == "OLD_FORMAT":
self.params[2].filter.list = ["POINT", "LINE", "POLYGON"]
elif self.params[1].value.upper() == "NEW_FORMAT":
self.params[2].filter.list = ["POINT", "LINE", "POLYGON",
"POINT_WITH_ANNO",
"LINE_WITH_ANNO",
"POLYGON_WITH_ANNO"]
# Provide default value for "feature type in file" parameter.
if not self.params[2].altered:
self.params[2].value = "POINT"
ValueList for Long and Double parameters
A Long or Double parameter can have a list of numeric values. The user can only choose or enter values that are in the list.
# Set filter for a Long parameter
self.params[7].filter.list = [10, 20, 30, 40, 50]
# Set filter for a Double parameter
self.params[8].filter.list = [10.0, 12.5, 15.0]
ValueList for Boolean parameters
There are two values for a Boolean parameter: true and false. The true value is always the first value in the list.
def initializeParameters(self):
# Set the Boolean choice for including or excluding angles.
self.params[6].filter.list = ["ANGLE", "NO_ANGLE"]
# Set the default value to false (no angle).
self.params[6].value = "NO_ANGLE"
return
def updateParameters(self):
# Enable angle format parameter if user wants angles.
if self.params[6].value.upper() == "ANGLE":
self.params[7].enabled = True
ValueList for Linear Unit, Areal Unit, and Time Unit parameters
A Linear Unit, Areal Unit, and Time Unit parameter can have a list of units. The user can only choose or enter units that are in the list
# Set filter for linear unit parameters
self.params[5].filter.type = "ValueList"
self.params[5].filter.list = ["Meters", "Kilometers"]
# Set filter for areal unit parameters
self.params[6].filter.type = "ValueList"
self.params[6].filter.list = ["Hectares", "SquareKilometers", "SquareMeters"]
# Set filter for time unit parameters
self.params[7].filter.type = "ValueList"
self.params[7].filter.list = ["Hours", "Days"]
Range
A Long, Double, Linear Unit, Areal Unit, or Time Unit parameter can have a Range filter. Range filters have two values: minimum and maximum. The first value in the list is the minimum. The range is inclusive, meaning the minimum and maximum are valid choices.
Range for Long and Double parameters
A Long or Double parameter can have a range of valid numeric values.
def initializeParameters(self):
# Utility values must be between -10 and 10.
self.params[7].filter.list = [-10, 10]
Range for Linear Unit, Areal Unit, and Time Unit parameters
A Linear Unit, Areal Unit, or Time Unit parameter can have a range of valid values. The user can specify any unit and it will be automatically converted for comparison to the unit of the minimum and maximum of the range filter.
# Set filter for linear unit parameters
self.params[5].filter.type = "Range"
self.params[5].filter.list = ["1 Meters", "10 Meters"]
# Set filter for areal unit parameters
self.params[6].filter.type = "Range"
self.params[6].filter.list = ["1 Acres", "10 Acres"]
# Set filter for time unit parameters
self.params[7].filter.type = "Range"
self.params[7].filter.list = ["1 Hours", "24 Hours"]
Set filter type on Long, Double, Linear Unit, Areal Unit, and Time Unit parameters
For Long, Double, Linear Unit, Areal Unit, and Time Unit parameters, the default filter type is ValueList. If you want it to be a Range filter, set the filter type in initializeParameters as follows:
def initializeParameters(self):
# Set the 'score' value parameters to a range filter
self.params[7].filter.type = "Range"
self.params[7].filter.list = [-10, 10]
# Set both filter types for a single Linear Unit parameter
self.params[5].filter.type = "Range"
self.params[5].filter.list = ["0 Meters", "10000 Meters"]
self.params[5].filter.type = "ValueList"
self.params[5].filter.list = ["Meters", "Kilometers", "Feet", "Miles", "Yards"]
You can only set the filter type for Long, Double, Linear Unit, Areal Unit, and Time Unit parameters.
FeatureClass
The example below shows setting the feature type of one input parameter based on the feature type of another input parameter.
def updateParameters(self):
# Set the input feature type of the second parameter based
# on the feature type of the first parameter.
if self.params[0].valueAsText:
desc = arcpy.Describe(self.params[0])
feature_type = desc.shapeType.lower()
if feature_type == "polygon":
self.params[1].filter.list = ["point", "multipoint"]
elif feature_type == "polyline":
self.params[1].filter.list = ["polygon"]
elif feature_type in ["point", "multipoint"]:
self.params[1].filter.list = ["polyline"]
else:
self.params[1].filter.list = []
return
File
The file filter contains a list of file suffixes that a file can have, such as .txt (simple text file) and .csv (comma-separated value). You can supply any text for a suffix—it doesn't have to be a suffix that ArcGIS recognizes. The suffix can be of any length and does not include the dot. The example below shows setting the filter for an input File parameter.
def initializeParameters(self):
# Set the input file type to our recognized options file suffixes.
self.params[0].filter.list = ["opt56", "opt57", "globalopt"]
return
Field
The field filter defines the permissible field types. Values can be "Short", "Long", "Float", "Single", "Double", "Text", "Date", "OID", "Geometry", "Blob", "Raster", "GUID", "GlobalID", and "XML".
Display versus internal name
The four field types that have an internal name are shown in the following table:
Display name | Internal name |
---|---|
Short | SmallInteger |
Long | Integer |
Float | Single |
Text | String |
When specifying a field filter, you can use either the display or internal name; that is, the following two lines of code are equivalent:
self.params[1].filter.list = ["Short", "Long", "Float", "Text"]
self.params[1].filter.list = ["SmallInteger", "Integer", "Single", "String"]
If you supply the display name, such as "short", it is converted and stored in the filter as "SmallInteger". You may not need to access values in the field filter, but if you do, be aware that the internal name is stored. The code snippet below shows how to account for this:
self.params[1].filter.list = ["Short", "Long"]
if self.params[1].filter.list[0].lower() == "SmallInteger":
# do something
Set a default field value
You can provide a default value for a field parameter by looping through the fields in the input table and choosing the first field that satisfies the filter.
def initializeParameters(self):
self.params[1].filter.list = ["Short", "Long", "Float", "Double"]
return
def updateParameters(self):
if self.params[0].valueAsText and not self.params[1].altered:
self.params[1].value = ""
desc = arcpy.Describe(self.params[0])
fields = desc.fields
# Set default to the first field that matches your filter.
for field in fields:
fType = field.type.lower()
if fType in ["SmallInteger", "Integer", "Single", "Double"]:
self.params[1].value = field.name
break
return
Caution:
Do not use the ListFields function in ToolValidator. Instead, use the Describe function as shown above.
Workspace
The workspace filter specifies the types of input workspaces that are permissible. There are three values:
Workspace filter | Description |
---|---|
FileSystem | A system folder, used to store shapefiles, and grids |
LocalDatabase | A file geodatabase |
RemoteDatabase | An enterprise database connection |