HERE Technologies предоставляет набор инструментов для работы с картографическими данными, включая отображение большого количества объектов на интерактивной карте. При увеличении числа маркеров производительность визуализации и читаемость интерфейса резко ухудшаются, поэтому применяется кластеризация — объединение близко расположенных объектов в группы.
HERE Maps API включает встроенный механизм кластеризации, который оптимизирует отображение точек интереса (POI), пользовательских маркеров и динамических данных, поступающих в реальном времени.
Кластеризация основана на группировке географически близких точек в один визуальный объект — кластер. При изменении масштаба карты:
Основная цель — снижение нагрузки на DOM и WebGL-рендеринг, а также повышение читаемости карты.
Ключевые свойства:
В JavaScript API используется модель слоёв данных:
H.map.Group — контейнер для объектовH.map.Marker — отдельная точкаH.clustering.Provider — источник кластеризованных
данныхH.clustering.Object — результат кластеризации (кластер
или одиночный маркер)Кластеризация строится поверх провайдера данных, который анализирует координаты и формирует иерархию групп.
Основной поток обработки:
Базовая структура подключения карты включает создание платформы, слоя карты и объекта отображения.
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.52, lng: 13.405 },
zoom: 5,
pixelRatio: window.devicePixelRatio || 1
}
);
const beh * avior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
const ui = H.ui.UI.createDefault(map, defaultLayers);
После создания карты добавляется слой кластеризации.
Данные формируются в виде массива объектов
H.clustering.DataPoint.
const dataPoints = [];
for (let i = 0; i < 1000; i++) {
const lat = 52 + Math.random() * 10;
const lng = 13 + Math.random() * 10;
dataPoints.push(
new H.clustering.DataPoint(lat, lng)
);
}
Каждая точка содержит только координаты, без визуального представления.
Основной компонент — H.clustering.Provider, который
принимает параметры группировки.
const clusteringProvider = new H.clustering.Provider(
dataPoints,
{
clusteringOptions: {
eps: 32,
minWeight: 2
}
}
);
Чем выше eps, тем крупнее формируются группы.
Для визуализации создаётся слой и добавляется в карту:
const clusteringLayer = new H.map.layer.ObjectLayer(clusteringProvider);
map.addLayer(clusteringLayer);
На карте начинают отображаться:
Каждый кластер можно кастомизировать через
getTheme().
clusteringProvider.getTheme = function () {
return {
getClusterPresentation: function (cluster) {
const count = cluster.getWeight();
const clusterMarker = new H.map.Marker(cluster.getPosition(), {
icon: new H.map.Icon(
createClusterIcon(count)
)
});
return clusterMarker;
},
getNoisePresentation: function (noisePoint) {
return new H.map.Marker(noisePoint.getPosition());
}
};
};
Функция createClusterIcon формирует визуальный элемент,
например canvas-иконку.
function createClusterIcon(count) {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = 40;
canvas.height = 40;
context.beginPath();
context.arc(20, 20, 18, 0, 2 * Math.PI);
context.fillStyle = '#2B6CB0';
context.fill();
context.fillStyle = '#FFFFFF';
context.font = 'bold 12px Arial';
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillText(count, 20, 20);
return new H.map.Icon(canvas.toDataURL());
}
Такой подход позволяет адаптировать внешний вид под дизайн интерфейса.
Кластеризация автоматически пересчитывается при:
Алгоритм пересчёта:
epsКластеры и одиночные точки могут обрабатываться через события карты.
map.addEventListener('tap', function (evt) {
const target = evt.target;
if (target instanceof H.map.Marker) {
const position = target.getGeometry();
map.setCenter(position);
map.setZoom(map.getZoom() + 2);
}
});
Поведение часто используется для:
При работе с большими наборами данных применяется подгрузка по области карты:
map.addEventListener('mapviewchangeend', function () {
const bounds = map.getViewModel().getLookAtData().bounds;
loadPoints(bounds).then(points => {
clusteringProvider.setDataPoints(points);
});
});
Функция setDataPoints позволяет обновлять кластеризацию
без пересоздания слоя.
При работе с тысячами и миллионами объектов критически важны оптимизации:
eps при высоких зумахДополнительно применяется:
При увеличении объёма данных стандартный клиентский алгоритм может становиться узким местом. Используются подходы:
В таком случае клиент получает уже агрегированные данные:
{
"lat": 52.52,
"lng": 13.40,
"count": 125
}
И отображает их как кластеры без вычислений на стороне браузера.
Кластеризация применяется в:
При высокой плотности данных без кластеризации карта теряет функциональность из-за визуального шума и перегрузки интерфейса.
Кластеризация тесно связана с концепцией zoom-dependent rendering:
Для реализации используются:
eps в зависимости от zoomclusteringProvider.setClusteringOptions({
eps: map.getZoom() < 8 ? 64 : 32,
minWeight: 2
});
Кластеризация интегрируется с:
Это позволяет строить многоуровневые геоаналитические системы, где кластеры становятся базовой единицей агрегации пространственной информации.