XYZ и тайловые источники

Модель XYZ представляет собой наиболее распространённый способ разбиения карты на набор квадратных растровых тайлов, каждый из которых имеет координаты x, y и уровень масштаба z. Эта схема лежит в основе большинства веб-карт, включая стандартные подложки, предоставляемые OpenStreetMap и коммерческими провайдерами.

В экосистеме OpenLayers работа с XYZ реализована через ol/source/XYZ, который инкапсулирует логику формирования URL, загрузки тайлов, кэширования и интеграции с системой слоёв ol/layer/Tile.


Принцип адресации XYZ-тайлов

Каждый тайл в XYZ-схеме идентифицируется тройкой координат:

  • z — уровень масштабирования (zoom level)
  • x — индекс тайла по горизонтали
  • y — индекс тайла по вертикали

При этом координаты формируются в проекции Web Mercator (EPSG:3857), где карта делится на квадратную сетку.

Формат URL обычно выглядит так:

https://tile.server/{z}/{x}/{y}.png

Именно эта шаблонная структура делает XYZ максимально простой для интеграции.


Источник ol/source/XYZ в OpenLayers

В OpenLayers XYZ-источник создаётся следующим образом:

import XYZ from 'ol/source/XYZ';
import TileLayer from 'ol/layer/Tile';

const source = new XYZ({
  url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
});

const layer = new TileLayer({
  source: source
});

Здесь ключевым элементом является параметр url, который поддерживает шаблонные переменные:

  • {z} — уровень масштаба
  • {x} — координата по X
  • {y} — координата по Y
  • {a-c} — выбор поддомена для балансировки нагрузки

Поддомены и балансировка нагрузки

Многие тайловые серверы используют поддомены для распределения запросов:

https://a.tile.server/{z}/{x}/{y}.png
https://b.tile.server/{z}/{x}/{y}.png
https://c.tile.server/{z}/{x}/{y}.png

OpenLayers поддерживает автоматическую подстановку:

const source = new XYZ({
  url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'
});

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


Кэширование и стратегия загрузки

XYZ-тайлы по своей природе статичны, поэтому эффективно кешируются как на уровне браузера, так и внутри OpenLayers.

Внутренний кэш ol/source/Tile:

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

Поведение загрузчика регулируется параметрами:

const source = new XYZ({
  url: 'https://tile.server/{z}/{x}/{y}.png',
  cacheSize: 512,
  transition: 0
});
  • cacheSize определяет количество тайлов в памяти
  • transition управляет анимацией появления тайлов

Связь XYZ с TileGrid

Хотя XYZ-источник часто используется «из коробки», его работа опирается на TileGrid, определяющий геометрию разбиения карты.

import TileGrid from 'ol/tilegrid/TileGrid';
import {get as getProjection} from 'ol/proj';

const grid = new TileGrid({
  extent: getProjection('EPSG:3857').getExtent(),
  resolutions: [156543.0339, 78271.5169, 39135.7584],
  tileSize: 256
});

Использование собственного tileGrid позволяет:

  • переопределить уровни масштабов
  • адаптировать источник под нестандартные серверы
  • синхронизировать тайлы с WMTS-системами

Стандартная проекция и её влияние

XYZ почти всегда работает в EPSG:3857, что обусловлено особенностями веб-картографии:

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

Любое отклонение от этой системы требует дополнительной трансформации координат, что может влиять на производительность.


Настройка формата тайлов

XYZ-источник поддерживает различные форматы изображений:

  • PNG — прозрачность, универсальность
  • JPG — меньший размер, отсутствие прозрачности
  • WebP — оптимизация по размеру и скорости

Пример:

const source = new XYZ({
  url: 'https://tile.server/{z}/{x}/{y}.webp',
  crossOrigin: 'anonymous'
});

Параметр crossOrigin критичен при работе с внешними доменами, чтобы избежать ограничений CORS при рендеринге canvas.


Управление ошибками загрузки тайлов

При работе с сетевыми источниками неизбежны ошибки:

  • недоступность сервера
  • отсутствие тайла на определённом zoom-уровне
  • сетевые таймауты

OpenLayers позволяет обрабатывать такие случаи:

const source = new XYZ({
  url: 'https://tile.server/{z}/{x}/{y}.png',
  tileLoadFunction: function(tile, src) {
    const img = tile.getImage();
    img.src = src;

    img.oner ror = function() {
      img.src = 'fallback.png';
    };
  }
});

Такой подход позволяет подменять недоступные тайлы заглушками.


Различие между XYZ и WMTS

XYZ часто путают с WMTS (Web Map Tile Service), однако различия принципиальны:

Параметр XYZ WMTS
Структура URL простая стандартизированная
Метаданные отсутствуют обязательны
Гибкость высокая ограниченная
Поддержка сеток фиксированная описываемая

WMTS требует описания GetCapabilities, тогда как XYZ опирается на соглашение URL-шаблона.


Кастомные тайловые серверы

XYZ-источник позволяет подключать собственные генераторы тайлов, например серверы на базе:

  • Mapnik
  • TileServer GL
  • GeoServer (через XYZ-экспорт)

Пример интеграции:

const source = new XYZ({
  url: 'https://maps.custom-server.com/tiles/{z}/{x}/{y}.png'
});

При этом важно соблюдать:

  • одинаковую тайловую сетку (256×256 или 512×512)
  • соответствие проекции
  • корректную схему масштабов

HiDPI и ретина-тайлы

Для экранов с высокой плотностью пикселей применяются тайлы увеличенного разрешения:

const source = new XYZ({
  url: 'https://tile.server/{z}/{x}/{y}@2x.png',
  tilePixelRatio: 2
});

tilePixelRatio сообщает системе рендеринга, что изображение содержит больше пикселей, чем стандартный тайл.

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

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

Ограничение уровней масштабирования

XYZ-серверы обычно ограничивают диапазон zoom-уровней. OpenLayers позволяет явно задавать границы:

const source = new XYZ({
  url: 'https://tile.server/{z}/{x}/{y}.png',
  minZoom: 3,
  maxZoom: 18
});

При выходе за пределы диапазона тайлы не запрашиваются, что снижает нагрузку и предотвращает ошибки 404.


Поведение при панорамировании и предзагрузке

OpenLayers использует стратегию предзагрузки соседних тайлов:

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

Это обеспечивает плавность навигации даже при медленном соединении.


Кастомные функции формирования URL

Иногда требуется динамическая логика генерации тайлового URL:

const source = new XYZ({
  tileUrlFunction: function(tileCoord) {
    const z = tileCoord[0];
    const x = tileCoord[1];
    const y = tileCoord[2];

    return `https://server/tiles/${z}/${x}/${y}.png`;
  }
});

Этот механизм используется при:

  • авторизации через токены
  • распределении нагрузки между серверами
  • генерации подписанных URL
  • работе с приватными тайловыми API

Смешанные источники и слоёвые комбинации

XYZ-слои часто комбинируются с:

  • векторными слоями (VectorLayer)
  • WMS-источниками
  • WebGL-рендерингом

Типичная структура карты:

  • базовый слой (XYZ)
  • слой дорог (вектор)
  • слой объектов (GeoJSON)

Такая архитектура разделяет визуальную подложку и семантические данные.


Производительность и оптимизация

Ключевые факторы производительности XYZ в OpenLayers:

  • размер тайлов (256 vs 512)
  • количество одновременно загружаемых запросов
  • кэширование браузера
  • сжатие изображений (WebP)
  • использование CDN

Дополнительно важна правильная настройка заголовков HTTP:

  • Cache-Control
  • ETag
  • Expires

Эти параметры определяют эффективность повторного использования тайлов.


Ограничения модели XYZ

Несмотря на простоту, XYZ имеет ряд ограничений:

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

Эти ограничения компенсируются высокой скоростью и универсальностью интеграции в веб-среде.