Удаление источников

Удаление источников данных в MapLibre GL JS представляет собой критически важную часть управления жизненным циклом карты. Источники (sources) напрямую связаны со слоями (layers), и неправильный порядок удаления или отсутствие контроля зависимостей приводит к ошибкам выполнения и утечкам памяти.


Основы удаления источников

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

Удаление источника выполняется методом:

map.removeSource('source-id');

Ключевое условие корректного удаления — отсутствие слоёв, которые используют данный источник. Попытка удалить источник, связанный со слоем, приводит к ошибке.


Взаимосвязь источников и слоёв

Каждый слой (layer) в стиле карты опирается на конкретный источник. Связь имеет строгую зависимость:

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

Пример зависимости:

map.addSource('cities', {
  type: 'geojson',
  data: citiesGeojson
});

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

Удаление источника без предварительного удаления слоя нарушает эту цепочку.


Порядок удаления

Корректный порядок операций при удалении всегда обратный созданию:

  1. Удаление всех слоёв, использующих источник
  2. Удаление самого источника
if (map.getLayer('cities-layer')) {
  map.removeLayer('cities-layer');
}

if (map.getSource('cities')) {
  map.removeSource('cities');
}

Несоблюдение порядка приводит к исключениям, поскольку MapLibre GL JS проверяет целостность стиля перед изменением структуры.


API removeSource и особенности поведения

Метод map.removeSource(id) выполняет следующие действия:

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

Особенности:

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

Проверка существования источника

Перед удалением источника используется проверка:

const source = map.getSource('cities');

if (source) {
  map.removeSource('cities');
}

Метод map.getSource возвращает объект источника или undefined, если он отсутствует в стиле.

Аналогично используется проверка слоя:

const layer = map.getLayer('cities-layer');

Ошибки при удалении источников

Наиболее распространённые ошибки:

1. Удаление источника с активными слоями

Error: Source "id" cannot be removed while layer "layer-id" is using it

Причина — нарушение зависимости слой → источник.


2. Повторное удаление источника

Вызов removeSource для уже удалённого источника приводит к исключению, поскольку стиль больше не содержит данного идентификатора.


3. Попытка удаления до загрузки стиля

Если стиль карты ещё не загружен, операции удаления недоступны:

map.on('load', () => {
  map.removeSource('cities');
});

Динамическое управление источниками

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

Пример замены источника:

function updateCities(data) {
  if (map.getSource('cities')) {
    map.removeSource('cities');
  }

  map.addSource('cities', {
    type: 'geojson',
    data
  });
}

Такой подход применяется при полной перезагрузке набора данных.


Обновление GeoJSON без удаления

Удаление источника не всегда требуется. Для GeoJSON-источников предусмотрено обновление данных:

const source = map.getSource('cities');

source.setData(newData);

Использование setData предпочтительнее, поскольку:

  • сохраняются слои;
  • отсутствуют лишние перерасчёты стиля;
  • уменьшается нагрузка на GPU и CPU.

Удаление источников в сложных стилях

В стилях с большим количеством слоёв источники могут использоваться множественными зависимостями.

Типичная структура:

  • один источник → несколько слоёв;
  • один слой → один источник.

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

const layers = map.getStyle().layers;
const dependentLayers = layers.filter(l => l.source === 'cities');

После выявления зависимых слоёв выполняется их последовательное удаление.


Производительность и очистка ресурсов

Удаление источника освобождает:

  • загруженные тайлы;
  • кэшированные данные;
  • WebGL ресурсы (буферы, текстуры).

При частой смене данных важно избегать избыточных операций удаления/добавления, поскольку это приводит к:

  • перерасчёту стиля;
  • повторной загрузке тайлов;
  • увеличению времени отрисовки.

Оптимальная стратегия — переиспользование источников с обновлением данных через setData или обновление URL для тайловых источников.


Удаление источников в runtime-логике

В приложениях с интерактивной картой источники часто удаляются в ответ на события интерфейса:

  • переключение фильтров;
  • смена тематического слоя;
  • изменение временного диапазона данных.

Пример сценария:

function toggleLayer(enabled) {
  if (!enabled) {
    if (map.getLayer('heatmap-layer')) {
      map.removeLayer('heatmap-layer');
    }
    if (map.getSource('heatmap')) {
      map.removeSource('heatmap');
    }
  }
}

Стабильность состояния карты

Корректное управление удалением источников влияет на стабильность состояния стиля. Нарушение порядка операций приводит к:

  • рассинхронизации слоёв;
  • неконсистентному стилю;
  • ошибкам рендеринга WebGL контекста.

Стабильная стратегия удаления всегда включает:

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