# Enduro Trails — Концепция и Архитектура **Дата:** 02.05.2026 **Автор:** Стрим 🌊 **Статус:** Концепция, ожидает согласования со Славой --- ## 🎯 Проблема Обычные OSM-карты оптимизированы для автомобилей — они ярко подсвечивают магистрали, а грунтовые дороги и тропы прячутся в шум. Для эндуро это **бесполезно**: асфальт не интересен, хочется увидеть где можно проехать по-настоящему. ## 💡 Решение Создать карту, где **грунтовки/тропы — главный слой**, а асфальт — тусклый фон. Плюс фичи для поиска и построения красивых маршрутов. --- ## Архитектура Схема архитектуры: `enduro_architecture.png` ``` OSM данные → ETL парсинг → Spatialite/PostGIS ├── Слой: Грунтовки ├── Слой: Рельеф (SRTM) ├── Слой: Препятствия ├── Роутинг (OSRM/GraphHopper) └── Аттрактивность (озёра, виды) ↓ API Backend (FastAPI) ↓ ┌───────────────────┼───────────────────┐ ↓ ↓ ↓ Фронт (PWA) Экспорт GPX/KML Мобильный оффлайн ``` --- ## Компоненты ### 1. Источник данных | Метод | Плюсы | Минусы | Когда нужен | |-------|--------|---------|-------------| | **PBF дамп** (Geofabrik) | Один раз скачал → локально нет API limits | Обновление раз в неделю | Основной метод | | **Overpass API** | Свежие данные (1-5 мин) | Rate limits, нужен интернет | По требованию / дельты | **Рекомендация:** PBF как база + Overpass для свежих изменений **Регион:** По умолчанию Центральный ФО, потом — расширение на всю Россию ### 2. ETL Парсинг **Технология:** Pyrosm (Python + osmium) или нативный Osmium **Что парсим:** #### Дороги (highway=*) - `track` — грунтовые дороги (основной фокус!) - `tracktype=grade1-5` — классификация по твёрдости - `surface=unpaved/gravel/sand/mud/earth` — покрытие - `trail_visibility=yes/no/negative` — видимость тропы - `path` — тропы (пешие + вел/мото) - `mtb:scale=0-6` — сложность МТБ - `sac_scale=hiking/alpine/demanding` — уровень - `unclassified` + `residential` + `service` + `footway` — только для связки (фон) - `motorway/trunk/primary/secondary/tertiary` — асфальт (фон, минимум деталей) #### Рельеф - SRTM DEM (30 м) или SRTM 90 м - Тангенс угла наклона → визуализация крутизны - Перепады высот для оценки аттрактивности #### Препятствия и ориентиры ``` waterway=ditch + ford — броды и канавы (пройти или нет?) waterway=stream + ford — ручьи с бродом natural=wetland — болота (сложно!) natural=sand — пески natural=mud — грязевые участки power=line + tower — ЛЭП как визуальные ориентиры barrier=gate + bollard — шлагбаумы, столбики highway=milestone — километровые столбы abandoned=* — заброшенные дороги, шахты ruins=yes — ruins, объекты интереса leisure=nature_reserve — заповедники, ограничения boundary=national_park — нацпарки man_made=bridge ford=yes — броды! surface=water + highway=track — переправы highway=construction — строящиеся дороги (проехать?) ``` ### 3. Хранилище **Основной выбор:** Spatialite (SQLite с SpatialExtensions) - Меньше зависимостей, portable - Файл .sqlite, легко бэкап/мигрировать - Достаточно для одного региона **Альтернатива:** PostGIS (есть на FR24 VM!) - Если нужен мультирегион или больше данных - Лучшая производительность на больших масштабах - Уже есть инфраструктура **Структура таблиц:** ```sql -- Дороги CREATE TABLE trails ( id INTEGER PRIMARY KEY, osm_id INTEGER, highway_type TEXT, -- track, path, etc. track_type TEXT, -- grade1-5 surface TEXT, -- paved, gravel, sand, etc. name TEXT, geometry GEOMETRY, -- LINESTRING length_m REAL, -- длина в метрах start_elevation REAL, -- высота начала end_elevation REAL, -- высота конца max_slope REAL, -- макс уклон % avg_slope REAL, -- средний уклон % mtb_scale TEXT, -- mtb:scale visibility TEXT, -- trail_visibility access TEXT, -- access=private/no bridge TEXT, -- yes/no ford TEXT, -- yes/no tags JSON -- остальные теги ); -- Точки интереса (POI) CREATE TABLE poi ( id INTEGER PRIMARY KEY, osm_id INTEGER, poi_type TEXT, -- lake, viewpoint, ruins, etc. name TEXT, geometry GEOMETRY, -- POINT elevation REAL, tags JSON ); -- Слой рельефа CREATE TABLE elevation_grid ( id INTEGER PRIMARY KEY, geometry GEOMETRY, -- POLYGON (ячейка сетки) min_elev REAL, max_elev REAL, avg_elev REAL, slope_pct REAL -- наклон ); ``` ### 4. Роутинг **Технология:** OSRM (Open Source Routing Machine) или GraphHopper **Кастомизация профиля "Enduro":** | Фактор | Вес | |--------|-----| | Грунтовки grade3-5 | 🟢 Минимальный вес (привлекают!) | | Асфальт primary+ | 🔴 Максимальный вес (избегать) | | Рядом с озером/видом | 🟢 Бонус (притягивает маршрут) | | Броды | ⚠️ Средний (зависит от настроек) | | Болота/пески | 🔴 Высокий (сложность) | | Частная территория | ⛔ Проклятие (не роутить!) | | Макс уклон > 20% | ⚠️ Высокий (по желанию) | ### 5. Фичи для построения маршрутов #### 🛤️ "Дикий путь" (Wild Route) - **Вход:** точки А и Б - **Цель:** максимизировать грунтовку, минимизировать асфальт - **Алгоритм:** модифицированный Dijkstra с весами (грунтовка = -1, асфальт = +10) - **Настройки:** % грунтовки (50/70/90%), максимальная дистанция #### 🎨 "Красивый маршрут" (Scenic Route) - **Вход:** начальная точка, желаемая дистанция - **Цель:** замкнутый круг через живописные места - **Оценка аттрактивности:** - Близость к водоёмам (+10) - Перепад высот > 300 м (+15) - Видовые точки на маршруте (+20) - Наличие заброек/руин (+10) - Тропы с trail_visibility=yes (+5) - Прохождение через ЛЭП как ориентир (+3) #### 🏔️ "Горка" (Elevation Route) - **Вход:** точка старта, желаемый набор высоты - **Цель:** максимизировать перепад высоты, минимизировать дистанцию - **Использование:** тренировка, эндуро-кросс #### 🔗 "Связка" (Link Route) - **Вход:** два существующих трека - **Цель:** соединить их грунтовками, не по асфальту #### 📍 "Разведка" (Recon Mode) - **Вход:** точка на карте - **Выход:** все грунтовые дороги в радиусе X км - **Использование:** посмотреть что есть вокруг, исследовать местность #### 🚧 "Препятствия" (Obstacle Layer) - Карта с подсветкой всех бродов, шлагбаумов, болот, ЛЭП - Фильтр по сезонам: некоторые дороги непроходимы в межсезонье - Отчёт "что тебя ждёт" перед поездкой #### 📊 Статистика маршрута - Общая дистанция, % грунтовки, % асфальта - Набор/потеря высоты - Максимальный уклон - Прогноз времени (зависит от сложности) - Техничность: 1-5 по grade дорогам --- ## Фронтенд ### Веб-приложение (основное) - **Картографический движок:** MapLibre GL JS (open source форк Mapbox GL) - **Стили:** кастомный Mapbox GL Style JSON с перевёрнутой логикой: - Грунтовки = яркие, толстые, с градиентом по grade - Асфальт = тонкие серые линии - POI = иконки (озёра 💙, видовые точки 📷, заброек 🏚️) - Рельеф = heatmap с тангенсом угла - **Функции:** - Клик → статистика дороги (название, длина, grade, покрытие) - Рисование маршрута (ручной + автоматический роутинг) - Поиск по названиям/тэгам - Фильтр слоёв (вкл/выкл) - Экспорт GPX/KML ### PWA (Mobile) - Progressive Web App для работы оффлайн - Кэш тайлов для оффлайн навигации - GPS трекинг в реальном времени - Оффлайн роутинг (загрузка графа в браузер) --- ## Данные и лицензии ### OpenStreetMap - **Лицензия:** ODbL (Open Database License) - **Требования:** атрибуция (© OpenStreetMap contributors) - **Коммерческое использование:** разрешено с сохранением атрибуции ### SRTM (рельеф) - **Источник:** NASA/USGS - **Лицензия:** Public Domain - **Качество:** 30 м (1 arc-second), 90 м для регионов без SRTM 30 м ### Overpass API - **Термины использования:** https://wiki.openstreetmap.org/wiki/Overpass_API - **Rate limits:** необходимо уважать (не чаще 1-2 запросов/сек) - **Рекомендуемое использование:** для дельта-обновлений, not bulk download --- ## Технический стек (предварительный) | Компонент | Технология | Обоснование | |-----------|------------|-------------| | Парсинг PBF | Pyrosm (Python) + Osmium | Простота, Python-стек | | Хранилище | Spatialite | Портативность, zero-config | | Роутинг | OSRM + кастомный профиль | Быстрый, проверенный | | API Backend | FastAPI (Python) | Async, типизация | | Тайлы | TileServer GL или самописный | Поддержка MapLibre | | Фронт | MapLibre GL JS + React/Vanilla | Open source, производительность | | Мобильный | PWA + Service Workers | Оффлайн, без store | --- ## Этапы реализации ### Фаза 1: MVP (дьявол в деталях) - [ ] Настройка PBF загрузки выбранного региона - [ ] Парсинг и фильтрация highway=track + surface - [ ] Импорт в Spatialite - [ ] Базовый рендеринг тайлов (грунтовки яркие, асфальт серый) - [ ] Веб-карта с MapLibre GL ### Фаза 2: Роутинг - [ ] Установка OSRM + кастомный профиль "Enduro" - [ ] API для роутинга (точки А→Б → маршрут) - [ ] "Дикий путь" — минимизация асфальта - [ ] Экспорт GPX ### Фаза 3: Слои и фичи - [ ] Импорт SRTM DEM + расчёт уклонов - [ ] Слой рельефа - [ ] POI (водоёмы, видовые точки, заброшки) - [ ] Слой препятствий (броды, шлагбаумы, болота) ### Фаза 4: Продвинутый роутинг - [ ] "Красивый маршрут" — через живописные места - [ ] "Горка" — макс набор высоты - [ ] "Разведка" — грунтовки вокруг точки - [ ] Оценка маршрута (дистанция, сложность, время) ### Фаза 5: Мобильность - [ ] PWA с оффлайн тайлами - [ ] GPS трекинг - [ ] Интеграция с OsmAnd/Locus (экспорт) --- ## Вопросы для Славы 1. **Регион:** какой регион берём для начала? (ЦФО, вся Россия, конкретная область?) 2. **Хостинг:** разворачиваем FR24 VM (PostGIS) или локально на mva154? 3. **Бюджет на данные:** SRTM 30 м бесплатные, но если нужен ASTER (15 м) — $50/регион 4. **Мобильное:** PWA достаточно, или нужно нативное приложение (Android)? 5. **Совместное использование:** сделать публичным (кто хочет пользуется) или только для Славы? 6. **Приоритет:** что важней — роутинг, красивая визуализация, или оффлайн работа? --- *Документ будет дорабатываться после согласования со Славой*