Tổng hợp các giá trị của đa giác lân cận bằng cách sử dụng QGIS?


11

Tôi hy vọng rằng bạn có thể giúp tôi với vấn đề sau: Tôi có một lớp vectơ (đa giác). Tôi muốn thêm một thuộc tính cho lớp - với mọi đa giác - tính tổng các giá trị của một trường cụ thể của tất cả các đa giác lân cận của nó.

Để đưa ra một ví dụ cụ thể hơn: Tôi có một lớp đa giác các quận chứa thông tin về dân số. Bây giờ, đối với mỗi quận, tôi muốn biết có bao nhiêu người sống ở tất cả các quận lân cận.

Vì tôi có hơn 300 quận, tôi không thể làm điều này bằng tay cho từng quận.

Có cách nào làm điều này hiệu quả hơn trong QGIS không?

Câu trả lời:


8

Loại điều này được thực hiện tốt nhất với Spatialite và SQL.

Trước tiên, bạn sẽ cần tải dữ liệu của mình vào cơ sở dữ liệu Spatialite có thể thực hiện bằng cách sử dụng plugin DBManager đi kèm với QGIS. Nhấp vào Nhập Layer/File button.

Với dữ liệu của bạn vào cơ sở dữ liệu, sau đó bạn có thể chạy truy vấn sau bằng SQLnút. Bạn sẽ chỉ phải thay đổi tên của các cột và bảng cho phù hợp với dữ liệu của bạn.

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

Nói cho công cụ truy vấn cột id duy nhất của bạn (id) và cột hình học (geomm), sau đó chỉ cần nhấp vào tải.

Bạn nên có một cái gì đó như thế này, một khi bạn dán nhãn nó tất nhiên

nhập mô tả hình ảnh ở đây

Phân tích truy vấn

Chúng tôi đang tham gia lớp vào chính nó bằng cách sử dụng:

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

nhưng chỉ khi hình học giao nhau và id không giống nhau, nếu không, chúng ta kết thúc với cùng một bản ghi hai lần cho mỗi đa giác. Chúng tôi cũng đang sử dụng LEFT OUTER JOINđể chúng tôi bao gồm các hồ sơ không tham gia tức là không có hàng xóm.

Trong phần chọn:

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

chúng tôi đang sử dụng COALESCEđể chuyển đổi NULLS(không có hàng xóm) thành nơi 0khác mà họ chỉ ở lại NULL.

Sau đó, chúng tôi chỉ GROUP BY a1.idđể chúng tôi có được một bản ghi cho mỗi đa giác.


Nathan, cảm ơn rất nhiều vì câu trả lời của bạn và những lời giải thích hữu ích. Nó đã làm việc ngay cả đối với một người mới bắt đầu spatialite và sql!
Alex

+1 Phần "phân tích truy vấn" được thực hiện độc đáo và rất hữu ích.
whuber

@Alex thứ tốt. Đừng quên đánh dấu vào nút chấp nhận.
Nathan W

2

Một cách khác để làm điều này là trong GRASS (sử dụng hộp công cụ GRASS hoặc trực tiếp trong GRASS). Trong ví dụ dưới đây, EA lớp là một lớp vectơ với các quốc gia và trong bảng thuộc tính một cột có dân số mỗi quốc gia. Xem bài đăng này để được giải thích chi tiết hơn.

Bước 1) Tạo lớp mới với bảng thuộc tính được liên kết với các ranh giới, với hai cột có ID đa giác giáp với đường biên ở bên trái và bên phải

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

Bước 2) Chạy SQL để tạo bảng liên kết ID quốc gia với tổng dân số của tất cả các quốc gia lân cậ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"

Bước 3) Tham gia bảng tmp mới với bảng thuộc tính ban đầu.

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

Bảng thuộc tính của lớp vectơ của bạn bây giờ sẽ có thêm một cột với tổng dân số của tất cả các quốc gia lân cận.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.