Слой (Layer) в MapLibre GL JS представляет собой описание способа отображения данных на карте. Источник данных определяет, какие объекты существуют, а слой определяет, как эти объекты должны выглядеть и при каких условиях отображаться.
Каждый слой содержит набор базовых свойств, управляющих его идентификацией, связью с источником данных, порядком отрисовки, масштабными ограничениями и визуальными параметрами.
Общая структура слоя выглядит следующим образом:
map.addLayer({
id: 'cities',
type: 'circle',
source: 'cities-source',
paint: {
'circle-radius': 6,
'circle-color': '#ff0000'
}
});
В данном примере:
id — уникальный идентификатор слоя;type — тип визуализации;source — источник данных;paint — свойства оформления.Свойство id задает уникальное имя слоя внутри карты.
{
id: 'roads'
}
Каждый слой обязан иметь собственный идентификатор.
Попытка создать два слоя с одинаковым идентификатором приведет к ошибке:
map.addLayer({
id: 'roads',
type: 'line',
source: 'transport'
});
map.addLayer({
id: 'roads',
type: 'line',
source: 'another-source'
});
Результат:
Layer with id "roads" already exists
Идентификатор используется практически во всех методах управления слоями.
Удаление слоя:
map.removeLayer('roads');
Изменение фильтра:
map.setFilter('roads', [
'==',
'class',
'highway'
]);
Изменение прозрачности:
map.setPaintProperty(
'roads',
'line-opacity',
0.5
);
Получение объекта слоя:
const layer = map.getLayer('roads');
Обычно используются понятные иерархические имена:
id: 'roads-main'
id: 'roads-secondary'
id: 'buildings-3d'
id: 'cities-labels'
id: 'water-polygons'
Такой подход значительно упрощает поддержку больших проектов.
Свойство type определяет способ отображения
геоданных.
{
type: 'circle'
}
Тип слоя влияет на доступные свойства оформления и на способ визуализации объектов.
Используется для фоновой заливки карты.
{
id: 'background',
type: 'background',
paint: {
'background-color': '#f0f0f0'
}
}
Источник данных не требуется.
Предназначен для отображения полигонов.
{
id: 'parks',
type: 'fill',
source: 'parks'
}
Примеры объектов:
Используется для отображения линий.
{
id: 'roads',
type: 'line',
source: 'roads'
}
Примеры объектов:
Отображает точки в виде окружностей.
{
id: 'cities',
type: 'circle',
source: 'cities'
}
Примеры:
Используется для иконок и текста.
{
id: 'labels',
type: 'symbol',
source: 'cities'
}
Поддерживает:
Предназначен для растровых тайлов.
{
id: 'satellite',
type: 'raster',
source: 'satellite-source'
}
Применяется для:
Используется для трехмерных объектов.
{
id: 'buildings',
type: 'fill-extrusion',
source: 'buildings'
}
Позволяет строить:
Создает тепловую карту.
{
id: 'traffic-heat',
type: 'heatmap',
source: 'traffic'
}
Подходит для отображения плотности событий.
Используется для рельефного затенения.
{
id: 'terrain',
type: 'hillshade',
source: 'dem'
}
Работает с цифровыми моделями высот.
Свойство source связывает слой с источником данных.
Источник добавляется отдельно:
map.addSource('cities-source', {
type: 'geojson',
data: '/data/cities.geojson'
});
Затем подключается к слою:
map.addLayer({
id: 'cities',
type: 'circle',
source: 'cities-source'
});
Один набор данных может использоваться несколькими слоями одновременно.
Источник:
map.addSource('cities', {
type: 'geojson',
data: citiesData
});
Слой точек:
map.addLayer({
id: 'cities-circle',
type: 'circle',
source: 'cities'
});
Слой подписей:
map.addLayer({
id: 'cities-labels',
type: 'symbol',
source: 'cities'
});
В результате точки и подписи будут отображаться независимо друг от друга.
Используется только для векторных тайлов.
Внутри одного набора векторных тайлов может находиться несколько слоев данных.
Например:
roads
buildings
water
landuse
railways
Для выбора конкретного слоя используется
source-layer.
{
id: 'roads',
type: 'line',
source: 'vector-source',
'source-layer': 'roads'
}
Источник:
map.addSource('osm', {
type: 'vector',
url: 'https://example.com/tiles.json'
});
Слой дорог:
{
id: 'roads',
type: 'line',
source: 'osm',
'source-layer': 'transportation'
}
Слой зданий:
{
id: 'buildings',
type: 'fill',
source: 'osm',
'source-layer': 'building'
}
Оба слоя используют один и тот же источник тайлов.
Определяет минимальный масштаб отображения слоя.
{
minzoom: 10
}
До достижения масштаба 10 слой не отображается.
map.addLayer({
id: 'city-labels',
type: 'symbol',
source: 'cities',
minzoom: 8
});
Поведение:
| Масштаб | Видимость |
|---|---|
| 5 | Нет |
| 6 | Нет |
| 7 | Нет |
| 8 | Да |
| 10 | Да |
| 15 | Да |
Подписи крупных городов:
minzoom: 3
Подписи улиц:
minzoom: 12
Номера домов:
minzoom: 16
Такой подход предотвращает перегрузку карты большим количеством объектов.
Определяет максимальный масштаб отображения слоя.
{
maxzoom: 15
}
После достижения масштаба 15 слой скрывается.
map.addLayer({
id: 'country-labels',
type: 'symbol',
source: 'countries',
maxzoom: 6
});
Поведение:
| Масштаб | Видимость |
|---|---|
| 2 | Да |
| 4 | Да |
| 6 | Да |
| 7 | Нет |
| 10 | Нет |
Можно ограничить диапазон отображения.
{
minzoom: 8,
maxzoom: 14
}
Слой будет отображаться только между указанными значениями масштаба.
Фильтр позволяет отображать только определенные объекты из источника данных.
Предположим, GeoJSON содержит города разных размеров:
{
"name": "Berlin",
"population": 3600000
}
Можно оставить только крупные города:
filter: [
'>',
'population',
1000000
]
filter: [
'==',
'type',
'capital'
]
Отображаются только столицы.
filter: [
'!=',
'status',
'closed'
]
filter: [
'in',
'class',
'motorway',
'trunk',
'primary'
]
Оператор AND:
filter: [
'all',
['==', 'type', 'city'],
['>', 'population', 500000]
]
Оператор OR:
filter: [
'any',
['==', 'type', 'city'],
['==', 'type', 'capital']
]
Раздел layout содержит свойства, влияющие на структуру
отображения объектов.
layout: {
visibility: 'visible'
}
Изменение layout-свойств обычно требует перерасчета слоя и выполняется реже, чем изменение paint-свойств.
Управляет видимостью слоя.
Показать:
layout: {
visibility: 'visible'
}
Скрыть:
layout: {
visibility: 'none'
}
Скрытие слоя:
map.setLayoutProperty(
'roads',
'visibility',
'none'
);
Показ слоя:
map.setLayoutProperty(
'roads',
'visibility',
'visible'
);
Это один из наиболее часто используемых механизмов управления отображением данных.
Секция paint определяет внешний вид объектов.
Пример:
paint: {
'circle-color': '#ff0000',
'circle-radius': 8
}
Именно здесь задаются:
paint: {
'line-color': '#0066ff',
'line-width': 4
}
paint: {
'fill-color': '#00aa00',
'fill-opacity': 0.5
}
paint: {
'circle-radius': 10,
'circle-color': '#ff6600',
'circle-opacity': 0.8
}
MapLibre GL JS отображает слои сверху вниз в порядке их добавления.
Пример:
map.addLayer(backgroundLayer);
map.addLayer(waterLayer);
map.addLayer(roadLayer);
map.addLayer(labelLayer);
Порядок будет следующим:
labels
roads
water
background
Последний добавленный слой оказывается поверх остальных.
Второй параметр метода addLayer позволяет указать слой,
перед которым необходимо выполнить вставку.
map.addLayer(
newLayer,
'labels'
);
Слой будет размещен непосредственно под слоем
labels.
Текущий стиль содержит массив слоев:
const layers = map.getStyle().layers;
Просмотр идентификаторов:
layers.forEach(layer => {
console.log(layer.id);
});
Этот подход широко применяется при анализе сложных стилей карт.
Практически любой слой строится на комбинации нескольких ключевых параметров:
map.addLayer({
id: 'major-cities',
type: 'circle',
source: 'cities',
minzoom: 5,
maxzoom: 15,
filter: [
'>',
'population',
500000
],
paint: {
'circle-radius': 8,
'circle-color': '#e53935'
}
});
В этом примере:
id идентифицирует слой;type определяет способ отображения;source задает источник данных;minzoom и maxzoom ограничивают диапазон
масштабов;filter выбирает нужные объекты;paint определяет внешний вид.Именно сочетание этих базовых свойств формирует основу любой визуализации в MapLibre GL JS, независимо от сложности карты, количества источников данных и используемого типа слоя.