Підсумовування значень сусідніх многокутників за допомогою 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), а потім просто натисніть кнопку load.

Ви повинні мати щось подібне, як тільки ви позначите це, звичайно

введіть тут опис зображення

Розбивка запитів

Ми приєднуємо шар до себе за допомогою:

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(без сусідів) в інший 0спосіб вони просто залишаються NULL.

Тоді ми просто GROUP BY a1.idтак, щоб отримати один запис на кожен багатокутник.


Натане, велике спасибі за вашу відповідь та корисні пояснення. Це працювало навіть для повного простору і sql для початківців!
Олексій

+1 Розділ "Розбивка запитів" добре виконаний і дуже корисний.
whuber

@ Алекс хороший матеріал. Не забудьте позначити кнопку прийняття.
Натан Ш

2

Ще один спосіб зробити це в GRASS (використовуючи панель інструментів GRASS або безпосередньо в GRASS). У наведеному нижче прикладі шар EA - це векторний шар із країнами, а в таблиці атрибутів - стовпчик із кількістю населення в країні. Дивіться цю публікацію для більш детального пояснення.

Крок 1) Створіть новий шар із таблицею атрибутів, пов’язаною з межами, з двома стовпцями з ідентифікаторами полігонів, що межують з лінією та правою лінією відповідно

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, щоб створити таблицю, яка пов'язує ідентифікатори країни з сумою населення всіх сусідніх країн:

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

Таблиця атрибутів вашого векторного шару повинна містити додатковий стовпець із підсумком кількості всіх сусідніх країн.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.