Настройка радиуса кластера

При работе с большим количеством точек на карте отображение каждого объекта отдельно быстро приводит к визуальной перегрузке интерфейса. Кластеризация позволяет объединять близко расположенные точки в группы, отображая вместо множества маркеров один кластер с количеством объектов внутри.

Одним из важнейших параметров кластеризации в 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
});

Результат:

  • точки объединяются агрессивнее;
  • количество кластеров уменьшается;
  • карта выглядит менее загруженной;
  • пользователь видит общую картину распределения объектов.

Такой вариант подходит для отображения:

  • глобальных событий;
  • географически распределённых объектов;
  • логистических сетей;
  • статистических данных на больших территориях.

Сравнение различных значений

Радиус 20

clusterRadius: 20

Характеристики:

  • много кластеров;
  • высокая детализация;
  • раннее разделение групп.

Радиус 50

clusterRadius: 50

Характеристики:

  • хороший баланс между читаемостью и детализацией;
  • значение по умолчанию;
  • подходит для большинства задач.

Радиус 100

clusterRadius: 100

Характеристики:

  • мало кластеров;
  • высокая степень объединения;
  • удобен для обзора крупных территорий.

Влияние на различные уровни масштабирования

Важно понимать, что радиус измеряется в пикселях экрана.

Пусть задано:

clusterRadius: 60

На масштабе:

Zoom 3

один пиксель покрывает огромную территорию, поэтому кластеры могут объединять тысячи объектов.

На масштабе:

Zoom 15

тот же радиус охватывает значительно меньшую географическую область.

Из-за этого кластеризация автоматически становится менее агрессивной по мере увеличения масштаба карты.


Совместное использование с clusterMaxZoom

Часто радиус настраивается вместе с максимальным уровнем кластеризации.

Пример:

map.addSource('stores', {
    type: 'geojson',
    data: stores,
    cluster: true,
    clusterRadius: 60,
    clusterMaxZoom: 12
});

Здесь:

  • до масштаба 12 используются кластеры;
  • после масштаба 12 отображаются отдельные точки;
  • радиус 60 определяет плотность объединения объектов.

Такое сочетание позволяет контролировать как степень группировки, так и момент её отключения.


Подбор радиуса для разных типов данных

Города

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. После приближения карты кластеры постепенно распадаются на отдельные объекты, обеспечивая плавный переход от общего обзора данных к детальному изучению каждой точки.