16 KiB
BRD: Enduro Trails — Фаза 4 «Продвинутый роутинг»
Версия: 1.0
Дата: 2026-05-04
Автор: Стрим 🌊
Статус: Согласовано ✅
1. Контекст и цели
Что уже есть
- Роутинг A→B «Дикий путь» (OSRM, до 5 альтернатив)
- Статистика покрытия (% грунт/асфальт/тропа)
- Промежуточные точки, GPX экспорт
- POI в БД: water, peak, viewpoint, ruins, ford, cave_entrance (14K штук)
Проблема
«Дикий путь» даёт маршрут от A до B с максимумом грунтовок. Но эндуристу часто нужно другое:
- «Покататься красиво» — замкнутый круг от дома, через живописные места, и обратно
- «Найти грунтовки рядом» — не знаешь куда ехать, покажи что есть вокруг
- «Соединить два трека» — есть два хороших участка, как их связать грунтовками
Цель
Дать эндуристу 3 новых режима роутинга, которые закрывают типичные сценарии: покататься, разведать, связать.
2. Фичи
F-11: «Красивый маршрут» (Scenic Route)
Описание
Пользователь указывает точку старта и желаемую дистанцию. Система строит замкнутый кольцевой маршрут, который проходит через максимально живописные места: озёра, видовые точки, заброшки, горы.
Зачем
Самый частый сценарий эндуриста: «Хочу покататься км на 150 от дома, но не по асфальту, а красиво». Сейчас нужно вручную ставить точки и строить маршрут. «Красивый маршрут» делает это автоматически.
Use Cases
UC-11.1 — Покататься от дома
Слава нажимает 🎨 «Красивый маршрут». Кликает на карте — точка старта (дом). Вводит дистанцию: 150 км. Система строит кольцевой маршрут: дом → озеро Сенеж → видовая точка → заброшка → грунтовки → дом. 142 км, 89% грунт.
UC-11.2 — Короткая поездка
Слава хочет покататься на 50 км. Маршрут: дом → лесной массив → грунтовки → дом. 48 км, 94% грунт.
UC-11.3 — Несколько вариантов
Система предлагает 2–3 кольцевых маршрута: северный (через озёра), восточный (через леса), южный (через поля). Слава выбирает северный — через озёра красивее.
UC-11.4 — Нет красивых мест рядом
Слава в степи, рядом нет озёр и видов. Система строит максимально грунтовый кольцевой маршрут, но без бонусных точек. Подпись: «Живописных объектов поблизости не найдено, маршрут по грунтовкам».
Алгоритм
Шаг 1: Найти привлекательные POI в радиусе
- Радиус = желаемая дистанция × 0.6 (примерное кольцо)
- Выбрать POI с оценкой аттрактивности:
| POI тип | Баллы | Вес |
|---|---|---|
natural=water (озёра, реки) |
10 | Высокий |
tourism=viewpoint (видовые точки) |
15 | Очень высокий |
historic=ruins (заброшки) |
10 | Высокий |
natural=peak (вершины) |
12 | Высокий |
natural=cave_entrance (пещеры) |
8 | Средний |
ford=yes (броды) |
5 | Низкий |
Шаг 2: Выбрать 3–5 POI для маршрута
- Жадный алгоритм: начать со старта, на каждом шаге выбирать ближайший POI с максимальными баллами
- Суммарная дистанция до POI ≤ желаемая дистанция × 0.8 (оставить запас на возврат)
- После последнего POI — маршрут обратно к старту
Шаг 3: Построить маршрут через POI
- Использовать OSRM: старт → POI1 → POI2 → ... → старт
- Каждый сегмент — запрос к OSRM с
alternatives=false
Шаг 4: Проверить дистанцию
- Если итоговая дистанция > желаемая × 1.3 — уменьшить кол-во POI, перестроить
- Если < желаемая × 0.5 — добавить POI, перестроить
Шаг 5: Альтернативы
- Повторить с другим набором POI (другое направление от старта)
- Дать 2–3 варианта
UI
Кнопка: 🎨 «Красивый маршрут» (рядом с 🗺️ «Дикий путь»)
Панель:
┌─────────────────────────────────┐
│ 🎨 Красивый маршрут │
│ │
│ 📍 Точка старта: кликни на карте│
│ 📏 Дистанция: [150] км │
│ │
│ [Построить маршрут] │
└─────────────────────────────────┘
Карточка маршрута (после построения):
┌─────────────────────────────────┐
│ 🎨 Северный маршрут 142 км │
│ ████████████░░░ 4 ч 20 мин │
│ 89% грунт · 11% асфальт │
│ │
│ 💊 Живописные объекты: │
│ 💧 Озеро Сенеж │
│ 👁 Смотровая «Высокая» │
│ 🏚 Заброшенная ферма │
│ │
│ [📥 GPX] [Выбрать маршрут] │
└─────────────────────────────────┘
Требования
- Время построения ≤ 15 секунд (несколько OSRM запросов)
- Дистанция: ввод от 20 до 500 км
- Кольцевой маршрут = старт и финиш на одной точке
- POI на маршруте показаны в карточке
- Спиннер на время построения
- До 3 вариантов маршрутов
F-14: «Разведка» (Recon Mode)
Описание
Пользователь кликает на карту → система показывает все грунтовые дороги в радиусе X км с краткой статистикой: сколько дорог, какая длина, какие типы.
Зачем
«Приехал на новое место — что тут есть?». Не нужно строить маршрут — просто посмотреть какие грунтовки рядом, оценить стоит ли ехать сюда.
Use Cases
UC-14.1 — Разведка в новом месте
Слава приехал на дачу в незнакомый район. Нажимает 📍 «Разведка», кликает на карту. Появляется круг радиусом 20 км с выделенными грунтовками. Статистика: «124 грунтовки, 380 км грунтовых дорог, 85% grade3-5, 12 бродов».
UC-14.2 — Оценка перед поездкой
Слава планирует поездку на выходные. Кликает на место на карте — видит что там всего 3 короткие грунтовки. Решает ехать в другое место.
UC-14.3 — Настройка радиуса
По умолчанию радиус 20 км. Слава меняет на 50 км — видит больше грунтовок.
Алгоритм
- Получить координаты клика (lat, lon)
- Запрос к БД:
SELECT highway_type, track_type, surface, length_m, name
FROM trails
WHERE min_lon <= ? AND max_lon >= ? AND min_lat <= ? AND max_lat >= ?
AND length_m >= 100
где bbox = центр ± радиус (0.18° для 20 км, 0.45° для 50 км) 3. Агрегировать: количество, суммарная длина, распределение по типам 4. Отрисовать круг на карте + подсветить грунтовки внутри
UI
Кнопка: 📍 «Разведка» (рядом с 🗺️ и 🎨)
Попап при клике:
┌─────────────────────────────────┐
│ 📍 Разведка — 20 км радиус │
│ │
│ 🛤 124 грунтовки · 380 км │
│ │
│ 🟡 Lev1-2: 45 шт · 120 км │
│ 🔴 Lev3-5: 68 шт · 210 км │
│ 🔴 Тропы: 11 шт · 50 км │
│ │
│ 💧 Озёра: 3 · 👁 Виды: 2 │
│ 🌊 Броды: 12 · 🏚 Руины: 1 │
│ │
│ Радиус: [20] [50] [100] км │
└─────────────────────────────────┘
На карте:
- Круг (Circle) с полупрозрачной заливкой
- Грунтовки внутри круга подсвечены (увеличена толщина / opacity)
Требования
- Радиус по умолчанию: 20 км, опции: 20 / 50 / 100
- Запрос к БД ≤ 2 секунды
- Круг визуально не мешает карте
- Статистика в попапе обновляется при изменении радиуса
F-13: «Связка» (Link Route)
Описание
Пользователь указывает два трека / точки на карте → система строит маршрут между ними по грунтовкам, минуя асфальт.
Зачем
«Ехал по отличной грунтовке, потом по другой — а между ними 10 км асфальта. Можно ли как-то по грунтовкам перейти?»
Use Cases
UC-13.1 — Связать два участка
Слава проехал грунтовку А и грунтовку Б. Между ними 8 км асфальта. Нажимает 🔗 «Связка», ставит конечную точку А и начальную точку Б. Система находит обход по грунтовкам: 12 км вместо 8 км асфальта, но 100% грунт.
UC-13.2 — Нет грунтовой связки
Между двумя точками нет никаких грунтовок — только асфальт. Система: «Грунтовая связка не найдена, кратчайший путь — 5 км по асфальту».
Алгоритм
Это просто роутинг A→B через «Дикий путь» — уже реализовано. Отличие только в UI:
- Вместо кнопки «Дикий путь» — кнопка 🔗 «Связка»
- Маркеры: не A/B, а «Трек 1 (конец)» и «Трек 2 (начало)»
- Карточка показывает только % грунта (асфальт — нежелательный элемент)
UI
Кнопка: 🔗 «Связка»
Панель:
┌─────────────────────────────────┐
│ 🔗 Связка │
│ │
│ 1️⃣ Конец трека: кликни на карте│
│ 2️⃣ Начало трека: кликни │
│ │
│ [Найти грунтовую связку] │
└─────────────────────────────────┘
Карточка:
┌─────────────────────────────────┐
│ 🔗 Связка 12 км │
│ ██████████████████░ 24 мин │
│ 92% грунт · 8% асфальт │
│ │
│ [📥 GPX] [Выбрать] │
└─────────────────────────────────┘
Требования
- Использует тот же OSRM «Дикий путь» роутинг
- Отличие от «Дикого пути» — только UI (другие маркеры, акцент на минимизацию асфальта)
- До 3 альтернативных связок
3. Нефункциональные требования
Производительность
- «Красивый маршрут» — ≤ 15 сек (3–5 OSRM запросов)
- «Разведка» — ≤ 2 сек (один SQL запрос)
- «Связка» — ≤ 5 сек (один OSRM запрос)
UI
- 3 новые кнопки в панели управления: 🎨 🔗 📍
- Режимы взаимоисключающие: активный режим деактивирует остальные
- При переключении режима — сброс предыдущего состояния
4. Приоритет реализации
| # | Фича | Приоритет | Сложность | Ценность |
|---|---|---|---|---|
| F-14 | «Разведка» | 🔴 Высокий | Низкая | Высокая |
| F-13 | «Связка» | 🟡 Средний | Низкая | Средняя |
| F-11 | «Красивый маршрут» | 🔴 Высокий | Высокая | Очень высокая |
Рекомендуемый порядок:
- F-14 «Разведка» — простая SQL-агрегация, быстрый результат, высокая ценность
- F-13 «Связка» — почти готово (переиспользуем OSRM), минимум нового кода
- F-11 «Красивый маршрут» — самый сложный (алгоритм выбора POI, несколько OSRM запросов), но самый ценный
5. Решения (согласовано 2026-05-04)
| # | Вопрос | Решение |
|---|---|---|
| 1 | Ввод дистанции | Текстовое поле + пресеты (50/100/150/200 км) |
| 2 | Направление маршрута | Система сама подбирает (без выбора направления) |
| 3 | Радиус «Разведки» | 20/50/100 км — ок |
| 4 | Точки «Связки» | Клик на карту (как «Дикий путь») |
| 5 | Сезонность | Пока не учитываем |
Документ согласован. Готов к передаче Dev-агенту.