Python スクリプトでのジオプロセシング タスクの作成
お使いのコンピュータで適切に稼働しているほとんどの Python スクリプト ツールは、GIS サーバで適切に発行および実行されます。この場合、スクリプトを修正する必要はありません。ただし、問題が発生した場合、それは、数多くのプロジェクト データを使用したスクリプト、または開発した Python モジュールをインポートするためのインポート ステートメントを使用したスクリプトが原因となっている可能性があります。この場合、以下の説明をご参照ください。
- スクリプトで使用されているプロジェクト データを発見して、タスクを実行するサーバでこれを使用可能にする方法。
- インポートされたモジュールを発見して、タスクを実行するサーバでこれを使用可能にする方法。
- プロジェクト データと Python モジュール パラメータを作成してスクリプトに渡す方法。
- ツールの整合チェック コードの操作方法、およびクライアントとサーバ間のやり取り。
- サードパーティ ライブラリの操作方法。
Python、ArcPy またはスクリプト ツールを使い慣れていない場合は、下記の「Python、ArcPy およびスクリプト ツールの概要」にスキップして便利なトピックの一覧をご参照ください。
スクリプトのプロジェクト データを発見する方法
パッケージまたはサービスのどちらの場合も、結果を共有し、その結果がスクリプト ツールを参照する際は必ず、スクリプトで使用されているプロジェクト データを発見するためにスクリプト ツールがスキャンされます。プロジェクト データが発見されると、一時フォルダに統合され、パッケージ化(パッケージを共有している場合)されるか、サーバにアップロード(サービスを共有している場合)されます。
スクリプトがスキャンされると、Python 変数で使用されるまたは関数への引数として使用されるそれぞれの引用符(一重または二重のいずれか)で囲まれた文字列がテストされ、存在するデータへのパスであるかどうかが確認されます。この場合のデータとは次のものを意味します。
- コンテンツ ウィンドウのレイヤ(ArcMap または ArcGlobe)
- フォルダ
- ファイル
- フィーチャクラス、シェープファイル、ジオデータベース、マップ ドキュメント(*.mxd)、レイヤ ファイル(*.lyr)などのジオデータセット
ここでは、ジオプロセシング ツールへの入力としてまたは他の Python モジュールを参照するパスとして使用されるデータのみを対象とします。出力データも統合されますが、プロジェクト データとは見なされません。
スクリプトに引用符で囲まれた文字列が発見されると、データの存在を確認する以下のようなテストが実行されます。
- 文字列はコンテンツ ウィンドウのレイヤを参照するか?
- 文字列にデータへの絶対パス(「e:\Warehousing\ToolData\SanFrancisco.gdb\streets」など)が含まれているか?
- 文字列はスクリプトの場所からの相対で発見できるデータを参照するか?スクリプトの場所は次のように定義されます。
- スクリプトが格納されているフォルダ。
- スクリプトがツールボックスに埋め込まれている場合、場所はツールボックスが格納されているフォルダになります。
- スクリプトが [Python] ツールボックスにある場合、場所は [Python] ツールボックスが格納されているフォルダになります。
これらのテストは、順次実行されます。テストに適合しデータが存在するとわかると、データは統合されます。ただし、1 つ例外があります。サービスを共有している場合は、サーバのデータ ストアが調べられ、データがデータ ストア内に存在するかどうかが判断されます。データがデータ ストア内に存在する場合、データは統合されません。
フォルダが統合される場合、フォルダ内のファイルとジオデータセットのみがコピーされ、サブフォルダはコピーされません。ファイル ジオデータセット、ラスタ、TIN などの一部のジオデータセットは実際にはフォルダですが、ジオデータセットでもあるため、コピーされます。フォルダにレイヤ ファイル(*.lyr)またはマップ ドキュメント(*.mxd)が含まれる場合、レイヤ ファイルまたはマップ ドキュメントが参照するすべてのデータも統合され、スクリプトの arcpy.mapping ルーチンが、参照されるデータにアクセスできるようになります。
フォルダの統合では、ツールで使用されることのない大きなデータセットやファイルによってフォルダが雑然とするのを避ける必要があります。これは、パッケージ化やサーバにアップロードするデータのサイズを必要以上に増やさないためです。(サーバのデータ ストアにあるフォルダはサーバにアップロードされないため、これらのフォルダには当てはまりません。)
例
以下の例は、このフォルダ構造に基づいています。
相対パスとフォルダ
スクリプトの場所からの相対でデータを発見する以下の方法は一般的なパターンで、特に ArcGIS 10.0 向けに作成されたサービスに適用されます。参照する場合、後に続くスクリプト コードが上記の Scripts フォルダにあります。ToolData フォルダに SanFrancisco.gdb が含まれています。SanFrancisco.gdb の中に、Streets という名前のフィーチャクラスがあります。以下のコード サンプルでは、スクリプトの場所(Scripts フォルダ)からの相対で ToolData フォルダへのパスが作成されます。
import arcpy
import os
import sys
# Get the pathname to this script, then strip off the
# script file name to yield the containing folder
#
scriptPath = sys.path[0]
thisFolder = os.path.dirname(scriptPath)
# Construct paths to ../ToolData/SanFrancisco.gdb/Streets and
# ../ToolData/Warehouse.lyr
#
toolDataPath = os.path.join(thisFolder, "ToolData")
streetFeatures = os.path.join(toolDataPath, "SanFrancisco.gdb", "Streets")
streetLyr = os.path.join(toolDataPath, "Warehouse.lyr")
以下のコードでは、「ToolData」という文字列(os.path.join 関数への引数)がテストされ、存在するデータであるかどうかが確認されます。この場合、スクリプトの場所からの相対位置に ToolData という名前のフォルダがあります。この ToolData フォルダが統合されます。そのすべてのコンテンツ(上記で説明したように、サブフォルダは除く)がパッケージ化またはサーバにアップロードされます(ToolData フォルダがサーバのデータ ストアの一部である場合を除く)。
個々のファイルがコピーされるのではなく、フォルダのコンテンツがコピーされることに注意してください。たとえば、上記のコードで、データセット e:/Warehousing/ToolData/SanFrancisco.gdb/Streets へのパスが作成されるとします。統合処理では、Streets データセットのみを分離してコピーするわけではありません。ToolData フォルダ全体がコピーされます。
ジオデータセットへの絶対パス
以下のコード サンプルに示すように、絶対パスは、e:/ などのドライブ文字から始まるパスです。
import arcpy
import os
streetFeatures = 'e:/Warehousing/ToolData/SanFrancisco.gdb/Streets'
上記のコードでは、Streets データセットとそれが依存する他のすべてのデータ(リレーションシップ クラス、ドメインなど)が統合されます。
ハイブリッドの例
import arcpy
import os
toolDataPath = r'e:\Warehousing\ToolData'
warehouseLyr = os.path.join(toolDataPath, "Warehouse.lyr")
上記のコードでは、ToolData フォルダ全体のコンテンツが統合されます。フォルダのコンテンツ(サブフォルダは除く)が統合されるため、Warehouse.lyr も、Warehouse.lyr が参照するデータとともに統合されます。
スラッシュとバックスラッシュ
Windows の表記規則では、パスの区切り文字としてバックスラッシュ(円記号)(\)を使用します。UNIX システムではスラッシュ(/)を使用します。
ArcGIS ではどちらを使用してもかまいません。スラッシュであっても、バックスラッシュであっても、該当するオペレーティング システムの表記法に変換されます。
スクリプトでのバックスラッシュ
UNIX 関連のプログラミング言語や C 言語(Python など)では、バックスラッシュ(\)はエスケープ文字と見なされます。たとえば、\t はタブを表します。パスにはバックスラッシュが含まれるので、バックスラッシュがエスケープ文字として使用されないようにする必要があります。最も簡単なのは、次のように r ディレクティブを使用して、パスを Python の未処理文字列に変換する方法です。これは、バックスラッシュを無視するよう Python に指示する方法です。
thePath = r"E:\data\telluride\newdata.gdb\slopes"
他の Python モジュールのインポート
スクリプトが、開発した他のスクリプトをインポートする場合があります。たとえば、以下のコードでは、myutils.py という名前の Python モジュールのインポートを示しています。このモジュールは、親スクリプトと同じディレクトリにあり、getFIDName という名前のルーチンを含んでいます。
import arcpy
import myutils
inFeatures = arcpy.GetParameterAsText(0)
inFID = myutils.getFIDName(inFeatures)
import ステートメントが使用されると必ず、以下の順序でスクリプトが特定されます。
- スクリプトと同じフォルダ。スクリプトがツールボックスに埋め込まれている場合、ツールボックスが格納されているフォルダが使用されます。
- システムの PYTHONPATH 変数が参照するフォルダ。
- システムの PATH 変数が参照するフォルダ。
インポートするモジュールを参照する方法として、sys.path.append メソッドの使用もあります。この方法を使用すると、インポートする必要のあるスクリプトを格納するフォルダにパスを設定できます。
import arcpy
import sys
import os
# Append the path to the utility modules to the system path
# for the duration of this script.
#
myPythonModules = r'e:\Warehousing\Scripts'
sys.path.append(myPythonModules)
import myutils # a Python file within myPythonModules
上記のコードでは、sys.path.append メソッドには引数としてフォルダが必要であることに注意してください。'e:\Warehousing\Scripts' はフォルダであるため、フォルダ全体のコンテンツが統合されます。ここでも、フォルダのコンテンツをコピーするためのルールが適用されます。ジオデータセットでないサブフォルダを除く、フォルダ内のすべてがコピーされます。
フォルダ内の Python スクリプトをスキャン対象として、プロジェクト データやインポート済みモジュールが検索されることはありません。
ツールの整合チェック コード
スクリプト ツールの作成経験がある場合は、ユーザ独自のツールの整合チェックのロジックを指定してもかまいません。ジオプロセシング サービスのクライアントは、ツールの整合チェック ロジックを実行する機能がありません。この機能があるのはサーバだけです。クライアントがその実行タスク要求をサービスに送信すると、サーバ上で整合チェック ロジックが実行されます。整合チェック ルーチンによってエラーがスローされると、タスクは実行を停止します。サービスからメッセージを返すと、整合チェック ルーチンによってスローされたメッセージがクライアントに表示されます。
整合チェック ロジックは Python を使用して実装されます。他の Python スクリプトと同様に、整合チェック コードがスキャンされ、プロジェクト データとモジュールがないか確認されます。たとえば、整合チェック ロジックにより、投影情報ファイル(*.prj)を格納するフォルダ(d:\approved_projections など)を開いて、ツールの実行時にクライアントが使用できる空間参照の選択リストを作成します。このフォルダはツールのパラメータではありません。ツールの整合チェック スクリプト内で使用されるプロジェクト データです。上記で説明した Python スクリプトと同じルールがここでも適用されます。その結果、d:\approved_projections フォルダが統合され、サーバにコピーされます(サーバのデータ ストアにある場合は除きます)。
プロジェクト データとモジュールのツール パラメータの作成
上記で説明したように、Python スクリプトは共有時にスキャンされ、コード内の引用符で囲まれた文字列に基づいて、スクリプトが使用するデータが決定されます。この処理を管理する場合、スクリプトが使用するすべてのデータとモジュールのパラメータを作成するという方法を使用できます。以下のスクリプトのサンプルは概念を示しています。すべてのプロジェクト データとモジュールがパラメータになり、スクリプトに渡されます。
import arcpy
import sys
import os
inFeatures = arcpy.GetParameterAsText(0) # Feature Layer
projectDataFolder = arcpy.GetParameterAsText(1) # Folder
myPythonModules = arcpy.GetParameterAsText(2) # Folder
# Append the path to the utility modules to the system path
# for the duration of this script.
#
sys.path.append(myPythonModules)
import myutils # a Python file within myPythonModules
# Construct a variable to hold the Streets feature class found in the
# project data folder
#
streetsFeatures = os.path.join(projectDataFolder, "SanFrancisco.gdb", "Streets")
上記のように、スクリプトがすべてのデータのパラメータを使用すると、次のようなメリットがあります。
- スクリプトに必要なデータがわかる - パラメータであることから、ツールのダイアログ ボックスで確認できます。どのデータを使用するかを決定するためにコードを編集する必要がありません。
- 内部のツール整合チェック ロジックが引き継がれる - パラメータ値が、存在しないデータを参照する場合、ツールのダイアログ ボックスにはエラーが表示され、ツールを実行して結果を作成することはできません。
- データの場所をリセットするには、スクリプトに場所を入力するのではなく(エラーが起こりやすいため)、ツールのダイアログ ボックスを使用して場所を参照できます。
- 結果をサービスとして共有すると、サービス エディタにより、フォルダのパラメータが [定数] の [入力モード] に設定されます。パラメータはクライアントに表示されません。公開時に、2 つのフォルダはサーバにコピーされます(フォルダがデータ ストアに登録されている場合を除きます)。サーバ上でタスクを実行すると、スクリプトは、コピーされたフォルダへのパスを受け取ります。
サードパーティ モジュール
サードパーティ モジュール(コア Python インストールの一部でないモジュール)は統合されません。サーバ上にモジュールが存在していて正しく実行されることを確認する必要があります。これは、ArcGIS Server と共にインストールされる numpy モジュールまたは matplotlib モジュールには適用されません。
サードパーティの Python モジュール(numpy と matplotlib 以外)を Linux にインストールするには、特別な処理が必要です。
Python、ArcPy およびスクリプト ツールの概要
Python、ArcPy およびスクリプト ツールを使い慣れていない方は、下の表に記載した、使用開始にあたって参考になるトピックをご参照ください。
ヘルプ トピック | コンテンツ |
---|---|
独自のプロセシング ツール作成の基本概要 | |
Python および ArcPy の入門トピック。これらのトピックでは、Python および ArcPy サイト パッケージの詳細を説明しています。 | |
Python を使用したカスタム スクリプト ツール作成の入門トピック。 | |
このトピックでは、スクリプト ツール パラメータの定義方法を詳しく説明しているため、スクリプト ツール作成プロセスを学習した後に参照する機会が多くなります。 |