В Mapbox GL JS визуализация карты строится вокруг декларативной модели стилей, где каждый визуальный элемент представлен слоем (layer). Слои описывают, как данные из источников (sources) должны отображаться на карте: линии дорог, полигоны зданий, точки интереса, тепловые карты и другие географические сущности.
Слой не содержит геометрии — он лишь интерпретирует данные из
источника и задаёт правила отрисовки через параметры paint
и layout.
Каждый слой привязан к источнику данных через поле
source. Источник может быть:
Связь слоя и источника определяет, какие данные будут визуализированы и каким способом.
map.addSource('cities', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [69.59, 42.32]
},
properties: {
name: 'City A'
}
}
]
}
});
После добавления источника создаётся слой, который использует эти данные.
Для добавления слоя используется метод addLayer:
map.addLayer({
id: 'cities-layer',
type: 'circle',
source: 'cities',
paint: {
'circle-radius': 6,
'circle-color': '#ff5200'
}
});
Каждый слой обязан иметь:
id — уникальный идентификатор слояtype — тип визуализацииsource — источник данныхСлои в Mapbox GL JS образуют стек. Порядок добавления влияет на визуальную приоритетность: более поздние слои отображаются поверх ранних.
Для управления порядком используется второй аргумент
addLayer:
map.addLayer({
id: 'roads',
type: 'line',
source: 'transport',
'source-layer': 'road',
paint: {
'line-color': '#333',
'line-width': 2
}
}, 'water');
Здесь слой roads будет добавлен перед слоем
water.
Используется для отображения площадных объектов: границ, зданий, регионов.
map.addLayer({
id: 'parks-fill',
type: 'fill',
source: 'parks',
paint: {
'fill-color': '#00aa55',
'fill-opacity': 0.4
}
});
Подходит для дорог, маршрутов, границ.
map.addLayer({
id: 'roads-line',
type: 'line',
source: 'roads',
paint: {
'line-color': '#888',
'line-width': 2
}
});
Используется для отображения точечных объектов.
map.addLayer({
id: 'cities-circle',
type: 'circle',
source: 'cities',
paint: {
'circle-radius': 5,
'circle-color': '#1e90ff'
}
});
Позволяет отображать подписи и маркеры.
map.addLayer({
id: 'labels',
type: 'symbol',
source: 'cities',
layout: {
'text-field': ['get', 'name'],
'text-size': 12
}
});
Используется для построения 3D зданий.
map.addLayer({
id: 'buildings-3d',
type: 'fill-extrusion',
source: 'buildings',
paint: {
'fill-extrusion-height': ['get', 'height'],
'fill-extrusion-color': '#aaa',
'fill-extrusion-opacity': 0.8
}
});
Применяется для анализа плотности точек.
map.addLayer({
id: 'heatmap',
type: 'heatmap',
source: 'earthquakes',
paint: {
'heatmap-intensity': 1,
'heatmap-radius': 10
}
});
Каждый слой управляется двумя основными группами свойств:
Отвечает за структуру и поведение слоя:
visibility)text-field)icon-image)layout: {
visibility: 'visible',
'text-field': ['get', 'name']
}
Определяет визуальное оформление:
paint: {
'line-color': '#ff0000',
'line-width': 3
}
Слои можно динамически скрывать и отображать через
setLayoutProperty:
map.setLayoutProperty('roads-line', 'visibility', 'none');
Возврат отображения:
map.setLayoutProperty('roads-line', 'visibility', 'visible');
Фильтры ограничивают набор отображаемых объектов внутри слоя.
map.addLayer({
id: 'major-cities',
type: 'circle',
source: 'cities',
filter: ['>', ['get', 'population'], 1000000],
paint: {
'circle-color': '#ff0000'
}
});
Фильтры основаны на выражениях Mapbox Expressions.
Слои поддерживают выражения, позволяющие задавать динамическое поведение стиля.
'circle-color': [
'interpolate',
['linear'],
['get', 'population'],
100000, '#2DC4B2',
1000000, '#3BB3C3',
5000000, '#129DD8'
]
Такие конструкции позволяют строить непрерывные шкалы визуализации.
Изменение параметров слоя выполняется без его пересоздания:
map.setPaintProperty('cities-circle', 'circle-radius', 10);
или
map.setFilter('major-cities', ['>', ['get', 'population'], 500000]);
Перед удалением слоя необходимо убедиться, что он не используется другими слоями:
map.removeLayer('cities-circle');
Слои делятся на логические группы:
Правильное позиционирование слоёв критично для читаемости карты, поскольку неправильный порядок приводит к перекрытию важных объектов менее значимыми.
При использовании векторных тайлов требуется указание
source-layer:
map.addLayer({
id: 'road-main',
type: 'line',
source: 'mapbox-streets',
'source-layer': 'road',
paint: {
'line-color': '#000',
'line-width': 2
}
});
source-layer определяет конкретный слой внутри
векторного тайлового набора.
Один источник может использоваться несколькими слоями одновременно:
map.addLayer({
id: 'water-fill',
type: 'fill',
source: 'water',
paint: {
'fill-color': '#00bfff'
}
});
map.addLayer({
id: 'water-outline',
type: 'line',
source: 'water',
paint: {
'line-color': '#0077aa'
}
});
Такой подход позволяет разделять заливку и обводку на независимые стили.
Слои добавляются только после события load:
map.on('load', () => {
map.addLayer({
id: 'cities',
type: 'circle',
source: 'cities'
});
});
Это связано с тем, что стиль карты должен быть полностью инициализирован до модификации.
Слои участвуют в системе событий:
map.on('click', 'cities-circle', (e) => {
console.log(e.features);
});
Каждый слой может быть интерактивной областью, если он поддерживает hit-testing.
Порядок слоёв влияет не только на визуализацию, но и на обработку событий: верхние слои перехватывают события первыми.