TMS схема тайлов

При работе с веб-картами большая часть данных отображается в виде набора тайлов — небольших изображений или векторных фрагментов, разбивающих карту на равномерную сетку. Для адресации таких тайлов используются координаты z/x/y, где:

  • z — уровень масштабирования (zoom);
  • x — номер столбца;
  • y — номер строки.

Существует несколько схем организации тайлов, среди которых наиболее распространены:

  • XYZ (Slippy Map);
  • TMS (Tile Map Service).

Понимание различий между ними крайне важно при подключении пользовательских источников данных в MapLibre GL JS.


Структура тайловой пирамиды

Картографические тайлы организованы в виде пирамиды масштабов.

На нулевом уровне масштабирования вся поверхность мира представлена одним тайлом:

z = 0

+-------+
|       |
|   0   |
|       |
+-------+

На каждом следующем уровне количество тайлов по горизонтали и вертикали удваивается:

Zoom Размер сетки
0 1 × 1
1 2 × 2
2 4 × 4
3 8 × 8
4 16 × 16

Количество тайлов вычисляется по формуле:

N = 2^z

где:

  • N — число тайлов по одной оси;
  • z — уровень масштабирования.

Например:

Zoom Тайлов по оси
0 1
1 2
2 4
5 32
10 1024

Схема XYZ

Сегодня большинство картографических сервисов используют схему XYZ.

Координаты начинаются в левом верхнем углу:

z = 1

(0,0)  (1,0)
+----+----+
|    |    |
+----+----+
|    |    |
+----+----+
(0,1)  (1,1)

Для получения тайла обычно используется URL следующего вида:

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

Пример:

https://server.com/5/10/12.png

Это означает:

  • масштаб 5;
  • столбец 10;
  • строка 12.

XYZ является стандартом де-факто для:

  • OpenStreetMap;
  • MapLibre;
  • Mapbox;
  • Google Maps;
  • Bing Maps.

Схема TMS

TMS была предложена организацией OSGeo как часть спецификации Tile Map Service.

Главное отличие заключается в направлении отсчёта координаты Y.

В TMS начало координат располагается в левом нижнем углу.

XYZ

(0,0)  (1,0)
+----+----+
|    |    |
+----+----+
|    |    |
+----+----+
(0,1)  (1,1)
TMS

(0,1)  (1,1)
+----+----+
|    |    |
+----+----+
|    |    |
+----+----+
(0,0)  (1,0)

Таким образом:

  • X совпадает;
  • Z совпадает;
  • меняется только Y.

Почему появилась TMS

Исторически многие GIS-системы используют декартову систему координат, где начало расположено снизу слева.

В компьютерной графике ситуация противоположная:

(0,0)
  |
  v

Координаты возрастают сверху вниз.

Поэтому веб-картография постепенно перешла на XYZ, а старые геоинформационные сервисы продолжили использовать TMS.

Сегодня TMS чаще встречается:

  • в архивных картографических проектах;
  • в GeoServer;
  • в TileCache;
  • в некоторых конфигурациях GDAL;
  • в старых WMTS-публикациях.

Преобразование Y между XYZ и TMS

Для конвертации используется простая формула.

Пусть имеется:

  • уровень масштабирования z;
  • координата y в XYZ.

Тогда координата TMS вычисляется как:

y_{TMS}=2^z-y_{XYZ}-1

Обратное преобразование выполняется аналогично:

y_{XYZ}=2^z-y_{TMS}-1

Поскольку операция симметрична, одна и та же формула работает в обоих направлениях.


Пример преобразования

Пусть имеется тайл:

z = 3
x = 4
y = 2

Количество строк на данном уровне:

2^3 = 8

Подставляем значения:

yTMS = 8 - 2 - 1

Получаем:

yTMS = 5

Итоговые координаты:

XYZ:
3/4/2

TMS:
3/4/5

Визуализация инверсии Y

Для уровня zoom = 2 существует сетка 4×4.

XYZ:

Y

0  +--+--+--+--+
1  +--+--+--+--+
2  +--+--+--+--+
3  +--+--+--+--+

TMS:

Y

3  +--+--+--+--+
2  +--+--+--+--+
1  +--+--+--+--+
0  +--+--+--+--+

Соответствие:

XYZ Y TMS Y
0 3
1 2
2 1
3 0

Подключение TMS-тайлов в MapLibre GL JS

MapLibre GL JS по умолчанию ожидает схему XYZ.

Обычное подключение растрового источника выглядит следующим образом:

map.addSource('raster-source', {
    type: 'raster',
    tiles: [
        'https://server.com/{z}/{x}/{y}.png'
    ],
    tileSize: 256
});

Если сервер возвращает TMS-тайлы, карта будет отображаться неправильно:

  • изображения окажутся перевёрнутыми по вертикали;
  • часть тайлов может отсутствовать;
  • возникнут ошибки загрузки.

Использование параметра scheme

Для поддержки TMS в спецификации стилей предусмотрено свойство scheme.

map.addSource('raster-source', {
    type: 'raster',
    tiles: [
        'https://server.com/{z}/{x}/{y}.png'
    ],
    tileSize: 256,
    scheme: 'tms'
});

После указания:

scheme: 'tms'

MapLibre автоматически выполняет преобразование координаты Y.

Фактически движок делает следующее:

y = (1 << z) - y - 1;

перед отправкой HTTP-запроса.


Подключение векторных TMS-тайлов

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

map.addSource('vector-source', {
    type: 'vector',
    tiles: [
        'https://server.com/{z}/{x}/{y}.pbf'
    ],
    scheme: 'tms'
});

MapLibre самостоятельно преобразует координаты.

Дополнительных действий не требуется.


Настройка через Style Specification

Источник можно определить непосредственно в объекте стиля.

const style = {
    version: 8,
    sources: {
        terrain: {
            type: 'raster',
            tiles: [
                'https://server.com/{z}/{x}/{y}.png'
            ],
            tileSize: 256,
            scheme: 'tms'
        }
    },
    layers: []
};

Затем стиль подключается стандартным способом:

const map = new maplibregl.Map({
    container: 'map',
    style
});

Проверка типа схемы тайлов

Иногда документация сервера отсутствует.

Определить тип схемы можно вручную.

Алгоритм проверки:

  1. Запросить тайл верхнего уровня.
  2. Сравнить содержимое верхних и нижних рядов.
  3. Проверить URL в инструментах разработчика браузера.
  4. Сопоставить реальные координаты с ожидаемыми.

Например, запрос:

https://server.com/2/1/0.png

может возвращать:

  • северную часть мира — XYZ;
  • южную часть мира — TMS.

Это позволяет быстро определить используемую систему.


Серверы, поддерживающие TMS

Наиболее часто TMS встречается в следующих системах:

  • GeoServer;
  • MapProxy;
  • TileCache;
  • QGIS Server;
  • GDAL.

При публикации слоёв в этих системах зачастую можно выбирать:

XYZ
или
TMS

по отдельности.


Типичные ошибки при работе с TMS

Перевёрнутая карта

Самая распространённая проблема.

Причина:

scheme: 'xyz'

при фактической TMS-схеме.

Исправление:

scheme: 'tms'

Отсутствие части тайлов

При неправильном расчёте Y сервер может получать запросы к несуществующим тайлам.

Пример:

404 Not Found

в сетевом журнале браузера.

Необходимо проверить соответствие схемы.


Двойное преобразование координат

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

Разработчик дополнительно включает:

scheme: 'tms'

В результате преобразование выполняется дважды.

Симптомы:

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

Смешивание XYZ и TMS источников

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

Например:

sources: {
    osm: {
        type: 'raster'
    },

    archive: {
        type: 'raster',
        scheme: 'tms'
    }
}

Каждый источник должен иметь собственную корректную настройку схемы.


Производительность и TMS

Использование TMS практически не влияет на производительность.

Преобразование выполняется одной арифметической операцией:

(1 << z) - y - 1

Затраты времени пренебрежимо малы по сравнению с:

  • сетевыми запросами;
  • декодированием PNG;
  • декодированием PBF;
  • рендерингом WebGL.

Поэтому выбор между XYZ и TMS определяется исключительно совместимостью с сервером данных.


Практические рекомендации

При подключении стороннего тайлового сервиса необходимо прежде всего определить используемую схему адресации.

Для современных веб-картографических сервисов обычно используется XYZ.

Для архивных GIS-серверов и некоторых геопространственных платформ может использоваться TMS.

Если карта выглядит перевёрнутой по вертикали, первым делом следует проверить параметр scheme.

Для TMS-источников рекомендуется использовать встроенную поддержку MapLibre через scheme: 'tms', а не выполнять преобразование координат вручную.

При работе с несколькими источниками каждый источник должен явно указывать собственную схему тайлов, чтобы исключить ошибки адресации и некорректное отображение данных.