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

160 lines
8.6 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 переворачивает эту логику: **грунтовки/тропы — главный слой**, асфальт — тусклый фон. Плюс фичи для поиска и построения красивых маршрутов (минимум асфальта, максимум красоты).
## Ключевые фичи
| Фича | Описание |
|------|----------|
| 🛤️ **"Дикий путь"** | Роутинг А→Б с максимизацией грунтовок (OSRM) |
| 🔍 **"Поиск"** | Поиск населённых пунктов и адресов (Nominatim) |
| 📏 **"Линейка"** | Измерение расстояния между точками на карте |
| 🚩 **"Флажки/метки"** | Расстановка именованных меток на карте |
| 🗺️ **"Умный маршрут"** | Промежуточные точки, % асфальт/грунт/тропа, GPX экспорт |
| 🎨 **"Красивый маршрут"** | Замкнутый круг через водоёмы, виды, заброшки |
| 🏔️ **"Горка"** | Макс набор высоты, мин дистанция (SRTM) |
| 🔗 **"Связка"** | Соединить два трека грунтовками |
| 📍 **"Разведка"** | Грунтовки вокруг точки |
| 🚧 **"Препятствия"** | Броды, шлагбаумы, болота, ЛЭП |
| 🌐 **"Народные треки"** | Сбор и отображение треков с внешних сервисов |
| 🌙 **"День/ночь"** | Переключатель темы — светлая/тёмная карта |
| 🎨 **"Эндуро-дизайн"** | Современный агрессивный UI в духе эндуро/оффроад |
## Регионы
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)
### OSRM
- **Данные:** `/home/slin/enduro-trails/data/enduro.osrm.*`
- **PBF:** `/home/slin/enduro-trails/data/enduro.osm.pbf`
- **Профиль:** `/home/slin/enduro-trails/osrm/enduro.lua`
- **Docker compose:** `/home/slin/enduro-trails/osrm/docker-compose.yml`
- **Контейнер:** `osrm-osrm-routed-1`, порт `5559`
- **OSRM_URL в app.py:** `http://172.22.0.1:5559`
- **Swap:** `/home/slin/swapfile3` (4 GB), итого 6 GB swap
## Текущее состояние (2026-05-03)
### ✅ Готово
**OSRM роутинг:**
- ✅ «Дикий путь» — OSRM с кастомным профилем `enduro.lua`
-`weight_name = 'routability'` (не `duration` — не оптимизирует по времени)
-`forward_speed = 30` для всех типов дорог (duration не влияет на выбор)
-`forward_rate` определяет предпочтительность: track=100, bridleway=90, path=85, motorway=0.1
-`tracktype` мультипликатор: grade1×1.3, grade3×1.0, grade5×0.8
- ✅ U-turn penalty 20s, нет односторонних ограничений
- ✅ Граф: `enduro.osrm.*` (~5.2 GB), собран из `enduro.osm.pbf` (ЦФО + Чувашия)
- ✅ Контейнер `osrm-osrm-routed-1`, порт 5559, OSRM_URL=`http://172.22.0.1:5559`
**Инфраструктура:**
- Прототип задеплоен: `https://openclaw.mva154.duckdns.org/enduro/`
- БД: 1 141 926 треков, 14 882 POI (Spatialite)
- Векторные тайлы (MVT) через FastAPI, 4 uvicorn workers
- FIFO-кэш тайлов (512 тайлов в памяти) [реализация — FIFO, не LRU]
- Упрощение геометрии по зуму (Shapely simplify)
- Фильтр треков по длине на низких зумах (z8: ≥500м, z9: ≥200м)
- Dockerfile — быстрый старт без apt/pip при рестарте
- Nginx `/enduro/` с HTTPS
**Карта и UI:**
- MapLibre GL JS, легенда (Lev1-2 / Lev3-5 / Тропа)
- Раскраска: Lev1-2 жёлтый (#FFD700), Lev3-5 красный (#FF4400)
- Тропы (path/footway/bridleway) — красный пунктир (#cc0000)
- Асфальт скрыт (visibility: none)
- Подложка: saturation -0.4, contrast 0.25, brightness-max 0.9
- Кнопка 🧭 компас (север/свободный режим)
- Кнопка 📍 геолокация с пульсирующим маркером
- Попапы: name, surface, tracktype, length_m, mtb_scale
**Фичи:**
- ✅ Роутинг "Дикий путь" — кнопка 🗺️, маркеры A/B, карточка с дистанцией и временем
- ✅ Поиск (Nominatim) — строка в хедере, debounce 400ms, flyTo
- ✅ Линейка 📏 — кружки точно на координатах, плашки над ними, крестик удаления, haversine расстояние
### ⏳ Бэклог
**Фаза 3 — Умный маршрут:**
- Промежуточные точки (перетаскиваемые)
- Статистика: % асфальт / lev1-2 / lev3-5 / тропа
- Скачать GPX
**Фаза 4 — Флажки/метки:**
- Расстановка именованных меток на карте
- Сохранение в localStorage
**Фаза 5 — Редизайн:**
- Тёмная тема, эндуро-стиль, адаптив под мобилку
**Фаза 6 — SRTM рельеф:**
- "Горка" — макс набор высоты
- Профиль высот на маршруте
**Фаза 7 — PWA + офлайн:**
- Service Worker, офлайн MBTiles, GPS-трекинг
**Фаза 8 — Народные треки:**
- Источники: OSM Traces, Wikiloc, Komoot, 4x4travel.ru, Enduroad.ru
- Отдельный слой `community_tracks`, фильтрация по типу активности
## Схема БД
```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
-- Примечание: poi НЕ имеет поля tags
```
## Ключевые решения
| Решение | Причина |
|---------|---------|
| 4 uvicorn workers | Устранение узкого места однопоточности |
| Фильтр по length_m на низких зумах | Производительность, читаемость карты |
| Относительные пути в app.js | Работает и через nginx /enduro/, и по прямому IP |
| Dockerfile вместо inline apt+pip | Устранил 452 рестарта контейнера |
| OSRM `weight_name='routability'` | `duration` → OSRM выбирал асфальт как быстрый |
| `forward_rate = penalty` (не /speed) | Penalty/метр — прямой вес пути |
| Два маркера на точку линейки | Кружок anchor:center точно на координатах, плашка offset вверх |
| stopPropagation на крестике линейки | Клик не проваливался на карту и не ставил новую точку |
---
*Ссылка на онтологию: `proj_enduro_trails`*