В Mapbox GL JS визуализация карты строится на основе слоёв (layers), каждый из которых описывает способ отображения географических данных из источников (sources). Все слои внутри стиля образуют строго упорядоченный стек рендеринга, где порядок определяет, что будет отрисовано поверх чего.
Ключевая особенность системы слоёв заключается в том, что порядок их
добавления влияет на итоговый визуальный результат. Более поздний слой
по умолчанию отображается выше предыдущих. Однако в реальных приложениях
требуется точный контроль позиции слоя относительно уже существующих
элементов. Для этого используется опция beforeId.
beforeId — параметр метода добавления слоя, позволяющий
явно указать, перед каким существующим слоем должен быть вставлен новый
слой.
Метод:
map.addLayer(layer, beforeId);
Где:
layer — объект слоя в формате Mapbox Style
SpecificationbeforeId — строковый идентификатор слоя, перед которым
должен быть размещён новый слойЕсли beforeId не указан, слой добавляется в конец стека,
становясь верхним.
Слои в Mapbox GL JS образуют упорядоченный массив. При использовании
beforeId происходит не добавление в конец, а вставка в
конкретную позицию:
beforeIdТаким образом формируется предсказуемая структура отображения, независимо от порядка загрузки данных.
Различные типы геометрий требуют строгого порядка отображения:
Использование beforeId позволяет фиксировать эти
отношения независимо от момента добавления слоёв.
map.addLayer({
id: 'water-fill',
type: 'fill',
source: 'water'
});
map.addLayer({
id: 'road-line',
type: 'line',
source: 'roads'
}, 'water-fill');
В этом примере слой дорог будет вставлен перед водными полигонами и, следовательно, отображаться ниже них.
Mapbox базовые стили содержат десятки предопределённых слоёв: дороги, границы, подписи, POI и другие элементы. При добавлении пользовательских данных часто требуется встроить их в существующую визуальную иерархию.
map.addLayer({
id: 'custom-parks',
type: 'fill',
source: 'parks'
}, 'road-label');
Здесь слой парков будет вставлен перед слоем road-label,
что позволяет разместить полигоны под подписями дорог.
Символические слои (symbol) имеют особую важность, так
как они отвечают за подписи и иконки. Часто требуется гарантировать, что
пользовательские элементы не перекрывают текст карты.
map.addLayer({
id: 'poi-markers',
type: 'symbol',
source: 'places',
layout: {
'icon-image': 'marker-15',
'text-field': ['get', 'name']
}
}, 'place-label');
Такой подход обеспечивает корректное размещение пользовательских POI под или над системными подписями.
Если указанный beforeId отсутствует в текущем стиле:
beforeId не
задавалсяЭто важно учитывать при динамическом добавлении слоёв, когда структура стиля может меняться.
beforeId опирается исключительно на текущее состояние
стиля. Это означает:
Поэтому при сложной композиции слоёв требуется централизованная логика их добавления.
При загрузке или смене стиля через setStyle:
map.setStyle('mapbox://styles/mapbox/streets-v12');
все слои переинициализируются. После этого:
beforeId должен выполняться после
события style.loadmap.on('style.load', () => {
map.addLayer(customLayer, 'waterway-label');
});
При использовании векторных тайлов beforeId работает
только на уровне отображаемых слоёв, а не источников данных. Один
источник может содержать несколько source-layers, но порядок их
визуализации контролируется исключительно слоями Mapbox GL JS.
Несмотря на гибкость, существуют ограничения:
beforeId зависит от точного совпадения строки ID слоя.
Любое изменение ID в стиле приводит к необходимости корректировки логики
вставки.
Нельзя задать:
Только конкретный слой.
Если несколько модулей добавляют слои независимо, возможны ситуации:
beforeId ещё не добавленСоздаётся список базовых якорных слоёв:
backgroundwaterroadroad-labelpoi-labelВсе пользовательские слои вставляются относительно этих точек:
const LAYERS = {
water: 'water',
roads: 'road',
labels: 'road-label'
};
map.addLayer(customLine, LAYERS.roads);
Слои группируются по смыслу:
beforeId используется как механизм закрепления границ
между уровнями.
Сам по себе beforeId не влияет на производительность
отрисовки, так как:
Однако частые вставки слоёв с перестройкой порядка могут:
При удалении слоя:
map.removeLayer('road-line');
структура стека изменяется, и последующие вставки через
beforeId могут ссылаться на уже несуществующие позиции.
При изменении свойств слоя:
map.setLayoutProperty('road-line', 'visibility', 'none');
слой остаётся в стеке, и beforeId продолжает учитывать
его позицию.
Для стабильного управления порядком слоёв используется стратегия:
beforeIdТакая модель устраняет зависимость от порядка загрузки и обеспечивает детерминированный рендеринг.
В Mapbox GL JS визуальная иерархия не задаётся декларативно через
уровни, а формируется порядком слоёв. beforeId становится
инструментом построения этой иерархии, позволяя:
Фактически он выступает как низкоуровневый механизм композиции сцены, аналогичный z-index в DOM, но с привязкой к конкретному графу слоёв.