Удаление и перемещение слоев

В Mapbox GL JS слои (layers) являются частью стиля карты и управляются через API объекта map. Каждый слой связан с источником данных (source) и имеет уникальный идентификатор id. Для удаления слоя используется метод removeLayer, который полностью исключает слой из текущего стиля.

Базовая сигнатура:

map.removeLayer('layer-id');

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

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

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

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

Метод getLayer возвращает объект слоя или undefined, если слой отсутствует.

Порядок удаления зависимых слоёв

Некоторые слои зависят от других (например, before-слои при добавлении). При удалении важно учитывать порядок:

map.removeLayer('labels-layer');
map.removeLayer('roads-layer');

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


Перемещение слоёв

Mapbox GL JS позволяет изменять порядок слоёв в стеке отрисовки. Порядок определяет, какие слои будут отображаться выше других.

Основной метод:

map.moveLayer('layer-id');

По умолчанию слой перемещается наверх стека.

Перемещение под другой слой

Чаще используется вариант вставки слоя перед другим:

map.moveLayer('layer-id', 'target-layer-id');

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

  • layer-id — перемещаемый слой
  • target-layer-id — слой, перед которым будет размещён первый

Пример использования

map.moveLayer('roads-layer', 'labels-layer');

В этом случае слой дорог окажется ниже слоя подписей.


Контроль порядка слоёв через стиль

Текущий порядок слоёв можно получить через стиль карты:

const layers = map.getStyle().layers;
console.log(layers);

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


Перестановка слоёв с учётом группировки

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

Пример перемещения слоя в определённую группу:

const layers = map.getStyle().layers;

const labelLayerId = layers.find(
    layer => layer.type === 'symbol' && layer.layout['text-field']
).id;

map.moveLayer('custom-layer', labelLayerId);

Здесь слой помещается прямо под первый слой с текстовыми подписями.


Удаление и повторное добавление слоя

Иногда слой необходимо не просто удалить, а заменить. В Mapbox GL JS нет метода «обновить слой», поэтому используется комбинация удаления и добавления:

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

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

Это особенно актуально при динамическом изменении стилей paint и layout.


Работа с зависимыми слоями и источниками

При удалении слоя источник данных остаётся активным:

map.removeLayer('points-layer');
map.removeSource('points-source');

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

Source is still in use by layer


Перемещение слоёв при добавлении

Альтернативой moveLayer является параметр beforeId в addLayer. Он задаёт позицию слоя сразу при создании:

map.addLayer({
    id: 'custom-layer',
    type: 'line',
    source: 'route-source',
    paint: {
        'line-color': '#0000ff',
        'line-width': 3
    }
}, 'labels-layer');

Этот подход предпочтительнее, если порядок известен заранее, так как исключает дополнительный вызов moveLayer.


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

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

function bringLayerToFront(layerId) {
    if (map.getLayer(layerId)) {
        map.moveLayer(layerId);
    }
}

Или возвращать слой на исходную позицию:

function sendLayerBack(layerId, beforeId) {
    if (map.getLayer(layerId)) {
        map.moveLayer(layerId, beforeId);
    }
}

Типичные ошибки при удалении и перемещении слоёв

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

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

Для предотвращения ошибок используется проверка состояния стиля:

if (map.isStyleLoaded() && map.getLayer('layer-id')) {
    map.removeLayer('layer-id');
}

Перестройка слоёв при смене стиля карты

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

map.on('style.load', () => {
    map.addLayer({
        id: 'custom-layer',
        type: 'fill',
        source: 'polygon-source',
        paint: {
            'fill-color': '#00ff00',
            'fill-opacity': 0.5
        }
    });
});

Это гарантирует корректную инициализацию структуры слоёв после смены стиля.


Приоритеты отрисовки и стек слоёв

Mapbox GL JS использует строгую модель стека:

  • нижние слои рисуются первыми
  • верхние слои перекрывают нижние
  • порядок определяется массивом style.layers

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