Создание точек на стыке линий

Вопросы по свободной ГИС QGIS. Сообщения об ошибках, предложения по улучшению, локализация.
Ответить
KartaBY
Активный участник
Сообщения: 101
Зарегистрирован: 16 июл 2011, 09:15
Репутация: 6

Создание точек на стыке линий

Сообщение KartaBY » 27 мар 2013, 14:28

Добрый день.
Перерыл форум, вики, но так и не смог решить вроде не сложную задачу.

Есть линейный слой графа дорог.
Граф состоит из непересекающихся отрезков.
ScreenShot029.jpg
то что смог сделать ((
ScreenShot029.jpg (18.74 КБ) 6305 просмотров
Задача.
В местах соединения отрезков и на свободных концах расставить точки средствами QGIS. (штатными средствами получилось расставить точки на все узлы линий и в местах соединений получились по 2-3-4 точки, что меня не устраивает)
Подзадача.
Точки раскрасить исходя из количества отрезков соединяющихся в точке. (синяя - конец отрезка, белая - два отрезка, желтая - три отрезка, зеленая - четыре отрезка и т.д.)
Подзадача.
Связать оба слоя таким образом, что бы при перетаскивании узла соединяющихся отрезков перетаскивалась бы и точка (если такое возможно).

Аватара пользователя
SS_Rebelious
Гуру
Сообщения: 1304
Зарегистрирован: 24 фев 2009, 16:51
Репутация: 99
Ваше звание: GIS pro-fan
Откуда: Lahti / Газ-ПУТИНбург
Контактная информация:

Re: Создание точек на стыке линий

Сообщение SS_Rebelious » 27 мар 2013, 20:31

Думается, это можно осуществить только программированием. Например используя Python можно поступить следующим образом:
1) извлекаем из геометрий линейного слоя значения координат (причём именно значения координат, а не объекты QgsPoint, так как они не подходят в качестве ключей к словарям), занося в словарь { (x,y): [N, M] }, где (x,y) - кортеж координат точки, N - количество линий, заканчивающихся (или начинающихся) в данной точке (0 - по умолчанию), M - общее количество точек с данными координатами (количество линий, пересекающихся в данной точке) 0 - по умолчанию:
а) проверяем, есть ли данный кортеж координат в нашем словаре, если нет, то заносим кортеж в качестве ключа в словарь, увеличивая M на 1. При этом, если точка, чьи координаты были только что извлечены находилась в начале или конце списка данной геометрии (то есть в начале или конце линии), то значение N увеличиваем на 1.
б) Ели кортеж уже есть в словаре - апдейтим значения M и N.

2) формируем пустой точечный слой с атрибутом - количество отрезков в точке и заносим туда данные из словаря:
а) превращаем кортеж координат в объект QgsPoint и добавляем его в слой, а в качестве атрибута заносим значение ( (M - N)*2 + N )

Надо ещё подумать, будет ли данный алгоритм справедлив для случаев с самопересекающимися и замкнутыми линиями (вроде бы это обстоятельство никак не повлияет).

Как редактировать оба слоя одновременно представить сложно. Мне в глову лезет только всякий изврат с занесением обоих слоёв в базу, созданием таблицы, где в одной колонке будут неуникальные геометрии из слоя с линиями, а в другой - ID из таблицы точек. Таким образом в ней одной геометрии из таблицы с линиями будет соответствовать N записей, содержащих ID точек, соответствующих данной геометрии. Имея эти таблицы теоретически можно сделать триггер, при котором при перемещении узла линии перезаписывалась бы геометрия соответствующих точек. Но в этом случае нельзя редактировать сразу много всего - полезут ошибки.

Наверное, тут больше подойдёт допиливание интерфейса редактирования QGIS под свои нужды посредством создания своего модуля параллельного редактирования двух слоёв: при выделении редактируемого узла его координты сравнивать с координатами из точечного слоя, чтобы найти соответствующую точку и потом применить к ней те же операции, которые были применены к узлу.
Look for something long enough, and you will find it. Look for something without understanding, and it will find you...
"All paid jobs absorb and degrade the mind." Aristotle
If you take 1 step towards freedom it'll take 2 steps towards you!

KartaBY
Активный участник
Сообщения: 101
Зарегистрирован: 16 июл 2011, 09:15
Репутация: 6

Re: Создание точек на стыке линий

Сообщение KartaBY » 28 мар 2013, 10:02

Спасибо за обстоятельный ответ.
Язык Питон наверное всем хорош, но я его не знаю. :cry:

После прочтения всего сказанного, у меня зародилась такая мысль (алгоритм действий без Питона):
1. Извлекаем точки в узлах линий (инструмент: "Извлечение узлов")
2. Извлекаем координаты точек (инструмент: "Экспортировать/добавить поле геометрии")
3. Сравнить координаты всех точек и в точках со совпадающими координатами проставить в доп. поле количество совпадений. Количество совпадений будет равно количеству соединяющихся линий.(тут у меня затык. как это записать в калькуляторе полей?)
4. Удалить дубликаты точек (не знаю каким инструментом)
5. Удалить точки которые не находятся на краях линии (не знаю каким инструментом).

P.s. Я любитель. так что сильно ногами не пинайте.
P.s.s. Данная задача придумана мной попрактиковаться в применении инструментов и просто потому, что мне интересно. Практического применения она не имеет (пока не имеет).

HasT
Активный участник
Сообщения: 142
Зарегистрирован: 16 окт 2009, 22:08
Репутация: 55
Откуда: Харьков

Re: Создание точек на стыке линий

Сообщение HasT » 30 мар 2013, 21:21

KartaBY писал(а):4. Удалить дубликаты точек (не знаю каким инструментом)
В плагине mmqgis (http://plugins.qgis.org/plugins/mmqgis/) есть инструмент удаления дублирующейся геометрии (MMQGIS-Modify-Delete Duplicate Geometries) или в SEXTANTE (http://plugins.qgis.org/plugins/sextante/) - QGIS geoalgoritms - Vector general tools - Delete Duplicate Geometries.
Предложу следующий алгоритм поиска:
1. извлечь точки в узлах линий (Вектор - Обработка геометрии - Извлечение узлов)
2. удаляем дублирующуюся геометрию в точечном слое (MMQGIS-Modify-Delete Duplicate Geometries)
3. строим буферные зоны для точечного слоя без дублирующейся геометрии (Вектор - Геообработка - Буферные зоны)
4. считаем количество геометрии точечного слоя (пункт 1) в полигонах (пункт 3) Вектор - Анализ - Количество точек в полигонах: 2 точки - две линии на пересечении, 3 - три...; 1 - вершина линии или начальный/кончный узел линии, что не подходит...
5. присваиваем атрибуты из полигонального слоя для слоя из пункта 2 и раскрашиваем точки в соответствии с значениями в таблиуе атрибутов
Для пункта 1 возможно в QGIS есть инструмент извлечения только начальной и конечной вершины объектов линейного слоя (как в gvSIG: в SEXTANTE - Topology - Extract endpoints of lines), что избавит от 'лишних' вершин.

gis.stackexchange.com/questions/31589/find-pseudo-nodes-in-free-gis-software - решение для поиска псевдо-нодов (вершины, в которых пересекаются две линии) в PostGIS/PostgreSQL
KartaBY писал(а):Точки раскрасить исходя из количества отрезков соединяющихся в точке. (синяя - конец отрезка, белая - два отрезка, желтая - три отрезка, зеленая - четыре отрезка и т.д.)
После запроса

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

CREATE VIEW vw_joinnodes_full AS
  SELECT b.*, j.ncolors
  FROM cache_joinnodes j INNER JOIN cache_bounds b 
       ON j.gid=b.gid;
будет создан точечный слой с количеством линий в таблице атрибутов.
KartaBY писал(а): 5. Удалить точки которые не находятся на краях линии (не знаю каким инструментом).
Точки, которые находятся на краях линии (dangling nodes) можно получить в gvSIG (создаем топологию, выбираем правило All line geometries of A must be free of dangling nodes, запускаем процесс создания слоя топологии и экспортируем получившийся слой dangling nodes в шейп-файл)

Ответить

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

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

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