QGIS kullanarak komşu poligonların değerlerini toplamak mı istiyorsunuz?


11

Umarım aşağıdaki sorun konusunda bana yardımcı olabilirsiniz: Bir vektör (çokgen) katmanım var. Her çokgen için - tüm komşu çokgenlerinin belirli bir alanının değerlerini toplayan bir öznitelik eklemek istiyorum.

Daha somut bir örnek vermek gerekirse: Nüfus hakkında bilgi içeren çokgen bir ilçe katmanım var. Şimdi, her bölge için komşu bölgelerinde kaç kişinin yaşadığını bilmek istiyorum.

300'den fazla ilçem olduğu için bunu her bölge için elle yapamıyorum.

QGIS'de bunu daha verimli yapmanın bir yolu var mı?

Yanıtlar:


8

Bu tür şeyler en iyi Spatialite ve SQL ile yapılır.

Öncelikle QGIS ile birlikte gelen DBManager eklentisini kullanarak yapabileceğiniz bir Spatialite veritabanına veri yüklemeniz gerekecektir. İçe Aktar'ı tıklayın Layer/File button.

Verilerinizi bir veritabanına girerek SQLdüğmesini kullanarak aşağıdaki sorguyu çalıştırabilirsiniz . Sütunların ve tabloların adlarını verilerinize uyacak şekilde değiştirmeniz yeterlidir.

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

Sorgu aracına benzersiz kimlik sütununuzu (id) ve geometri sütununuzu (geomm) söyleyin, ardından yükle'yi tıklayın.

Elbette etiketledikten sonra böyle bir şeye sahip olmalısınız

resim açıklamasını buraya girin

Sorgu Dağılımı

Katmanı kendi üzerine kullanarak birleştiriyoruz:

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

ancak sadece geometrilerin kesiştiği ve id'lerin aynı olmadığı yerlerde, aksi takdirde her poligon için iki kez aynı kayıt elde ederiz. Ayrıca LEFT OUTER JOIN, komşu olmayan yani katılmayan kayıtları da içerecek şekilde kullanıyoruz .

Seçim bölümünde:

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

Biz (hiçbir komşu) aksi takdirde sadece kalmak COALESCEdönüştürmek için kullanıyoruz .NULLS0NULL

Sonra GROUP BY a1.idher bir çokgen için tek bir kayıt elde edelim.


Nathan, cevabınız ve faydalı açıklamalarınız için çok teşekkürler. Toplam bir spatialite ve sql acemi için bile çalıştı!
Alex

+1 "Sorgu dökümü" bölümü iyi yapılmış ve çok yardımcı.
whuber

@Alex iyi şeyler. Kabul et düğmesini tıklamayı unutmayın.
Nathan W

2

Bunu yapmanın başka bir yolu da GRASS (GRASS araç kutusunu kullanarak veya doğrudan GRASS'ta). Aşağıdaki örnekte, EA katmanı ülkeleri olan bir vektör katmanıdır ve öznitelik tablosunda ülke başına nüfus içeren bir sütundur. Daha ayrıntılı bir açıklama için bu gönderiye bakın .

Adım 1) Sırasıyla sol ve sağdaki sınır çizgisini çevreleyen çokgen kimliğine sahip iki sütunla, sınırlara bağlı öznitelik tablosu ile yeni bir katman oluşturun

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

Adım 2) Ülke kimliklerini tüm komşu ülkelerin nüfusunun toplamıyla ilişkilendiren bir tablo oluşturmak için bir SQL çalıştırın:

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"

Adım 3) Yeni tablo tmp'sini orijinal özellik tablosuyla birleştirin.

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

Vektör katmanınızın nitelik tablosunda artık tüm komşu ülkelerin toplam nüfusu olan fazladan bir sütun bulunmalıdır.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.