Группировка маркеров в картографических приложениях решает проблему визуального перегруза при отображении большого количества точек на ограниченном пространстве карты. В контексте HERE Technologies и HERE Maps API этот механизм реализуется через кластеризацию объектов, позволяющую объединять близко расположенные маркеры в единые агрегированные элементы на разных уровнях масштабирования.
Кластеризация в HERE Maps API строится на уровне слоя данных. Вместо добавления отдельных объектов на карту используется промежуточный слой, который анализирует пространственное распределение точек и динамически формирует группы.
Ключевые компоненты:
H.clustering.Provider — поставщик кластеризованных
данныхH.clustering.DataPoint — базовая точка для
кластеризацииH.map.layer.ObjectLayer — слой отображения
объектовH.map.Marker — визуальный маркер (кластер или одиночная
точка)Основная идея заключается в том, что карта не управляет маркерами напрямую, а получает уже агрегированные данные от провайдера кластеров.
Перед использованием кластеризации необходимо создать карту и подключить модуль кластеризации.
const platform = new H.service.Platform({
apikey: 'YOUR_API_KEY'
});
const defaultLayers = platform.createDefaultLayers();
const map = new H.Map(
document.getElementById('map'),
defaultLayers.vector.normal.map,
{
center: { lat: 52.5, lng: 13.4 },
zoom: 6,
pixelRatio: window.devicePixelRatio || 1
}
);
const beh * avior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
const ui = H.ui.UI.createDefault(map, defaultLayers);
После создания карты подключается провайдер кластеров:
const dataPoints = [];
for (let i = 0; i < 1000; i++) {
dataPoints.push(
new H.clustering.DataPoint(
Math.random() * 180 - 90,
Math.random() * 360 - 180
)
);
}
Центральный объект кластеризации —
H.clustering.Provider.
const clusteredDataProvider = new H.clustering.Provider(dataPoints, {
clusteringOptions: {
eps: 32, // радиус кластеризации в пикселях
minWeight: 2
}
});
Эти параметры напрямую влияют на плотность кластеризации и поведение при зуме.
Для отображения используется слой объектов:
const clusteringLayer = new H.map.layer.ObjectLayer(clusteredDataProvider);
map.addLayer(clusteringLayer);
Каждый кластер или одиночная точка автоматически преобразуется в визуальный объект.
Один из ключевых механизмов — настройка theme,
определяющего визуальное представление кластеров.
const clusteredDataProvider = new H.clustering.Provider(dataPoints, {
clusteringOptions: {
eps: 64,
minWeight: 2
},
theme: {
getClusterPresentation: function (cluster) {
const weight = cluster.getWeight();
const svg = `
<svg width="40" height="40">
<circle cx="20" cy="20" r="18" fill="#1976d2" />
<text x="20" y="25" text-anchor="middle" font-size="12" fill="#fff">
${weight}
</text>
</svg>
`;
const icon = new H.map.Icon(svg, {
size: { w: 40, h: 40 }
});
const marker = new H.map.Marker(cluster.getPosition(), { icon });
marker.setData(cluster);
return marker;
},
getNoisePresentation: function (noisePoint) {
const icon = new H.map.Icon('data:image/svg+xml;utf-8,<svg></svg>', {
size: { w: 10, h: 10 }
});
return new H.map.Marker(noisePoint.getPosition(), { icon });
}
}
});
В кластерной модели существуют два типа сущностей:
getWeight())Кластеры поддерживают события, аналогично обычным маркерам.
map.addEventListener('tap', function (evt) {
const target = evt.target;
if (target instanceof H.map.Marker) {
const data = target.getData();
if (data.getWeight) {
map.setCenter(data.getPosition());
map.setZoom(map.getZoom() + 2);
}
}
});
Поведение обычно строится вокруг двух сценариев:
Кластеризация динамически пересчитывается при изменении zoom-level.
Основные принципы:
Это поведение управляется параметром eps, который
фактически работает в пикселях экрана, а не в географических
координатах.
При работе с большими наборами данных (10 000+ точек) важно учитывать:
Удаление нерелевантных точек до передачи в провайдер снижает нагрузку.
Слишком маленький eps приводит к росту числа
объектов.
Данные могут подгружаться по географическим тайлам.
При масштабировании до десятков тысяч точек кластеризация становится обязательной. Без неё карта теряет интерактивность.
Типичное поведение:
Кластеризация не ограничена географическими координатами. Каждый
DataPoint может содержать произвольные метаданные.
new H.clustering.DataPoint(lat, lng, null, {
id: 123,
type: 'restaurant',
rating: 4.8
});
Эти данные доступны при обработке событий:
const data = marker.getData();
const original = data.getData();
Кластеры могут менять внешний вид в зависимости от содержимого:
Для сложных систем применяется многоуровневая агрегация:
Кластеры интегрируются с базовыми возможностями карты:
Это позволяет кластеризации оставаться синхронизированной с состоянием карты без дополнительного кода синхронизации.
Обновление кластеров происходит через изменение источника данных:
clusteredDataProvider.setDataPoints(newDataPoints);
После этого карта автоматически пересчитывает группы и обновляет отображение без ручного вмешательства.
При быстром изменении zoom:
Типичный pipeline кластеризации включает:
DataPointProviderЭта модель обеспечивает стабильную работу даже при высокой плотности объектов и сложной визуализации.