Потоковая передача

Потоковая передача данных (Streaming) в CesiumJS представляет собой механизм постепенной загрузки и отображения пространственной информации по мере необходимости. Вместо загрузки полного набора геоданных при запуске приложения система получает только те данные, которые требуются для текущей области просмотра и текущего уровня детализации.

Подобный подход особенно важен при работе с:

  • глобальными трехмерными сценами;
  • спутниковыми снимками высокого разрешения;
  • цифровыми моделями рельефа;
  • облаками точек;
  • трехмерными городами;
  • динамическими объектами реального времени;
  • массивами данных, содержащими миллионы объектов.

Основная цель потоковой передачи заключается в минимизации потребления памяти, сокращении времени первоначальной загрузки и обеспечении плавной работы приложения.


Архитектура потоковой загрузки в CesiumJS

CesiumJS использует многоуровневую архитектуру передачи данных.

Основные компоненты:

  1. Источник данных на сервере.
  2. Система разбиения данных на тайлы.
  3. Сетевой транспорт.
  4. Клиентский механизм загрузки.
  5. Кэширование.
  6. Отрисовка в WebGL.

Схема работы выглядит следующим образом:

Сервер данных
       ↓
 Тайловый сервис
       ↓
 HTTP-запросы
       ↓
 CesiumJS
       ↓
 Кэш памяти
       ↓
 GPU
       ↓
 Отображение сцены

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


Потоковая передача изображений

Одним из наиболее распространённых сценариев является загрузка картографических слоев.

Для этого используются различные провайдеры изображений.

Пример подключения OpenStreetMap:

const viewer = new Cesium.Viewer("cesiumContainer", {
    imageryProvider: new Cesium.OpenStreetMapImageryProvider({
        url: "https://tile.openstreetmap.org/"
    })
});

В данном случае изображения подгружаются небольшими тайлами.

Когда камера перемещается:

  1. Определяется текущая область просмотра.
  2. Рассчитываются необходимые тайлы.
  3. Выполняются сетевые запросы.
  4. Тайлы сохраняются в кэше.
  5. Происходит отображение на глобусе.

Загрузка выполняется асинхронно и не блокирует интерфейс.


Тайловая система

Практически все потоковые данные в Cesium основаны на тайловой структуре.

Тайл представляет собой небольшой фрагмент общего набора данных.

Например:

Уровень 0
┌─────┬─────┐
│ 0   │ 1   │
├─────┼─────┤
│ 2   │ 3   │
└─────┴─────┘

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

LOD 0
  ↓
LOD 1 (4 тайла)
  ↓
LOD 2 (16 тайлов)
  ↓
LOD 3 (64 тайла)

Такой подход обеспечивает:

  • быстрое масштабирование;
  • выборочную загрузку данных;
  • снижение сетевого трафика;
  • эффективное использование памяти.

Уровни детализации (LOD)

Потоковая передача тесно связана с системой Level of Detail.

Принцип работы:

  • дальние объекты отображаются упрощённо;
  • близкие объекты отображаются детализированно.

Например, при просмотре Земли из космоса нет необходимости загружать текстуры зданий или детализированные модели улиц.

При приближении камеры Cesium автоматически запрашивает более детализированные данные.

Для 3D Tiles используется метрика ошибки:

const tileset = await Cesium.Cesium3DTileset.fromUrl(
    "tileset/tileset.json"
);

tileset.maximumScreenSpaceError = 8;

Параметр maximumScreenSpaceError определяет баланс между качеством изображения и производительностью.

Меньшее значение:

  • выше качество;
  • больше сетевой трафик;
  • выше нагрузка на GPU.

Большее значение:

  • ниже качество;
  • меньше запросов;
  • выше скорость работы.

Потоковая передача рельефа

Рельеф также загружается по частям.

Пример:

const terrain = await Cesium.CesiumTerrainProvider.fromIonAssetId(
    1
);

const viewer = new Cesium.Viewer("cesiumContainer", {
    terrainProvider: terrain
});

Во время перемещения камеры происходят:

  • загрузка необходимых участков высот;
  • уточнение геометрии поверхности;
  • замена грубых моделей детализированными.

На больших масштабах подгружаются дополнительные данные высот только для наблюдаемой области.


Потоковая передача 3D Tiles

Формат 3D Tiles является основным механизмом потоковой передачи трехмерных данных в CesiumJS.

Он разработан специально для работы с огромными объемами геопространственной информации.

Пример подключения:

const tileset = await Cesium.Cesium3DTileset.fromUrl(
    "city/tileset.json"
);

viewer.scene.primitives.add(tileset);

В наборе 3D Tiles содержатся:

  • здания;
  • модели инфраструктуры;
  • BIM-объекты;
  • облака точек;
  • фотограмметрия;
  • цифровые двойники городов.

Cesium загружает только видимые тайлы.

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


Иерархия 3D Tiles

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

Пример:

Root
├── Tile A
│   ├── Tile A1
│   ├── Tile A2
│   └── Tile A3
└── Tile B
    ├── Tile B1
    └── Tile B2

При перемещении камеры система выполняет обход дерева.

Для каждого узла проверяются:

  • видимость;
  • расстояние;
  • текущий LOD;
  • экранная ошибка.

После этого принимается решение:

Загрузить
или
Не загружать

Такой механизм позволяет отображать сцены, содержащие миллиарды полигонов.


Потоковая передача облаков точек

CesiumJS поддерживает потоковую загрузку Point Cloud через 3D Tiles.

Типичные источники данных:

  • LiDAR-сканирование;
  • аэрофотосъемка;
  • лазерное картографирование;
  • инженерные измерения.

Пример:

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 позволяет передавать:

  • траектории;
  • телеметрию;
  • координаты транспорта;
  • состояние датчиков;
  • параметры движения.

При обновлении данных объекты автоматически меняют своё положение на сцене.


Streaming через WebSocket

Для задач реального времени часто применяется 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 хранит ранее загруженные тайлы:

  • в оперативной памяти;
  • в графической памяти GPU.

Если пользователь возвращается к недавно просмотренной области, повторная загрузка зачастую не требуется.

Механизм кэша позволяет:

  • уменьшить сетевой трафик;
  • снизить задержки;
  • ускорить навигацию.

Управление потреблением памяти

Для больших сцен необходимо контролировать объём используемой памяти.

Пример:

tileset.cacheBytes = 536870912;

В данном случае задаётся лимит около 512 МБ.

Также можно использовать:

tileset.maximumCacheOverflowBytes =
    268435456;

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


Предварительная загрузка данных

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

viewer.scene.globe.preloadAncestors = true;
viewer.scene.globe.preloadSiblings = true;

Предварительная загрузка позволяет:

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

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


Отсечение невидимых данных

Одной из ключевых технологий потоковой передачи является отсечение невидимых объектов.

Cesium использует:

  • Frustum Culling;
  • Horizon Culling;
  • Bounding Volume Tests.

Пример логики:

Объект вне камеры?
    Да → не загружать
    Нет → анализировать дальше

Это позволяет существенно сократить количество загружаемых данных.


События загрузки тайлов

Для мониторинга процесса потоковой передачи доступны события.

Пример:

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;

Такие инструменты позволяют определить:

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

Оптимизация потоковой передачи

Наиболее эффективные методы оптимизации:

Настройка Screen Space Error

tileset.maximumScreenSpaceError = 16;

Увеличение значения снижает объём передаваемых данных.

Ограничение кэша

tileset.cacheBytes = 256 * 1024 * 1024;

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

Использование сжатия

На сервере рекомендуется применять:

  • gzip;
  • Brotli;
  • Draco Compression;
  • Meshopt Compression.

Правильная структура тайлов

Эффективное дерево тайлов должно обеспечивать:

  • равномерное распределение данных;
  • разумную глубину иерархии;
  • отсутствие слишком крупных узлов.

Минимизация количества запросов

Объединение мелких объектов в крупные пакеты позволяет уменьшить сетевые накладные расходы.


Особенности потоковой передачи в глобальных сценах

При работе на масштабе всей планеты возникают дополнительные сложности:

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

Cesium решает эти задачи посредством сочетания:

  • тайловой архитектуры;
  • иерархических уровней детализации;
  • интеллектуального кэширования;
  • асинхронной загрузки;
  • отсечения невидимых объектов;
  • адаптивного управления качеством визуализации.

Благодаря этим механизмам становится возможной интерактивная работа с глобальными геопространственными наборами данных объёмом в десятки и сотни гигабайт непосредственно внутри веб-браузера.