Выбор стиля карты

Визуальное представление карты в Mapbox GL JS определяется стилем (style). Стиль — это JSON-спецификация, описывающая внешний вид всех слоёв, источников данных, шрифтов, цветов, прозрачности, а также правил отрисовки геометрии.

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

Ключевые элементы стиля:

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

Структура style specification

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

{
  "version": 8,
  "name": "Custom Style",
  "sources": {},
  "layers": [],
  "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
  "sprite": "mapbox://sprites/mapbox/streets-v11",
  "transition": {
    "duration": 300,
    "delay": 0
  }
}

version

Фиксированное значение 8 — текущая версия спецификации стилей.

sources

Описание источников данных:

"sources": {
  "cities": {
    "type": "vector",
    "url": "mapbox://examples.8fgz4egr"
  }
}

Типы источников:

  • vector — векторные тайлы
  • raster — растровые тайлы
  • geojson — локальные данные
  • image — наложенные изображения
  • video — видеопотоки

layers

Массив слоёв определяет порядок отрисовки. Каждый слой описывает:

  • тип слоя
  • источник данных
  • фильтры
  • стилизацию

Базовые стили Mapbox

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

  • Streets — уличная карта
  • Light — светлая минималистичная
  • Dark — тёмная тема
  • Satellite — спутниковая подложка
  • Outdoors — топографическая карта

Каждый стиль представляет собой полноценный JSON-документ, который можно модифицировать или использовать как основу.


Применение стиля в Mapbox GL JS

Стиль задаётся при инициализации карты:

import mapboxgl from "mapbox-gl";

mapboxgl.accessToken = "YOUR_TOKEN";

const map = new mapboxgl.Map({
  container: "map",
  style: "mapbox://styles/mapbox/streets-v12",
  center: [37.6173, 55.7558],
  zoom: 10
});

Также допускается использование локального JSON:

const map = new mapboxgl.Map({
  container: "map",
  style: {
    version: 8,
    sources: {},
    layers: []
  }
});

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

Стиль можно менять во время работы карты:

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

После смены стиля:

  • все пользовательские слои удаляются
  • источники пересоздаются
  • события style.load повторно срабатывают

Для восстановления кастомных слоёв используется обработчик:

map.on("style.load", () => {
  map.addSource("points", {
    type: "geojson",
    data: pointsData
  });

  map.addLayer({
    id: "points-layer",
    type: "circle",
    source: "points",
    paint: {
      "circle-radius": 6,
      "circle-color": "#ff0000"
    }
  });
});

Слои: основа визуализации

Слой (layer) определяет, как отображаются данные из источника.

Основные типы слоёв:

  • fill — полигоны
  • line — линии
  • circle — точки
  • symbol — текст и иконки
  • raster — растровые изображения
  • heatmap — тепловые карты
  • fill-extrusion — 3D-экструзии

Пример слоя линий

map.addLayer({
  id: "route",
  type: "line",
  source: "route-source",
  layout: {
    "line-join": "round",
    "line-cap": "round"
  },
  paint: {
    "line-color": "#3b9ddd",
    "line-width": 4
  }
});

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

Источник определяет, откуда поступают географические данные.

GeoJSON источник

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

Векторные тайлы

map.addSource("buildings", {
  type: "vector",
  url: "mapbox://mapbox.3d-buildings"
});

Выражения в стилях

Mapbox GL JS поддерживает expression-систему для динамической стилизации.

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

"circle-color": [
  "interpolate",
  ["linear"],
  ["get", "population"],
  0, "#2DC4B2",
  1000, "#3BB3C3",
  5000, "#669EC4",
  10000, "#8B88B6"
]

Условные выражения

"circle-radius": [
  "case",
  ["boolean", ["get", "selected"], false],
  10,
  5
]

Создание собственного стиля

Стиль может быть полностью определён вручную.

Минимальный пример:

const customStyle = {
  version: 8,
  sources: {
    osm: {
      type: "raster",
      tiles: [
        "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
      ],
      tileSize: 256
    }
  },
  layers: [
    {
      id: "osm-layer",
      type: "raster",
      source: "osm"
    }
  ]
};

Темизация и переключение визуальных режимов

Стиль часто используется для реализации светлой и тёмной темы.

Пример переключения

const light = "mapbox://styles/mapbox/light-v11";
const dark = "mapbox://styles/mapbox/dark-v11";

function toggleTheme(isDark) {
  map.setStyle(isDark ? dark : light);
}

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


Управление слоями после загрузки стиля

Порядок слоёв критически важен. Новый слой добавляется поверх существующих.

map.addLayer({
  id: "labels",
  type: "symbol",
  source: "points",
  layout: {
    "text-field": ["get", "name"],
    "text-size": 12
  }
}, "waterway-label");

Здесь "waterway-label" задаёт слой, перед которым будет вставлен новый.


Условная стилизация по zoom и свойствам

Стили могут изменяться в зависимости от масштаба:

"line-width": [
  "interpolate",
  ["linear"],
  ["zoom"],
  5, 1,
  10, 2,
  15, 4
]

Это позволяет адаптировать визуализацию под уровень детализации.


Работа с 3D стилями

Поддержка экструзии зданий:

map.addLayer({
  id: "buildings-3d",
  type: "fill-extrusion",
  source: "composite",
  "source-layer": "building",
  paint: {
    "fill-extrusion-height": ["get", "height"],
    "fill-extrusion-color": "#aaa",
    "fill-extrusion-opacity": 0.8
  }
});

Sprite и glyphs

Sprite содержит иконки для symbol-слоёв:

"sprite": "mapbox://sprites/mapbox/streets-v11"

Glyphs определяют шрифты:

"glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf"

Без них текстовые подписи и иконки не отображаются.


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

Сложность стиля напрямую влияет на производительность:

  • количество слоёв
  • количество выражений
  • плотность данных
  • частота перерисовки

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

  • объединение слоёв
  • использование фильтров вместо дублирования источников
  • минимизацию paint-выражений
  • кэширование GeoJSON

Организация масштабируемой архитектуры стилей

В крупных приложениях стили разделяются:

  • базовый стиль (фон, дороги)
  • тематические слои (POI, аналитика)
  • пользовательские слои (динамические данные)

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