Река-притоки
-
- Новоприбывший
- Сообщения: 7
- Зарегистрирован: 13 май 2013, 18:45
- Репутация: 3
Река-притоки
Здравствуйте.
Есть линейный слой гидрография (шейп). Нужно для реки найти все притоки и притоки притоков ...
Первое, что пришло в голову: пространственный выбор "касание", который с каждым разом добавляет притоки. Работает медленно.
Может есть что более быстрое? Сетевой анализ, например. Но не пойму, как от построенного графа перейти к моей реке и ее притокам.
Есть линейный слой гидрография (шейп). Нужно для реки найти все притоки и притоки притоков ...
Первое, что пришло в голову: пространственный выбор "касание", который с каждым разом добавляет притоки. Работает медленно.
Может есть что более быстрое? Сетевой анализ, например. Но не пойму, как от построенного графа перейти к моей реке и ее притокам.
-
- Гуру
- Сообщения: 5173
- Зарегистрирован: 26 сен 2009, 16:26
- Репутация: 792
- Ваше звание: званий не имею
- Откуда: Москва
Re: Река-притоки
Если есть ЦМР, то логичнее всего построить бассейн и потом выделить все реки, которые внутри.
Редактор материалов, модератор форума
-
- Гуру
- Сообщения: 5354
- Зарегистрирован: 09 апр 2010, 19:30
- Репутация: 1021
- Ваше звание: просто мимо прохожу
- Откуда: Ё-бург
-
- Гуру
- Сообщения: 5173
- Зарегистрирован: 26 сен 2009, 16:26
- Репутация: 792
- Ваше звание: званий не имею
- Откуда: Москва
Re: Река-притоки
Есть такой вариант:
— строим буферные зоны фиксированной ширины по всем рекам (обязательно с объединением буферов);
— разбиваем составные объекты (буферы получаются мультиполигоном, а нужен набор полигонов);
— выделяем буферную зону нужной реки и делаем "извлечь по пространственному положению"; выбрать из слоя с реками, слой пересечения — буферные зоны, "находится внутри".
— строим буферные зоны фиксированной ширины по всем рекам (обязательно с объединением буферов);
— разбиваем составные объекты (буферы получаются мультиполигоном, а нужен набор полигонов);
— выделяем буферную зону нужной реки и делаем "извлечь по пространственному положению"; выбрать из слоя с реками, слой пересечения — буферные зоны, "находится внутри".
Редактор материалов, модератор форума
-
- Участник
- Сообщения: 51
- Зарегистрирован: 01 июл 2015, 17:46
- Репутация: 37
- Откуда: Черкассы
- Контактная информация:
Re: Река-притоки
Написал скрипт, но он выделяет только притоки первого порядка. Функцию нужно сделать рекурсивной, но у меня не получается. Возможно, кто-то доработает:
Update 0:
В таком виде запускается бесконечная рекурсия, которая все же остановится через пару тысяч итераций (у меня QGIS зависает на 2-3 минуты). Цель достигнута (все притоки выделены), но способ так себе. Попробую довести до ума.
Код: Выделить всё
def inflower(a):
for selected in a:
for feature in layer.getFeatures():
if feature.geometry().intersects(selected.geometry().boundingBox()):
inflow.append(feature.id())
layer.select(inflow)
inflow = []
layer = iface.activeLayer()
selection = layer.selectedFeatures()
inflower(selection)
Update 0:
В таком виде запускается бесконечная рекурсия, которая все же остановится через пару тысяч итераций (у меня QGIS зависает на 2-3 минуты). Цель достигнута (все притоки выделены), но способ так себе. Попробую довести до ума.
Код: Выделить всё
inflow = []
def inflower():
layer = iface.activeLayer()
selection = layer.selectedFeatures()
for selected in selection:
for feature in layer.getFeatures():
if feature.geometry().intersects(selected.geometry().boundingBox()):
inflow.append(feature.id())
layer.select(inflow)
inflower()
inflower()
-
- Новоприбывший
- Сообщения: 7
- Зарегистрирован: 13 май 2013, 18:45
- Репутация: 3
Re: Река-притоки
Я тоже написал подобный скрипт. Но работает крайне медленно. Быстрее получается при использовании алгоритмов геообработки:Elf писал(а): В таком виде запускается бесконечная рекурсия, которая все же остановится через пару тысяч итераций (у меня QGIS зависает на 2-3 минуты). Цель достигнута (все притоки выделены), но способ так себе. Попробую довести до ума.
Код: Выделить всё
# coding: utf8
import processing
n1=1
layer = iface.activeLayer()
while True:
riv=processing.runalg('qgis:saveselectedfeatures', layer, None)
processing.runalg('qgis:selectbylocation', layer, riv['OUTPUT_LAYER'], ['touches'] ,1)
fs=layer.selectedFeatures()
print u'Выделено объектов:', len(fs)
n2=len(fs)
if n2==n1:
break
n1=n2
Скрипт выделяет все притоки любого порядка.
-
- Гуру
- Сообщения: 5173
- Зарегистрирован: 26 сен 2009, 16:26
- Репутация: 792
- Ваше звание: званий не имею
- Откуда: Москва
Re: Река-притоки
Скрипт, написанный *sergiks*, работает лучше, если сначала прогнать слой рек через модуль GRASS <v.clean> с параметром "break" с небольшим произвольным порогом (threshold). Затем уже в полученном слое выделяем любой приток (вне зависимости от порядка) из интересующей нас реки и запускаем скрипт; выделяются вся река с притоками.
Основное и очевидное условие: все линии должны соприкасаться друг с другом.
Основное и очевидное условие: все линии должны соприкасаться друг с другом.
Редактор материалов, модератор форума
-
- Участник
- Сообщения: 51
- Зарегистрирован: 01 июл 2015, 17:46
- Репутация: 37
- Откуда: Черкассы
- Контактная информация:
Re: Река-притоки
Незавершенный скрипт не давал мне покоя. После консультации с ГИС-специалистом все же удалось довести дело до конца.
Код: Выделить всё
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Cкрипт выделяет притоки всех порядков выделенной реки.
The script selects all inflows of selected river.
Недостаток: другая река или приток другой реки также будут выделены, если они
находятся слишком близко (пересекают минимальный прямоугольник, в который
вписана изначально выделенная река и (или) ее приток).
'''
from qgis.core import *
from qgis.utils import *
layer = iface.activeLayer()
geom_ids = []
def inflower(line, set):
for item in set.copy():
if item.geometry().intersects(line.geometry().boundingBox()):
geom_ids.append(item.id())
set.remove(item)
inflower(item, set)
layer.select(geom_ids)
for selected in layer.selectedFeatures():
river = selected
features = set()
for feature in layer.getFeatures():
if river.id() != feature.id():
features.add(feature)
inflower(river, features)
features.clear()
geom_ids = []
-
- Новоприбывший
- Сообщения: 7
- Зарегистрирован: 13 май 2013, 18:45
- Репутация: 3
Re: Река-притоки
А если проверять не пересечение с прямоугольником, а само касание, т.е. вместоElf писал(а):Недостаток: другая река или приток другой реки также будут выделены, если они
находятся слишком близко (пересекают минимальный прямоугольник, в который
вписана изначально выделенная река и (или) ее приток).
Код: Выделить всё
if item.geometry().intersects(line.geometry().boundingBox()):
использовать:
Код: Выделить всё
if item.geometry().touches(line.geometry()):
-
- Участник
- Сообщения: 51
- Зарегистрирован: 01 июл 2015, 17:46
- Репутация: 37
- Откуда: Черкассы
- Контактная информация:
Re: Река-притоки
Пробовал и так. Почему-то ничего не выделялось.
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 3 гостя