はじめに
この記事ではQGISのプラグイン開発を行うにあたって、
「geopandasの機能が使いたいけど、ユーザーに煩雑なインストール作業を強いたくない!」
という願いを叶えるための記事です。
ユーザーがインストール作業することに抵抗がない場合は、
以下の記事の方がスマートだと思います。
まず結論
先に結論を言いますが、この記事では
pandas&geopandasの機能を使った処理のみをexe化して、プラグインからexeを実行させる
という方法で実現しています。
「exe化はしたくない」という縛りがある場合、この記事では解決しません。
あしからず。
実行環境
- Windows10
- QGIS 3.16
geopandasの処理をexe化する
geopandas処理を含む部分だけを別ファイルにする
exe化をするにあたって、まずはgeopandasの機能を使っている処理を
関数にしておき、別のpyファイルに保存します。
この時、関数に読み込みたい引数はコマンドライン引数で与えるようにしておきます。
正直、文章だけだと意味が分からないと思うので、
サンプルプログラムとして'extract.py'を作ってみました。
「国土数値情報 道の駅データから温泉施設がある道の駅を抽出する」
という機能を'extract_hotspring'という関数として作っています。
(使用例を見せたいだけなので、実用性とか考えなくていいよね)
import sys
import pandas as pd
import geopandas as gpd
def extract_hotspring(args):
# argsの中身は以下の通り
# args = [extract.py, shpファイルのパス]
# shpファイルのパスを取得
shp_file = args[1]
# shpファイルからDataframeを生成
df = gpd.read_file(shp_file, encoding='Shift-JIS')
# 温泉施設がある(P35_018が1になっている)データを抽出
df = df[df['P35_018'] == 1]
# 出力ファイルを指定
export_file = shp_file.replace('.shp', '_onsen.shp')
# Dataframeをファイルに出力
df.to_file(export_file)
return 0
if __name__ == '__main__':
# コマンドライン引数の読み込み
args = sys.argv
# 温泉抽出関数の呼び出し
extract_hotspring(args)
print('end')
上記のファイルでは、'extract_hotspring'にはshpファイルを直接渡さずに
コマンドライン引数'args'を渡すようになっていますね。
作成したpyファイルをexe化する
pyファイルのexe化は色々なやり方があると思いますが、
ここではcx_freezeを使ってexeファイルする方法にします。
(pyinstallerはexeファイル作るのにやたらと時間がかかったので不採用です)
cx_freezeの使い方は以下の記事が分かりやすいので
変に説明せずにリンクを貼っておきますね。
サンプルプログラムで動作確認したい方は、
cx-freezeのインストール後にコマンドプロンプトにて、以下のコマンドを実行してください。
(念のため書きますが、'extract.py'があるフォルダで実行してくださいね)
cxfreeze -c extract.py --target-dir exe_file
無事に動けば以下の様に、指定した名前(今回は'exe_file')のフォルダが作られます。
ちなみに'data'とか'downloads'はzipとかshpファイルを
保存したフォルダなので気にしなくてOKです。
pyqgisでexeファイルを実行する
pyqgisのコード内でexeファイルを指定して、実行させるようにすればOKです。
subprocess.run([exeファイル, 引数])
...が、この際exeファイルはフォルダごとプラグインフォルダに移すことをお勧めします。
理由は以下二点です。
- exeファイルの格納場所は統一しておく必要がある
- ユーザー視点で、スクリプトとexeを別の場所にコピーするのは面倒
これもイメージがつきにくいと思うので、具体例を示しながら補足説明します。
pyqgisでプラグインを作成する場合、以下のフォルダ内に配置すると思います。
(この辺は詳しくないので、自信ありませんが)
C:\Program Files\QGIS 3.16\apps\qgis\python\plugins
'plugins'フォルダの中に自作プラグイン(今回は'plugin_hotspring'としました)を格納します。
この時、自作プラグインのフォルダ内にexeフォルダを入れておきます。
こうしておくと、プラグインの導入と同時にexeファイルのパスも確定するので
'plugin.py'の中でexeファイルが指定しやすくなります。
def main_plugin(argument):
# exeファイルのパスを指定する(パスが固定されるので引数にしなくて済む)
exe_file = r"C:\\Program Files\\QGIS 3.16\\apps\\qgis\\python\\plugins\\plugin_hotspring\\exe_file\\extract.exe"
# exeファイルを実行する
subprocess.run([exe_file, shp_file])
return 0
終わりに
今回はQGISのプラグイン開発で使いたくなるであろうgeopandasに
フォーカスを当てて書いてみました。
試してはいませんが、他のライブラリでも同様の手順で対応できると思うので
QGISのpython環境に入っていないライブラリを使いたい時はお試しください。
まあ個人的には「QGISのpythonならpandas&geopandasはデフォルトで入れておいてよ」
というのが本音ですけどね...