Жизненный цикл карты

Жизненный цикл карты в Mapbox GL JS начинается с создания экземпляра объекта карты. На этом этапе формируется базовая структура WebGL-контекста, подготавливаются внутренние состояния рендера, а также регистрируются основные обработчики событий.

Создание карты:

mapboxgl.accessToken = 'TOKEN';

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

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

  • инициализация WebGL-контекста;
  • создание сцены рендеринга;
  • подготовка тайловой системы;
  • запуск загрузки стиля;
  • регистрация системных событий.

На этом этапе карта существует как объект, но визуальное отображение ещё не готово.


Загрузка и применение стиля

Стиль в Mapbox GL JS представляет собой JSON-описание визуального представления карты: слои, источники данных, шрифты, спрайты и параметры рендера.

После установки параметра style начинается процесс загрузки:

  • скачивание JSON-описания стиля;
  • загрузка sprite-атласа;
  • загрузка glyphs (шрифтовых наборов);
  • инициализация источников данных.

Ключевым моментом является событие загрузки стиля:

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

На этом этапе карта уже может отображать базовую географию, но слои и источники данных могут ещё не быть полностью готовы.


Событие load и готовность карты

Событие load фиксирует момент, когда:

  • стиль загружен;
  • базовые источники и слои инициализированы;
  • WebGL-сцена готова к рендерингу.
map.on('load', () => {
  // карта полностью инициализирована
});

После этого момента становится возможным безопасное добавление собственных слоёв и источников данных.

Пример добавления слоя:

map.on('load', () => {
  map.addSource('points', {
    type: 'geojson',
    data: {
      type: 'FeatureCollection',
      features: []
    }
  });

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

Рендер-цикл и обновление кадра

Mapbox GL JS использует непрерывный цикл рендеринга на основе WebGL. Перерисовка сцены происходит при изменении состояния карты:

  • перемещение;
  • масштабирование;
  • изменение угла наклона;
  • обновление источников данных;
  • изменение стилей.

Каждое изменение приводит к планированию нового кадра.

Событие render вызывается при каждом перерисованном кадре:

map.on('render', () => {
  // вызывается при каждом кадре рендеринга
});

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


Завершение рендеринга кадра

Событие idle фиксирует момент, когда карта завершила все текущие вычисления и не имеет запланированных обновлений:

map.on('idle', () => {
  // карта находится в состоянии покоя
});

Состояние idle наступает, когда:

  • завершена загрузка тайлов;
  • отсутствуют активные анимации;
  • рендер-очередь пуста.

Это состояние часто используется как индикатор завершённой загрузки данных после интерактивных операций.


Обновление состояния карты

Жизненный цикл карты включает множество динамических состояний, возникающих в процессе взаимодействия и изменения параметров.

Перемещение и масштабирование

Любое изменение положения карты инициирует перерасчёт матрицы проекции и обновление видимых тайлов.

События:

map.on('move', () => {});
map.on('zoom', () => {});
map.on('rotate', () => {});

Каждое из этих событий влияет на:

  • пересчёт координат;
  • перераспределение тайлов;
  • обновление отрисовки слоёв.

Изменение данных источников

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

map.getSource('points').setData(newData);

После этого:

  • запускается повторная валидация GeoJSON;
  • пересчитываются привязки к слоям;
  • инициируется рендер нового кадра.

Изменение стиля

Полная смена стиля запускает частичный перезапуск жизненного цикла:

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

При этом:

  • старые слои и источники удаляются;
  • загружается новый стиль;
  • повторно инициируется загрузка sprite и glyphs;
  • снова активируется событие style.load.

Асинхронная природа жизненного цикла

Процессы внутри Mapbox GL JS происходят асинхронно и распределены по этапам:

  • загрузка ресурсов (сетевые операции);
  • обработка данных (CPU-bound операции);
  • рендеринг (GPU-bound операции).

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


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

Отображение карты основано на тайловой модели. При изменении области видимости запускается загрузка новых тайлов:

  • определение границ viewport;
  • вычисление необходимых тайлов;
  • асинхронная загрузка данных;
  • кеширование загруженных элементов.

Каждый тайл проходит собственный мини-жизненный цикл:

  • запрос;
  • получение данных;
  • декодирование;
  • отрисовка.

Удаление карты и освобождение ресурсов

Завершающий этап жизненного цикла связан с удалением экземпляра карты:

map.remove();

При этом выполняются операции:

  • удаление WebGL-контекста;
  • освобождение памяти тайлов;
  • снятие всех обработчиков событий;
  • очистка DOM-контейнера;
  • остановка рендер-цикла.

После вызова remove объект карты перестаёт участвовать в любых внутренних процессах.


Управление состояниями через события

Жизненный цикл управляется системой событий, которая отражает все ключевые стадии работы карты:

  • инициализация;
  • загрузка стиля;
  • готовность;
  • рендеринг;
  • простои;
  • обновления данных;
  • разрушение объекта.

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


Взаимодействие WebGL и внутреннего состояния

Основой визуализации выступает WebGL-контекст, который создаётся при инициализации карты. Все последующие операции транслируются в графические команды:

  • буферизация вершин;
  • управление текстурами;
  • компоновка слоёв;
  • отрисовка кадра.

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