anorithのブログ

主にGIS系の記事を書く。

QGIS(1) pyQGISで画像を出力する

概要

  • pyQGISで画像を出力して保存する

参考

使用するデータなど

QGISで表示されている内容の画像化

QGISで上記のデータとOSMを読み込みます。 避難場所データは「洪水」属性で分類して色分けして表示しています。 ここでのスタイルが画像にも反映されます。

pythonコンソールを開き以下のスクリプトを入力します。

pythonスクリプト

# QGISのプロジェクトファイルがあるディレクトリに画像を保存
image_location = os.path.join(QgsProject.instance().homePath(), "render.png")

# 静岡県の指定緊急避難場所データのレイヤー
vlayer1 = QgsProject.instance().mapLayersByName("22")[0]
# OpenStreetMapのレイヤー
vlayer2 = QgsProject.instance().mapLayersByName("OpenStreetMap")[0]

options = QgsMapSettings()
options.setLayers([vlayer1, vlayer2]) # 後ろのレイヤが下にくる
options.setBackgroundColor(QColor(255, 255, 255)) # 背景色設定(今回はOSM読み込むので意味なしだが・・・)
options.setOutputSize(QSize(800, 600)) # 画像の出力サイズ
options.setExtent(vlayer1.extent()) # これで静岡県のデータがある周辺に設定される
options.setDestinationCrs(vlayer1.crs()) # CRSを設定。

# レンダリング用ジョブのオブジェクトを作成
render = QgsMapRendererParallelJob(options) 

# レンダリングが終わったら画像を保存するようにする
def finished():
    img = render.renderedImage()
    img.save(image_location, "png")
    print("saved")

render.finished.connect(finished)

render.start()

↓こんな感じですね。

終わるとimage_locationで定めた場所に以下のような画像が保存されます。

注意点としては、レンダリングPythonスクリプトとは別で処理が走る点ですね。 処理が別で走っているのでstart()終了後にすぐ保存しようとしてもまだレンダリングが終わっていなくておかしなことになります。 そのため終了後の動作(ここでは画像の保存)をfinish()関数とrender.finished.connect(finished)で定義しておいてレンダリングが終わった後に保存するようにしている、ということみたいですね。

今回はすでにプロジェクトに読み込んでスタイルも設定してあるレイヤーを画像化しました。 pyQGISはレイヤー読み込みもスタイル適用もスクリプトでできるので、そこも含めたスクリプトも書けそうです。もっと言えばQGIS起動しなくてもQGISPython部分だけ起動して画像の生成もできるのでしょうが・・・それはいろいろと設定が面倒くさそう?