160 lines
8.6 KiB
Markdown
160 lines
8.6 KiB
Markdown
# 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`*
|