在学习这个案例之前,先花一点时间了解一下什么是CZML
CZML Structure · AnalyticalGraphicsInc/czml-writer Wiki (github.com)
Cesium Language (CZML) 入门1 — CZML Structure(CZML的结构) - laixiangran - 博客园
CZML是JSON得一个子集,这意味着有效得CZML文档也是JSON文档,CZML文档包含一个JSON数组,其中数组中得每一个对象都是一个CZML数据包。
然后创建一个项目:先看一下代码
<script>
window.startup=function(Cesium){
//创建一个地图容器
const viewer = new Cesium.Viewer("cesiumContainer", {
shouldAnimate: true, });
//创建一个div
const statusDisplay = document.createElement("div");
const fuelDisplay = document.createElement("div");
const czmlPath = "../SampleData/";
let vehicleEntity;
//创建一个czmldatasource来保存多个实体
const dataSource = new Cesium.CzmlDataSource();
viewer.dataSources.add(dataSource);
//创建一个数组保存几个czml流
const partsToLoad = [
{
url: "MultipartVehicle_part1.czml",
range: [0, 1500],
requested: false,
loaded: false,
arguments
},
{
url: "MultipartVehicle_part2.czml",
range: [1500, 3000],
requested: false,
loaded: false,
},
{
url: "MultipartVehicle_part3.czml",
range: [3000, 4500],
requested: false,
loaded: false,
},
];
//处理czml文件到数据流中
function processPart(part){
part.requested=true;
//处理数据解析为实例
dataSource.process(czmlPath + part.url).then(function () {
part.loaded=true;//已经加载
});
}
//预先加载第一部分,程序写道这里已经可以看到运行得小车了
processPart(partsToLoad[0]);
}
if(typeof Cesium!=="undefined"){
window.startupCalled=true;
window.startup(Cesium);
}
</script>
这些代码已经可以加载出来一个运行得小车了。但是此时小车处于一个什么状态呢,就是处于地图上得一个点,距离我们得视觉感觉特别远,下面我们继续优化代码,将小车调整到我们得视觉课时范围内。
加上这一句代码之后,再次刷新界面,小车就直接出现在最前端了。
if (!viewer.trackedEntity) {
viewer.trackedEntity = vehicleEntity = dataSource.entities.getById(
"Vehicle"
);
}
因为我们使用得是多个part,我们做个提示显示当前用的是那个part。
//用来显示当前使用得是哪一个part
function updateStatusDisplay() {
let msg = "";
//循环判断当前part是否加载成功,已经加载得显示为loaded 没有加载得显示为not needed yet
partsToLoad.forEach(function (part) {
msg += `${part.url} - `;
if (part.loaded) {
msg += "Loaded.<br/>";
} else if (part.requested) {
msg += "Loading now...<br/>";
} else {
msg += "Not needed yet.<br/>";
}
});
//将字符串赋值给html
statusDisplay.innerHTML = msg;
}
现在得代码我们已经实现加载一个part得方法,因为我们要加载多个part。下面我们就要使用Viewer里面时钟得ontrick事件
viewer.clock.onTick.addEventListener(function(clock){
})
这个事件是一直被触发得,我们现在要给这个事件添加条件,当第一个part运行快结束得时候,加载出来第二个part
viewer.clock.onTick.addEventListener(function(clock){
//计算提供的实例之间的时间差(以秒为单位)。
const timeOffset = Cesium.JulianDate.secondsDifference(
clock.currentTime,//当前时间
clock.startTime //开始时间
);
//过滤掉使用过的part 然后加载新的part
//过滤条件
//比如第一个part得时候,因为已经请求成功 part.requested=true
partsToLoad
.filter(function (part) {
return (
!part.requested &&
timeOffset >= part.range[0] - preloadTimeInSeconds &&
timeOffset <= part.range[1]
);
})
.forEach(function (part) {
processPart(part);
});
if (vehicleEntity) {
const fuel = vehicleEntity.properties.fuel_remaining.getValue(
clock.currentTime
);
if (Cesium.defined(fuel)) {
fuelDisplay.textContent = `Fuel: ${fuel.toFixed(2)} gal`;
}
}
})
代码地址在:https://gitee.com/parrotfamily/cesium-study/tree/master/Multi-part%20CZML