[値の計算] ツールは、Python 式から値を返す汎用 ModelBuilder ツールです。 このツールではシンプルな計算、Python の組み込みの関数とモジュール、ジオプロセシング関数とオブジェクト、独自の Python コードをサポートしています。
式
[式] パラメーターだけを使用してさまざまな計算を実行します。
算術計算
[値の計算] ツールで評価の対象となるのは、Python の簡易な算術式です。 以下のサンプル式をご参照ください。
演算子 | 説明 | 例 | 結果 |
---|---|---|---|
x + y | x に y を加算 | 3 + 5 | 8 |
x - y | x から y を減算 | 4.3 - 2.1 | 2.2 |
x * y | x に y を乗算 | 8 * 9 | 72 |
x / y | x を y で除算 | 4 / 1.25 | 3.2 |
x // y | x を y で除算 (切り捨て除算) | 4 // 1.25 | 3 |
x % y | x を y で除算した結果の余り | 4 % 1.25 | 0.25 |
x**y | x の y 乗 | 2 ** 3 | 8 |
x < y | x が y 未満かどうか | 2 < 3 | 1 |
x <= y | x が y 以下かどうか | 2 <=3 | 1 |
x > y | x が y より大きいかどうか | 2 > 3 | 0 |
x >= y | x が y 以上かどうか | 2 >= 3 | 0 |
x == y | x と y が等しいかどうか | 2 == 3 | 0 |
x != y | x と y が等しくないかどうか | 2 != 3 | 1 |
[値の計算] ツールでは、Python の math モジュールを使用することによって、複雑な数値演算の実行を実現しています。
値の平方根を返します。
Expression:
math.sqrt(25)
値の余弦をラジアン単位で返します。
Expression:
math.cos(0.5)
定数も math モジュールを介してサポートされます。
π の定数値を返します。
Expression:
math.pi
[値の計算] ツールでは、random モジュールを使用して乱数を生成できます。 以下は、random モジュールの使用例です。
0 ~ 10 のランダム整数を返します。
Expression:
random.randint(0, 10)
平均値が 10、標準偏差が 3 の正規分布から派生したランダム値を返します。
Expression:
random.normalvariate(10, 3)
文字列の例
文字列値では Python 演算子とインデックスを使用できます。
例 | 説明 | 結果 |
---|---|---|
"Input" + " " + "Name" | 文字列の連結。 | 入力名 |
"Input_Name"[6:] | 最後から 7 つ目の文字 | 名前 |
"STREET".lower() | 文字列値を小文字に変換します。 | 道路 |
"Street Name".split()[1] | ある文字列をスペースで区切って複数の文字列に分割します。 さらに、2 番目に返された文字列を取得します。 | 名前 |
[値の計算] ツールでは文字列の文字を置換または削除できます。 たとえば、入力値に小数部分 (この例では、入力テーブルのフィールド値) があり、その小数部分の値をインライン変数置換で別のツールの出力名に含める場合は、replace メソッドを使用して小数部分を置換することができます。
Expression:
"%Value%".replace(".", "")
文字列では、Python はバックスラッシュ文字 (\) をエスケープ文字として扱います。 たとえば、文字列 "C:\temp\newProjectFolder" で \n は改行を表し、\t はタブを表します。 文字列が想定通りに解釈されるようにするために、次のいずれかを実行します。
- バックスラッシュの代わりにスラッシュ (/) を使用する。
- バックスラッシュを 1 つではなく 2 つ使用する。
- 文字列の前に文字 r を配置することで、文字列を文字列リテラルに変換する。
データ タイプ
[データ タイプ] パラメーターでは、[値の計算] ツール出力のデータ タイプを指定します。 [値の計算] ツールの出力データ タイプが、後続のツールの必須入力データ タイプと一致していることを確認することが重要です。
[値の計算] ツールの出力は、[Plus]、[Greater Than]、[Less Than] など、ラスターまたは定数値を受け入れるどの Spatial Analyst ツールでも使用できます。 [値の計算] ツールの出力を使用するには、[データ タイプ] の値を [構築されたラスター] に変更します。 このデータ タイプは、セル値が数式または定数で表されるラスター サーフェスです。
[Greater Than] ツールの入力として使用される、[構築されたラスター] データ タイプの計算された値を返します。
Expression:
%A% + 120
[式] パラメーター値ではインライン変数置換を使用します。 ツールを実行すると、%A% は変数 A の値で置換されます。 変数 [A] に 120 を足した値は、[Greater Than] ツールの [入力ラスター、または定数値 1] として使用されます。
コード ブロック
シンプルな計算の場合、通常は [式] パラメーターだけを使用すれば済みます。 複数行の計算や論理演算 (if-else) などの複雑な式の場合は、[コード ブロック] パラメーターも必要です。 [コード ブロック] パラメーターは [式] パラメーターと併用する必要があります。
[コード ブロック] パラメーターで定義しておいた変数は、[式] パラメーターから参照できます。
たとえば、フォルダー パスのファイル数をカウントする「size」が [コード ブロック] で定義されています。 これは、実行中に [式] パラメーターから参照されます。 [値の計算] ツールの出力値は実際のファイル数に 5 を足したものになります。
Expression:
5 + size
Code Block:
import os
size = 0
folderpath = r"C:\temp\csvFiles"
for ele in os.scandir(folderpath):
size += 1
[コード ブロック] パラメーターを使って関数を定義し、[式] パラメーターから関数を呼び出すこともできます。 Python では、def ステートメントの後に関数名を付けることで関数を定義します。 関数には必須の引数とオプションの引数を含めることも、引数を一切含めないこともできます。 return ステートメントを使用して関数の出力を返します。
時間
[コード ブロック] パラメーターを使用して Python のモジュールとメソッドを呼び出せます。 以下の例では、time モジュールの ctime メソッドを呼び出しています。
データを定期的にバックアップする必要があるケースでは、フォルダー名に時間を追加することでデータを区別しやすくなります。 次の例は、フォルダー名にタイム スタンプを追加する方法を示しています。 time.ctime 関数は「Tue Jun 22 16:24:08 2021」のような形式で現在の日時を返します。 スペースと句読点が許可されていないため、[フォルダーの作成] ツールで戻り値を直接フォルダー名として使用することはできません。 これらを削除するには、置換の必要なエレメントごとにメソッドをスタックして、Python の replace メソッドを使用します。 この例で結果として得られるフォルダーの名前は「TueJun221622522021」です。
Expression:
gettime()
Code Block:
import time
def gettime():
# First replace removes punctuation marks. Second replace removes spaces.
return time.ctime().replace(":", "").replace(" ", "")
If-then-else とインライン置換
[コード ブロック] パラメーターは関数入力パラメーターを通じて値を取ることもできます。 [コード ブロック] のパラメーター数は、[式] パラメーターのパラメーター数と一致させる必要があります。 ツールを実行すると、[式] から [コード ブロック] にパラメーター値が渡されます。 以下に示すように、[式] パラメーターとしてインライン変数を使用することで、モデル変数値を渡せます。
以下の例では、関数 getAspectDir に 1 つのパラメーターとして inValue があります。 [式] パラメーターは [Input Degree] 変数の値を [コード ブロック] に渡します。
以下の例では、[Input Degree] 値に基づいて傾斜方向を計算しています。 [Input Degree] 変数値が「223」であるため、出力傾斜方向として「South」が返されます。
Expression:
getAspectDir("%Input Degree%")
Code Block:
def getAspectDir(inValue):
inValue = int(inValue)
if inValue >= 45 and inValue < 135:
return "East"
elif inValue >= 135 and inValue < 225:
return "South"
elif inValue >= 225 and inValue < 315:
return "West"
else:
return "North"
複数のインライン置換
[コード ブロック] パラメーターでは複数のインライン変数値を取ることもできます。
コード ブロックは、[User Input Value] 変数の値が [Default Value] の値より大きいかどうかをチェックします。 値が大きい場合、[値の計算] ツールの出力値は [User Input Value] になります。 それ以外の場合、出力値は [Default Value] の値になります。 こちらのケースでは、[出力値] が 10 になります。
Expression:
fn("%User Input Value%","%Default Value%")
Code Block:
def fn(userInputValue, defaultValue):
if float(userInputValue) > float(defaultValue):
return float(userInputValue)
else:
return float(defaultValue)
注意:
式で文字列型のインライン変数を引用符 ("%string variable%") で囲みます。 インライン変数が数値 (double、long) 型なら、引用符は必要ありません (「%double%」のように指定すれば済みます)。
データ パスの連結
次の例は、指定したフォルダー パスと名前にフィーチャをコピーする方法を示しています。 [コード ブロック] パラメーターでは、[Folder Path] と [Folder Name] の 2 つの値を使用できます。 このコードではフォルダー パスと名前の組み合わせが存在するかどうかを評価します。 組み合わせたパスが存在しない場合、makedirs 関数によって不足しているフォルダーが追加されます。 パスが適切に解釈されるようにするには、[式] パラメーターでフォルダー パスの前に文字「r」が必要です。
Expression:
getPath(r"%Folder Path%", "%Folder Name%")
Code Block:
import os
def getPath(folderPath, folderName):
outPath = os.path.join(folderPath, folderName)
if not os.path.exists(outPath):
os.makedirs(outPath)
return outPath
バッファー距離値と単位の連結
[バッファー] ツールなど、直線距離を受け付けるツールと [値の計算] ツールを併用するには、以下を実行します。
- [コード ブロック] パラメーターで距離値と距離単位を返します。
- [データ タイプ] パラメーター値を [距離単位] に設定します。
こちらの例では、[値の計算] ツールが [バッファー] ツールで使用する値「12 Kilometers」を返しています。
Expression:
fn("%A%", "%B%")
Code Block:
def fn(a, b):
distance = int(a) * int(b)
return f"{distance} Kilometers"
ArcPy
ArcPy は、Python によるグラフィックス データの解析、データの変換、データの管理、マップの自動化を実行するうえで有用かつ生産性の高い方法を提供する、Esri Python サイト パッケージです。ArcPy は、ジオプロセシング ツールへのアクセスだけでなく、単純または複雑なワークフローを作成するための追加機能、クラス、モジュールへのアクセスも提供します。
Cursor
カーソルを使ってデータを操作できます。 カーソルとは、テーブルの行セットの反復処理やテーブルへの新しい行の挿入に使用できるデータ アクセス オブジェクトです。 カーソルには検索、挿入、および更新の 3 つの形態があり、一般的にはデータの読み取りと書き込みに使用されます。
樹木の種類コードを一般的な名前に変換するには、UpdateCursor を使用してテーブルの各樹木を反復処理します。 樹木コード値に基づいて、それに一般的な名前を割り当てます。 たとえば、樹木のコードが「PIPO」の場合、一般的な名前である「ponderosa pine」を CommonName フィールドに割り当てます。
Expression:
fn("%trees%")
Code Block:
def fn(trees):
with arcpy.da.UpdateCursor(trees, ["Code", "CommonName"]) as cursor:
for row in cursor:
if row[0] == "PIPO":
row[1] = "ponderosa pine"
elif row[0] == "BEPA":
row[1] = "paper birch"
elif row[0] == "FAGR":
row[1] = "American beech"
cursor.updateRow(row)
ジオプロセシング ツール
ArcPy はジオプロセシング ツールへのアクセスも可能にします。 [コード ブロック] パラメーター内でジオプロセシング ツールを呼び出せます。
以下の例では、[値の計算] ツールで [属性検索]、[フィーチャのコピー]、[バッファー] の各ツールを使用しています。 「HIGHWAY」という単語を含む LABEL フィールドがある道路をツールがすべて選択し、それらのコピーを作成して道路をバッファーします。
Expression:
fn("%Input Feature Class%")
Code Block:
def fn(InputFC):
# To allow overwriting outputs change overwriteOutput option to True.
arcpy.env.overwriteOutput = True
# Process: Select Layer By Attribute (Select Layer By Attribute) (management)
InputFC_Layer, Count = arcpy.management.SelectLayerByAttribute(InputFC, "NEW_SELECTION", "LABEL LIKE '%HIGHWAY%'")
# Process: Copy Features (Copy Features) (management)
copyFeaturesOutput = "C:\\temp\\Output.gdb\\copyFeaturesOutput"
arcpy.management.CopyFeatures(InputFC_Layer, copyFeaturesOutput)
# Process: Buffer (Buffer) (analysis)
bufferOutput = "C:\\temp\\Output.gdb\\bufferOutput"
arcpy.analysis.Buffer(copyFeaturesOutput, bufferOutput, "1500 Feet")
return bufferOutput