В MapLibre GL JS отображение точечных данных чаще всего реализуется через слой типа circle, который интерпретирует каждую точку GeoJSON как окружность на экране. В отличие от символов (symbol), круги рисуются напрямую в WebGL и обладают предсказуемой производительностью даже при больших объёмах данных.
Ключевая особенность кругового слоя заключается в том, что радиус задаётся не в географических единицах, а в пикселях экрана, что делает визуализацию независимой от проекции карты и обеспечивает стабильное восприятие масштаба на разных уровнях zoom.
Для отображения точек через радиус используется источник данных GeoJSON и слой circle:
map.addSource('points', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [69.589, 42.874]
},
properties: {
value: 10
}
}
]
}
});
map.addLayer({
id: 'circle-layer',
type: 'circle',
source: 'points',
paint: {
'circle-radius': 5,
'circle-color': '#3b82f6'
}
});
На этом уровне радиус фиксирован и одинаков для всех объектов.
circle-radius — центральное свойство, определяющее размер точки.
Поддерживаются три основных режима:
Простейший вариант:
'circle-radius': 8
Каждая точка будет иметь радиус 8 пикселей независимо от данных и масштаба.
Радиус часто связывается с атрибутами GeoJSON, формируя так называемые пропорциональные символы:
'circle-radius': [
'get',
'value'
]
Однако прямое использование значения редко даёт корректный визуальный результат, так как численные значения данных обычно не соответствуют пиксельному масштабу. Поэтому применяется масштабирование:
'circle-radius': [
'*',
['get', 'value'],
2
]
Такой подход превращает атрибут value в визуально
интерпретируемый размер.
Более устойчивый способ — интерполяция:
'circle-radius': [
'interpolate',
['linear'],
['get', 'value'],
1, 2,
10, 6,
50, 18
]
Здесь:
Между ними происходит плавное масштабирование.
Отдельный класс задач связан с изменением радиуса при изменении zoom. Это позволяет сохранять читаемость точек при увеличении масштаба.
'circle-radius': [
'interpolate',
['linear'],
['zoom'],
5, 2,
10, 6,
15, 14
]
При малом масштабе точки остаются компактными, а при приближении увеличиваются.
На практике радиус часто зависит одновременно от атрибута и масштаба:
'circle-radius': [
'*',
[
'interpolate',
['linear'],
['get', 'value'],
1, 1,
10, 5,
50, 12
],
[
'interpolate',
['linear'],
['zoom'],
5, 0.5,
10, 1,
15, 1.5
]
]
Такой подход позволяет строить адаптивные визуализации, где данные и масштаб карты влияют на итоговый размер символа.
Слишком большие или слишком маленькие радиусы нарушают читаемость. Для стабилизации используется clamp-подобная логика:
'circle-radius': [
'clamp',
[
'interpolate',
['linear'],
['get', 'value'],
1, 2,
100, 20
],
2,
20
]
Это фиксирует диапазон радиусов в пределах от 2 до 20 пикселей.
Радиус визуально усиливается через обводку:
'circle-stroke-width': 1,
'circle-stroke-color': '#1f2937'
Обводка становится особенно важной при плотном расположении точек, предотвращая визуальное слияние.
Радиус тесно связан с прозрачностью, так как крупные точки требуют уменьшения визуального веса:
'circle-opacity': [
'interpolate',
['linear'],
['get', 'value'],
1, 0.4,
50, 0.9
]
Это позволяет сохранить баланс плотности данных на карте.
Свойство blur влияет на визуальную «мягкость» края:
'circle-blur': 0.2
При увеличении blur круг выходит за границы строгой геометрии, создавая эффект тепловой карты при высокой плотности точек.
При работе с большими наборами данных радиус часто используется вместе с кластеризацией источника:
map.addSource('clusters', {
type: 'geojson',
data: points,
cluster: true,
clusterRadius: 40
});
Кластеры получают собственный радиус, который можно масштабировать:
'circle-radius': [
'step',
['get', 'point_count'],
10,
10, 15,
50, 25,
100, 40
]
Здесь радиус отражает количество объектов внутри кластера.
Круги в MapLibre GL JS рендерятся через WebGL, что делает вычисление радиуса дешёвым с точки зрения CPU. Однако сложные выражения:
могут увеличивать нагрузку на GPU-пайплайн.
Оптимизация достигается через:
Радиус точек используется в нескольких устойчивых моделях визуализации:
1. Пропорциональные символы Размер отражает числовую величину (население, интенсивность, частота).
2. Масштабируемые маркеры Радиус увеличивается при приближении карты для сохранения читаемости.
3. Кластерные представления Радиус отражает плотность объектов.
4. Категориальная визуализация Разные диапазоны радиусов соответствуют классам данных.
Эти проблемы приводят к визуальной перегрузке и потере читаемости даже при корректных данных.
Человеческое восприятие площади нелинейно: увеличение радиуса в 2 раза увеличивает площадь круга в 4 раза. Это делает линейное масштабирование визуально некорректным при больших диапазонах значений.
Для компенсации применяется нелинейная трансформация:
'circle-radius': [
'interpolate',
['exponential', 1.5],
['get', 'value'],
1, 2,
50, 20
]
Экспоненциальная интерполяция позволяет приблизить визуальное восприятие к реальным различиям данных.
Радиус точек определяет не только размер символа, но и структуру визуального пространства карты. При плотных данных он формирует паттерны группировки, при редких — подчёркивает отдельные объекты, а при динамическом zoom становится инструментом управления читаемостью без изменения геометрии данных.