Ограничение перемещения в CesiumJS реализуется на нескольких уровнях:
управление камерой, географические рамки сцены, ограничения
взаимодействия с террейном и тайлсетами, а также логические ограничения
для сущностей. Библиотека предоставляет низкоуровневые механизмы
контроля через Scene, Camera и
ScreenSpaceCameraController, позволяя формировать строгие
или мягкие границы навигации в 3D-пространстве.
Основной механизм ограничения пользовательского перемещения камеры
сосредоточен в scene.screenSpaceCameraController. Этот
объект управляет всеми интерактивными действиями: вращением,
масштабированием, панорамированием.
Ключевые параметры:
minimumZoomDistance и maximumZoomDistance
— задают диапазон допустимого удаления камерыenableRotate — разрешение вращения сценыenableTranslate — разрешение панорамированияenableZoom — разрешение масштабированияenableTilt — наклон камерыenableLook — свободный режим обзораОграничение диапазона приближения камеры:
viewer.scene.screenSpaceCameraController.minimumZoomDistance = 1000.0;
viewer.scene.screenSpaceCameraController.maximumZoomDistance = 5000000.0;
При установке этих значений камера перестаёт пересекать заданные границы, что особенно важно при работе с глобальными сценами или локальными 3D-моделями.
Ограничение перемещения по поверхности Земли часто реализуется через
Cesium.Rectangle. Этот тип задаёт прямоугольную область в
географических координатах (радианы).
const bounds = Cesium.Rectangle.fromDegrees(
30.0, 10.0, // запад, юг
40.0, 20.0 // восток, север
);
viewer.scene.globe.cartographicLimitRectangle = bounds;
Использование cartographicLimitRectangle ограничивает
перемещение камеры по долготе и широте, предотвращая выход за заданный
регион.
Дополнительно возможно принудительное удержание камеры в пределах области через обработку событий:
viewer.camera.changed.addEventListener(function () {
const cartographic = Cesium.Cartographic.fromCartesian(viewer.camera.position);
if (!Cesium.Rectangle.contains(bounds, cartographic)) {
viewer.camera.setView({
destination: Cesium.Rectangle.center(bounds)
});
}
});
Подобный подход применяется при создании региональных картографических приложений.
Высота камеры над поверхностью контролируется через
Cartographic.height и параметры контроллера.
const controller = viewer.scene.screenSpaceCameraController;
controller.minimumZoomDistance = 200.0;
controller.maximumZoomDistance = 2000000.0;
Для более точного контроля используется анализ позиции камеры:
viewer.camera.changed.addEventListener(function () {
const height = Cesium.Cartographic.fromCartesian(viewer.camera.position).height;
if (height < 200.0) {
viewer.camera.zoomOut(10.0);
}
});
Ограничение высоты часто применяется в сценах с высокодетализированными 3D Tiles, где чрезмерное приближение приводит к нежелательным артефактам или перегрузке данных.
Контроль углов обзора камеры позволяет предотвращать нежелательные ракурсы, например полный переворот камеры или чрезмерный наклон к горизонту.
const controller = viewer.scene.screenSpaceCameraController;
controller.minimumPitch = Cesium.Math.toRadians(-20.0);
controller.maximumPitch = Cesium.Math.toRadians(-80.0);
Ограничение вращения по roll также возможно через прямую модификацию ориентации камеры:
viewer.camera.setView({
orientation: {
heading: Cesium.Math.toRadians(0.0),
pitch: Cesium.Math.toRadians(-45.0),
roll: 0.0
}
});
Для строгого контроля ориентации используется перехват изменений:
viewer.camera.changed.addEventListener(function () {
if (viewer.camera.roll !== 0.0) {
viewer.camera.roll = 0.0;
}
});
Ограничение перемещения над поверхностью реализуется через
clampToGround для сущностей и геометрии.
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(37.6173, 55.7558),
point: {
pixelSize: 10,
color: Cesium.Color.RED,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
}
});
Для линий и полигонов:
viewer.entities.add({
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([
37.6, 55.7,
37.7, 55.8
]),
clampToGround: true,
width: 3
}
});
Такой режим ограничивает вертикальное смещение объектов и фиксирует их на поверхности глобуса.
Для трёхмерных тайлсетов применяется ограничение через bounding
volume. После загрузки Cesium3DTileset можно вычислить его
границы и использовать их для контроля камеры.
const tileset = new Cesium.Cesium3DTileset({
url: 'tileset.json'
});
viewer.scene.primitives.add(tileset);
tileset.readyPromise.then(function () {
const boundingSphere = tileset.boundingSphere;
viewer.camera.flyToBoundingSphere(boundingSphere);
});
Ограничение выхода за пределы модели:
viewer.camera.changed.addEventListener(function () {
const distance = Cesium.Cartesian3.distance(
viewer.camera.position,
tileset.boundingSphere.center
);
if (distance > tileset.boundingSphere.radius * 5) {
viewer.camera.zoomIn(distance - tileset.boundingSphere.radius * 5);
}
});
Bounding sphere и bounding box используются для создания виртуальных границ навигации.
const sphere = new Cesium.BoundingSphere(
Cesium.Cartesian3.fromDegrees(37.0, 55.0),
100000.0
);
Проверка положения камеры:
const cameraPosition = viewer.camera.positionWC;
if (!Cesium.BoundingSphere.contains(sphere, cameraPosition)) {
viewer.camera.setView({
destination: sphere.center
});
}
Подобный подход позволяет ограничивать перемещение внутри произвольных областей, независимо от географической системы координат.
На уровне сцены возможно полное блокирование отдельных типов взаимодействия:
const controller = viewer.scene.screenSpaceCameraController;
controller.enableTranslate = false;
controller.enableZoom = true;
controller.enableRotate = true;
controller.enableTilt = false;
Такой режим применяется для фиксированных визуализаций, где допустим только просмотр с ограниченной свободой движения.
Реальные приложения используют комбинации ограничений:
Rectangle для регионаminimumZoomDistanceclampToGroundКомбинированный контроль часто реализуется через обработчик
camera.changed, где выполняется проверка всех параметров
позиции камеры и корректировка при выходе за допустимые пределы.
viewer.camera.changed.addEventListener(function () {
const cartographic = Cesium.Cartographic.fromCartesian(viewer.camera.position);
const height = cartographic.height;
if (height < 500.0) {
viewer.camera.position = viewer.camera.position.clone();
viewer.camera.zoomOut(50.0);
}
if (!Cesium.Rectangle.contains(bounds, cartographic)) {
viewer.camera.setView({
destination: Cesium.Rectangle.center(bounds)
});
}
});
Такая модель позволяет формировать строгую навигационную среду, где перемещение камеры подчинено заранее заданным пространственным и геометрическим правилам.