Визуальная модель в Mapbox GL JS построена вокруг строгого разделения данных и их отображения. Центральным элементом этой модели выступают слои (layers), которые определяют, как геоданные превращаются в визуальные примитивы на карте.
Архитектура слоёв тесно связана с понятием стиля карты. Стиль представляет собой набор источников данных (sources) и слоёв, где каждый слой отвечает за конкретный способ визуализации данных из одного или нескольких источников.
Каждый слой в Mapbox GL JS представляет собой объект с набором свойств:
id)type)source)filter)minzoom,
maxzoom)Слой не содержит геоданных напрямую. Он лишь интерпретирует данные из источника.
Ключевой принцип: слой = правила отображения данных, а не сами данные.
Источник (source) определяет, откуда берутся геометрии. Один источник может использоваться несколькими слоями одновременно.
Основные типы источников:
Связь слоя с источником задаётся через свойство
source:
map.addSource('cities', {
type: 'geojson',
data: '/data/cities.geojson'
});
map.addLayer({
id: 'cities-layer',
type: 'circle',
source: 'cities'
});
Разделение источников и слоёв позволяет переиспользовать данные с разными стилями отображения.
Слои в Mapbox GL JS строго типизированы. Каждый тип соответствует определённой визуальной примитивной модели.
Фоновый слой. Отображает цвет или градиент под всей картой.
{
id: 'background',
type: 'background',
paint: {
'background-color': '#1a1a1a'
}
}
Используется для полигонов. Основной тип для отображения областей.
{
id: 'countries-fill',
type: 'fill',
source: 'countries',
paint: {
'fill-color': '#3bb2d0',
'fill-opacity': 0.6
}
}
Линейные объекты: дороги, маршруты, границы.
{
id: 'roads',
type: 'line',
source: 'roads',
paint: {
'line-color': '#ff8800',
'line-width': 2
}
}
Точечные данные в виде окружностей.
{
id: 'points',
type: 'circle',
source: 'places',
paint: {
'circle-radius': 6,
'circle-color': '#ff0000'
}
}
Комбинированные слои для текста и иконок. Используются для подписей объектов.
{
id: 'labels',
type: 'symbol',
source: 'places',
layout: {
'text-field': ['get', 'name'],
'text-size': 12
}
}
Отображение растровых тайлов (например, спутниковые снимки).
{
id: 'satellite',
type: 'raster',
source: 'satellite-source'
}
3D-экструзия полигонов, часто используется для зданий.
{
id: 'buildings-3d',
type: 'fill-extrusion',
source: 'buildings',
paint: {
'fill-extrusion-height': ['get', 'height'],
'fill-extrusion-color': '#aaa'
}
}
Визуализация плотности точек.
{
id: 'heat',
type: 'heatmap',
source: 'earthquakes',
paint: {
'heatmap-intensity': 1,
'heatmap-color': [
'interpolate',
['linear'],
['heatmap-density'],
0, 'blue',
1, 'red'
]
}
}
Слои в стиле представляют собой упорядоченный стек. Порядок определяет перекрытие визуальных элементов.
Слой, добавленный позже, отображается выше предыдущих.
map.addLayer(layerA);
map.addLayer(layerB); // layerB выше layerA
Контроль порядка возможен через параметр beforeId:
map.addLayer(newLayer, 'existing-layer-id');
Это позволяет точно управлять визуальной иерархией.
Каждый слой разделяется на две группы свойств:
Определяет структурное поведение:
Пример:
layout: {
visibility: 'visible',
'text-field': ['get', 'name']
}
Определяет визуальное оформление:
paint: {
'line-color': '#00ff00',
'line-width': 3
}
Фильтры ограничивают отображаемые объекты внутри слоя без изменения источника.
filter: ['==', ['get', 'type'], 'park']
Фильтры поддерживают логические операторы:
==, !=<, >inall, any, noneПример сложного фильтра:
filter: [
'all',
['==', ['get', 'status'], 'active'],
['>', ['get', 'population'], 100000]
]
Слои поддерживают выражения (expressions), позволяющие строить динамическое поведение стиля.
Пример зависимости цвета от свойства:
'circle-color': [
'interpolate',
['linear'],
['get', 'value'],
0, '#2DC4B2',
100, '#F7455D'
]
Данные могут напрямую управлять визуальными параметрами, что формирует data-driven styling.
Слои могут изменять поведение в зависимости от zoom уровня карты.
minzoom: 5,
maxzoom: 12
Также масштаб может использоваться внутри выражений:
'line-width': [
'interpolate',
['linear'],
['zoom'],
5, 1,
10, 4
]
Слой может быть скрыт без удаления:
layout: {
visibility: 'none'
}
Переключение состояния:
map.setLayoutProperty('layer-id', 'visibility', 'visible');
Каждый слой обязан иметь уникальный id. Он используется
для:
map.removeLayer('layer-id');
Ошибки в идентификаторах приводят к конфликтам при сборке стиля.
Слои не изолированы визуально. Они взаимодействуют через:
opacity)Пример наложения:
Такая структура формирует стандартную карту.
Mapbox GL JS поддерживает кастомные слои через WebGL API.
const customLayer = {
id: 'custom',
type: 'custom',
renderingMode: '3d',
onAdd: function(map, gl) {
// инициализация WebGL ресурсов
},
render: function(gl, matrix) {
// отрисовка
}
};
Это позволяет интегрировать собственные графические пайплайны поверх карты.
Слои формируют сцену, аналогичную графическому движку:
Такая модель обеспечивает высокую гибкость визуализации без изменения исходных данных.