В экосистеме HERE Technologies работа с маркерами в HERE Maps API
построена на событийной модели, основанной на унифицированной системе
H.mapevents. Каждый маркер (H.map.Marker)
способен генерировать пользовательские события: наведение, клик,
касание, перетаскивание, а также низкоуровневые pointer-события.
События не привязаны напрямую к DOM — они транслируются через слой карты, что позволяет одинаково обрабатывать взаимодействие как на desktop, так и на mobile устройствах.
Базовая модель взаимодействия строится вокруг метода
addEventListener. Каждый маркер является объектом,
поддерживающим интерфейс событий.
const marker = new H.map.Marker({ lat: 52.5200, lng: 13.4050 });
marker.addEventListener('tap', function (evt) {
console.log('Маркер нажат');
});
Событие tap является универсальным и используется вместо
click для поддержки сенсорных устройств.
Для десктопного поведения также доступен pointerdown, но
в большинстве случаев рекомендуется использовать высокоуровневые события
API.
Каждое событие передаёт объект evt, содержащий полезную
информацию:
target — объект, вызвавший событие (маркер)currentPointer — координаты указателяtype — тип событияtarget.getGeometry() — географические координаты
маркераmarker.addEventListener('tap', function (evt) {
const coords = evt.target.getGeometry();
console.log(coords.lat, coords.lng);
});
Это позволяет строить интерактивные сценарии без обращения к DOM-слою.
Маркер может хранить произвольные данные через setData.
Это ключевой механизм связывания географического объекта с
бизнес-логикой.
marker.setData({
id: 42,
title: 'Офис',
type: 'branch'
});
marker.addEventListener('tap', function (evt) {
const data = evt.target.getData();
console.log(data.title);
});
Такой подход часто используется для отображения всплывающих окон и карточек объектов.
Наиболее распространённый сценарий — открытие информационного окна при клике на маркер.
const bubble = new H.ui.InfoBubble({ lat: 52.5200, lng: 13.4050 }, {
content: 'Информация об объекте'
});
marker.addEventListener('tap', function (evt) {
ui.addBubble(bubble);
});
Событие выступает триггером для UI-слоя, при этом логика отображения полностью отделена от маркера.
Для включения drag-интеракции требуется активация поведения карты
через H.mapevents.Behavior.
const beh * avior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
После этого маркер можно сделать перетаскиваемым:
marker.draggable = true;
Далее обрабатываются события:
marker.addEventListener('dragstart', function (evt) {
console.log('Начало перетаскивания');
});
marker.addEventListener('drag', function (evt) {
const pointer = evt.currentPointer;
marker.setGeometry(pointer);
});
marker.addEventListener('dragend', function (evt) {
console.log('Перетаскивание завершено');
});
Ключевой момент заключается в том, что координаты маркера обновляются вручную на основе позиции указателя.
Вместо подписки на каждый маркер можно использовать централизованный обработчик на уровне карты:
map.addEventListener('tap', function (evt) {
if (evt.target instanceof H.map.Marker) {
console.log('Клик по маркеру');
}
});
Такой подход эффективен при работе с большим количеством объектов, особенно при динамической генерации маркеров.
Система событий поддерживает унифицированные pointer-события:
pointerdownpointeruppointermovepointerenterpointerleavemarker.addEventListener('pointerenter', function () {
console.log('Курсор наведён на маркер');
});
Эти события полезны при создании кастомных эффектов подсветки и анимаций.
Каждый обработчик можно удалить через
removeEventListener. Важно сохранять ссылку на функцию.
function onTap(evt) {
console.log('tap');
}
marker.addEventListener('tap', onTap);
marker.removeEventListener('tap', onTap);
При динамическом создании маркеров это критично для предотвращения утечек памяти.
Событийная модель имеет ряд особенностей:
Behavior.При включённом Behavior часть событий перехватывается
системой управления картой. Например, перетаскивание карты может
блокировать drag маркера.
const beh * avior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
behavior.disable(H.mapevents.Behavior.DRAGGING);
Это позволяет разделять сценарии взаимодействия между картой и объектами.
При работе с тысячами маркеров важно учитывать нагрузку:
function handleTap(evt) {
const marker = evt.target;
const data = marker.getData();
}
При использовании кластеров события часто перенаправляются на кластерный объект вместо отдельного маркера. В этом случае требуется проверка типа объекта:
map.addEventListener('tap', function (evt) {
if (evt.target.getData && evt.target.getData().cluster) {
console.log('Кластер');
}
});
Такой подход позволяет различать агрегированные и одиночные объекты без изменения архитектуры событийной системы.
Часто используемые комбинации событий:
tap → открытие информационного окнаpointerenter → подсветка маркераdrag → изменение геометрии объектаdragend → сохранение координат на сервереmarker.addEventListener('dragend', function (evt) {
const coords = evt.target.getGeometry();
saveToServer(coords);
});
События формируют основу интерактивной модели геоприложений, где каждый маркер выступает автономным интерактивным объектом, управляемым через единый событийный механизм.