代码如下
我这里使用的是vue,需要将拾取到的点传入其中,调用这个函数就可以实现模型的匀速贴地飞行。
里面代码有些冗余,自己可以修改一下。
czmlNew(){
let positions = this.$czmlActiveLocation;
let distance = []
for (let i = 0;i<positions.length-1;i++){
let dis = Cesium.Cartesian3.distance(positions[i],positions[i+1])
distance.push(dis)
}
// new Cartesian3(1216348.1632364073, -4736348.958775471, 4081284.5528982095) 所需的数据格式
let stPos = positions[0];
let endPos = positions[positions.length-1];
let times =[Cesium.JulianDate.fromDate(new Date())]
times.push(Cesium.JulianDate.addSeconds(times[0], 360, new Cesium.JulianDate()))
for(let i = 1;i<positions.length-1;i++){
let s = Cesium.JulianDate.addSeconds(times[i], 360 * (distance[i]/distance[0]), new Cesium.JulianDate())
times.push(s)
}
let stTime = times[0];
let endTime = times[times.length-1];
var start = stTime.clone();
var stop = endTime.clone();
this._viewer.clock.startTime = start.clone();
this._viewer.clock.stopTime = stop.clone();
this._viewer.clock.currentTime = start.clone();
this._viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end
this._viewer.clock.multiplier = 10;
let timeOfResolution = 6;
let oriSamples = new Cesium.SampledProperty(Cesium.Cartesian3);
oriSamples.addSamples(times, positions);
let geodesic = new Cesium.EllipsoidGeodesic( 。
stPos,
endPos
);
let lenInMeters = Math.ceil(geodesic.surfaceDistance);
let samplesNum = Math.floor(
Cesium.JulianDate.secondsDifference(endTime, stTime) / timeOfResolution
);
let sampledPositions = [];
let sampledTimes = [];
for (let i = 0; i < samplesNum + 1; i++) {
let sampleTime = Cesium.JulianDate.addSeconds(
stTime,
i * timeOfResolution,
new Cesium.JulianDate()
);
let tmpPos = oriSamples.getValue(sampleTime);
sampledPositions.push(Cesium.Cartographic.fromCartesian(tmpPos));
sampledTimes.push(sampleTime);
}
var that = this
let promise = Cesium.sampleTerrainMostDetailed(
that._viewer.terrainProvider,
sampledPositions
).then(() => {
let carPositionProperty = new Cesium.SampledPositionProperty();
for (let i = 0;i<sampledPositions.length;i++){
sampledPositions[i].height = sampledPositions[i].height + 20
}
for (let i = 0; i < samplesNum + 1; i++) {
carPositionProperty.addSample(
sampledTimes[i],
Cesium.Ellipsoid.WGS84.cartographicToCartesian(sampledPositions[i])
);
}
let isConstant = false;
let curSegmentNo = 0;
let lastSegementNo = -1;
let p2 = Cesium.Ellipsoid.WGS84.cartographicToCartesian(sampledPositions[sampledPositions.length-1]);
let curPolyline = [stPos];
this._viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(function (time, result) {
curSegmentNo = Math.floor(
Cesium.JulianDate.secondsDifference(time, stTime) / timeOfResolution
);
if (curSegmentNo !== lastSegementNo) {
let tmpP = Cesium.Ellipsoid.WGS84.cartographicToCartesian(
sampledPositions[curSegmentNo]
);
curPolyline.push(tmpP);
lastSegementNo = curSegmentNo;
}
if (curSegmentNo === samplesNum - 1) {
curSegmentNo = 0;
curPolyline = [];
console.log("cleared!");
}
return curPolyline;
}, isConstant),
clampToGround: true,
width: 5,
show: false,
material: Cesium.Color.RED,
availability: new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({
start: stTime,
stop: endTime,
}),
]),
},
});
var position = carPositionProperty;
this.flyEntity = this._viewer.entities.add({
availability: new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({
start: start,
stop: stop,
}),
]),
position: position,
orientation: new Cesium.VelocityOrientationProperty(position),
model: {
uri: this.czml.czmlModelUrl,
minimumPixelSize: 64,
maximumSize: 128,
show:true,
runAnimations: true
},
path: {
show:false,
resolution: 1,
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.1,
color: Cesium.Color.YELLOW,
}),
width: 1,
},
});
});
},
另外
之前原本想用下面这种方法,通过每一帧获取地形高度来实现模型游览的,可是没有实现,如果某位大佬有解决方法的话请不吝赐教。
this._viewer.scene.postRender.addEventListener()