Интеграция Studio и GL JS

Связка Mapbox GL JS и Mapbox Studio строится вокруг единого формата описания карты — Style Specification (style JSON). Studio выступает средой визуального конструирования стиля, а GL JS — средой исполнения этого стиля в браузере.

Основной принцип взаимодействия:

  • Mapbox Studio формирует style.json
  • GL JS загружает стиль по URL
  • дальнейшее управление картой происходит через API слоёв и источников

Ключевой связующий элемент — Style URL.


Style URL как точка интеграции

После публикации стиля в Mapbox Studio он получает уникальный идентификатор вида:

mapbox://styles/{username}/{style_id}

Этот URL используется напрямую в GL JS:

import mapboxgl from "mapbox-gl";

mapboxgl.accessToken = "YOUR_MAPBOX_ACCESS_TOKEN";

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

При инициализации происходит:

  • загрузка style JSON
  • загрузка источников данных (sources)
  • загрузка слоёв (layers)
  • подгрузка sprite и glyphs

Структура стиля Mapbox Studio

Стиль, созданный в Mapbox Studio, представляет собой JSON-документ со следующими ключевыми секциями:

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

Пример фрагмента:

{
  "version": 8,
  "sources": {
    "streets": {
      "type": "vector",
      "url": "mapbox://mapbox.mapbox-streets-v8"
    }
  },
  "layers": [
    {
      "id": "road-primary",
      "type": "line",
      "source": "streets",
      "source-layer": "road",
      "paint": {
        "line-color": "#ff0000",
        "line-width": 2
      }
    }
  ]
}

GL JS интерпретирует эту структуру без необходимости ручного построения слоёв при загрузке.


Использование стилей Studio в runtime

После загрузки стиля через Mapbox GL JS возможна динамическая модификация карты без возврата в Studio.

Изменение источников и слоёв

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

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

Studio определяет базовую структуру, GL JS расширяет её runtime-слоями.


Переопределение слоёв из Studio

Любой слой, созданный в Mapbox Studio, может быть изменён через API:

map.setPaintProperty("road-primary", "line-color", "#00ff00");
map.setLayoutProperty("road-primary", "visibility", "none");

Механизм:

  • идентификация слоя по id
  • изменение paint/layout свойств
  • немедленная перерисовка WebGL сцены

Версионирование стилей

Каждая публикация стиля в Mapbox Studio создаёт новую версию. GL JS всегда загружает immutable snapshot стиля.

Преимущества:

  • отсутствие разрывов при обновлении
  • предсказуемость рендера
  • возможность отката через Studio

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

mapbox://styles/username/style_id

или с указанием версии:

mapbox://styles/username/style_id?fresh=true

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

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

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

Поведение:

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

Синхронизация пользовательских слоёв

После setStyle пользовательские слои должны быть восстановлены:

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

  map.addLayer({
    id: "custom-layer",
    type: "circle",
    source: "custom"
  });
});

Причина:

  • Studio-стиль перезаписывает runtime-состояние
  • GL JS не сохраняет динамически добавленные слои между стилями

Работа с token и доступом к Studio-ресурсам

Mapbox использует токены доступа:

  • public token — для клиента
  • secret token — для управления стилями
mapboxgl.accessToken = "pk.xxxxx";

Токен определяет доступ к:

  • style JSON
  • tilesets
  • sprites
  • glyphs

Интеграция tilesets из Studio

В Mapbox Studio создаются tilesets, которые затем подключаются как источники:

{
  "sources": {
    "custom-tiles": {
      "type": "vector",
      "url": "mapbox://username.tileset_id"
    }
  }
}

В GL JS:

map.addSource("custom-tiles", {
  type: "vector",
  url: "mapbox://username.tileset_id"
});

Tilesets обеспечивают:

  • масштабируемую геоданную
  • серверную генерализацию
  • оптимизированный WebGL рендер

Sprite и glyph pipeline

Стиль Studio включает ссылки:

"sprite": "mapbox://sprites/username/style_id",
"glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf"

GL JS загружает:

  • sprite sheet (иконки)
  • glyph ranges (шрифты)

Это обеспечивает:

  • единый визуальный стиль
  • поддержку локализации
  • ускоренный рендер текста

Динамическая фильтрация данных

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

map.setFilter("poi-labels", [
  "all",
  ["==", "class", "restaurant"]
]);

Механизм:

  • фильтр применяется на уровне слоя
  • данные не перезапрашиваются
  • изменяется только GPU-пайплайн

Интеграция пользовательских стилей с runtime логикой

Типовой сценарий:

  1. стиль создаётся в Studio
  2. подключается в GL JS
  3. runtime добавляет интерактивность

Пример:

map.on("click", "poi-layer", (e) => {
  const feature = e.features[0];

  new mapboxgl.Popup()
    .setLngLat(feature.geometry.coordinates)
    .setHTML(feature.properties.name)
    .addTo(map);
});

Studio отвечает за визуальную базу, GL JS — за поведение.


Контроль порядка слоёв

Mapbox GL JS позволяет управлять порядком слоёв, созданных в Studio:

map.moveLayer("water-layer", "road-primary");

или вставка:

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

Это важно при комбинировании:

  • базовых слоёв Studio
  • кастомных аналитических слоёв
  • интерактивных overlay

Обработка событий загрузки стиля

Критический этап интеграции:

map.on("load", () => {
  // стиль Studio полностью загружен
});

Дополнительно:

  • styledata
  • sourcedata
  • render

Эти события позволяют синхронизировать внешние данные с визуализацией.


TransformRequest для контроля загрузки ресурсов

GL JS предоставляет перехват запросов:

const map = new mapboxgl.Map({
  container: "map",
  style: "mapbox://styles/username/style_id",
  transformRequest: (url, resourceType) => {
    if (resourceType === "Tile") {
      return {
        url,
        headers: { Authorization: "Bearer TOKEN" }
      };
    }
  }
});

Используется для:

  • проксирования запросов
  • кастомной авторизации
  • кеширования tiles

Разделение ответственности Studio и GL JS

Mapbox Studio:

  • визуальное проектирование
  • настройка слоёв
  • цветовые схемы
  • экспорт style JSON

Mapbox GL JS:

  • рендер WebGL
  • обработка событий
  • динамическое обновление слоёв
  • интеграция с приложением

Mapbox:

  • хранение ресурсов
  • tiles API
  • authentication
  • delivery infrastructure