Ограничения перемещения

Ограничение перемещения в 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-моделями.

Географические границы через Rectangle

Ограничение перемещения по поверхности Земли часто реализуется через 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;
  }
});

Привязка перемещения к поверхности terrain

Ограничение перемещения над поверхностью реализуется через 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
  }
});

Такой режим ограничивает вертикальное смещение объектов и фиксирует их на поверхности глобуса.

Ограничение перемещения камеры в пределах 3D Tileset

Для трёхмерных тайлсетов применяется ограничение через 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 volumes для логических границ

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 для региона
  • ограничение высоты через minimumZoomDistance
  • запрет наклона камеры
  • привязка объектов к поверхности через clampToGround
  • контроль выхода за bounding sphere тайлсета

Комбинированный контроль часто реализуется через обработчик 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)
    });
  }
});

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