Выражения для heatmap

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

Heatmap в MapLibre GL JS формируется на основе исходного источника данных типа geojson. Каждый объект рассматривается как вклад в распределённое поле плотности. На итоговую визуализацию влияют четыре ключевых свойства слоя:

  • heatmap-weight — вес каждого объекта
  • heatmap-intensity — глобальная интенсивность слоя
  • heatmap-radius — радиус влияния точки
  • heatmap-color — цветовая интерполяция плотности
  • heatmap-opacity — прозрачность слоя

Все эти параметры поддерживают выражения (expressions), что позволяет строить динамическую визуализацию на основе атрибутов данных, масштаба и других контекстных параметров.

Выражение heatmap-weight

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

Типичная практика — связывать интенсивность с уровнем зума:

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

При низком зуме плотность сглаживается, при высоком — усиливается детализация. Такой подход компенсирует визуальное «разрежение» данных при увеличении масштаба.

В ряде случаев применяется ступенчатая модель:

"heatmap-intensity": [
  "step",
  ["zoom"],
  1,
  5, 2,
  10, 4
]

Это позволяет формировать дискретные уровни визуального усиления без плавных переходов.

Heatmap-color и цветовые выражения

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

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

Выражения позволяют динамически изменять радиус в зависимости от масштаба:

"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 регулирует видимость слоя и часто используется для плавного появления и исчезновения тепловой карты при изменении масштаба или состояния интерфейса.

Базовая анимация через зум:

"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 на тепловую модель

Система выражений в стиле MapLibre GL JS основана на вычислении значений на уровне рендеринга. Это означает, что все параметры heatmap пересчитываются при изменении:

  • масштаба карты
  • положения камеры
  • свойств объектов
  • состояния feature-state

Такой подход обеспечивает высокую гибкость без необходимости пересчёта данных на стороне сервера.

Особое значение имеет ["heatmap-density"], который является результатом внутренней агрегации. Он не хранится в данных, а вычисляется динамически на основе вклада всех точек в пиксельное пространство.

Сочетание heatmap с другими слоями

Heatmap часто используется как базовый слой аналитики, поверх которого накладываются дополнительные визуальные элементы:

  • circle слой для точного отображения отдельных точек при высоком зуме
  • symbol слой для маркировки кластеров
  • fill слой для отображения агрегированных регионов

Типичная схема переключения:

  • низкий зум — heatmap
  • средний зум — смешанный режим
  • высокий зум — точечная визуализация

Переключение реализуется через minzoom и maxzoom либо через opacity с выражениями.

Производственные аспекты использования выражений

Эффективность heatmap зависит от количества точек и сложности выражений. Рекомендации по оптимизации:

  • минимизация вложенных interpolate выражений
  • избегание сложных арифметических операций внутри heatmap-weight
  • использование предвычисленных атрибутов в GeoJSON
  • ограничение максимального радиуса на высоких зумах

Каждое выражение пересчитывается на стороне GPU-пайплайна, поэтому чрезмерная сложность напрямую влияет на производительность рендеринга.

Дополнительный эффект даёт правильная нормализация данных: заранее приведённые к диапазону 0–1 значения позволяют упростить выражения и снизить вычислительную нагрузку.

Динамическое управление тепловыми параметрами

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

map.setPaintProperty("heatmap-layer", "heatmap-radius", [
  "interpolate",
  ["linear"],
  ["zoom"],
  0, 5,
  10, 40
]);

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


Система heatmap-выражений в MapLibre GL JS представляет собой композицию параметрических функций, каждая из которых управляет отдельным аспектом плотностной визуализации. Совместное использование interpolate, step, атрибутов данных и встроенных значений плотности формирует гибкую модель, способную масштабироваться от простых тепловых карт до сложных аналитических визуализаций пространственных данных.