UNPKG

gisthreemap

Version:

基于webGL的三维api

271 lines (238 loc) 8.91 kB
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