Отредактировано:
Я хочу проиллюстрировать свой вопрос. Предположим, что вы находитесь в «Точке A» и хотите перейти в «Точку B». Эти точки не будут в таблице "at_2po_4pgr", потому что они не являются узлами источника / цели. Затем я бы искал ближайший узел для точек A и B (зеленые точки). После этого я мог бы выполнить вызов shorttest_path с использованием идентификаторов зеленых точек и получить «оранжевый» путь. Но для получения реальной стоимости пути (расстояния) в первом случае мне нужно вычесть «offsetA», а во втором случае добавить «offset B». Чтобы вычислить расстояние между красными и зелеными точками, я запускаю следующий запрос:
SELECT * FROM st_distance(
ST_GeomFromText('POINT(-3.6963314 42.3498066)',4326),
ST_GeomFromText('POINT(-3.6954276 42.3479634)',4326))
,
Как бы я знал, когда добавить или вычесть смещение?
Извините за мой английский!
источник
Ответы:
Я не думаю, что вы можете положиться на ближайшую вершину. Представьте, что источник и цель расположены на одном ребре близко к одной и той же вершине.
Вы бы предпочли три! разные случаи:
источник
Вы можете найти такую функцию здесь: https://github.com/pgRouting/pgrouting-contrib/blob/master/wrapper/routing_core_smart.sql#L69
Он ищет ближайшую ссылку в сети, что обычно дает лучший результат. Если вы используете Shooting Star, вы можете начать маршрутизацию от / до этой ссылки. Для A * или Dijkstra вы либо выбираете начальную или конечную точку ссылки, либо создаете «виртуальный» узел, разделяя ссылку на две части.
источник
Я собираюсь объяснить решение, которое я нашел (возможно, не лучший).
Согласно сообщению изображения, давайте предположим , что мы находимся в точке А , и мы будем идти к точке B . Как я объяснил выше, эти точки не вершины (источник / цели в таблице, сгенерированной с помощью инструмента osm2po).
В связи с этим нам нужно знать направление ходьбы / вождения. Если мы пойдем из ближайшей вершины в точку A (зеленая точка) по оранжевому пути, нам придется вычесть смещение между точкой A и зеленой точкой (ближайшая вершина). Но если нам нужно было пройти через улицу Calle Almirante Bonifaz , то мы должны добавить смещение к длине этого края (от зеленой точки до пересечения между Calle Almirante Bonifaz и Calle San Juan ).
Я запускаю следующий запрос, чтобы получить кратчайший путь (вам нужно расширение pgRouting, описанное здесь pgRouting - установка и требования здесь установка и требования ):
Это приводит к набору ребер, которые представляют полный маршрут. Например, одним из возможных выходных данных для этого запроса может быть:
Где поле gid ( идентификатор в сгенерированной таблице osm2po) представляет идентификатор края. Что ж, мы должны проверить смещения в начале и в конце (точки A / B).
Если мы проверяем начало смещения, мы должны проверить , если первый край множества ребер , полученных в приведенном выше запрос одно и то же до ближайшего пути к точке A . Если они совпадают, мы вычтем смещение. Если они не совпадают, мы добавим смещение. Чтобы получить ближайшую ссылку на точку, я запускаю следующий запрос:
Вы должны адаптировать эту функцию так, чтобы она возвращала ближайшее ребро. Сначала вы должны изменить тип link_point (добавить поле near_link ):
Вы также должны изменить find_node_by_nearest_link_within_distance . Просто добавьте последнюю строку (я только показываю выдержку из функции):
Затем вам нужно знать, каково расстояние между точкой ( точка A / точка B ) и ближайшим краем (смещение). Для этого я запускаю этот запрос:
Где геом это the_geom поле в osm2po сгенерированной таблицы.
На этом этапе у нас будет смещение, чтобы добавить или вычесть.
Наконец, вам нужно знать длину края, чтобы применить значение, полученное в запросе выше, и откорректировать действительное (если вы работаете с типом геометрии, вам придется нормализовать полученное значение в метрах. Просто умножьте 111000 на длину, полученную в запрос):
Если бы мы проверили конечное смещение, то нам нужно было бы проверить, совпадает ли последний путь из набора путей, полученных в вышеупомянутом запросе, с ближайшим путем к конечной точке ( точка B ), и мы добавили бы / вычли в так же, как и раньше.
Извините за мой английский.
источник
В pgrouting pgr_trsp - Кратчайший путь ограничения поворота (TRSP) делает именно то, что вы ищете.
Вместо указания исходного и целевого узлов вы можете указать исходные и целевые ребра, а также дробь вдоль ребра, где находятся ваш источник и пункт назначения.
(Вы можете использовать ST_Line_Locate_Point, чтобы получить эту дробь из вашей точечной геометрии, предполагая, что вы знаете ближайший край.)
См. Http://docs.pgrouting.org/2.0/en/src/trsp/doc/index.html#trsp.
источник