Страница 1 из 1

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

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

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

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

Добавлено: 27 мар 2013, 20:31
SS_Rebelious
Думается, это можно осуществить только программированием. Например используя 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 под свои нужды посредством создания своего модуля параллельного редактирования двух слоёв: при выделении редактируемого узла его координты сравнивать с координатами из точечного слоя, чтобы найти соответствующую точку и потом применить к ней те же операции, которые были применены к узлу.

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

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

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

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

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

Добавлено: 30 мар 2013, 21:21
HasT
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 в шейп-файл)