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

Entity和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物体交互

屏幕空间事件

ScreenSpaceEventHandler

Methods

destroy()

getInputAction(type, modifier) →

isDestroyed() → boolean

removeInputAction(type, modifier)

setInputAction(action, type, modifier)

屏幕空间事件类型

ScreenSpaceEventType

Name Type Description
LEFT_DOWN number Represents a mouse left button down event.
LEFT_UP number Represents a mouse left button up event.
LEFT_CLICK number Represents a mouse left click event.
LEFT_DOUBLE_CLICK number Represents a mouse left double click event.
RIGHT_DOWN number Represents a mouse left button down event.
RIGHT_UP number Represents a mouse right button up event.
RIGHT_CLICK number Represents a mouse right click event.
MIDDLE_DOWN number Represents a mouse middle button down event.
MIDDLE_UP number Represents a mouse middle button up event.
MIDDLE_CLICK number Represents a mouse middle click event.
MOUSE_MOVE number Represents a mouse move event.
WHEEL number Represents a mouse wheel event.
PINCH_START number Represents the start of a two-finger event on a touch surface.
PINCH_END number Represents the end of a two-finger event on a touch surface.
PINCH_MOVE number Represents a change of a two-finger event on a touch surface.

键盘事件

KeyboardEventModifier

Name Type Description
SHIFT number Represents the shift key being held down.
CTRL number Represents the control key being held down.
ALT number Represents the alt key being held down.

具体的交互实现 拾取

1
2
3
4
5
6
7
8
9
10
11
12
13
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
handler.setInputAction(function (movement) {
console.log('movement', movement) // 鼠标点击位置
const pickedObject = viewer.scene.pick(movement.position) // scene.pick 选中物体
console.log('pickedObject', pickedObject) // 选中物体信息
// 判断是否选中id为字符串的物体
if (Cesium.defined(pickedObject) && typeof pickedObject.id === 'string') {
let attributes = rectPrimitive.getGeometryInstanceAttributes(pickedObject.id)
attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(
Cesium.Color.YELLOW.withAlpha(0.5),
)
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)

Entity材质使用materialProperty

Entity

RectangleGraphics

MaterialProperty

创建实体下面有各种示例

Create entities

创建颜色材质

1
2
const material = new Cesium.ColorMaterialProperty(new Cesium.Color(1.0, 1.0, 1.0, 1))
console.log(material)

创建棋盘材质

1
2
3
4
5
const material = new Cesium.CheckerboardMaterialProperty({
evenColor: Cesium.Color.WHITE,
oddColor: Cesium.Color.BLACK,
repeat: new Cesium.Cartesian2(4, 4),
});

创建条纹材质

1
2
3
4
5
const material = new Cesium.StripeMaterialProperty({
evenColor: Cesium.Color.WHITE,
oddColor: Cesium.Color.BLACK,
repeat: 32,
});

创建网格材质

1
2
3
4
5
6
const material = new Cesium.GridMaterialProperty({
color: Cesium.Color.YELLOW,
cellAlpha: 0.2,
lineCount: new Cesium.Cartesian2(8, 8),
lineThickness: new Cesium.Cartesian2(2.0, 2.0),
});

Entity折线材质设置

Creating Entities – Cesium

创建折线实体

1
2
3
4
5
6
7
viewer.entities.add({
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([-75, 35, -125, 35]),
width: 5,
material: material,
},
})

创建虚线材质

1
2
3
4
const material = new Cesium.PolylineDashMaterialProperty({
color: Cesium.Color.YELLOW,
dashLength: 10,
})

创建箭头材质

1
const material = new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED)

创建发光飞线效果

1
2
3
4
5
const material = new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.1, // 发光强度
taperPower: 0.7, // 衰减强度
color: Cesium.Color.YELLOW,
})

Appearance外观与材质

Appearance

Primitive是使用的Material,Entity是使用的MaterialProperty

PerInstanceColor

使用Instance的颜色去着色

1
2
3
let rectAppearance = new Cesium.PerInstanceColorAppearance({
flat: true,
})

EllipsoidSurface

设定几何体都是与地球的椭球体平行,假定几何体与地球椭球体平行,就可以在计算大量顶点属性的时候节省内存

1
2
3
let rectAppearance = new Cesium.EllipsoidSurfaceAppearance({
material: material,
})

或者这个基类,但还是推荐上面这个

1
2
3
let rectAppearance = new Cesium.MaterialAppearance({
material: material,
})

Primitive材质类型与设置

Material

type color

  • color:RGBA 颜色对象。
1
2
3
let material = new Cesium.Material.fromType('Color', {
color: Cesium.Color.AQUA.withAlpha(0.5),
})

type image

  • image:图像路径。
  • repeat:具有 x 和 y 值的对象,用于指定重复图像的次数。
1
2
3
4
let material = new Cesium.Material.fromType('Image', {
image: './texture/logo.png',
repeat: new Cesium.Cartesian2(1, 1),
})

要注意01创建几何体时将顶点格式化改成椭球体EllipsoidSurfaceAppearance

1
2
3
4
5
let rectGeometry = new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(50.28, 1.09, 150.48, 40.23),
height: 0, // 距离表面的高度
vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
})

type diffuseMap

  • image:图像路径。
  • channels:包含 r、g、b 和 a 的任意组合的三个字符串,用于选择所需的图像通道。
  • repeat:具有 x 和 y 值的对象,用于指定重复图像的次数。
1
2
3
4
let material = new Cesium.Material.fromType('DiffuseMap', {
image: './texture/logo.png',
repeat: new Cesium.Cartesian2(1, 1),
})

type grid

  • color:整个材质的 RGB 颜色对象。
  • cellAlpha:网格线之间单元格的 Alpha 值。这将与 color.alpha 结合使用。
  • lineCount:具有 x 和 y 值的对象,分别指定列数和行数。
  • lineThickness:具有 x 和 y 值的对象,用于指定网格线的粗细(如果可用,则以像素为单位)。
  • lineOffset:具有 x 和 y 值的对象,指定网格线的偏移量(范围为 0 到 1)。
1
2
3
4
5
6
let material = new Cesium.Material.fromType('Grid', {
color: Cesium.Color.YELLOW.withAlpha(0.5),
cellAlpha: 0.2,
lineCount: new Cesium.Cartesian2(4, 4),
lineThickness: new Cesium.Cartesian2(4, 4)
})

type water

  • baseWaterColor:RGB 颜色 对象 水的基色。
  • blendColor:从水区域混合到非水区域时使用的 RGB 颜色对象。
  • specularMap:用于指示水区域的单通道纹理。
  • normalMap:水法线扰动的法线贴图。
  • frequency:控制波数的数字。
  • animationSpeed:控制水的动画速度的数字。
  • amplitude:控制水波振幅的数字。
  • specularIntensity:控制镜面反射强度的数字。
1
2
3
4
5
let material = new Cesium.Material.fromType('Water', {
baseWaterColor: Cesium.Color.GREEN,
distortion: 0.2,
normalMap: './Assets/Textures/waterNormals.jpg',
})

fabric自定义着色器设置材质

用JSON数据格式设置材质

1
2
3
4
5
6
7
8
let material = new Cesium.Material({
fabric: {
type: 'Color',
uniforms: {
color: new Cesium.Color(1.0, 1.0, 0.0, 1.0)
}
}
});
1
2
3
4
5
6
7
8
let material = new Cesium.Material({
fabric: {
type: 'Image',
uniforms: {
image: './texture/logo.png',
},
},
})

编写着色器修改材质

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let material = new Cesium.Material({
fabric: {
uniforms: {},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
// 设置材质的颜色
material.diffuse = vec3(1.0, 0.0, 0.0);
return material;
}
`,
},
})

Cesium着色器自带函数与变量

czm_getDefaultMaterial

czm_material

保存可用于照明的材质信息。由所有 czm_getMaterial 函数返回。

名字 类型 描述
diffuse vec3 向各个方向均匀散射的入射光。
specular float 沿单个方向反射的入射光的强度。
shininess float 镜面反射的清晰度。值越高,创建的镜面高光越小、越聚焦。
normal vec3 表面的法线在眼睛坐标中。它用于法线贴图等效果。默认值为曲面的未修改法线。
emission vec3 材质在所有方向上均匀发射的光。默认值为 vec3(0.0),它不发光。
alpha float 此材质的不透明度。0.0 是完全透明的;1.0 是完全不透明的。

编写着色器修改材质

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let material = new Cesium.Material({
fabric: {
uniforms: {},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
// 设置材质的颜色
material.diffuse = vec3(1.0, 0.0, 0.0);
return material;
}
`,
},
})

设置条纹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let material = new Cesium.Material({
fabric: {
uniforms: {},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
// 生成默认的基础材质
czm_material material = czm_getDefaultMaterial(materialInput);
// 设置材质的颜色
// material.diffuse = vec3(materialInput.st, 0.0);
// 设置条纹
float strength = mod(materialInput.s * 10.0, 1.0);
// 设置材质的颜色
material.diffuse = vec3(strength, 0.0, 0.0);
return material;
}
`,
},
})

GSAP动态条纹

反向就减去uTime

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
import gsap from 'gsap'

let material = new Cesium.Material({
fabric: {
uniforms: {
uTime: 0,
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
// 生成默认的基础材质
czm_material material = czm_getDefaultMaterial(materialInput);
// 设置材质的颜色
// material.diffuse = vec3(materialInput.st, 0.0);
// 设置条纹
float strength = mod((materialInput.s + uTime) * 10.0, 1.0);
// 设置材质的颜色
material.diffuse = vec3(strength, 0.0, 0.0);
return material;
}
`,
},
})

gsap.to(material.uniforms, {
uTime: 1,
duration: 2,
repeat: -1,
ease: 'linear'
})

Appearance编写着色器修改外观

编写着色器修改外观

片元着色器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let rectAppearance = new Cesium.EllipsoidSurfaceAppearance({
// material: material,
fragmentShaderSource: `
in vec3 v_positionMC;
in vec3 v_positionEC;
in vec2 v_st;

void main()
{
czm_materialInput materialInput;

out_FragColor = vec4(v_st, 1.0, 1.0);
}
`,
})

往返GSAP动态变化

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
let rectAppearance = new Cesium.EllipsoidSurfaceAppearance({
// material: material,
fragmentShaderSource: `
in vec3 v_positionMC;
in vec3 v_positionEC;
in vec2 v_st;
uniform float uTime;

void main()
{
czm_materialInput materialInput;

out_FragColor = vec4(v_st, uTime, 1.0);
}
`,
})

rectAppearance.uniforms = {
uTime: 0,
}

gsap.to(rectAppearance.uniforms, {
uTime: 1,
duration: 2,
repeat: -1,
yoyo: true,
ease: 'linear',
})

编写自定义MaterialProperty材质

重新实现MaterialProperty类

MaterialProperty

根据文档重新实现一下MaterialProperty

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
class CustomMaterialProperty {
constructor() {
this.definitionChanged = new Cesium.Event()
Cesium.Material._materialCache.addMaterial('CustomMaterial', {
fabric: {
type: 'CustomMaterial',
uniforms: {},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
// 生成默认的基础材质
czm_material material = czm_getDefaultMaterial(materialInput);
material.diffuse = vec3(materialInput.st, 1.0);
return material;
}
`,
},
})
}
getType() {
return 'CustomMaterial'
}
getValue(time, result) {
return result
}
}

let material = new CustomMaterialProperty()

设置动态变化

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
class CustomMaterialProperty {
constructor() {
this.definitionChanged = new Cesium.Event()
Cesium.Material._materialCache.addMaterial('CustomMaterial', {
fabric: {
type: 'CustomMaterial',
uniforms: {
uTime: 0,
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
// 生成默认的基础材质
czm_material material = czm_getDefaultMaterial(materialInput);
material.diffuse = vec3(materialInput.st, uTime);
return material;
}
`,
},
})
}
getType() {
return 'CustomMaterial'
}
getValue(time, result) {
let t = performance.now() / 1000 // 毫秒转秒
t = t % 1
result.uTime = t
return result
}
}

let material = new CustomMaterialProperty()

用GSAP设置动态变化

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
class CustomMaterialProperty {
constructor() {
this.definitionChanged = new Cesium.Event()
Cesium.Material._materialCache.addMaterial('CustomMaterial', {
fabric: {
type: 'CustomMaterial',
uniforms: {
uTime: 0,
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
// 生成默认的基础材质
czm_material material = czm_getDefaultMaterial(materialInput);
material.diffuse = vec3(materialInput.st, uTime);
return material;
}
`,
},
})
}
getType() {
return 'CustomMaterial'
}
getValue(time, result) {
let t = performance.now() / 1000 // 毫秒转秒
t = t % 1
result.uTime = t
return result
}
}

let material = new CustomMaterialProperty()

加载GeoJSON数据

GeoJsonDataSource

加载GeoJSON数据

1
2
3
4
5
6
7
8
9
10
11
let dataGeo = await Cesium.GeoJsonDataSource.load(
'https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json',
{
stroke: Cesium.Color.HOTPINK,
fill: Cesium.Color.PINK,
strokeWidth: 3,
markerSymbol: '?',
},
)
// 添加数据
await viewer.dataSources.add(dataGeo)

添加数据的另一种方式,.then

这样的话获取时就不加await了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let dataGeo = Cesium.GeoJsonDataSource.load(
'https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json',
{
stroke: Cesium.Color.HOTPINK,
fill: Cesium.Color.PINK,
strokeWidth: 3,
markerSymbol: '?',
},
)

dataGeo.then((data) => {
console.log(data)
viewer.dataSources.add(data)
})

自定义GeoJSON生成物体的样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dataGeo.then((data) => {
viewer.dataSources.add(data)
let entities = data.entities.values
entities.forEach((entity, i) => {
entity.polygon.material = new Cesium.ColorMaterialProperty(
Cesium.Color.fromRandom({
alpha: 1,
}),
);
entity.polygon.outline = false;
// 设置随机高度
let randomNum = parseInt(Math.random() * 10)
entity.polygon.extrudedHeight = 100000 * randomNum;
})
})

image-20250321145854737

KML数据生成3D地理标记

谷歌的标准

KmlDataSource

1
2
3
4
5
6
7
let kmlUrl = './Assets/facilities1.kml'
let kmlDataPromise = Cesium.KmlDataSource.load(kmlUrl)
console.log(kmlDataPromise)
kmlDataPromise.then((dataSource) => {
console.log(dataSource)
viewer.dataSources.add(dataSource)
})

KMZ

1
2
3
4
5
6
7
let kmlUrl = './Assets/gdpPerCapita2008.kmz'
let kmlDataPromise = Cesium.KmlDataSource.load(kmlUrl)
console.log(kmlDataPromise)
kmlDataPromise.then((dataSource) => {
console.log(dataSource)
viewer.dataSources.add(dataSource)
})