В Leaflet группировка слоёв реализуется через два базовых контейнера:
L.LayerGroup и L.FeatureGroup. Оба позволяют
объединять несколько слоёв в единый объект, управлять ими как единым
целым и применять массовые операции добавления, удаления и перебора.
L.LayerGroup представляет собой контейнер для любых
слоёв: маркеров, тайловых слоёв, геометрий и пользовательских
объектов.
const group = L.layerGroup();
Также возможно инициализировать сразу набор слоёв:
const group = L.layerGroup([
L.marker([51.5, -0.09]),
L.marker([51.51, -0.1]),
L.polyline([[51.5, -0.09], [51.51, -0.1]])
]);
Добавляет слой в группу.
group.addLayer(L.marker([51.5, -0.09]));
Возвращает сам объект группы, что позволяет строить цепочки вызовов.
Удаляет конкретный слой из группы.
group.removeLayer(marker);
Также можно передавать идентификатор слоя:
group.removeLayer(layerId);
Проверяет наличие слоя в группе.
if (group.hasLayer(marker)) {
// слой присутствует
}
Полностью очищает группу, удаляя все слои.
group.clearLayers();
Метод часто используется при полной перезагрузке данных.
Возвращает массив всех слоёв внутри группы.
const layers = group.getLayers();
Результат можно использовать для итерации или анализа структуры.
Позволяет пройтись по каждому слою группы.
group.eachLayer(layer => {
console.log(layer);
});
Внутри callback доступен каждый слой без необходимости извлечения массива.
Добавляет всю группу на карту как единый слой.
group.addTo(map);
Эквивалент:
map.addLayer(group);
Удаляет группу с карты.
group.removeFrom(map);
L.FeatureGroup наследуется от LayerGroup,
но добавляет функциональность, связанную с векторными объектами:
маркерами, полигонами, линиями.
const featureGroup = L.featureGroup([
L.marker([51.5, -0.09]),
L.circle([51.51, -0.1], { radius: 200 })
]);
Возвращает ограничивающий прямоугольник всех слоёв группы.
const bounds = featureGroup.getBounds();
map.fitBounds(bounds);
Метод особенно важен для автоматического масштабирования карты под содержимое группы.
Привязывает всплывающее окно ко всей группе.
featureGroup.bindPopup('Объекты группы');
Popup будет активироваться при взаимодействии с любым элементом внутри группы.
Привязывает tooltip ко всей группе.
featureGroup.bindTooltip('Информация');
FeatureGroup поддерживает обработку событий как единый объект.
featureGroup.on('click', e => {
console.log('Клик по любому объекту группы');
});
События делегируются от дочерних элементов к группе.
Карта Leaflet также предоставляет методы управления слоями, включая группы.
Добавляет слой или группу.
map.addLayer(group);
Удаляет слой или группу с карты.
map.removeLayer(group);
Проверяет наличие слоя на карте.
map.hasLayer(group);
Группы могут содержать другие группы, создавая иерархическую структуру.
const innerGroup = L.layerGroup([
L.marker([51.5, -0.09])
]);
const outerGroup = L.layerGroup([innerGroup]);
outerGroup.addTo(map);
При управлении такой структурой методы clearLayers,
removeLayer и eachLayer применяются рекурсивно
только к первому уровню, без автоматического глубокого обхода.
Для сложных структур используется комбинированный обход:
outerGroup.eachLayer(layer => {
if (layer instanceof L.LayerGroup) {
layer.eachLayer(inner => {
console.log(inner);
});
} else {
console.log(layer);
}
});
Каждый слой внутри группы имеет внутренний идентификатор, используемый Leaflet для быстрого доступа.
Доступ к слою по идентификатору (доступен в
FeatureGroup).
const layer = featureGroup.getLayer(id);
Получение идентификатора слоя.
const id = featureGroup.getLayerId(marker);
Группы слоёв часто используются для пакетного управления отображением данных.
if (map.hasLayer(group)) {
map.removeLayer(group);
} else {
map.addLayer(group);
}
group.clearLayers();
data.forEach(item => {
group.addLayer(L.marker([item.lat, item.lng]));
});
map.fitBounds(featureGroup.getBounds());
События внутри FeatureGroup распространяются от дочерних
слоёв вверх.
featureGroup.on('mouseover', e => {
console.log('Наведение на элемент группы');
});
Каждый дочерний слой остаётся источником события, но группа получает агрегированный поток событий.
LayerGroup не хранит геометрическую информациюFeatureGroup ориентирован на векторные объектыclearLayers() не вызывает индивидуальные
пользовательские очистки слоёвgetBounds() доступен только для
FeatureGroupconst restaurants = L.layerGroup();
const parks = L.layerGroup();
const transport = L.layerGroup();
map.addLayer(restaurants);
map.removeLayer(parks);
fetch('/api/points')
.then(res => res.json())
.then(data => {
group.clearLayers();
data.forEach(p => {
group.addLayer(L.marker([p.lat, p.lng]));
});
});