Source события

В MapLibre GL JS система источников данных построена вокруг реактивной модели загрузки и обновления информации. Каждый источник — будь то векторные тайлы, GeoJSON или растровые данные — генерирует события, отражающие текущее состояние загрузки, обновления и готовности данных к отрисовке. Работа с этими событиями позволяет контролировать жизненный цикл данных, синхронизировать интерфейс и реализовывать сложные сценарии взаимодействия с картой.


Общая модель событий данных

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

Основные категории:

  • загрузка данных (dataloading)
  • обновление данных (data)
  • завершение загрузки источника (sourcedata)
  • обновление стиля, влияющее на источники (styledata)

Каждое из этих событий отражает разные этапы пайплайна: от запроса тайлов до их готовности к рендерингу.


Событие data

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

map.on('data', (e) => {
    console.log(e.sourceId);
    console.log(e.isSourceLoaded);
    console.log(e.dataType);
});

Структура объекта события

Событие data может включать:

  • sourceId — идентификатор источника, который инициировал событие
  • dataType — тип данных (source, style, tile)
  • isSourceLoaded — флаг завершения загрузки источника
  • tile — ссылка на тайл (если событие связано с тайлами)

Поведение

Событие может срабатывать многократно в процессе:

  • загрузки тайлов
  • обновления фильтров
  • изменения стиля
  • пересчёта данных после zoom/pan

Событие sourcedata

sourcedata — ключевое событие для отслеживания состояния конкретного источника. Оно вызывается каждый раз, когда источник получает новые данные или изменяет своё состояние загрузки.

map.on('sourcedata', (e) => {
    if (e.sourceId === 'cities') {
        console.log('Обновление источника cities');
    }
});

Особенности

Событие содержит более точную информацию, чем data, и ориентировано на работу с конкретными источниками.

Поля объекта события

  • sourceId — идентификатор источника
  • isSourceLoaded — индикатор полной загрузки источника
  • source — объект самого источника (в зависимости от типа)
  • tile — тайл, если событие связано с векторными тайлами
  • type — тип события (data)

Различие между data и sourcedata

Несмотря на схожесть, эти события имеют принципиально разную семантику.

data

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

sourcedata

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

Событие dataloading

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

map.on('dataloading', (e) => {
    console.log('Началась загрузка:', e.sourceId);
});

Назначение

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

Поведение

Может вызываться многократно при:

  • перемещении карты
  • изменении масштаба
  • динамическом обновлении источников

Событие styledata

Хотя формально не относится напрямую к источникам, styledata влияет на них, так как стиль определяет:

  • какие источники активны
  • как они интерпретируются
  • какие слои используют данные источников
map.on('styledata', () => {
    console.log('Стиль обновлён, источники могли измениться');
});

Когда возникает

  • загрузка нового стиля
  • изменение layout или paint свойств
  • динамическое переключение стиля

Жизненный цикл источника через события

Типичный цикл работы источника можно представить как последовательность событий:

  1. dataloading — старт загрузки
  2. sourcedata — поступление данных
  3. data — обновление состояния карты
  4. повторные sourcedata при догрузке тайлов
  5. data с isSourceLoaded: true — завершение загрузки

Работа с множественными источниками

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

  • векторные тайлы городов
  • GeoJSON для пользовательских объектов
  • растровые слои

События позволяют фильтровать поток данных:

map.on('sourcedata', (e) => {
    switch (e.sourceId) {
        case 'roads':
            // обработка дорожной сети
            break;
        case 'buildings':
            // обработка зданий
            break;
    }
});

Отслеживание завершения загрузки источника

Наиболее важный сценарий — определение момента полной готовности источника.

map.on('data', (e) => {
    if (e.sourceId === 'places' && e.isSourceLoaded) {
        console.log('Источник places полностью загружен');
    }
});

Логика isSourceLoaded учитывает:

  • загрузку всех тайлов
  • завершение запросов
  • обновление внутреннего состояния кэша

События тайлов внутри источников

Для векторных источников ключевым элементом являются тайлы. События могут содержать ссылку на конкретный тайл:

  • загрузка тайла
  • декодирование данных
  • применение к слоям
map.on('sourcedata', (e) => {
    if (e.tile) {
        console.log('Тайл обновлён:', e.tile.tileID);
    }
});

Практика фильтрации событий

При работе с крупными картами важно ограничивать обработку событий только нужными источниками.

Фильтрация по sourceId

map.on('sourcedata', (e) => {
    if (e.sourceId !== 'population') return;

    // логика только для population
});

Фильтрация по состоянию загрузки

map.on('data', (e) => {
    if (!e.isSourceLoaded) return;

    console.log('Источник готов:', e.sourceId);
});

Синхронизация UI с состоянием источников

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

  • отображение спиннеров загрузки
  • блокировка взаимодействия
  • обновление списков объектов
map.on('dataloading', (e) => {
    showLoader(e.sourceId);
});

map.on('data', (e) => {
    if (e.isSourceLoaded) {
        hideLoader(e.sourceId);
    }
});

Особенности поведения при зуме и панорамировании

Каждое изменение viewport вызывает перерасчёт тайлов:

  • старые тайлы выгружаются
  • новые запрашиваются
  • источники генерируют поток sourcedata

При быстром перемещении карты события могут приходить в большом количестве, поэтому требуется:

  • дебаунсинг обработки
  • фильтрация по актуальному zoom
  • игнорирование устаревших тайлов

Потенциальные проблемы обработки событий

Дублирование событий

Один источник может генерировать несколько событий на один и тот же тайл из-за:

  • повторной загрузки
  • изменения стиля
  • кэш-инвалидации

Несогласованность состояния

События приходят асинхронно, поэтому:

  • dataloading может опередить styledata
  • sourcedata может прийти до полной готовности карты

Роль событий источников в архитектуре приложения

События источников являются фундаментом реактивного слоя MapLibre GL JS. На их основе строятся:

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

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