Темы оформления

Mapbox GL JS использует декларативную модель оформления карты, в которой внешний вид определяется через style specification — структурированный JSON-объект, описывающий источники данных, слои, слои символов, растровые тайлы, фильтры, выражения и глобальные параметры отображения. Основой визуальной системы выступает граф слоёв, где каждый слой отвечает за конкретный тип визуализации: линии, заливки, символы, 3D-экструзии, тепловые карты.


Стиль в Mapbox GL JS представляет собой объект с фиксированной структурой:

  • sources — источники данных (vector, raster, geojson)
  • layers — визуальные слои, связанные с источниками
  • sprite — набор иконок
  • glyphs — описание шрифтов для текстовых слоёв
  • light — параметры освещения для 3D-эффектов
  • transition — глобальные настройки анимации изменений

Каждый слой в layers имеет тип (type) и набор свойств (paint, layout), определяющих внешний вид.

{
  "version": 8,
  "sources": {},
  "layers": []
}

Тематическое оформление через style JSON

Основной механизм визуальных тем реализуется через разные style JSON-файлы. Каждая тема — это отдельная конфигурация:

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

Mapbox предоставляет предустановленные стили:

  • streets
  • outdoors
  • light
  • dark
  • satellite
  • navigation-day
  • navigation-night

Пример подключения темы:

map.setStyle('mapbox://styles/mapbox/dark-v11');

Смена стиля полностью перестраивает визуальный граф карты, включая слои, источники и текстуры.


Слои как основа визуальной темы

Каждая тема формируется набором слоёв. Типы слоёв:

Fill (заливка)

Используется для полигонов: районы, здания, границы.

{
  id: 'water-fill',
  type: 'fill',
  source: 'composite',
  'source-layer': 'water',
  paint: {
    'fill-color': '#1e90ff',
    'fill-opacity': 0.8
  }
}

Line (линии)

Дороги, маршруты, границы.

{
  id: 'road',
  type: 'line',
  paint: {
    'line-color': '#ffffff',
    'line-width': 2
  }
}

Symbol (символы)

Текстовые подписи и иконки.

{
  id: 'city-label',
  type: 'symbol',
  layout: {
    'text-field': ['get', 'name'],
    'text-size': 14
  }
}

Circle (точечные данные)

Используется для событий, объектов, POI.

{
  id: 'points',
  type: 'circle',
  paint: {
    'circle-radius': 6,
    'circle-color': '#ff0000'
  }
}

Paint и Layout как ядро визуальной темы

Каждый слой делится на две логические группы свойств:

  • layout — геометрия и поведение (размещение, видимость, порядок)
  • paint — визуальное оформление (цвет, прозрачность, ширина, размытие)

Пример разделения:

paint: {
  'line-color': '#333',
  'line-opacity': 0.9
},
layout: {
  'line-cap': 'round',
  'line-join': 'bevel'
}

Layout влияет на структуру отображения, paint — на визуальное восприятие темы.


Динамическая смена темы

Темы могут переключаться без перезагрузки карты. Это ключевой механизм адаптивного UI (день/ночь, режимы навигации).

map.setStyle('mapbox://styles/mapbox/light-v11');

После смены стиля необходимо повторно добавлять пользовательские слои:

map.on('style.load', () => {
  map.addLayer(customLayer);
});

Экспресии как инструмент стилизации

Expressions позволяют вычислять свойства динамически.

Цвет по атрибуту

'fill-color': [
  'match',
  ['get', 'type'],
  'park', '#2ecc71',
  'water', '#3498db',
  '#cccccc'
]

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

'circle-radius': [
  'interpolate',
  ['linear'],
  ['zoom'],
  5, 2,
  10, 8,
  15, 20
]

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


Иерархия слоёв и тема композиции

Порядок слоёв определяет итоговую визуальную структуру:

  1. фон
  2. вода
  3. земля
  4. дороги
  5. здания
  6. подписи

Каждый слой перекрывает предыдущий, создавая визуальную глубину.

map.addLayer(layer, 'road-label');

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


Пользовательские темы и кастомизация

Создание собственной темы начинается с базового стиля:

const style = {
  version: 8,
  sources: {
    osm: {
      type: 'vector',
      url: 'mapbox://mapbox.mapbox-streets-v8'
    }
  },
  layers: []
};

Далее добавляются собственные визуальные правила:

  • корпоративные цвета
  • минималистичная палитра
  • контрастные схемы для accessibility
  • тематические стили (туризм, логистика, аналитика)

Световые и 3D параметры темы

Параметр light управляет восприятием 3D объектов:

light: {
  anchor: 'viewport',
  color: '#ffffff',
  intensity: 0.5
}

В сочетании с fill-extrusion слоями формируются 3D здания:

{
  id: 'buildings',
  type: 'fill-extrusion',
  paint: {
    'fill-extrusion-height': ['get', 'height'],
    'fill-extrusion-color': '#aaa'
  }
}

Тема через фильтрацию данных

Фильтры позволяют создавать тематические подмножества данных:

filter: ['==', ['get', 'class'], 'primary']

Комбинация фильтров и paint-свойств формирует тематические представления:

  • транспортная тема
  • тема инфраструктуры
  • тема плотности населения

Sprite и glyphs как визуальная основа темы

  • sprite — набор иконок для POI и слоёв символов
  • glyphs — шрифты для текста
"sprite": "mapbox://sprites/mapbox/streets-v11",
"glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf"

Замена sprite полностью меняет визуальную идентичность темы.


Переиспользование и композиция стилей

Темы часто строятся на основе базовых стилей с переопределением слоёв:

map.setStyle(baseStyle);

map.on('style.load', () => {
  const layers = map.getStyle().layers;
});

Модификация существующих слоёв позволяет создавать производные темы без полной пересборки стиля.


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

Каждый элемент темы влияет на рендеринг WebGL:

  • количество слоёв
  • сложность expressions
  • использование blur и shadow
  • density символов

Оптимизация темы требует балансировки между визуальной сложностью и FPS.


Темы и адаптивность интерфейса

Темы часто синхронизируются с состоянием приложения:

  • ночной режим интерфейса → dark style
  • аналитический режим → минималистичная схема
  • навигация → high-contrast roads

Переключение происходит через setStyle, обеспечивая полную замену визуальной модели без потери данных источников при корректной архитектуре.