16 KiB
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!)
- Если нужен мультирегион или больше данных
- Лучшая производительность на больших масштабах
- Уже есть инфраструктура
Структура таблиц:
-- Дороги
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)
- Вход: точки А и Б
- Цель: максимизировать грунтовку, минимизировать асфальт
- Реализация (v0.2, OSRM):
- Кастомный профиль
enduro.luaдляosrm-routed weight_name = 'routability'— OSRM оптимизирует не по времени, а по предпочтительности дорогforward_speed = 30для всех типов дорог — duration одинаковый, выбор идёт ТОЛЬКО поforward_rateforward_rate(чем выше — тем предпочтительнее): track=100, bridleway=90, path=85, cycleway=70, motorway=0.1tracktypeмультипликатор: grade1×1.3 (твёрдая грунтовка), grade3×1.0, grade5×0.8 (размытая тропа)weight = distance / forward_rate— самый короткий путь по грунтовкам, даже если ехать дольше- U-turn penalty 20s, развороты разрешены
- Граф ~5.2 GB из
enduro.osm.pbf(ЦФО + Чувашия), контейнерosrm-routedпорт 5559
- Кастомный профиль
- Проблемы: может строить "вне дорог" через unmapped-связи между нодами OSM
🎨 "Красивый маршрут" (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 (экспорт)
Вопросы для Славы
- Регион: какой регион берём для начала? (ЦФО, вся Россия, конкретная область?)
- Хостинг: разворачиваем FR24 VM (PostGIS) или локально на mva154?
- Бюджет на данные: SRTM 30 м бесплатные, но если нужен ASTER (15 м) — $50/регион
- Мобильное: PWA достаточно, или нужно нативное приложение (Android)?
- Совместное использование: сделать публичным (кто хочет пользуется) или только для Славы?
- Приоритет: что важней — роутинг, красивая визуализация, или оффлайн работа?
Документ будет дорабатываться после согласования со Славой