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)
- QGIS公式サイトにアクセス
- 「ダウンロード」から最新版を選択
- 「スタンドアロンインストーラ」を推奨
- インストーラを実行
推奨初期設定
設定
設定 → オプション → 一般
├── ロケールを上書き: 日本語
└── プロジェクト保存時にレイヤ情報を相対パスで保存
設定 → オプション → 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で雛形作成
- プラグイン → Plugin Builder → Plugin Builder
- 必要情報を入力
- 出力先フォルダを指定
- 生成
生成後の作業
- 生成されたフォルダをQGISプラグインフォルダにコピー
- Windows:
C:\Users\{user}\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins
- Windows:
- QGISを再起動
- プラグインを有効化
簡単なプラグインコード例(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 配布・公開方法
社内配布
- プラグインフォルダをZIP化
- 配布先でプラグインフォルダに展開
- QGISで有効化
公式リポジトリへの公開
- QGIS Plugin Repositoryでアカウント作成
- プラグインをZIP化してアップロード
- 審査後、公開
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基礎を学んでからがおすすめです。
まずは以下から始めましょう:
- Python基礎(変数、ループ、関数)
- QGISの基本操作
- Pythonコンソールで簡単なコードを試す
- 徐々に複雑な処理へ
QGISのバージョンはどれを使えばいいですか?
LTR(長期サポート版)を推奨します。
- LTR版:安定性重視、業務利用向け
- 最新版:新機能を試したい場合
バージョンによってPyQGIS APIが異なる場合があるので、開発時は対象バージョンを固定しましょう。
プラグインの開発にどれくらい時間がかかりますか?
シンプルなものなら1日〜数日です。
| 複雑さ | 目安 |
|---|---|
| 簡単(ボタン1つで処理) | 1日 |
| 中程度(UI付き) | 3〜5日 |
| 複雑(高度な機能) | 1週間以上 |
7. 応用・発展
さらに学ぶために
AI連携
Webマップ化
- QGISからLeaflet/OpenLayersへの出力
- qgis2webプラグインの活用
