Програмно знаходження багатокутників, які> 90% перекриті іншим шаром векторного багатокутника за допомогою QGIS?


9

Приклади шарів

Я намагаюся розібратися, як за допомогою пітона витягти багатокутники в одному векторі, які перекриваються на> 90% іншим вектором. Тоді я хотів би мати вектор / карту, яка відображатиме лише ті багатокутники. На прикладі зображення показані мої шари. Я хочу, щоб усі сірі багатокутники були> 90% червоними.

Мені це потрібно зробити через python (або аналогічно автоматизованими методами). У мене є ~ 1000 карт, щоб обробляти так само.


Ви хочете зробити накладення "об'єднання" (див. Infogeoblog.wordpress.com/2013/01/08/geo-processing-in-qgis для деяких основ), а потім для кожного оригінального багатокутника обчисліть статистику "в" та "поза" gis.stackexchange.com/questions/43037/…, щоб визначити відсоток накладання ... підказка: вам потрібно провести вимірювання площі gis.stackexchange.com/questions/23355/…
Майкл

Дякую за поради. Це той самий підхід, який я тільки намагався. Я можу зробити об'єднання через консоль python досить легко. Вже додані значення атрибутів області. Це наступний крок, в якому я не впевнений. Як я можу використовувати python для обчислення статистики "в" та "поза", щоб я міг ідентифікувати / вибрати / вирізати і т.д.> полігони> 90%?
померлого

Я думаю, що це можливо без пітона. Вам потрібен абсолютно питон або рішення з віртуальними шарами добре для вас?
Пірма

Області 'в' матимуть атрибути обох полігонів, а області 'в' мають лише атрибути з одного набору багатокутників. Отримайте обидва набори статистики площ і приєднайтеся до початкових полігонів, додайте поле для "в", "поза" та покриття, обчисліть значення "в" і "поза" від суми площ, а потім розділіть "на" на початкова площа (або 'в' + 'поза') для обчислення відсотків.
Майкл Стімсон

1
Pierma - Мені просто потрібен автоматизований метод пошуку полігонів.
померлого

Відповіді:


3

Наступний код працює в моїй консолі Python QGIS. Він створює шар пам'яті з багатокутниками, які> 90% перекриваються червоними ділянками.

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

#for polygon_intersects
feats_lyr1 = [ feat for feat in layers[0].getFeatures() ]

#for xwRcl
feats_lyr2 = [ feat for feat in layers[1].getFeatures() ]

selected_feats = []

for i, feat1 in enumerate(feats_lyr1):
    area1 = 0
    area2 = 0
    for j, feat2 in enumerate(feats_lyr2):
        if feat1.geometry().intersects(feat2.geometry()):
            area = feat1.geometry().intersection(feat2.geometry()).area()
            print i, j, area, feat2.attribute('class')
            if feat2.attribute('class') == 1:
                area1 += area
            else:
                area2 += area
    crit = area1/(area1 + area2)
    print crit
    if crit > 0.9:
        selected_feats.append(feat1)

epsg = layers[0].crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           "mem_layer",
                           "memory")

prov = mem_layer.dataProvider()

for i, feat in enumerate(selected_feats):
    feat.setAttributes([i])

prov.addFeatures(selected_feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

Я спробував код із цими двома векторними шарами:

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

Після запуску коду на консолі Python QGIS для підтвердження результатів були надруковані індекси i, j задіяних функцій, ділянок перетину, атрибут поля в полігонах_інтерсектах (1 для червоних областей та 2 для сірих областей) та критерій перекриття .

0 0 9454207.56892 1
0 1 17429206.7906 2
0 2 10326705.2376 2
0 4 40775341.6814 1
0 5 26342803.0964 2
0 7 11875753.3216 2
0.432253120382
1 6 1198411.02558 2
1 7 1545489.96614 2
1 10 27511427.9909 1
0.90930850584
2 7 750262.940888 2
2 8 12012343.5859 1
0.941213972294
3 6 23321277.5158 2
0.0

Створений шар пам'яті (зелені функції) можна спостерігати на наступному зображенні. Це було як очікувалося.

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


6

Тут рішення, яке не потребує python.

Додайте новий віртуальний шар із запитом:

WITH r AS (
SELECT 
    Basins800.rowid AS idGray, 
    area(Basins800.geometry) AS areaGray, 
    area(Intersection(Basins800.geometry, Severity.geometry)) AS aeraInter, 
    Basins800.geometry AS geomGray 
  FROM Basins800, Severity
)

SELECT *, areaInterSum/areaGray  AS overlap , geomGray 
    FROM (
        SELECT 
           idGray, 
           areaGray, 
           sum(areaInter) AS areaInterSum, 
           geomGray 
        FROM r 
        GROUP BY idGray) 
     WHERE areaInterSum/areaGray > 0.9

З:

  • Basins800 як ваш шар, який потрібно фільтрувати із сірими багатокутниками

  • Важкість: ваш червоний шар перекривається.

В результаті вийде новий шар, у якому лише всі сірі плоскігони> 90% перекриваються червоними багатокутниками, з новим полем, що містить відсотки перекриття.

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

Сподіваюся, це працює. Я можу додати більше деталей запиту, якщо це потрібно.

Примітка: Ваші дані містять дуже малі багатокутники (що надходять від вашої растрової обробки та відповідають растровому пікселю (на малюнку ми можемо побачити 4 полігони, але є ще 25 малих полігонів). Це робить запит дуже повільним для виконання (функція перетину) генерує одну функцію для кожної пари функцій з двох шарів).


Я отримую помилку під час запуску запиту за допомогою кнопки "створити віртуальний шар". "Помилка виконання запиту на CREATE TEMP VIEW _tview AS WITH r AS (" .... решта коду тут ... далі: "1 - біля" WITH ": синтаксична помилка." Я досить новачок у QGIS. Чи можу я створити цей віртуальний шар програмно? Дякую за допомогу!
dnormous

Ось посилання для завантаження
форм-

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

Це лише один невеликий фрагмент процесу. У мене є приблизно 1000 таких карт, тому автоматизація процесу буде дуже корисною.
померлого

Я все ще отримую ту саму помилку -> "1 - біля" З ": помилка синтаксису". Я підключив локальні назви кожного шару для GrayLayer та redLayer. Місцева назва чи я повинен використовувати? тобто: сірий шар позначений як "Basins_800", тому у мене є код на зразок "Basins_800.geometry"
dnormous

2

Переглянувши посилання на формати Severity та Basins800 , я міг зрозуміти необхідний геопроцес. Я змінив код у:

Програмно знаходження багатокутників, які> 90% перекриті іншим шаром векторного багатокутника за допомогою QGIS?

для отримання цього:

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

#for Severity
feats_lyr1 = [ feat for feat in layers[0].getFeatures() ]

#for Basins800
feats_lyr2 = [ feat for feat in layers[1].getFeatures() ]

selected_feats = []

print "processing..."

for i, feat1 in enumerate(feats_lyr1):
    for j, feat2 in enumerate(feats_lyr2):
        if feat1.geometry().intersects(feat2.geometry()):
            area1 = feat1.geometry().intersection(feat2.geometry()).area()
            area2 = feat1.geometry().area()
            print i, j, area1, area2
    crit = area1/area2
    print crit
    if crit > 0.9:
        selected_feats.append(feat1)

epsg = layers[0].crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           "mem_layer",
                           "memory")

prov = mem_layer.dataProvider()

for i, feat in enumerate(selected_feats):
    feat.setAttributes([i])

prov.addFeatures(selected_feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

Після запуску коду за допомогою цих файлів форм на консолі Python QGIS за кілька хвилин я отримав подібний результат, як і Pierma ; де шар пам'яті мав 31 функцію (різну з 29 полігонів, отриманих ним).

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

Я не збираюся налагоджувати результати, оскільки є 1901 * 3528 = 6706728 взаємодій для функцій. Однак код виглядає багатообіцяючим.

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