23.7. プロセシングアルゴリズムをコンソールから使う
コンソールを使うことによって、上級ユーザは生産性を向上させるとともに、プロセシングフレームワークの他のどのGUI要素を使っても実現できない、複雑な操作ができるようになります。複数のアルゴリズムを必要とするモデルを、コマンドラインインターフェイスを使って定義することができます。さらにループや条件分岐などの処理を加えることによって、より柔軟で強力なワークフローを作りあげることができます。
QGISにプロセシング専用コンソールはありませんが、プロセシングのコマンドのすべてがQGISの内臓 Pythonコンソール で実行可能です。つまりそれらのコマンドをコンソールでの作業に組み込み、コンソールで可能なその他すべての機能(QGIS API からのメソッドもそこに含まれます)と、プロセシングアルゴリズムをつなぐことができるということです。
Pythonコンソールで実行することのできるコードは、たとえそれが特定のプロセシングメソッドを呼び出していないとしても、その他のすべてのアルゴリズムと同様に、後からツールボックスやグラフィカルモデラーやその他のあらゆるコンポーネントから呼び出すことのできる新しいアルゴリズムに変換することができます。実際にツールボックスにあるアルゴリズムのいくつかは、簡単なスクリプトです。
このセクションでは、QGIS Pythonコンソールからプロセシングアルゴリズムを使用する方法と、Pythonを使ってアルゴリズムを書く方法を見ていきます。
23.7.1. Python コンソールからアルゴリズムを呼び出す
最初にやるべきことは、次のコードでプロセシングの機能をインポートすることです。
>>> from qgis import processing
Now, there is basically just one (interesting) thing you can do with
that from the console: execute an algorithm. That is done using the
run()
method, which
takes the name of the algorithm to execute
as its first parameter, and then a variable number of additional
parameters depending on the requirements of the algorithm. So the
first thing you need to know is the name of the algorithm to
execute. That is not the name you see in the toolbox, but rather a
unique command–line name. To find the right name for your algorithm,
you can use the processingRegistry
.
Type the following line in your console:
>>> for alg in QgsApplication.processingRegistry().algorithms():
print(alg.id(), "->", alg.displayName())
次のようなものが表示されるはずです(見やすくなるようにダッシュを余計に追加しています)。
3d:tessellate --------------> Tessellate
gdal:aspect ----------------> Aspect
gdal:assignprojection ------> Assign projection
gdal:buffervectors ---------> Buffer vectors
gdal:buildvirtualraster ----> Build Virtual Raster
gdal:cliprasterbyextent ----> Clip raster by extent
gdal:cliprasterbymasklayer -> Clip raster by mask layer
gdal:clipvectorbyextent ----> Clip vector by extent
gdal:clipvectorbypolygon ---> Clip vector by mask layer
gdal:colorrelief -----------> Color relief
gdal:contour ---------------> Contour
gdal:convertformat ---------> Convert format
gdal:dissolve --------------> Dissolve
...
これはすべての利用可能なアルゴリズムのIDと対応する名前のリストです。プロバイダ名とアルゴリズム名でソートされています。
アルゴリズムのコマンドラインでの名前が分かったら、次にすべきことはアルゴリズムを実行するための正しいシンタックスを確認することです。これは run()
メソッドを呼ぶ際に必要なパラメータを確認するということです。
アルゴリズムを詳細に説明してくれるメソッドがあって、アルゴリズムが必要とするパラメータのリストと、生成される結果を記述してくれます。algorithmHelp(id_of_the_algorithm)
メソッドを使うとこの情報を得ることができます。アルゴリズムの説明用の名前ではなく、IDを使ってください。
例えば native:buffer
をパラメータとしてこのメソッドを呼び出すと(qgis:buffer
は native:buffer
のエイリアスなので同様に使えます)、以下のような説明が表示されます。
>>> processing.algorithmHelp("native:buffer")
Buffer (native:buffer)
This algorithm computes a buffer area for all the features in an
input layer, using a fixed or dynamic distance.
The segments parameter controls the number of line segments to
use to approximate a quarter circle when creating rounded
offsets.
The end cap style parameter controls how line endings are handled
in the buffer.
The join style parameter specifies whether round, miter or
beveled joins should be used when offsetting corners in a line.
The miter limit parameter is only applicable for miter join
styles, and controls the maximum distance from the offset curve
to use when creating a mitered join.
----------------
Input parameters
----------------
INPUT: Input layer
Parameter type: QgsProcessingParameterFeatureSource
Accepted data types:
- str: layer ID
- str: layer name
- str: layer source
- QgsProcessingFeatureSourceDefinition
- QgsProperty
- QgsVectorLayer
DISTANCE: Distance
Parameter type: QgsProcessingParameterDistance
Accepted data types:
- int
- float
- QgsProperty
SEGMENTS: Segments
Parameter type: QgsProcessingParameterNumber
Accepted data types:
- int
- float
- QgsProperty
END_CAP_STYLE: End cap style
Parameter type: QgsProcessingParameterEnum
Available values:
- 0: Round
- 1: Flat
- 2: Square
Accepted data types:
- int
- str: as string representation of int, e.g. '1'
- QgsProperty
JOIN_STYLE: Join style
Parameter type: QgsProcessingParameterEnum
Available values:
- 0: Round
- 1: Miter
- 2: Bevel
Accepted data types:
- int
- str: as string representation of int, e.g. '1'
- QgsProperty
MITER_LIMIT: Miter limit
Parameter type: QgsProcessingParameterNumber
Accepted data types:
- int
- float
- QgsProperty
DISSOLVE: Dissolve result
Parameter type: QgsProcessingParameterBoolean
Accepted data types:
- bool
- int
- str
- QgsProperty
OUTPUT: Buffered
Parameter type: QgsProcessingParameterFeatureSink
Accepted data types:
- str: destination vector file, e.g. 'd:/test.shp'
- str: 'memory:' to store result in temporary memory layer
- str: using vector provider ID prefix and destination URI,
e.g. 'postgres:...' to store result in PostGIS table
- QgsProcessingOutputLayerDefinition
- QgsProperty
----------------
Outputs
----------------
OUTPUT: <QgsProcessingOutputVectorLayer>
Buffered
これでアルゴリズムの実行に必要なことはすべて分かりました。すでに触れたように、アルゴリズムは run()
を使って実行することができます。シンタックスは以下のようになります。
>>> processing.run(name_of_the_algorithm, parameters)
パラメータの箇所には実行したいアルゴリズムに応じたパラメータの辞書がきます。algorithmHelp()
メソッドでリストアップされていたものをここで使います。
1 >>> processing.run("native:buffer", {'INPUT': '/data/lines.shp',
2 'DISTANCE': 100.0,
3 'SEGMENTS': 10,
4 'DISSOLVE': True,
5 'END_CAP_STYLE': 0,
6 'JOIN_STYLE': 0,
7 'MITER_LIMIT': 10,
8 'OUTPUT': '/data/buffers.shp'})
パラメータが任意のもので、それを使いたくない時は、そのパラメータを辞書に含めないでください。
パラメータが指定されなかった時はデフォルト値が使われます。
パラメータの種別により値を指定する方法は様々です。次に入力パラメータの種別ごとにその値を指定する方法を簡単に見ていきましょう。
ラスタレイヤ、ベクタレイヤ、テーブル。これらは単純に、使いたいデータオブジェクトの識別名(QGIS TOCが保持している名前)か、もしくはファイル名を文字列で指定してください。ファイル名を指定した場合、対応するレイヤがまだ読み込まれていない場合はファイルを開いて読み込みますが、マップキャンバスには追加されません。レイヤのQGISオブジェクトインスタンスをすでに取得している場合は、これをパラメータとして渡すこともできます。
Enumeration. If an algorithm has an enumeration parameter, the value of that parameter should be entered using an integer value. To know the available options, you can use the
algorithmHelp()
command, as above. For instance, thenative:buffer
algorithm has an enumeration called JOIN_STYLE:JOIN_STYLE: Join style Parameter type: QgsProcessingParameterEnum Available values: - 0: Round - 1: Miter - 2: Bevel Accepted data types: - int - str: as string representation of int, e.g. '1' - QgsProperty
この例では、パラメータは3つの選択肢を持ちます。値は0始まりであることに注意してください。
真偽値。
True
かFalse
を使用してください。複数の入力。値は入力を記述したものをセミコロン (
;
) で区切った文字列です。各入力が単一レイヤやテーブルの場合はデータオブジェクト名やファイルパスが使えます。XXX のテーブル項目名。利用する項目名の文字列を使ってください。このパラメータは大文字小文字を区別します。
固定テーブル。テーブルのすべての値のリストを、各値をカンマ (
,
) で区切った上で、全体を引用符 ("
) で囲んで入力します。値は最上位列から始まり、左から右に進みます。テーブルを表す2次元の配列も使えます。CRS。使いたいCRSのEPSGコード番号を入力します。
範囲。
xmin
,xmax
,ymin
およびymax
の値を、カンマ (,
) で区切って、文字列で指定しなければなりません。
真偽値、ファイル、文字列および数値パラメータには特に付け加える説明はありません。
文字列、真偽値、数値などの入力パラメータはデフォルト値を持ちます。デフォルト値は対応するパラメータの入力が欠けていた時に使われます。
出力データオブジェクトには、ツールボックスから実行される時と同様に、それを保存するために使うファイルパスを入力してください。出力オブジェクトが指定されない時は、結果は一時ファイルに保存されます(もしくは出力が任意の時はスキップされます)。ファイルの拡張子はファイルフォーマットから決定されます。アルゴリズムでサポートされていないファイル拡張子を入力した場合は、その出力タイプのデフォルトファイルフォーマットが使われ、それに対応する拡張子が与えられたファイルパスに付加されます。
Unlike when an algorithm is executed from the toolbox, outputs are not
added to the map canvas if you execute that same algorithm from the
Python console using run()
,
but runAndLoadResults()
will do that.
The run()
method returns
a dictionary with one or more output names (the
ones shown in the algorithm description) as keys and the file paths of
those outputs as values:
1 >>> myresult = processing.run("native:buffer", {'INPUT': '/data/lines.shp',
2 'DISTANCE': 100.0,
3 'SEGMENTS': 10,
4 'DISSOLVE': True,
5 'END_CAP_STYLE': 0,
6 'JOIN_STYLE': 0,
7 'MITER_LIMIT': 10,
8 'OUTPUT': '/data/buffers.shp'})
9 >>> myresult['OUTPUT']
10 /data/buffers.shp
You can load feature output by passing the corresponding file paths to
the load()
method.
Or you could use runAndLoadResults()
instead of
run()
to load
them immediately.
If you want to open an algorithm dialog from the console you can use the
createAlgorithmDialog
method. The only mandatory parameter is the algorithm
name, but you can also define the dictionary of parameters so that the dialog
will be filled automatically:
1 >>> my_dialog = processing.createAlgorithmDialog("native:buffer", {
2 'INPUT': '/data/lines.shp',
3 'DISTANCE': 100.0,
4 'SEGMENTS': 10,
5 'DISSOLVE': True,
6 'END_CAP_STYLE': 0,
7 'JOIN_STYLE': 0,
8 'MITER_LIMIT': 10,
9 'OUTPUT': '/data/buffers.shp'})
10 >>> my_dialog.show()
The execAlgorithmDialog
method opens the dialog immediately:
1 >>> processing.execAlgorithmDialog("native:buffer", {
2 'INPUT': '/data/lines.shp',
3 'DISTANCE': 100.0,
4 'SEGMENTS': 10,
5 'DISSOLVE': True,
6 'END_CAP_STYLE': 0,
7 'JOIN_STYLE': 0,
8 'MITER_LIMIT': 10,
9 'OUTPUT': '/data/buffers.shp'})
23.7.2. スクリプトを作成してツールボックスから実行する
Pythonコードを書くことによって自分独自のアルゴリズムを書くことができます。プロセッシングスクリプトは QgsProcessingAlgorithm
クラスを拡張します。そのため必要な機能を実装するためにはそこにさらにコードを追加する必要があります。プロセッシングツールボックス最上部の:guilabel:スクリプト ドロップダウンメニューから 新しいスクリプトを作成... (白紙)と テンプレートから新しいスクリプトを作成... (必須の関数 QgsProcessingAlgorithm
のコードを含むテンプレート)を選ぶことができます。するとコードを入力するためのプロセッシングスクリプトエディタが開きます。ここでスクリプトを保存すると scripts
フォルダ(スクリプトを保存ダイアログを開いたときのデフォルトフォルダ)に .py
拡張子でアルゴリズムとして保存されます。
アルゴリズムの名前(ツールボックスに表示されるもの)はコードの中で定義されます。
プロセッシングアルゴリズムを定義する次のコード例を見てみましょう。このアルゴリズムは、最初のレイヤ平滑化の後に、ユーザによって指定されたベクタレイヤに対する、ユーザ定義のバッファ距離によるバッファ操作を行うアルゴリズムとして機能するものです。
1from qgis.core import (QgsProcessingAlgorithm,
2 QgsProcessingParameterNumber,
3 QgsProcessingParameterFeatureSource,
4 QgsProcessingParameterFeatureSink)
5
6from qgis import processing
7
8class algTest(QgsProcessingAlgorithm):
9 INPUT_BUFFERDIST = 'BUFFERDIST'
10 OUTPUT_BUFFER = 'OUTPUT_BUFFER'
11 INPUT_VECTOR = 'INPUT_VECTOR'
12
13 def __init__(self):
14 super().__init__()
15
16 def name(self):
17 return "algTest"
18
19 def displayName(self):
20 return "algTest script"
21
22 def createInstance(self):
23 return type(self)()
24
25 def initAlgorithm(self, config=None):
26 self.addParameter(QgsProcessingParameterFeatureSource(
27 self.INPUT_VECTOR, "Input vector"))
28 self.addParameter(QgsProcessingParameterNumber(
29 self.INPUT_BUFFERDIST, "Buffer distance",
30 QgsProcessingParameterNumber.Double,
31 100.0))
32 self.addParameter(QgsProcessingParameterFeatureSink(
33 self.OUTPUT_BUFFER, "Output buffer"))
34
35 def processAlgorithm(self, parameters, context, feedback):
36 #DO SOMETHING
37 algresult = processing.run("native:smoothgeometry",
38 {'INPUT': parameters[self.INPUT_VECTOR],
39 'ITERATIONS':2,
40 'OFFSET':0.25,
41 'MAX_ANGLE':180,
42 'OUTPUT': 'memory:'},
43 context=context, feedback=feedback, is_child_algorithm=True)
44 smoothed = algresult['OUTPUT']
45 algresult = processing.run('native:buffer',
46 {'INPUT': smoothed,
47 'DISTANCE': parameters[self.INPUT_BUFFERDIST],
48 'SEGMENTS': 5,
49 'END_CAP_STYLE': 0,
50 'JOIN_STYLE': 0,
51 'MITER_LIMIT': 10,
52 'DISSOLVE': True,
53 'OUTPUT': parameters[self.OUTPUT_BUFFER]},
54 context=context, feedback=feedback, is_child_algorithm=True)
55 buffered = algresult['OUTPUT']
56 return {self.OUTPUT_BUFFER: buffered}
必要なインポートを行った後に、続いて QgsProcessingAlgorithm
の諸関数が定義されます。
name()
: The id of the algorithm (lowercase).displayName()
: A human readable name for the algorithm.createInstance()
: Create a new instance of the algorithm class.initAlgorithm()
: Configure the parameterDefinitions and outputDefinitions.ここでアルゴリズムのパラメータと出力を記述します。この例では、入力のためには feature source を、出力結果のためには feature sink とバッファ距離用の数値を定義しています。
processAlgorithm()
: Do the work.Here we first run the
smoothgeometry
algorithm to smooth the geometry, and then we run thebuffer
algorithm on the smoothed output. To be able to run algorithms from within another algorithm we have to set theis_child_algorithm
argument toTrue
. You can see how input and output parameters are used as parameters to thesmoothgeometry
andbuffer
algorithms.
入力と出力のために多くの種類のパラメータが使用可能です。以下はアルファベット順にソートされたリストです。
コンストラクタの最初のパラメータはパラメータ名です。2番目はユーザインターフェイス用のパラメータの説明です。それ以外のパラメータは、パラメータの種別に依存します。
入力は QgsProcessingAlgorithm
クラスの parameterAs
関数によってQGISクラスに変換されます。例えばバッファ距離のために数値を double で取得するには次のようにします。
self.parameterAsDouble(parameters, self.INPUT_BUFFERDIST, context)).
processAlgorithm
関数は、アルゴリズムで定義されたすべての出力値を含む辞書を返さなければなりません。これによって、同一モデル内の別のアルゴリズムを含む他のアルゴリズムから、これらの出力にアクセスすることが可能になります。
行儀のよいアルゴリズムは、意味のある限りより多くの出力を定義し返さなければなりません。取り立てて特色のない数値や文字列などの出力は、アルゴリズムをより大きなモデルの一部として実行する時に役立ちます。これらの値は、モデル中で続くアルゴリズムの入力パラメータとして使うことができるからです。処理された地物の数や、処理中に見つかった不正な地物の数、出力される地物の数のような数値を、出力に加えることを検討してください。より多くの出力を返せば返すほど、そのアルゴリズムはより役立つものになります。
23.7.2.1. フィードバック
The feedback
object passed to
processAlgorithm()
should be used for user feedback / interaction.
You can use the setProgress()
function of the feedback
object to update
the progress bar (0 to 100) to inform the user about the progress of the
algorithm. This is very useful if your algorithm takes a long time to complete.
The feedback
object provides an
isCanceled()
method that
should be monitored to enable cancelation of the algorithm by the user.
The pushInfo()
method of
feedback
can be used to send information
to the user, and reportError()
is handy for pushing non-fatal errors to users.
Algorithms should avoid using other forms of providing feedback to
users, such as print statements or logging to
QgsMessageLog
, and
should always use the feedback object instead. This allows verbose
logging for the algorithm, and is also thread-safe (which is
important, given that algorithms are typically run in a background
thread).
23.7.2.2. エラーハンドリング
If your algorithm encounters an error which prevents it from
executing, such as invalid input values or some other condition from
which it cannot or should not recover, then you should raise a
QgsProcessingException
.
E.g.:
if feature['value'] < 20:
raise QgsProcessingException('Invalid input value {}, must be >= 20'.format(feature['value']))
Try to avoid raising
QgsProcessingException
for
non-fatal errors
(e.g. when a feature has a null geometry), and instead just report
these errors via feedback.reportError()
and skip the feature. This
helps make your algorithm "model-friendly", as it avoids halting the
execution of an entire algorithm when a non-fatal error is
encountered.
23.7.2.3. スクリプトのドキュメントを作成する
As in the case of models, you can create additional documentation for your scripts, to explain what they do and how to use them.
QgsProcessingAlgorithm
provides the helpString()
,
shortHelpString()
and
helpUrl()
functions for that purpose.
Specify / override these to provide more help to the user.
shortDescription()
is used in the tooltip when hovering over the algorithm in the toolbox.
23.7.3. 実行前後のスクリプトのフック
Scripts can also be used as pre- and post-execution hooks that are run before and after an algorithm is run, respectively. This can be used to automate tasks that should be performed whenever an algorithm is executed.
文法は上述のものと同様ですが、 alg
という名前のグローバル変数を追加で使用でき、これはたった今(あるいはまさにこれから)実行されるアルゴリズムを表します。
In the General group of the processing options dialog, you will find two entries named Pre-execution script and Post-execution script where the filenames of the scripts to be run in each case can be entered.