Удаление объектов

В MapLibre GL JS графические объекты чаще всего представлены слоями, привязанными к источникам данных. Удаление слоя выполняется методом removeLayer, который требует предварительной проверки существования слоя в стиле карты.

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

if (map.getLayer('cities-layer')) {
    map.removeLayer('cities-layer');
}

Удаление слоя затрагивает только визуальное представление. Источник данных, связанный с этим слоем, остаётся активным до отдельного удаления.

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


Удаление источников данных (sources)

Источники данных в MapLibre GL JS представляют собой фундаментальный уровень хранения географической информации. Удаление источника выполняется через removeSource, однако операция возможна только при отсутствии зависимых слоёв.

Типичный порядок удаления включает два шага:

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

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

Попытка удалить источник с активными слоями приводит к ошибке выполнения. Поэтому контроль зависимостей является обязательным этапом управления состоянием карты.

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


Обновление GeoJSON как альтернатива удалению объектов

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

Источник обновляется методом setData, который заменяет текущий набор геометрий новым.

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

const updatedData = {
    type: 'FeatureCollection',
    features: [
        // оставшиеся объекты
    ]
};

source.setData(updatedData);

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

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


Удаление маркеров (Markers)

Маркерные объекты представляют собой DOM-элементы, размещённые поверх WebGL-карты. Удаление маркера осуществляется методом remove, который полностью удаляет его из DOM и освобождает связанные ресурсы.

const marker = new maplibregl.Marker()
    .setLngLat([66.9237, 48.0196])
    .addTo(map);

marker.remove();

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

При массовом управлении маркерами требуется хранение ссылок на созданные экземпляры. Отсутствие контроля приводит к накоплению неиспользуемых DOM-узлов и снижению производительности.


Удаление всплывающих окон и контролов

Popup-объекты также управляются через метод remove.

const popup = new maplibregl.Popup()
    .setLngLat([66.9237, 48.0196])
    .setHTML('Информация')
    .addTo(map);

popup.remove();

Контролы карты (например, масштабирование, геолокация) удаляются через removeControl:

map.removeControl(new maplibregl.NavigationControl());

Важно учитывать, что removeControl требует точной ссылки на экземпляр контроллера. Попытка удалить новый экземпляр без сохранённой ссылки не влияет на уже добавленный элемент.


Очистка событий и обработчиков

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

function onClick(e) {
    console.log(e.lngLat);
}

map.on('click', onClick);

// удаление обработчика
map.off('click', onClick);

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

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


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

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

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

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

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


Динамическое удаление объектов в GeoJSON-потоках

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

Сценарий включает:

  • получение нового набора данных
  • фильтрацию удаляемых объектов
  • повторную передачу данных через setData

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

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


Типичные ошибки при удалении объектов

Часто встречающиеся проблемы включают:

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

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


Массовое удаление объектов при смене состояния карты

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

Процедура включает последовательное удаление:

map.getStyle().layers.forEach(layer => {
    if (layer.id.startsWith('dynamic-')) {
        map.removeLayer(layer.id);
    }
});

Object.keys(map.getStyle().sources).forEach(sourceId => {
    if (sourceId.startsWith('dynamic-')) {
        map.removeSource(sourceId);
    }
});

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


Очистка карты при уничтожении экземпляра

При завершении работы с картой выполняется полная очистка всех ресурсов. Это включает удаление DOM-элементов, обработчиков событий и WebGL-контекста.

map.remove();

Данный вызов освобождает память и предотвращает утечки, связанные с длительным жизненным циклом WebGL-контекста.

Удаление карты является финальной операцией, после которой любые обращения к её методам становятся недопустимыми.