La validation concerne tout ce qui se passe avant de cliquer sur le bouton OK d'un outil. Lorsque vous créez vos propres outils personnalisés, la validation vous permet de personnaliser les modalités de réaction des paramètres ainsi que leurs interactions avec les valeurs et avec les autres paramètres. La validation s'effectue avec un bloc de code Python permettant de contrôler le comportement de l'outil.
Pour en savoir plus sur la validation, reportez-vous à la rubrique Présentation de la validation dans les outils de script.
Vous pouvez personnaliser le comportement de la boîte de dialogue de votre outil de script, par exemple l'activation ou la désactivation des paramètres, la fourniture de valeurs par défaut ou la mise à jour des mots-clés d'une chaîne. Pour personnaliser le comportement de votre outil de script, cliquez avec le bouton droit sur l'outil de script, cliquez sur Propriétés, puis sur l'onglet Validation. Dans le volet Validation, vous pouvez indiquer le code Python qui implémente une classe Python nommée ToolValidator.
Bien que la classe ToolValidator soit implémentée à l'aide du code Python, vous pouvez utiliser n'importe quel langage de script pour accomplir le travail de l'outil.
ToolValidator est une classe Python qui contient trois méthodes : initializeParameters(self), updateParameters(self) et updateMessages(self). Elle contient également la méthode d'initialisation de la classe Python standard, __init__(self). Pour afficher et modifier la classe ToolValidator, cliquez avec le bouton droit sur votre outil de script, cliquez sur Propriétés, puis sur l'onglet Validation. L'illustration suivante montre l'onglet Validation avec le code de la classe ToolValidator par défaut. Cliquez sur le bouton Modifier pour modifier le code, puis cliquez sur OK ou Appliquer pour appliquer vos modifications.
Méthode | Description |
---|---|
__init__ | Initialise la classe ToolValidator. Importez les bibliothèques dont vous avez besoin et initialisez l'objet (self). |
initializeParameters | Appelée lors de la première ouverture de la boîte de dialogue de l'outil ou lorsque l'outil est utilisé pour la première fois dans la ligne de commande. |
updateParameters | Appelée à chaque fois que l'utilisateur modifie un paramètre dans la boîte de dialogue de l'outil. Après le renvoi à partir d'updateParameters, le géotraitement appelle sa routine de validation interne. |
updateMessages | Appelée après le renvoi à partir de la routine de validation interne. Vous pouvez examiner les messages créés à partir de la validation interne et les modifier si vous le souhaitez. |
Voici quelques exemples de code ToolValidator. Pour une description complète de toutes les méthodes et pour plus d'exemples, consultez la rubrique Programmation d'une classe ToolValidator.
Activer ou désactiver un paramètre
L'exemple ci-dessous provient de l'outil Hot Spot Analysis :
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
Remarque de codage : lorsque vous définissez des variables booléennes, telles que Enabled, vous pouvez utiliser ces syntaxes :
self.params[8].enabled = 1
self.params[8].enabled = bool(1)
self.params[8].enabled = True # Note upper case: "True", not "true"
Tout nombre ou valeur non nul(le) est considéré(e) comme vrai(e).
Définir une valeur par défaut
Cet exemple provient également de l'outil Hot Spot Analysis :
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
Mettre à jour un filtre
Voici un exemple de mise à jour dynamique d'un filtre Liste de valeurs contenant une liste de mots-clés. Si l'utilisateur saisit "OLD_FORMAT" dans le deuxième paramètre, le troisième paramètre contient "POINT", "LIGNE" et "POLYGONE". Si "NEW_FORMAT" est saisi, le troisième paramètre contient trois choix supplémentaires.
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
Voici un autre exemple où le filtre Liste de valeurs dans le second paramètre change en fonction du type de forme présent dans le premier paramètre, une classe d'entités :
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
Personnaliser un message
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
Mise à jour de la description de données en sortie à l'aide de l'objet de schéma
Outre la personnalisation du comportement de la boîte de dialogue de l'outil, vous pouvez utiliser ToolValidator pour mettre à jour les descriptions de variables de données en sortie pour ModelBuilder. Les variables de données dans ModelBuilder peuvent être considérées comme de brèves descriptions des jeux de données, comme illustré ci-dessous. Les variables de données contiennent toutes les propriétés auxquelles vous avez accès à l'aide de la fonction Describe dans Python.
Tous les outils doivent mettre à jour la description de leurs données en sortie pour leur utilisation dans ModelBuilder. En mettant à jour la description, les processus suivants dans ModelBuilder peuvent voir les modifications des données en attente avant l'exécution de tout processus. Les deux exemples ci-dessous montrent comment les processus suivants considèrent les modifications en attente.
Le premier exemple, illustré ci-dessous, montre un modèle contenant les outils Ajouter un champ et Calculer un champ. Dans Ajouter un champ, la variable de données en sortie, Parks (2), est mise à jour pour contenir le nouveau champ, TrackingID. Du fait de la mise à jour de la sortie, la boîte de dialogue Calculer un champ affiche TrackingID dans la liste des noms de champs.
Le second exemple (non illustré) est un modèle où la sortie de l'outil Découper est utilisée comme entrée de l'outil Polygone vers raster. Etant donné que l'outil Découper découpe les entités en entrée, la classe d'entités en sortie a les mêmes propriétés que la classe d'entités en entrée, à une exception près : son étendue géographique. L'étendue géographique de la classe d'entités en sortie correspond à l'intersection géométrique de l'entrée et des étendues d'entités de découpage. L'outil Polygone vers raster utilise la nouvelle étendue géographique pour déterminer une taille de cellule par défaut.
Dans la classe ToolValidator, vous pouvez utiliser un objet Schema pour établir des règles pour créer la description de la sortie. Par exemple, vous pouvez établir les règles suivantes :
- Faire une copie de la description du jeu de données en entrée et ajouter un nouveau champ à sa liste de champs (comme Ajouter un champ) ou ajouter une liste de champs fixes (comme Ajouter les coordonnées XY).
- Définir la liste des champs en sortie comme étant tous les champs dans un ensemble de jeux de données et, éventuellement, ajouter des champs pour contenir les identifiants des entités à partir de l'ensemble des jeux de données (comme Agréger et Intersecter).
- Définir l'étendue d'un jeu de données dans un autre paramètre ou l'union ou l'intersection (comme Découper) de jeux de données dans une liste de paramètres.
- Définir un type de géométrie spécifique (point, ligne ou polygone), le définir sur celui d'un jeu de données dans un autre paramètre ou sur un type minimal ou maximal dans une liste de paramètres. La définition du type de géométrie minimal et maximal est points = 0, polylignes = 1, polygones = 2. Le type de géométrie minimal dans l'ensemble {point, polyligne, polygone} est donc le point et le maximal, le polygone.
Les paramètres en sortie ont un objet Schema
L'objet Schema est créé par géotraitement. Chaque paramètre de type classe d'entités, table, raster ou espace de travail en sortie dispose d'un objet Schema. Seules les données de type classe d'entités, table, raster et espace de travail en sortie disposent d'un objet Schema, tous les autres types de données n'en ont pas. Vous pouvez accéder à cette structure via l'objet Parameter et définir les règles de description de la sortie. Lors du renvoi à partir d'updateParameters, la routine de validation interne examine les règles que vous avez définies et actualise la description de la sortie.
Définition des dépendances
Chaque fois que vous créez une règle telle que "copier les champs du jeu de données dans le paramètre 3, puis ajouter un champ", vous devez indiquer à l'objet Schema à partir de quel paramètre vous souhaitez effectuer la copie (paramètre 3). en ajoutant des dépendances à l'objet Parameter. Vous pouvez ajouter plusieurs dépendances.
def initializeParameters(self):
# Set the dependencies for the output and its schema properties
#
self.params[2].parameterDependencies = [0, 1]
ParameterDependencies prend une liste Python.
Les exemples suivants montrent comment définir et utiliser des dépendances.
Exemples de définition de dépendances : Découper et Ajouter un champ
Rappelez-vous que l'outil Découper copie la définition des entités en entrée, puis définit l'étendue sur l'intersection des entités en entrée et des entités de découpage. L'exemple suivant montre comment cette règle est appliquée dans ToolValidator. (L'outil Découper étant un outil intégré et non un script, il n'utilise pas de classe ToolValidator Python. Les outils intégrés procèdent à leur validation à l'aide de routines internes qui sont essentiellement les mêmes que ToolValidator. Toutefois, si une classe ToolValidator Python avait été utilisée, cela ressemblerait à ça.)
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
L'outil Ajouter un champ copie la définition d'un paramètre en entrée et ajoute le champ spécifié par l'utilisateur. Le lien ci-dessous montre comment Ajouter un champ serait implémenté dans ToolValidator.
Définition d'une structure dans initializeParameters et updateParameters
Notez que l'exemple de Découper ci-dessus modifie l'objet Schema dans initializeParameters et que updateParameters se contente de renvoyer. En revanche, l'outil Ajouter un champ doit modifier l'objet Schema dans updateParameters car il ne possède pas la définition du champ à ajouter jusqu'à ce que l'utilisateur fournisse les informations (updateParameters est alors appelé).
Ces deux cas peuvent être considérés comme statique et dynamique. Découper s'appuie uniquement sur les jeux de données figurant dans les paramètres dépendants (cas statique), tandis que l'outil Ajouter un champ doit examiner d'autres paramètres (tels que le nom de champ et le type de champ) qui ne sont pas des paramètres dépendants (cas dynamique).
Ce comportement statique et dynamique est évident dans la façon dont une classe ToolValidator est appelée :
- Lors de la première ouverture de la boîte de dialogue de l'outil, initializeParameters est appelé. Vous définissez les règles statiques pour décrire la sortie. Aucune description en sortie n'est créée à ce moment, puisque l'utilisateur n'a spécifié aucune valeur pour les paramètres.
- Une fois que l'utilisateur a interagi d'une manière quelconque avec la boîte de dialogue de l'outil, updateParameters est appelé.
- updateParameters peut modifier la structure pour prendre en compte le comportement dynamique qui ne peut pas être déterminé à partir des dépendances de paramètres, comme par exemple l'ajout d'un nouveau champ tel qu'Ajouter un champ.
- Après avoir été renvoyées à partir d'updateParameters, les routines de validation internes sont appelées et les règles figurant dans l'objet Schema sont appliquées pour mettre à jour la description des données en sortie.
- updateMessages est alors appelé. Vous pouvez examiner les messages d'avertissement et d'erreur que la validation interne a pu créer et les modifier ou ajouter des messages d'avertissements et d'erreurs.
Nom du jeu de données en sortie : clonage de sortie dérivée et de sortie requise
Lorsque vous définissez la propriété Schema.Clone sur true, vous indiquez au géotraitement de faire une copie exacte (clone) de la description dans le premier paramètre dépendant de la liste des dépendances de paramètres. En règle générale, vous définissez Clone sur true dans initializeParameters plutôt que dans updateParameters, puisqu'il n'a besoin d'être défini qu'une fois.
Si le ParameterType du paramètre en sortie est défini sur Derived, une copie exacte est faite. C'est le comportement de l'outil Ajouter un champ.
Si le ParameterType est défini sur Required, une copie exacte est également faite, mais le chemin d'accès du catalogue au jeu de données est modifié. Etant donné que la plupart des outils créent de nouvelles données, c'est le comportement le plus courant.
Pour en savoir plus
La rubrique Programmation d'une classe ToolValidator fournit des informations sur les objets Parameter, Schema et Filter et donne des exemples de code.
Tous les outils système basés sur des scripts, tels que les anneaux concentriques multiples, disposent d'un code ToolValidator que vous pouvez examiner et étudier. De nombreux outils de la boîte à outils Spatial Statistics sont des outils de script, et vous pouvez examiner leur implémentation dans ToolValidator.
Vous ferez certainement des erreurs dans votre implémentation de ToolValidator : des erreurs de syntaxe, d'exécution ou de logique. La rubrique Débogage d'une classe ToolValidator vous montre comment le géotraitement repère et signale les erreurs et vous donne des stratégies de débogage.