Как получить ближайшую точку на линейной линии к данной точке?

28

Я давно использую PostGIS, но никогда не использовал LINESTRINGгеометрию ...! :)

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

Решение, которое я нашел, состоит в том, чтобы выбрать все линии линий в моей точке, используя expand()метод, и определить расстояние между каждой строкой и моей точкой, используя ST_Distance()метод.

Вот SQL:

SELECT myLineId, myLineName, ST_Distance(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395),myLineGeom) AS myLineDistance
FROM myLines
WHERE myLineGeom && expand(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395), 100)
ORDER BY myLineDistance;

Результаты, которые я получаю, выглядят нормально, но я чувствую, что что-то не так в моей реализации.

1) Вы, ребята, думаете, что expand()можете получить все заинтересованные строки?

2) Ребята, вы считаете, что ST_Distance()это правильный метод? Думаю, я делаю это неправильно, поскольку расстояние, которое я хотел бы получить, - это наименьшее расстояние между точкой и моей линией, а не расстояние между точкой и одной из точек линейной линии.

Иллюстрация:

альтернативный текст

Виви
источник

Ответы:

11

Объявление 1) Глядя на документацию по вашим используемым функциям, я бы сказал: «Да, все соответствующие строки будут найдены».

развернуть (геометрия, поплавок)

Эта функция возвращает ограничивающий прямоугольник, развернутый во всех направлениях из ограничивающего прямоугольника входной геометрии, на величину, указанную во втором аргументе. Очень полезно для запросов расстояния (), чтобы добавить к запросу фильтр индекса.

A && B

Оператор "&&" является оператором "перекрытия". Если ограничивающий прямоугольник A перекрывает ограничивающий прямоугольник B, оператор возвращает true.

объявление 2) Вы должны быть в состоянии достичь того, что вы хотите с помощью:

line_interpolate_point(linestring, line_locate_point(LineString, Point))

line_interpolate_point (строка строки, местоположение)

Интерполирует точку вдоль линии. Первый аргумент должен быть LINESTRING. Второй аргумент - это число с плавающей запятой между 0 и 1, представляющее долю от общей длины 2d, в которой должна быть расположена точка.

line_locate_point (LineString, Point)

Возвращает число с плавающей точкой от 0 до 1, представляющее местоположение ближайшей точки на LineString к данной точке, в виде доли от общей длины 2d линии. Вы можете использовать возвращенное местоположение, чтобы извлечь точку (line_interpolate_point)

Источник: http://main.merlin.com.ua/doc/postgis/docs/ch06.html

Подземье
источник
Для пункта 2) мне просто интересно, дает ли ST_Distance между геометрией POINT и геометрией LINESTRING наименьшее возможное расстояние между тезисами (то есть, длину перпендикулярной линии между POINT и LINGESTRING); я хочу расстояние от каждой геометрии линии :)
Vivi
И я думаю, это не то расстояние, которое я ищу, так как «функция line_locate_point дает вам значение от 0 до 1, представляющее местоположение ближайшей точки на LineString к данной точке»: /
Vivi
Боюсь, вы потеряли меня в своем последнем комментарии. Теперь я больше не уверен, чего ты хочешь;)
Подземье
1
Извините :) Мне бы хотелось: дать геометрию LINESTRING (представляющую путь) и геометрию POINT, я хочу иметь ближайшую геометрию POINT, которая находится на пути (которая может не являться точкой определения геометрии LINESTRING). Это понятно? Может быть, я должен обновить свой пост с рисунком: D
Виви
Я не могу обновить свое сообщение, поэтому вот ссылка на рисунок того, что я хотел бы получить: i.imgur.com/UwPxo.jpg
Виви
7

алло

Сначала вопрос о том, что возвращает ST_Distance. ST_Distance возвращает кратчайшее расстояние между линией и точкой (или какие типы геометрии вводятся). Это означает, что ST_Distance между точкой (1 3) и линией строк (0 0,0 10) вернется 1. Расстояние не будет измерено между точка и (0 0) или точка и (0 10), но из точки (1 3) в (0 3).

Итак, насколько я понимаю, ST_Distance дает вам ответ, который вы хотите.

Если вы хотите найти точку (0 3) в приведенном выше примере, вы можете использовать ST_Closestpoint, если у вас есть PostGIS 1.5. Для моего примера вы используете его следующим образом: ST_Closestpoint ('LINESTRING (0 0,0 10)' :: geometry, ' ТОЧКА (1 3) ':: geometry) тогда вы должны получить взамен точку (0 3), точку на линии, которая ближе всего к вашей точке.

HTH Никлас

Никлас Авен
источник
5

Я нашел это :) (Ну, я думаю: P)

С помощью ST_Line_Locate_Point()и ST_Line_Interpolate_point()мне удалось получить точку, которая НЕ является частью определения LINESTRING, но находится на указанной линии :) Все, что мне нужно сделать, это получить расстояние от моей точки до этой точки, и все готово.

SELECT AsText(ST_Line_Interpolate_Point(myLineGeom,ST_Line_Locate_Point(myLineGeom,ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395))))
FROM myLines
WHERE myGeom && expand(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395), 100)

ST_Line_Locate_Point()Способ найти местоположение ближайшей точки на линии в данной точке, то ST_Line_Interpolate_Pointспособ превратить это место в точку.

Виви
источник
1
St_distance между точкой и линией даст вам тот же ответ. Почему вы думаете, что вы должны сделать это таким образом?
Никлас Авен
1
Я думаю, что ST_Distance можно использовать с любым типом геометрии. postgis.refractions.net/docs/ST_Distance.html :ST_Distance(geometry g1, geometry g2)
Magno C
2

Эта ветка архивов Postgis может ответить вам http://postgis.refractions.net/pipermail/postgis-users/2007-June/016045.html

ThomasG77
источник
refractions.net не работает для меня: "срок действия refractions.net истек 14.09.2010 и ожидает обновления или удаления".
Подземье
@underdark это работает для меня
Дассуки
@dassouki: это странно: |
Подземье
@underdark refractions.net снова работает
ThomasG77