QGIS のプロセシングプラグインを書いてみた

# QGIS のプロセシング

QGIS では非常に様々な機能が「プロセシングツール」から利用することができます。それらは単一の機能であることが多く、複数の処理を組み合わせることで各利用者の目的を達成できるようになっています。また、自然と中間データ（一時的なレイヤ）が大量に生成されますが、モデルビルダを使って処理モデルを定義し、最終成果物のみを出力することもできます。

## プロセシングに機能を追加

プロセシングに、新しい機能を追加することは簡単にできます。
<img alt="プロセシングツール" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215290/abdd4154-a55a-1a1d-5f7c-51ec429fe5d6.png" width="300">

[テンプレート](https://github.com/qgis/QGIS/blob/master/python/plugins/processing/script/ScriptTemplate.py)にあるとおり、 `QgsProcessingAlgorithm` を継承したクラスを作成し、 `tr` 、 `createInstance` や `name` などのメソッドを定義します。このへんは約束事のような感じです、

```python
class ExampleProcessingAlgorithm(QgsProcessingAlgorithm):
    def tr(self, string):
        return QCoreApplication.translate('Processing', string)

    def createInstance(self):
        return ExampleProcessingAlgorithm()

    def name(self):
        # このアルゴリズムの ID
        return 'myscript'

    def displayName(self):
        # このアルゴリズムの表示名
        return self.tr('My Script')
```


`initAlgorithm` 内で使用するパラメータを `addParameter` すると、自動的に UI が設定されます。

```python
    # 入力レイヤ用のパラメータの識別子
    INPUT = 'INPUT'

    def initAlgorithm(self, config=None):

        # FeatureSource （入力ベクタレイヤ）を登録
        # addParameter （登録）するだけで、自動的にウィジェットが配置される
        self.addParameter(
            QgsProcessingParameterFeatureSource(
                self.INPUT,
                self.tr('Input layer'),
                [QgsProcessing.TypeVectorAnyGeometry]
            )
        )
```

`processAlgorithm` に実行時の処理を記載します。

```python
    def processAlgorithm(self, parameters, context, feedback):

        # parameterAs＊＊＊ でパラメータを参照することができる
        #
        # この例では QgsProcessingParameterFeatureSource のパラメータなので
        # parameterAsSource を使って取得する。
        # QgsProcessingFeatureSource クラスのオブジェクトが得られる。
        # レイヤクラスではないが QgsVectorLayer クラスと同じように地物等を参照できる。
        source = self.parameterAsSource(
            parameters, self.INPUT, context
        )

        # やりたい処理をかく

        # （モデルビルダ等で流用可能な）結果。出力レイヤとは別の概念
        return {}
```

既存のプロセシングツールや QGIS 式じゃ少し難しくて Python を使いたいけれども、プラグインを作るほどじゃない場合などにちょうどよい実行環境となります。

Plugin Builder プラグインよりも更にトライアンドエラーがしやすく、またプロセシング用のウィジェットが使えしかも自動でいい感じの見た目を作ってくれます。

## 使えるパラメータ（ウィジェット）

使えるパラメータを `initAlgorithm` を列挙し、ウィジェットの確認ができるスクリプトを書きました。

* https://gist.github.com/tohka/604008af548d88a78ec235bf22cc51be

<img alt="使えるパラメータ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215290/ca00b1d1-0d40-14e2-9df2-ffd3a0363894.png" width="600">

プロセシングツールの「ツールボックスにスクリプトを追加...」から登録することができます。気軽でいいですね。

ただし手元の QGIS が QGIS 3.8 だったので、最近追加されたパラメータには対応できていません。また正確に言えば UI は変更することができます。上記スクリプトでは `QgsProcessingParameterEnum` に対しコンボボックス（デフォルト）とラジオボタン（コード内ではなぜか `CheckBoxes` ）の例を記載していますし、別途定義したやつを使うことも可能です。

## プラグイン

プロセシング対応のプラグインを作ることもできます。

[ドキュメント](https://docs.qgis.org/3.10/en/docs/pyqgis_developer_cookbook/processing.html)にあるとおり、 `metadata.txt` に `hasProcessingProvider=yes` が必須になります。

習作として、測地線を書くプラグインを作ってみました。

* https://github.com/tohka/geodesic_plugin

<img alt="測地線" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215290/44f26acc-57f5-9287-3ec3-e7223f7d3852.png" width="600">

Plugin Builder のテンプレートを使っていない、割と最小限のプロセシングプラグインになっているかと思います。リポジトリには登録していないので、 zip ファイルからインストールしてください。（よくわかってないですが zip を展開してインストールする際のファイル名も重要なので github の Download ZIP や Releases からのダウンロードだと unload のときなどにエラーが発生する可能性があります。）

処理内容自体はちゃんとしてるので、機能追加（マルチポイントレイヤから生成等）し、ゆくゆくはちゃんとリポジトリ登録したいとは考えています。

## 参考等

QGIS のプロセシングの各処理のソースコードは参考になります。

* https://github.com/qgis/QGIS/tree/master/python/plugins/processing/algs/qgis