Cesium入门到精通

打造第一个Cesium应用

将node_modules\cesium\Build\Cesium中的Assets、ThirdParty、Widgets、Workers复制到public,将Widgets复制到src

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<script setup>
import * as Cesium from 'cesium'
import './Widgets/widgets.css'
import { onMounted } from 'vue'

// 设置静态资源路径
window.CESIUM_BASE_URL = '/'

onMounted(() => {
const viewer = new Cesium.Viewer('cesiumContainer', {})
})
</script>

<template>
<div id="cesiumContainer" ref="cesiumContainer"></div>
</template>

<style scoped>
* {
margin: 0;
padding: 0;
}

#cesiumContainer {
width: 100vw;
height: 100vh;
}
</style>

Cesium基础设置

设置Token

1
Cesium.Ion.defaultAccessToken = 'mytoken'

隐藏Logo

1
viewer.cesiumWidget.creditContainer.style.display = 'none'

隐藏控制台报错

1
2
3
const viewer = new Cesium.Viewer('cesiumContainer', {
infoBox: false, // 是否显示信息窗口
})

默认视角

1
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(73.66, 3.88, 135.05, 53.55)

Viewer查看器详细讲解

1
2
3
4
5
6
7
8
9
infoBox: false, // 是否显示信息窗口
geocoder: false, // 是否显示地名查找控件
homeButton: false, // 是否显示Home按钮
sceneModePicker: false, // 是否显示场景模式选择控件
baseLayerPicker: false, // 是否显示图层选择控件
navigationHelpButton: false, // 是否显示帮助信息控件
animation: false, // 是否显示动画控件
timeline: false, // 是否显示时间线控件
fullscreenButton: false, // 是否显示全屏按钮

Cesium天空盒

1
2
3
4
5
6
7
8
9
10
11
// 设置天空盒
skyBox: new Cesium.SkyBox({
sources: {
positiveX: './texture/sky/px.jpg',
negativeX: './texture/sky/nx.jpg',
positiveY: './texture/sky/ny.jpg',
negativeY: './texture/sky/py.jpg',
positiveZ: './texture/sky/pz.jpg',
negativeZ: './texture/sky/nz.jpg',
},
}),

Cesium自定义地图与地图叠加

viewer里面的各项参数

https://cesium.com/learn/ion-sdk/ref-doc/Viewer.html?classFilter=viewer

异步加载地图

https://cesium.com/learn/ion-sdk/ref-doc/global.html?classFilter=createWorldImageryAsync#createWorldImageryAsync

1
imageryProvider: await Cesium.createWorldImageryAsync(),

官方文档里的一种加载地图方法

https://cesium.com/learn/ion-sdk/ref-doc/ArcGisMapServerImageryProvider.html?classFilter=imageryprovider

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
baseLayer: new Cesium.ImageryLayer(
new Cesium.WebMapTileServiceImageryProvider({
url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=0538fcef2829bb9ab47ec5b98a56ddf6',
layer: 'img',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'GoogleMapsCompatible',
}),
),
// 天地图矢量
baseLayer: new Cesium.ImageryLayer(
new Cesium.WebMapTileServiceImageryProvider({
url: 'http://t0.tianditu.gov.cn/vec_w/wmts?tk=0538fcef2829bb9ab47ec5b98a56ddf6',
layer: 'vec',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'GoogleMapsCompatible',
}),
),
// OSM地图
baseLayer: new Cesium.ImageryLayer(
new Cesium.OpenStreetMapImageryProvider({
url: 'https://tile.openstreetmap.org/',
}),
),
// 高德地图
baseLayer: new Cesium.ImageryLayer(
new Cesium.UrlTemplateImageryProvider({
url: 'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
layer: 'amap',
style: 'default',
format: 'image/jpeg',
tileMatrixSetID: 'GoogleMapsCompatible',
}),
),

地图叠加

https://cesium.com/learn/ion-sdk/ref-doc/ImageryLayer.html?classFilter=imagery

1
2
3
4
5
6
7
8
9
10
var imageryLayers = viewer.imageryLayers
var layer = imageryLayers.addImageryProvider(
new Cesium.WebMapTileServiceImageryProvider({
url: 'http://t0.tianditu.gov.cn/vec_w/wmts?tk=0538fcef2829bb9ab47ec5b98a56ddf6',
layer: 'vec',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'GoogleMapsCompatible',
}),
)

添加地形与添加自定义地形

默认地形数据

1
2
3
4
terrainProvider: await Cesium.createWorldTerrainAsync({
requestWaterMask: true, // 加载水面
requestVertexNormals: true // 加载地形法线
}),

自定义地形需要安装cesiumlab,然后处理dem数据

1
2
3
4
5
6
7
terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl(
'./terrains/gz',
{
requestWaterMask: true, // 加载水面
requestVertexNormals: true, // 加载地形法线
}
)

坐标系与坐标系数值转换

  1. 屏幕坐标系,二维笛卡尔坐标系,Cartesian2类型
  2. 地理坐标系,WGS84坐标系,Cartographic类型,经度,纬度,高度
  3. 笛卡尔空间直角坐标系,Cartesian3类型

角度转弧度

1
const radians = Cesium.Math.toRadians(30)

弧度转角度

1
const degrees = Cesium.Math.toDegrees(2 * Math.PI)

将经纬度转换为笛卡尔坐标

1
const cartesian = Cesium.Cartesian3.fromDegrees(114.057865, 22.543094, 300)

将笛卡尔坐标转换为经纬度

1
const cartographic = Cesium.Cartographic.fromCartesian(cartesian)

相机的方向和位置

setview瞬间移动到指定位置

1
2
3
4
5
6
7
8
9
10
const tiananmen = Cesium.Cartesian3.fromDegrees(116.407395, 39.904211, 1000);
viewer.camera.setView({
destination: tiananmen
// 指定相机视角
orientation: {
heading: Cesium.Math.toRadians(0), // 相机的方位角 y轴
pitch: Cesium.Math.toRadians(-90), // 相机的俯仰角 x轴
roll: 0.0 // 相机的翻滚角 z轴
}
});
image-20250318210750237

相机动画与相机动态交互

飞到指定位置

1
2
3
4
5
6
7
8
9
viewer.camera.flyTo({
destination: tiananmen,
// 指定相机视角
orientation: {
heading: Cesium.Math.toRadians(0), // 相机的方位角 y轴
pitch: Cesium.Math.toRadians(-45), // 相机的俯仰角 x轴
roll: 0 // 相机的翻滚角 z轴
}
})

通过按键控制相机移动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
document.addEventListener('keydown', (e) => {
// console.log(e)
const height = viewer.camera.positionCartographic.height
const moveRate = height / 20
if (e.key === 'w') { // 向前移动
viewer.camera.moveForward(moveRate)
} else if (e.key === 's') { // 向后移动
viewer.camera.moveBackward(moveRate)
} else if (e.key === 'a') { // 向左移动
viewer.camera.moveLeft(moveRate)
} else if (e.key === 'd') { // 向右移动
viewer.camera.moveRight(moveRate)
} else if (e.key === 'ArrowLeft') { // 向左旋转
viewer.camera.lookLeft(Cesium.Math.toRadians(1))
} else if (e.key === 'ArrowRight') { // 向右旋转
viewer.camera.lookRight(Cesium.Math.toRadians(1))
} else if (e.key === 'ArrowUp') { // 向上旋转
viewer.camera.lookUp(Cesium.Math.toRadians(1))
} else if (e.key === 'ArrowDown') { // 向下旋转
viewer.camera.lookDown(Cesium.Math.toRadians(1))
} else if (e.key === 'q') { // 逆时针旋转
viewer.camera.twistLeft(Cesium.Math.toRadians(1))
} else if (e.key === 'e') { // 顺时针旋转
viewer.camera.twistRight(Cesium.Math.toRadians(1))
}
})

添加物体与3D建筑

https://cesium.com/learn/cesiumjs/ref-doc/Entity.html

创建一个点

1
2
3
4
5
6
7
8
9
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(113.3191, 23.108, 10),
point: {
color: Cesium.Color.RED,
pixelSize: 10,
outlineColor: Cesium.Color.YELLOW,
outlineWidth: 2,
},
})

添加3D建筑

1
viewer.scene.primitives.add(await Cesium.createOsmBuildingsAsync())

标签与广告牌

添加文字标签和广告牌

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(113.3191, 23.109, 800),
label: {
text: '广州塔',
font: '20px sans-serif',
fillColor: Cesium.Color.YELLOW,
outlineColor: Cesium.Color.RED,
outlineWidth: 2,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
pixelOffset: new Cesium.Cartesian2(0, -24), // 偏移量
horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 水平对齐方式
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 垂直对齐方式
},
billboard: {
image: './texture/gzt.png',
width: 100,
height: 100,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.TOP,
}
})

3D模型添加与设置

添加飞机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
viewer.entities.add({
name: 'Airplane',
position: Cesium.Cartesian3.fromDegrees(113.3191, 23.095, 1500),
model: {
uri: '/model/Air.glb',
minimumPixelSize: 128, // 设置飞机的最小像素大小
silhouetteSize: 5, // 设置飞机的轮廓线宽度
silhouetteColor: Cesium.Color.WHITE, // 设置飞机的轮廓线颜色
distanceDisplayCondition: new Cesium.DistanceDisplayCondition( // 设置飞机的显示条件
0,
10000
)
},
})

椭圆、走廊、圆柱体添加与设置

创建实体 https://cesium.com/learn/cesiumjs-learn/cesiumjs-creating-entities/

​ 盒子实体 https://sandcastle.cesium.com/?src=Box.html

​ 圆圈 椭圆实体 https://sandcastle.cesium.com/?src=Circles%20and%20Ellipses.html

​ 走廊实体 https://sandcastle.cesium.com/?src=Corridor.html

​ 转角类型 https://cesium.com/learn/cesiumjs/ref-doc/global.html#CornerType

​ 圆柱体 锥体 https://sandcastle.cesium.com/?src=Cylinders%20and%20Cones.html

直接定位到实体

1
2
3
viewer.zoomTo(viewer.entities);

viewer.flyTo(viewer.entities);

多边形、体积折线、矩形、椭球体设置

多边形 https://sandcastle.cesium.com/?src=Polygon.html

折线 https://sandcastle.cesium.com/?src=Polyline.html

体积折线 https://sandcastle.cesium.com/?src=Polyline%20Volume.html

矩形 https://sandcastle.cesium.com/?src=Rectangle.html

球体和椭球体 https://sandcastle.cesium.com/?src=Spheres%20and%20Ellipsoids.html

Primitive创建图像物体

使用entity创建矩形

1
2
3
4
5
6
const rectangle = viewer.entities.add({
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(116.28, 39.89, 116.48, 40.03),
material: Cesium.Color.RED.withAlpha(0.5),
},
})

使用primitive创建矩形,更底层,粒度更精细

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 01-创建几何体
let rectGeometry = new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(116.28, 40.09, 116.48, 40.23),
height: 0, // 距离表面的高度
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
})

// 02-创建实例
let rectInstance = new Cesium.GeometryInstance({
geometry: rectGeometry,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW.withAlpha(0.5)),
},
})

// 03-设置外观
let rectAppearance = new Cesium.PerInstanceColorAppearance({
flat: true,
})

// 04-图元
let rectPrimitive = new Cesium.Primitive({
geometryInstances: rectInstance,
appearance: rectAppearance,
})

// 05-添加到场景中
viewer.scene.primitives.add(rectPrimitive)

Primitive多个实体与颜色修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// 01-创建几何体
let rectGeometry = new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(116.28, 40.09, 116.48, 40.23),
height: 0, // 距离表面的高度
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
})

let rectGeometry2 = new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(116.68, 40.09, 116.88, 40.23),
height: 0, // 距离表面的高度
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
})

// 02-创建实例
let rectInstance = new Cesium.GeometryInstance({
id: 'rect1',
geometry: rectGeometry,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW.withAlpha(0.5)),
},
})

let rectInstance2 = new Cesium.GeometryInstance({
id: 'rect2',
geometry: rectGeometry2,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE.withAlpha(0.5)),
},
})

// 03-设置外观
let rectAppearance = new Cesium.PerInstanceColorAppearance({
flat: true,
})

// 04-图元
let rectPrimitive = new Cesium.Primitive({
geometryInstances: [rectInstance, rectInstance2],
appearance: rectAppearance,
})

// 05-添加到场景中
viewer.scene.primitives.add(rectPrimitive)

// 动态修改图元颜色
// setTimeout(() => {
// let attributes = rectPrimitive.getGeometryInstanceAttributes('rect1')
// attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(
// Cesium.Color.GREEN.withAlpha(0.5),
// )
// }, 5000)

setInterval(() => {
let attributes = rectPrimitive.getGeometryInstanceAttributes('rect1')
attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(
Cesium.Color.fromRandom({
alpha: 0.5,
}),
)
}, 1000)

与Entity和Primitive物体交互