新建文件
- 新建文件
- 复制初始化模板
- 准备资源,将资源放置在assets文件下 温馨小贴士: 在代码中记得更改所需资源的路径,需要更改两次
创建DataSource
- Cesium的DataSource是用于加载和处理地理数据的接口
- 允许将各种类型的数据加载到Cesium中,包括地理信息系统(GIS)数据、传感器数据、地形数据等。
- DataSource提供了一种统一的方式来处理不同类型的数据。支持各种常见的地理数据格式,如GeoJSON、KML、GPX等。可以使用DataSource来加载这些数据
- DataSource还提供了一些功能,例如数据过滤、数据聚合、数据样式设置等。可以使用这些功能来处理和展示加载的数据
- Cesium的DataSource是一个用于加载、处理和展示各种类型地理数据的接口,能够方便地将不同格式的数据加载到Cesium中
//创建DataSource
var datasource = new Cesium.CustomDataSource("enetiestestdata");
viewer.dataSources.add(datasource)
制作线实体数组(路径的点集)
- 这一步是在代码中编写路径数据,在实际开发中,路径数据多为从数据库读取(地理信息服务公交车)或加载静态资源(kk园区.json文件)
var lujingdata = [[117.4603186710001, 31.14388249900003, 11.147400000001653],
[117.45946237800001, 31.143739847000063, 11.108399999997346],
[117.45859906800001, 31.143571198000075, 10.89079999999376],
[117.45789337300005, 31.143422075000046, 11.12170000000333],
[117.4571119630001, 31.143350937000037, 11.545700000002398],
[117.45620292500007, 31.143325030000028, 11.529899999994086],
[117.45545284400009, 31.143363754000063, 11.038100000005215],
[117.45473256600008, 31.143448056000068, 10.86380000000645],
[117.45399052200003, 31.143623321000064, 11.345600000000559],
[117.45347615200001, 31.14381135600007, 11.687300000005052],
[117.45292459000007, 31.144031608000034, 12.106100000004517],
[117.45192097000006, 31.144426226000064, 12.842399999994086],
[117.45065835500009, 31.144954275000032, 12.712299999999232],
[117.44980033200011, 31.145266268000057, 12.504899999999907],
[117.44943370300007, 31.145413392000023, 12.731599999999162],
[117.44920128900003, 31.145382554000037, 12.967699999993783],
[117.44897692800009, 31.144980649000047, 14.909599999999045],
[117.44872415000009, 31.14449598400006, 14.55899999999383],
[117.44851592000009, 31.144125416000065, 14.410999999992782],
[117.44848024700002, 31.14392828000007, 14.475800000000163],
[117.44948683700011, 31.14350793500006, 14.507400000002235],
[117.45089297600009, 31.142959855000072, 14.290399999998044],
[117.45149371900004, 31.142693826000027, 14.127099999997881],
[117.45166848000008, 31.142571364000048, 15.52610000000277],
[117.4516358520001, 31.142433625000024, 14.0341000000044],
[117.45082070700005, 31.140899211000033, 13.289099999994505],
[117.45082070700005, 31.140899211000033, 13.289099999994505]]
加载线
- 使用线实体表示路径
//添加线
datasource.entities.add({
name: "line",
polyline: {
positions: Cesium.Cartesian3.fromDegreesArrayHeights(lujingdata.flat()),
material: Cesium.Color.RED,
width: 1
}
})
创建了SampledPositionProperty 对象
- Cesium的SampledPositionProperty对象是一种用于表示实体在时间上变化位置的属性对象。
- 是一种时间动态的属性,可以用于将实体的位置随时间进行插值,并在三维地球上进行动画演示。
- SampledPositionProperty对象可以用于表示实体的连续运动轨迹,通过在不同的时间点上添加位置和时间信息,可以创建一个时间序列,描述实体在不同时间点上的位置。这些位置点可以通过插值方法来计算并在动画中平滑地过渡。
- SampledPositionProperty对象可以用于表示多种实体,如飞机、车辆、船只等在时间上的位置变化。通过设置不同的时间点和位置,可以实现对实体运动轨迹的精确控制和动画展示。
var property = new Cesium.SampledPositionProperty();
// 创建一个Date对象并将其赋值给变量starttime,用于记录开始时间。
var starttime = new Date();
var stoptime;
// 通过调用starttime.getTime()获取开始时间的毫秒表示,并将其赋值给变量timestamp。
var timestamp = starttime.getTime();
// 对lujingdata数组中的每个元素执行回调函数。该回调函数接收当前元素的值和索引作为参数。
lujingdata.forEach((pos, index) => {
//在循环体内部,创建一个新的Date对象,并将timestamp与index乘以5000相加,得到一个新的时间值。将该时间值赋值给变量time。
var time = new Date(timestamp + index * 5000);
//更新stoptime的值为当前的time。
stoptime = time;
//根据pos数组中的经纬度和高度值,创建一个Cartesian3对象,并将其赋值给变量position。
var position = Cesium.Cartesian3.fromDegrees(pos[0], pos[1], pos[2])
//使用Cesium.JulianDate.fromDate方法将time转换为Cesium.JulianDate对象,并将该对象和position作为参数,调用property对象的addSample方法,将时间和位置样本添加到property中。
property.addSample(Cesium.JulianDate.fromDate(time), position);
})
//设置property对象的插值选项,包括插值度和插值算法。
property.setInterpolationOptions({
interpolationDegree: 0.0001,
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation
});
给数据源的 entities 属性添加实体对象
- 给数据源的 entities 属性添加了一个包含路径、标签以及位置的实体对象。
//1.使用datasource.entities.add()方法向数据源中添加实体,并传入一个包含实体属性的对象。
var entitydd = datasource.entities.add({
//2.实体的availability属性指定了实体的可视时间段。
availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
start: Cesium.JulianDate.fromDate(starttime),
stop: Cesium.JulianDate.fromDate(new Date(stoptime))
})]),
position: property,
// 3.实体的billboard属性指定了实体的图标属性
billboard: {
image: "./assets/yingjiwuzi.png",
scale: 0.5,
pixelOffset: new Cesium.Cartesian2(0, -120),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
clampToGround: true
},
// 4.实体的path属性指定了实体的路径属性。
path: {
leadTime: 0,
resolution: 1,
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.1,
color: Cesium.Color.GREEN
}),
width: 10
}
});
- 注释2处:实体的availability属性指定了实体的可视时间段。这里使用了一个Cesium.TimeIntervalCollection对象,它包含了一个Cesium.TimeInterval对象。Cesium.TimeInterval对象通过Cesium.JulianDate.fromDate()方法将起始时间(starttime)和结束时间(stoptime)转换为Cesium的时间格式。
- 注释3处:使用了一个图片路径(”./assets/yingjiwuzi.png”)作为图标的image属性,设置了图标的缩放比例(scale为0.5),设置了图标在屏幕上的偏移位置(pixelOffset为一个Cartesian2对象,表示在x和y方向上的偏移量),设置了图标在地面上的高度参考(heightReference为Cesium.HeightReference.CLAMP_TO_GROUND,表示图标的高度参考为地面),设置了图标是否贴地显示(clampToGround为true)。
- 注释4处:设置了路径的提前时间(leadTime为0,表示路径的起点与实体的当前位置一致),设置了路径的分辨率(resolution为1,表示路径上的点之间的距离为1米),设置了路径的材质(material为一个PolylineGlowMaterialProperty对象,表示路径的材质为一个发光的线材质,颜色为绿色),设置了路径的宽度(width为10,表示路径的宽度为10像素)。
设置动画
viewer.clock.currentTime = Cesium.JulianDate.fromDate(starttime);
viewer.clock.stopTime = Cesium.JulianDate.fromDate(new Date(stoptime));
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP,
viewer.clock.shouldAnimate = true;
viewer.zoomTo(datasource);
- 第一行:将地图的当前时间设置为
starttime
参数所指定的时间。starttime
可以是一个JavaScript的Date
对象或者是一个表示时间的字符串。Cesium.JulianDate.fromDate()
方法将时间转换为Cesium支持的JulianDate
格式。 - 第二行:将地图的停止时间设置为
stoptime
参数所指定的时间。stoptime
参数的格式与starttime
相同。 - 第三行:设置地图时钟的范围为
Cesium.ClockRange.LOOP_STOP
。当地图时间超过停止时间时,时钟会重新从开始时间开始循环。 - 第四行:设置地图时钟是否应该自动播放。当设置为
true
时,地图会根据时间范围和速率自动更新地图视图。 - 第五行:将地图视图定位到指定的数据源。
datasource
参数是一个Cesium的数据源对象,可以是一个Cesium的Entity
对象或者是一个DataSource
对象。使地图自动调整视图以适应数据源的范围。
效果
加载模型
- 使用下列代码替换 “给数据源的 entities 属性添加实体对象” 部分的代码
var entitydd = datasource.entities.add({
availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
start: Cesium.JulianDate.fromDate(starttime),
stop: Cesium.JulianDate.fromDate(new Date(stoptime))
})]),
position: property, // 点集
//朝向
orientation: new Cesium.VelocityOrientationProperty(property),
label: {
text: "",
fillColor: Cesium.Color.RED,
pixelOffset: new Cesium.Cartesian2(0, -30)
},
// 1.实体的model属性用于指定实体的3D模型。
model: {
uri: './assets/xiaofangche.gltf',
scale: 1,
minimumPixelSize: 70,
maximumScale: 70
},
path: {
leadTime: 0,
resolution: 1,
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.1,
color: Cesium.Color.GREEN
}),
width: 10
}
});
- 注释1处:模型的URI是’./assets/xiaofangche.gltf’,即gltf格式的模型文件路径。模型的缩放比例为1,最小像素大小为70,最大缩放比例为70。
模型效果
拓展
- 在末尾加上以下代码
viewer.clock.onTick.addEventListener((tick) => {
entitydd.position.getValue(tick.currentTime);
//转为经纬度
var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(entitydd.position.getValue(tick.currentTime))
cartographic.longitude = Cesium.Math.toDegrees(cartographic.longitude)
cartographic.latitude = Cesium.Math.toDegrees(cartographic.latitude)
entitydd.label.text = Number(cartographic.longitude).toFixed(4) + "," + Number(cartographic.latitude).toFixed(4);
})
- 该代码段为一个事件监听器,当时钟触发tick事件时执行代码块。
- Tick:(钟表)发出滴答声,滴答地走时。可以理解为cesium时钟对象(clock)开始起作用,即cesium中时间开始流动
- 通过
entitydd.position.getValue(tick.currentTime)
获取了一个位置值。该位置值是一个Cartesian3类型的坐标,表示三维空间中的一个点的位置。 - 通过
Cesium.Ellipsoid.WGS84.cartesianToCartographic(entitydd.position.getValue(tick.currentTime))
将该位置值转换为地理坐标系中的经纬度。具体来说,使用WGS84椭球体将Cartesian3坐标转换为Cartographic类型,该类型包含了经度、纬度和高度信息。 - 将经度和纬度由弧度转换为度数,并将其四舍五入保留四位小数。
- 将转换后的经纬度作为文本赋值给
entitydd.label.text
属性,该属性表示了一个实体的标签文本
效果
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>cesium模板</title>
<style>
* {
padding: 0;
margin: 0;
}
#cesium-container {
width: 100vw;
height: 100vh;
overflow: hidden;
}
</style>
<link rel="stylesheet" type="text/css" href="./Cesium/Widgets/widgets.css">
<script type="text/javascript" src="./Cesium/Cesium.js"></script>
</head>
<body>
<div id="cesium-container"></div>
</body>
<script>
// 请自己去cesium官网注册申请一个token替换
Cesium.Ion.defaultAccessToken =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0ZmJmOGExOC1kMGZjLTRhNmMtYjgyZS04MDU2NDcxMTI2N2IiLCJpZCI6MTY2ODYsImlhdCI6MTY1OTk3MjU2MH0.YacXSjuuxfg6sO8lrcmnMYPyYDuslJ98xiumwnhUh58";
const viewer = new Cesium.Viewer("cesium-container", {
selectionIndicator: false,
animation: false,
baseLayerPicker: false,
timeline: false,
sceneModePicker: true,
navigationHelpButton: false,
useDefaultRenderLoop: true,
showRenderLoopErrors: true,
fullscreenButton: false,
infoBox: false,
imageryProvider: new Cesium.UrlTemplateImageryProvider({
url: " http://webrd01.is.autonavi.com/appmaptile?&scale=1&lang=zh_cn&style=8&x={x}&y={y}&z={z}",
})
});
//创建DataSource
var datasource = new Cesium.CustomDataSource("enetiestestdata");
viewer.dataSources.add(datasource)
var lujingdata = [[117.4603186710001, 31.14388249900003, 11.147400000001653],
[117.45946237800001, 31.143739847000063, 11.108399999997346],
[117.45859906800001, 31.143571198000075, 10.89079999999376],
[117.45789337300005, 31.143422075000046, 11.12170000000333],
[117.4571119630001, 31.143350937000037, 11.545700000002398],
[117.45620292500007, 31.143325030000028, 11.529899999994086],
[117.45545284400009, 31.143363754000063, 11.038100000005215],
[117.45473256600008, 31.143448056000068, 10.86380000000645],
[117.45399052200003, 31.143623321000064, 11.345600000000559],
[117.45347615200001, 31.14381135600007, 11.687300000005052],
[117.45292459000007, 31.144031608000034, 12.106100000004517],
[117.45192097000006, 31.144426226000064, 12.842399999994086],
[117.45065835500009, 31.144954275000032, 12.712299999999232],
[117.44980033200011, 31.145266268000057, 12.504899999999907],
[117.44943370300007, 31.145413392000023, 12.731599999999162],
[117.44920128900003, 31.145382554000037, 12.967699999993783],
[117.44897692800009, 31.144980649000047, 14.909599999999045],
[117.44872415000009, 31.14449598400006, 14.55899999999383],
[117.44851592000009, 31.144125416000065, 14.410999999992782],
[117.44848024700002, 31.14392828000007, 14.475800000000163],
[117.44948683700011, 31.14350793500006, 14.507400000002235],
[117.45089297600009, 31.142959855000072, 14.290399999998044],
[117.45149371900004, 31.142693826000027, 14.127099999997881],
[117.45166848000008, 31.142571364000048, 15.52610000000277],
[117.4516358520001, 31.142433625000024, 14.0341000000044],
[117.45082070700005, 31.140899211000033, 13.289099999994505],
[117.45082070700005, 31.140899211000033, 13.289099999994505]]
//添加线
datasource.entities.add({
name: "line",
polyline: {
positions: Cesium.Cartesian3.fromDegreesArrayHeights(lujingdata.flat()),
material: Cesium.Color.RED,
width: 1
}
})
var property = new Cesium.SampledPositionProperty();
var starttime = new Date();
var stoptime;
var timestamp = starttime.getTime();
lujingdata.forEach((pos, index) => {
var time = new Date(timestamp + index * 5000);
stoptime = time;
var position = Cesium.Cartesian3.fromDegrees(pos[0], pos[1], pos[2])
property.addSample(Cesium.JulianDate.fromDate(time), position);
})
property.setInterpolationOptions({
interpolationDegree: 0.0001,
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation
});
// var entitydd = datasource.entities.add({
// availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
// start: Cesium.JulianDate.fromDate(starttime),
// stop: Cesium.JulianDate.fromDate(new Date(stoptime))
// })]),
// position: property, // 点集
// billboard: {
// image: "./assets/yingjiwuzi.png",
// scale: 0.5,
// pixelOffset: new Cesium.Cartesian2(0, -120),
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
// clampToGround: true //是否贴地
// },
// path: {
// leadTime: 0,
// resolution: 1,
// material: new Cesium.PolylineGlowMaterialProperty({
// glowPower: 0.1,
// color: Cesium.Color.GREEN
// }),
// width: 10
// }
// });
var entitydd = datasource.entities.add({
availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
start: Cesium.JulianDate.fromDate(starttime),
stop: Cesium.JulianDate.fromDate(new Date(stoptime))
})]),
position: property, // 点集
//朝向
orientation: new Cesium.VelocityOrientationProperty(property),
label: {
text: "",
fillColor: Cesium.Color.RED,
pixelOffset: new Cesium.Cartesian2(0, -30)
},
model: {
uri: './assets/xiaofangche.gltf',
scale: 1,
minimumPixelSize: 70,
maximumScale: 70
},
path: {
leadTime: 0,
resolution: 1,
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.1,
color: Cesium.Color.GREEN
}),
width: 10
}
});
viewer.clock.currentTime = Cesium.JulianDate.fromDate(starttime); //修改时间轴的当前时间
viewer.clock.stopTime = Cesium.JulianDate.fromDate(new Date(stoptime));
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP,
viewer.clock.shouldAnimate = true; //开始播放
viewer.zoomTo(datasource)
viewer.clock.onTick.addEventListener((tick) => {
entitydd.position.getValue(tick.currentTime);
//转为经纬度
var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(entitydd.position.getValue(tick.currentTime))
cartographic.longitude = Cesium.Math.toDegrees(cartographic.longitude)
cartographic.latitude = Cesium.Math.toDegrees(cartographic.latitude)
entitydd.label.text = Number(cartographic.longitude).toFixed(4) + "," + Number(cartographic. Latitude).toFixed(4);
})
</script>
</html>
视频:【cesium路径回放】
公众号:OctS