Personalizar el comportamiento de una herramienta 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. Al agregar el código Python, puede
- Habilitar o deshabilitar un parámetro según los valores incluidos en otros parámetros.
- Actualizar un filtro de parámetro. Con un filtro de campo, puede crear una lista de tipos de campos válidos, como LONG y DOUBLE. Con un filtro de cadena de texto, puede configurar una lista de palabras clave válidas, como se muestra a continuación. Hay seis tipos de filtros: Lista de valores, Rango, Clase de entidad, Archivo, Campo y Espacio de trabajo.
- Proporcione valores predeterminados para los parámetros, como el tamaño de celda para los rásteres.
- Personalice los mensajes de advertencia y error que aparecen en el cuadro de diálogo.
- Coloque los parámetros en diferentes categorías.
- Actualice la descripción de datasets de salida para utilizar en ModelBuilder.
Cómo funciona ToolValidator
La clase ToolValidator es un bloque de código Python que utiliza el geoprocesamiento para controlar cómo cambia el cuadro de diálogo de la herramienta y la ventana Python según la entrada del usuario. La clase ToolValidator también se utiliza para describir los datos de salida de la herramienta, lo cual es importante para la construcción de modelos. Las herramientas del sistema (proporcionadas por Esri) siempre han tenido la capacidad de reaccionar a la entrada del usuario y posteriormente modificar el cuadro de diálogo de la herramienta como se describe anteriormente.
Hasta ArcGIS 9.3, las herramientas de secuencia de comandos no tuvieron esta capacidad: el cuadro de diálogo de la herramienta era estático y la salida de la herramienta de secuencia de comandos no incluía una descripción actualizada, dificultando el trabajo con herramientas de secuencia de comandos en ModelBuilder. La clase ToolValidator está disponible para brindarle todas las capacidades de una herramienta de sistema.
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 y validación
Validación significa verificar que todos los parámetros de la herramienta sean correctos y proporcionar mensajes útiles si es el caso contrario. Hay dos partes en la validación:
- La parte que puede hacer al agregar un código a la clase de ToolValidator.
- La parte que ArcGIS hace automáticamente por usted. Se hace referencia a esta parte de la validación como validación interna (o validación básica), dado que es la validación básica que se realiza internamente mediante el geoprocesamiento en ArcGIS.
En primer lugar, observe lo que hace la validación interna:
- Si se requiere un parámetro, comprobar que esté vacío (nada introducido aún) y, si es así, enviar el mensaje "Se requiere un valor" al cuadro de diálogo de la herramienta (con un punto verde en lugar de una x roja).
- Comprobar que el valor que el usuario introdujo sea del tipo correcto (por ejemplo, introducir un ráster en lugar de una clase de entidad o un carácter alfabético en vez de un número).
- Comprobar la pertenencia del filtro. Es decir, si tiene un filtro de Lista de valores que incluye palabras clave como ROJO, NARANJA y AMARILLO y usted escribe AZUL, recibirá un mensaje de error porque AZUL no se encuentra en el filtro de Lista de valores.
- Comprobar la existencia de datasets de entrada.
- Generar una ruta de catálogo predeterminada para datasets de salida.
- Actualizar la descripción de la información de salida de acuerdo con un conjunto de reglas incluidas en el objeto especial, Esquema.
- Comprobar la existencia de datasets de salida contra la configuración del entorno overwriteOutput. Si el dataset existe y la configuración overwriteOutput es falsa, se produce un error; en caso contrario, se produce una advertencia.
- Si el parámetro es un tipo de datos de campo, verificar la existencia del campo en la tabla asociada.
- Comprobar que el dataset de salida no sea el mismo que el dataset de entrada (a menos que se derive la salida, como Agregar campo).
- Para los parámetros que contienen tipos de datos de unidad de área y lineales, configurar los valores predeterminados al examinar los valores correspondientes en ArcMap (si se ejecutan desde ArcMap).
- Si la salida es una cobertura, cuadrícula o tabla INFO, comprobar el límite de 13 caracteres del nombre del archivo para estos datasets.
La validación interna no realiza lo siguiente (pero lo puede realizar con una clase ToolValidator):
- Actualizar los filtros de acuerdo con la interacción con otros parámetros. Por ejemplo, si el usuario introduce una clase de entidad de punto en el primer parámetro, usted quiere que el cuadro de diálogo de la herramienta visualice ROJO, NARANJA y AMARILLO en el tercer parámetro. Si introducen una clase de entidad poligonal, querrá visualizar AZUL, ÍNDIGO y VIOLETA en el tercer parámetro.
- Habilitar/deshabilitar parámetros.
- Calcular valores predeterminados.
- Ejecutar cualquier interacción de parámetro específica de la herramienta.
El código que agrega a la clase ToolValidator trabaja junto con la validación interna de la manera siguiente:
- Puede proporcionar un conjunto de reglas que la validación interna utiliza para actualizar la descripción de datasets de salida. Estas reglas se incluyen en un objeto de esquema.
- Puede actualizar los filtros antes de que se lleve a cabo la validación interna. Considerando el ejemplo anterior, si se introduce una clase de entidad de puntos, actualizaría el filtro para incluir ROJO, NARANJA y AMARILLO. La validación interna verifica el valor que el usuario introdujo contra los valores encontrados en el filtro.
Además, como se menciona, puede hacer que ToolValidator calcule los valores predeterminados, habilite y deshabilite parámetros y personalice mensajes. Estos tipos de acciones no influyen en la validación interna; sólo afectan la apariencia del cuadro de diálogo de la herramienta.
Uso de la clase ToolValidator para personalizar el cuadro de diálogo 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 o la línea de comandos. 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. |
No invoque otras herramientas de geoprocesamiento ni abra datasets en ToolValidator porque la clase ToolValidator se ejecuta cada vez que un usuario modifica algo en el cuadro de diálogo de la herramienta. Utilice las herramientas de geoprocesamiento en la secuencia de comandos, no en ToolValidator.
Debe implementar los tres métodos, initializeParameters(self), updateParameters(self) y updateMessages(self). No deben hacer nada excepto volver pero se deben proporcionar para que ToolValidator sea una clase de Python válida.
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, como Habilitado, puede utilizar 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). # import string if self.params[0].value: if not self.params[6].altered: extent = string.split(arcpy.Describe(self.params[0].value).extent, " ") width = float(extent[2]) - float(extent[0]) height = float(extent[3]) - float(extent[1]) if width > height: self.params[6].value = width / 100 else: self.params[6].value = 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 simplemente 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 coordinadas 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 volver 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.
Si nunca utilizó listas o una lista de listas, al principio puede parecer confuso pero rápidamente se acostumbrará a ellas y encontrará su utilidad para toda clase de actividades. A continuación se presenta un código de Python que demuestra listas y listas de listas. Estos ejemplos se muestran en modo interactivo (la ventana de Python, la ventana Interactiva en PythonWin o Python Shell en IDLE), donde introduce un código y obtiene resultados inmediatos.
Ejemplo 1: En Python, toda variable o literal que está rodeada por corchetes se transforma en una lista. Cuando imprime una lista, siempre se agregan los corchetes.
>>> a = [1] >>> print a [1] >>> b = 2 >>> c = [b] >>> print c [2]
Ejemplo 2: Una lista puede contener cualquier cantidad de elementos de todo tipo. Para acceder a un elemento de la lista, utilice corchetes que incluyan el índice del elemento. El primer elemento de una lista es siempre [0].
>>> a = [1, "two", 12.6] >>> print a [1, 'two', 12.6] >>> print a[0] 1
Ejemplo 3: una lista de listas simple
>>> listOfLists = [ [1,2,3], ["one", "two", "three"] ] >>> print listOfLists [[1, 2, 3], ['one', 'two', 'three']] >>> print listOfLists[0] [1, 2, 3] >>> print listOfLists[0][2] 3 >>> print listOfLists[1][2] three
Ejemplo 4: otra lista de listas. Observe que las listas miembro no tienen que ser de la misma longitud.
>>> listA = [1, 2, 3] >>> listB = ["a", "b", "C", "Z"] >>> listOfLists = [listA, listB] >>> print listOfLists [[1, 2, 3], ['a', 'b', 'C', 'Z']] >>> print listOfLists[1][3] Z
Ejemplo 5: Cree una lista vacía y a continuación agregue y quite cosas.
>>> a = [] >>> a.append("zero") >>> print a ['zero'] >>> b = [1, 2, 3] >>> a.append(b) >>> print a ['zero', [1, 2, 3]] >>> a.remove([1, 2, 3]) >>> print a ['zero']
Para obtener más información sobre las listas de Python (o sobre cualquier otra característica de Python), visite http://docs.python.org/.
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 updateParameter(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 sean 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.