200 lines
11 KiB
Markdown
200 lines
11 KiB
Markdown
# Enduro Trails 🏍️
|
||
|
||
> OSM-карта с фокусом на грунтовые дороги для построения красивых эндуро-маршрутов
|
||
|
||
**Статус:** active
|
||
**Старт:** 2026-05-02
|
||
**Автор:** Слава
|
||
|
||
---
|
||
|
||
## Концепция
|
||
|
||
Обычные карты оптимизированы под автомобили — асфальт яркий, грунтовки не видны. Enduro Trails переворачивает эту логику: **грунтовки/тропы — главный слой**, асфальт — тусклый фон. Плюс фичи для поиска и построения красивых маршрутов (минимум асфальта, максимум красоты).
|
||
|
||
---
|
||
|
||
## Регион
|
||
|
||
1. **ЦФО + Чувашия** (первый регион, прототип)
|
||
2. Расширение на новые ФО по запросу
|
||
|
||
---
|
||
|
||
## Архитектура
|
||
|
||
### Стек
|
||
- Pyrosm/Osmium → парсинг PBF
|
||
- Spatialite → хранение (прототип), PostGIS → продакшен
|
||
- OSRM (кастомный профиль `enduro.lua`) → роутинг
|
||
- FastAPI + uvicorn (4 workers) → бэкенд
|
||
- MapLibre GL JS → фронт (веб + PWA)
|
||
|
||
### Инфраструктура
|
||
- **Сервер:** `slin@82.22.50.71`, sudo `motoZ@yaz2010`
|
||
- **Контейнер приложения:** `prototype-enduro-trails-1`, порт `5558`
|
||
- **URL:** `https://openclaw.mva154.duckdns.org/enduro/`
|
||
- **Код на сервере:** `/home/slin/enduro-trails/prototype/`
|
||
- **Workspace:** `/home/node/.openclaw/workspace/tasks/enduro-trails/prototype/`
|
||
- **БД:** `/home/slin/enduro-trails/data/centralfederal.sqlite` (431 MB, 1.1M треков, 14K POI)
|
||
- **OSRM контейнер:** `osrm-osrm-routed-1`, порт `5559`
|
||
- **OSRM данные:** `/home/slin/enduro-trails/data/enduro.osrm.*` (~5.2 GB)
|
||
- **OSRM профиль:** `/home/slin/enduro-trails/osrm/enduro.lua`
|
||
- **Swap:** `/home/slin/swapfile3` (4 GB), итого 6 GB swap
|
||
- **Деплой:** Node.js ssh2 (SSH бинарник в контейнере не работает — glibc 2.36 vs 2.38)
|
||
|
||
### Деплой
|
||
```bash
|
||
# SFTP через ssh2: /tmp/deploy_app.js
|
||
# docker cp + restart (файлы запечены в образ)
|
||
docker cp /home/slin/enduro-trails/prototype/app.py prototype-enduro-trails-1:/app/app.py
|
||
docker restart prototype-enduro-trails-1
|
||
```
|
||
|
||
---
|
||
|
||
## Схема БД
|
||
|
||
```sql
|
||
-- trails: id, osm_id, highway_type, track_type, surface, name, length_m,
|
||
-- mtb_scale, visibility, smoothness, access, tags, geom BLOB,
|
||
-- min_lon, max_lon, min_lat, max_lat
|
||
|
||
-- poi: id, osm_id, poi_type, name, geom BLOB, lon, lat
|
||
```
|
||
|
||
---
|
||
|
||
## Реестр фич
|
||
|
||
| ID | Фича | Описание | Статус | Фаза |
|
||
|----|------|----------|--------|------|
|
||
| F-01 | Альтернативные маршруты | До 5 вариантов с разным балансом грунт/асфальт | ✅ Готово | 3 |
|
||
| F-02 | Статистика маршрута | Карточки с % покрытия, полоска, развёрнутый вид | ✅ Готово | 3 |
|
||
| F-03 | Человекочитаемое время | "2 ч 35 мин" вместо "155 мин" | ✅ Готово | 3 |
|
||
| F-04 | Промежуточные точки | Добавление, удаление, drag, debounce 300ms | ✅ Готово | 3 |
|
||
| F-05 | GPX экспорт | Трек + waypoints + флажки, имя enduro-YYYYMMDDHHMMSS.gpx | ✅ Готово | 3 |
|
||
| F-06 | Флажки/метки | localStorage, попап → A / → B / удалить, иконки | ✅ Готово | 3 |
|
||
| F-07 | Исключить шлагбаумы | Баррьеры → inaccessible в OSRM | 📋 BRD готов | 3.1 |
|
||
| F-08 | Исключить тротуары | footway/pedestrian/steps убрать из графа | 📋 BRD готов | 3.1 |
|
||
| F-09 | Больше альтернатив | Penalized re-query + дедупликация | 📋 BRD готов | 3.1 |
|
||
| F-10 | Слой препятствий | Шлагбаумы, броды, блокпосты на карте | 📋 BRD готов | 3.1 |
|
||
| F-11 | "Красивый маршрут" | Замкнутый круг через водоёмы, виды, заброшки | ⏳ Бэклог | 4 |
|
||
| F-12 | "Горка" | Макс набор высоты, мин дистанция (SRTM) | ⏳ Бэклог | 6 |
|
||
| F-13 | "Связка" | Соединить два трека грунтовками | ⏳ Бэклог | 4 |
|
||
| F-14 | "Разведка" | Грунтовки вокруг точки | ⏳ Бэклог | 4 |
|
||
| F-15 | "Народные треки" | OSM Traces, Wikiloc, Komoot, 4x4travel | ⏳ Бэклог | 8 |
|
||
| F-16 | Тёмная тема | День/ночь + эндуро-дизайн | ⏳ Бэклог | 5 |
|
||
| F-17 | PWA + офлайн | Service Worker, MBTiles, GPS-трекинг | ⏳ Бэклог | 7 |
|
||
|
||
---
|
||
|
||
## Выполненные фазы
|
||
|
||
### ✅ Фаза 1 — MVP (02.05.2026)
|
||
- PBF парсинг (ЦФО + Чувашия)
|
||
- Spatialite БД (1.1M треков, 14K POI)
|
||
- FastAPI self-hosted MVT тайлы
|
||
- MapLibre GL JS карта с кастомным стилем
|
||
- Попапы с информацией о дороге
|
||
- Контролы слоёв
|
||
|
||
### ✅ Фаза 2 — Роутинг + UI (03.05.2026)
|
||
- OSRM + кастомный профиль `enduro.lua` (порт 5559)
|
||
- Роутинг «Дикий путь» — кнопка 🗺️, маркеры A/B
|
||
- Поиск (Nominatim, debounce 400ms)
|
||
- Линейка 📏 (haversine)
|
||
- Геолокация 📍, компас 🧭
|
||
|
||
### ✅ Фаза 3 — Умный маршрут (04.05.2026)
|
||
- **F-01:** Альтернативные маршруты (до 5, цвета: синий/зелёный/фиолетовый/оранжевый/серый)
|
||
- **F-02:** Статистика покрытия (карточки: компактные + развёрнутые, полоска покрытия, %)
|
||
- **F-03:** `formatDuration()` — "2 ч 35 мин" / "1 дн 2 ч 50 мин"
|
||
- **F-04:** Промежуточные точки (до 8, draggable, debounce 300ms)
|
||
- **F-05:** GPX 1.1 экспорт (трек + waypoints + флажки)
|
||
- **F-06:** Флажки 🚩 (localStorage, 50 лимит, попап → A / → B / удалить)
|
||
|
||
**Баги исправлены (04.05):**
|
||
- formatDuration(86400) → "1 дн" (не "1 дн 0 ч")
|
||
- OSRM TooBig → retry 5→3→1
|
||
- Панель маршрута перекрывала кнопки → CSS right: 56px
|
||
- Длинные маршруты не строились → radiuses=5000 + NoSegment retry с 10km + timeout 60s
|
||
|
||
---
|
||
|
||
## Бэклог по фазам
|
||
|
||
### 📋 Фаза 3.1 — Улучшение роутинга (BRD готов, ожидает согласования)
|
||
**BRD:** `BRD_PHASE3.1.md`
|
||
|
||
| Фича | Описание | Сложность | Требует |
|
||
|------|----------|-----------|---------|
|
||
| F-07 | Шлагбаумы → inaccessible в OSRM | Низкая (lua) | Пересборка графа ~40 мин |
|
||
| F-08 | Убрать footway/pedestrian/steps из графа | Низкая (lua) | Пересборка графа ~40 мин |
|
||
| F-09 | Penalized re-query для разных альтернатив | Высокая | — |
|
||
| F-10 | Слой препятствий на карте (🚧🌊⛔) | Средняя | Перепарсинг PBF ~30 мин |
|
||
|
||
**Порядок:** F-07+F-08 вместе (одна пересборка) → F-09 → F-10
|
||
|
||
### ⏳ Фаза 4 — Продвинутый роутинг
|
||
- F-11 «Красивый маршрут» — замкнутый круг через живописные места (озёра, виды, заброшки)
|
||
- Оценка аттрактивности: близость к воде +10, перепад высот +15, viewpoints +20
|
||
- F-13 «Связка» — соединить два трека грунтовками
|
||
- F-14 «Разведка» — все грунтовки в радиусе X км от точки
|
||
|
||
### ⏳ Фаза 5 — Редизайн
|
||
- F-16 Тёмная тема + эндуро-стиль + адаптив под мобилку
|
||
|
||
### ⏳ Фаза 6 — SRTM рельеф
|
||
- F-12 «Горка» — макс набор высоты, мин дистанция
|
||
- Профиль высот на маршруте
|
||
- SRTM DEM 30м данные (Public Domain)
|
||
|
||
### ⏳ Фаза 7 — PWA + офлайн
|
||
- F-17 Service Worker, офлайн MBTiles, GPS-трекинг в реальном времени
|
||
- Интеграция с OsmAnd/Locus (экспорт)
|
||
|
||
### ⏳ Фаза 8 — Народные треки
|
||
- F-15 Источники: OSM Traces, Wikiloc, Komoot, 4x4travel.ru, Enduroad.ru
|
||
- Отдельный слой `community_tracks`, фильтрация по типу активности
|
||
|
||
---
|
||
|
||
## Ключевые решения
|
||
|
||
| Решение | Причина |
|
||
|---------|---------|
|
||
| 4 uvicorn workers | Устранение узкого места однопоточности |
|
||
| Фильтр по length_m на низких зумах | Производительность, читаемость |
|
||
| Относительные пути в app.js | Работает через nginx /enduro/ и по прямому IP |
|
||
| OSRM `weight_name='routability'` | `duration` → OSRM выбирал асфальт |
|
||
| `forward_rate = penalty` | Penalty/метр — прямой вес пути |
|
||
| `radiuses=5000` в OSRM запросах | Без этого длинные маршруты не снэппятся |
|
||
| Retry TooBig: 5→3→1 | OSRM не даёт 5 альтернатив на длинных маршрутах |
|
||
| Retry NoSegment: radiuses=10000 | Точки далеко от дорог — нужен широкий snap |
|
||
| Timeout 60s для retry | Длинные маршруты строятся >30с |
|
||
| Node.js ssh2 для деплоя | SSH бинарник в контейнере требует glibc 2.38 |
|
||
| docker cp вместо compose build | Файлы запечены в образ, cp в running container быстрее |
|
||
| Сэмплирование каждые ~500м для stats | Без этого расчёт >30с на длинных маршрутах |
|
||
| Grid cache для calc_route_stats | Убирает повторные SQL запросы для близких точек |
|
||
|
||
---
|
||
|
||
## Документы
|
||
|
||
| Документ | Описание |
|
||
|----------|----------|
|
||
| `PROJECT.md` | Этот файл — общее состояние проекта |
|
||
| `CONCEPT.md` | Концепция и архитектура |
|
||
| `TECHNICAL_SPEC.md` | ТЗ прототипа v0.1 |
|
||
| `DEV_TASK.md` | Стабилизация v0.1 (архив) |
|
||
| `BRD_PHASE3.md` | Бизнес-требования Фазы 3 (согласовано) |
|
||
| `BRD_PHASE3.1.md` | Бизнес-требования Фазы 3.1 (на согласовании) |
|
||
| `TEST_CASES_PHASE3.md` | 56 тест-кейсов |
|
||
| `DEV_TASK_PHASE3.md` | ТЗ для Dev-агента Фаза 3 |
|
||
| `reports/` | Отчёты о тестировании |
|
||
|
||
---
|
||
|
||
*Ссылка на онтологию: `proj_enduro_trails`*
|