QGIS(1) pyQGISで画像を出力する
概要
- pyQGISで画像を出力して保存する
参考
- PyQGIS 開発者用 Cookbook 地図のレンダリングと印刷
- PyQGIS: Render (Print/Save) a Layer as an Image
- https://opensourceoptions.com/blog/pyqgis-render-print-save-a-layer-as-an-image/
- 似たような記事。
QPainter
というものを使っている。よくわからない。extent
の指定の仕方が違うので参考になるかも。
- pyQGISでできることのまとめ(自分用)
- https://qiita.com/nishi_bayashi/items/96e6eff8bf4fd578c32d
- 今回の内容とはあまり関係ないけど便利そうなのでメモとして記載しておく
使用するデータなど
- 指定緊急避難場所データ-静岡県
- https://www.geospatial.jp/ckan/dataset/hinanbasho-22
- geojsonを使用(shapeでもよいはず)
- QGISのバージョン: 3.22.14
QGISで表示されている内容の画像化
QGISで上記のデータとOSMを読み込みます。 避難場所データは「洪水」属性で分類して色分けして表示しています。 ここでのスタイルが画像にも反映されます。
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起動しなくてもQGISのPython部分だけ起動して画像の生成もできるのでしょうが・・・それはいろいろと設定が面倒くさそう?