Dark map: give the roads overlay the same invert/hue/brightness filter as tiles

Road colours were tuned for light tiles and blended into the inverted dark
tiles. Filter the roads pane identically: add the CSS rule for
.leaflet-roadsPane (record screen roads already use that pane), and on the
roads screen draw the polylines through a canvas renderer bound to a new
roadsPane so the same rule applies there too.
This commit is contained in:
4aiman 2026-10-19 19:26:20 +03:00
commit d4dda3da0c
4 changed files with 38 additions and 5 deletions

View file

@ -50,7 +50,7 @@
- **Сегменты - сворачиваемо** - в детали трека список сегментов высот (climb/descent, до десятков штук) свёрнут в аккордеон (`<details>`, свёрнут по умолчанию, счётчик в заголовке); тап разворачивает/сворачивает. Кнопки внизу (Похвастаться, Экспорт, Пересчитать, Удалить) остаются доступны без долгого скролла.
- **Де-джиттер трека** — сглаживание дрожащего GPS-трека методом Савицкого-Голея (настраиваемое окно/число итераций, живое превью на карте детали трека). Хранится обратимо: оригинал и сглаженный вариант лежат раздельно, калории пересчитываются по сглаженным точкам, откат к оригиналу в один тап. Точность каждого фикса (`accuracy_m`) пишется в БД: при пересчёте трека точки хуже порога «Макс. погрешность GPS» исключаются из расчёта и линии (обратимо — точки в БД остаются; поднять порог = вернуть). Работает во всех пересчётах (кнопка «Пересчитать», «Пересчитать всё», после де-джиттера); импорт/старьё без точности и dead-reckoning заполнения не трогает.
- **POI на карте** — точки интереса (кафе, магазины, вода, туалеты, банки/ATM, остановки, укрытия, смотровые и т.д.) круглыми контрастными значками (эмодзи в кружке, читаемо на светлой и тёмной карте). Кнопка `📍` с панелью-фильтром категорий; рендер по видимой области от зума 13. Данные оффлайн (`data/pois.json`, ~100 км вокруг опорной точки, 5662 объекта из OSM/Overpass). На картах записи, деталей трека и дорог.
- **Тёмная карта** — тумблер `☾` на экранах записи, деталей трека и дорог: инвертирует ТОЛЬКО слой тайлов (`invert + hue-rotate 180° + brightness`, трек/маршрут/дороги остаются цветными), выбор запоминается. Работает одинаково на офлайн-тайлах и онлайне, без ключей/квот/перепаковки.
- **Тёмная карта** — тумблер `☾` на экранах записи, деталей трека и дорог: инвертирует слой тайлов (`invert + hue-rotate 180° + brightness`, трек/маршрут остаются цветными), выбор запоминается. Оверлей дорог получает ТОТ ЖЕ фильтр (пан `roadsPane`), чтобы его цвета сдвигались вместе с тайлами и оставались контрастными на тёмной карте. Работает одинаково на офлайн-тайлах и онлайне, без ключей/квот/перепаковки.
- **Метки ветра** — кнопка «Ветер» на экране записи: тап открывает интервал встречного ветра, тап закрывает. Метки хранятся с треком (`wind_marks`) как эталон для проверки оценки ветра по треку; на расчёт калорий/мощности не влияют. Голосовые метки — на будущее.
- **Слежение карты (тумблер `⊕`)** — на экране записи карта по умолчанию центрируется на текущей позиции при каждой новой точке. Кнопка `⊕` (подсвечена = слежу) выключает автоцентрирование: карту можно свободно подвигать и осмотреться, когда «где я» непонятно (отклонился от трека или трек ведёт туда, где дороги нет), а новые точки её не возвращают. Повторный тап центрирует на текущей позиции и включает слежение снова. По умолчанию включено при каждом заходе (не запоминается).
- **Экспорт/импорт** — свои продукты, рецепты и добавки одним файлом (JSON).

View file

@ -0,0 +1,25 @@
# Сессия 2026-10-19 - тёмные дороги на тёмной карте + диагностика незагруженных тайлов
## Задача 1: дороги не видны на тёмной карте
Тёмный фильтр (`invert(1) hue-rotate(180deg) brightness(1.5)`) висел только на
`.leaflet-tile-pane`; цвета дорог (под светлые тайлы) на инвертированных тайлах сливались.
Сделано (тот же фильтр на пан дорог, авто по классу `body.dark-map`, без перерисовки):
- styles.css: добавлено `body.dark-map .leaflet-roadsPane { filter: invert(1) hue-rotate(180deg) brightness(1.5); }`.
- Экран записи: дороги уже в `roadsPane` (SVG) - правок не нужно, правило применилось само.
- Экран "Дороги" (`showRoadsMap`, canvas): добавлен пан `roadsPane` (zIndex 240) и
`L.canvas({pane:"roadsPane"})`-рендер, полилинии дорог рисуются через него -> тот же фильтр
накрывает и этот экран.
- Трек/маршрут/POI не трогали (пользователь просил дороги).
Проверка: синтаксис JS ок. На телефоне: тумблер Луна на записи и на экране "Дороги" - дороги
контрастны и на тёмной, и на светлой; трек/маршрут не инвертированы. (Живую проверку делает
пользователь.)
## Задача 2: незагруженные тайлы на 90-км треке (только диагностика, без правок)
Факты от пользователя: офлайн-карты ВЫКЛ, мобильный интернет в поездке БЫЛ. Значит код
(`tilecache.js` createTile) должен был тянуть тайлы с OSM - пустота при живой сети это
аномалия, нужны факты. bbox трека: lat 47.47-47.57, lon 40.08-40.48 (Ростовская обл.).
План диагностики (read-only): CDP в живой WebView (localStorage.baldav_offline_maps,
TileCache.count(), перебор IndexedDB baldav_tiles по bbox на зумах 13-16) + logcat при
открытии трека (идут ли фетчи на a.tile.openstreetmap.org и статус). Результат - отдельно.

View file

@ -1279,9 +1279,13 @@ select {
zoom controls. Give them slots in the right-hand stack. */
.rec-nogo-btn { right: 8px; bottom: 314px; }
.rec-reroute-btn { right: 8px; bottom: 352px; }
/* Dark map: invert ONLY the tile layer (overlays — track, route, roads, puck — keep
their colours). User-tuned filter on OSM standard tiles. Applies to every Leaflet map. */
/* Dark map: invert ONLY the tile layer (track, route, puck keep their colours).
User-tuned filter on OSM standard tiles. Applies to every Leaflet map. */
body.dark-map .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) brightness(1.5); }
/* Roads overlay was tuned for LIGHT tiles, so on inverted (dark) tiles it blended in.
Give the roads pane the SAME filter as the tiles so road colours shift identically and
stay contrasting. Roads live in `roadsPane` (record screen SVG + roads screen canvas). */
body.dark-map .leaflet-roadsPane { filter: invert(1) hue-rotate(180deg) brightness(1.5); }
/* Darken the map backdrop too, else the light Leaflet container (#ddd) flashes bright
between/behind tiles while zooming or where a tile is missing. */
body.dark-map .leaflet-container { background: #1b1f24; }

View file

@ -8748,11 +8748,15 @@ async function showRoadsMap() {
}
if (seg.length >= 2) segments.push({ coords: seg, atype: segType });
// Draw: bike = blue, walk = brown
// Draw: bike = blue, walk = brown. Roads go in their own pane with a dedicated canvas
// renderer so the dark-map CSS filter (body.dark-map .leaflet-roadsPane) can invert/shift
// road colours the same way it does the tiles — keeps them visible on the dark map.
if (!map.getPane("roadsPane")) { map.createPane("roadsPane"); map.getPane("roadsPane").style.zIndex = 240; }
let roadsRenderer = L.canvas({ pane: "roadsPane" });
let allCoords = [];
for (let s of segments) {
let color = roadColor(s.atype);
L.polyline(s.coords, { color, weight: 4, opacity: 1, smoothFactor: 2.5 }).addTo(map); // px-space simplify: fewer points zoomed out
L.polyline(s.coords, { color, weight: 4, opacity: 1, smoothFactor: 2.5, renderer: roadsRenderer }).addTo(map); // px-space simplify: fewer points zoomed out
allCoords.push(...s.coords);
}