Цветовая палитра

В стиле MapLibre GL JS цвет является одной из ключевых составляющих визуального языка карты. Он определяет читаемость, семантическое различие объектов и визуальную иерархию слоёв. Цвет задаётся через свойства стиля слоя (paint properties) и поддерживает как статические значения, так и динамические выражения, зависящие от масштаба, атрибутов данных и состояния объектов.

Основные свойства, связанные с цветом, встречаются практически во всех типах слоёв:

  • fill-color — заливка полигонов
  • line-color — цвет линий
  • circle-color — цвет точек в circle-слоях
  • text-color — цвет подписей
  • icon-color — окраска иконок (при использовании SDF-иконок)

Каждое из этих свойств поддерживает широкий набор форматов задания цвета и выражений.


Форматы задания цвета

Шестнадцатеричная запись

Наиболее распространённый формат — HEX:

"fill-color": "#3b82f6"

Допускаются варианты:

  • #RGB
  • #RRGGBB
  • #RRGGBBAA (с альфа-каналом)

Пример с прозрачностью:

"line-color": "#ff000080"

RGBA и RGB

Поддерживается функциональная запись:

"circle-color": "rgba(255, 0, 0, 0.5)"

или:

"text-color": "rgb(20, 20, 20)"

RGBA особенно полезен при визуализации плотных слоёв, где требуется контролировать наложение объектов.


Цветовые строки CSS

MapLibre GL JS поддерживает именованные цвета:

"fill-color": "steelblue"

Однако использование именованных цветов ограничивает контроль над оттенками и обычно применяется в прототипировании.


Цвет как часть декларативного стиля

MapLibre GL JS использует декларативный стиль JSON, где цвет — это часть описания слоя:

{
  "id": "water",
  "type": "fill",
  "source": "map-data",
  "source-layer": "water",
  "paint": {
    "fill-color": "#2b6cb0",
    "fill-opacity": 0.8
  }
}

В этом контексте цвет не вычисляется императивно, а описывается как правило отображения данных.


Интерполяция цвета

Одной из наиболее мощных возможностей является плавная интерполяция цвета в зависимости от масштаба или числовых данных.

Интерполяция по зуму

"line-color": [
  "interpolate",
  ["linear"],
  ["zoom"],
  5, "#cbd5e0",
  10, "#63b3ed",
  15, "#2b6cb0"
]

Здесь цвет линии изменяется при увеличении масштаба, формируя визуальную иерархию дорог или границ.


Интерполяция по данным

Цвет может зависеть от свойства объекта:

"fill-color": [
  "interpolate",
  ["linear"],
  ["get", "population"],
  0, "#edf2f7",
  100000, "#90cdf4",
  1000000, "#2b6cb0"
]

Такой подход позволяет строить хороплет-карты, где интенсивность цвета отражает числовые значения.


Дискретные цветовые шкалы (step)

В отличие от интерполяции, step создаёт пороговые изменения цвета:

"circle-color": [
  "step",
  ["get", "risk_level"],
  "#48bb78",
  1, "#ecc94b",
  2, "#ed8936",
  3, "#e53e3e"
]

Этот метод часто используется для классификации категорий или уровней опасности.


Условная логика и match

match-выражения

Позволяют сопоставлять конкретные значения:

"fill-color": [
  "match",
  ["get", "landuse"],
  "forest", "#2f855a",
  "residential", "#f7fafc",
  "industrial", "#718096",
  "#cccccc"
]

Такой подход применяется при тематическом раскрашивании слоёв.


Цветовые пространства и восприятие

При построении цветовых шкал важно учитывать особенности восприятия. MapLibre GL JS работает в RGB, однако при проектировании палитр часто используется логика:

  • равномерного изменения яркости
  • контрастности для слоёв
  • цветовой различимости категорий

На практике используются предрасчитанные палитры, например:

  • последовательные (sequential)
  • дивергентные (diverging)
  • категориальные (categorical)

Динамическое управление цветом через feature-state

MapLibre GL JS позволяет изменять цвет без изменения исходного GeoJSON через состояние объекта:

map.setFeatureState(
  { source: "regions", id: 42 },
  { hover: true }
)

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

"fill-color": [
  "case",
  ["boolean", ["feature-state", "hover"], false],
  "#f56565",
  "#4299e1"
]

Это создаёт интерактивные эффекты наведения и выделения.


Прозрачность и наложение цветов

Практически каждый цветовой параметр имеет соответствующий opacity:

  • fill-opacity
  • line-opacity
  • text-opacity
  • icon-opacity

Комбинация цвета и прозрачности определяет поведение слоя при наложении:

"fill-color": "#3182ce",
"fill-opacity": 0.4

При высокой плотности слоёв прозрачность становится инструментом управления визуальным шумом.


Сложные выражения цвета

Комбинирование условий

"circle-color": [
  "case",
  ["==", ["get", "type"], "hospital"], "#e53e3e",
  ["==", ["get", "type"], "school"], "#3182ce",
  "#a0aec0"
]

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


Вложенные выражения

"line-color": [
  "interpolate",
  ["linear"],
  ["zoom"],
  8,
  [
    "match",
    ["get", "class"],
    "primary", "#2c5282",
    "secondary", "#4299e1",
    "#a0aec0"
  ],
  14,
  [
    "match",
    ["get", "class"],
    "primary", "#1a365d",
    "secondary", "#2b6cb0",
    "#718096"
  ]
]

Цвет одновременно зависит от масштаба и атрибутов данных, формируя многомерную модель визуализации.


Палитры и системное проектирование цвета

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

Последовательные палитры

Используются для числовых данных:

  • светлый → тёмный
  • низкое → высокое значение

Дивергентные палитры

Используются для отклонений от нормы:

  • отрицательные значения → нейтраль → положительные

Категориальные палитры

Используются для типов объектов:

  • каждая категория получает уникальный оттенок

MapLibre GL JS не навязывает палитры, но предоставляет инструменты для их реализации через выражения.


Цвет текста и читаемость

Цвет текста требует учёта фона карты:

"text-color": "#111827",
"text-halo-color": "#ffffff",
"text-halo-width": 2

Halo (обводка) используется для повышения контрастности на сложных подложках, особенно при наложении на спутниковые или насыщенные тайлы.


Цвет в растровых и векторных слоях

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

{
  "id": "satellite",
  "type": "raster",
  "source": "satellite-tiles",
  "paint": {
    "raster-opacity": 1
  }
}

Цветовая обработка в растровых слоях ограничена, так как изображение уже закодировано.


Производительность цветовых выражений

Сложные выражения цвета влияют на производительность рендеринга. Наиболее затратные конструкции:

  • вложенные match внутри interpolate
  • частое использование feature-state
  • глубокие условные цепочки case

Оптимизация достигается за счёт:

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

Цвет как элемент семантики карты

Цвет в MapLibre GL JS выполняет не декоративную, а структурную функцию:

  • кодирует типы объектов
  • отображает числовые значения
  • создаёт визуальную иерархию
  • поддерживает интерактивность
  • усиливает восприятие пространственных данных

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