1.创建CZML数据结构
const czml=[{
id: "document",
name: "CZML",
version: "1.0",
clock: {
interval: "2022-08-04T10:00:00Z/2022-08-04T15:00:00Z", // 时间段
currentTime: "2022-08-04T10:00:00Z", // 开始时间
multiplier: 1, // 已多少倍速播放
range: "CLAMPED",
},
},
{
id: "path",
name: "path with GPS flight data",
description: "",
availability: "2022-08-04T10:00:00Z/2022-08-04T15:00:00Z", // 时间段
path: {
material: {
//轨迹颜色
polylineOutline: {
color: {
rgba: color,
},
outlineColor: {
rgba: outlineColor,
},
outlineWidth: outlineWidth,
},
},
width: width,
leadTime: 0, // 提前绘制时间
},
model: {
gltf: "模型地址",
scale: 0.1,
minimumPixelSize: 100,
},
position: {
epoch: "2022-08-04T10:00:00Z", // 该项开始绘制路径时间
cartographicDegrees: [
0,113,20,1000,//时间为秒,经度,维度,高度(米)
],//数据
},
},
]
2.添加控制并监听
// 更新播放时间
const updateCurrentTime = (index) => {
let time = new Date(Number(data[index].tms));
viewer.clockViewModel.currentTime = Cesium.JulianDate.fromDate(time);
}
// 变更播放状态
const updatePlayStatus = (state) => {
viewer.clock.canAnimate = state;
viewer.clock.shouldAnimate = state;
}
//变更倍数
const updateCurrentMultiplier = (multiplier) => {
viewer.clockViewModel.multiplier = multiplier;
}
// 监听播放状态
Cesium.knockout.getObservable(viewer.clockViewModel, 'shouldAnimate').subscribe(function(isAnimating) {
if (isAnimating) {
console.log('Cesium clock is animating.');
} else {
console.log('Cesium clock is paused.');
}
});
// 检测实时播放的时间轴
Cesium.knockout.getObservable(viewer.clockViewModel, 'currentTime').subscribe(function(clockTime) {
//设置航向角,根据返回数据设置
let cartesian3 = Cesium.Cartesian3.fromDegrees(
Number(returnData.list[playIndex].lng),
Number(returnData.list[playIndex].lat),
Number(returnData.list[playIndex].height) / 100 // 高度
);
let heading = Cesium.Math.toRadians((returnData.list[playIndex].yaw) - 90);
let pitch = Cesium.Math.toRadians(returnData.list[playIndex].pitch);
let roll = Cesium.Math.toRadians(returnData.list[playIndex].roll);
let hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
entity.orientation = Cesium.Transforms.headingPitchRollQuaternion(
cartesian3,
hpr
);
// entity.orientation
});
// 设置播放状态
// viewer.clockViewModel.shouldAnimate = true;
viewer.dataSources
.add(Cesium.CzmlDataSource.load(czml))
.then(function(ds) {
let s = ds.entities.getById("path");
viewer.trackedEntity = s; // 设置相机跟随
entity = s; //记录实例,方便改变方向角
// 设置图标执行下个点
// s.orientation = new Cesium.VelocityOrientationProperty(s.position);
// s.billboard.alignedAxis = new Cesium.VelocityVectorProperty(
// s.position,
// true
// );
});
3.在js中使用
//获取数据
axios.get(url).then(res=>{
czml[1].position.cartographicDegrees =res
updatePlayStatus(true)//改变运动状态,启动动画
})
4.以下是我在项目中封装的完整代码,通过解析后台csv文件数据得到经纬度
import axios from "axios";
const d3 = require("d3-dsv");
export function setCzmlData(viewer, config = {}) {
let {
url, // csv文件
playEvene, // 播放事件,返回播放状态
endPlay, // 结束事件,返回最后一个点
playChange, // 播放改变时间,返回当前播放点,播放点对应的数据,时间
color = [170, 255, 85, 255], // 线条颜色
width = 6, // 线条大小
outlineColor = [170, 255, 85, 255], // 边框颜色
outlineWidth = 6, // 边框大小
modelUrl = "模型地址", // 模型地址
} = config;
return new Promise((resolve, reject) => {
if (!url) {
return reject("csv文件不能为空")
}
const czml = [{
id: "document",
name: "CZML",
version: "1.0",
clock: {
interval: "2022-08-04T10:00:00Z/2022-08-04T15:00:00Z", // 时间段
currentTime: "2022-08-04T10:00:00Z", // 开始时间
multiplier: 1, // 已多少倍速播放
range: "CLAMPED",
},
},
{
id: "path",
name: "path with GPS flight data",
description: "",
availability: "2022-08-04T10:00:00Z/2022-08-04T15:00:00Z", // 时间段
path: {
material: {
polylineOutline: {
color: {
rgba: color,
},
outlineColor: {
rgba: outlineColor,
},
outlineWidth: outlineWidth,
},
},
width: width,
leadTime: 0, // 提前绘制时间
},
model: {
gltf: modelUrl,
scale: 0.1,
minimumPixelSize: 100,
},
position: {
epoch: "2022-08-04T10:00:00Z", // 该项开始绘制路径时间
cartographicDegrees: [],
},
},
];
let entity = ''
axios.get(url).then((res) => {
let index = res.data.indexOf("End") + 4;
let list = res.data.substr(index);
let data = d3.csvParse(list);
let returnData = generateData(data)
let newData = [];
let time = Number(data[0].tms);
let start = new Date(Number(data[0].tms)).toJSON().trim()
let end = new Date(Number(data[data.length - 1].tms)).toJSON().trim()
czml[0].clock.currentTime = start;
czml[0].clock.interval = `${start}/${end}`;
czml[1].availability = `${start}/${end}`;
czml[1].position.epoch = `${start}`;
for (let i = 0; i < data.length; i++) {
let item = data[i];
let item1 = returnData.list[i]
let tms = Number(item.tms) - time;
newData.push(
tms / 1000, // 时间,秒
Number(item1.lng),
Number(item1.lat),
Number(item.height) / 100 // 高度
);
}
czml[1].position.cartographicDegrees = newData;
// 更新播放时间
const updateCurrentTime = (index) => {
let time = new Date(Number(data[index].tms));
viewer.clockViewModel.currentTime = Cesium.JulianDate.fromDate(time);
}
// 变更播放状态
const updatePlayStatus = (state) => {
viewer.clock.canAnimate = state;
viewer.clock.shouldAnimate = state;
}
//变更倍数
const updateCurrentMultiplier = (multiplier) => {
viewer.clockViewModel.multiplier = multiplier;
}
let params = {
returnData,
czml,
updateCurrentTime,
updatePlayStatus,
updateCurrentMultiplier
}
resolve(params);
// 监听播放状态
Cesium.knockout.getObservable(viewer.clockViewModel, 'shouldAnimate').subscribe(function(isAnimating) {
if (isAnimating) {
console.log('Cesium clock is animating.');
} else {
console.log('Cesium clock is paused.');
}
playEvene && playEvene(isAnimating)
});
// 检测实时播放的时间轴
let playIndex = 1;
Cesium.knockout.getObservable(viewer.clockViewModel, 'currentTime').subscribe(function(clockTime) {
// 播放状态
let shouldAnimate = viewer.clockViewModel.shouldAnimate;
// 当前时间轴播放时间
let currentTime = clockTime.toString();
let tms = new Date(currentTime).getTime();
// 播放结束
if (parseInt(tms / 100) >= parseInt(Number(data[data.length - 1].tms) / 100)) {
endPlay && endPlay(data[data.length - 1], data.length - 1);
return false;
}
if (shouldAnimate) {
if (tms >= Number(data[playIndex].tms)) {
playIndex++;
}
} else {
for (let i = 0; i < data.length; i++) {
if (Number(data[i].tms) >= tms) {
playIndex = i + 1;
break;
}
}
}
// 播放监听事件
playChange && playChange(playIndex, returnData.list[playIndex], currentTime)
//设置航向角,根据返回数据设置
let cartesian3 = Cesium.Cartesian3.fromDegrees(
Number(returnData.list[playIndex].lng),
Number(returnData.list[playIndex].lat),
Number(returnData.list[playIndex].height) / 100 // 高度
);
let heading = Cesium.Math.toRadians((returnData.list[playIndex].yaw) - 90);
let pitch = Cesium.Math.toRadians(returnData.list[playIndex].pitch);
let roll = Cesium.Math.toRadians(returnData.list[playIndex].roll);
let hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
entity.orientation = Cesium.Transforms.headingPitchRollQuaternion(
cartesian3,
hpr
);
// entity.orientation
});
// 设置播放状态
// viewer.clockViewModel.shouldAnimate = true;
viewer.dataSources
.add(Cesium.CzmlDataSource.load(czml))
.then(function(ds) {
let s = ds.entities.getById("path");
viewer.trackedEntity = s; // 设置相机跟随
entity = s; //记录实例,方便改变方向角
// 设置图标执行下个点
// s.orientation = new Cesium.VelocityOrientationProperty(s.position);
// s.billboard.alignedAxis = new Cesium.VelocityVectorProperty(
// s.position,
// true
// );
});
});
})
}