При работе с большими наборами геоданных в Mapbox GL JS ключевой механизм оптимизации отображения — кластеризация точек через GeoJSON source. Кластеры объединяют близко расположенные точки в единые объекты, уменьшая нагрузку на рендеринг и повышая читаемость карты при низких масштабах.
Внутри системы кластеризации используется алгоритм, основанный на Supercluster, который динамически группирует точки в зависимости от текущего масштаба карты.
Кластеризация включается на уровне источника данных:
map.addSource('points', {
type: 'geojson',
data: 'data.geojson',
cluster: true,
clusterRadius: 50,
clusterMaxZoom: 14
});
Ключевые параметры:
После активации источника Mapbox автоматически создаёт три типа данных:
Метод getClusterExpansionZoom возвращает масштаб (zoom
level), на котором выбранный кластер «раскроется» и разделится на более
мелкие кластеры или отдельные точки.
Это значение вычисляется динамически на основе внутреннего индекса кластеризации и текущей структуры данных.
Основная задача метода — обеспечить плавную навигацию к раскрытию группы объектов.
Метод вызывается через источник данных:
map.getSource('points').getClusterExpansionZoom(clusterId, callback);
Где:
cluster_id)Частый сценарий — обработка клика по кластеру и плавное приближение к уровню раскрытия:
map.on('click', 'clusters', (e) => {
const features = map.queryRenderedFeatures(e.point, {
layers: ['clusters']
});
const clusterId = features[0].properties.cluster_id;
map.getSource('points').getClusterExpansionZoom(clusterId, (err, zoom) => {
if (err) return;
map.easeTo({
center: features[0].geometry.coordinates,
zoom: zoom
});
});
});
Внутренне Mapbox GL JS:
cluster_idВажно понимать: возвращаемый zoom не является фиксированным значением данных, он вычисляется динамически в зависимости от текущей конфигурации источника.
Кластеры существуют только в диапазоне от minZoom до
clusterMaxZoom.
getClusterExpansionZoom возвращает именно тот уровень,
где произойдёт первое разбиение выбранного кластераНа практике метод часто комбинируется с анимацией камеры:
map.getSource('points').getClusterExpansionZoom(clusterId, (err, zoom) => {
map.flyTo({
center: coordinates,
zoom: zoom
});
});
Разница между методами анимации:
easeTo — плавное изменение без ускоренияflyTo — анимация с эффектом полёта и кривой
движенияМетод getClusterExpansionZoom часто используется вместе
с другими функциями источника:
getClusterLeaves(clusterId, limit, offset, callback) —
получение объектов внутри кластераgetClusterChildren(clusterId, callback) — получение
непосредственных дочерних элементовОднако в отличие от них, getClusterExpansionZoom не
возвращает данные, а только вычисляет оптимальный масштаб для раскрытия
структуры.
Каждый кластер в GeoJSON источнике содержит свойства:
{
"cluster": true,
"cluster_id": 123,
"point_count": 45,
"point_count_abbreviated": 45
}
cluster_id является ключом для всех операций кластерного
API, включая getClusterExpansionZoom.
В callback первым аргументом может быть ошибка:
(err, zoom) => {}
Возможные причины:
cluster_idХотя метод кажется простым, его результат зависит от предварительно построенного индекса кластеров.
Особенности:
clusterRadius и
clusterMaxZoomИзменение этих параметров полностью меняет поведение результата.
map.on('click', 'clusters', (e) => {
const cluster = map.queryRenderedFeatures(e.point, {
layers: ['clusters']
})[0];
const clusterId = cluster.properties.cluster_id;
map.getSource('points').getClusterExpansionZoom(clusterId, (err, zoom) => {
map.easeTo({
center: cluster.geometry.coordinates,
zoom
});
});
});
При выборе элемента списка можно синхронизировать карту:
function zoomToCluster(clusterId, coordinates) {
map.getSource('points').getClusterExpansionZoom(clusterId, (err, zoom) => {
map.flyTo({
center: coordinates,
zoom
});
});
}
Метод применяется для построения логики UI:
Кластеризация Mapbox GL JS базируется на пространственном индексе, где:
getClusterExpansionZoom фактически запрашивает
минимальный уровень, при котором кластер перестаёт существовать как
агрегат.
При большом количестве точек:
clusterMaxZoomЭто нормальное поведение, обусловленное алгоритмом группировки.
В более сложных системах метод применяется как часть связки:
Он выступает как связующее звено между пространственной структурой данных и логикой UI-слоя карты