Appearance
Use Case #10: Эхолокация рельефа (Связь карты и графика высот)
1. В чем проблема? (Зачем это вообще нужно)
Представь: ты построил на сайте маршрут на 50 километров.
- Сверху экрана — карта. По ней идет синяя линия твоего пути.
- Снизу экрана — график высот (горы и ямы). В самой середине графика ты видишь ОГРОМНУЮ ГОРУ.
- Боль юзера: Ты сидишь и думаешь: "Блин, а где эта гора физически находится на карте? Это в лесу? Возле какого города начнется этот подъем?". Тебе приходится гадать, потому что карта и график — это просто две отдельные неживые картинки.
2. Как это ДОЛЖНО работать (Магия для пользователя)
Мы свяжем карту и график невидимой нитью, чтобы они откликались на движения мышки.
- Сценарий А: «Ищу гору» Ты просто наводишь курсор мыши на самую высокую гору на графике внизу. В ЭТУ ЖЕ СЕКУНДУ сверху на карте, прямо на твоем синем маршруте, загорается яркий маркер. Ты ведешь мышку по графику вправо-влево (вниз по склону) — а маркер послушно бегает по карте вдоль дороги! Проблема решена за 1 секунду.
- Сценарий Б: «Смотрю на дорогу» Ты видишь какую-то извилистую тропинку на карте и думаешь: "Тут спуск или подъем?". Наводишь мышку на эту тропинку прямо на карте. В эту же секунду на графике внизу загорается вертикальная полоска-подсветка! Ты сразу видишь ответ.
3. СЕКРЕТ ДЛЯ ПРОГРАММИСТА (Как сделать так, чтобы не глючило)
⚠️ Внимание: тут ошибаются 90% новичков!
❌ Как делать НЕ НАДО (Ошибка координат): Плохой программист попытается связать карту и график по GPS-координатам [x, y]. Почему это сломается: Если юзер поехал маршрут "Туда-Обратно", синяя линия маршрута легла сама на себя. Если юзер наведет мышку на эту дорогу на карте, программа запутается: "Ой! Юзер ехал тут ТУДА (утром) и ОБРАТНО (вечером). Какую высоту мне показать?!". Точка начнет бешено прыгать туда-сюда (Проблема Маятника).
✅ Как делать ПРАВИЛЬНО (Правило «Нитка с бусами»): Забудь про GPS-координаты для этой фичи!
- Представь, что маршрут — это просто длинная нитка, на которую по очереди надели 5000 бусинок. У каждой бусинки есть строгий порядковый номер (от 0 до 5000). Это называется Индекс.
- График внизу состоит из тех же самых 5000 бусинок.
Как работает идеальная программа:
- Юзер навел мышку на гору на графике. Программа смотрит: "Так, мышка сейчас висит над бусинкой №400".
- График ничего не высчитывает, он просто кричит Карте через глобальный стейт: "Эй, Карта! Подсвети красным цветом бусинку №400!".
- Карта находит у себя 400-ю бусинку и рисует на ней красную точку. ВСЁ!
Программе абсолютно плевать, что путь "Туда" (бусинка №100) и путь "Обратно" (бусинка №4900) физически лежат на одном асфальте. Номера-то разные! Точка бегает идеально плавно.
4. Высший пилотаж UX (Zoom-to-Selection)
- Если юзер зажал левую кнопку мыши на графике и выделил прямоугольником всю гору целиком (Drag Selection).
- Камера на карте автоматически делает Zoom-to-fit (подбирает Bounding Box), крупно и плавно показывая именно этот выделенный подъем на экране.
Эпики и Задачи
Epic 1: Двухсторонняя синхронизация (Нитка с бусами)
- Task 1.1: Реализовать глобальный стейт
hoveredPointIndex(Zustand), принимающийnumber | null. - Task 1.2 (График -> Карта): При
mousemoveнад компонентом Графика вычислять индекс пересечения (по X оси) и сетить его вhoveredPointIndex. Подписывать слой карты на этот индекс для рендера плавающего маркера. - Task 1.3 (Карта -> График): При
mousemoveнад MapLibre линией вычислять индекс ближайшей вершины (feature.idили поиск по массиву) и сетить вhoveredPointIndex. Подписывать График на этот индекс для отрисовки вертикального тултипа.
Epic 2: Zoom-to-Selection
- Task 2.1: Имплементировать выделение (Brush tool) на графике высот.
- Task 2.2: При событии
onBrushEndизвлекать срез массива отstartIndexдоendIndex, вычислять для негоBoundingBoxи вызывать методmap.fitBounds(bbox)с плавной анимацией.