В стандартной конфигурации CesiumJS активно использует сетевые источники данных: спутниковые снимки, карты местности, цифровые модели рельефа, 3D Tiles, GeoJSON-файлы, изображения, модели и различные сервисы. При отсутствии доступа к сети значительная часть функциональности становится недоступной.
Offline-режим представляет собой организацию работы приложения, при которой все необходимые ресурсы располагаются локально и могут использоваться без подключения к интернету. Такой подход востребован в следующих сценариях:
Для полноценной работы без сети необходимо локально разместить:
Типичная структура проекта выглядит следующим образом:
project/
│
├── index.html
├── app.js
│
├── Cesium/
│ ├── Build/
│ └── Assets/
│
├── data/
│ ├── geojson/
│ ├── terrain/
│ ├── tilesets/
│ └── models/
│
└── imagery/
├── level0/
├── level1/
└── level2/
Все необходимые данные хранятся непосредственно в файловой системе либо на локальном сервере.
Первым шагом является скачивание библиотеки.
Установка через 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
}
);
Используемые файлы загружаются напрямую из локальной директории.
Если требуется отображение одной карты без пирамиды тайлов, применяется 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
}
);
Подход подходит для:
Во многих организациях картографические данные разворачиваются внутри локальной сети.
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 часто используются:
Исходными данными обычно служат:
После преобразования получается структура Quantized Mesh, понятная CesiumJS.
Большинство современных геопространственных систем используют формат 3D Tiles.
Структура набора:
tileset/
├── tileset.json
├── 0/
├── 1/
└── ...
Подключение:
const tileset =
await Cesium.Cesium3DTileset.fromUrl(
"./tileset/tileset.json"
);
viewer.scene.primitives.add(
tileset
);
Все модели будут загружаться локально.
При автономной работе особенно важно учитывать объём данных.
Крупные наборы могут занимать:
| Тип данных | Размер |
|---|---|
| Городской квартал | 500 МБ – 2 ГБ |
| Небольшой город | 5–20 ГБ |
| Мегаполис | 50–500 ГБ |
| Страна | сотни гигабайт |
Поэтому обычно применяются:
GeoJSON полностью поддерживается без сети.
const dataSource =
await Cesium.GeoJsonDataSource.load(
"./data/cities.geojson"
);
viewer.dataSources.add(
dataSource
);
Данные могут содержать:
Поддерживаются и KML-документы.
const kml =
await Cesium.KmlDataSource.load(
"./data/routes.kml"
);
viewer.dataSources.add(kml);
Подход часто используется при интеграции с геоинформационными системами.
Для анимации объектов удобно применять CZML.
const czml =
await Cesium.CzmlDataSource.load(
"./data/flight.czml"
);
viewer.dataSources.add(czml);
Вся анимация воспроизводится автономно.
Модели glTF и GLB могут храниться внутри проекта.
viewer.entities.add({
position:
Cesium.Cartesian3.fromDegrees(
37.6176,
55.7558,
0
),
model: {
uri: "./models/building.glb",
scale: 1.0
}
});
Загрузка выполняется напрямую из файловой системы или локального сервера.
Для веб-приложений полезно использовать 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.
Создание базы:
const request =
indexedDB.open(
"OfflineGIS",
1
);
Данные могут содержать:
Одним из наиболее популярных способов создания полностью автономных решений является использование 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
Все данные остаются локальными.
При создании полностью автономного решения полезно отслеживать любые внешние запросы.
Проверка через инструменты разработчика браузера позволяет убедиться, что приложение не обращается к:
Идеальным результатом считается ситуация, когда все запросы направлены только на локальные ресурсы.
В offline-сценариях необходимо предусматривать защиту от отсутствующих файлов.
Пример:
try {
const tileset =
await Cesium.Cesium3DTileset
.fromUrl(
"./tileset/tileset.json"
);
viewer.scene.primitives.add(
tileset
);
}
catch(error) {
console.error(
"Набор тайлов не найден",
error
);
}
Подобный подход повышает устойчивость приложения.
Для автономных проектов особенно важна скорость чтения данных.
Основные рекомендации:
Грамотно подготовленный набор локальных ресурсов позволяет обеспечивать производительность, сопоставимую с онлайн-сервисами.
┌───────────────────────┐
│ CesiumJS │
└───────────┬───────────┘
│
▼
┌───────────────────────┐
│ Local HTTP Server │
└───────────┬───────────┘
│
┌──────────┼──────────┐
▼ ▼ ▼
Imagery Terrain 3D Tiles
│
▼
GeoJSON
│
▼
Models
Подобная архитектура обеспечивает полноценную работу геопространственного приложения без доступа к внешним сетям, сохраняя поддержку картографии, трёхмерной визуализации, пространственного анализа и отображения больших наборов геоданных.