10 KiB
10 KiB
type, work_item_id, title, version, status, created_at, updated_at, authors
| type | work_item_id | title | version | status | created_at | updated_at | authors | |
|---|---|---|---|---|---|---|---|---|
| brd | ET-010 | BRD: Координаты центра карты в scale-zoom-bar | 1 | draft | 2026-05-31 | 2026-05-31 |
|
BRD — ET-010: Координаты центра карты в scale-zoom-bar
1. Цель
Дать пилоту-эндуристу возможность мгновенно «снять» координаты любой точки маршрута, центрировав на ней карту — без открытия адресной строки браузера, без копирования из URL-хеша и без переключения в сторонние навигаторы.
Дополнительно — эта работа служит end-to-end final dry-run
проверкой пайплайна analyst → architect → coder → tester после
слияния PR #9 (UI/visual testing). Цели dry-run:
- Подтвердить, что полный пакет артефактов аналитика (BRD + ТЗ + AC + test-plan + UI-test-cases) собирается, валидируется и синхронизируется в pipeline без ручного вмешательства.
- Подтвердить, что UI-составляющая (Playwright + screenshot) стабильна на «зелёной» минимальной задаче.
- Подтвердить, что параллельные dry-run работы (ET-009 / ET-010) не конфликтуют по зонам ответственности.
2. Контекст
- Веб-приложение: MapLibre GL JS 4.7 + vanilla JS, без фреймворка.
- Базовая страница:
src/web/index.html; стили —src/web/app.css; логика —src/web/app.js. - В
src/web/app.js:1405-1409уже создаётся custom-overlay#scale-zoom-bar(top-right) с двумя суб-элементами:.szb-scale— горизонтальная шкала с подписью «30 km»;.szb-zoom— зум-индикатор «z7». Обновление обоих делаетupdateScaleZoom(), навешанная наmap.on('move')иmap.on('zoom').
- Координаты центра карты уже доступны через
map.getCenter()→{ lng, lat }. - Параллельная задача ET-009 добавляет нативный
maplibregl.ScaleControlвbottom-left. Не пересекается с ET-010. - Темы (день/ночь): переключение реализовано через
switchMapStyle()→map.setStyle()→rebuildMapOverlays(). Кастомный#scale-zoom-barсуществует независимо от стиля MapLibre и не затирается приsetStyle(). - Backend и БД не затрагиваются.
3. Scope
In scope
| # | Функция |
|---|---|
| F-01 | Новый суб-элемент .szb-coords внутри #scale-zoom-bar |
| F-02 | Текст элемента — "<lat>, <lon>" с тремя знаками после запятой |
| F-03 | Обновление координат происходит в существующей updateScaleZoom() |
| F-04 | Координаты обновляются на map.on('move') (включая зум) |
| F-05 | Цвет / шрифт / выравнивание — совместимы с соседними .szb-* на обеих темах |
| F-06 | Поведение при setStyle() (тема): #scale-zoom-bar не пересоздаётся, текст остаётся |
| F-07 | Доступность: .szb-coords имеет aria-hidden="true" (декоративный элемент) |
| F-08 | Координаты обновляются и в десктопном, и в мобильном viewport |
Out of scope
- Координаты курсора при
mousemove(тач не работает). - Копирование координат по клику в clipboard.
- Форматы координат, отличные от десятичных (DMS, MGRS).
- Локализация (буквы N/E/S/W) — показываем чистые числа.
- Высота центра карты (это PH-8 Elevation Profile).
- Сохранение «показывать/скрывать координаты» в
localStorage. - Изменение поведения индикатора линейки
#ruler-info. - Backend-эндпоинт настроек пользователя.
4. Метрики успеха
| Метрика | Критерий |
|---|---|
| Видимость индикатора | Элемент .szb-coords присутствует в DOM на каждой загрузке |
| Дефолтное значение | После загрузки на дефолтной позиции (55.5, 40.5) текст — "55.500, 40.500" |
| Реакция на panning | После map.panTo([41.0, 56.0]) текст становится "56.000, 41.000" (± 0.001) |
| Реакция на зум | При зум-ин/зум-аут центр карты тот же → координаты не меняются (а вот .szb-zoom меняется) |
| Формат | Всегда три знака после точки, разделитель ", ", без N/E/S/W |
| Отрицательные координаты | Лондон (51.5, -0.1) показывается как "51.500, -0.100" |
| Совместимость с темой | После переключения темы (#btn-theme) текст продолжает обновляться, цвет читаем |
| Совместимость с overlay-ями | После загрузки GPX / построения маршрута / переключения рельефа .szb-coords обновляется |
| Производительность | На пять последовательных panBy подряд UI не «лагает», нет ошибок в console.error |
| Не ломает существующий функционал | Шкала и зум-индикатор продолжают работать как раньше |
| Доступность | .szb-coords имеет aria-hidden="true"; скринридер не зачитывает координаты |
5. Риски
| Риск | Вероятность | Влияние | Митигация |
|---|---|---|---|
Конфликт с ET-009 (ScaleControl в bottom-left) |
Низкая | Низкое | Разные зоны экрана; никаких общих DOM-узлов |
#scale-zoom-bar пропадает при setStyle() |
Низкая | Низкое | Элемент уже устойчив к setStyle() (существующий код); проверяется AC-05 |
| Текст координат «прыгает» по ширине (3 → 4 знака) | Средняя | Низкое | Фиксируем toFixed(3) всегда — ширина строки стабильна |
На мобильном #scale-zoom-bar становится узким, координаты не помещаются |
Средняя | Среднее | Используем white-space: nowrap и flex-обёртку; см. ТЗ §3 UI/UX |
Слишком частые map.on('move') вызывают перерисовку DOM |
Низкая | Низкое | Обновляем DOM только если значение текста реально изменилось |
| Скринридер начинает зачитывать обновляющиеся координаты | Низкая | Среднее | aria-hidden="true" на .szb-coords |
Отрицательные координаты округляются неверно (-0.0005 → "-0.000") |
Низкая | Низкое | Используем Number.parseFloat(x.toFixed(3)) или принимаем "-0.000" как корректно |
6. Зависимости
- Внешние: нет. Никаких новых сетевых запросов, API-ключей или внешних сервисов.
- Внутренние: использует существующую функцию
updateScaleZoom()и существующий DOM-узел#scale-zoom-bar(src/web/app.js:1405-...). - Параллельные work item:
- ET-007 (satellite map) — не затрагивает
#scale-zoom-bar, разные файлы (style*.json,index.html, новые функции). Конфликта нет. - ET-009 (
ScaleControlвbottom-left) — другой DOM-узел, другой угол карты. Конфликта нет.
- ET-007 (satellite map) — не затрагивает
- Файлы: только
src/web/app.js(расширениеupdateScaleZoom()и создание.szb-coords) иsrc/web/app.css(стили.szb-coords). - Backend, БД, OSRM, миграции, контейнеры — не затрагиваются.