gisthreemap
Version:
基于webGL的三维api
271 lines (238 loc) • 8.91 kB
JavaScript
class TrackedAnimate {
constructor(viewer, sourcename, cb) {
this.viewer = viewer;
this.cb = cb;
this.sourcename = sourcename;
// 时钟设置为循环
this.viewer.clock.clockRange = Cesium.ClockRange['LOOP_STOP'];
//自定义事件对象
this.viewer.clock.onStop.addEventListener(() => {
this.endRoam()
})
}
// 当传入mytiemobj(自定义时间时,速度参数失效)
startRoam(positions, speed, mytiemobj, additional) {
let newPositions = positions.map(item => {
return Cesium.Cartesian3.fromDegrees(item[0], item[1], item[2]);
});
this.addRoamLine(newPositions, speed, mytiemobj, additional);
}
//添加漫游路线
addRoamLine(positions, speed, mytiemobj, additional) {
this.endRoam();
let timeObj = null;
if (mytiemobj) {
timeObj = mytiemobj
} else {
timeObj = this.getSiteTimes(positions, speed);
}
let startTime = Cesium.JulianDate.fromDate(new Date());
let stopTime = Cesium.JulianDate.addSeconds(
startTime,
timeObj.timeSum,
new Cesium.JulianDate()
);
// let stopTime = Cesium.JulianDate.fromDate(new Date('2022-09-15 10:21:50'));
console.log(startTime, stopTime)
this.viewer.clock.startTime = startTime.clone();
this.viewer.clock.stopTime = stopTime.clone();
this.viewer.clock.currentTime = startTime.clone();
let property = this.getSampledPositionProperty(
positions,
startTime,
timeObj.siteTimes
);
this.addModel(startTime, stopTime, property, additional);
if (additional.Perspective) {
let { transformX, transformZ, transformY } = additional.Perspective
this.Perspective(transformX, transformZ, transformY)
}
this.viewer.trackedEntity = this.animateEntity;
console.log(timeObj.timeSum * 1000,'总时间')
// 更新相机位置(第一视角)
// 时钟设置为循环
// this.timoutId = setTimeout(e => {
// this.endRoam();
// }, timeObj.timeSum * 1000);
}
addModel(startTime, stopTime, property, additional = {
model: {
show: true,
uri: 'model/Cesium_Man.glb',
scale: 10,
color: null,
minimumPixelSize: 60,
maximumScale: 50000,
},
path: {
resolution: 1,
width: 20,
material: Cesium.Color.RED,
}
}) {
let dataSource = null
// 获取dataSource 存在的状态
const indataSource = this.viewer.dataSources.getByName(this.sourcename)[0]
// 如果存在 先清除所有实体
if (indataSource) {
indataSource.entities.removeAll()
dataSource = indataSource
} else {
// 生成新的dataSource
dataSource = new Cesium.CustomDataSource(this.sourcename)
// dataSource添加到viewer
this.viewer.dataSources.add(dataSource)
}
// 默认显示或隐藏
// dataSource.show = true
this.animateEntity = dataSource.entities.add({
// 实体可用性,在指定时间内返回有效数据
availability: new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({
start: startTime,
stop: stopTime,
}),
]),
id: 'tracemodel',
eid: `tracemodel`,
// 位置信息随时间变化property
position: property,
// 实体方向
orientation: new Cesium.VelocityOrientationProperty(property),
// billboard: {
// image: require('../../assets/images/popbg.png'),
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
// },
model: additional.model,
// 轨迹路径
path: additional.path
})
// this.animateEntity = this.viewer.entities.add();
}
endRoam() {
//……
// 暂停
this.viewer.clock.shouldAnimate = false;
this.viewer.clock.currentTime = this.viewer.clock.startTime;
console.log('暂停')
// this.viewer.clock.tick(this.viewer.clock.startTime)
}
getSampledPositionProperty(positions, startTime, siteTimes) {
// 生成property
let property = new Cesium.SampledPositionProperty();
for (let i = 0; i < positions.length; i++) {
const time = Cesium.JulianDate.addSeconds(
startTime,
siteTimes[i],
new Cesium.JulianDate()
);
property.addSample(time, positions[i]);
}
console.log(property, 'property')
return property
}
//计算每个点位时间与总时间
getSiteTimes(positions, speed) {
let timeSum = 0;
let times = [];
for (let i = 0; i < positions.length; i++) {
if (i === 0) {
times.push(0);
continue;
}
timeSum += this.spaceDistance([positions[i - 1], positions[i]]) / speed;
times.push(timeSum);
}
return {
timeSum,
siteTimes: times,
};
}
//计算距离
spaceDistance(positions) {
let distance = 0;
for (let i = 0; i < positions.length - 1; i++) {
let point1cartographic = Cesium.Cartographic.fromCartesian(
positions[i]
);
let point2cartographic = Cesium.Cartographic.fromCartesian(
positions[i + 1]
);
/**根据经纬度计算出距离**/
let geodesic = new Cesium.EllipsoidGeodesic();
geodesic.setEndPoints(point1cartographic, point2cartographic);
let s = geodesic.surfaceDistance;
//返回两点之间的距离 如果带高度的话
s = Math.sqrt(
Math.pow(s, 2) +
Math.pow(point2cartographic.height - point1cartographic.height, 2)
);
distance = distance + s;
}
return distance.toFixed(2);
}
// 获取模型视角
getModelMatrix(entity, time, result) {
//视角变换
let matrix3Scratch = new Cesium.Matrix3();
let position = Cesium.Property.getValueOrUndefined(
entity.position,
time,
new Cesium.Cartesian3()
);
if (!Cesium.defined(position)) {
return undefined;
}
let orientation = Cesium.Property.getValueOrUndefined(
entity.orientation,
time,
new Cesium.Quaternion()
);
if (!Cesium.defined(orientation)) {
result = Cesium.Transforms.eastNorthUpToFixedFrame(
position,
undefined,
result
);
} else {
result = Cesium.Matrix4.fromRotationTranslation(
Cesium.Matrix3.fromQuaternion(orientation, matrix3Scratch),
position,
result
);
}
return result;
}
/**
*
* @param {距离运动点的距离(后方)} transformX
* @param {距离运动点的高度(上方)} transformZ
* @param {距离运动点的高度(侧方)} transformY
*/
// 视角跟随
Perspective(transformX = 10, transformZ = 1.5, transformY = 0) {
if (transformX === 0 && transformX === 0 && transformY === 0) {
return
}
let scratch = new Cesium.Matrix4();
let renderListener = (e) => {
//viewer.camera.positionCartographic.height = 2000 + $this.limitCamera(f_property);
if (this.viewer.trackedEntity) {
this.getModelMatrix(this.viewer.trackedEntity, this.viewer.clock.currentTime, scratch);
this.viewer.scene.camera.lookAtTransform(
scratch,
new Cesium.Cartesian3(-transformX, transformY, transformZ)
);
}
};
this.PerspectiveRender = this.viewer.clock.onTick.addEventListener(renderListener);
}
// 指定
// 取消视角跟随
concelPerspective() {
if (this.PerspectiveRender) {
this.PerspectiveRender.call()
}
}
}
export default TrackedAnimate