Meringkas nilai-nilai poligon tetangga menggunakan QGIS?

11

Saya harap Anda dapat membantu saya dengan masalah berikut: Saya memiliki layer vektor (poligon). Saya ingin menambahkan atribut ke layer yang - untuk setiap poligon - menjumlahkan nilai dari bidang tertentu dari semua poligon yang bertetangga.

Untuk memberikan contoh yang lebih konkret: Saya memiliki lapisan poligon kabupaten yang berisi informasi tentang populasi. Sekarang, untuk setiap distrik saya ingin tahu berapa banyak orang yang tinggal di semua distrik tetangganya.

Karena saya memiliki lebih dari 300 kabupaten, saya tidak dapat melakukan ini dengan tangan untuk setiap kabupaten.

Apakah ada cara melakukan ini lebih efisien di QGIS?

Alex
sumber

Jawaban:

8

Hal semacam ini paling baik dilakukan dengan Spatialite dan SQL.

Pertama, Anda perlu memuat data Anda ke dalam basis data Spatialite yang dapat dilakukan menggunakan plugin DBManager yang dikirimkan bersama QGIS. Klik tombol Impor Layer/File button.

Dengan data Anda ke dalam basis data, Anda kemudian dapat menjalankan kueri berikut menggunakan SQLtombol. Anda hanya perlu mengubah nama kolom dan tabel agar sesuai dengan data Anda.

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

Beri tahu alat kueri kolom id unik Anda (id) dan kolom geometri (geomm), lalu klik muat

Anda harus memiliki sesuatu seperti ini, setelah Anda memberi label tentunya

masukkan deskripsi gambar di sini

Rincian Permintaan

Kami bergabung dengan layer itu sendiri menggunakan:

LEFT OUTER JOIN areas a2 ON NOT a1.id = a2.id 
                            AND intersects(a2.geomm, a1.geomm)

tetapi hanya jika geometri berpotongan dan id tidak sama, jika tidak kita berakhir dengan rekaman yang sama dua kali untuk setiap poligon. Kami juga menggunakan LEFT OUTER JOINsehingga kami menyertakan catatan yang tidak bergabung yaitu tidak punya tetangga.

Di bagian pilih:

SELECT COALESCE(SUM(a2.pop),0) as pop_neighbours, 
            a1.pop, 
            a1.name, 
            a1.id, 
            a1.geomm

kami menggunakan COALESCEuntuk mengubah NULLS(tidak ada tetangga) menjadi 0kalau tidak mereka hanya tinggal NULL.

Lalu kami hanya GROUP BY a1.idagar kami mendapatkan satu catatan untuk setiap poligon.

Nathan W
sumber
Nathan, terima kasih banyak atas jawaban dan penjelasan Anda yang bermanfaat. Itu bekerja bahkan untuk total spatialite dan sql pemula!
Alex
+1 Bagian "perincian permintaan" dilakukan dengan baik dan sangat membantu.
whuber
@Alex barang bagus. Jangan lupa untuk mencentang tombol terima.
Nathan W
2

Cara lain untuk melakukan ini adalah dalam GRASS (menggunakan kotak alat GRASS atau langsung dalam GRASS). Pada contoh di bawah ini, layer EA adalah layer vektor dengan negara dan dalam tabel atribut, kolom dengan populasi per negara. Lihat posting ini untuk penjelasan lebih rinci.

Langkah 1) Buat layer baru dengan tabel atribut yang ditautkan ke batas, dengan dua kolom dengan ID poligon yang berbatasan dengan garis batas masing-masing di sebelah kiri dan kanan

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

Langkah 2) Jalankan SQL untuk membuat tabel yang menautkan ID negara dengan jumlah populasi semua negara tetangga:

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"

Langkah 3) Gabungkan tmp tabel baru dengan tabel atribut asli.

v.db.join map=EA@ConsStat layer=1 column=cat otable=tmp ocolumn=ID

Tabel atribut dari layer vektor Anda sekarang harus memiliki kolom tambahan dengan jumlah populasi semua negara tetangga.

Ecodiv
sumber
2

Jawaban yang bagus dari @Nathan . Saya mencoba melakukan ini menggunakan pyqgis dan rupawan. Lihat posting ini untuk mengunduh skirpt dan jalankan di QGIS. Keuntungan dari metode ini adalah Anda mendapatkan hasilnya sebagai bagian dari tabel atribut.

masukkan deskripsi gambar di sini

spatialthoughts
sumber