สรุปค่าของรูปหลายเหลี่ยมเพื่อนบ้านโดยใช้ QGIS?


11

ฉันหวังว่าคุณสามารถช่วยฉันด้วยปัญหาต่อไปนี้: ฉันมีเลเยอร์เวกเตอร์ (รูปหลายเหลี่ยม) ฉันต้องการเพิ่มคุณสมบัติให้กับเลเยอร์ที่ - สำหรับทุกรูปหลายเหลี่ยม - รวมค่าของเขตข้อมูลเฉพาะของรูปหลายเหลี่ยมที่อยู่ใกล้เคียงทั้งหมด

เพื่อยกตัวอย่างที่เป็นรูปธรรมมากขึ้น: ฉันมีเลเยอร์หลายเหลี่ยมของเขตที่มีข้อมูลเกี่ยวกับประชากร ทีนี้สำหรับทุกอำเภอฉันอยากรู้ว่ามีกี่คนที่อาศัยอยู่ในเขตใกล้เคียงทั้งหมด

เนื่องจากฉันมีมากกว่า 300 เขตฉันไม่สามารถทำสิ่งนี้ได้ด้วยมือสำหรับแต่ละเขต

QGIS ทำสิ่งนี้ได้อย่างมีประสิทธิภาพมากขึ้นหรือไม่?

คำตอบ:


8

สิ่งนี้ทำได้ดีที่สุดกับ Spatialite และ SQL

ก่อนอื่นคุณจะต้องโหลดข้อมูลของคุณลงในฐานข้อมูล Spatialite ซึ่งสามารถทำได้โดยใช้ปลั๊กอิน DBManager ที่มาพร้อมกับ QGIS 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) แล้วคลิกโหลด

คุณควรมีอะไรแบบนี้เมื่อคุณติดป้ายกำกับแน่นอน

ป้อนคำอธิบายรูปภาพที่นี่

Query Breakdown

เรากำลังรวมเลเยอร์เข้ากับตัวเองโดยใช้:

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

แต่เฉพาะที่รูปทรงเรขาคณิตตัดกันและรหัสไม่เหมือนกันมิฉะนั้นเราจะจบลงด้วยการบันทึกเดียวกันสองครั้งสำหรับแต่ละรูปหลายเหลี่ยม เรายังใช้LEFT OUTER JOINเพื่อให้เรารวมบันทึกที่ไม่ได้เข้าร่วมเช่นไม่มีเพื่อนบ้าน

ในส่วนที่เลือก:

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

เราจะใช้COALESCEในการสั่งซื้อเพื่อแปลงNULLS(ไม่มีเพื่อนบ้าน) ลงมิฉะนั้นพวกเขาเพียงแค่ต้องการเข้าพัก0NULL

จากนั้นเราก็GROUP BY a1.idจะได้รับการบันทึกเดียวสำหรับแต่ละรูปหลายเหลี่ยม


นาธานขอบคุณมากสำหรับคำตอบและคำอธิบายที่เป็นประโยชน์ของคุณ มันทำงานได้แม้กระทั่งการเริ่มต้นเชิงพื้นที่และ sql ทั้งหมด!
อเล็กซ์

+1 ส่วน "การแยกย่อยแบบสอบถาม" ทำได้ดีและมีประโยชน์มาก
whuber

@Alex สิ่งที่ดี อย่าลืมทำเครื่องหมายที่ปุ่มยอมรับ
นาธาน W

2

อีกวิธีในการทำเช่นนี้คือ GRASS (โดยใช้กล่องเครื่องมือ GRASS หรือโดยตรงใน GRASS) ในตัวอย่างด้านล่างเลเยอร์ EA เป็นเลเยอร์เวกเตอร์ที่มีประเทศและในคอลัมน์ตารางแอตทริบิวต์ที่มีประชากรต่อประเทศ ดูโพสต์นี้สำหรับคำอธิบายรายละเอียดเพิ่มเติม

ขั้นตอนที่ 1) สร้างเลเยอร์ใหม่พร้อมตารางแอตทริบิวต์ที่เชื่อมโยงกับขอบเขตโดยมีสองคอลัมน์ที่มี ID ของรูปหลายเหลี่ยมที่ล้อมรอบเส้นขอบด้านซ้ายและขวาตามลำดับ

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

ตารางแอตทริบิวต์ของเลเยอร์เวกเตอร์ของคุณควรมีคอลัมน์เพิ่มเติมพร้อมจำนวนรวมของประเทศเพื่อนบ้านทั้งหมด


2

คำตอบที่ดีโดย @Nathan ฉันพยายามทำสิ่งนี้โดยใช้ pyqgis และหุ่นดี ลองอ่านโพสต์นี้เพื่อดาวน์โหลด scirpt และรันใน QGIS ข้อดีของวิธีนี้คือคุณจะได้รับผลลัพธ์เป็นส่วนหนึ่งของตารางคุณสมบัติ

ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.