Offline режим

В стандартной конфигурации CesiumJS активно использует сетевые источники данных: спутниковые снимки, карты местности, цифровые модели рельефа, 3D Tiles, GeoJSON-файлы, изображения, модели и различные сервисы. При отсутствии доступа к сети значительная часть функциональности становится недоступной.

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

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

Для полноценной работы без сети необходимо локально разместить:

  • библиотеку CesiumJS;
  • изображения базовых карт;
  • модели рельефа;
  • 3D Tiles;
  • GeoJSON и KML данные;
  • текстуры и 3D-модели;
  • шрифты и вспомогательные ресурсы.

Архитектура автономного приложения

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

project/
│
├── index.html
├── app.js
│
├── Cesium/
│   ├── Build/
│   └── Assets/
│
├── data/
│   ├── geojson/
│   ├── terrain/
│   ├── tilesets/
│   └── models/
│
└── imagery/
    ├── level0/
    ├── level1/
    └── level2/

Все необходимые данные хранятся непосредственно в файловой системе либо на локальном сервере.


Локальное размещение CesiumJS

Первым шагом является скачивание библиотеки.

Установка через npm:

npm install cesium

Либо использование готовой сборки:

Cesium/
 ├── Build/
 ├── Assets/
 ├── Widgets/
 └── ThirdParty/

Подключение в HTML:

<link
    href="./Cesium/Widgets/widgets.css"
    rel="stylesheet"
/>

<script src="./Cesium/Cesium.js"></script>

Создание Viewer:

const viewer = new Cesium.Viewer("cesiumContainer");

После локального размещения сама библиотека уже не требует доступа к CDN.


Отключение стандартных интернет-сервисов

По умолчанию Cesium пытается использовать встроенные облачные ресурсы.

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

Пример создания Viewer без стандартных источников:

const viewer = new Cesium.Viewer("cesiumContainer", {
    imageryProvider: false,
    baseLayerPicker: false,
    geocoder: false,
    timeline: false,
    animation: false
});

Другой вариант:

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

В этом случае используется простой эллипсоид Земли без загрузки рельефа.


Использование локальных растровых карт

Самым распространённым решением является хранение тайлов на локальном сервере.

Структура каталога:

imagery/
 ├── 0/
 ├── 1/
 ├── 2/
 └── ...

Подключение тайлов:

const imageryProvider =
    new Cesium.UrlTemplateImageryProvider({
        url: "./imagery/{z}/{x}/{y}.png"
    });

const viewer = new Cesium.Viewer(
    "cesiumContainer",
    {
        imageryProvider
    }
);

Используемые файлы загружаются напрямую из локальной директории.


Single Image Provider

Если требуется отображение одной карты без пирамиды тайлов, применяется SingleTileImageryProvider.

const provider =
    new Cesium.SingleTileImageryProvider({
        url: "./maps/world.png",
        rectangle:
            Cesium.Rectangle.fromDegrees(
                -180,
                -90,
                180,
                90
            )
    });

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

Подход подходит для:

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

Локальные WMTS-сервисы

Во многих организациях картографические данные разворачиваются внутри локальной сети.

Cesium способен подключаться к внутреннему WMTS-серверу.

const provider =
    new Cesium.WebMapTileServiceImageryProvider({
        url: "http://localhost/wmts",
        layer: "base",
        style: "default",
        tileMatrixSetID: "EPSG:3857",
        format: "image/png"
    });

Доступ к интернету при этом не требуется.


Работа с локальным рельефом

Без рельефа трёхмерная сцена выглядит упрощённой. Для автономных решений обычно используется собственный набор terrain-данных.

Структура каталога:

terrain/
 ├── layer.json
 ├── 0/
 ├── 1/
 └── ...

Подключение:

viewer.terrainProvider =
    await Cesium.CesiumTerrainProvider.fromUrl(
        "./terrain"
    );

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


Генерация terrain-данных

Для подготовки terrain часто используются:

  • Cesium ion Self-Hosted;
  • Cesium Terrain Builder;
  • GDAL;
  • Quantized Mesh Pipeline;
  • специализированные GIS-инструменты.

Исходными данными обычно служат:

  • SRTM;
  • ASTER GDEM;
  • LiDAR;
  • DEM;
  • цифровые модели высот предприятия.

После преобразования получается структура Quantized Mesh, понятная CesiumJS.


Offline 3D Tiles

Большинство современных геопространственных систем используют формат 3D Tiles.

Структура набора:

tileset/
 ├── tileset.json
 ├── 0/
 ├── 1/
 └── ...

Подключение:

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

viewer.scene.primitives.add(
    tileset
);

Все модели будут загружаться локально.


Организация больших наборов 3D Tiles

При автономной работе особенно важно учитывать объём данных.

Крупные наборы могут занимать:

Тип данных Размер
Городской квартал 500 МБ – 2 ГБ
Небольшой город 5–20 ГБ
Мегаполис 50–500 ГБ
Страна сотни гигабайт

Поэтому обычно применяются:

  • SSD-хранилища;
  • локальные серверы;
  • кэширование;
  • предварительная генерация LOD.

Загрузка локальных GeoJSON-файлов

GeoJSON полностью поддерживается без сети.

const dataSource =
    await Cesium.GeoJsonDataSource.load(
        "./data/cities.geojson"
    );

viewer.dataSources.add(
    dataSource
);

Данные могут содержать:

  • точки;
  • линии;
  • полигоны;
  • атрибуты объектов.

Загрузка KML

Поддерживаются и KML-документы.

const kml =
    await Cesium.KmlDataSource.load(
        "./data/routes.kml"
    );

viewer.dataSources.add(kml);

Подход часто используется при интеграции с геоинформационными системами.


Загрузка CZML

Для анимации объектов удобно применять CZML.

const czml =
    await Cesium.CzmlDataSource.load(
        "./data/flight.czml"
    );

viewer.dataSources.add(czml);

Вся анимация воспроизводится автономно.


Использование локальных glTF-моделей

Модели glTF и GLB могут храниться внутри проекта.

viewer.entities.add({
    position:
        Cesium.Cartesian3.fromDegrees(
            37.6176,
            55.7558,
            0
        ),
    model: {
        uri: "./models/building.glb",
        scale: 1.0
    }
});

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


Offline-кэширование ресурсов браузером

Для веб-приложений полезно использовать Service Worker.

Регистрация:

navigator.serviceWorker.register(
    "/sw.js"
);

Простейший Service Worker:

self.addEventListener(
    "install",
    event => {
        event.waitUntil(
            caches.open("app-cache")
                .then(cache => {
                    return cache.addAll([
                        "/",
                        "/app.js",
                        "/Cesium/Cesium.js"
                    ]);
                })
        );
    }
);

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


Использование IndexedDB

Для хранения больших объёмов пространственных данных применяется IndexedDB.

Создание базы:

const request =
    indexedDB.open(
        "OfflineGIS",
        1
    );

Данные могут содержать:

  • GeoJSON;
  • метаданные;
  • настройки пользователя;
  • результаты вычислений.

Electron и автономные настольные приложения

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

Структура:

Electron
 + CesiumJS
 + Local Terrain
 + Local Tiles
 + Local Database

Преимущества:

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

Работа через встроенный локальный сервер

Многие ресурсы Cesium невозможно корректно открыть через протокол:

file://

Поэтому обычно запускают локальный HTTP-сервер.

Пример для Node.js:

const express =
    require("express");

const app = express();

app.use(
    express.static("./")
);

app.listen(3000);

После запуска:

http://localhost:3000

Все данные остаются локальными.


Контроль сетевой активности

При создании полностью автономного решения полезно отслеживать любые внешние запросы.

Проверка через инструменты разработчика браузера позволяет убедиться, что приложение не обращается к:

  • внешним тайловым сервисам;
  • Cesium ion;
  • CDN;
  • сторонним API;
  • удалённым изображениям.

Идеальным результатом считается ситуация, когда все запросы направлены только на локальные ресурсы.


Обработка отсутствующих данных

В offline-сценариях необходимо предусматривать защиту от отсутствующих файлов.

Пример:

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

    viewer.scene.primitives.add(
        tileset
    );
}
catch(error) {
    console.error(
        "Набор тайлов не найден",
        error
    );
}

Подобный подход повышает устойчивость приложения.


Оптимизация производительности

Для автономных проектов особенно важна скорость чтения данных.

Основные рекомендации:

  • использовать формат GLB вместо OBJ;
  • минимизировать размер текстур;
  • применять сжатие gzip и brotli;
  • генерировать уровни детализации;
  • использовать SSD вместо HDD;
  • сокращать количество одновременно отображаемых объектов;
  • выполнять предварительную обработку геоданных.

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


Типовая схема полностью автономной системы

┌───────────────────────┐
│      CesiumJS         │
└───────────┬───────────┘
            │
            ▼
┌───────────────────────┐
│   Local HTTP Server   │
└───────────┬───────────┘
            │
 ┌──────────┼──────────┐
 ▼          ▼          ▼
Imagery   Terrain   3D Tiles
            │
            ▼
        GeoJSON
            │
            ▼
         Models

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