При работе с большим количеством точек на карте отображение каждого объекта отдельно быстро приводит к визуальной перегрузке интерфейса. Кластеризация позволяет объединять близко расположенные точки в группы, отображая вместо множества маркеров один кластер с количеством объектов внутри.
Одним из важнейших параметров кластеризации в MapLibre GL JS является
clusterRadius — радиус, определяющий,
какие точки считаются достаточно близкими для объединения в кластер.
Настройка радиуса напрямую влияет на внешний вид карты, читаемость данных и производительность визуализации.
clusterRadiusРадиус кластера задаётся при создании источника данных
(GeoJSONSource):
map.addSource('earthquakes', {
type: 'geojson',
data: 'earthquakes.geojson',
cluster: true,
clusterRadius: 50
});
Здесь значение 50 означает радиус в пикселях
экранного пространства, а не в метрах или километрах.
MapLibre анализирует расположение точек на текущем уровне масштабирования и объединяет объекты, расстояние между которыми меньше указанного радиуса.
Предположим, имеются пять точек:
● ● ● ● ●
Если радиус достаточно большой, все пять точек могут оказаться внутри одной области кластеризации:
[ 5 ]
Если радиус уменьшить:
[ 3 ] [ 2 ]
При дальнейшем уменьшении:
● ● ● ● ●
В этом случае кластеризация практически перестаёт работать, поскольку расстояния между точками превышают установленный радиус.
Если параметр не указан явно:
map.addSource('places', {
type: 'geojson',
data: data,
cluster: true
});
MapLibre использует стандартное значение:
clusterRadius: 50
Во многих случаях этого достаточно для начальной настройки, однако реальные проекты часто требуют подбора радиуса под конкретный набор данных.
Пример:
map.addSource('places', {
type: 'geojson',
data: data,
cluster: true,
clusterRadius: 20
});
Особенности такого подхода:
Малый радиус полезен для данных с высокой плотностью расположения точек.
Например:
Пример:
map.addSource('places', {
type: 'geojson',
data: data,
cluster: true,
clusterRadius: 100
});
Результат:
Такой вариант подходит для отображения:
clusterRadius: 20
Характеристики:
clusterRadius: 50
Характеристики:
clusterRadius: 100
Характеристики:
Важно понимать, что радиус измеряется в пикселях экрана.
Пусть задано:
clusterRadius: 60
На масштабе:
Zoom 3
один пиксель покрывает огромную территорию, поэтому кластеры могут объединять тысячи объектов.
На масштабе:
Zoom 15
тот же радиус охватывает значительно меньшую географическую область.
Из-за этого кластеризация автоматически становится менее агрессивной по мере увеличения масштаба карты.
clusterMaxZoomЧасто радиус настраивается вместе с максимальным уровнем кластеризации.
Пример:
map.addSource('stores', {
type: 'geojson',
data: stores,
cluster: true,
clusterRadius: 60,
clusterMaxZoom: 12
});
Здесь:
Такое сочетание позволяет контролировать как степень группировки, так и момент её отключения.
clusterRadius: 80
Причина:
clusterRadius: 50
Причина:
clusterRadius: 30
Причина:
clusterRadius: 100
Причина:
Практика показывает, что идеального значения не существует.
Удобный способ подбора — быстро менять параметр:
const radius = 30;
const radius = 50;
const radius = 80;
const radius = 120;
После каждого изменения оцениваются:
В некоторых приложениях радиус зависит от режима отображения данных.
Например:
function createSource(radius) {
map.addSource('points', {
type: 'geojson',
data: geojson,
cluster: true,
clusterRadius: radius
});
}
Использование:
createSource(30);
или
createSource(90);
Такой подход позволяет создавать различные сценарии визуализации без изменения структуры данных.
Параметр clusterRadius не оказывает столь сильного
влияния на производительность, как объём данных, однако косвенный эффект
присутствует.
Малые значения:
clusterRadius: 10
могут приводить к появлению большого числа кластеров и отдельных точек.
Очень большие значения:
clusterRadius: 200
уменьшают количество отображаемых объектов, но ухудшают информативность карты.
На практике наиболее распространённый диапазон:
20–100
Он обеспечивает хороший баланс между скоростью работы и качеством визуализации.
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [37.6176, 55.7558],
zoom: 5
});
map.on('load', () => {
map.addSource('locations', {
type: 'geojson',
data: 'locations.geojson',
cluster: true,
clusterRadius: 70,
clusterMaxZoom: 14
});
map.addLayer({
id: 'clusters',
type: 'circle',
source: 'locations',
filter: ['has', 'point_count'],
paint: {
'circle-color': '#3b82f6',
'circle-radius': 25
}
});
map.addLayer({
id: 'cluster-count',
type: 'symbol',
source: 'locations',
filter: ['has', 'point_count'],
layout: {
'text-field': ['get', 'point_count'],
'text-size': 14
}
});
map.addLayer({
id: 'unclustered',
type: 'circle',
source: 'locations',
filter: ['!', ['has', 'point_count']],
paint: {
'circle-color': '#ef4444',
'circle-radius': 6
}
});
});
В данном примере точки объединяются в пределах радиуса 70 пикселей, образуя кластеры до масштаба 14. После приближения карты кластеры постепенно распадаются на отдельные объекты, обеспечивая плавный переход от общего обзора данных к детальному изучению каждой точки.