qgis-impl-vector-analysis について
PyQGISで空間データのワークフローを作る開発者向けの、ベクター解析リファレンスです。APIの使用例に加え、ジオメトリ、CRS、出力処理の注意点をまとめています。
主な機能
- 01空間フィーチャの抽出と索引
- 02ジオメトリ操作とオーバーレイ
- 03属性結合と位置による結合
- 04ベクターデータのGeoPackage出力
- 05CRSとジオメトリの安全上の注意
活用シーン
- 01範囲や式によるフィーチャ抽出
- 02バッファーとオーバーレイ結果の作成
- 03複数ベクターレイヤー間の属性結合
- 04解析結果のディスクへの保存
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ impertio-studio/ qgis-claude-skill-package --skill qgis-impl-vector-analysisインストール後、Claude Code で/qgis-impl-vector-analysisを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/anti-patterns.mdexamples.mdmethods.md詳細
qgis-impl-vector-analysis
クイックリファレンス
コアクラス
| クラス | 用途 | インポート |
|---|---|---|
QgsFeatureRequest | 矩形、式、または FID で地物をフィルタリングします | qgis.core |
QgsSpatialIndex | 高速な空間検索のためのインメモリ R ツリーです | qgis.core |
QgsGeometry | ジオメトリ操作(バッファー、交差、包含)を行います | qgis.core |
QgsVectorFileWriter | ベクターレイヤーをディスクに書き込みます(GPKG、SHP、GeoJSON) | qgis.core |
QgsCoordinateTransformContext | 出力用の CRS 変換コンテキストです | qgis.core |
processing | QGIS Processing アルゴリズムを実行します | import processing |
主な Processing アルゴリズム ID
| アルゴリズム | 用途 |
|---|---|
native:buffer | 地物の周囲にバッファー領域を作成します |
native:clip | オーバーレイレイヤーで入力レイヤーをクリップします |
native:intersection | 2 つのレイヤーの幾何学的な交差を計算します |
native:union | 2 つのレイヤーの幾何学的な和集合を計算します |
native:difference | 幾何学的な差分(A から B を除いたもの)を計算します |
native:symmetricaldifference | A または B のいずれか一方に含まれる地物を抽出します |
native:dissolve | 属性値ごとに地物を結合します |
native:joinattributestable | フィールド値の一致に基づいて属性を結合します |
native:joinattributesbylocation | ジオメトリの関係に基づいて空間結合を行います |
native:extractbyexpression | 式に一致する地物を抽出します |
native:extractbylocation | 空間的な関係に基づいて地物を抽出します |
native:fieldcalculator | 式を使ってフィールド値を計算します |
重大な警告
絶対に、再投影せずに CRS が異なるレイヤーをオーバーレイ操作に渡さないでください。Processing アルゴリズムは自動的に再投影しますが、PyQGIS のジオメトリメソッドは再投影しません。直接 QgsGeometry 操作を行う前に、必ず CRS が一致していることを確認してください。
絶対に、NULL ジオメトリに対して QgsGeometry メソッドを呼び出さないでください。ジオメトリ操作を行う前に、必ず feature.hasGeometry() を確認してください。NULL ジオメトリは、エラーが通知されずに処理が失敗したり、クラッシュしたりする原因になります。
絶対に、QgsVectorFileWriter.create() を使用した後に del writer を呼び出し忘れないでください。ライターオブジェクトが破棄されるまで、ファイルはディスクに書き込まれません。
絶対に、バッチ処理で大規模なデータセットに 'OUTPUT': 'memory:' を使用しないでください。メモリレイヤーは RAM を消費し、QGIS を終了すると失われます。永続化するには、必ず GeoPackage に書き込んでください。
絶対に、processing.run() が入力レイヤーを変更すると想定しないでください。常に新しい出力レイヤーが作成されます。結果には result['OUTPUT'] からアクセスしてください。
外部ソースの入力データを使用する場合は、オーバーレイ操作の前に必ず native:fixgeometries を使用してください。無効なジオメトリがあると、オーバーレイアルゴリズムが通知なしに失敗したり、不完全な結果を生成したりします。
スタンドアロンスクリプトで processing.run() を呼び出す前に、必ず Processing フレームワークを初期化してください。
from qgis.core import QgsApplication
import processing
from processing.core.Processing import Processing
Processing.initialize()
決定木:使用するオーバーレイ操作の選択
What is your goal?
|
+-- Keep ONLY the area where both layers overlap
| --> native:intersection
|
+-- Combine ALL areas from both layers into one
| --> native:union
|
+-- Remove areas of layer B from layer A
| +-- Keep remainder of A only
| | --> native:difference
| +-- Keep remainder of BOTH A and B (exclude overlap)
| --> native:symmetricaldifference
|
+-- Cut layer A to the boundary of layer B
| --> native:clip
|
+-- Transfer attributes from one layer to another
+-- Based on matching field values
| --> native:joinattributestable
+-- Based on spatial relationship
| --> native:joinattributesbylocation
+-- Based on nearest feature
--> native:joinattributesbynearest
Clip と Intersection の比較
| 項目 | native:clip | native:intersection |
|---|---|---|
| 出力ジオメトリ | 入力と同じ | オーバーレイ境界で分割・結合される場合があります |
| オーバーレイ属性 | 含まれません | 出力に含まれます |
| 用途 | 調査範囲に合わせて切り取ります | 両方のレイヤーのデータを結合します |
| パフォーマンス | 高速です | 低速です(属性の処理があるため) |
基本パターン
パターン 1:地物リクエストによる空間クエリ
from qgis.core import QgsFeatureRequest, QgsRectangle
# Filter by bounding rectangle with exact geometry test
area = QgsRectangle(100.0, -1.0, 101.0, 0.0)
request = QgsFeatureRequest().setFilterRect(area)
request.setFlags(QgsFeatureRequest.ExactIntersect)
request.setLimit(100)
for feature in layer.getFeatures(request):
print(feature.id(), feature.geometry().asWkt())
パターン 2:高速検索のための空間インデックス
from qgis.core import QgsSpatialIndex, QgsPointXY
index = QgsSpatialIndex(layer.getFeatures())
# Nearest neighbor: returns feature IDs
nearest_ids = index.nearestNeighbor(QgsPointXY(15.5, 47.1), 5)
# Bounding box intersection: returns feature IDs
bbox = QgsRectangle(14.0, 46.0, 17.0, 49.0)
intersecting_ids = index.intersects(bbox)
# Retrieve actual features by ID
for fid in nearest_ids:
feature = layer.getFeature(fid)
パターン 3:Processing によるバッファー解析
import processing
result = processing.run("native:buffer", {
'INPUT': layer,
'DISTANCE': 100,
'SEGMENTS': 5,
'END_CAP_STYLE': 0, # 0=Round, 1=Flat, 2=Square
'JOIN_STYLE': 0, # 0=Round, 1=Miter, 2=Bevel
'MITER_LIMIT': 2,
'DISSOLVE': False,
'OUTPUT': 'memory:'
})
buffered_layer = result['OUTPUT']
パターン 4:QgsGeometry によるバッファー処理(単一地物)
geom = feature.geometry()
if not geom.isNull():
buffered = geom.buffer(100.0, 5) # distance, segments
パターン 5:オーバーレイ操作(Intersection)
import processing
result = processing.run("native:intersection", {
'INPUT': layer_a,
'OVERLAY': layer_b,
'INPUT_FIELDS': [],
'OVERLAY_FIELDS': [],
'OVERLAY_FIELDS_PREFIX': '',
'OUTPUT': 'memory:'
})
intersection_layer = result['OUTPUT']
パターン 6:フィールド値による属性結合
result = processing.run("native:joinattributestable", {
'INPUT': layer_a,
'FIELD': 'id',
'INPUT_2': layer_b,
'FIELD_2': 'foreign_id',
'FIELDS_TO_COPY': [],
'METHOD': 0, # 0=one-to-many, 1=first match only
'DISCARD_NONMATCHING': False,
'PREFIX': '',
'OUTPUT': 'memory:'
})
パターン 7:位置による空間結合
result = processing.run("native:joinattributesbylocation", {
'INPUT': target_layer,
'PREDICATE': [0], # 0=intersects, 1=contains, 2=equals,
# 3=touches, 4=overlaps, 5=within, 6=crosses
'JOIN': join_layer,
'JOIN_FIELDS': [],
'METHOD': 0, # 0=one-to-many, 1=one-to-first, 2=largest overlap
'DISCARD_NONMATCHING': False,
'PREFIX': '',
'OUTPUT': 'memory:'
})
パターン 8:属性によるディゾルブ
result = processing.run("native:dissolve", {
'INPUT': layer,
'FIELD': ['province'], # Dissolve field(s); empty list = dissolve all
'SEPARATE_DISJOINT': False,
'OUTPUT': 'memory:'
})
よく使う操作
フィールド計算(編集バッファー)
with edit(layer):
field_idx = layer.fields().indexOf('area_m2')
for feature in layer.getFeatures():
if feature.hasGeometry():
area = feature.geometry().area()
layer.changeAttributeValue(feature.id(), field_idx, area)
フィールド計算(Processing)
result = processing.run("native:fieldcalculator", {
'INPUT': layer,
'FIELD_NAME': 'area_m2',
'FIELD_TYPE': 0, # 0=Float, 1=Integer, 2=String, 3=Date
'FIELD_LENGTH': 10,
'FIELD_PRECISION': 3,
'FORMULA': '$area',
'OUTPUT': 'memory:'
})
地物の選択
# Select by expression
layer.selectByExpression('"type" = \'highway\'')
# Iterate selected features
for feature in layer.selectedFeatures():
print(feature.id())
# Clear selection
layer.removeSelection()
式による地物の抽出
result = processing.run("native:extractbyexpression", {
'INPUT': layer,
'EXPRESSION': '"population" > 50000',
'OUTPUT': 'memory:'
})
位置による地物の抽出
result = processing.run("native:extractbylocation", {
'INPUT': layer,
'PREDICATE': [0], # 0=intersects
'INTERSECT': reference_layer,
'OUTPUT': 'memory:'
})
出力を GeoPackage に書き込む
from qgis.core import QgsVectorFileWriter, QgsCoordinateTransformContext
save_options = QgsVectorFileWriter.SaveVectorOptions()
save_options.driverName = "GPKG"
save_options.fileEncoding = "UTF-8"
error = QgsVectorFileWriter.writeAsVectorFormatV3(
layer,
"/path/to/output.gpkg",
QgsCoordinateTransformContext(),
save_options
)
地物を個別に書き込む
from qgis.core import QgsVectorFileWriter, QgsWkbTypes, QgsCoordinateTransformContext
save_options = QgsVectorFileWriter.SaveVectorOptions()
save_options.driverName = "GPKG"
writer = QgsVectorFileWriter.create(
"/path/to/output.gpkg",
layer.fields(),
QgsWkbTypes.Polygon,
layer.crs(),
QgsCoordinateTransformContext(),
save_options
)
for feature in layer.getFeatures():
writer.addFeature(feature)
del writer # ALWAYS delete to flush and close the file
統計情報を使った集計
result = processing.run("native:aggregate", {
'INPUT': layer,
'GROUP_BY': '"province"',
'AGGREGATES': [
{'aggregate': 'sum', 'delimiter': ',', 'input': '"population"',
'length': 10, 'name': 'total_pop', 'precision': 0, 'type': 6}
],
'OUTPUT': 'memory:'
})
参考リンク
- references/methods.md -- QgsGeometry、QgsVectorFileWriter、QgsFeatureRequest、QgsSpatialIndex の API シグネチャと、プロセシングアルゴリズムのパラメーター
- references/examples.md -- 実際のデータを使ったベクター解析の完全なワークフロー
- references/anti-patterns.md -- ベクター解析でよくある間違いとその回避方法
公式情報源
- https://docs.qgis.org/3.34/en/docs/pyqgis_developer_cookbook/vector.html
- https://docs.qgis.org/3.34/en/docs/pyqgis_developer_cookbook/geometry.html
- https://qgis.org/pyqgis/3.34/core/QgsGeometry.html
- https://qgis.org/pyqgis/3.34/core/QgsVectorFileWriter.html
- https://qgis.org/pyqgis/3.34/core/QgsSpatialIndex.html