auto-sync: 2026-05-04 01:00:01

This commit is contained in:
Stream
2026-05-04 01:00:01 +03:00
parent eb802831a5
commit 5e7a362b24
2 changed files with 221 additions and 120 deletions

View File

@@ -16,99 +16,138 @@
| Фича | Описание |
|------|----------|
| 🛤️ **"Дикий путь"** | Роутинг А→Б с максимизацией грунтовок |
| 🛤️ **"Дикий путь"** | Роутинг А→Б с максимизацией грунтовок (OSRM) |
| 🔍 **"Поиск"** | Поиск населённых пунктов и адресов (Nominatim) |
| 📏 **"Линейка"** | Измерение расстояния между точками на карте |
| 🚩 **"Флажки/метки"** | Расстановка именованных меток на карте |
| 🗺️ **"Умный маршрут"** | Промежуточные точки, % асфальт/грунт/тропа, GPX экспорт |
| 🎨 **"Красивый маршрут"** | Замкнутый круг через водоёмы, виды, заброшки |
| 🏔️ **"Горка"** | Макс набор высоты, мин дистанция |
| 🏔️ **"Горка"** | Макс набор высоты, мин дистанция (SRTM) |
| 🔗 **"Связка"** | Соединить два трека грунтовками |
| 📍 **"Разведка"** | Грунтовки вокруг точки |
| 🚧 **"Препятствия"** | Броды, шлагбаумы, болота, ЛЭП |
| 🌐 **"Народные треки"** | Сбор и отображение треков с внешних сервисов |
| 🔍 **"Поиск"** | Поиск населённых пунктов, адресов и объектов как на обычных картах |
| 🌙 **"День/ночь"** | Переключатель темы — светлая/тёмная карта |
| 🎨 **"Эндуро-дизайн"** | Современный агрессивный UI в духе эндуро/оффроад |
| 📏 **"Линейка"** | Измерение расстояния между точками на карте |
| 🚩 **"Флажки/метки"** | Расстановка именованных меток на карте |
| 🗺️ **"Умный маршрут"** | Промежуточные точки, расстояние между ними, % асфальт/грунт/тропа |
## Регионы
1. **ЦФО + Чувашия** (первый регион, прототип)
2. Расширение на новые ФО по запросу
## План
Прототип (mva154) → проверка концепта → новая VM с PostGIS + OSRM → масштабируемая платформа
## Архитектура
Схема: `../../enduro_architecture.png`
Концепт: [CONCEPT.md](CONCEPT.md)
### Стек
- Pyrosm/Osmium → парсинг PBF
- Spatialite/PostGIS → хранение
- OSRM (кастомный профиль) → роутинг
- FastAPI → бэкенд
- Spatialite → хранение (прототип), PostGIS → продакшен
- OSRM (кастомный профиль `enduro.lua`) → роутинг
- FastAPI + uvicorn (4 workers) → бэкенд
- MapLibre GL JS → фронт (веб + PWA)
## Хостинг
### Инфраструктура (прототип)
- **Прототип:** `slin@82.22.50.71`, контейнер `prototype-enduro-trails-1`, порт `5558`
- **Сервер:** `slin@82.22.50.71`, sudo пароль `motoZ@yaz2010`
- **Контейнер:** `prototype-enduro-trails-1`, порт `5558`
- **URL:** `https://openclaw.mva154.duckdns.org/enduro/`
- **Продакшен:** новая VM (4 vCPU, 8 GB RAM, 50 GB диск)
- **Код на сервере:** `/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)
-Прототип задеплоен: `https://openclaw.mva154.duckdns.org/enduro/`
- ✅ БД: 1 141 926 треков, 14 882 POI (Spatialite)
- ✅ Векторные тайлы (MVT) через FastAPI, 4 uvicorn workers
- ✅ LRU-кэш тайлов (512 тайлов в памяти)
- ✅ Упрощение геометрии по зуму (Shapely simplify)
- ✅ Фильтр треков по длине на низких зумах (z8: ≥500м, z9: ≥200м)
- ✅ Dockerfile — быстрый старт контейнера без apt/pip при рестарте
- ✅ Nginx `/enduro/` с HTTPS через `openclaw.mva154.duckdns.org`
- ✅ Фронт: MapLibre GL JS, легенда (Lev1-2 / Lev3-5 / Тропа)
- ✅ Тропы — красный пунктир, асфальт скрыт
- ✅ Кнопки: 🧭 компас (север/свободный), 📍 геолокация с маркером
- ✅ Попапы с name, surface, tracktype, length_m, mtb_scale
###Готово
## План развития
**Инфраструктура:**
- Прототип задеплоен: `https://openclaw.mva154.duckdns.org/enduro/`
- БД: 1 141 926 треков, 14 882 POI (Spatialite)
- Векторные тайлы (MVT) через FastAPI, 4 uvicorn workers
- LRU-кэш тайлов (512 тайлов в памяти)
- Упрощение геометрии по зуму (Shapely simplify)
- Фильтр треков по длине на низких зумах (z8: ≥500м, z9: ≥200м)
- Dockerfile — быстрый старт без apt/pip при рестарте
- Nginx `/enduro/` с HTTPS
| Фаза | Что | Статус |
|------|-----|--------|
| Фаза 1 | Прототип — визуализация OSM треков | ✅ Готово |
| Фаза 2 | OSRM роутинг + "Дикий путь" | 🔄 В работе |
| Фаза 3 | SRTM рельеф + уклоны + "Горка" | ⏳ Планируется |
| Фаза 4 | "Красивый маршрут", "Связка", "Разведка" | ⏳ Планируется |
| Фаза 5 | PWA + оффлайн | ⏳ Планируется |
| Фаза 6 | Народные треки — сбор с внешних сервисов | ⏳ Планируется |
**Карта и 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
### Фаза 6: Народные треки (детали)
**Фичи:**
- ✅ Роутинг "Дикий путь" — кнопка 🗺️, маркеры A/B, карточка с дистанцией и временем
- ✅ Поиск (Nominatim) — строка в хедере, debounce 400ms, flyTo
- ✅ Линейка 📏 — кружки точно на координатах, плашки над ними, крестик удаления, haversine расстояние
Источники для сбора:
- **OSM Traces** — публичные GPS-треки загруженные в OSM, бесплатно, API открытый
- **Wikiloc** — огромная база треков эндуристов/велосипедистов/туристов, есть API
- **Komoot** — активно используется эндуристами и велотуристами
- **Strava** — велосипедисты, бегуны (API платный для массового сбора)
- **4x4travel.ru** — джипперы, форум с GPX-файлами
- **Enduroad.ru** — эндуро-сообщество
- **Garmin Connect** — публичные активности
### 🔄 В работе
Реализация:
- Сборщик треков → конвертация в GeoJSON → отдельная таблица `community_tracks` в БД
- Отдельный слой на карте "Народные треки" (другой цвет, можно вкл/выкл)
- Фильтрация по типу активности: мото / велосипед / джип / пеший
- Атрибуты: источник, автор, дата, рейтинг, тип активности
- OSRM пересборка с `weight_name='routability'` (3-я итерация, запущена 2026-05-03 ~21:00 UTC)
- Предыдущая версия с `weight_name='duration'` давала маршруты по асфальту
- Новый профиль: штрафы track=1, tertiary=15, secondary=25, primary=40, trunk=60, motorway=999
| Компонент | Объём |
|-----------|--------|
| PBF (регион) | ~150-200 MB |
| Spatialite/PostGIS | ~500 MB - 1 GB |
| OSRM граф | ~1-3 GB |
| SRTM DEM | ~2-3 GB |
| Тайлы (z10-16) | ~2-5 GB |
| **Итого** | **~5-12 GB** |
### ⏳ Бэклог
**Фаза 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,
min_lon, max_lon, min_lat, max_lat
-- poi
id, osm_id, poi_type, name, lon, lat, 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 на крестике линейки | Клик не проваливался на карту и не ставил новую точку |
---

View File

@@ -1,6 +1,6 @@
# Прототип Enduro Trails на mva154
**Статус:** done
**Статус:** active
**Приоритет:** high
**Проект:** proj_enduro_trails
@@ -8,50 +8,24 @@
## Задача
Настроить прототип на mva154 для проверки концепции Enduro Trails.
Настроить и развить прототип на mva154 для проверки концепции Enduro Trails.
## Что делаем
---
### 1. PBF Парсинг (ЦФО + Чувашия)
- Скачать PBF дамп европейской части России с Geofabrik
- Отфильтровать по bounding box (ЦФО + Чувашия)
- Распарсить highway=track, highway=path с тегами surface, tracktype, mtb:scale
- Сохранить GeoJSON в `tasks/enduro-trails/data/`
## ✅ Выполнено
### 2. Spatialite
- Импортировать отфильтрованные дороги в Spatialite
- Создать базовые индексы для поиска
- Добавить слой POI (водоёмы, видовые точки, брошенные объекты)
### Фаза 1 — Базовый прототип (2026-05-02)
### 3. Базовый рендеринг тайлов
- Настроить tileserver-gl или самописный генератор тайлов
- Стиль: грунтовки яркие, асфальт серый
- Поддержка z10-z16
### 4. Веб-карта (MapLibre GL)
- Простой HTML + MapLibre GL JS
- Загрузка тайлов
- Базовые контролы слоёв
## Критерии выполнения
- [x] Скачан и отфильтрован PBF дамп
- [x] Парсинг → Spatialite работает (1 141 926 треков, 14 882 POI)
- [x] Тайлы генерируются с кастомным стилем (MVT через FastAPI)
- [x] Веб-карта показывает грунтовки ярко, асфальт тускло
- [x] Клик по дороге → информация (название, surface, tracktype, length_m, mtb_scale)
## Стабилизация v0.1 (2026-05-02)
- [x] `parse.py` — bbox-колонки и индекс `idx_trails_bbox`, `lon`/`lat` для poi
- [x] `app.py``length_m`/`mtb_scale` в props, SQL bbox-фильтр для POI, валидация z/x/y, параметризованный LIMIT
- [x] `index.html` — JS вынесен в `app.js`, CSS в `app.css`, `toggleLayer` через `window._map`, правильные `layerGroups` ids
- [x] `requirements.txt``mapbox-vector-tile==2.2.0`, без parse-зависимостей
- [x] Создан `Dockerfile`, обновлён `docker-compose.yml`
- [x] Создан `scripts/smoke_check.py`
- [x] PBF парсинг ЦФО + Чувашия → Spatialite (1 141 926 треков, 14 882 POI)
- [x] `parse.py` — bbox-колонки, индекс `idx_trails_bbox`, `lon`/`lat` для poi
- [x] `app.py` — MVT тайлы через FastAPI, `length_m`/`mtb_scale` в props, SQL bbox-фильтр, валидация z/x/y
- [x] `index.html` + `app.js` + `app.css` — MapLibre GL JS фронт
- [x] `requirements.txt``mapbox-vector-tile==2.2.0`
- [x] `Dockerfile` + `docker-compose.yml`
- [x] `scripts/smoke_check.py`
- [x] Задеплоено на `82.22.50.71:5558`, smoke checks прошли
## Оптимизация и улучшения (2026-05-03)
### Оптимизация (2026-05-03)
- [x] LRU-кэш тайлов (512 тайлов в памяти, gzip)
- [x] Упрощение геометрии по зуму (Shapely simplify, адаптивный tolerance)
@@ -60,34 +34,122 @@
- [x] Dockerfile пересобран — контейнер стартует мгновенно без apt/pip
- [x] Nginx location `/enduro/` → HTTPS через `openclaw.mva154.duckdns.org`
- [x] Все пути в фронте относительные — работает и через nginx, и по прямому IP
### UI/UX (2026-05-03)
- [x] Кнопка 🧭 компас (север/свободный режим)
- [x] Кнопка 📍 геолокация с пульсирующим маркером
- [x] Тропы — красный пунктир, асфальт скрыт
- [x] Легенда: Lev1-2 / Lev3-5 / Тропа
- [x] Тропы (path/footway/bridleway) — красный пунктир (#cc0000)
- [x] Асфальт скрыт (visibility: none, opacity: 0)
- [x] Легенда: Lev1-2 / Lev3-5 / Тропа (компактно, без асфальта)
- [x] Раскраска: Lev1-2 жёлтый (#FFD700), Lev3-5 красный (#FF4400), одинаковая толщина
- [x] Подложка: raster-saturation -0.4, raster-contrast 0.25, raster-brightness-max 0.9
- [x] Попапы: name, surface, tracktype, length_m, mtb_scale
## Данные для ЦФО + Чувашия
### Фаза 2 — Роутинг + Поиск + Линейка (2026-05-03)
**BBOX (приблизительно):**
- Запад: 30.0
- Восток: 45.0
- Юг: 51.0
- Север: 59.0
- [x] OSRM граф собран с кастомным `enduro.lua` профилем (3 попытки, с 6 GB swap)
- [x] Swap добавлен: `/home/slin/swapfile3` (4 GB), итого 6 GB
- [x] OSRM роутер запущен: контейнер `osrm-osrm-routed-1`, порт `5559`
- [x] API endpoint `/api/route` в `app.py` (httpx → OSRM)
- [x] Фронт роутинга: кнопка 🗺️, маркеры A/B, карточка с дистанцией и временем
- [x] Поиск (Nominatim): строка в хедере, debounce 400ms, limit 6, countrycodes=ru, flyTo
- [x] Линейка 📏: кружки точно на координатах (anchor:center), плашки над ними (offset [0,-20]), крестик с stopPropagation, haversine расстояние
**PBF источник:** `https://download.geofabrik.de/russia/centralfederal.ru-latest.osm.pbf`
Чувашия может быть включена или отдельным дампом — нужно проверить Geofabrik
---
## Техстек
## 🔄 В работе
- **Парсинг:** Pyrosm (Python)
- **Хранение:** Spatialite
- **Тайлы:** TileServer GL или Python + Pillow/Mapnik
- **Фронт:** MapLibre GL JS (CDN)
### OSRM пересборка (3-я итерация, запущена 2026-05-03 ~21:00 UTC)
## Примечания
**Проблема:** маршрут шёл по Ленинградскому шоссе вместо грунтовок.
**Причина:** `weight_name = 'duration'` → OSRM оптимизирует по времени, асфальт быстрее.
**Решение:**
- `weight_name = 'routability'`
- `forward_rate = penalty` (penalty/метр, не делённый на скорость)
- Штрафы: track=1, tertiary=15, secondary=25, primary=40, trunk=60, motorway=999
- Прототип локальный (mva154:5558 или другой порт)
- Без роутинга на этом этапе (только визуализация)
- OSRM ставим в фазе 2
**Проверить после сборки:** маршрут Хоругвино → Дятлово должен идти по грунтовкам, не по Ленинградке.
---
## ⏳ Бэклог
### Фаза 3 — Умный маршрут
- [ ] Промежуточные точки (перетаскиваемые waypoints)
- [ ] Статистика маршрута: % асфальт / 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`
- [ ] Фильтрация по типу активности (мото / вело / джип / пеший)
---
## Технические детали
### Файловая структура на сервере
```
/home/slin/enduro-trails/
├── prototype/ ← код контейнера (= workspace/tasks/enduro-trails/prototype/)
│ ├── app.py
│ ├── Dockerfile
│ ├── docker-compose.yml
│ ├── requirements.txt
│ └── static/
│ ├── index.html
│ ├── app.js
│ ├── app.css
│ └── style.json
├── data/
│ ├── centralfederal.sqlite (431 MB, БД треков)
│ ├── enduro.osm.pbf (PBF для OSRM)
│ └── enduro.osrm.* (граф OSRM)
└── osrm/
├── enduro.lua (кастомный профиль)
└── docker-compose.yml (OSRM роутер)
```
### Деплой
```bash
# Обновить статику и пересобрать контейнер
cd /home/slin/enduro-trails/prototype
docker compose up -d --build
```
### OSRM пересборка
```bash
cd /home/slin/enduro-trails/osrm
docker compose run --rm osrm-prepare
docker compose up -d
```
### Проверка OSRM
```bash
curl "http://localhost:5559/route/v1/driving/36.8,56.1;36.9,56.2?overview=full&geometries=geojson"
```
---