GUIDE 02

QGIS開発ガイド

Python連携とプラグイン開発

QGISをより深く活用したい方向けに、Pythonとの連携方法やプラグイン開発について解説します。
業務効率化や自動化を実現するためのノウハウを網羅的にまとめました。

約20分で読めます QGIS / Python

QGIS開発ガイド:Python連携からプラグイン開発まで

QGISは、無償で使える本格的なGISソフトです。

Pythonと連携することで、業務に合わせた自動化やカスタマイズが可能になります。

このガイドでは、QGISの基本操作からPyQGIS、プラグイン開発まで、実践的な開発手法を解説します。

1. QGISとは

1.1 オープンソースGISの強み

QGIS(Quantum GIS)は、オープンソースの地理情報システムです。

主な特徴

  • 完全無償(商用利用も可)
  • Windows、macOS、Linux対応
  • 200以上のデータ形式に対応
  • Python連携で高度なカスタマイズ
  • 活発なコミュニティ

1.2 ArcGISとの比較

項目 QGIS ArcGIS
費用 無償 有償(年間ライセンス)
サポート コミュニティ 公式サポート
機能 必要十分 豊富・統合的
カスタマイズ PyQGIS(Python) ArcPy(Python)
プラグイン 1000以上 公式ツールボックス
学習資料 増加中 豊富

QGISを選ぶ理由

  • コストを抑えたい
  • オープンソースの柔軟性が欲しい
  • 自社でカスタマイズしたい
  • 特定ベンダーに依存したくない

1.3 商用利用について

QGISはGNU GPL(General Public License)で提供されています。

できること

  • 商用業務での利用
  • 社内ツールとしての利用
  • クライアントへの納品物作成
  • QGISを使ったサービス提供

注意点

  • QGISを改変して配布する場合はソースコード公開が必要
  • 通常の業務利用では特に制約なし

2. QGIS基本操作

2.1 インストールと初期設定

インストール手順(Windows)

  1. QGIS公式サイトにアクセス
  2. 「ダウンロード」から最新版を選択
  3. 「スタンドアロンインストーラ」を推奨
  4. インストーラを実行

推奨初期設定

設定
設定 → オプション → 一般
├── ロケールを上書き: 日本語
└── プロジェクト保存時にレイヤ情報を相対パスで保存

設定 → オプション → CRS
└── デフォルトCRS: EPSG:6668(JGD2011)または EPSG:4326(WGS84)

2.2 データの読み込み・表示

対応データ形式(主要なもの)

形式 拡張子 説明
シェープファイル .shp 最も普及している形式
GeoPackage .gpkg 新しい標準、単一ファイル
GeoJSON .geojson Web向け、テキスト形式
CSV .csv 座標列があれば点データとして
ラスター .tif, .jpg, .png 画像データ

読み込み方法

  • レイヤ → レイヤを追加 → ベクタレイヤを追加
  • またはファイルをドラッグ&ドロップ

地理院タイルの追加

設定
XYZ Tiles → 新規接続
URL: https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png

2.3 基本的な分析機能

よく使う機能

機能 メニュー 用途
バッファ ベクタ → 空間演算ツール 一定距離内の範囲を作成
クリップ ベクタ → 空間演算ツール 範囲で切り抜き
属性結合 プロパティ → 結合 属性テーブルの結合
空間結合 ベクタ → データ管理ツール 空間的に結合
フィールド計算機 属性テーブル 属性値の計算・編集


3. Python×QGIS(PyQGIS)

3.1 PyQGIS入門

PyQGISは、PythonからQGISの機能を利用するためのAPIです。

できること

  • 処理の自動化
  • バッチ処理(複数ファイルの一括処理)
  • カスタムツールの作成
  • プラグイン開発

Pythonコンソールの起動

メニュー
プラグイン → Pythonコンソール

基本的なコード例

Python
# 現在のプロジェクトを取得
project = QgsProject.instance()

# すべてのレイヤを取得
layers = project.mapLayers()

# レイヤ名を表示
for layer_id, layer in layers.items():
    print(layer.name())

3.2 処理の自動化

シェープファイルの読み込み

Python
# ベクタレイヤを読み込み
layer = QgsVectorLayer("path/to/file.shp", "layer_name", "ogr")

# レイヤが有効か確認
if layer.isValid():
    QgsProject.instance().addMapLayer(layer)
    print("レイヤを追加しました")
else:
    print("レイヤの読み込みに失敗しました")

属性データの取得

Python
layer = iface.activeLayer()

# すべてのフィーチャをループ
for feature in layer.getFeatures():
    # 属性値を取得
    attrs = feature.attributes()
    # ジオメトリを取得
    geom = feature.geometry()
    print(f"ID: {feature.id()}, 属性: {attrs}")

バッファ処理の実行

Python
import processing

# 入力レイヤ
input_layer = iface.activeLayer()

# バッファ処理を実行
result = processing.run("native:buffer", {
    'INPUT': input_layer,
    'DISTANCE': 100,  # バッファ距離(メートル)
    'OUTPUT': 'memory:'  # メモリ上に出力
})

# 結果をプロジェクトに追加
QgsProject.instance().addMapLayer(result['OUTPUT'])

3.3 バッチ処理の実装

複数ファイルの一括処理例

Python
import os
import processing

# 入力フォルダ
input_folder = "C:/data/input"
# 出力フォルダ
output_folder = "C:/data/output"

# フォルダ内のシェープファイルを処理
for filename in os.listdir(input_folder):
    if filename.endswith(".shp"):
        input_path = os.path.join(input_folder, filename)
        output_path = os.path.join(output_folder, f"buffered_{filename}")

        # バッファ処理
        processing.run("native:buffer", {
            'INPUT': input_path,
            'DISTANCE': 50,
            'OUTPUT': output_path
        })

        print(f"処理完了: {filename}")

print("すべての処理が完了しました")

4. プラグイン開発

4.1 プラグインの仕組み

QGISプラグインは、Pythonで書かれた拡張機能です。

プラグインの構成

ディレクトリ構成
my_plugin/
├── __init__.py          # プラグイン初期化
├── my_plugin.py         # メイン処理
├── my_plugin_dialog.py  # ダイアログ処理
├── my_plugin_dialog_base.ui  # UI定義(Qt Designer)
├── metadata.txt         # プラグイン情報
├── icon.png             # アイコン
└── resources.qrc        # リソースファイル

4.2 開発環境構築

必要なツール

  • QGIS(開発対象バージョン)
  • テキストエディタ(VS Code推奨)
  • Qt Designer(UI作成用、QGISに同梱)
  • Plugin Builder(プラグイン雛形生成)

Plugin Builderのインストール

手順
プラグイン → プラグインの管理とインストール
→ "Plugin Builder" を検索してインストール

4.3 基本的なプラグイン作成

Plugin Builderで雛形作成

  1. プラグイン → Plugin Builder → Plugin Builder
  2. 必要情報を入力
  3. 出力先フォルダを指定
  4. 生成

生成後の作業

  1. 生成されたフォルダをQGISプラグインフォルダにコピー
    • Windows: C:\Users\{user}\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins
  2. QGISを再起動
  3. プラグインを有効化

簡単なプラグインコード例(my_plugin.py)

Python
from qgis.PyQt.QtWidgets import QAction, QMessageBox
from qgis.core import QgsProject

class MyPlugin:
    def __init__(self, iface):
        self.iface = iface

    def initGui(self):
        # メニューにアクションを追加
        self.action = QAction("マイプラグイン", self.iface.mainWindow())
        self.action.triggered.connect(self.run)
        self.iface.addToolBarIcon(self.action)

    def unload(self):
        # プラグイン削除時の処理
        self.iface.removeToolBarIcon(self.action)

    def run(self):
        # メイン処理
        layer = self.iface.activeLayer()
        if layer:
            feature_count = layer.featureCount()
            QMessageBox.information(
                None,
                "結果",
                f"レイヤ '{layer.name()}' のフィーチャ数: {feature_count}"
            )
        else:
            QMessageBox.warning(None, "警告", "レイヤが選択されていません")

4.4 配布・公開方法

社内配布

  1. プラグインフォルダをZIP化
  2. 配布先でプラグインフォルダに展開
  3. QGISで有効化

公式リポジトリへの公開

  1. QGIS Plugin Repositoryでアカウント作成
  2. プラグインをZIP化してアップロード
  3. 審査後、公開


5. 実践テクニック

5.1 大量データの処理

パフォーマンス改善のコツ

Python(悪い例 vs 良い例)
# 悪い例:毎回レイヤを再描画
for feature in layer.getFeatures():
    # 処理
    layer.triggerRepaint()  # 毎回再描画(遅い)

# 良い例:処理後にまとめて再描画
layer.startEditing()
for feature in layer.getFeatures():
    # 処理
layer.commitChanges()
layer.triggerRepaint()  # 最後に1回だけ再描画

空間インデックスの活用

Python
# 空間インデックスを作成
spatial_index = QgsSpatialIndex(layer.getFeatures())

# 特定の範囲内のフィーチャを高速検索
rect = QgsRectangle(139.7, 35.6, 139.8, 35.7)
candidate_ids = spatial_index.intersects(rect)

5.2 他ツールとの連携

Excelとの連携

Python
import pandas as pd

# Excelを読み込み
df = pd.read_excel("data.xlsx")

# DataFrameからQGISレイヤを作成
layer = QgsVectorLayer("Point?crs=EPSG:4326", "excel_data", "memory")
provider = layer.dataProvider()

# フィールドを追加
fields = [QgsField(col, QVariant.String) for col in df.columns]
provider.addAttributes(fields)
layer.updateFields()

# データを追加
for idx, row in df.iterrows():
    feature = QgsFeature()
    feature.setGeometry(QgsGeometry.fromPointXY(
        QgsPointXY(row['経度'], row['緯度'])
    ))
    feature.setAttributes(list(row))
    provider.addFeature(feature)

QgsProject.instance().addMapLayer(layer)

GeoJSONでの出力

Python
# レイヤをGeoJSONで出力
QgsVectorFileWriter.writeAsVectorFormat(
    layer,
    "output.geojson",
    "UTF-8",
    layer.crs(),
    "GeoJSON"
)

5.3 トラブルシューティング

よくあるエラーと対処

エラー 原因 対処
レイヤが表示されない CRSの不一致 プロジェクトCRSを確認
文字化け エンコーディング UTF-8で読み込み直す
処理が遅い インデックスなし 空間インデックスを作成
メモリ不足 データが大きすぎる 範囲を限定して処理

デバッグ方法

Python
# Pythonコンソールでprint出力
print(f"変数の値: {variable}")

# QgsMessageLogに出力(プラグイン開発時)
from qgis.core import QgsMessageLog, Qgis
QgsMessageLog.logMessage("デバッグメッセージ", "MyPlugin", Qgis.Info)

6. よくある質問(FAQ)

プログラミング初心者でもPyQGISは使えますか?

Python基礎を学んでからがおすすめです。

まずは以下から始めましょう:

  1. Python基礎(変数、ループ、関数)
  2. QGISの基本操作
  3. Pythonコンソールで簡単なコードを試す
  4. 徐々に複雑な処理へ
QGISのバージョンはどれを使えばいいですか?

LTR(長期サポート版)を推奨します。

  • LTR版:安定性重視、業務利用向け
  • 最新版:新機能を試したい場合

バージョンによってPyQGIS APIが異なる場合があるので、開発時は対象バージョンを固定しましょう。

プラグインの開発にどれくらい時間がかかりますか?

シンプルなものなら1日〜数日です。

複雑さ 目安
簡単(ボタン1つで処理) 1日
中程度(UI付き) 3〜5日
複雑(高度な機能) 1週間以上

7. 応用・発展

さらに学ぶために

AI連携

Webマップ化

  • QGISからLeaflet/OpenLayersへの出力
  • qgis2webプラグインの活用

関連記事

お問い合わせ

QGIS開発、カスタマイズについてのご相談は、お気軽にお問い合わせください。

  • 初回相談無料
  • オンライン対応可能
  • 小規模からのスタート歓迎

お問い合わせはこちら →

最終更新: 2025年1月

QGISをもっと活用しませんか?

カスタム開発やプラグイン開発で
業務効率を劇的に改善します。