Відсоток багатокутника в одному профілі форми у межах багатокутника іншого


13

Я новачок, вибачте, якщо це очевидно / вже просили і відповіли, але я нічого не міг знайти.

У мене є два форм-файли : 1. адміністративний прикордонний шар для графства у Великобританії, відомий як межа LSOA, що має в ньому 500 маленьких зон 2. зона затоплення.

В ідеалі я хочу дізнатися, яка з маленьких зон LSOA знаходиться у ≥50% у зоні затоплення, і в кінцевому підсумку є "так" або "1" для кожної з 500 зон LSOA.

Але я не знаю, як це зробити. Я зрозумів, що можу приєднатись до двох форм-файлів, але загального атрибута між ними немає. Тоді я подумав, що можу використовувати функцію Join Attribute by Location, яка працювала і показує мені, які LSOA знаходяться в зоні затоплення, але це майже всі (див. Зображення 2).

Я думаю, що це проблема SQL, але я не знаю. Я новачок у QGIS і ніколи не використовував PostgreSQL.

Будь-яка допомога буде дуже вдячна. Я можу надати будь-яку інформацію, яку вам потрібні прекрасні люди, щоб допомогти мені.

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

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

Відповіді:


12

Це відносно просте завдання з використанням інструментів для геообробки, включених до QGIS.

  1. Обчисліть площу ваших зон LSOA.

    • Відкрийте таблицю атрибутів шару LSOA.
    • Увімкнути режим редагування.
    • Відкрийте калькулятор поля.
    • Створіть нове поле типу "Десяткове число (справжнє)" з виразом "$ area".
    • Вимкнути режим редагування (збереження правки).
  2. Об’єднайте шар зони затоплення в єдину багатоскладову функцію.

    • Vector > Geometry Tools > Singleparts to Multipart.
    • Виберіть "--- Об'єднати всі ---" для поля Унікальний ідентифікатор.
  3. Перетинають зонний шар LSOA з шаром зони багатотопної затоплення.

    • Vector > Geoprocessing Tools > Intersect.
    • Вхідним шаром є зони LSOA, пересічним шаром є зони затоплення.
  4. Отриманий шар буде частинами зон LSOA (з атрибутами шару зон LSOA), які перекриваються шаром зон затоплення. Для обчислення частки кожної зони LSOA в зоні повені:

    • Обчисліть площу перехрещених ознак (як на кроці №1), потім
    • Додайте ще одне поле, розділивши початкову (загальну) площу на ділянку, що перетинається. Результат - десятковий від 0 до 1. Помножте на 100, щоб дати відсоток.
  5. Приєднайте оригінальний шар LSOA до пересіченого шару, використовуючи унікальний ідентифікатор, який спільний для обох шарів.

  6. Експортуйте з'єднаний шар як новий файл форми.

  7. Видаліть дублювані атрибути.

Et voilà!

Без кроку №2 буде створено індивідуальну функцію для кожної особливості зони затоплення для кожної функції LSOA. Це, мабуть, не те, що ви хочете, якщо вас цікавить лише загальне покриття для кожної зони LSOA. Якщо ви хочете розмежовувати рівномірне / припливне / плювіальне затоплення (а дані про зону затоплення підтримують це), ви можете перетворити одночастинку в багаточастину, вказавши поле "ТИП" як поле унікального ідентифікатора.


Дякую за твою допомогу! Цінується. Однак у мене виникають певні проблеми. Я стежив за кроками. Крок 3, перехрестя, пройшло 10 годин, і коли було зроблено все, що я отримав, це порожній профіль : i.imgur.com/QIM6Gtg.png Чи щось я пропустив? Я спробував завершити процес і зробити крок 4, але немає даних для обчислення площі перетину.
KJGarbutt

У мене раніше були проблеми з перехрестями з шарами затоплення. Особливості великі і складні. Те, як я працював над цим раніше, - це розділити їх на більш дрібні функції, тому просторовий індекс може виконати більше роботи. Для цього створіть векторну сітку такої ж міри, як шар затоплення ( Vector > Research Tools > Vector Grid... Output grid as polygons), потім переріжте сітку з шаром затоплення. Потім використовуйте результат замість шару затоплення на кроці 3. Я здогадуюсь, що причина шару порожня - це те, що він вийшов з ладу.
Snorfalorpagus

Знову дякую. Єдина проблема в тому, що QGIS виходить з ладу щоразу, коли я намагаюся створити векторну сітку. Я дотримувався поради звідси, але вона виходить з ладу щоразу. Я неодноразово змінював параметри і намагався використовувати лише файл форми форми затоплення, замість того, щоб весь файл проекту був відкритий, і він виходить з ладу кожен раз. Будь-які ідеї? ! Скріншот тут .
KJGarbutt

Параметри X і Y, які ви вказали, набагато замалі. Спробуйте щось на зразок 1000 x 1000. Ви можете навіть зробити це кілька разів, тобто спочатку зробіть 5000 x 5000, використовуючи вихід, щоб створити 500 x 500. Дивіться відповідні відповіді тут: gis.stackexchange.com/a/66319/12420
Snorfalorpagus

Я майже тріснув це з вашою допомогою! Однак, коли я йду приєднуватися до вихідного шару LSOA з пересіченим шаром, я втрачаю багато даних. Я думаю, це тому, що деякі створені квадратичні сіткові квадрати потрапляють в одну і ту ж область LSOA і тому мають той самий код LSOA, як кожен. Таким чином, я закінчую 2+ відсотковими цифрами для кожної області LSOA, коли я роблю приєднання, і, здається, я отримую лише одну з них. Чи є спосіб підсумовувати кожен відсоток для кожного квадрату сітки з однаковою LSOA?
KJGarbutt

6

Ви можете використовувати просторовий і деякі просторові функції SQL.

Select t1.geometry, t1.ID, area(t1.geometry), area(t2.geometry) ...... (anything you need to have in the table results)

(area(intersection(t1.geometry,t2.geometry))) as "Commun_AREA"

, ("Commun_AREA"*100/(area(t1.geometry))) as "Percent_AREA"

From lsoa as t1, flood_zone as t2

Where Intersects( t1.geometry,t2.geometry ) = 1

3

Це здається чимось, що можна зробити набагато простіше, ніж подані відповіді. Я б особисто застосував простий скрипт python:

floodName = "the layer name here"
boundryName = "the layer name here"
fieldName = "the name of the field to contain the output 1/0"
minCoverage = 0.5 # the minimum amount of area covered to write 1
updateMap = [] # this will store values to be written    

# get layers
floodLayer = QgsMapLayerRegistry.instance().mapLayersByName(floodName)[0]
boundryLayer = QgsMapLayerRegistry.instance().mapLayersByName(boundryName)[0]
fieldIndex = boundryLayer.dataProvider().fieldNameIndex(fieldName)    

# iterate through boundries
for b in boundryLayer.getFeatures():
    # get only flood features that intersect with this feature's bounding box
    # this will make the script go way faster than it would otherwise
    request = QgsFeatureRequest().setFilterRect(b.geometry().boundingBox())
    floodGeom = geometry()
    floodFeat = QgsFeature()
    iter = floodLayer.getFeatures(request)
    iter.nextFeature(feat)
    while iter.nextFeature(feat):
        floodGeom = floodGeom.combine(feat.geometry())
    intersectGeom = b.geometry().intersection(feat.geometry())
    if intersectGeom.area() > minCoverage * b.geometry().area():
        updateMap[b.id()] = {fieldIndex : 1}
    else:
        updateMap[b.id()] = {fieldIndex : 0}

boundryLayer.dataProvider().changeAttributeValues(updateMap)

це оцінює лише потоки багатокутників, які перетинаються з обмежувальним вікном кожного прикордонного шару, тому його слід досить швидко запустити, тоді він оновлює лише одне поле в існуючому шарі (замість складної операції створення цілком нового шару та копіювання старих значень потім видалення)


2

У мене була така ж проблема, як KJ, виконуючи вказівки Snorfalorpagus, використовуючи метод "Пересікання" на кроці 3. Для обчислення знадобилося досить багато часу, і те, що мені залишилося, було порожнім.

Я намагався виконувати ті самі кроки, за винятком використання методу "Clip" в QGIS замість Intersect - так, у вашому прикладі, що залишилося б, це ті ділянки, які НЕ покриті зоною затоплення. Здається, це чомусь спрацювало, і я зміг використати обчислення поля "Площа" з попереднього кроку, а також новий розрахунок "Площа" на решті частин кожного багатокутника, щоб визначити% кожної області, яка НЕ ​​була покритий іншим шаром багатокутника.

Це технічно навпаки того, що ви просили. Але звідти це просто питання віднімання кожного значення від 1 , щоб отримати те , що буде покрито зоною затоплення.

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