Симметрическая разность полигонов

Вопросы по свободной ГИС QGIS. Сообщения об ошибках, предложения по улучшению, локализация.
Аватара пользователя
SMOuk96
Интересующийся
Сообщения: 29
Зарегистрирован: 30 июн 2017, 17:07
Репутация: 2
Откуда: Красноярск

Симметрическая разность полигонов

Сообщение SMOuk96 » 04 июн 2018, 07:24

Доброго дня уважаемые форумчане! :) Столкнулся с задачей по созданию модуля на Python для Qgis. Необходимо обойти все полигональные объекты shape-файла и применить к ним операцию симметрической разности. Пример такого shape-файла приложил
WV2_B45_20160625_C_NDVI_F165_S_Sieve_Convexhull-9.shp
(12.58 КБ) 861 скачивание
.
Нашел в qgis в модуле ftools функцию Симметрической разность, она работает с исходным слоем и слоем разности. Можно ли как-то посмотреть код данной функции, чтобы переделать ее под работу с одним слоем :?: И двигаюсь ли я в нужно направлении. Прошу вашей помощи потому что новичок в этой теме и зашел в тупик. Help me, plz :?
На данный момент сам сделал (по примерам из интернета) загрузку слоев в comboBox.

Александр Мурый
Гуру
Сообщения: 5173
Зарегистрирован: 26 сен 2009, 16:26
Репутация: 793
Ваше звание: званий не имею
Откуда: Москва

Re: Симметрическая разность полигонов

Сообщение Александр Мурый » 04 июн 2018, 10:55

Вы выложили только часть шейп-файла (сам .shp). Ещё надо как минимум .shx и .dbf.
SMOuk96 писал(а):
04 июн 2018, 07:24
Необходимо обойти все полигональные объекты shape-файла и применить к ним операцию симметрической разности
Вам нужно получить пересечения всех полигонов в одном слое? Если так, используйте модуль GRASS <v.clean> из панели инструментов ("Анализ данных"/Processing). Опция "bpol".
Редактор материалов, модератор форума

Аватара пользователя
SMOuk96
Интересующийся
Сообщения: 29
Зарегистрирован: 30 июн 2017, 17:07
Репутация: 2
Откуда: Красноярск

Re: Симметрическая разность полигонов

Сообщение SMOuk96 » 04 июн 2018, 18:56

Результат работы скрипта должен быть примерно таким (сделал вручную)
Screenshot_2.png
Screenshot_2.png (109.71 КБ) 8390 просмотров
Александр Мурый писал(а):
04 июн 2018, 10:55
Если так, используйте модуль GRASS <v.clean> из панели инструментов ("Анализ данных"/Processing). Опция "bpol".
Результат работы bpol:
Screenshot_3.png
Screenshot_3.png (50.42 КБ) 8390 просмотров
Думал он оставит только пересечения, но нет.
Александр Мурый, возможно ли получить пересечения полигонов и потом от исходного слоя отнять данное пересечение, чтобы и получить симметрическую разность?
Т. к. делаю скрипт, то вызывать команды надо оттуда, а не из интерфейса, а как вызвать Опцию "blop" модуля GRASS <v.clean>?
Возможно что-то такое? processing.runalg('qgis:blop',исходный файл,True,id,'файл для записи') ?

Александр Мурый
Гуру
Сообщения: 5173
Зарегистрирован: 26 сен 2009, 16:26
Репутация: 793
Ваше звание: званий не имею
Откуда: Москва

Re: Симметрическая разность полигонов

Сообщение Александр Мурый » 05 июн 2018, 11:25

Сделал простую модель для Processing - "Polygon self symmetrical difference". Используется алгоритм SAGA "Polygon self intersection" и извлечение по атрибутам.
Экспорт модели в Python-скрипт:

Код: Выделить всё

##Polygon self symmetrical difference=name
##poly=vector
##polygonselfsymmetricaldifference=output vector
outputs_QGISADDUNIQUEVALUEINDEXFIELD_1=processing.runalg('qgis:adduniquevalueindexfield', poly,'diff_id',None)
outputs_SAGAPOLYGONSELFINTERSECTION_1=processing.runalg('saga:polygonselfintersection', outputs_QGISADDUNIQUEVALUEINDEXFIELD_1['OUTPUT'],'diff_id',None)
outputs_QGISEXTRACTBYEXPRESSION_1=processing.runalg('qgis:extractbyexpression', outputs_SAGAPOLYGONSELFINTERSECTION_1['INTERSECT'],'"ID" not like '%|%'',polygonselfsymmetricaldifference)
Вот файл модели:
Вложения
symm_diff_self.zip
(983 байт) 343 скачивания
symm_diff_self.zip
(991 байт) 339 скачиваний
3.PNG
3.PNG (20 КБ) 8342 просмотра
2.PNG
2.PNG (16.15 КБ) 8342 просмотра
Редактор материалов, модератор форума

Аватара пользователя
rhot
Гуру
Сообщения: 1727
Зарегистрирован: 25 янв 2011, 17:50
Репутация: 194
Ваше звание: доктор
Откуда: Архангельск

Re: Симметрическая разность полигонов

Сообщение rhot » 05 июн 2018, 11:32

Я вообще начал замечать, что SAGA работает в разы быстрее QGIS, потому что последний обрастает ненужным функционалом и плюшками.
___________(¯`·.¸(¯`·.¸ Scientia potentia est _/ {SILVA}:::{FOSS}:::{GIS} \_ Знание сила ¸.·´¯)¸.·´¯)___________

Александр Мурый
Гуру
Сообщения: 5173
Зарегистрирован: 26 сен 2009, 16:26
Репутация: 793
Ваше звание: званий не имею
Откуда: Москва

Re: Симметрическая разность полигонов

Сообщение Александр Мурый » 05 июн 2018, 12:13

rhot писал(а):
05 июн 2018, 11:32
Я вообще начал замечать, что SAGA работает в разы быстрее QGIS, потому что последний обрастает ненужным функционалом и плюшками.
Ну не знаю, алгоритм SAGA "Polygon self intersection" тупит нещадно даже на нескольких полигонах.
Редактор материалов, модератор форума

Аватара пользователя
rhot
Гуру
Сообщения: 1727
Зарегистрирован: 25 янв 2011, 17:50
Репутация: 194
Ваше звание: доктор
Откуда: Архангельск

Re: Симметрическая разность полигонов

Сообщение rhot » 05 июн 2018, 12:18

Александр Мурый писал(а):
05 июн 2018, 12:13
Ну не знаю, алгоритм SAGA "Polygon self intersection" тупит нещадно даже на нескольких полигонах.
Линукс или винда? Какая версия саги?
___________(¯`·.¸(¯`·.¸ Scientia potentia est _/ {SILVA}:::{FOSS}:::{GIS} \_ Знание сила ¸.·´¯)¸.·´¯)___________

Александр Мурый
Гуру
Сообщения: 5173
Зарегистрирован: 26 сен 2009, 16:26
Репутация: 793
Ваше звание: званий не имею
Откуда: Москва

Re: Симметрическая разность полигонов

Сообщение Александр Мурый » 05 июн 2018, 12:35

rhot писал(а):
05 июн 2018, 12:18
Линукс или винда? Какая версия саги?
В линуксах 2.3.1, в виндах 2.3.2, и везде проблемы с Сагой. Модель делалась на винде, работает нормально только там пока.
Редактор материалов, модератор форума

Аватара пользователя
rhot
Гуру
Сообщения: 1727
Зарегистрирован: 25 янв 2011, 17:50
Репутация: 194
Ваше звание: доктор
Откуда: Архангельск

Re: Симметрическая разность полигонов

Сообщение rhot » 05 июн 2018, 13:46

Александр Мурый писал(а):
05 июн 2018, 12:35
везде проблемы с Сагой. Модель делалась на винде, работает нормально только там пока.
Хмм,.. выложите, пожалуйста, вектор потестить.
___________(¯`·.¸(¯`·.¸ Scientia potentia est _/ {SILVA}:::{FOSS}:::{GIS} \_ Знание сила ¸.·´¯)¸.·´¯)___________

Dmitry Stasev
Участник
Сообщения: 67
Зарегистрирован: 13 мар 2018, 08:59
Репутация: 22
Откуда: MO

Re: Симметрическая разность полигонов

Сообщение Dmitry Stasev » 05 июн 2018, 14:07

SMOuk96 писал(а):
04 июн 2018, 18:56
возможно ли получить пересечения полигонов и потом от исходного слоя отнять данное пересечение, чтобы и получить симметрическую разность?
Можно сиквелами, только не уверен в стабильности на больших объемах

Вот попробовал:

Код: Выделить всё

With CTE AS(
	SELECT '1' AS grp, st_union(st_intersection(a.geometry, b.geometry)) as geometry 
	FROM test a JOIN test b ON (
		(a.id < b.id)and
		(a.geometry is NOT NULL)and
		(b.geometry is NOT NULL)and
		(st_intersects(a.geometry, b.geometry))
	) 
	GROUP BY grp
) 
SELECT st_difference(test.geometry, CTE.geometry) FROM test
JOIN CTE 
1. Тут сам слой - "test"
2. Для корректного поиска пересечений добавил поле "id" - int
3. В обобщенном выражении считаю разницу и потом вычитаю ее из всех объектов
Для экспериментов достаточно вставить SQL в виртуальный слой и поправить под себя "test" и "id"

PS
Сделал для эксперимента (захотелось попробовать одним запросом), поэтому что там с производительностью ...
Последний раз редактировалось Dmitry Stasev 05 июн 2018, 15:02, всего редактировалось 1 раз.

Александр Мурый
Гуру
Сообщения: 5173
Зарегистрирован: 26 сен 2009, 16:26
Репутация: 793
Ваше звание: званий не имею
Откуда: Москва

Re: Симметрическая разность полигонов

Сообщение Александр Мурый » 05 июн 2018, 14:55

rhot писал(а):
05 июн 2018, 13:46
Хмм,.. выложите, пожалуйста, вектор потестить.
Тестовый слой рисуется за несколько секунд в кугисе. Дело не в векторе, дело, видимо, в самом модуле Processing. Например, в линуксовой версии QGIS 2.18.* алгоритм SAGA "Polygon self intersection" не работает в принципе почему-то.
А вообще, мы отклонились от темы.
Редактор материалов, модератор форума

Dmitry Stasev
Участник
Сообщения: 67
Зарегистрирован: 13 мар 2018, 08:59
Репутация: 22
Откуда: MO

Re: Симметрическая разность полигонов

Сообщение Dmitry Stasev » 05 июн 2018, 15:03

Александр Мурый писал(а):
05 июн 2018, 14:55
Тестовый слой рисуется за несколько секунд в кугисе
Интересно как мой скриптик отработает, не посмотрите?

Александр Мурый
Гуру
Сообщения: 5173
Зарегистрирован: 26 сен 2009, 16:26
Репутация: 793
Ваше звание: званий не имею
Откуда: Москва

Re: Симметрическая разность полигонов

Сообщение Александр Мурый » 05 июн 2018, 16:15

Dmitry Stasev писал(а):
05 июн 2018, 15:03
Интересно как мой скриптик отработает, не посмотрите?
На виртуальном слое, сделанном на базе memory-слоя, не взлетело. Не понимает поле "id".
Редактор материалов, модератор форума

Dmitry Stasev
Участник
Сообщения: 67
Зарегистрирован: 13 мар 2018, 08:59
Репутация: 22
Откуда: MO

Re: Симметрическая разность полигонов

Сообщение Dmitry Stasev » 05 июн 2018, 16:29

Александр Мурый писал(а):
05 июн 2018, 16:15
Не понимает поле "id"
конечно я же выше писал, что надо добавить или поменять на свое.
Вот этот python - скрипт должен сам все сделать )
Сделает "SelfSymDifference" слой из активного

Код: Выделить всё

from qgis.PyQt.QtCore import *

srcLayer = iface.activeLayer()
dstLayerName = 'SelfSymDifference'
idName = 'idSelfSymDifference'
srcLayer.startEditing()
myField = QgsField(idName, QVariant.Int )
srcLayer.addAttribute( myField )
srcLayer.updateFields()

idx = srcLayer.fieldNameIndex(idName)
i = 0
for f in srcLayer.getFeatures():
    f[idx] = i
    i += 1
    srcLayer.updateFeature( f )
srcLayer.commitChanges()

tpl = '''
With CTE AS(
    SELECT '1' AS grp, st_union(st_intersection(a.geometry, b.geometry)) as geometry 
    FROM %s a JOIN test b ON (
        (a.%s < b.%s)and
        (a.geometry is NOT NULL)and
        (b.geometry is NOT NULL)and
        (st_intersects(a.geometry, b.geometry))
    ) 
    GROUP BY grp
) 
SELECT st_difference(test.geometry, CTE.geometry) FROM %s
JOIN CTE'''

sql = tpl % (srcLayer.name(), idName, idName, srcLayer.name())

layer = QgsVectorLayer("?query="+sql, dstLayerName, "virtual")
QgsMapLayerRegistry.instance().addMapLayer(layer, True)
ЗЫ
без проверок на валидность и типы слоев.

Аватара пользователя
SMOuk96
Интересующийся
Сообщения: 29
Зарегистрирован: 30 июн 2017, 17:07
Репутация: 2
Откуда: Красноярск

Re: Симметрическая разность полигонов

Сообщение SMOuk96 » 05 июн 2018, 18:37

Александр Мурый писал(а):
05 июн 2018, 11:25
Сделал простую модель для Processing - "Polygon self symmetrical difference". Используется алгоритм SAGA "Polygon self intersection" и извлечение по атрибутам.
Запускаю ваш скрипт, но к сожалению у меня почему-то нет второго алгоритма SAGAовского, версия QGIS 2.18.9
1.png
1.png (13.11 КБ) 8238 просмотров
Александр Мурый писал(а):
05 июн 2018, 11:25
Вот файл модели:
Впервые сталкиваюсь с таким, попробовал открыть в QT Creator, но особо не понял что куда. Не посоветуете что-то почитать чтобы понимать хотя бы что за файл с расширение .model или как-то "на пальцах"..

Ответить

Вернуться в «QGIS»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 3 гостя