CesiumJS построен вокруг модульной системы провайдеров данных, где каждый тип пространственного контента инкапсулируется в отдельный контракт загрузки и представления. Пользовательские провайдеры позволяют подключать нестандартные источники тайлов, серверные схемы, локальные хранилища или специализированные геоданные без изменения ядра визуализации. Архитектура ориентирована на унификацию: сцена работает с абстракциями, а не с конкретными форматами.
Внутренняя модель CesiumJS разделяет визуализацию и источник данных. Любой провайдер реализует набор методов, через которые движок запрашивает:
Ключевая идея — ленивое получение данных. Сцена не загружает весь слой целиком, а обращается к провайдеру по мере необходимости, запрашивая только видимые тайлы.
Провайдеры делятся на несколько категорий:
Пользовательские реализации чаще всего затрагивают первые два типа, поскольку они наиболее тесно связаны с внешними тайловыми сервисами.
ImageryProvider представляет собой интерфейс, определяющий доступ к растровым тайлам. Он не навязывает конкретный формат, но требует соблюдения логики тайловой пирамиды.
Основные методы и свойства:
Вся система построена вокруг координат (x, y, level), где level соответствует zoom-уровню.
Пользовательский провайдер создаётся через реализацию интерфейса объекта. CesiumJS допускает как классовую реализацию, так и объект с функциями.
Базовая структура:
class CustomImageryProvider {
constructor(options) {
this._url = options.url;
this._tileWidth = 256;
this._tileHeight = 256;
this._maximumLevel = options.maximumLevel || 18;
this._minimumLevel = 0;
this._tilingScheme = new Cesium.WebMercatorTilingScheme();
this._rectangle = this._tilingScheme.rectangle;
this._credit = options.credit;
this._ready = true;
}
get url() {
return this._url;
}
get tileWidth() {
return this._tileWidth;
}
get tileHeight() {
return this._tileHeight;
}
get maximumLevel() {
return this._maximumLevel;
}
get minimumLevel() {
return this._minimumLevel;
}
get tilingScheme() {
return this._tilingScheme;
}
get rectangle() {
return this._rectangle;
}
get ready() {
return this._ready;
}
requestImage(x, y, level) {
const url = `${this._url}/${level}/${x}/${y}.png`;
return Cesium.ImageryProvider.loadImage(this, url);
}
}
Такой подход позволяет подключать любой REST-сервис, который следует tile XYZ-схеме.
Ключевая сложность пользовательских провайдеров — соответствие координатной системы сервера и CesiumJS.
Используются две основные схемы:
WebMercatorTilingScheme применяется по умолчанию для большинства интернет-картографических сервисов. Он оперирует проекцией, где меридианы и параллели трансформируются в квадратную сетку.
При несовпадении схемы необходимо либо:
Пример кастомной трансформации уровня:
const longitude = Cesium.Math.lerp(west, east, x / Math.pow(2, level));
const latitude = Cesium.Math.lerp(south, north, y / Math.pow(2, level));
Ошибки в этом слое приводят к смещению тайлов, инверсии оси Y или разрыву карты.
Частый сценарий — подключение сервиса, возвращающего бинарные изображения или динамически генерируемые тайлы.
Поддерживаются форматы:
Пример обработки бинарного ответа:
requestImage(x, y, level) {
const url = `${this._url}?z=${level}&x=${x}&y=${y}`;
return fetch(url)
.then(response => response.blob())
.then(blob => Cesium.loadImageFromBlob(blob));
}
Такая схема полезна для серверов, генерирующих изображения на лету (например, тепловые карты или аналитические слои).
CesiumJS уже содержит внутренний механизм кеширования, однако пользовательские провайдеры могут дополнительно оптимизировать сеть:
Пример простого кеша:
const cache = new Map();
requestImage(x, y, level) {
const key = `${level}/${x}/${y}`;
if (cache.has(key)) {
return cache.get(key);
}
const promise = Cesium.ImageryProvider.loadImage(
this,
`${this._url}/${key}.png`
);
cache.set(key, promise);
return promise;
}
Важно учитывать, что кеширование должно быть ограничено по памяти, иначе сцена деградирует при длительной работе.
TerrainProvider отвечает за геометрию земной поверхности. В отличие от ImageryProvider, он работает с высотными данными и геометрическими мешами.
Ключевые методы:
Пример минимальной реализации:
class CustomTerrainProvider {
constructor(url) {
this._url = url;
this._tilingScheme = new Cesium.WebMercatorTilingScheme();
this._errorEvent = new Cesium.Event();
this._ready = true;
}
requestTileGeometry(x, y, level) {
const url = `${this._url}/terrain/${level}/${x}/${y}.bin`;
return fetch(url)
.then(r => r.arrayBuffer())
.then(buffer => Cesium.TerrainData.createTerrainMesh(buffer));
}
get tilingScheme() {
return this._tilingScheme;
}
get errorEvent() {
return this._errorEvent;
}
}
При создании кастомного TerrainProvider критично учитывать:
Основные узкие места:
Оптимизационные подходы:
CesiumJS активно использует Web Workers, поэтому предпочтительно возвращать бинарные данные, чтобы минимизировать блокировку основного потока.
Провайдеры должны корректно обрабатывать:
Пример fallback-логики:
requestImage(x, y, level) {
const url = buildUrl(x, y, level);
return Cesium.ImageryProvider.loadImage(this, url)
.catch(() => Cesium.ImageryProvider.loadImage(this, this._fallbackUrl));
}
При отсутствии fallback слоя сцена может отображать “дырки”, что ухудшает визуальную целостность.
Хотя 3D Tiles не является классическим провайдером, он часто взаимодействует с пользовательскими источниками данных. При потоковой загрузке моделей:
Пример динамической подмены источника:
const tileset = new Cesium.Cesium3DTileset({
url: new Cesium.Resource({
url: customEndpoint,
requestHeaders: {
Authorization: token
}
})
});
Такой подход позволяет подключать защищённые или приватные геоданные без изменения структуры сцены.
Пользовательские провайдеры должны учитывать версионные изменения CesiumJS:
Архитектура допускает постепенную миграцию: старые провайдеры могут работать через адаптеры, если соблюдён базовый контракт методов.
Наиболее критическая ошибка — несоответствие tilingScheme серверу, приводящее к систематическому смещению всех тайлов.
Пользовательские провайдеры часто используются для:
В таких сценариях провайдер становится не просто источником данных, а адаптером между вычислительной системой и 3D-движком сцены.