Базовые и оверлейные слои

Leaflet Leaflet official website строится вокруг концепции слоёв карты, где каждый визуальный элемент представляет собой отдельный слой, управляемый единым интерфейсом карты. Разделение на базовые и оверлейные слои позволяет гибко комбинировать картографические данные и визуальные объекты без нарушения общей структуры отображения.

Базовые слои — это взаимоисключающие подложки карты. В любой момент времени активен только один базовый слой. Чаще всего это тайловые карты (tile layers), предоставляющие географическую подложку: улицы, спутник, топографию или стилизованные карты.

TileLayer как основа базового слоя

Основной класс для работы с базовыми слоями — L.tileLayer. Он загружает изображения тайлов по шаблону URL:

const osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  attribution: '© OpenStreetMap contributors',
  maxZoom: 19
});

Ключевые параметры:

  • {s} — поддомен (a, b, c) для балансировки нагрузки
  • {z} — уровень масштабирования
  • {x}, {y} — координаты тайла
  • attribution — обязательная атрибуция источника данных
  • maxZoom и minZoom — ограничения масштабирования

Добавление базового слоя на карту:

const map = L.map('map', {
  center: [55.751244, 37.618423],
  zoom: 10,
  layers: [osm]
});

Переключение базовых слоёв

Leaflet поддерживает механизм смены базовой карты через L.control.layers. Это создаёт интерфейс, позволяющий переключать подложки без ручного удаления и добавления слоёв.

const osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
const satellite = L.tileLayer('https://{s}.sat.abc.com/{z}/{x}/{y}.jpg');

const baseMaps = {
  "OpenStreetMap": osm,
  "Спутник": satellite
};

const map = L.map('map', {
  center: [55.75, 37.61],
  zoom: 10,
  layers: [osm]
});

L.control.layers(baseMaps).addTo(map);

Особенность базовых слоёв:

  • одновременно активен только один слой из группы
  • при переключении предыдущий автоматически удаляется
  • логика реализуется через radio-кнопки в UI контроле

Оверлейные слои (Overlay Layers)

Оверлейные слои — это дополнительные элементы, накладываемые поверх базовой карты. В отличие от базовых слоёв, они могут быть включены одновременно в любом количестве.

Типичные оверлеи:

  • маркеры (L.marker)
  • линии (L.polyline)
  • полигоны (L.polygon)
  • окружности (L.circle)
  • GeoJSON-слои (L.geoJSON)
  • группы объектов (L.layerGroup, L.featureGroup)

Маркеры как оверлей

const marker = L.marker([55.75, 37.61]).addTo(map);

Полилинии

const line = L.polyline([
  [55.75, 37.61],
  [55.76, 37.62],
  [55.77, 37.60]
], {
  color: 'blue'
}).addTo(map);

Полигоны

const polygon = L.polygon([
  [55.75, 37.61],
  [55.76, 37.62],
  [55.74, 37.63]
], {
  color: 'red',
  fillColor: '#f03',
  fillOpacity: 0.3
}).addTo(map);

Управление оверлеями через Layer Control

Оверлейные слои также интегрируются в L.control.layers, но отображаются как чекбоксы, позволяя включать несколько слоёв одновременно.

const cities = L.layerGroup();
const marker1 = L.marker([55.75, 37.61]).addTo(cities);
const marker2 = L.marker([59.93, 30.31]).addTo(cities);

const overlays = {
  "Города": cities
};

L.control.layers(baseMaps, overlays).addTo(map);

Ключевая логика:

  • baseMaps → взаимоисключающие слои
  • overlays → независимые слои

LayerGroup и FeatureGroup

LayerGroup

L.layerGroup объединяет несколько слоёв в единый контейнер без дополнительной логики взаимодействия.

const group = L.layerGroup([
  L.marker([55.75, 37.61]),
  L.marker([59.93, 30.31])
]);

group.addTo(map);

Используется для:

  • логической группировки объектов
  • массового добавления/удаления
  • управления видимостью

FeatureGroup

L.featureGroup расширяет LayerGroup, добавляя возможность обработки событий и вычисления границ.

const featureGroup = L.featureGroup([
  L.marker([55.75, 37.61]),
  L.polygon([
    [55.74, 37.60],
    [55.76, 37.60],
    [55.75, 37.62]
  ])
]).addTo(map);

map.fitBounds(featureGroup.getBounds());

Особенности:

  • поддержка событий (click, mouseover)
  • вычисление bounding box
  • удобен для динамического зума на группу объектов

Панели (Panes) и управление z-index

Leaflet использует систему панелей для управления порядком наложения слоёв. Каждая панель соответствует уровню z-index.

Основные панели:

  • tilePane — базовые тайлы
  • overlayPane — векторные оверлеи
  • markerPane — маркеры
  • popupPane — всплывающие окна

Создание пользовательской панели:

map.createPane('customPane');
map.getPane('customPane').style.zIndex = 650;

const circle = L.circle([55.75, 37.61], {
  pane: 'customPane',
  radius: 500
}).addTo(map);

Это позволяет:

  • управлять перекрытием слоёв
  • изолировать визуальные элементы
  • создавать сложные визуальные композиции

GeoJSON как оверлейный слой

GeoJSON интегрируется через L.geoJSON, автоматически создавая слои на основе данных.

const geojson = L.geoJSON(data, {
  style: function(feature) {
    return { color: 'green' };
  },
  onEachFeature: function(feature, layer) {
    layer.bindPopup(feature.properties.name);
  }
}).addTo(map);

Особенности:

  • автоматическое создание слоёв
  • поддержка событий
  • стилизация через функции
  • масштабируемость для больших наборов данных

Динамическое управление слоями

Любой слой можно добавлять и удалять динамически:

map.addLayer(osm);
map.removeLayer(osm);

Проверка состояния:

map.hasLayer(osm);

Это используется для:

  • условного отображения данных
  • фильтрации оверлеев
  • переключения режимов карты

Комбинирование базовых и оверлейных слоёв

Типичная архитектура карты включает:

  • один базовый слой (тайлы)
  • множество оверлеев (данные)
  • контроллер слоёв
  • группировку логических объектов
const map = L.map('map', {
  center: [55.75, 37.61],
  zoom: 10
});

const osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);

const markers = L.layerGroup([
  L.marker([55.75, 37.61]),
  L.marker([55.76, 37.62])
]).addTo(map);

L.control.layers(
  { "OSM": osm },
  { "Маркерный слой": markers }
).addTo(map);

Такая структура позволяет отделить:

  • источник подложки
  • бизнес-данные
  • визуальные эффекты
  • пользовательское взаимодействие

Поведение слоёв при масштабировании

Разные типы слоёв реагируют на zoom по-разному:

  • tileLayer — перезагружает тайлы
  • marker — масштабируется визуально без изменения геометрии
  • vector layers — пересчитываются при необходимости
  • GeoJSON — может рестилироваться динамически
map.on('zoomend', () => {
  console.log(map.getZoom());
});

Это позволяет:

  • адаптировать визуализацию под масштаб
  • скрывать или показывать объекты
  • изменять стиль в зависимости от zoom level