auto-sync: 2026-05-13 14:40:01

This commit is contained in:
Stream
2026-05-13 14:40:07 +03:00
parent 10b37a3bee
commit fc450b5aab
2 changed files with 112 additions and 0 deletions

61
memory/2026-05-13.md Normal file
View File

@@ -0,0 +1,61 @@
# 2026-05-13 — Terrain UI фикс + генерация тайлов
## Что сделано
### Terrain UI баги (из UI-тестов)
- **Попап terrain** — позиционирование исправлено (привязка к кнопке, а не top-right угол)
- **Подписи чекбоксов** — были невидимы из-за отсутствия шрифтов в headless Chromium. Установлены Noto Sans в тестовое окружение. В реальном браузере подписи были видны всегда.
- **"Зум 10+"** подсказка для hillshade — теперь вызывается при открытии попапа + стилизована заметно
- **Переименование:** Гипсометрия → "Высоты цветом", Отмывка → "Тени рельефа"
- **Opacity:** снижен с 0.85 → 0.65 для читаемости подписей населённых пунктов
### Генерация hypso тайлов
- **Root cause пустых тайлов:** VRT создавался с относительными путями к HGT, сохранялся в другую директорию → GDAL не находил source files → все пиксели = 0
- **Фикс:** VRT строится с абсолютными путями через `-input_file_list`
- **Тестовая генерация:** Чувашия (зумы 5-14) — подтверждена работоспособность
- **Полная генерация:** 81 HGT файл, зумы 5-12, ~48K тайлов
### Скачивание недостающих SRTM
- Дыра E041-E046 (Владимир — Нижний Новгород — Чебоксары) закрыта
- 14 файлов скачаны с kurviger.de зеркала (User-Agent нужен!)
- Итого: 81 HGT файл (было 67)
### Новый слой: Перепады (TRI — Terrain Ruggedness Index)
- Отдельный чекбокс "Перепады" в попапе рельефа
- Алгоритм: gdaldem TRI → color-relief с порогами от TRI=3
- Цветовая шкала: прозрачный (плоско) → жёлтый (3-5) → оранжевый (5-10) → красный (10+)
- Первая версия порогов (TRI=10) была слишком высокой — среднее TRI=2.97
- Пересгенерено с порогом от 3 — теперь видно
### Деплой
- Статика отдаётся через контейнер `prototype-enduro-trails-1` (FastAPI)
- Файлы на хосте НЕ = файлы в контейнере (образ вкомпилен при сборке)
- Нужен `docker cp` после каждого изменения CSS/JS/HTML
- Nginx location `/enduro/terrain/``/home/slin/enduro-trails/data/terrain/` (тайлы с хоста напрямую)
## Технические заметки
### SRTM зеркала
- `firmware.ardupilot.org/SRTM/ap_srtm3/` — ненадёжно (0 байт)
- `srtm.kurviger.de/SRTM3/Eurasia/` — работает, но нужен User-Agent (403 без него)
- `viewfinderpanoramas.org/dem3/` — таймауты
### Headless Chromium шрифты
- Контейнер OpenClaw не имеет шрифтов и fontconfig
- Установлены Noto Sans в `~/.local/share/fonts/` + fontconfig из deb
- Без этого кириллица не рендерится в скриншотах
### TRI color ramp (финальный)
```
0-2: прозрачный
3: жёлтый (alpha 60)
4: жёлтый (alpha 100)
5: оранжевый (alpha 140)
7: тёмно-оранжевый (alpha 180)
10: красный (alpha 200)
15+: тёмно-красный (alpha 220+)
```
## TODO
- [ ] Попап terrain: третий чекбокс обрезается на мобильном — нужен overflow/scroll или сдвиг позиции
- [ ] На зуме 10 MapLibre запрашивает тайлы зума 11 (devicePixelRatio?) — нужно генерить зум 11 тоже или разобраться с overzooming

View File

@@ -0,0 +1,51 @@
import urllib.request
import zipfile
import os
SRTM_DIR = '/home/slin/enduro-trails/data/srtm'
BASE_URL = 'https://srtm.kurviger.de/SRTM3/Eurasia'
# Smolensk ~32E to Solnechnogorsk ~37E
# Latitudes: N53-N56 (Smolensk is at 54.8N, Moscow at 55.7N)
tiles = []
for lat in [53, 54, 55, 56]:
for lon in range(32, 37):
tiles.append(f'N{lat}E{lon:03d}')
os.chdir(SRTM_DIR)
count = 0
opener = urllib.request.build_opener()
opener.addheaders = [('User-Agent', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36')]
urllib.request.install_opener(opener)
for tile in tiles:
hgt = f'{tile}.hgt'
if os.path.exists(hgt):
print(f' EXISTS: {hgt}')
continue
url = f'{BASE_URL}/{tile}.hgt.zip'
tmp = f'/tmp/{tile}.hgt.zip'
try:
print(f' Downloading {tile}...', end=' ', flush=True)
urllib.request.urlretrieve(url, tmp)
if os.path.getsize(tmp) > 0:
with zipfile.ZipFile(tmp, 'r') as z:
z.extractall('.')
os.remove(tmp)
size = os.path.getsize(hgt) if os.path.exists(hgt) else 0
print(f'OK ({size // 1024}KB)')
count += 1
else:
print('EMPTY')
os.remove(tmp)
except Exception as e:
print(f'FAIL: {e}')
if os.path.exists(tmp):
os.remove(tmp)
print(f'\nDownloaded: {count} new files')
print(f'Total HGT: {len([f for f in os.listdir(".") if f.endswith(".hgt")])}')