ツールの [OK] ボタンをクリックする前に、整合チェックを必ず実行します。独自のカスタム ツールを作成する場合、整合チェックによって、パラメータの値に対する動作とパラメータ同士の動作をカスタマイズすることができます。整合チェックは、ツールの動作を制御するために使用される Python コードのブロックを使用して実行されます。
整合チェックの詳細については、「スクリプト ツールの整合チェックの概要」をご参照ください。
スクリプト ツールのダイアログ ボックスに、パラメータの有効化と無効化、デフォルト値の設定、文字列キーワードの更新など、カスタム動作を設定することができます。スクリプト ツールにカスタム動作を追加するには、スクリプト ツールを右クリックしてから、[プロパティ] → [確認] タブの順にクリックします。[確認] パネルでは、ToolValidator という Python クラスを実装する Python コードを記述できます。
ToolValidator クラスは Python コードを使用して実装されていますが、ツールの実際の処理には任意のスクリプト言語を使用できます。
ToolValidator は、initializeParameters(self)、updateParameters(self)、updateMessages(self) の 3 つのメソッドを持つ Python コードです。また、標準 Python クラスの初期化メソッドである __init__(self) も含まれています。ToolValidator クラスを表示および編集するには、スクリプト ツールを右クリックして、[プロパティ] → [確認] タブの順にクリックします。次の図は、デフォルト ToolValidator クラスのコードの [確認] タブです。コードを編集するには、[編集] ボタンをクリックします。編集後は、[OK] または [適用] をクリックして、編集内容を適用します。
メソッド | 説明 |
---|---|
__init__ | ToolValidator クラスを初期化します。必要なライブラリをインポートし、オブジェクト(self)を初期化します。 |
initializeParameters | ツールのダイアログ ボックスを最初に開いたとき、またはツールがコマンド ラインで最初に使用されるときに 1 度呼び出されます。 |
updateParameters | ツール ダイアログ ボックスでユーザがパラメータを変更するたびに呼び出されます。updateParameters が終了すると、ジオプロセシングは内部整合チェック ルーチンを呼び出します。 |
updateMessages | 内部整合チェック ルーチンが終了すると呼び出されます。内部整合チェックで作成されたメッセージは、必要に応じて変更できます。 |
ToolValidator コードの例を、次にいくつか示します。すべてのメソッドの詳細やその他の例については、「ToolValidator クラスのプログラミング」をご参照ください。
パラメータを有効化または無効化する
次の例は、[ホット スポット分析(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
コーディングの注意:Enabled などの Boolean 変数を設定する場合は、次の構文を使用できます。
self.params[8].enabled = 1
self.params[8].enabled = bool(1)
self.params[8].enabled = True # Note upper case: "True", not "true"
0 以外の数値または値は true と見なされます。
デフォルト値を設定する
次の例も、[ホット スポット分析(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
フィルタを更新する
次の例では、キーワードの選択肢が含まれる値のリスト フィルタを動的に更新しています。ユーザが 2 番目のパラメータに「OLD_FORMAT」を入力した場合、3 番目のパラメータには「POINT」、「LINE」、「POLYGON」が含まれます。「NEW_FORMAT」を入力した場合、3 番目のパラメータには、さらに 3 つの選択肢が含まれます。
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
次の例では、2 番目のパラメータの値のリスト フィルタが、最初のパラメータであるフィーチャクラスの形状タイプに基づいて変化します。
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
メッセージをカスタマイズする
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
Schema オブジェクトを使用した出力データの記述の更新
ツール ダイアログ ボックスの動作をカスタマイズする他に、ToolValidator を使用して、ModelBuilder の出力データ変数の記述を更新することができます。ModelBuilder 内のデータ変数は、次の図のように、データセットの簡単な説明と考えることができます。データ変数には、Python の Describe 関数を使用してアクセスできるすべてのプロパティが含まれています。
すべてのツールは、ModelBuilder で使用できるように、出力データの記述を更新する必要があります。記述を更新することで、ModelBuilder の後続のプロセスが、任意のプロセスの実行前にデータへの適用前の変更内容を参照できます。次の 2 つの例では、後続のプロセスが適用前の変更内容を参照しています。
次に示す最初の例は、[フィールドの追加(Add Field)] と [フィールド演算(Calculate Field)] ツールを含むモデルです。[フィールドの追加(Add Field)] では、Parks (2) という出力データ変数が TrackingID という新しいフィールドを持つように更新されています。出力が更新されたため、[フィールド演算(Calculate Field)] ダイアログ ボックスの [フィールド名] のリストには、[TrackingID] が表示されます。
2 番目の例(図はありません)は、[クリップ(Clip)] ツールの出力を [ポリゴン → ラスタ(Polygon to Raster)] ツールの入力として使用しているモデルです。[クリップ(Clip)] ツールは、入力フィーチャをくり抜く方法を使用するので、出力フィーチャクラスには、地理範囲という 1 つの大きな例外を除いて、入力フィーチャクラスと同じプロパティをすべて持ちます。出力フィーチャクラスの地理範囲は、入力およびクリップ フィーチャの範囲の交差部分です。[ポリゴン → ラスタ(Polygon to Raster)] ツールは、新しい地理範囲を使用して、デフォルトのセル サイズを決定します。
ToolValidator クラス内では、Schema オブジェクトを使用して、出力の記述を構築するためのルールを設定できます。たとえば、次のようなルールを設定できます。
- 入力データセットの記述のコピーを作成して、([フィールドの追加(Add Field)] のように)新しいフィールドをフィールドのリストに追加したり、([XY 座標の追加(Add XY Coordinates)] のように)固定フィールドのリストを追加したりします。
- ([ユニオン(Union)] や [インターセクト(Intersect)] のように)出力フィールドのリストがデータセットのコレクション内にあるすべてのフィールドになるように設定し、必要に応じて、データセットのコレクションからフィーチャ ID を含むフィールドを追加します。
- 範囲を、別のパラメータのデータセットの範囲や、パラメータのリスト内にあるデータセットのユニオンまたは([クリップ(Clip)] のように)インターセクトに設定します。
- 特定のジオメトリ タイプ(ポイント、ライン、ポリゴン)を設定します。または、別のパラメータ内にあるデータセットのジオメトリ タイプや、パラメータのリストにある最小または最大のタイプに設定します。最小および最大のジオメトリ タイプの定義は、ポイントは 0、ポリラインは 1、ポリゴンは 2 です。そのため、ポイント、ポリライン、ポリゴンの中で最小のジオメトリ タイプはポイントで、最大はポリゴンです。
出力パラメータが持つ Schema
Schema オブジェクトは、ジオプロセシングによって作成されます。タイプがフィーチャクラス、テーブル、ラスタ、ワークスペースである出力パラメータはすべて、Schema オブジェクトを持ちます。フィーチャクラス、テーブル、ラスタ、ワークスペースの出力データ タイプだけがスキーマを持ちます。他のデータ タイプは持ちません。このスキーマには、Parameter オブジェクトを通してアクセスし、出力を記述するためのルールを設定します。updateParameters が終了すると、内部整合チェック ルーチンが設定したルールを調べて、出力の記述を更新します。
依存性の設定
「パラメータ 3 のデータセットのフィールドをコピーしてから、フィールドを追加する」といったルールを作成する際は、コピー元のパラメータ(パラメータ 3)を Schema オブジェクトに教える必要があります。これには、Parameter オブジェクトに依存性を追加します。依存性は、複数追加することができます。
def initializeParameters(self):
# Set the dependencies for the output and its schema properties
#
self.params[2].parameterDependencies = [0, 1]
parameterDependencies は、Python リストを使用します。
以下の例は、依存性の設定と使用法を示しています。
依存性の設定の例:クリップ(Clip)とフィールドの追加(Add Field)
[クリップ(Clip)] は、入力フィーチャ定義のコピーを作成してから、入力フィーチャとクリップ フィーチャのインターセクトに範囲を設定します。次の例では、ToolValidator でこのルールを実装しています。([クリップ(Clip)] は組み込みツールであり、スクリプトではないため、Python の ToolValidator クラスは使用していません。組み込みツールは内部ルーチンを使用して整合チェックを行いますが、本質的には ToolValidator と同じです。しかし、もし Python の ToolValidator クラスを使用しているとすると、次のようになります。)
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
[フィールドの追加(Add Field)] は、入力パラメータの定義をコピーして、ユーザ指定フィールドを追加します。次のリンクは、[フィールドの追加(Add Field)] を ToolValidator で実装した場合を示しています。
initializeParameters 対 updateParameters でのスキーマの設定
上記の [クリップ(Clip)] の例は initializeParameters で Schema オブジェクトを変更し、updateParameters はリターン以外何もしていないことに注意してください。一方、[フィールドの追加(Add Field)] は、ユーザが情報を設定し(updateParameters が呼び出されるまで)、追加するフィールドの定義を持たないため、Schema オブジェクトは updateParameters で変更する必要があります。
これら 2 つは、静的な場合と動的な場合と考えることができます。[クリップ(Clip)] は従属パラメータ内のデータセット以外は使用しません(静的な場合)。一方、[フィールドの追加(Add Field)] は(フィールド名やフィールド タイプなど)従属パラメータでない他のパラメータを調べる必要があります(動的な場合)。
この静的な場合と動的な場合の動作の違いは、次のように、ToolValidator クラスの呼び出し方において明白になります。
- ツール ダイアログ ボックスを最初に開いたとき、initializeParameters が呼び出されます。ここには、出力を記述するための静的なルールを設定します。この時点では、ユーザはパラメータに値を指定していないため、出力の記述は作成されません。
- ユーザがツール ダイアログ ボックスと何らかの対話を行うと、updateParameters が呼び出されます。
- updateParameters は、[フィールドの追加(Add Field)] での新しいフィールドの追加といった、パラメータの依存性から決定できない動的な動作を扱うスキーマを変更できます。
- updateParameters の終了後、内部整合チェック ルーチンが呼び出され、Schema オブジェクト内にあるルールが適用されて、出力データの記述が更新されます。
- 次に、updateMessages が呼び出されます。内部整合チェックが作成した警告およびエラー メッセージを調べて、それらを変更したり、警告やエラーを追加したりできます。
出力データセット名:派生出力のクローン対必須出力
Schema.Clone プロパティを true に設定した場合、ジオプロセシングは、パラメータ依存性リストの最初の従属パラメータ内にある記述の厳密なコピー(クローン)を作成します。通常、Clone を true に設定するのは 1 回だけなので、設定は updateParameters ではなく initializeParameters で行います。
出力パラメータの ParameterType が Derived に設定されている場合、厳密なコピーが作成されます。[フィールドの追加(Add Field)] ツールの動作はこれです。
ParameterType が Required に設定されている場合、厳密なコピーも作成されますが、データセットへのカタログ パスが変更されます。ほとんどのツールは新しいデータを作成するため、これが最も一般的な動作です。
参考情報
「ToolValidator クラスのプログラミング」は、Parameter、Schema、Filter の各オブジェクトの詳細を説明して、コードの例を提示しています。
[多重リング バッファ(Multiple Ring Buffer)] など、すべてのスクリプトベースのシステム ツールには、参考になる ToolValidator コードがあります。[空間統計] ツールボックス内のほとんどのツールはスクリプト ツールなので、ToolValidator の実装を調べることができます。
ToolValidator の実装時に、構文やランタイムあるいはロジックのエラーといった誤りを犯すことがあります。「ToolValidator クラスのデバッグ」では、ジオプロセシングをトラップし、エラーを報告し、デバッグのための方針を得るための方法を説明しています。