CesiumJS предоставляет несколько уровней взаимодействия для
распространения 3D-контента: от простого сохранения состояния камеры до
полноценного встраивания готовых сцен в сторонние веб-приложения.
Основные подходы к sharing и embedding базируются на сериализации
состояния Viewer, использовании URL-параметров,
iframe-встраивании и публикации ассетов через Cesium ion.
Одним из базовых механизмов шаринга является сохранение состояния камеры и параметров сцены в адресной строке. В CesiumJS нет единого обязательного стандарта для этого, однако распространённой практикой является ручная сериализация ключевых параметров:
Camera.position)heading, pitch,
roll)Entity)Пример формирования URL с параметрами:
const camera = viewer.camera;
const cartographic = Cesium.Cartographic.fromCartesian(camera.position);
const state = {
lon: Cesium.Math.toDegrees(cartographic.longitude),
lat: Cesium.Math.toDegrees(cartographic.latitude),
height: cartographic.height,
heading: camera.heading,
pitch: camera.pitch,
roll: camera.roll
};
const url = new URL(window.location.href);
url.searchParams.set("lon", state.lon);
url.searchParams.set("lat", state.lat);
url.searchParams.set("h", state.height);
url.searchParams.set("heading", state.heading);
url.searchParams.set("pitch", state.pitch);
url.searchParams.set("roll", state.roll);
history.replaceState({}, "", url);
Восстановление состояния при загрузке:
const params = new URLSearchParams(window.location.search);
const lon = parseFloat(params.get("lon"));
const lat = parseFloat(params.get("lat"));
const height = parseFloat(params.get("h"));
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(lon, lat, height),
orientation: {
heading: parseFloat(params.get("heading")),
pitch: parseFloat(params.get("pitch")),
roll: parseFloat(params.get("roll"))
}
});
Такой подход делает сцену воспроизводимой и позволяет передавать ссылку на конкретный ракурс.
Cesium Sandcastle — инструмент для демонстрации примеров кода CesiumJS — поддерживает встроенный механизм генерации share-ссылок. Каждая сцена может быть сериализована в URL, содержащий код JavaScript.
Механизм основан на:
Пример логики:
Sandcastle.addDefaultToolbarButton("Share", function () {
const code = editor.getValue();
const encoded = btoa(unescape(encodeURIComponent(code)));
const url = `${location.origin}/Sandcastle/index.html#c=${encoded}`;
navigator.clipboard.writeText(url);
});
Такой подход применяется преимущественно для демонстраций и обучения, где важна передача не только состояния сцены, но и исходного кода.
Для более продвинутого sharing используется сохранение состояния визуальных слоёв:
ColorBlendMode)Пример сохранения активных слоёв:
const layers = viewer.imageryLayers._layers.map(layer => ({
url: layer.imageryProvider?.url,
alpha: layer.alpha,
show: layer.show
}));
Восстановление:
layers.forEach(cfg => {
viewer.imageryLayers.addImageryProvider(
new Cesium.UrlTemplateImageryProvider({ url: cfg.url })
);
});
Для 3D Tiles:
const tileset = viewer.scene.primitives.add(
new Cesium.Cesium3DTileset({
url: tilesetUrl
})
);
Сериализация таких данных обычно выводится в JSON, который затем помещается в URL или хранится на сервере.
Наиболее распространённый способ встраивания CesiumJS-приложений —
использование <iframe>. Такой подход применяется при
публикации готовых сцен или приложений, размещённых на отдельном
домене.
Базовый пример:
<iframe
src="https://example.com/cesium-app"
width="100%"
height="600"
style="border: none;"
></iframe>
Особенности embedding:
Viewer извнеДля динамического взаимодействия между родительской страницей и
Cesium-приложением используется window.postMessage.
Внутри Cesium-приложения:
window.addEventListener("message", (event) => {
if (event.data.type === "FLY_TO") {
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
event.data.lon,
event.data.lat,
event.data.height
)
});
}
});
На стороне embedding-страницы:
const iframe = document.querySelector("iframe");
iframe.contentWindow.postMessage({
type: "FLY_TO",
lon: 71.4304,
lat: 51.1283,
height: 10000
}, "*");
Такой подход позволяет управлять сценой без прямого доступа к внутреннему API.
Cesium ion предоставляет готовые механизмы публикации сцен и ассетов. После загрузки данных (3D Tiles, terrain, imagery) формируется уникальный endpoint, который может быть встроен в приложение.
Типичный сценарий:
Пример подключения tileset:
const viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: Cesium.createWorldTerrain()
});
const tileset = new Cesium.Cesium3DTileset({
url: Cesium.IonResource.fromAssetId(123456)
});
viewer.scene.primitives.add(tileset);
viewer.zoomTo(tileset);
Для embedding в сторонний сайт используется тот же код, но с ограничением доступа через access token.
При встраивании Cesium-сцен критически важна настройка токенов и CORS:
Пример установки токена:
Cesium.Ion.defaultAccessToken = "YOUR_ACCESS_TOKEN";
Для production-сцен используется:
CesiumJS зависит от размеров canvas, поэтому embedding требует корректной адаптации контейнера:
#cesiumContainer {
width: 100%;
height: 100vh;
margin: 0;
padding: 0;
overflow: hidden;
}
При изменении размеров окна важно уведомлять Cesium:
window.addEventListener("resize", () => {
viewer.resize();
});
В современных приложениях часто используется
ResizeObserver:
const observer = new ResizeObserver(() => {
viewer.resize();
});
observer.observe(document.getElementById("cesiumContainer"));
CesiumJS может быть встроен как через CDN, так и через локальную сборку.
CDN-вариант:
<script src="https://cesium.com/downloads/cesiumjs/releases/1.120/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.120/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
Self-hosted вариант:
import * as Cesium from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
Embedding в этом случае становится частью обычного frontend-приложения.
Для сложных систем используется гибридный подход:
Пример URL:
https://app.com/viewer?sceneId=42&mode=3d
Загрузка сцены:
fetch(`/api/scenes/${sceneId}`)
.then(res => res.json())
.then(scene => {
loadScene(viewer, scene);
});
Такой подход масштабируется лучше, чем длинные URL с сериализацией всего состояния.
3D Tiles являются основным форматом CesiumJS для потокового отображения больших данных. При embedding важно учитывать:
Пример:
const tileset = new Cesium.Cesium3DTileset({
url: Cesium.IonResource.fromAssetId(98765),
maximumScreenSpaceError: 2
});
viewer.scene.primitives.add(tileset);
viewer.zoomTo(tileset);
При встраивании таких сцен часто используется lazy-loading, чтобы минимизировать стартовую нагрузку iframe.
Встраивание CesiumJS в интерфейсы часто сопровождается дополнительными слоями управления:
Связь с viewer:
function toggleLayer(layer) {
layer.show = !layer.show;
}
Такая архитектура разделяет embedding сцены и бизнес-логику интерфейса, позволяя масштабировать приложения с геопространственными данными.