В основе отображения карт в OpenLayers лежит тайловая система, в которой карта разбивается на небольшие квадратные изображения фиксированного размера. Эти изображения (тайлы) загружаются по мере необходимости в зависимости от текущего масштаба и области просмотра.
Основные источники тайлов реализуются через классы
ol/source/XYZ, ol/source/OSM,
ol/source/TileWMS, ol/source/WMTS. Несмотря на
различия протоколов, общая логика загрузки и обработки ошибок строится
на единой модели событий и состояния тайлов.
Ключевой принцип: каждый тайл имеет жизненный цикл состояний —
idle → loading → loaded | error.
Наиболее распространённый вариант — XYZ, где тайлы
запрашиваются по шаблону URL:
import XYZ from 'ol/source/XYZ';
const source = new XYZ({
url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
});
Подстановка {z}, {x}, {y}
формирует координаты тайла в сетке.
import OSM from 'ol/source/OSM';
const source = new OSM();
Этот источник является обёрткой над XYZ с предустановленным URL и параметрами.
Каждый тайл в OpenLayers проходит несколько этапов:
Состояние тайла можно отслеживать через внутренние события источника.
OpenLayers предоставляет набор событий для контроля процесса:
tileloadstart — начало загрузки тайлаtileloadend — успешное завершение загрузкиtileloaderror — ошибка загрузкиПример регистрации обработчиков:
source.on('tileloadstart', function (event) {
console.log('Начало загрузки тайла', event.tile.getTileCoord());
});
source.on('tileloadend', function (event) {
console.log('Тайл загружен');
});
source.on('tileloaderror', function (event) {
console.log('Ошибка загрузки тайла', event.tile.getTileCoord());
});
Каждое событие передаёт объект event, содержащий ссылку
на тайл и контекст запроса.
Ошибки в тайловых запросах возникают по нескольким причинам:
Сервер тайлов может быть временно недоступен или перегружен. В этом случае запросы возвращают HTTP-ошибки (500, 502, 503).
Потеря соединения, нестабильный интернет или блокировка запросов.
Ошибки в {z}/{x}/{y} или неправильный домен приводят к
404.
При загрузке с внешних доменов браузер может блокировать ответ, если сервер не отдаёт корректные заголовки.
Стандартный способ обработки ошибок — подписка на
tileloaderror:
source.on('tileloaderror', function (event) {
const tile = event.tile;
const coord = tile.getTileCoord();
console.warn('Ошибка тайла:', coord);
});
Это позволяет фиксировать проблемные области карты и реализовывать повторные попытки загрузки.
tileLoadFunctionНекоторые источники позволяют полностью заменить механизм загрузки:
import XYZ from 'ol/source/XYZ';
const source = new XYZ({
tileLoadFunction: function (tile, src) {
const image = tile.getImage();
image.onl oad = function () {
console.log('Загружено:', src);
};
image.oner ror = function () {
console.log('Ошибка загрузки:', src);
};
image.src = src;
},
url: 'https://tile-server/{z}/{x}/{y}.png'
});
Этот подход используется для:
Одной из распространённых задач является повторная загрузка тайла при ошибке.
source.on('tileloaderror', function (event) {
const tile = event.tile;
const src = tile.getKey ? tile.getKey() : null;
if (tile.__retryCount === undefined) {
tile.__retryCount = 0;
}
if (tile.__retryCount < 3) {
tile.__retryCount++;
setTimeout(() => {
tile.load();
}, 500 * tile.__retryCount);
}
});
Здесь реализуется экспоненциальная задержка между попытками.
OpenLayers активно использует кэширование, чтобы минимизировать повторные запросы.
Кэш работает на уровне:
Ошибки могут кэшироваться так же, как успешные ответы. Это создаёт ситуацию, когда проблемный тайл больше не запрашивается.
Для обхода этого используется:
tile.setKey(Date.now());
или модификация URL:
url: 'https://tile-server/{z}/{x}/{y}.png?ts=' + Date.now()
Каждый тайл имеет внутреннее состояние, которое можно интерпретировать:
0 — idle1 — loading2 — loaded3 — errorХотя прямой доступ к состояниям ограничен, поведение можно отслеживать через события источника.
В WMTS-источниках (ol/source/WMTS) структура запросов
более строгая: используются tile matrix sets.
Ошибки здесь часто связаны с:
origin тайловой сеткиmatrixIdimport WMTS from 'ol/source/WMTS';
const source = new WMTS({
url: 'https://wmts-server',
layer: 'layer-name',
matrixSet: 'EPSG:3857',
format: 'image/png'
});
Для WMS-тайлов ошибки часто связаны с серверной генерацией изображения:
import TileWMS from 'ol/source/TileWMS';
const source = new TileWMS({
url: 'https://wms-server',
params: {
LAYERS: 'layer',
TILED: true
}
});
При ошибке сервер может вернуть XML с описанием ошибки вместо изображения. OpenLayers интерпретирует это как failure загрузки изображения.
Частая практика — использование промежуточного сервера:
OpenLayers → Backend Proxy → Tile Server
Преимущества:
В OpenLayers нет встроенного явного таймаута для тайловых запросов, но его можно реализовать вручную:
tileLoadFunction: function (tile, src) {
const img = tile.getImage();
const timeout = setTimeout(() => {
img.src = '';
console.log('timeout:', src);
}, 8000);
img.onl oad = function () {
clearTimeout(timeout);
};
img.oner ror = function () {
clearTimeout(timeout);
};
img.src = src;
}
Для анализа ошибок используются:
tileloaderrorДополнительно можно маркировать проблемные зоны, сохраняя координаты тайлов, вызвавших ошибку.
При массовом отказе источника OpenLayers продолжает пытаться загружать тайлы в пределах viewport. Это может привести к:
Для предотвращения применяются:
layer.setVisible(false))layer.setSource(newSource))Практическая стратегия включает:
tileloaderrorЭти механизмы позволяют стабилизировать работу карты даже при нестабильных источниках данных.