Потоковая передача данных (Streaming) в CesiumJS представляет собой механизм постепенной загрузки и отображения пространственной информации по мере необходимости. Вместо загрузки полного набора геоданных при запуске приложения система получает только те данные, которые требуются для текущей области просмотра и текущего уровня детализации.
Подобный подход особенно важен при работе с:
Основная цель потоковой передачи заключается в минимизации потребления памяти, сокращении времени первоначальной загрузки и обеспечении плавной работы приложения.
CesiumJS использует многоуровневую архитектуру передачи данных.
Основные компоненты:
Схема работы выглядит следующим образом:
Сервер данных
↓
Тайловый сервис
↓
HTTP-запросы
↓
CesiumJS
↓
Кэш памяти
↓
GPU
↓
Отображение сцены
При изменении положения камеры Cesium автоматически определяет, какие тайлы необходимо загрузить, а какие можно удалить из памяти.
Одним из наиболее распространённых сценариев является загрузка картографических слоев.
Для этого используются различные провайдеры изображений.
Пример подключения OpenStreetMap:
const viewer = new Cesium.Viewer("cesiumContainer", {
imageryProvider: new Cesium.OpenStreetMapImageryProvider({
url: "https://tile.openstreetmap.org/"
})
});
В данном случае изображения подгружаются небольшими тайлами.
Когда камера перемещается:
Загрузка выполняется асинхронно и не блокирует интерфейс.
Практически все потоковые данные в Cesium основаны на тайловой структуре.
Тайл представляет собой небольшой фрагмент общего набора данных.
Например:
Уровень 0
┌─────┬─────┐
│ 0 │ 1 │
├─────┼─────┤
│ 2 │ 3 │
└─────┴─────┘
Каждый следующий уровень детализации делит родительский тайл на четыре дочерних.
LOD 0
↓
LOD 1 (4 тайла)
↓
LOD 2 (16 тайлов)
↓
LOD 3 (64 тайла)
Такой подход обеспечивает:
Потоковая передача тесно связана с системой Level of Detail.
Принцип работы:
Например, при просмотре Земли из космоса нет необходимости загружать текстуры зданий или детализированные модели улиц.
При приближении камеры Cesium автоматически запрашивает более детализированные данные.
Для 3D Tiles используется метрика ошибки:
const tileset = await Cesium.Cesium3DTileset.fromUrl(
"tileset/tileset.json"
);
tileset.maximumScreenSpaceError = 8;
Параметр maximumScreenSpaceError определяет баланс между
качеством изображения и производительностью.
Меньшее значение:
Большее значение:
Рельеф также загружается по частям.
Пример:
const terrain = await Cesium.CesiumTerrainProvider.fromIonAssetId(
1
);
const viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: terrain
});
Во время перемещения камеры происходят:
На больших масштабах подгружаются дополнительные данные высот только для наблюдаемой области.
Формат 3D Tiles является основным механизмом потоковой передачи трехмерных данных в CesiumJS.
Он разработан специально для работы с огромными объемами геопространственной информации.
Пример подключения:
const tileset = await Cesium.Cesium3DTileset.fromUrl(
"city/tileset.json"
);
viewer.scene.primitives.add(tileset);
В наборе 3D Tiles содержатся:
Cesium загружает только видимые тайлы.
Если объект оказывается за пределами экрана, связанные данные могут быть выгружены из памяти.
Каждый набор данных имеет древовидную структуру.
Пример:
Root
├── Tile A
│ ├── Tile A1
│ ├── Tile A2
│ └── Tile A3
└── Tile B
├── Tile B1
└── Tile B2
При перемещении камеры система выполняет обход дерева.
Для каждого узла проверяются:
После этого принимается решение:
Загрузить
или
Не загружать
Такой механизм позволяет отображать сцены, содержащие миллиарды полигонов.
CesiumJS поддерживает потоковую загрузку Point Cloud через 3D Tiles.
Типичные источники данных:
Пример:
const pointCloud = await Cesium.Cesium3DTileset.fromUrl(
"lidar/tileset.json"
);
viewer.scene.primitives.add(pointCloud);
Даже если набор содержит сотни миллионов точек, одновременно отображается лишь небольшая часть данных.
Система автоматически выбирает нужный уровень детализации.
Помимо статической геометрии Cesium поддерживает передачу изменяющихся во времени объектов.
Наиболее распространённый формат — CZML.
Пример:
const dataSource =
await Cesium.CzmlDataSource.load("flight.czml");
viewer.dataSources.add(dataSource);
CZML позволяет передавать:
При обновлении данных объекты автоматически меняют своё положение на сцене.
Для задач реального времени часто применяется WebSocket.
Пример подключения:
const socket =
new WebSocket("wss://example.com/tracking");
socket.onmess age = function(event) {
const data = JSON.parse(event.data);
entity.position =
Cesium.Cartesian3.fromDegrees(
data.lon,
data.lat,
data.height
);
};
Подобная схема используется для:
Данные поступают непрерывным потоком без постоянных HTTP-запросов.
Кэширование играет важнейшую роль в производительности.
Cesium хранит ранее загруженные тайлы:
Если пользователь возвращается к недавно просмотренной области, повторная загрузка зачастую не требуется.
Механизм кэша позволяет:
Для больших сцен необходимо контролировать объём используемой памяти.
Пример:
tileset.cacheBytes = 536870912;
В данном случае задаётся лимит около 512 МБ.
Также можно использовать:
tileset.maximumCacheOverflowBytes =
268435456;
После достижения установленных ограничений Cesium начинает удалять редко используемые тайлы.
Для уменьшения визуальных задержек используется механизм предзагрузки.
viewer.scene.globe.preloadAncestors = true;
viewer.scene.globe.preloadSiblings = true;
Предварительная загрузка позволяет:
Недостатком является увеличение использования памяти и сетевого трафика.
Одной из ключевых технологий потоковой передачи является отсечение невидимых объектов.
Cesium использует:
Пример логики:
Объект вне камеры?
Да → не загружать
Нет → анализировать дальше
Это позволяет существенно сократить количество загружаемых данных.
Для мониторинга процесса потоковой передачи доступны события.
Пример:
tileset.tileLoad.addEventListener(
function(tile) {
console.log("Загружен:", tile);
}
);
Событие выгрузки:
tileset.tileUnload.addEventListener(
function(tile) {
console.log("Удален:", tile);
}
);
Событие видимости:
tileset.tileVisible.addEventListener(
function(tile) {
console.log("Виден:", tile);
}
);
Эти механизмы полезны при профилировании и оптимизации приложения.
Cesium предоставляет встроенные инструменты анализа.
Отображение статистики:
viewer.scene.debugShowFramesPerSecond = true;
Отладка границ тайлов:
tileset.debugShowBoundingVolume = true;
Показ экранной ошибки:
tileset.debugShowGeometricError = true;
Такие инструменты позволяют определить:
Наиболее эффективные методы оптимизации:
tileset.maximumScreenSpaceError = 16;
Увеличение значения снижает объём передаваемых данных.
tileset.cacheBytes = 256 * 1024 * 1024;
Контроль использования памяти особенно важен для мобильных устройств.
На сервере рекомендуется применять:
Эффективное дерево тайлов должно обеспечивать:
Объединение мелких объектов в крупные пакеты позволяет уменьшить сетевые накладные расходы.
При работе на масштабе всей планеты возникают дополнительные сложности:
Cesium решает эти задачи посредством сочетания:
Благодаря этим механизмам становится возможной интерактивная работа с глобальными геопространственными наборами данных объёмом в десятки и сотни гигабайт непосредственно внутри веб-браузера.