Работа с тепловыми картами в MapLibre GL JS строится на системе декларативных стилей и выражений, которые вычисляются на основе свойств данных и состояния карты в реальном времени. Heatmap-слой предназначен для визуализации плотности точечных данных, где каждый объект влияет на окружающую область с определённым весом и радиусом влияния. В отличие от символических или круговых слоёв, тепловая карта агрегирует вклад множества точек в непрерывное поле значений.
Heatmap в MapLibre GL JS формируется на основе исходного источника
данных типа geojson. Каждый объект рассматривается как
вклад в распределённое поле плотности. На итоговую визуализацию влияют
четыре ключевых свойства слоя:
heatmap-weight — вес каждого объектаheatmap-intensity — глобальная интенсивность слояheatmap-radius — радиус влияния точкиheatmap-color — цветовая интерполяция плотностиheatmap-opacity — прозрачность слояВсе эти параметры поддерживают выражения (expressions), что позволяет строить динамическую визуализацию на основе атрибутов данных, масштаба и других контекстных параметров.
heatmap-weight определяет вклад каждой точки в общую
плотность. По умолчанию каждая точка имеет вес 1, однако использование
выражений позволяет учитывать внешние данные, например числовые свойства
объектов.
Часто используется масштабирование через
interpolate:
"heatmap-weight": [
"interpolate",
["linear"],
["get", "mag"],
0, 0,
6, 1
]
В этом примере атрибут mag (например, магнитуда или
интенсивность события) нормализуется в диапазон от 0 до 1. Такой подход
позволяет усиливать влияние значимых точек и подавлять слабые.
Также возможно использование логарифмических или ступенчатых зависимостей:
"heatmap-weight": [
"step",
["get", "count"],
0,
10, 0.5,
50, 1
]
step-выражение задаёт пороговую модель, где вес резко
увеличивается при достижении определённых значений.
heatmap-intensity управляет общей «яркостью» теплового
слоя. Этот параметр особенно важен при работе с разными уровнями
масштабирования карты, так как плотность точек визуально изменяется при
увеличении или уменьшении масштаба.
Типичная практика — связывать интенсивность с уровнем зума:
"heatmap-intensity": [
"interpolate",
["linear"],
["zoom"],
0, 1,
9, 3
]
При низком зуме плотность сглаживается, при высоком — усиливается детализация. Такой подход компенсирует визуальное «разрежение» данных при увеличении масштаба.
В ряде случаев применяется ступенчатая модель:
"heatmap-intensity": [
"step",
["zoom"],
1,
5, 2,
10, 4
]
Это позволяет формировать дискретные уровни визуального усиления без плавных переходов.
Цвет тепловой карты определяется плотностью пикселей, вычисляемой на
основе агрегации точек. Наиболее часто используется выражение
interpolate с линейной или экспоненциальной
интерполяцией.
Базовая схема:
"heatmap-color": [
"interpolate",
["linear"],
["heatmap-density"],
0, "rgba(0,0,255,0)",
0.2, "blue",
0.4, "cyan",
0.6, "lime",
0.8, "yellow",
1, "red"
]
Здесь heatmap-density — встроенное значение,
нормализованное от 0 до 1, отражающее локальную концентрацию точек.
Использование прозрачного начального цвета критично для корректного наложения слоёв. Более сложные схемы часто применяют несколько точек перегиба:
"heatmap-color": [
"interpolate",
["exponential", 1.5],
["heatmap-density"],
0, "rgba(255,255,255,0)",
0.1, "#2c7bb6",
0.3, "#abd9e9",
0.5, "#ffffbf",
0.7, "#fdae61",
1, "#d7191c"
]
Экспоненциальная интерполяция усиливает различия в средних значениях плотности, делая переходы более контрастными.
Также возможно использование step для резких
градаций:
"heatmap-color": [
"step",
["heatmap-density"],
"rgba(0,0,0,0)",
0.2, "blue",
0.5, "yellow",
0.8, "red"
]
Такой подход применяется в аналитических визуализациях, где важны дискретные уровни плотности.
Радиус определяет географическую область, в пределах которой каждая точка влияет на итоговую плотность. Малые значения создают детализированную карту, большие — сглаженную агрегацию.
Выражения позволяют динамически изменять радиус в зависимости от масштаба:
"heatmap-radius": [
"interpolate",
["linear"],
["zoom"],
0, 2,
9, 20,
14, 50
]
На низком зуме точки практически не перекрываются, что снижает шум. При увеличении масштаба радиус расширяется, позволяя видеть локальные кластеры.
Альтернативный вариант с step:
"heatmap-radius": [
"step",
["zoom"],
5,
8, 15,
12, 30
]
Подобная конфигурация используется для резкого изменения детализации при переходе между уровнями масштаба.
heatmap-opacity регулирует видимость слоя и часто
используется для плавного появления и исчезновения тепловой карты при
изменении масштаба или состояния интерфейса.
Базовая анимация через зум:
"heatmap-opacity": [
"interpolate",
["linear"],
["zoom"],
7, 1,
9, 0
]
Это позволяет постепенно заменять тепловую карту другими типами визуализации, например круговыми слоями.
Также возможно связывание с условиями данных:
"heatmap-opacity": [
"case",
["boolean", ["feature-state", "hidden"], false],
0,
1
]
Такой подход позволяет управлять видимостью отдельных объектов через
feature-state.
На практике все параметры heatmap работают совместно и формируют многомерную модель визуализации. Например, изменение веса точек влияет на плотность, радиус — на сглаживание, а интенсивность — на общий уровень визуального усиления.
Типовая конфигурация слоя:
{
"id": "heatmap-layer",
"type": "heatmap",
"source": "events",
"maxzoom": 15,
"paint": {
"heatmap-weight": [
"interpolate",
["linear"],
["get", "value"],
0, 0,
10, 1
],
"heatmap-intensity": [
"interpolate",
["linear"],
["zoom"],
0, 1,
9, 3
],
"heatmap-radius": [
"interpolate",
["linear"],
["zoom"],
0, 2,
9, 25
],
"heatmap-color": [
"interpolate",
["linear"],
["heatmap-density"],
0, "rgba(0,0,255,0)",
0.3, "blue",
0.5, "lime",
0.7, "yellow",
1, "red"
],
"heatmap-opacity": [
"interpolate",
["linear"],
["zoom"],
7, 1,
10, 0
]
}
}
Подобные конфигурации позволяют строить адаптивные карты плотности, которые автоматически подстраиваются под масштаб и структуру данных.
Система выражений в стиле MapLibre GL JS основана на вычислении значений на уровне рендеринга. Это означает, что все параметры heatmap пересчитываются при изменении:
Такой подход обеспечивает высокую гибкость без необходимости пересчёта данных на стороне сервера.
Особое значение имеет ["heatmap-density"], который
является результатом внутренней агрегации. Он не хранится в данных, а
вычисляется динамически на основе вклада всех точек в пиксельное
пространство.
Heatmap часто используется как базовый слой аналитики, поверх которого накладываются дополнительные визуальные элементы:
circle слой для точного отображения отдельных точек при
высоком зумеsymbol слой для маркировки кластеровfill слой для отображения агрегированных регионовТипичная схема переключения:
Переключение реализуется через minzoom и
maxzoom либо через opacity с выражениями.
Эффективность heatmap зависит от количества точек и сложности выражений. Рекомендации по оптимизации:
interpolate выраженийheatmap-weightКаждое выражение пересчитывается на стороне GPU-пайплайна, поэтому чрезмерная сложность напрямую влияет на производительность рендеринга.
Дополнительный эффект даёт правильная нормализация данных: заранее приведённые к диапазону 0–1 значения позволяют упростить выражения и снизить вычислительную нагрузку.
Heatmap-слой допускает изменение всех выражений в рантайме через
setPaintProperty. Это используется для интерактивной
аналитики:
map.setPaintProperty("heatmap-layer", "heatmap-radius", [
"interpolate",
["linear"],
["zoom"],
0, 5,
10, 40
]);
Таким образом можно адаптировать визуализацию под пользовательские сценарии без перезагрузки источника данных.
Система heatmap-выражений в MapLibre GL JS представляет собой
композицию параметрических функций, каждая из которых управляет
отдельным аспектом плотностной визуализации. Совместное использование
interpolate, step, атрибутов данных и
встроенных значений плотности формирует гибкую модель, способную
масштабироваться от простых тепловых карт до сложных аналитических
визуализаций пространственных данных.