Files
wiki/tasks/enduro-trails/BRD_PHASE3.1.md
2026-05-04 17:10:05 +03:00

17 KiB
Raw Permalink Blame History

BRD: Enduro Trails — Фаза 3.1 «Улучшение роутинга»

Версия: 1.0
Дата: 2026-05-04
Автор: Стрим 🌊
Статус: На согласовании


1. Контекст и цели

Что уже есть (Фаза 23)

  • OSRM с кастомным профилем enduro.lua — один маршрут A→B, до 5 альтернатив
  • Роутинг предпочитает грунтовки (rate=100) и избегает асфальт (rate=14)
  • Статистика покрытия: % грунт / асфальт / тропа

Проблемы

  1. Мало альтернативных маршрутов — OSRM часто даёт 12 варианта вместо 35. Пользователь видит один путь и не может сравнить
  2. Шлагбаумы не блокируют проездresult.barrier = true добавляет penalty, но маршрут всё равно идёт через шлагбаум. Эндурист не знает — открыт шлагбаум или нет
  3. Тротуары включены в роутингfootway rate=60, OSRM считает тротуары «проезжей» дорогой. В городе маршрут может пойти по тротуару — это незаконно и опасно
  4. Нет визуального предупреждения — пользователь не видит где на маршруте шлагбаумы, броды, частные территории

Цель

Сделать роутинг безопасным и разнообразным: больше вариантов на выбор, нет маршрутов через шлагбаумы и тротуары, визуальные предупреждения об препятствиях.


2. Фичи


F-07: Исключить шлагбаумы из роутинга

Описание

Дороги с шлагбаумами (gate, bollard, lift_gate), блокпостами (border_control), цепями (chain), столбиками (cycle_barrier, motorcycle_barrier) полностью исключаются из графа OSRM. Маршрут никогда не пойдёт через шлагбаум.

Зачем

Шлагбаум может быть закрыт. Эндурист приезжает — и путь заблокирован. Приходится искать объезд на месте. Лучше сразу строить маршрут без шлагбаумов.

Use Cases

UC-07.1 — Маршрут без шлагбаумов

Слава строит маршрут через лесной массив. Раньше OSRM мог провести через дорогу с шлагбаумом. Теперь маршрут обходит шлагбаум, даже если путь длиннее.

UC-07.2 — Шлагбаум на единственной дороге

Единственная дорога к точке B перекрыта шлагбаумом. OSRM не находит маршрут. Пользователь видит: «Маршрут не найден: на пути есть препятствия (шлагбаумы)».

Исключаемые типы препятствий (OSM tag barrier=*)

barrier Описание Действие
gate Ворота, шлагбаум Исключить
lift_gate Шлагбаум с подъёмником Исключить
bollard Столбик / боллард Исключить
chain Цепь Исключить
cycle_barrier Велобарьер Исключить
motorcycle_barrier Мотобарьер Исключить
border_control Блокпост Исключить
cattle_grid Коровья решётка ⚠️ Оставить (проезжая)
ford Брод ⚠️ Оставить (отдельная фича)
block Блок Исключить

Реализация

В enduro.luaprocess_node: заменить result.barrier = true на result.barrier = false + result.forward_mode = mode.inaccessible (полная блокировка ноды).

function process_node(profile, node, result)
  local barrier = node:get_value_by_key("barrier")
  if barrier == "gate" or barrier == "bollard" or barrier == "lift_gate" 
     or barrier == "chain" or barrier == "cycle_barrier" 
     or barrier == "motorcycle_barrier" or barrier == "border_control"
     or barrier == "block" then
    result.barrier = false          -- НЕ penalty, а полный запрет
    result.forward_mode = mode.inaccessible
    result.backward_mode = mode.inaccessible
  end
end

⚠️ Требуется пересборка OSRM графа (~40 мин). Это разовая операция.


F-08: Исключить тротуары из роутинга

Описание

Дороги с highway=footway, highway=pedestrian, highway=steps исключаются из графа OSRM. Маршрут не пойдёт по тротуару или пешеходной улице.

Зачем

Тротуар — не дорога для мотоцикла. В городе OSRM может провести маршрут по тротуару (rate=60 — довольно привлекательный). Это незаконно, опасно для пешеходов, и эндуристу не нужно.

Use Cases

UC-08.1 — Маршрут без тротуаров

Слава строит маршрут в черте города. Раньше OSRM мог провести по тротуару вдоль дороги. Теперь маршрут идёт только по проезжей части.

UC-08.2 — Пешеходная зона

Точка B находится на пешеходной улице. OSRM не может доехать прямо до точки — строит маршрут до ближайшей проезжей дороги.

Исключаемые типы дорог

highway Описание Действие
footway Тротуар / пешеходная дорожка Исключить из роутинга
pedestrian Пешеходная зона / улица Исключить
steps Лестница Исключить
corridor Крытый переход Исключить

Реализация

В enduro.luaprocess_way: убрать footway из highway_rate и добавить проверку:

-- Дороги, исключаемые из роутинга (тротуары и пешеходные зоны)
local excluded_highways = {
  footway = true,
  pedestrian = true,
  steps = true,
  corridor = true,
}

function process_way(profile, way, result)
  local highway = way:get_value_by_key("highway")
  if not highway then return end
  
  -- Исключаем тротуары и пешеходные зоны
  if excluded_highways[highway] then return end  -- пропускаем эту дорогу
  
  local rate = highway_rate[highway]
  if not rate then return end
  ...

⚠️ Требуется пересборка OSRM графа (~40 мин). Вместе с F-07 — одна пересборка.


F-09: Больше альтернативных маршрутов

Описание

Предложить пользователю до 5 существенно разных маршрутов, не только варианты от OSRM.

Зачем

OSRM alternatives даёт маршруты, которые расходятся на ~510% пути. Они визуально почти одинаковые. Пользователь хочет видеть принципиально разные пути: через лес А vs через лес Б vs через поля.

Подход

Шаг 1: Максимизировать OSRM-альтернативы

  • Запросить alternatives=5 с radiuses для лучшего снэппинга
  • При TooBig — fallback на 3→1 (уже реализовано)

Шаг 2: Дополнительно — штрафование уже найдённых путей После получения первого маршрута — запросить OSRM повторно, но «заштрафить» дороги, через которые прошёл первый маршрут. Для этого:

  • Увеличить вес дорог на маршруте (concept: «penalized re-query»)
  • OSRM annotations=true возвращает список way-узлов маршрута

Реализация (упрощённая):

  1. Запрос 1: alternatives=5 — получаем N маршрутов от OSRM
  2. Если N < 3 — сделать повторный запрос с другим snapping или radiuses
  3. Дедупликация: убрать маршруты, которые отличаются менее чем на 10% от уже найденных (по дистанции)

Критерий «существенно разный маршрут»:

  • Отличается по дистанции на ≥10%
  • Или проходит через разные ключевые точки (определяется по перекрытию геометрии: Jaccard similarity < 0.7)

Use Cases

UC-09.1 — Выбор из 3+ маршрутов

Слава строит маршрут 200 км. Получает 3 варианта: через лес (180 км, 92% грунт), через поля (210 км, 95% грунт), комбинированный (195 км, 85% грунт). Каждый визуально отличается на карте.

UC-09.2 — Только один путь

Точки A и B в одном лесу — один разумный путь. Система показывает 1 маршрут, подпись «Альтернативных маршрутов не найдено».


F-10: Слой препятствий на карте

Описание

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

Зачем

Даже если маршрут обходит шлагбаум — полезно видеть где они. «Ага, тут шлагбаум, значит объехать можно через ту грунтовку». Без слоя — пользователь не знает о препятствиях пока не упрётся.

Use Cases

UC-10.1 — Просмотр препятствий

Слава включает слой «Препятствия». На карте появляются иконки: 🚧 шлагбаумы, 🌊 броды, блокпосты. Видит что на интересной грунтовке стоит шлагбаум — решает построить маршрут через другую дорогу.

UC-10.2 — Препятствие на маршруте

Маршрут построен. Слава видит брод на маршруте. Кликает — попап: «Брод. Возможен проезд только в сухое время года». Решает выбрать другой маршрут.

Источники данных (OSM теги)

Тип OSM тег Иконка Цвет
Шлагбаум barrier=gate/lift_gate 🚧 🟠 оранжевый
Столбик barrier=bollard/block 🔴 красный
Брод ford=yes или highway=ford 🌊 🔵 голубой
Блокпост barrier=border_control 🛂 🔴 красный
Частная территория access=private/no 🔒 🟡 жёлтый

Реализация

Бэкенд:

  1. Добавить парсинг препятствий в scripts/parse.py — таблица obstacles:
CREATE TABLE obstacles (
    id INTEGER PRIMARY KEY,
    osm_id INTEGER,
    obstacle_type TEXT,  -- gate, bollard, ford, border_control, private
    name TEXT,
    lon REAL,
    lat REAL
);
CREATE INDEX idx_obstacles_bbox ON obstacles(lon, lat);
  1. Добавить POI-слой obstacles в build_mvt() — точки с obstacle_type в props.

Фронт:

  1. Слой в style.json: obstacles-circles — цветные круги по типу
  2. Кнопка в хедере: 🚧 Препятствия (toggle on/off)
  3. Попап при клике: тип, название, предупреждение

⚠️ Требует перепарсинга PBF — добавить extract точек barrier из OSM данных.


3. Приоритет реализации

# Фича Приоритет Сложность Зависимости
F-07 Исключить шлагбаумы 🔴 Высокий Низкая (lua) + средняя (пересборка графа ~40 мин) Пересборка OSRM
F-08 Исключить тротуары 🔴 Высокий Низкая (lua) + средняя (пересборка) Пересборка OSRM
F-09 Больше альтернатив 🟡 Средний Высокая (алгоритм)
F-10 Слой препятствий 🟡 Средний Средняя (parse + style + UI) Перепарсинг PBF

Рекомендуемый порядок:

  1. F-07 + F-08 вместе — одна правка enduro.lua, одна пересборка графа
  2. F-09 — улучшение альтернативных маршрутов (на уже исправленном графе)
  3. F-10 — слой препятствий (перепарсинг + UI)

4. Пересборка OSRM графа

F-07 и F-08 требуют пересборки — это ~40 минут на сервере mva154.

Порядок:

  1. Обновить enduro.lua (убрать footway из rate + заблокировать barrier nodes)
  2. Запустить пересборку:
cd /home/slin/enduro-trails/osrm
docker compose run --rm osrm-prepare
  1. Перезапустить роутер:
docker compose restart osrm-routed
  1. Проверить: маршрут не идёт через шлагбаумы и тротуары

5. Открытые вопросы для Славы

  1. Шлагбаумы — всегда блокировать? Некоторые шлагбаумы открыты всегда (например, на въезде в дачный посёлок). Полная блокировка означает что маршрут НИКОГДА не пойдёт через шлагбаум. Ок, или хочешь опцию «показывать предупреждение но не блокировать»?

  2. Тротуары vs тропыfootway в лесу это тропа (можно проехать), footway в городе это тротуар (нельзя). Различать по контексту (город/лес) сложно. Предлагаю: исключить все footway, а тропы оставить как path/bridleway (rate=85/90). Норм?

  3. Слой препятствий — стоит ли перепарсить PBF сейчас, или отложить на потом? Перепарсинг ~30 мин + пересборка OSRM ещё ~40 мин. Итого ~70 мин работы сервера.

  4. Альтернативы — алгоритм — проще всего оставить OSRM alternatives как есть, но добавить дедупликацию (убрать визуально одинаковые). Или хочешь чтобы я исследовала «penalized re-query» подход для принципиально разных маршрутов? Это сложнее и дольше.


Документ готов к согласованию. После ответов — обновлю и передам Dev-агенту.