Cesium 视角切换 API 详解
下面我将详细讲解 Cesium 中各个视角切换 API 的使用场景、使用方式、参数说明及注意事项,并提供代码示例:
1. viewer.camera.setView(options)
使用场景
-
地图初始化定位
-
需要立即切换视角(无动画过渡)
-
需要精确控制相机位置和方向
使用方式
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(116.39, 39.9, 1500),
orientation: {
heading: Cesium.Math.toRadians(45),
pitch: Cesium.Math.toRadians(-30),
roll: 0.0
}
});
参数说明
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
destination | Cartesian3 或 Rectangle | 目标位置(坐标或矩形区域) | 必填 |
orientation.heading | number | 偏航角(弧度),0表示正北 | 0 |
orientation.pitch | number | 俯仰角(弧度),-π/2表示垂直向下 | -π/2 |
orientation.roll | number | 翻滚角(弧度) | 0 |
convert | boolean | 是否将方向参数从度数转换为弧度 | false |
endTransform | Matrix4 | 变换矩阵 | undefined |
transform | Matrix4 | 变换矩阵 | undefined |
注意事项
-
此方法会立即切换视角,没有动画效果
-
对于经纬度坐标,使用
Cesium.Cartesian3.fromDegrees(lon, lat, height)进行转换 -
角度参数单位为弧度,使用
Cesium.Math.toRadians()进行转换 -
当 destination 是 Rectangle 时,会显示整个矩形区域
2. viewer.camera.flyTo(options)
使用场景
-
需要动画效果切换视角
-
场景漫游和路径飞行
-
用户交互式视角切换
-
需要控制飞行时间和路径
使用方式
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883, 1000),
orientation: {
heading: Cesium.Math.toRadians(90),
pitch: Cesium.Math.toRadians(-25),
roll: 0
},
duration: 8,
complete: () => console.log("飞行完成!"),
maximumHeight: 5000,
pitchAdjustHeight: 50
});
参数说明
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
destination | Cartesian3 或 Rectangle | 目标位置 | 必填 |
orientation | Object | 包含 heading, pitch, roll | 当前视角 |
duration | number | 飞行时间(秒) | 自动计算 |
complete | function | 完成回调函数 | undefined |
cancel | function | 取消回调函数 | undefined |
maximumHeight | number | 飞行过程中的最大高度 | 50000000 |
pitchAdjustHeight | number | 避免穿地的高度调整 | 0 |
flyOverLongitude | number | 飞越经度 | undefined |
flyOverLongitudeWeight | number | 飞越经度权重 | undefined |
easingFunction | function | 缓动函数 | EasingFunction.LINEAR_NONE |
offset | HeadingPitchRange | 偏移量 | undefined |
注意事项
-
连续调用 flyTo() 可能导致动画中断,使用 complete 回调确保顺序执行
-
设置 maximumHeight 可避免飞行高度过高
-
pitchAdjustHeight 可防止相机穿入地形
-
飞行时间(duration)在移动端应适当缩短(3-5秒)
-
使用 easingFunction 可创建更自然的飞行效果
3. viewer.zoomTo(target)
使用场景
-
快速缩放到特定实体
-
定位点、线、面等几何体
-
定位模型或3D图块
-
不需要飞行动画的场景
使用方式
// 创建实体
const entity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(139.77, 35.68, 100),
point: {
pixelSize: 20,
color: Cesium.Color.RED
}
});
// 缩放到实体
viewer.zoomTo(entity);
// 缩放到数据源
const dataSource = await Cesium.GeoJsonDataSource.load('data.geojson');
viewer.dataSources.add(dataSource);
viewer.zoomTo(dataSource);
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
target | Entity/EntityCollection/DataSource | 要缩放的目标 |
offset | HeadingPitchRange | 偏移量(可选) |
注意事项
-
可以缩放单个实体或整个数据源
-
此方法会立即切换视角,没有动画效果
-
对于大量实体,建议使用数据源而非遍历实体
-
使用 offset 参数可以控制观察角度和距离
-
当实体在地形下方时,相机可能会调整到地表上方
4. viewer.flyTo(target, options)
使用场景
-
需要动画飞行到实体
-
模型展示和三维可视化
-
需要控制观察角度和距离
-
用户交互式聚焦实体
使用方式
// 飞行到实体
viewer.flyTo(entity, {
offset: new Cesium.HeadingPitchRange(
Cesium.Math.toRadians(45),
Cesium.Math.toRadians(-30),
500
),
duration: 4,
maximumHeight: 3000
});
// 飞行到数据源
viewer.flyTo(dataSource, {
duration: 6,
offset: new Cesium.HeadingPitchRange(
Cesium.Math.toRadians(0),
Cesium.Math.toRadians(-45),
1000
)
});
参数说明
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
target | Entity/EntityCollection/DataSource | 目标实体 | 必填 |
options.duration | number | 飞行时间(秒) | 自动计算 |
options.offset | HeadingPitchRange | 观察偏移量 | 自动计算 |
options.complete | function | 完成回调 | undefined |
options.cancel | function | 取消回调 | undefined |
options.maximumHeight | number | 最大飞行高度 | 50000000 |
options.pitchAdjustHeight | number | 避免穿地高度 | 0 |
options.easingFunction | function | 缓动函数 | EasingFunction.LINEAR_NONE |
注意事项
-
这是定位实体的首选方法(相比 zoomTo)
-
使用 offset 参数可以精确控制观察角度
-
HeadingPitchRange 的三个参数:heading(偏航角)、pitch(俯仰角)、range(距离)
-
对于模型展示,推荐俯仰角设置为 -30° 到 -45°
-
开启地形时,相机会自动贴合地表
5. 相机方向控制 (Heading/Pitch/Roll)
使用场景
-
调整相机观察角度
-
创建特定视角的截图
-
模拟不同观察方向
-
配合其他视角切换方法使用
使用方式
// 设置偏航角(0=北,90=东)
viewer.camera.setHeading(Cesium.Math.toRadians(45));
// 设置俯仰角(0=水平,-90=垂直向下)
viewer.camera.setPitch(Cesium.Math.toRadians(-30));
// 设置翻滚角(通常保持0)
viewer.camera.setRoll(0);
// 旋转相机(绕Z轴旋转)
viewer.camera.rotate(Cesium.Cartesian3.UNIT_Z, Cesium.Math.toRadians(-10));
// 俯仰相机(绕X轴旋转)
viewer.camera.rotate(Cesium.Cartesian3.UNIT_X, Cesium.Math.toRadians(-5));
// 获取当前方向
const heading = viewer.camera.heading;
const pitch = viewer.camera.pitch;
const roll = viewer.camera.roll;
参数说明
| 方法 | 参数 | 说明 |
|---|---|---|
setHeading(angle) | number | 设置偏航角(弧度) |
setPitch(angle) | number | 设置俯仰角(弧度) |
setRoll(angle) | number | 设置翻滚角(弧度) |
rotate(axis, angle) | axis: Cartesian3, angle: number | 绕指定轴旋转相机 |
lookUp(angle) | number | 向上看(增加俯仰角) |
lookDown(angle) | number | 向下看(减少俯仰角) |
lookLeft(angle) | number | 向左看(增加偏航角) |
lookRight(angle) | number | 向右看(减少偏航角) |
注意事项
-
所有角度参数都是弧度制
-
旋转操作是相对于当前相机位置的
-
直接设置方向会立即生效(无动画)
-
使用 rotate 方法可实现相对旋转
-
俯仰角范围通常为 -90°(垂直向下)到 90°(垂直向上)
6. 沿路径飞行
使用场景
-
场景漫游和导览
-
飞行模拟
-
动态展示路径
-
创建视频飞行路径
使用方式
// 定义路径点
const positions = [
Cesium.Cartesian3.fromDegrees(116.39, 39.9, 1000), // 北京
Cesium.Cartesian3.fromDegrees(121.47, 31.23, 2000), // 上海
Cesium.Cartesian3.fromDegrees(114.05, 22.55, 1500) // 香港
];
// 创建飞行路径
const flightPath = viewer.entities.add({
polyline: {
positions: positions,
width: 5,
material: Cesium.Color.YELLOW
}
});
// 沿路径飞行
viewer.camera.flyTo({
destination: positions[1],
orientation: {
direction: new Cesium.Cartesian3(0, 1, 0), // 自定义方向
up: Cesium.Cartesian3.UNIT_Z
},
flightPath: {
leadTime: 10, // 向前预测时间
curve: Cesium.ArcType.GEODESIC // 路径类型
},
duration: 20
});
关键参数
| 参数 | 说明 |
|---|---|
flightPath.leadTime | 相机沿飞行路径提前的时间(秒) |
flightPath.curve | 路径曲线类型(GEODESIC, RHUMB, NONE) |
orientation.direction | 自定义相机方向向量 |
orientation.up | 自定义相机的上方向 |
duration | 飞行总时间 |
注意事项
-
使用
Cesium.SampledPositionProperty可实现更精确的路径控制 -
设置 leadTime 可以使相机朝飞行方向前看
-
对于长距离飞行,使用 GEODESIC 曲线类型
-
可通过
viewer.camera.moveStart和viewer.camera.moveEnd事件控制飞行过程 -
使用
viewer.camera.cancelFlight()可取消当前飞行
7. 相机范围限制
使用场景
-
防止相机飞出地球
-
限制最小/最大高度
-
约束地图浏览范围
-
防止相机穿入地下
使用方式
// 限制相机高度范围
viewer.scene.screenSpaceCameraController.minimumZoomDistance = 1000; // 最小高度1000米
viewer.scene.screenSpaceCameraController.maximumZoomDistance = 10000000; // 最大高度
// 限制俯仰角范围
viewer.scene.screenSpaceCameraController.minimumPitch = Cesium.Math.toRadians(-90);
viewer.scene.screenSpaceCameraController.maximumPitch = Cesium.Math.toRadians(0);
// 禁用某些相机操作
viewer.scene.screenSpaceCameraController.enableRotate = false; // 禁用旋转
viewer.scene.screenSpaceCameraController.enableTilt = false; // 禁用倾斜
viewer.scene.screenSpaceCameraController.enableZoom = false; // 禁用缩放
// 设置约束矩形
viewer.scene.camera.constrainedAxis = Cesium.Cartesian3.UNIT_Z; // 约束Z轴
viewer.scene.camera.maximumZoomFactor = 2; // 最大缩放因子
常用约束属性
| 属性 | 说明 |
|---|---|
minimumZoomDistance | 最小缩放距离(米) |
maximumZoomDistance | 最大缩放距离(米) |
minimumPitch | 最小俯仰角(弧度) |
maximumPitch | 最大俯仰角(弧度) |
enableRotate | 是否允许旋转 |
enableTilt | 是否允许倾斜 |
enableZoom | 是否允许缩放 |
enableTranslate | 是否允许平移 |
constrainedAxis | 约束的轴 |
maximumZoomFactor | 最大缩放因子 |
注意事项
-
开启地形时,高度约束是相对于地形的
-
俯仰角约束对于创建特定应用场景很有用
-
禁用某些控制器可以创建专用地图浏览体验
-
约束矩形对于特定区域的地图应用非常有用
-
使用
viewer.scene.screenSpaceCameraController控制用户交互行为
8. viewer.trackedEntity (实体跟随)
使用场景
-
跟踪移动的实体(如车辆、飞机、船舶等)
-
实时监控特定对象
-
创建第一人称或第三人称视角
-
动态演示和模拟
使用方式
// 创建实体
const entity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(0, 0, 0),
model: {
uri: 'path/to/model.gltf'
}
});
// 开始跟踪实体
viewer.trackedEntity = entity;
// 停止跟踪
viewer.trackedEntity = undefined;
// 设置跟踪时的偏移量
entity.viewFrom = new Cesium.Cartesian3(-50.0, 0.0, 50.0); // 在实体的左后方50米,上方50米
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
trackedEntity | Entity | 要跟踪的实体,设置为undefined停止跟踪 |
高级配置
// 自定义跟踪视角
viewer.trackedEntity = entity;
// 获取或设置跟踪偏移量
const offset = new Cesium.HeadingPitchRange(
Cesium.Math.toRadians(45), // 偏航角
Cesium.Math.toRadians(-30), // 俯仰角
100.0 // 距离
);
// 使用自定义偏移量
viewer.trackedEntityView = offset;
// 或者直接设置实体的viewFrom属性
entity.viewFrom = new Cesium.Cartesian3(-50.0, 0.0, 50.0);
注意事项
-
跟踪实体时,相机会自动保持实体在视野中心,并随实体移动而移动
-
可以通过调整
viewer.trackedEntity来切换跟踪的实体或停止跟踪 -
跟踪状态下,用户无法手动控制相机(除非停止跟踪)
-
可以通过
viewer.clock.onTick事件更新实体位置,相机会自动跟随 -
跟踪时,相机默认保持一定的距离和角度,可以通过修改实体的
viewFrom属性来调整 -
对于移动的实体,跟踪效果非常流畅,适合车辆监控等场景
9. viewer.camera.viewBoundingSphere(boundingSphere, offset)
使用场景
-
将相机视角调整到包含一个包围球(BoundingSphere)的视图
-
用于查看整个3D模型或瓦片集的范围
-
立即调整视角(无动画)
使用方式
// 获取实体的包围球
const boundingSphere = entity.boundingSphere;
// 调整相机视角到包围球
viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0, -0.5, 0));
// 对于瓦片集(Cesium3DTileset)
tileset.readyPromise.then(function(tileset) {
const boundingSphere = tileset.boundingSphere;
viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0, -0.5, 0));
});
// 手动创建包围球
const center = Cesium.Cartesian3.fromDegrees(116.39, 39.9, 0);
const radius = 1000; // 半径(米)
const boundingSphere = new Cesium.BoundingSphere(center, radius);
viewer.camera.viewBoundingSphere(boundingSphere);
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
boundingSphere | BoundingSphere | 包围球,包含中心点和半径 |
offset | HeadingPitchRange | 可选,观察的偏移量(航向角、俯仰角、距离) |
注意事项
-
此方法会立即调整相机视角,没有动画
-
包围球可以通过实体的
boundingSphere属性获取,但注意实体必须已加载 -
对于瓦片集,需要在
readyPromise解析后才能获取正确的包围球 -
使用偏移量可以调整观察角度和距离
-
如果包围球无效或未定义,可能会抛出错误
-
此方法适用于需要立即查看整个对象范围的场景
10. viewer.camera.flyToBoundingSphere(boundingSphere, options)
使用场景
-
动画飞行到包围球的范围
-
用于平滑过渡到3D模型或瓦片集的全览视图
-
提供更好的用户体验,避免视角突然跳跃
使用方式
// 获取实体的包围球
const boundingSphere = entity.boundingSphere;
// 飞行到包围球
viewer.camera.flyToBoundingSphere(boundingSphere, {
duration: 3,
offset: new Cesium.HeadingPitchRange(0, -0.5, 0)
});
// 对于瓦片集
tileset.readyPromise.then(function(tileset) {
const boundingSphere = tileset.boundingSphere;
viewer.camera.flyToBoundingSphere(boundingSphere, {
duration: 4,
offset: new Cesium.HeadingPitchRange(0, -0.5, 0)
});
});
// 手动创建包围球并飞行
const center = Cesium.Cartesian3.fromDegrees(116.39, 39.9, 0);
const radius = 1000;
const boundingSphere = new Cesium.BoundingSphere(center, radius);
viewer.camera.flyToBoundingSphere(boundingSphere, {
duration: 3,
offset: new Cesium.HeadingPitchRange(
Cesium.Math.toRadians(45),
Cesium.Math.toRadians(-30),
0
)
});
参数说明
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
boundingSphere | BoundingSphere | 包围球 | 必填 |
options.duration | number | 飞行时间(秒) | 自动计算 |
options.offset | HeadingPitchRange | 观察偏移量 | 自动计算 |
options.complete | function | 完成回调函数 | undefined |
options.cancel | function | 取消回调函数 | undefined |
options.maximumHeight | number | 最大飞行高度 | 自动计算 |
options.pitchAdjustHeight | number | 避免穿地高度 | 0 |
options.easingFunction | function | 缓动函数 | EasingFunction.LINEAR_NONE |
注意事项
-
此方法会动画飞行到包围球,提供平滑的过渡效果
-
包围球可以通过实体的
boundingSphere属性获取,但注意实体必须已加载 -
对于瓦片集,需要在
readyPromise解析后才能获取正确的包围球 -
使用偏移量可以调整观察角度和距离
-
飞行时间(duration)和最大高度(maximumHeight)可以控制飞行的速度和高度
-
如果包围球无效或未定义,可能会抛出错误
-
此方法特别适合展示大型3D模型或建筑群
11. 综合示例:实体跟踪与包围球结合使用
javascript
// 创建移动实体(如车辆)
const vehicle = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.39, 39.9, 0),
model: {
uri: 'models/vehicle.gltf',
scale: 1.0
},
orientation: new Cesium.VelocityOrientationProperty(position) // 根据速度方向自动旋转
});
// 设置跟踪偏移量(第三人称视角)
vehicle.viewFrom = new Cesium.Cartesian3(-20.0, -10.0, 15.0);
// 开始跟踪
viewer.trackedEntity = vehicle;
// 模拟车辆移动
let longitude = 116.39;
setInterval(() => {
longitude += 0.001; // 向东移动
vehicle.position = Cesium.Cartesian3.fromDegrees(longitude, 39.9, 0);
}, 100);
// 飞行到车辆的全览视图
document.getElementById('overview-btn').addEventListener('click', function() {
// 暂停跟踪
const wasTracking = viewer.trackedEntity;
viewer.trackedEntity = undefined;
// 飞行到包围球
viewer.camera.flyToBoundingSphere(vehicle.boundingSphere, {
duration: 2,
offset: new Cesium.HeadingPitchRange(0, -Math.PI/4, vehicle.boundingSphere.radius * 2.5),
complete: function() {
// 飞行完成后恢复跟踪
if (wasTracking) {
viewer.trackedEntity = vehicle;
}
}
});
});
12. 瓦片集(3D Tile的特殊处理
// 加载3D瓦片集
const tileset = await Cesium.Cesium3DTileset.fromUrl('tilesets/building/tileset.json');
viewer.scene.primitives.add(tileset);
// 等待瓦片集加载完成
tileset.readyPromise.then(function(tileset) {
// 获取瓦片集的包围球
const boundingSphere = tileset.boundingSphere;
// 飞行到瓦片集
viewer.camera.flyToBoundingSphere(boundingSphere, {
duration: 4,
offset: new Cesium.HeadingPitchRange(
Cesium.Math.toRadians(0), // 正北方向
Cesium.Math.toRadians(-45), // 45度俯角
boundingSphere.radius * 1.5 // 距离为半径的1.5倍
)
});
// 或者立即查看瓦片集
// viewer.camera.viewBoundingSphere(boundingSphere);
});
// 处理瓦片集的可见性
tileset.style = new Cesium.Cesium3DTileStyle({
color: {
conditions: [
["${Height} >= 300", "rgba(45, 0, 75, 0.5)"],
["${Height} >= 200", "rgb(102, 71, 151)"],
["${Height} >= 100", "rgb(170, 162, 204)"],
["${Height} >= 50", "rgb(224, 226, 238)"],
["${Height} >= 25", "rgb(252, 230, 200)"],
["${Height} >= 10", "rgb(248, 176, 87)"],
["${Height} >= 5", "rgb(198, 106, 11)"],
["true", "rgb(127, 59, 8)"]
]
}
});
13. 注意事项与最佳实践
-
性能考虑:
-
对于大型瓦片集,使用
flyToBoundingSphere而不是viewBoundingSphere可以提供更好的用户体验 -
在移动设备上,减少飞行时间和复杂度
-
-
错误处理:
javascript
-
try { viewer.camera.viewBoundingSphere(boundingSphere); } catch (e) { console.error("无法查看包围球:", e); // 回退到默认视角 viewer.camera.setView({ destination: Cesium.Cartesian3.fromDegrees(116.39, 39.9, 10000) }); } -
内存管理:
-
当不再需要跟踪实体时,及时设置
viewer.trackedEntity = undefined -
对于大型瓦片集,使用适当的细节层次(LOD)设置
-
-
用户体验:
-
提供视觉反馈,如加载指示器
-
允许用户取消飞行操作
-
提供返回上一视图的功能
-
-
移动端适配:
// 检测移动设备 const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); // 调整飞行参数 viewer.camera.flyToBoundingSphere(boundingSphere, { duration: isMobile ? 2 : 4, // 移动端飞行时间更短 maximumHeight: isMobile ? 5000 : 10000 // 移动端最大高度更低 });
通用注意事项
-
坐标系转换:
-
使用
Cesium.Cartesian3.fromDegrees(lon, lat, height)转换经纬度为三维坐标 -
使用
Cesium.Cartographic.fromCartesian(cartesian)转换三维坐标为经纬度
-
-
性能优化:
-
飞行到大量实体时,优先使用
viewer.flyTo(DataSource) -
复杂场景中设置 flyTo 的 maximumHeight 避免俯冲穿模
-
避免频繁调用视角切换方法
-
-
地形交互:
-
开启地形时 (
viewer.terrainProvider = Cesium.createWorldTerrain()) -
相机高度会自动调整到地形上方
-
使用
pitchAdjustHeight调整避免穿地
-
-
移动端适配:
-
减少飞行时间(duration: 3)
-
简化路径和动画
-
禁用不必要的相机操作
-
-
动画冲突处理:
javascript
-
viewer.camera.flyTo({ // 参数... complete: () => { // 第一个飞行完成后执行第二个飞行 viewer.camera.flyTo({ // 第二个飞行参数... }); } }); -
方向参数参考:
-
Heading:0 表示正北,π/2 为正东(弧度制)
-
Pitch:0 表示水平,-π/2 表示垂直向下
-
Roll:0 表示水平,通常不需要调整
-
这些API和方法提供了Cesium中视角切换的全面控制,根据具体场景选择合适的方法和参数组合,可以创建出流畅、自然的3D场景导航体验。
3024

被折叠的 条评论
为什么被折叠?



