В архитектуре CesiumJS класс Resource представляет
универсальный механизм работы с удалёнными ресурсами. Он используется
для загрузки изображений, JSON-файлов, тайлов местности, 3D-моделей,
текстур, геопространственных данных и любых других сетевых ресурсов.
Практически все высокоуровневые компоненты CesiumJS в той или иной
форме используют Resource. Через него осуществляется:
Класс расположен в пространстве имён
Cesium.Resource.
Базовый способ создания ресурса предполагает передачу URL.
const resource = new Cesium.Resource({
url: "https://example.com/data.json"
});
Также допускается сокращённая форма:
const resource = new Cesium.Resource(
"https://example.com/data.json"
);
После создания объект хранит всю информацию, необходимую для выполнения запросов.
Основное свойство объекта — url.
const resource = new Cesium.Resource({
url: "https://server.com/tiles"
});
console.log(resource.url);
Результат:
https://server.com/tiles
URL может быть как абсолютным, так и относительным.
const resource = new Cesium.Resource({
url: "./assets/model.glb"
});
Очень часто серверные сервисы требуют передачи параметров запроса.
Например:
https://server.com/data?id=25&type=city
Вместо ручной сборки строки рекомендуется использовать
queryParameters.
const resource = new Cesium.Resource({
url: "https://server.com/data",
queryParameters: {
id: 25,
type: "city"
}
});
Получаемый URL:
https://server.com/data?id=25&type=city
Такой подход уменьшает вероятность ошибок и автоматически выполняет экранирование специальных символов.
Параметры можно изменять динамически.
const resource = new Cesium.Resource({
url: "https://server.com/data"
});
resource.setQueryParameters({
page: 5
});
URL станет:
https://server.com/data?page=5
Добавление новых параметров:
resource.setQueryParameters({
limit: 100
});
Результат:
https://server.com/data?page=5&limit=100
Для полной замены существующих параметров используется второй аргумент.
resource.setQueryParameters(
{
category: "buildings"
},
true
);
Теперь старые параметры будут удалены.
Во многих картографических сервисах используются шаблоны.
Пример:
https://server.com/tiles/{z}/{x}/{y}.png
Для формирования итогового адреса применяются шаблонные значения.
const resource = new Cesium.Resource({
url: "https://server.com/tiles/{z}/{x}/{y}.png"
});
resource.setTemplateValues({
z: 5,
x: 12,
y: 7
});
Получаем:
https://server.com/tiles/5/12/7.png
Многие API требуют передачу дополнительных заголовков.
Например:
const resource = new Cesium.Resource({
url: "https://api.example.com/data",
headers: {
Authorization: "Bearer token123",
Accept: "application/json"
}
});
Cesium автоматически добавит указанные заголовки к запросу.
Заголовки можно обновлять динамически.
resource.headers["Authorization"] =
"Bearer newToken";
Либо:
resource.headers = {
Authorization: "Bearer abc",
Accept: "application/json"
};
Одной из наиболее полезных возможностей является создание дочерних ресурсов.
Предположим, существует базовый адрес:
const api = new Cesium.Resource({
url: "https://api.example.com/"
});
Создание дочернего ресурса:
const users = api.getDerivedResource({
url: "users"
});
Результат:
https://api.example.com/users
Другой пример:
const posts = api.getDerivedResource({
url: "posts"
});
Результат:
https://api.example.com/posts
Подход особенно полезен при работе с REST API.
Для загрузки JSON предусмотрен метод fetchJson().
resource.fetchJson()
.then(data => {
console.log(data);
});
Эквивалентный HTTP-запрос:
GET /data.json
Возвращаемое значение — Promise.
На практике удобнее использовать async/await.
async function loadData() {
const data = await resource.fetchJson();
console.log(data);
}
Для текстовых файлов применяется fetchText().
const resource = new Cesium.Resource({
url: "notes.txt"
});
const text = await resource.fetchText();
console.log(text);
Для загрузки двоичных файлов используется
fetchArrayBuffer().
const resource = new Cesium.Resource({
url: "model.glb"
});
const buffer =
await resource.fetchArrayBuffer();
Такой подход широко используется при работе с:
Метод:
fetchBlob()
Пример:
const blob =
await resource.fetchBlob();
Возвращается объект Blob, пригодный для дальнейшей
обработки браузером.
Для изображений используется специальный метод.
const image =
await resource.fetchImage();
После получения объект можно использовать самостоятельно.
document.body.appendChild(image);
Дополнительные параметры:
resource.fetchImage({
flipY: true
});
Или:
resource.fetchImage({
preferImageBitmap: true
});
Подобные настройки особенно полезны при работе с WebGL.
Иногда встроенных методов недостаточно.
Для таких случаев существует fetch().
resource.fetch({
responseType: "json"
});
Пример:
const result = await resource.fetch({
method: "POST"
});
Передача данных серверу:
const resource = new Cesium.Resource({
url: "https://api.example.com/create"
});
await resource.fetch({
method: "POST",
data: JSON.stringify({
name: "Building",
floors: 20
})
});
await resource.fetch({
method: "PUT",
data: JSON.stringify({
id: 1,
name: "Updated"
})
});
await resource.fetch({
method: "DELETE"
});
Некоторые сервисы требуют промежуточного прокси-сервера.
Cesium предоставляет класс DefaultProxy.
const proxy =
new Cesium.DefaultProxy("/proxy/");
Подключение:
const resource = new Cesium.Resource({
url: "https://external-server.com/data",
proxy: proxy
});
Все запросы будут автоматически проходить через прокси.
Сетевые ошибки неизбежны, особенно при работе с глобальными геоданными.
Для автоматического повторения запросов используется механизм retry.
const resource = new Cesium.Resource({
url: "https://server.com/data"
});
Настройка:
resource.retryAttempts = 3;
Теперь Cesium сможет выполнить до трёх повторных попыток.
Логика повтора полностью настраивается.
resource.retryCallback = function(error) {
console.log(error);
return Promise.resolve(true);
};
Возврат:
true
означает повтор запроса.
Возврат:
false
означает окончательное завершение операции.
resource.retryAttempts = 5;
resource.retryCallback = function(error) {
if (error.statusCode === 503) {
return Promise.resolve(true);
}
return Promise.resolve(false);
};
Повтор будет происходить только при временной недоступности сервера.
Некоторые поставщики картографической информации требуют обязательного отображения авторства.
Для этого используется свойство credits.
const resource = new Cesium.Resource({
url: "https://provider.com/data"
});
При использовании провайдеров Cesium автоматически извлекает и отображает необходимые кредиты.
Метод:
resource.isDataUri
Позволяет определить, используется ли Data URI.
Пример:
const resource = new Cesium.Resource({
url: "data:image/png;base64,..."
});
console.log(resource.isDataUri);
Результат:
true
Data URI позволяют хранить ресурс непосредственно внутри строки.
const resource = new Cesium.Resource({
url: "dat a:text/plain;base64,SGVsbG8="
});
Получение содержимого:
const text =
await resource.fetchText();
Метод:
Cesium.Resource.createIfNeeded()
Удобен для библиотечного кода.
const resource =
Cesium.Resource.createIfNeeded(
"https://server.com/data.json"
);
Если передан URL, будет создан новый объект.
Если передан объект Resource, он будет возвращён без
изменений.
const r1 = new Cesium.Resource({
url: "data.json"
});
const r2 =
Cesium.Resource.createIfNeeded(r1);
console.log(r1 === r2);
Результат:
true
async function loadConfig() {
const resource = new Cesium.Resource({
url: "/config/app.json",
retryAttempts: 3
});
try {
const config =
await resource.fetchJson();
return config;
} catch(error) {
console.error(
"Ошибка загрузки конфигурации",
error
);
}
}
Практически все провайдеры Cesium принимают URL, который внутренне
преобразуется в Resource.
Например:
const imagery =
new Cesium.UrlTemplateImageryProvider({
url:
"https://tile.openstreetmap.org/{z}/{x}/{y}.png"
});
Внутри провайдера создаётся объект Resource,
который:
Благодаря этому единый механизм сетевого взаимодействия используется во всей экосистеме CesiumJS.
Централизация сетевых запросов
Повторное использование конфигурации
Удобство масштабирования
Интеграция с внутренней архитектурой Cesium
Класс Resource является фундаментальным компонентом
системы загрузки данных в CesiumJS и служит универсальным уровнем
абстракции между прикладным кодом и сетевой инфраструктурой
приложения.