La validación es todo lo que ocurre antes de que se hace clic en el botón Aceptar de una herramienta. Al crear sus propias herramientas personalizadas, la validación le permite personalizar cómo responden e interactúan los parámetros con los valores y entre sí. La validación se realiza con un bloque de código de Python que se utiliza para controlar el comportamiento de la herramienta.
Para obtener más información acerca de la validación, consulte Entender la validación en las herramientas de secuencia de comandos
Puede proporcionar un comportamiento propio para el cuadro de diálogo de la herramienta de secuencia de comandos, como habilitar y deshabilitar parámetros, proporcionar valores predeterminados y actualizar palabras clave de cadena de texto. Para agregar un comportamiento propio para la herramienta de secuencia de comandos, haga clic derecho en la herramienta de secuencia de comandos, haga clic en Propiedades, y a continuación haga clic en la pestaña Validación. En el panel Validación, puede proporcionar un código Python que implementa una clase de Python denominada ToolValidator.
Aunque la clase ToolValidator se implementa mediante código Python, aún puede utilizar cualquier idioma de secuencia de comandos para realizar el trabajo actual de la herramienta.
ToolValidator es una clase Python que contiene tres métodos: initializeParameters(self), updateParameters(self) y updateMessages(self). También incluye el método estándar de inicio de clase de Python, __init__(self). Para ver y editar la clase ToolValidator, haga clic derecho en la herramienta de secuencia de comandos, haga clic en Propiedades y a continuación haga clic en la pestaña Validación. La ilustración a continuación muestra la pestaña Validación con el código de clase ToolValidator predeterminado. Haga clic en el botón Editar para editar el código y, después de editarlo, haga clic en Aceptar o Aplicar para aplicar las modificaciones.
Método | Descripción |
---|---|
__init__ | Inicia la clase ToolValidator. Importa todas las bibliotecas que necesita e inicia el objeto (self). |
initializeParameters | Se invoca una vez cuando el cuadro de diálogo de la herramienta se abre por primera vez o cuando la herramienta se utiliza por primera vez en la línea de comandos. |
updateParameters | Se invoca cada vez que el usuario modifica un parámetro en el cuadro de diálogo de la herramienta. Después de volver de updateParameters, el geoprocesamiento invoca su rutina de validación interna. |
updateMessages | Se invoca después de volver de la rutina de validación interna. Puede examinar los mensajes creados desde la validación interna y modificarlos si lo desea. |
A continuación se presentan algunos ejemplos del código de ToolValidator. Para obtener una descripción completa de todos los métodos y más ejemplos, consulte Programar una clase ToolValidator.
Habilitar o deshabilitar un parámetro
Este ejemplo es de la herramienta Análisis de punto caliente:
def updateParameters(self): # If the option to use a weights file is selected (the user chose # "Get Spatial Weights From File"), enable the parameter for specifying # the file, otherwise disable it # if self.params[3].value == "Get Spatial Weights From File": self.params[8].enabled = 1 else: self.params[8].enabled = 0
Nota de codificación: Cuando configura variables booleanas, comoHabilitado, puede usar estas sintaxis:
self.params[8].enabled = 1 self.params[8].enabled = bool(1) self.params[8].enabled = True # Note upper case: "True", not "true"
Todo número o valor que no sea cero se considera verdadero.
Configurar un valor predeterminado
Este ejemplo es también de la herramienta Análisis de punto caliente:
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].value: if not self.params[6].altered: extent = arcpy.Describe(self.params[0].value).extent if extent.width > extent.height: self.params[6].value = extent.width / 100 else: self.params[6].value = extent.height / 100 return
Actualizar un filtro
A continuación se presenta un ejemplo de la actualización dinámica de un filtro de lista de valores que incluye una lista de elección de palabras clave. Si el usuario introduce "OLD_FORMAT" en el segundo parámetro, el tercer parámetro contiene "POINT", "LINE" y "POLYGON". Si se introduce "NEW_FORMAT", el tercer parámetro contiene tres elecciones adicionales.
class ToolValidator: def __init__(self): import arcpy self.params = arcpy.GetParameterInfo() def initializeParameters(self): return def updateParameters(self): # Provide default values for "file format type" and # "feature type in file" # if not self.params[1].altered: self.params[1].value = "OLD_FORMAT" if not self.params[2].altered: self.params[2].value = "POINT" # Update the value list filter of the "feature type in file" parameter # depending on the type of file (old vs. new format) input # if self.params[1].value == "OLD_FORMAT": self.params[2].filter.list = ["POINT", "LINE", "POLYGON"] elif self.params[1].value == "NEW_FORMAT": self.params[2].filter.list = ["POINT", "LINE", "POLYGON", "POINT_WITH_ANNO", "LINE_WITH_ANNO", "POLYGON_WITH_ANNO"] return def updateMessages(self): return
Aquí hay otro ejemplo donde el filtro de la lista de valores en el segundo parámetro cambia según el tipo de forma encontrado en el primer parámetro, una clase de entidad:
def updateParameters(self): # Update the value list filter in the second parameter based on the # shape type in the first parameter # stringFilter = self.params[1].filter fc = self.params[0].value if fc: shapetype = arcpy.Describe(fc).shapeType.lower() if shapetype == "point" or shapetype == "multipoint": stringFilter.list = ["RED", "GREEN", "BLUE"] elif shapetype == "polygon": stringFilter.list = ["WHITE", "GRAY", "BLACK"] else: stringFilter.list = ["ORANGE", "INDIGO", "VIOLET"] else: stringFilter.list = ["RED", "GREEN", "BLUE"] # If the user hasn't changed the keyword value, set it to the default value # (first value in the value list filter). # if not self.params[1].altered: self.params[1].value = stringFilter.list[0] return
Personalizar un mensaje
def updateMessages(self): self.params[6].clearMessage() # Check to see if the threshold distance contains a value of zero and the user has # specified a fixed distance band. # if self.params[6].value <= 0: if self.params[3].value == "Fixed Distance Band": self.params[6].setErrorMessage("Zero or a negative distance is invalid \ when using a fixed distance band. Please \ use a positive value greater than zero." ) elif self.params[6].value < 0: self.params[6].setErrorMessage("A positive distance value is required \ when using a fixed distance band. \ Please specify a distance.") return
Actualizar la descripción de los datos de salida por medio del objeto Esquema
Además de personalizar la conducta del cuadro de diálogo de la herramienta, puede utilizar ToolValidator para actualizar las descripciones de las variables de los datos de salida para ModelBuilder. Puede pensar a las variables de datos en ModelBuilder como nada más que descripciones breves de datasets, como se ilustra a continuación. Las variables de datos contienen cada propiedad a la que accede con la función Describe en Python.
Todas las herramientas deben actualizar la descripción de los datos de salida para su uso en ModelBuilder. Al actualizar la descripción, los procesos subsiguientes en ModelBuilder pueden observar cambios pendientes en los datos antes de ejecutar cualquier proceso. Los dos ejemplos a continuación muestran cómo los procesos subsiguientes observan cambios pendientes.
El primer ejemplo, que se ilustra a continuación, muestra un modelo que contiene las herramientas Agregar campo y Calcular campo. En Agregar campo, la variable de datos de salida, Parks (2) se actualiza para incluir el campo nuevo, TrackingID. Debido a la actualización de la salida, el cuadro de diálogo de Calcular campo muestra TrackingID en la lista de nombres de campos.
El segundo ejemplo (que no se muestra) es un modelo donde la salida de la herramienta Recortar se utiliza como entrada para la herramienta De polígono a ráster. Dado que la herramienta Recortar utiliza un enfoque que "recorta según un molde" para crear las entidades de entrada, la clase de entidad de salida tiene las mismas propiedades que la clase de entidad de entrada con una excepción notable: su extensión geográfica. La extensión geográfica de la clase de entidad de salida es la intersección geométrica de las extensiones de las entidades de entrada y de recorte. La herramienta De polígono a ráster utiliza la nueva extensión geográfica para determinar un tamaño de celda predeterminado.
Dentro de la clase ToolValidator, puede utilizar un objeto de Esquema para configurar reglas para construir la descripción de la salida. Por ejemplo, puede configurar las reglas de la manera siguiente:
- Realice una copia de la descripción del dataset de entrada y agregue un campo nuevo a su lista de campos (como Agregar campo), o agregue una lista de campos fijos (como Agregar coordenadas XY).
- Configure la lista de campos de salida para que sean todos los campos en un conjunto de datasets y, opcionalmente, agregue campos para incluir los Id. de la entidad desde el conjunto de datasets (como Combinación e Intersecar).
- Configure la extensión como la de un dataset en otro parámetro, o la combinación o intersección (como Recortar) de datasets en una lista de parámetros.
- Configure un tipo de geometría específica (punto, línea, polígono) o establézcalo como el de un dataset en otro parámetro o como el tipo mínimo o máximo en una lista de parámetros. La definición de tipo de geometría mínima o máxima es puntos = 0, polilíneas = 1, polígonos = 2. Por lo tanto, el tipo de geometría mínimo en el conjunto {punto, polilínea, polígono} es punto y el máximo es polígono.
Los parámetros de salida tienen un esquema
El objeto de Esquema se crea mediante el geoprocesamiento. Cada parámetro de salida de tipo clase de entidad, tabla, ráster o espacio de trabajo tiene un objeto de esquema. Sólo los tipos de datos de salida de clase de entidad, tabla, ráster y espacio de trabajo tienen un esquema; los otros tipos de datos no. Accede a este esquema por medio del objeto de parámetro y configura las reglas para describir la salida. Al regresar de, updateParameters, la rutina de validación interna examina las reglas que configuró y actualiza la descripción de la salida.
Configurar dependencias
Siempre que crea una regla como "copiar los campos del dataset en el parámetro 3 y a continuación agregar un campo", tiene que decirle al objeto de Esquema qué parámetro desea copiar del (parámetro 3). Esto se realiza al agregar dependencias al objeto del parámetro. Puede agregar más de una dependencia.
def initializeParameters(self): # Set the dependencies for the output and its schema properties # self.params[2].parameterDependencies = [0, 1]
parameterDependencies toma una lista de Python.
El ejemplo a continuación muestra la configuración y el uso de dependencias.
Ejemplos de configuración de dependencias: Recortar y Agregar campo
Recuerde que Recortar realiza una copia de la definición de entidades de entrada, y establece la extensión como la intersección de las entidades de entrada y las entidades de recorte. A continuación se presenta un ejemplo de cómo se implementa esta regla en ToolValidator. (Debido a que Recortar es una herramienta integrada y no una secuencia de comandos, no utiliza una clase ToolValidator de Python. Las herramientas integradas realizan la validación con rutinas internas que esencialmente son las mismas que ToolValidator. Pero si utilizó una clase ToolValidator de Python, se vería de este modo).
def initializeParameters(self): # Set the dependencies for the output and its schema properties # self.params[2].parameterDependencies = [0, 1] # Feature type, geometry type, and fields all come from the first # dependent (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 updateParameters(self): return
Agregar campo copia la definición de un parámetro de entrada y agrega el campo especificado por el usuario. El vínculo a continuación muestra cómo se implementaría Agregar campo en ToolValidator.
Configuración de esquema en el inicio de initializeParameters frente a updateParameters
Observe que el ejemplo de Recortar que se muestra arriba modifica el objeto de Esquema en initializeParameters y que updateParameters no hace más que regresar. Agregar campo, por otra parte, debe modificar el objeto de Esquema en updateParameters porque no tiene la definición del campo a agregar hasta que el usuario brinde la información (y se invoque updateParameters).
Se pueden considerar estos dos casos como estático frente a dinámico. Recortar no necesita nada excepto los datasets encontrados en los parámetros dependientes (caso estático), mientras que Agregar campo debe examinar otros parámetros (como nombre de campo y tipo de campo) que no son parámetros dependientes (caso dinámico).
Este comportamiento estático y dinámico es evidente en la forma en que se invoca la clase ToolValidator a continuación:
- Cuando el cuadro de diálogo de la herramienta se abre por primera vez, se invoca initializeParameters(). Usted configura las reglas estáticas para describir la salida. No se genera ninguna descripción de salida en este momento, dado que el usuario no tiene valores especificados para ninguno de los parámetros.
- Una vez que el usuario interactúa con el cuadro de diálogo de la herramienta de algún modo, se invoca updateParameters.
- updateParameters puede modificar el objeto de esquema para justificar el comportamiento dinámico que no puede determinarse desde las dependencias del parámetro (como agregar un campo nuevo con Agregar campo).
- Después de regresar de updateParameters, se invocan las rutinas de validación internas y se aplican las reglas que se encuentran en el objeto de Esquema para actualizar la descripción de los datos de salida.
- Entonces se invoca updateMessages. Puede examinar los mensajes de advertencia y de error que la validación interna puede haber creado y modificarlos o agregar advertencias y errores.
Nombre del dataset de salida: Clonación de salida derivada frente a salida requerida
Cuando configura la propiedad Schema.Clone como verdadera, le está indicando al geoprocesamiento que realice una copia exacta (clon) de la descripción en el primer parámetro dependiente de la lista de dependencia de parámetros. Normalmente, configura Clon como verdadero en initializeParameters en lugar de updateParameters dado que solo se debe configurar una vez.
Si el ParameterType del parámetro de salida se configura como Derivado, se realiza una copia exacta. Este es el comportamiento de la herramienta Agregar campo.
Si ParameterType se configura como Requerido, también se realiza una copia exacta pero se modifica la ruta del catálogo al dataset. Dado que la mayoría de las herramientas generan datos nuevos, este comportamiento es el más común.
Más información
Programar una clase ToolValidator brinda detalles sobre los objetos de Parámetro, Esquema y Filtro, y proporciona ejemplos de código.
Todas las herramientas basadas en secuencia de comandos, como Zona de influencia en anillos múltiples, tienen un código de ToolValidator que puede se puede examinar y desde el cual puede aprender. La mayoría de las herramientas en la caja de herramientas Estadística espacial son herramientas de secuencia de comandos y tienen una implementación ToolValidator que puede examinar.
Desafortunadamente, cometerá errores en la implementación de ToolValidator, ya sea errores de sintaxis, runtime o lógica. Depurar una clase ToolValidator muestra cómo el geoprocesamiento captura e informa errores y le brinda algunas estrategias para la depuración.