Google Maps JavaScript API поддерживает отображение больших наборов географических объектов, однако при росте числа маркеров прямая отрисовка приводит к деградации производительности и визуальному шуму. Clustering решает задачу агрегации точек в зависимости от масштаба карты, обеспечивая одновременно читаемость и масштабируемость интерфейса.
Кластеризация в контексте карт — это группировка близко расположенных маркеров в один визуальный элемент, который отображает агрегированную информацию (например, количество точек).
Ключевая идея:
В рамках экосистемы Google Maps чаще всего применяется подход:
Наиболее распространённая реализация — библиотека
@googlemaps/markerclusterer.
Базовый пример:
import { MarkerClusterer } from "@googlemaps/markerclusterer";
const map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 48.0, lng: 66.9 },
zoom: 5,
});
const markers = locations.map((location) => {
return new google.maps.Marker({
position: location,
});
});
const clusterer = new MarkerClusterer({
map,
markers,
});
Особенность подхода:
Ограничение:
Grid clustering делит карту на виртуальную сетку. Все маркеры внутри одной ячейки объединяются.
Алгоритмически:
Преимущества:
Недостатки:
Альтернатива grid-подходу — объединение по радиусу.
Логика:
Упрощённая модель расстояния:
genui{“math_block_widget_always_prefetch_v2”:{“content”:“d = ”}}
На практике используются геодезические расстояния (Haversine), а не евклидовы координаты.
Преимущества:
Недостатки:
Для географических координат применяется формула:
a = ^2() + _1 _2 ^2()
и итоговое расстояние:
c = 2 (, )
где:
Такой подход критичен для корректной кластеризации на глобальных масштабах.
Библиотека supercluster (Mapbox-экосистема) применяется
как более быстрый альтернативный алгоритм.
Принцип:
Особенность:
Пример:
import Supercluster from "supercluster";
const index = new Supercluster({
radius: 60,
maxZoom: 16,
});
index.load(
points.map(p => ({
geometry: { coordinates: [p.lng, p.lat] },
}))
);
const clusters = index.getClusters([-180, -85, 180, 85], 5);
Преимущество:
Ключевая концепция: кластеризация зависит от zoom level.
Типовая модель:
Это реализуется через:
При больших данных важна не только кластеризация, но и способ рендера.
Подходы:
Canvas-стратегия:
При экстремальных объёмах данных (миллионы точек) кластеризация переносится на сервер.
Схема:
Преимущества:
Недостатки:
Для оптимизации используются:
H3 особенно эффективен:
Ключевые события:
zoom_changeddragendidleТиповой debounce-паттерн:
let timeout;
map.addListener("bounds_changed", () => {
clearTimeout(timeout);
timeout = setTimeout(() => {
updateClusters();
}, 150);
});
Это предотвращает:
Кластеры часто кастомизируются:
Пример логики:
const renderer = {
render: ({ count }) => {
return new google.maps.Marker({
label: String(count),
});
},
};
При малом количестве точек вместо кластера используется “раскладывание” маркеров по окружности.
Принцип:
Используется когда:
В реальных системах применяется комбинация:
Такая архитектура обеспечивает: