Heatmap

Heatmap-слой предназначен для визуализации плотности точечных данных на карте без отображения отдельных маркеров. Вместо дискретных точек используется непрерывное распределение интенсивности, где цвет и яркость отражают концентрацию событий в пространстве.

Основная область применения — анализ больших наборов координат: геолокации пользователей, события, заказы, точки интереса, телеметрия. Heatmap позволяет быстро выявлять кластеры и зоны активности без перегрузки интерфейса.


Геометрическая модель heatmap

Heatmap в Mapbox GL JS строится на основе точечных данных из источника типа GeoJSON. Каждая точка влияет на окружающее пространство в радиусе, формируя «поле плотности».

Формально каждая точка задаёт вклад:

  • интенсивность (weight)
  • радиус влияния
  • спад (decay / blur)

Результирующее изображение представляет собой интерполяцию этих влияний.


Источник данных

Heatmap-слой всегда опирается на source типа geojson.

map.addSource('points', {
  type: 'geojson',
  data: {
    type: 'FeatureCollection',
    features: [
      {
        type: 'Feature',
        properties: {
          magnitude: 1
        },
        geometry: {
          type: 'Point',
          coordinates: [37.6173, 55.7558]
        }
      }
    ]
  }
});

Каждый Feature должен содержать Point-геометрию. Дополнительные свойства используются для управления весом.


Добавление heatmap-слоя

map.addLayer({
  id: 'heatmap-layer',
  type: 'heatmap',
  source: 'points',
  maxzoom: 18,
  paint: {
    'heatmap-weight': 1
  }
});

Минимальная конфигурация включает:

  • type: 'heatmap'
  • source с точками
  • базовый параметр heatmap-weight

Ключевые параметры paint

Heatmap-слой управляется набором выражений в paint, определяющих поведение визуализации.


heatmap-weight

Определяет вклад каждой точки в итоговую плотность.

'heatmap-weight': [
  'interpolate',
  ['linear'],
  ['get', 'magnitude'],
  0, 0,
  6, 1
]

Чем выше значение, тем сильнее влияние точки.


heatmap-intensity

Управляет общей «силой» heatmap.

'heatmap-intensity': [
  'interpolate',
  ['linear'],
  ['zoom'],
  0, 1,
  9, 3
]

Используется для усиления эффекта при увеличении масштаба.


heatmap-radius

Радиус влияния каждой точки в пикселях.

'heatmap-radius': [
  'interpolate',
  ['linear'],
  ['zoom'],
  0, 2,
  9, 20
]

Малые значения дают локальные пятна, большие — сглаженную карту плотности.


heatmap-blur

Степень размытия.

'heatmap-blur': 1

Повышение blur уменьшает резкость границ и усиливает непрерывность распределения.


heatmap-opacity

Прозрачность слоя.

'heatmap-opacity': 0.8

Часто используется в связке с другими слоями (например, точечными маркерами поверх heatmap).


Цветовая модель

Цвет задаётся через интерполяцию плотности.

'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 в Mapbox GL JS часто комбинируется с изменением параметров по zoom.

'heatmap-radius': [
  'interpolate',
  ['exponential', 2],
  ['zoom'],
  0, 2,
  10, 25
],

'heatmap-intensity': [
  'interpolate',
  ['linear'],
  ['zoom'],
  0, 1,
  12, 4
]

Так достигается эффект детализации: при уменьшении масштаба данные агрегируются визуально, при увеличении — раскрываются локальные структуры.


Влияние свойств данных

Каждый Feature может содержать свойства, влияющие на итоговую визуализацию:

  • числовой вес (например, magnitude, count, value)
  • категории (для фильтрации)
  • временные метки (для динамических heatmap)

Пример:

properties: {
  magnitude: 5,
  type: 'event'
}

Использование веса:

'heatmap-weight': ['get', 'magnitude']

Производительность

Heatmap является более эффективной альтернативой рендерингу большого количества circle-слоёв, но чувствителен к объёму данных.

Факторы производительности:

  • количество точек в GeoJSON
  • частота обновления источника
  • сложность выражений paint
  • количество слоёв поверх heatmap

Оптимизация часто включает:

  • предварительную агрегацию данных
  • использование тайловых источников
  • фильтрацию по zoom

Сравнение с кластеризацией

Heatmap и кластеризация решают схожие задачи, но различаются подходом:

  • heatmap — непрерывная плотность
  • clusters — дискретные группы точек

Кластеризация:

cluster: true,
clusterRadius: 40

Heatmap предпочтителен при анализе распределения, кластеризация — при необходимости точного подсчёта групп.


Комбинирование с точечным слоем

Часто heatmap используется совместно с circle-слоем для перехода от плотности к отдельным объектам.

map.addLayer({
  id: 'points-layer',
  type: 'circle',
  source: 'points',
  paint: {
    'circle-radius': 3,
    'circle-color': 'white'
  }
});

Типичный паттерн:

  • zoom < 10 → heatmap
  • zoom ≥ 10 → точки
'heatmap-opacity': [
  'interpolate',
  ['linear'],
  ['zoom'],
  7, 1,
  10, 0
]

Фильтрация данных

Heatmap можно ограничивать по условиям:

filter: ['==', ['get', 'type'], 'event']

или более сложные условия:

filter: ['>=', ['get', 'magnitude'], 3]

Динамическое обновление данных

Источник можно обновлять без пересоздания слоя:

map.getSource('points').setData(newGeojson);

Это позволяет строить динамические heatmap в реальном времени (например, потоковые события).


Расширенные выражения

Mapbox GL JS поддерживает выражения, позволяющие комбинировать данные:

'heatmap-weight': [
  '+',
  ['get', 'magnitude'],
  ['*', ['get', 'importance'], 0.5]
]

Также возможно нормирование:

['/', ['get', 'value'], 10]

Практическая структура слоя

Типичная конфигурация heatmap-слоя включает:

  • source GeoJSON
  • heatmap-weight на основе свойства
  • heatmap-intensity с привязкой к zoom
  • heatmap-radius с экспоненциальной зависимостью
  • heatmap-color через density interpolation
  • heatmap-opacity для переходов

Поведение при масштабировании

На низком zoom:

  • точки сгруппированы
  • высокая обобщённость

На среднем zoom:

  • появляются локальные пики плотности

На высоком zoom:

  • heatmap часто исчезает
  • отображаются отдельные точки или кластеры

Особенности визуальной интерпретации

Heatmap не отражает точные координаты объектов, а только плотность распределения. Это важно учитывать при анализе:

  • цвет не означает абсолютное значение
  • яркость зависит от радиуса и интенсивности
  • соседние зоны влияют друг на друга

Типовые ошибки конфигурации

  • отсутствие нормализации веса → перегруженные области
  • слишком большой radius → потеря детализации
  • отсутствие zoom-адаптации → одинаковая картинка на всех масштабах
  • чрезмерный blur → исчезновение структуры данных

Интеграция с аналитикой

Heatmap-слой часто используется как визуальный слой поверх аналитических систем:

  • поведенческая аналитика пользователей
  • тепловые карты доставки
  • анализ дорожного трафика
  • мониторинг IoT-устройств

В таких системах GeoJSON часто формируется сервером в агрегированном виде для снижения нагрузки на клиент.