PyQGISメモ

QGISというGISの表示ソフトウェアをPythonで操作するPyQGISについての備忘録です。レイアウトの操作などをPyQGISで行う方法をまとめています。
QGISについて何もわからない場合はこちらが詳しいです。

https://gis-oer.github.io/gitbook/book/index.html

また、PyQGISについてはPyQGIS開発者用Cookbookも分かりやすいです。

PyQGIS 開発者用 Cookbook — QGIS Documentation ドキュメント
QGIS 3.28 documentation: PyQGIS 開発者用 Cookbook

以下はCookbookのソースコードを一部引用しています。

PostGISのDBを読み込む

# PostGIS DB読込設定
uri = QgsDataSourceUri()
# set host name, port, database name, username and password
uri.setConnection("localhost", "5432", "dbname", "johny", "xxx")

読み込んだDBに対してクエリを実行する

sql = "Select ROW_NUMBER() Over() as primary_key_field, (略)"

# set database schema, table name, geometry column and optionally
# subset (WHERE clause)
uri.setDataSource('', f'({sql})', 'geometry', '', 'primary_key_field')

SQL文を実行するときは必ずシーケンスID(あればプライマリーキーなど)を指定しなければなりません。SQL文を実行しない場合は指定しなくても大丈夫です。結合したデータなどでシーケンスIDがなければ、ROW_NUMBERで抽出したデータに連番が振れます。

参考

QgsDataSourceuRI and left outer join
I'm trying to load data from different tables using left out...

レイヤーの追加

SQLを実行して得られたデータからレイヤーを追加します。

layername = "test"
dblayer = QgsVectorLayer(uri.uri(), layername, "postgres")
if not dblayer.isValid():
    QMessageBox.about(None, "Error", "開けません!")
else:
    QgsProject.instance().addMapLayer(dblayer)

参考

QgsDataSourceuRI and left outer join
I'm trying to load data from different tables using left out...

レイヤースタイルの適用

あらかじめ、qmlファイルを準備してある場合、レイヤーにスタイルを適用することができます。DBからレイヤーを大量に生成するような場合に便利です。

dblayer.loadNamedStyle('C:/style.qml')
dblayer.triggerRepaint()

印刷レイアウトの設定

あらかじめQGISのプロジェクトに印刷レイアウトを保存してある場合、印刷図面に適用することができます。複数図面を印刷する場合に便利です。

manager = project.layoutManager()
layout = manager.layoutByName("print")

凡例の修正

印刷に使用する凡例を操作することができます。ベースの地図などを凡例から取り除きたい+複数図面印刷時に凡例は図面ごとに変えたいなどという場合に便利です。
QGISは凡例の自動更新をオフにしてある状態です。

project = QgsProject.instance()

legend = [i for i in layout.items() if isinstance(i, QgsLayoutItemLegend)][0]

legend.setAutoUpdateModel(True) # 連続出力の場合いったんを更新
legend.setAutoUpdateModel(False) # 自動更新をオフ

layer_to_remove = project.mapLayersByName('削除するレイヤー名')[0]
legend.model().rootGroup().removeLayer(layer_to_remove)

legend.adjustBoxSize()

参考

Hide legend entries in PyQGIS
I made a template that allows to quickly export a map. For l...

レイアウトの更新

印刷レイアウトの設定・凡例の修正をした際に変更を反映します。

layout.refresh()

画像の出力

指定パス(img_path)に画像を出力します。

exporter = QgsLayoutExporter(layout)
exporter.exportToImage(img_path, QgsLayoutExporter.ImageExportSettings())

まとめ

日本語だと細かい情報が見つからず、英語ドキュメントに大変助けられました。

タイトルとURLをコピーしました