mcpField
Q
qgis-impl-vector-analysis

qgis-impl-vector-analysis

github.com/impertio-studioデータ・データベース3948 回インストール31 週間前に更新
リポジトリ

qgis-impl-vector-analysis について

PyQGISで空間データのワークフローを作る開発者向けの、ベクター解析リファレンスです。APIの使用例に加え、ジオメトリ、CRS、出力処理の注意点をまとめています。

主な機能

  1. 01空間フィーチャの抽出と索引
  2. 02ジオメトリ操作とオーバーレイ
  3. 03属性結合と位置による結合
  4. 04ベクターデータのGeoPackage出力
  5. 05CRSとジオメトリの安全上の注意

活用シーン

  1. 01範囲や式によるフィーチャ抽出
  2. 02バッファーとオーバーレイ結果の作成
  3. 03複数ベクターレイヤー間の属性結合
  4. 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.md
examples.md
methods.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
processingQGIS Processing アルゴリズムを実行しますimport processing
主な Processing アルゴリズム ID
アルゴリズム用途
native:buffer地物の周囲にバッファー領域を作成します
native:clipオーバーレイレイヤーで入力レイヤーをクリップします
native:intersection2 つのレイヤーの幾何学的な交差を計算します
native:union2 つのレイヤーの幾何学的な和集合を計算します
native:difference幾何学的な差分(A から B を除いたもの)を計算します
native:symmetricaldifferenceA または 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:clipnative: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 -- ベクター解析でよくある間違いとその回避方法
公式情報源

コメント