Обработчики событий карты

Обработчики событий в HERE Technologies и JavaScript API карты HERE Maps API for JavaScript являются ключевым механизмом взаимодействия пользователя с картографическим интерфейсом. Через события реализуются клики по объектам, перемещения карты, масштабирование, работа с маркерами, пользовательские жесты и множество других сценариев, формирующих интерактивность геоприложений.

Событийная модель основана на подписке (event-driven architecture). Каждый объект карты способен генерировать события, а разработчик — подписываться на них через методы addEventListener или специализированные методы API.

Основные принципы:

  • события привязываются к конкретному объекту (карта, маркер, слой);
  • обработчики получают объект события с контекстной информацией;
  • возможна динамическая регистрация и удаление обработчиков;
  • поддерживаются одноразовые обработчики.

Базовый синтаксис:

map.addEventListener('eventType', function (event) {
    // обработка события
});

Удаление:

map.removeEventListener('eventType', handler);

События карты (Map Events)

Каркас интерактивности формируют события самого объекта карты.

Основные события

  • mapviewchange — изменение состояния отображения карты;
  • mapviewchangeend — завершение изменения вида;
  • pointerdown — нажатие на карту;
  • pointerup — отпускание указателя;
  • tap — одиночный клик/тап;
  • dbltap — двойной клик;
  • dragstart, drag, dragend — перетаскивание карты;
  • wheel — масштабирование колесом мыши.

Пример обработки перемещения карты:

map.addEventListener('mapviewchange', (event) => {
    const center = map.getCenter();
    const zoom = map.getZoom();

    console.log('Центр карты:', center);
    console.log('Масштаб:', zoom);
});

События взаимодействия с указателем

Указательные события являются базовым уровнем взаимодействия и включают как мышь, так и сенсорные устройства.

pointerdown / pointerup

Используются для отслеживания начала и окончания взаимодействия:

map.addEventListener('pointerdown', (evt) => {
    console.log('Нажатие в координатах:', evt.currentPointer.viewportX, evt.currentPointer.viewportY);
});

tap и dbltap

Абстрактные события, объединяющие мышь и touch-интерфейс:

map.addEventListener('tap', (evt) => {
    const geoPoint = map.screenToGeo(
        evt.currentPointer.viewportX,
        evt.currentPointer.viewportY
    );

    console.log('Координаты клика:', geoPoint);
});

События перетаскивания карты

Перемещение карты управляется цепочкой событий:

  • dragstart — начало движения;
  • drag — активное перемещение;
  • dragend — завершение.

Пример контроля движения:

map.addEventListener('dragstart', () => {
    console.log('Начало перемещения карты');
});

map.addEventListener('drag', (evt) => {
    console.log('Перемещение...', evt.currentPointer);
});

map.addEventListener('dragend', () => {
    console.log('Перемещение завершено');
});

События масштабирования

Масштабирование происходит через колесо мыши или жесты:

  • wheel — изменение масштаба колесом;
  • mapviewchange — отражает итоговое изменение zoom.

Пример:

map.addEventListener('wheel', (evt) => {
    console.log('Изменение масштаба колесом');
});

Контроль уровня масштабирования:

map.addEventListener('mapviewchangeend', () => {
    console.log('Текущий zoom:', map.getZoom());
});

События объектов на карте

Маркеры, полигоны и линии обладают собственной системой событий.

Маркеры

Маркер реагирует на пользовательские действия:

  • tap
  • pointerenter
  • pointerleave
marker.addEventListener('tap', (evt) => {
    console.log('Маркер нажат');
});

Наведение курсора

marker.addEventListener('pointerenter', () => {
    console.log('Курсор над маркером');
});

marker.addEventListener('pointerleave', () => {
    console.log('Курсор покинул маркер');
});

События слоёв и объектов данных

При работе с векторными слоями события часто связаны с выборкой объектов.

dataLayer.addEventListener('tap', (evt) => {
    const target = evt.target;
    const data = target.getData();

    console.log('Выбран объект:', data);
});

События позволяют реализовать:

  • выбор объектов;
  • фильтрацию по клику;
  • интерактивные инфо-панели.

Объект события

Каждое событие содержит унифицированный объект с информацией:

Основные поля:

  • type — тип события;
  • target — объект-источник;
  • currentPointer — данные указателя;
  • timestamp — время события.

Пример анализа события:

map.addEventListener('tap', (evt) => {
    console.log(evt.type);
    console.log(evt.timestamp);
});

Преобразование экранных координат в географические

Одна из ключевых задач — преобразование координат:

map.addEventListener('tap', (evt) => {
    const geo = map.screenToGeo(
        evt.currentPointer.viewportX,
        evt.currentPointer.viewportY
    );

    console.log('Геокоординаты:', geo.lat, geo.lng);
});

Обратное преобразование:

const screenPoint = map.geoToScreen({ lat: 52.5, lng: 13.4 });

Удаление и управление обработчиками

Для оптимизации производительности важно управлять подписками.

Сохранение ссылки на функцию

function onTap(evt) {
    console.log('tap');
}

map.addEventListener('tap', onTap);
map.removeEventListener('tap', onTap);

Одноразовые обработчики

map.addEventListener('tap', handler, { once: true });

Делегирование событий

При работе с множеством объектов используется делегирование:

map.addEventListener('tap', (evt) => {
    if (evt.target instanceof H.map.Marker) {
        console.log('Клик по маркеру');
    }
});

Такой подход снижает нагрузку на систему и упрощает архитектуру.

Особенности мобильных устройств

Сенсорные устройства объединяют жесты:

  • pinch-to-zoom → wheel / mapviewchange;
  • swipe → drag;
  • long press → специализированные события (в зависимости от конфигурации).

Унификация событий позволяет использовать один обработчик для всех платформ.

Производительность событийной системы

При работе с большим количеством событий важно учитывать:

  • минимизацию количества подписок;
  • использование делегирования;
  • удаление неиспользуемых обработчиков;
  • избегание тяжелых вычислений внутри callback.

Пример оптимизации:

map.addEventListener('pointermove', throttle((evt) => {
    console.log(evt.currentPointer);
}, 50));

Распространённые сценарии использования событий

  • отображение информации о точке клика;
  • динамическое обновление UI при перемещении карты;
  • построение маршрутов по клику;
  • фильтрация объектов слоя;
  • интерактивные панели данных;
  • работа с геоаналитикой в реальном времени.