import { PUBLIC_URL, Cesium, wutu3d } from '@/global'; import { Cartesian3_to_WGS84, viewerflyToLonLat } from './utils'; import * as R from 'ramda'; /** * 带轨迹移动对象 * @namespace TrackLineWithModel */ export class TrackLineWithModel { constructor(map, option) { this.map = map; /** * 三维对象 * @memberof TrackLineWithModel */ this.viewer = map.viewer; /** * 初始化选项 * @memberof TrackLineWithModel */ this.option = R.merge( { type: '', scale: 0.1, // 模型比例 minimumPixelSize: 20, // 像素大小 points: [], // 轨迹 Array [{}] // uri: `http://106.12.93.244/data/models/gltf/qiche.gltf`, // model: "./models/dry_garbage_truck.glb", model: './models/qiche.gltf', }, option || {} ); /** * 类型 * @memberof TrackLineWithModel */ this.type = this.option.type; /** * 状态 * @desc playing 行驶中,stop 休息中 * @memberof TrackLineWithModel */ this.status = 'stop'; /** * 实例对象 * @memberof TrackLineWithModel */ this.entity = null; /** * 唯一ID * @memberof TrackLineWithModel */ this.id = Cesium.createGuid(); /** * 飞行路线 * @memberof TrackLineWithModel */ this.flyLine = null; } setFlyLine(option) { if (this.flyLine) { this.flyLine.destroy(); } let _option = R.mergeRight( { mode: '', followedZ: 500, followedX: 0, speed: 40, wave: { size: 50, duration: 8000, color: '#05FAFC', gradient: 0.1, count: 2, }, path: { color: '#07FFFF', width: 3, opacity: 0.5, }, }, option || {} ); const pathOption = _option.path; this.flyLine = new wutu3d.FlyLine(this.viewer, { id: this.id, name: this.id, interpolation: false, clockLoop: true, // dy 第一视角, gs 跟随, "" 为空 camera: { type: _option.mode, followedX: _option.followedX, followedZ: _option.followedZ, }, points: this.option.points, speed: _option.speed, model: { show: true, uri: this.option.model, scale: this.option.scale, minimumPixelSize: this.option.minimumPixelSize, }, path: { show: true, isAll: false, ...pathOption }, }); this.addEffect(_option.wave); this.flyLine.start(); this.addWheelEvent(); } switchEye({ type, followedX, followedZ }) { const flyLine = this.flyLine; if (!flyLine) return; flyLine.options.camera.type = type; flyLine.options.camera.followedX = followedX; flyLine.options.camera.followedZ = followedZ; this.addWheelEvent(); } getCurrentPosition() { if (this.flyLine) { return this.flyLine.position.clone(); } if (this && this.entity) { return this.entity.position._value; } return new Cesium.Cartesian3(); } addEffect(option) { if (this._effect && this.viewer.entities.contains(this._effect)) { this.viewer.entities.remove(this._effect); this._effect = null; } this._effect = this.viewer.entities.add({ position: new Cesium.CallbackProperty( this.getCurrentPosition.bind(this), false ), ellipse: { height: 0.0, semiMinorAxis: option.size, semiMajorAxis: option.size, material: new wutu3d.CircleWaveMaterial({ duration: option.duration, color: option.color ? Cesium.Color.fromCssColorString(option.color) : Cesium.Color.AQUA, gradient: option.gradient, count: option.count, }), }, show: true, }); } /** * 更新飞行路线对象 * @param {Object} option * @return {this} */ updateFlyLine(option) { this.flyLine.updateStyle(option); return this; } /** * 注销 */ destroy() { if (this._effect) { this.viewer.entities.remove(this._effect); this._effect = null; } this.clear(); if (this.entity && this.entity.parent) { this.entity.parent.remove(this.entity); this.entity = null; } } clear() { if (this.flyLine) { this.flyLine.stop(); this.flyLine.destroy(); this.flyLine = null; } } _updatePosition() {} /** * 获取位置 * @return {Cesium.Cartesian3} */ getPosition() { return Cesium.clone( this.entity ? this.entity.position : this.flyLine.position ); } /** * 设置位置 * @param {Cesium.Cartesian3} position * @return this */ setPosition(position) { position && position instanceof Cesium.Cartesian3 && this.entity && this.entity.position.setValue(Cesium.clone(position)); return this; } /** * 添加到数据源中 * @param {Cesium.DataSource} dataSource * @return dataSource */ addToCollection(dataSource) { if (dataSource instanceof Cesium.DataSource) { if (this.entity && dataSource.entities.contains(this.entity)) { dataSource.entities.remove(this.entity); } this.entity = dataSource.entities.add({ id: this.id, position: new Cesium.Cartesian3(), }); } return this.entity; } /** * 设置属性 * @param {Object} props * @return {TrackLineWithModel} */ setProperties(props) { const entity = this.getEntity(); if (!props || !entity) return this; for (const key in props) { const target = entity.properties.hasProperty(key); if (target) { entity.properties.removeProperty(key); } entity.properties.addProperty(key, props[key]); } return this; } /** * 获取属性 * @param {String} key */ getProperty(key) { const entity = this.getEntity(); return entity && entity.properties[key]; } /** * 获取模型配置 */ getModel() { return Cesium.Model.fromGltf({ url: `./models/dry_garbage_truck.glb`, }); } /** * 设置模型 */ setModel() { const entity = this.getEntity(); if (!entity) return; } getEntity() { return this.entity; } focus() { if (this.entity) { const pos = Cartesian3_to_WGS84(this.entity.position._value); viewerflyToLonLat(this.viewer, pos.x, pos.y, 1000, 0, -30); } } /** * 驾驶作业状态 * @param {Function} callback * @return {this} */ play(callback) { this.status = 'playing'; this.flyLine.start(callback); return this; } /** * 休息状态 * @return {this} */ stop() { this.status = 'stop'; this.flyLine.stop(); return this; } /** * 排队状态 * @return {this} */ inline() { this.status = 'inline'; this.flyLine.stop(); return this; } removeWheelEvent() { if (this.wheelHandler) { this.wheelHandler.removeInputAction(Cesium.ScreenSpaceEventType.WHEEL); } } addWheelEvent() { if (!this.viewer) return; this.removeWheelEvent(); this.wheelHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas); const { flyLine } = this; this.wheelHandler.setInputAction(event => { if (event < 0 && flyLine.options.camera.followedZ < 100) return; flyLine.options.camera.followedZ += event > 0 ? 50 : -50; }, Cesium.ScreenSpaceEventType.WHEEL); } }