Архитектура Enduro Trails
Обзор
Веб-приложение для планирования эндуро-маршрутов с визуализацией рельефа.
Компоненты
- Frontend — MapLibre GL JS, vanilla JS (ES modules)
- Backend API — FastAPI (Python 3.12), uvicorn
- Tile Server — статические raster tiles (PNG), раздаются через FastAPI/nginx
- Routing Engine — OSRM с кастомным эндуро-профилем
- Database — SQLite + Spatialite (точки интереса, маршруты, публичные GPS-треки)
- GPS Tracks Pipeline —
gps-collector(docker-compose service,profiles: [batch]), запускается host cron'ом 1–2 раза в неделю; собирает публичные GPS-треки с внешних платформ вdata/gps_tracks.sqlite(ET-008 / ADR-007)
Слои карты
- Base map: Схема (OpenStreetMap raster) либо Спутник (Esri World Imagery raster) — переключается в UI (ET-007 / ADR-004)
- Hillshade (рельеф с тенями)
- TRI (Terrain Ruggedness Index — сложность рельефа)
- Hypsometric (высотная раскраска)
- Trails (маршруты из OSM)
Внешние тайл-провайдеры
Клиент (браузер) обращается напрямую к двум внешним raster-tile сервисам. Сервер mva154 эти тайлы не проксирует и не кэширует.
| Провайдер | Назначение | URL | Активация | API-ключ |
|---|---|---|---|---|
| OpenStreetMap | Базовый слой «Схема» | https://tile.openstreetmap.org/{z}/{x}/{y}.png |
всегда (default подложка) | нет |
| Esri World Imagery | Базовый слой «Спутник» | https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x} |
лениво — только при включении «Спутник» пользователем (ET-007) | нет |
Атрибуция обоих провайдеров выводится MapLibre автоматически при активном source.
GPS Tracks Pipeline (ET-008)
Серверный офлайн-pipeline сбора публичных GPS-треков. Не часть runtime API, изолирован отдельным docker-compose service'ом и отдельной БД.
Компонент
- Сервис:
gps-collectorвdocker-compose.yml,profiles: ["batch"], тот же образ чтоapp, не стартует приdocker compose up -d. - Точка входа:
scripts/gps_collect.py(см.src/api/gps_tracks/). - Расписание: cron на mva154, Mon + Thu 03:00 UTC; + ежемесячный GC.
- БД:
data/gps_tracks.sqlite(SQLite + Spatialite, отдельный файл отcentralfederal.sqlite).
Внешние источники pipeline
Скрейпинг/API только из контейнера gps-collector, при наличии
accepted-ADR на источник.
| Источник | Доступ | Лицензия | ADR | MVP |
|---|---|---|---|---|
| OSM Public GPS Traces | API api.openstreetmap.org/api/0.6/trackpoints |
ODbL | ADR-009 (accepted) | да |
| EnduroRussia.ru | публичный JSON API endurorussia.ru/api/tracks |
публичная, обезличенно (без user) | ADR-010 (accepted; активирован в ET-009) | да |
| Wikiloc | HTML-парсинг www.wikiloc.com + downloadTrail.do |
proprietary, некоммерческое использование, обезличенно | ADR-012 (accepted; активирован в ET-009) | да |
| ttrails.ru / Тропинки.ру | HTML + GPX-ссылки | требует review | ADR-011 (proposed/blocked) | условно |
Источник без status: accepted в ADR pipeline'ом пропускается (см.
ADR-007 §6 licensing guard).
Клиентский слой публичных треков
Двухрежимная отдача (см. ADR-008):
- z=8..11 — MVT через
GET /api/gps-tracks/tiles/{z}/{x}/{y}.mvt+ сервер-LRU. - z≥12 — GeoJSON через
GET /api/gps-tracks?bbox=...&activity=...&source=.... - z<8 — слой скрыт (защита от шторма запросов).
Скачивание одного трека из popup карты (ET-011):
GET /api/gps-tracks/{track_id}/download — отдаёт GPX 1.1 с
правильным Content-Disposition и UTF-8 именем по RFC 5987. Разрешено
только для источников с download_allowed: true в
config/gps_sources.yaml (MVP: только osm). Cap 200000 точек →
413 Payload Too Large. См. ADR-014 / ADR-015.
Health/observability: GET /api/gps-tracks/health — состояние БД,
число треков по источникам, последний прогон.
Деплой
Один Docker Compose на mva154. Nginx проксирует /enduro/ на контейнер.
Клиентские модули (src/web/)
| Модуль | Описание | Work Item |
|---|---|---|
app.js |
Главный модуль: MapLibre, роутинг, UI, тёмная тема | PH-1..PH-6 |
units.js |
Централизованный форматтер расстояний (км/мили), localStorage, событие unitchange |
ET-005 |
gpx.js |
GPX 1.1 парсер (DOMParser), рендеринг треков/waypoints, canvas-профиль высот, rebuildMapOverlays() |
ET-006 |
gps_tracks.js |
Слой публичных GPS-треков (MVT + GeoJSON гибрид по zoom), фильтры по активности/источнику, popup с метаданными, halo на спутнике, restorePublicTracksState() |
ET-008 |
style.json |
MapLibre стиль (светлая тема) | PH-1/PH-5 |
style-dark.json |
MapLibre стиль (тёмная тема) | PH-5 |