Класс TileLayer

TileLayer является одним из базовых классов Leaflet и отвечает за отображение тайловых слоёв карты. Тайловый слой представляет собой набор изображений фиксированного размера, которые загружаются с сервера по координатам {x, y, z} (где z — уровень масштабирования, x и y — координаты тайла).

В Leaflet данный класс реализован как L.TileLayer и чаще всего создаётся через фабричную функцию L.tileLayer.


Создание слоя

Базовая форма создания тайлового слоя:

L.tileLayer(urlTemplate, options)

URL-шаблон

URL содержит плейсхолдеры:

  • {z} — уровень масштаба
  • {x} — координата тайла по оси X
  • {y} — координата тайла по оси Y
  • {s} — поддомены (если используются)

Пример:

const layer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  subdomains: 'abc',
  maxZoom: 19
});

Основные опции

minZoom и maxZoom

Ограничивают диапазон масштабирования, при котором слой активен.

L.tileLayer(url, {
  minZoom: 0,
  maxZoom: 18
});

tileSize

Размер тайла в пикселях. Стандартное значение — 256.

tileSize: 256

При нестандартных серверах возможно использование 512:

tileSize: 512

opacity

Устанавливает прозрачность слоя.

opacity: 0.7

Используется для наложения нескольких слоёв.


attribution

Текст атрибуции источника данных карты.

attribution: '© OpenStreetMap contributors'

subdomains

Позволяет распределить загрузку тайлов между несколькими поддоменами.

subdomains: 'abc'

или массив:

subdomains: ['a', 'b', 'c']

errorTileUrl

URL изображения, которое подставляется при ошибке загрузки тайла.

errorTileUrl: '/images/tile-error.png'

zoomOffset

Смещение уровня масштабирования для серверов с нестандартной нумерацией тайлов.

zoomOffset: 1

tms

Используется при TMS-схеме тайлинга, где ось Y инвертирована.

tms: true

detectRetina

Автоматически загружает тайлы высокого разрешения для Retina-экранов.

detectRetina: true

crossOrigin

Настройка CORS для загрузки изображений.

crossOrigin: true

или

crossOrigin: 'anonymous'

Добавление на карту

Слой подключается к карте через метод addTo:

const map = L.map('map');

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

tiles.addTo(map);

Эквивалентная запись:

L.tileLayer(url, options).addTo(map);

Управление слоем

Удаление слоя

map.removeLayer(tiles);

или:

tiles.remove();

Изменение URL

Позволяет динамически переключать источник тайлов.

tiles.setUrl('https://{s}.tile.example.com/{z}/{x}/{y}.png');

Изменение прозрачности

tiles.setOpacity(0.5);

Изменение z-index

Определяет порядок наложения слоёв.

tiles.setZIndex(1000);

Перемещение слоя

tiles.bringToFront();
tiles.bringToBack();

Поведение загрузки тайлов

TileLayer реализует ленивую загрузку: тайлы запрашиваются только при необходимости в текущей области видимости карты.

Механизм включает:

  • вычисление текущих тайлов по bbox карты
  • очередь загрузки изображений
  • кэширование уже загруженных тайлов
  • отмену ненужных запросов при перемещении карты

События TileLayer

loading

Срабатывает при начале загрузки тайлов.

tiles.on('loading', () => {
  console.log('началась загрузка тайлов');
});

load

Срабатывает, когда все тайлы текущего вида загружены.

tiles.on('load', () => {
  console.log('все тайлы загружены');
});

tileload

Срабатывает при загрузке отдельного тайла.

tiles.on('tileload', (event) => {
  console.log(event.tile.src);
});

tileerror

Возникает при ошибке загрузки тайла.

tiles.on('tileerror', (event) => {
  console.log('ошибка тайла', event.coords);
});

Внутренняя структура тайлов

Каждый тайл представляет собой DOM-элемент <img>, который:

  • создаётся при необходимости
  • позиционируется абсолютным образом
  • обновляется при смене масштаба или перемещении карты

Координаты тайла рассчитываются по формуле привязки к Web Mercator проекции.


Поддержка Retina-дисплеев

При включённой опции detectRetina происходит:

  • увеличение zoom-уровня на 1
  • загрузка тайлов 512×512 вместо 256×256
  • последующее масштабирование изображения

Кэширование и производительность

TileLayer использует встроенный кэш DOM:

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

Оптимизация включает:

  • ограничение количества одновременных загрузок
  • приоритет загрузки центральных тайлов
  • отмену загрузки при быстром pan/zoom

Работа с нестандартными проекциями

Хотя Leaflet по умолчанию использует Web Mercator, TileLayer может адаптироваться через:

  • tms: true — инверсия оси Y
  • кастомные CRS (Coordinate Reference System)
  • смещение zoomOffset

Пример конфигурации слоя высокой детализации

const highResTiles = L.tileLayer('https://tiles.server.com/{z}/{x}/{y}.png', {
  tileSize: 512,
  zoomOffset: -1,
  detectRetina: true,
  maxZoom: 20,
  attribution: 'Map data source'
});

Несколько слоёв одновременно

const base = L.tileLayer(url1, { maxZoom: 18 });
const labels = L.tileLayer(url2, { maxZoom: 18, opacity: 0.8 });

base.addTo(map);
labels.addTo(map);

Слои накладываются в порядке добавления или через zIndex.


Динамическая замена слоя

function switchLayer(type) {
  tiles.setUrl(
    type === 'satellite'
      ? 'https://sat.tiles/{z}/{x}/{y}.jpg'
      : 'https://map.tiles/{z}/{x}/{y}.png'
  );
}

Ограничения и особенности

  • производительность зависит от сервера тайлов
  • отсутствие тайлов приводит к пустым участкам карты
  • высокие zoom-уровни требуют увеличенного объёма памяти
  • неправильный tileSize вызывает смещение карты
  • CORS ограничения могут блокировать загрузку изображений

Контейнер слоя

TileLayer создаёт собственный DOM-контейнер внутри панели карты:

  • хранит <img> элементы тайлов
  • управляет позиционированием через CSS transform
  • синхронизируется с системой координат карты

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

При zoom:

  1. вычисляются новые координаты тайлов
  2. старые тайлы либо масштабируются временно, либо удаляются
  3. запрашиваются новые изображения
  4. происходит плавная подмена содержимого

Использование прозрачности слоёв

Комбинация нескольких слоёв часто опирается на opacity:

base.setOpacity(1.0);
overlay.setOpacity(0.4);

Это позволяет формировать гибридные визуализации (карта + спутник + подписи).