Путевая анимация в CesiumJS строится вокруг модели времени и интерполяции координат. В отличие от статических объектов, движущиеся сущности описываются как функция времени, где каждая точка пути привязана к конкретному моменту. Центральная идея заключается в том, что позиция объекта не хранится как фиксированное значение, а вычисляется динамически на основе временной шкалы сцены.
В основе лежит SampledPositionProperty — структура,
которая хранит набор временных меток и соответствующих им координат.
Cesium интерполирует между этими значениями, создавая непрерывное
движение.
const position = new Cesium.SampledPositionProperty();
position.addSample(
Cesium.JulianDate.fromIso8601("2026-01-01T10:00:00Z"),
Cesium.Cartesian3.fromDegrees(71.4304, 51.1282, 1000)
);
position.addSample(
Cesium.JulianDate.fromIso8601("2026-01-01T10:10:00Z"),
Cesium.Cartesian3.fromDegrees(71.5000, 51.1500, 1500)
);
Каждая добавленная точка формирует узел траектории, а интерполяция между узлами обеспечивает плавное перемещение объекта.
Путевые анимации полностью зависят от системного времени сцены.
Viewer.clock определяет текущее время, направление
воспроизведения и скорость.
Ключевые параметры:
startTime — начало временного диапазонаstopTime — конец временного диапазонаcurrentTime — текущее значение времениmultiplier — скорость воспроизведенияshouldAnimate — флаг активностиconst viewer = new Cesium.Viewer("cesiumContainer");
viewer.clock.startTime = Cesium.JulianDate.fromIso8601("2026-01-01T10:00:00Z");
viewer.clock.stopTime = Cesium.JulianDate.fromIso8601("2026-01-01T10:30:00Z");
viewer.clock.currentTime = viewer.clock.startTime.clone();
viewer.clock.multiplier = 60;
viewer.clock.shouldAnimate = true;
Сцена начинает «проигрывать» временной интервал, а все объекты с временными свойствами автоматически обновляются.
Путевая анимация обычно реализуется через Entity.
Позиция, заданная как временная функция, привязывается к сущности через
свойство position.
const entity = viewer.entities.add({
availability: new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({
start: Cesium.JulianDate.fromIso8601("2026-01-01T10:00:00Z"),
stop: Cesium.JulianDate.fromIso8601("2026-01-01T10:30:00Z")
})
]),
position: position,
point: {
pixelSize: 10,
color: Cesium.Color.YELLOW
}
});
availability ограничивает существование объекта во
времени, что важно для корректной работы временной сцены и оптимизации
отрисовки.
Cesium поддерживает несколько стратегий интерполяции, влияющих на характер движения:
position.setInterpolationOptions({
interpolationDegree: 2,
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation
});
При недостаточном количестве точек движение становится угловатым, при увеличении степени интерполяции — более гладким, но потенциально менее предсказуемым.
Для динамических объектов важно не только положение, но и ориентация.
VelocityOrientationProperty вычисляет направление движения
на основе производной позиции.
entity.orientation = new Cesium.VelocityOrientationProperty(position);
Это позволяет объекту разворачиваться по направлению движения без ручного вычисления углов Эйлера или кватернионов.
Визуализация пути осуществляется через PathGraphics. Это
создаёт след, который отображает историю перемещения объекта.
entity.path = {
leadTime: 0,
trailTime: 600,
width: 3,
material: Cesium.Color.CYAN
};
trailTime определяет длину отображаемого следаleadTime отвечает за прогнозируемую часть путиmaterial задаёт визуальный стиль линииЧасто путь формируется из заранее известных точек маршрута. В этом случае координаты преобразуются в временные узлы с равномерным распределением времени.
const coords = [
[71.4304, 51.1282],
[71.4500, 51.1350],
[71.4700, 51.1400],
[71.5000, 51.1500]
];
const start = Cesium.JulianDate.fromIso8601("2026-01-01T10:00:00Z");
const position = new Cesium.SampledPositionProperty();
coords.forEach((c, i) => {
const time = Cesium.JulianDate.addSeconds(
start,
i * 300,
new Cesium.JulianDate()
);
position.addSample(
time,
Cesium.Cartesian3.fromDegrees(c[0], c[1], 1000)
);
});
Равномерное распределение временных меток создаёт стабильную скорость движения, которая при необходимости может быть модифицирована через изменение интервалов.
Слежение камеры за объектом реализуется через привязку к сущности. Камера автоматически обновляет положение и ориентацию относительно текущего состояния объекта.
viewer.trackedEntity = entity;
В этом режиме камера синхронизируется с временной моделью и следует за объектом без дополнительной логики обновления.
Более гибкий вариант предполагает ручное управление:
viewer.scene.preUpdate.addEventListener(() => {
const pos = entity.position.getValue(viewer.clock.currentTime);
if (pos) {
viewer.camera.lookAt(pos, new Cesium.HeadingPitchRange(0, -0.5, 2000));
}
});
Альтернативный способ визуализации пути — обновляемая полилиния. Она строится на основе массива уже пройденных координат.
const positions = [];
viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(() => positions, false),
width: 2,
material: Cesium.Color.ORANGE
}
});
При каждом обновлении времени можно добавлять новую точку:
viewer.clock.onTick.addEventListener(() => {
const time = viewer.clock.currentTime;
const pos = entity.position.getValue(time);
if (pos) {
positions.push(pos.clone());
}
});
Такой подход используется для отображения реального трека без заранее заданной траектории.
Путевые анимации могут учитывать рельеф или игнорировать его в зависимости от режима привязки.
clampToGround — прижим к поверхностиCesium.Cartesian3.fromDegrees(longitude, latitude, height, undefined, result);
При использовании clampToGround высота игнорируется, а
позиция пересчитывается по цифровой модели рельефа.
Для сложных сценариев применяется CZML — формат описания временных данных. Он позволяет задавать траектории без императивного кода.
const czml = [{
id: "document",
version: "1.0"
}, {
id: "vehicle",
position: {
cartographicDegrees: [
0, 71.4304, 51.1282, 1000,
600, 71.5000, 51.1500, 1500
]
},
path: {
material: { solidColor: { color: { rgba: [0, 255, 255, 255] } } },
width: 3
}
}];
viewer.dataSources.add(Cesium.CzmlDataSource.load(czml));
CZML особенно полезен при потоковой передаче траекторий из серверных систем.
При увеличении количества объектов возрастает нагрузка на интерполяцию и отрисовку. Основные методы оптимизации:
availabilityНа уровне сцены важную роль играет requestRenderMode,
уменьшающий количество кадров при отсутствии изменений:
const viewer = new Cesium.Viewer("cesiumContainer", {
requestRenderMode: true,
maximumRenderTimeChange: Infinity
});
Для групповых путевых анимаций важно синхронизировать временные
шкалы. Все объекты используют общий clock, что позволяет
строить координированные сценарии движения.
viewer.clock.multiplier = 120;
viewer.clock.shouldAnimate = true;
При одинаковом временном диапазоне разные
SampledPositionProperty формируют согласованные траектории,
даже при различной сложности маршрутов.
Если текущее время выходит за пределы доступных sample-данных, Cesium
прекращает интерполяцию и возвращает undefined. Это
состояние используется для скрытия объекта или его фиксации на последней
известной позиции.
const pos = position.getValue(viewer.clock.currentTime);
if (!pos) {
entity.show = false;
}
Полноценная путевая анимация формируется объединением нескольких механизмов:
SampledPositionProperty задаёт движениеVelocityOrientationProperty формирует поворотPathGraphics отображает следViewer.trackedEntity обеспечивает сопровождениеЭти элементы работают как единая система, где временная модель является центральным управляющим механизмом, а визуальные компоненты лишь интерпретируют её состояние в каждый момент времени.