Files
wiki/tasks/enduro-trails/PROJECT.md
2026-05-04 22:50:01 +03:00

200 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`*