回答:
この種のことは、SpatialiteとSQLを使用するのが最適です。
最初に、QGISに付属のDBManagerプラグインを使用して実行できるSpatialiteデータベースにデータをロードする必要があります。インポートをクリックしLayer/File button
ます。
データベースへのデータを使用して、SQL
ボタンを使用して次のクエリを実行できます。データに合わせて列とテーブルの名前を変更する必要があります。
SELECT COALESCE(SUM(a2.pop),0) as pop_neighbours,
a1.pop,
a1.name,
a1.id,
a1.geomm FROM areas a1
LEFT OUTER JOIN areas a2 ON NOT a1.id = a2.id
AND intersects(a2.geomm, a1.geomm)
GROUP BY a1.id
クエリツールに一意のID列(id)とジオメトリ列(geomm)を伝え、[ロード]をクリックします。
もちろんラベルを付けたら、このようなものが必要です
クエリの内訳
次を使用して、レイヤーをそれ自体に結合しています。
LEFT OUTER JOIN areas a2 ON NOT a1.id = a2.id
AND intersects(a2.geomm, a1.geomm)
ただし、ジオメトリが交差し、IDが同じでない場合のみ、そうでない場合、各ポリゴンに対して同じレコードが2回作成されます。また、aを使用しているLEFT OUTER JOIN
ので、結合しない、つまり隣人のないレコードが含まれます。
選択部分で:
SELECT COALESCE(SUM(a2.pop),0) as pop_neighbours,
a1.pop,
a1.name,
a1.id,
a1.geomm
(隣人なし)COALESCE
をに変換するために使用しています。NULLS
0
NULL
次にGROUP BY a1.id
、ポリゴンごとに1つのレコードを取得するようにします。
これを行う別の方法は、GRASS(GRASSツールボックスを使用するか、GRASSで直接)です。次の例では、レイヤーEAは国を含むベクターレイヤーであり、属性テーブルでは国ごとの人口を含む列です。より詳細な説明については、この投稿を参照してください。
手順1)境界にリンクされた属性テーブルを使用して新しいレイヤーを作成します。ポリゴンのIDを持つ2つの列は、それぞれ左右の境界線に接しています
v.category EA out=EAc layer=2 type=boundary option=add
v.db.addtable EAc layer=2 col="left integer,right integer"
v.to.db EAc option=sides col=left,right layer=2 type=boundary
ステップ2)SQLを実行して、国IDとすべての近隣国の人口の合計をリンクするテーブルを作成します。
db.execute sql="CREATE TABLE tmp AS
SELECT ID, sum(pop) as population FROM (
SELECT DISTINCT EAc_2.left as ID, EAc.pop as pop
FROM EAc_2
LEFT JOIN EAc ON EAc_2.right = EAc.cat
WHERE EAc_2.left > -1 AND EAc_2.right > -1
UNION
SELECT DISTINCT EAc_2.right as ID, EAc.pop as pop
FROM EAc_2
LEFT JOIN EAc ON EAc_2.left = EAc.cat
WHERE EAc_2.left > -1 AND EAc_2.right > -1
) GROUP BY ID"
手順3)新しいテーブルtmpを元の属性テーブルと結合します。
v.db.join map=EA@ConsStat layer=1 column=cat otable=tmp ocolumn=ID
ベクターレイヤーの属性テーブルには、すべての近隣国の合計人口を含む追加の列があります。
@Nathanによる素晴らしい回答。私はpyqgisを使ってこれをうまくやってみました。この投稿をチェックして、スクリプトをダウンロードし、QGISで実行してください。この方法の利点は、属性テーブルの一部として結果を取得できることです。