131 lines
6.0 KiB
Markdown
131 lines
6.0 KiB
Markdown
# BRD: Рельеф (Terrain Layer)
|
||
|
||
## Цель
|
||
Пользователь видит рельеф местности на карте — цветами (все зумы) и тенями (зум 10+). Это позволяет на мелком зуме искать интересные холмистые/горные зоны, а на крупном — детально планировать маршрут по оврагам и склонам.
|
||
|
||
## Пользовательский сценарий
|
||
1. Открывает карту на зуме 6 (весь ЦФО)
|
||
2. Видит зелёные равнины, жёлтые холмы, коричневые горы
|
||
3. Находит интересную гористую зону
|
||
4. Зумит туда
|
||
5. На зуме 12+ добавляются тени — овраги и склоны становятся объёмными
|
||
6. Строит маршрут по интересному рельефу
|
||
|
||
## UI
|
||
|
||
### Кнопка в toolbar
|
||
- Иконка: 🏔️ (или `mountain` из Lucide)
|
||
- Позиция: после кнопки слоёв, перед линейкой
|
||
- Состояние: inactive (серая) / active (белая, подсвечена)
|
||
|
||
### Попап при нажатии
|
||
```
|
||
┌─────────────┐
|
||
│ 🏔️ Рельеф │
|
||
├─────────────┤
|
||
│ ☑️ Цветной │ ← всегда доступен
|
||
│ рельеф │
|
||
│ │
|
||
│ ☐ Теневой │ ← disabled на зуме < 10
|
||
│ рельеф │ (grayed out с подписью
|
||
│ │ "Доступно при приближении")
|
||
└─────────────┘
|
||
```
|
||
|
||
- Чекбоксы независимые
|
||
- Состояние сохраняется в localStorage
|
||
- Попап закрывается по тапу вне его или повторному тапу на кнопку
|
||
|
||
## Слои на карте (MapLibre)
|
||
|
||
### Цветной рельеф (hypsometric)
|
||
- **Z-Index:** между `background` и основными слоями (дороги, POI)
|
||
- **Opacity:** 0.4-0.5 (настраиваемо)
|
||
- **Zoom:** 5-15 (все зумы)
|
||
- **Source:** `terrain-hypso` → растровые тайлы `/terrain/hypso/{z}/{x}/{y}.png`
|
||
|
||
### Теневой рельеф (hillshade)
|
||
- **Z-Index:** поверх цветного, под дорогами
|
||
- **Opacity:** 0.3-0.4
|
||
- **Zoom:** 10-15 (minzoom 10)
|
||
- **Source:** `terrain-hillshade` → `/terrain/hillshade/{z}/{x}/{y}.png`
|
||
- **Visibility:** none при зуме < 10 (MapLibre `minzoom` + toggle)
|
||
|
||
## Данные
|
||
|
||
### Источник
|
||
SRTM 1 Arc-Second Global (~30м разрешение)
|
||
- Формат: `.hgt` файлы
|
||
- Лицензия: Public Domain (NASA)
|
||
- Покрытие: 60°N - 56°S
|
||
|
||
### Регион
|
||
ЦФО + Чувашия (первый этап)
|
||
- ~30-40 тайлов .hgt (1°×1°)
|
||
- ~100 MB сырых данных
|
||
|
||
### Генерация тайлов
|
||
|
||
#### Цветной рельеф
|
||
- GDAL: `gdaldem color-relief` с кастомной ramp
|
||
- Цвета:
|
||
- 0-50м: #2d5016 (тёмно-зелёный)
|
||
- 50-150м: #5a8a3a (зелёный)
|
||
- 150-300м: #a8c66c (светло-зелёный)
|
||
- 300-500м: #d4b85a (жёлтый)
|
||
- 500-800м: #c49420 (оранжево-жёлтый)
|
||
- 800-1200м: #8b5a2b (коричневый)
|
||
- 1200-2000м: #6b4423 (тёмно-коричневый)
|
||
- 2000м+: #ffffff (белый, снежные вершины)
|
||
- Растеризация в тайлы: `gdal2tiles.py` или rio-tiler
|
||
- Формат: PNG с прозрачностью (или без, opacity в MapLibre)
|
||
- Зумы: 5-15
|
||
- Размер тайла: 256×256
|
||
- Итоговый объём: ~50-100 MB (оценочно)
|
||
|
||
#### Теневой рельеф
|
||
- GDAL: `gdaldem hillshade` (-az 315 -alt 45)
|
||
- Grayscale PNG
|
||
- Зумы: 10-15
|
||
- Итоговый объём: ~20-40 MB
|
||
|
||
### Хранение
|
||
- Сервер: `/home/slin/enduro-trails/data/terrain/`
|
||
- `hypso/{z}/{x}/{y}.png`
|
||
- `hillshade/{z}/{x}/{y}.png`
|
||
- Nginx: location `/enduro/terrain/` → alias `/home/slin/enduro-trails/data/terrain/`
|
||
- Кэширование: `expires 1y` (тайлы не меняются)
|
||
|
||
## Интеграция с существующим кодом
|
||
|
||
### Backend (FastAPI)
|
||
- Новый endpoint не нужен — nginx отдаёт статику
|
||
- При необходимости: `/terrain/{layer}/{z}/{x}/{y}.png` → FileResponse
|
||
|
||
### Frontend (MapLibre)
|
||
- Добавить `raster` sources в стиль карты
|
||
- Добавить `raster` layers с `paint: { 'raster-opacity': ... }`
|
||
- Toolbar: кнопка + попап компонент
|
||
- localStorage ключ: `terrain_layers`
|
||
|
||
### Стили
|
||
- Тёмная тема: ramp адаптирован под тёмную подложку
|
||
- Светлая тема: ramp адаптирован под светлую (после F-18)
|
||
|
||
## Приоритет
|
||
P1 — блокер для фазы 6 (SRTM профиль высот, фича «Горка»)
|
||
|
||
## Критерии приёмки
|
||
- [ ] На зуме 6 виден цветной рельеф всего ЦФО
|
||
- [ ] Москва — зелёная, Смоленская возвышенность — жёлтая, Урал на востоке — коричневый
|
||
- [ ] На зуме 12+ теневой рельеф показывает овраги и склоны
|
||
- [ ] Тoggle работает: можно цветной без теневого, теневой без цветного, оба, ни одного
|
||
- [ ] Состояние сохраняется после перезагрузки
|
||
- [ ] Мобильный: попап не перекрывает кнопки, закрывается по тапу вне
|
||
- [ ] Десктоп: попап позиционируется относительно кнопки
|
||
|
||
## Зависимости
|
||
- SRTM данные (скачать)
|
||
- GDAL в контейнере/на сервере (или отдельный скрипт генерации)
|
||
- Место на диске: ~150 MB тайлов
|