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

Ближайшие объекты

Добавлено: 06 окт 2022, 08:06
zubenko1592
Здравствуйте!
Появилась необходимости перейти на qgis.

До этого работал в Арке.

Столкнулся с рядом проблем.

Была стандартная задача:
есть точечный слой и линейный.
точки в точечном слое расположены в доль полилиний с минимальными смещениями.

нужно получить для каждой из точек FID ближайшей полилинии, координаты ближайшего места на полилинии и ближайшее расстояние до полилинии.

В арке это не вызывало абсолютно никаких проблем. Делалось все чуть ли не в 2 клика...

Но в Qgis... в панели анализа такой функци я не нашел. максимально похожее что я нашел в Q - это v.distance в grass.

работает она ужасно...:

1) у меня структура каталогов (сложилась за долгие года работы) имеет в названиях кирилицу... пути с кирилицей сразу ошибка... попробовал создать в корне диска папку с названием латиницей.Вродебы ошибка исчезла, но...

2) в журнале хода выполнения начали появляться милион других ошибок...

3) делается все ооооочнь долго. около 400 точек обрабатывалось минут 20...

4) по итогу v.distance выдал список ОТДЕЛЬНЫХ шейпов для каждой из точек. При этом выдал ошибку их создания.... он для каждой точки стоздает свой слой?????

5) в самой опции v.distance нужно выбирать соответсвующее количество полей 'upload'. Без этого функция вообще не запускается...



По итогу потратил кучу времени, танцев с бубном и ничего в результате не получилось....



Как решать эту задачу в Qшке?? не уже-ли она на стольно топорная??

Re: Ближайшие объекты

Добавлено: 06 окт 2022, 08:32
zubenko1592
нашел модуль NNJoin

он быстро и без проблем выдает расстояния до ближайших объектов. только не выдает ближайшие координаты ближайшего объекта. а это тоже нужно

Поэтому проблема решилась только частично.

Есть ли полное решение?

Re: Ближайшие объекты

Добавлено: 06 окт 2022, 12:46
AlexRomantsov
zubenko1592 писал(а): 06 окт 2022, 08:32Есть ли полное решение?
Давайте по шагам двигаться.
Ваш слой точек, открываете таблицу атрибутов, и в ней ищете кнопку "Калькулятор полей".
Этот метод работает в текущем слое, без создания его новых реплик, что бывает удобно.
Итак, в калькуляторе полей пишите выражение:
to_int( array_to_string( overlay_nearest( 'ваш_слой_с_линиями', id_l)))
где overlay_nearest вернет значение поля id_L ближайшего к текущей точке линейного объекта в слое 'ваш_слой_с_линиями' в виде массива, array_to_string - преобразует массив в текст, а to_int - попробует преобразовать текст в целое число.
Там же, в диалоге, говорите "Новое поле" (как вариант - Обновить существующее), даете ему название, тип.
Поиск ближнего1.JPG
Поиск ближнего1.JPG (50.02 КБ) 3770 просмотров
После Ок в таблице точек появится новое поле, в котором Id_L ближайшего линейного объекта у всех (или выбранных) записей.

Re: Ближайшие объекты

Добавлено: 06 окт 2022, 12:54
AlexRomantsov
Похожим образом, в другие поля можно собрать инфу о дистанциях и координатах. Здесь времени пока нет посмотреть, как, попробуйте сами, например покопайте функции shortest_line(geometry1,geometry2), distance(geometry1,geometry2), closest_point(geometry1,geometry2).

Re: Ближайшие объекты

Добавлено: 06 окт 2022, 12:59
AlexRomantsov
Подобные выражения также прикручиваются к Формам полей (Свойства слоя), для целей автоматизированного заполнения атрибутов из значений других объектов, например при создании новой точки можно сразу подставить в нужное поле ID (или Name, любое поле) из ближайшей к точке линии.

Re: Ближайшие объекты

Добавлено: 06 окт 2022, 19:22
zubenko1592
AlexRomantsov писал(а): 06 окт 2022, 12:46to_int( array_to_string( overlay_nearest( 'ваш_слой_с_линиями', id_l)))
работает!

Re: Ближайшие объекты

Добавлено: 07 окт 2022, 06:24
AlexRomantsov
Отлично. Теперь следующий шаг. Также, Таблица атрибутов точечного слоя, Калькулятор полей, Новое поле, в выражении ищем кратчайшую дистанцию от текущей точки до ближайшего линейного объекта в другом слое:
Дистанция до ближнего:
distance( $geometry, geometry( get_feature( 'ваш_слой_с_линиями', 'id_l', "id_Line" ) ) )

где distance - собственно функция, в которой
$geometry - очередной (в таблице) точечный объект,
geometry( get_feature - функция получения геометрии объекта из другого слоя при условии что id_l другого слоя равен найденному выше значению из поля (в точках) id_Line

Или в сочетании с предыдущим запросом, при котором не используем ранее найденный в таблицу Id линии:
distance( $geometry, geometry( get_feature( 'ваш_слой_с_линиями', 'id_l', to_int( array_to_string( overlay_nearest( 'ваш_слой_с_линиями', id_l))) )))

где to_int( array_to_string( overlay_nearest из предыдущего примера.

Внимание! Полученные значения дистанций зависят от настроек эллипсоида для вычисления расстояний. Проверьте Меню - Проект - Свойства, вкладка Общие, Измерения, Элдипсоид для вычислений. Корректно WGS84 (EPSG:7030), иногда Krassowsky.

Re: Ближайшие объекты

Добавлено: 07 окт 2022, 06:31
AlexRomantsov
Ну и последнее, третье желание :):
zubenko1592 писал(а): 06 окт 2022, 08:06координаты ближайшего места на полилинии
Координаты в каком виде вы хотели бы получить? В WKT, типа текста Point(123.456, 789.123)? Или отдельно x, отдельно y? Нужен ли пересчет в другие СК?

Re: Ближайшие объекты

Добавлено: 13 окт 2022, 23:17
zubenko1592
AlexRomantsov писал(а): 07 окт 2022, 06:31Координаты в каком виде вы хотели бы получить? В WKT, типа текста Point(123.456, 789.123)? Или отдельно x, отдельно y? Нужен ли пересчет в другие СК?
Желательно в 2х разных столбцах X и Y. В текущей СК проекта.

Re: Ближайшие объекты

Добавлено: 14 окт 2022, 04:56
AlexRomantsov
Ок, немного изменим предыдущее выражение.
Также, таблица атрибутов, калькулятор полей, новое поле Х (real), выражение:
x(closest_point( geometry( get_feature( 'ваш_слой_с_линиями', 'id_l', to_int( array_to_string( overlay_nearest( 'ваш_слой_с_линиями', id_l))) )),$geometry) )

где х - функция, извлекающая X координату из:
closest_point - функции, возвращающей точку геометрии 1, ближайшую к геометрии 2
остальные параметры в теме выше...

Повторить выражение для координаты y.

Re: Ближайшие объекты

Добавлено: 14 окт 2022, 05:04
AlexRomantsov
При необходимости, в случае если системы координат каждого из слоев и карты разные, а xy надо получить в одной из них или вообще в четвертой, добавьте в нужные места выражения функцию
transform(geometry, идентификатор исходной СК, идентификатор целевой СК),
например так transform($geometry, 'EPSG:4326', 'USER:100017')

Re: Ближайшие объекты

Добавлено: 14 окт 2022, 05:51
AlexRomantsov
И в завершении, если такие операции повседневны, можно добавить в таблицу или в карточку атрибутов кнопку с нужным действием. Настраивается в Свойствах слоя - Действия. Но для этого нужны какие то представления о Питоне.
Лайт вариант - добавить выражение в Пользовательские, тогда всегда будет под рукой шаблон.
добавить свое выражение.jpg
добавить свое выражение.jpg (40.14 КБ) 3383 просмотра

Re: Ближайшие объекты

Добавлено: 14 окт 2022, 11:29
Эдуард Казаков
Есть ещё модуль Closest Points
В нём инструмент "Find closest point for each feature". Результат - новый точечный слой ближайших точек на самой линии, в атрибутах айдишники исходных объектов и расстояние. Координаты извлекаются в калькуляторе полей или инструментом "add geometry attributes", и вместе с расстояниями присоединяются к исходным точкам через панель связи в свойствах слоя