# 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 тайлов
