スクリプトでの出力シンボルの設定

スクリプト ツールのパラメータのシンボル プロパティを使用すると、単一のレイヤ ファイル(*.lyr)を出力パラメータに関連付けることができます。スクリプト ツールを実行すると、レイヤ ファイル内にあるシンボルを使用して、出力がディスプレイに追加されます。また、スクリプトの symbology コードでシンボル プロパティを設定することもできます。

いずれの場合も、出力パラメータに関連付けることができるレイヤ ファイルは 1 つに限られます。出力が明確に定義されている場合は、1 つのレイヤ ファイルだけで十分に機能します。ただし、出力が明確に定義されていない場合もあります。たとえば、出力が 1 つのフィーチャクラスであることがわかっていても、そのフィーチャクラスに含まれるのがポイント、ポリライン、ポリゴン フィーチャのいずれであるかが、ツールが実行されるまで不明な場合などです。レイヤ ファイルはジオメトリ タイプに依存しています。つまり、1 つのレイヤ ファイルで複数のフィーチャ タイプをシンボル表示することはできません。このような場合は、ジオメトリ タイプごとに 1 つずつ、3 つのレイヤ ファイルを用意し、出力ジオメトリ タイプに基づいて正しいレイヤ ファイルを関連付ける必要があります。次のコード スニペットは、この手法を具体的に示しています。

    # Set the symbology of the output. 
    #   output    = the output value
    #   params[2] = the output parameter
    #
    params = arcpy.GetParameterInfo()
    desc = arcpy.Describe(output)
    if desc.shapeType == "Polygon":
        params[2].symbology = "c:/Tools/Extractor/ToolData/polygon.lyr"
    elif desc.shapeType == "Polyline":
        params[2].symbology = "c:/Tools/Extractor/ToolData/polyline.lyr"
    else:
        params[2].symbology = "c:/Tools/Extractor/ToolData/point.lyr"

上記のスクリプトのロジックは比較的簡単で、ジオメトリ(シェープ)タイプをテストし、その結果に従ってレイヤ ファイルを設定します。より複雑なロジックの場合でも、パターンはこれと同じです。

スクリプトでのシンボルの設定と ToolValidator クラスでのシンボルの設定

ToolValidator クラスでのツール整合チェック ロジックのプログラミングに精通していれば、上記のコード スニペットを updateParameters メソッドに書き換えて使用できることがわかります。実際には、1 つのレイヤ ファイルだけを参照する必要がある場合に、スクリプト ツールのプロパティまたは initializeParameters メソッドのいずれかで設定を行います。しかし、複数のレイヤ ファイルのうちのいずれかにシンボルを設定する必要がある場合は、スクリプト ツールで設定してください。この種のロジックを ToolValidator クラスで設定すると、ツールの整合チェックと関係がないロジックによってコードが肥大化し、場合によっては、使用されるレイヤ ファイルが、ツールが実行されるまでわからなくなることがあります。

サンプル スクリプト

次に示すスクリプトでは、ポートランド市の公園からの距離に基づいてフィーチャを作成します。入力フィーチャ、距離、および出力フィーチャという 3 つのパラメータがあります。出力フィーチャは、マップ上で他のフィーチャと簡単に区別できるようにシンボル表示されます(区別しにくいデフォルト シンボル以外のシンボル)。入力フィーチャはポイント、ポリライン、またはポリゴンのいずれかであるため、3 つの異なるレイヤ ファイルが必要とされます。

このスクリプトでは、移植性を確保するために、複数のコーディング テクニックを具体的に示しています。これらはすべてツール共有フォルダ構造をベースにしています。

使用されている移植性を持つテクニックは次のとおりです。

Python スクリプトの移植性の詳細

# ExtractData.py
# Description: Script that will extract features from an input layer within a specified
#              distance from a park.
# Parameters:
#  0 - input features
#  1 - distance from parks (linear units)
#  2 - output feature class

import arcpy
from arcpy import env
import os
import sys

env.overwriteOutput = True

try:
    # This tool makes use of the recommended toolshare folder structure,
    #  a system folder with a Scripts and ToolData subfolder. We can
    #  discover the pathname of this toolshare folder by examining the
    #  first argument to the script, which is the pathname to the script
    #  (example: "E:\examples\symbology\scripts\ExtractData.py".)  We
    #  then use this toolSharePath variable to create pathnames to our 
    #  shapefile data and layer files ("E:\examples\symbology\ToolData\points.lyr").
    #
    scriptPath      = sys.argv[0]
    toolSharePath   = os.path.dirname(os.path.dirname(scriptPath))
    dataPath        = os.path.join(toolSharePath, "ToolData")
    parkPath        = os.path.join(dataPath, "PortlandParks.shp")
    pointLyrPath    = os.path.join(dataPath, "point.lyr")
    polygonLyrPath  = os.path.join(dataPath, "polygon.lyr")
    polylineLyrPath = os.path.join(dataPath, "polyline.lyr")
    
    # Buffer the parks by the specified distance.  The output is a scratch
    #  feature class in the same workspace as the output feature class
    #
    arcpy.SetProgressorLabel("Buffering parks ...")
    scrname = arcpy.CreateScratchName("xxx", "", "featureclass", 
                                      os.path.dirname(arcpy.GetParameterAsText(2)))
    arcpy.Buffer_analysis(parkPath, scrname, arcpy.GetParameterAsText(1))

    # Clip the defined layer with the buffered parks
    #
    arcpy.SetProgressorLabel("Clipping " + arcpy.GetParameterAsText(0) + " ..." )
    output = arcpy.Clip_analysis(arcpy.GetParameterAsText(0), scrname, 
                                 arcpy.GetParameterAsText(2))

    # Delete intermediate dataset
    #
    try:
        arcpy.Delete_management(scrname)
    except:
        pass

    # Set the symbology of the output. 
    #
    params = arcpy.GetParameterInfo()
    desc = arcpy.Describe(output)
    if desc.shapeType == "Polygon":
        params[2].symbology = polygonLyrPath
    elif desc.shapeType == "Polyline":
        params[2].symbology = polylineLyrPath
    else:
        params[2].symbology = pointLyrPath

except:
    arcpy.AddError("An error occurred. " + arcpy.GetMessages(2))
    

7/10/2012