大量のGISデータを扱うと、QGISの動作が重くなることがあります。
QGISで大量データを扱う方法【パフォーマンス改善ガイド】
この記事では、大量データを効率的に扱うためのテクニックを解説します。
大量データの課題
よくある症状
症状
- 地図の表示が遅い
- ズーム・パンがカクつく
- 処理に時間がかかる
- メモリ不足エラー
- QGISがフリーズ
データ量の目安
| 規模 | フィーチャ数 | 注意点 |
|---|---|---|
| 小 | 〜10,000 | 通常問題なし |
| 中 | 10,000〜100,000 | 設定の最適化推奨 |
| 大 | 100,000〜1,000,000 | 要対策 |
| 超大 | 1,000,000〜 | 専用の対策必須 |
空間インデックスの活用
空間インデックスとは
データの位置情報を効率的に検索するための索引です。
【空間インデックスなし】 全フィーチャを順番にチェック → 遅い 【空間インデックスあり】 位置で絞り込んでからチェック → 速い
インデックスの作成
QGIS GUI:
レイヤを右クリック → プロパティ → ソース → 「空間インデックスを作成」
PyQGIS:
python
layer = iface.activeLayer()
provider = layer.dataProvider()
# 空間インデックスを作成
if provider.capabilities() & QgsVectorDataProvider.CreateSpatialIndex:
provider.createSpatialIndex()
print("空間インデックスを作成しました")
GeoPackageの空間インデックス
GeoPackageでは自動的に空間インデックスが作成されます。
確認方法
- DB Manager → GeoPackage → テーブル
- 「情報」タブで確認
データの軽量化
ジオメトリの簡略化
複雑なポリゴンを単純化して軽量化:
QGIS GUI:
ベクタ → ジオメトリツール → ジオメトリの簡素化 パラメータ: ・許容値:0.0001(度)または10(メートル) → 値が大きいほど簡素化
PyQGIS:
python
import processing
result = processing.run("native:simplifygeometries", {
'INPUT': layer,
'METHOD': 0, # Douglas-Peucker
'TOLERANCE': 10, # メートル
'OUTPUT': 'memory:'
})
頂点数の削減
python
# 頂点数の確認
for feature in layer.getFeatures():
geom = feature.geometry()
if geom:
vertex_count = sum(1 for _ in geom.vertices())
print(f"ID {feature.id()}: {vertex_count} 頂点")
属性データの削減
不要な属性フィールドを削除:
python
# 必要なフィールドのみ保持
fields_to_keep = ['id', 'name', 'area']
processing.run("native:retainfields", {
'INPUT': layer,
'FIELDS': fields_to_keep,
'OUTPUT': 'memory:'
})
表示設定の最適化
縮尺に応じた表示
小縮尺では表示しない設定:
レイヤプロパティ → レンダリング → 「縮尺に応じた表示」にチェック → 最小:1:10000 / 最大:1:100000
シンボルの簡素化
重いシンボル
複雑なSVGアイコン、グラデーション、影効果、ラベルのバッファ
軽いシンボル
単純な形状(丸、四角)、単色、効果なし
ラベルの最適化
レイヤプロパティ → ラベル → レンダリング → 「このレイヤの最大フィーチャラベル数」:1000 → 「妨げるラベルを表示」:チェックなし
レンダリング設定
設定 → オプション → レンダリング
- 描画キャッシュを有効にする:チェック
- キャッシュサイズ:1024MB以上
- 並列レンダリングを使う:チェック
効率的なデータ形式
データ形式の比較
| 形式 | 読み込み速度 | 推奨用途 |
|---|---|---|
| GeoPackage | ◎ 高速 | 大量データ、推奨 |
| Shapefile | ○ 普通 | 互換性重視 |
| GeoJSON | △ 遅い | Web向け、小規模 |
| PostGIS | ◎ 高速 | 超大規模 |
GeoPackageへの変換
レイヤを右クリック → エクスポート → 新規ファイルに地物を保存 → 形式:GeoPackage
PostGISの活用
超大規模データはPostGISが最適:
PostGISのメリット
- サーバーサイドで処理
- インデックスが高性能
- 複数人での同時アクセス
- SQLで高度なクエリ
メモリ管理
メモリ使用量の確認
Windows
タスクマネージャー → QGIS のメモリ使用量
メモリ使用量の削減
不要なレイヤを削除:
python
# 使っていないレイヤを削除
for layer_id, layer in QgsProject.instance().mapLayers().items():
if not layer.name() in ['必要なレイヤ1', '必要なレイヤ2']:
QgsProject.instance().removeMapLayer(layer_id)
範囲を限定して読み込み:
python
# 特定範囲のみ読み込み
uri = f"{filepath}|layername={layername}|subset=ST_Within(geometry, ST_GeomFromText('POLYGON(...)'))"
layer = QgsVectorLayer(uri, "layer", "ogr")
処理の高速化
範囲を限定した処理
python
# 処理対象の範囲を限定
extent = QgsRectangle(139.7, 35.6, 139.8, 35.7)
request = QgsFeatureRequest().setFilterRect(extent)
for feature in layer.getFeatures(request):
# 処理
pass
空間インデックスを活用した検索
python
# 空間インデックスを作成
spatial_index = QgsSpatialIndex(layer.getFeatures())
# 特定範囲内のフィーチャIDを取得(高速)
ids = spatial_index.intersects(QgsRectangle(139.7, 35.6, 139.8, 35.7))
# IDからフィーチャを取得
for fid in ids:
feature = layer.getFeature(fid)
# 処理
バッチ更新
python
# 悪い例:毎回コミット
for feature in layer.getFeatures():
layer.startEditing()
layer.changeAttributeValue(feature.id(), 0, "value")
layer.commitChanges() # 毎回コミット → 遅い
# 良い例:まとめてコミット
layer.startEditing()
for feature in layer.getFeatures():
layer.changeAttributeValue(feature.id(), 0, "value")
layer.commitChanges() # 最後に1回 → 速い
プログレスと中断
python
from qgis.core import QgsTask
class LargeDataTask(QgsTask):
def run(self):
total = self.layer.featureCount()
for i, feature in enumerate(self.layer.getFeatures()):
if self.isCanceled():
return False
# 処理
self.setProgress(i / total * 100)
return True
トラブルシューティング
表示が遅い
対処
- 空間インデックスを作成
- 縮尺に応じた表示を設定
- シンボルを簡素化
- GeoPackageに変換
処理がタイムアウト
対処
- データを分割して処理
- 範囲を限定
- バックグラウンドタスクを使用
- PostGISで処理
メモリ不足
対処
- 不要なレイヤを削除
- 64bit版QGISを使用
- PCのメモリを増設
- データを分割
まとめ
パフォーマンス改善の優先順位
優先順位
- 1. 空間インデックスを作成
- 2. GeoPackageを使用
- 3. 縮尺に応じた表示を設定
- 4. シンボル・ラベルを簡素化
- 5. 必要に応じてPostGIS
チェックリスト
確認項目
- □ 空間インデックスを作成した
- □ GeoPackageに変換した
- □ 縮尺に応じた表示を設定した
- □ シンボルを簡素化した
- □ 不要なレイヤを削除した
関連記事
