В MapLibre GL JS управление отображением слоёв строится вокруг
свойства layout.visibility, которое определяет, участвует
ли слой в рендеринге сцены. Это базовый механизм, через который
реализуются переключатели карт, тематические режимы отображения,
фильтрация визуальных уровней и динамическая настройка интерфейса
карты.
Слой в MapLibre GL JS представляет собой декларативное описание того, как геоданные из источника должны быть визуализированы. Видимость слоя — это не удаление данных и не отключение источника, а лишь управление участием слоя в отрисовке кадра.
Каждый слой в стиле может содержать блок layout, внутри
которого задаётся параметр:
visibility: "visible" — слой отображается и участвует в
рендерингеvisibility: "none" — слой полностью исключается из
отрисовки{
id: "roads",
type: "line",
source: "vector-source",
"source-layer": "transportation",
layout: {
visibility: "visible"
},
paint: {
"line-color": "#888",
"line-width": 2
}
}
Отключение слоя:
map.setLayoutProperty("roads", "visibility", "none");
Включение слоя:
map.setLayoutProperty("roads", "visibility", "visible");
Этот механизм работает мгновенно и не требует пересборки источника данных.
Важно различать несколько уровней управления отображением:
visibility)Полное включение или выключение слоя на уровне рендеринга.
filter)Управляет тем, какие фичи из источника попадают в слой.
map.setFilter("roads", ["==", ["get", "type"], "primary"]);
paint.*-opacity)Позволяет скрывать визуально, но слой продолжает участвовать в отрисовке.
map.setPaintProperty("roads", "line-opacity", 0);
Различие принципиально: visibility: none отключает слой
на уровне pipeline, тогда как opacity и filter продолжают выполнять
вычисления.
Отключение слоя через visibility: none имеет прямое
влияние на производительность:
При большом количестве слоёв (десятки и сотни) переключение видимости становится ключевым инструментом оптимизации интерфейса карты.
Особенно заметно это в сценариях:
MapLibre GL JS предоставляет несколько методов для управления состоянием слоёв:
Основной способ изменения visibility:
map.setLayoutProperty("buildings", "visibility", "none");
Позволяет получить текущее состояние:
map.getLayoutProperty("buildings", "visibility");
Удаление слоя:
map.removeLayer("buildings");
Разница с visibility: none:
removeLayer полностью удаляет слой из стиляvisibility: none сохраняет слой и его конфигурациюvisibility не требует
пересоздания слояУдаление оправдано только при динамическом изменении структуры стиля, тогда как visibility используется для переключений состояния.
Хотя visibility не поддерживает выражения напрямую, его
поведение часто комбинируется с параметрами:
minzoommaxzoom{
id: "city-labels",
type: "symbol",
source: "places",
layout: {
"text-field": "{name}"
},
minzoom: 10,
maxzoom: 15
}
Такая конфигурация позволяет скрывать слой автоматически при выходе за диапазон зума.
В отличие от visibility, это не переключение состояния,
а встроенное условие рендеринга.
В MapLibre GL JS порядок слоёв строго определяет их наложение. Даже если слой видим, он может быть перекрыт другим слоем выше по стеку.
При изменении видимости важно учитывать:
Пример управления порядком:
map.moveLayer("roads", "waterways");
Свойство visibility не поддерживает плавные переходы.
Переключение происходит мгновенно.
Для создания визуальной анимации скрытия используются альтернативные подходы:
map.setPaintProperty("roads", "line-opacity", 1);
map.setPaintProperty("roads", "line-opacity", 0);
Типичный паттерн:
visibility: nonemap.setPaintProperty("roads", "line-opacity", 0);
setTimeout(() => {
map.setLayoutProperty("roads", "visibility", "none");
}, 200);
Это позволяет избежать резкого исчезновения геометрии.
Symbol layers (type: "symbol") имеют дополнительную
сложность, так как включают:
При visibility: none полностью отключается:
Это делает symbol layers особенно чувствительными к переключению видимости с точки зрения производительности.
Важно понимать, что visibility слоя не влияет на источник
(source):
Поэтому переключение видимости — это операция уровня представления, а не данных.
Хотя visibility не является выражаемым параметром,
аналогичная логика достигается через фильтры и свойства
paint/layout:
map.setFilter("roads", ["==", ["get", "class"], "primary"]);
Или через zoom-based стили:
"line-opacity": [
"interpolate",
["linear"],
["zoom"],
5, 0,
10, 1
]
Такие подходы заменяют необходимость частого переключения visibility в сложных сценах.
Слой с visibility: none полностью исключается из:
map.queryRenderedFeatures(point, {
layers: ["roads"]
});
Если слой скрыт, он не вернёт результаты, даже если геометрия присутствует в данных.
Это важно при реализации:
Группы слоёв управляются синхронно:
const layers = ["roads", "buildings", "labels"];
layers.forEach(id => {
map.setLayoutProperty(id, "visibility", "none");
});
Например:
Каждый режим активирует свой набор слоёв, остальные скрываются через
visibility: none.
Слои загружаются заранее, но становятся видимыми только при необходимости:
map.setLayoutProperty("3d-buildings", "visibility", "visible");
Это уменьшает задержки при переключении режимов.
Несмотря на простоту, модель имеет ограничения:
Поэтому в сложных приложениях visibility используется как часть более широкой стратегии управления стилем, а не как единственный механизм отображения.