import Dialog from '../../Element/Dialog'; import EventBinding from '../../Element/Dialog/eventBinding'; import { html } from "./_element"; import Base from "../index"; import MouseEvent from '../../../Event/index' import EditGltf from "../../ModelController/EditGltf"; import Controller from "../../../Controller/index"; import MouseTip from '../../../MouseTip' import LabelObject from '../LabelObject' import { setActiveViewer, CameraController, closeRotateAround } from '../../../Global/global' import { syncData, get2DView, get3DView } from '../../../Global/MultiViewportMode' import { legp } from '../../../Obj/Element/datalist'; import { getFontList, getFontFamilyName } from '../../Element/fontSelect' import { setSplitDirection, syncSplitData, setActiveId, getSdk } from '../../../Global/SplitScreen' class TrajectoryMotion extends Base { #timeoutEventObject = null #lineEdit = false #_requestAnimationFrameEventId #_requestAnimationFrameEventId2 #mouseRightevent #firstPersonViewEvent /** * @constructor * @description 轨迹运动 * @param options {object} * @param options.name {string} 名称 * @param options.speed=1 {number} 运行速度 * @param options.delay=0 {number} 运动延迟时间(毫秒) * @param options.loop=true {boolean} 循环 * @param options.height {number} 起始点高度 * @param options.ground=false {boolean} 贴地 * @param options.state=true {boolean} 模型运动 * @param options.routeDirection=true {boolean} 路径方向 * @param options.viewFollow=false {boolean} 视角跟随 * @param options.model {object} 模型参数 * @param options.model.show=true {boolean} 模型显隐 * @param options.model.url {url} 模型地址 * @param options.model.pixelSize=70 {number} 模型像素大小 * @param options.model.heading=0 {number} * @param options.model.pitch=0 {number} * @param options.model.roll=0 {number} * @param options.model.scale=1 {number} 模型比例 * @param options.model.animate {string} 模型动画 * @param options.line {object} 路径参数 * @param options.line.show=true {boolean} 路径显隐 * @param options.line.smooth=false {boolean} 路径圆滑 * @param options.line.noseToTail=false {boolean} 路径收尾相联 * @param {Array.} options.line.positions 经纬度和高度的列表,值交替 [{lon,lat,alt},...] * @param _Dialog {object} 弹框事件 * @param _Dialog.confirmCallBack {function} 弹框确认时的回调 * */ constructor(sdk, options = {}, _Dialog = {}) { super(sdk, options); this.options.name = options.name || '' this.options.show = (options.show || options.show === false) ? options.show : true this.options.speed = (options.speed || options.speed === 0) ? options.speed : 1 if (this.options.speed <= 0) { this.options.speed = 0.01 } this.options.delay = options.delay || 0 this.options.loop = options.loop || options.loop === false ? options.loop : true this.options.model = options.model = options.model || {} this.options.line = options.line = options.line || {} this.options.line.positions = options.line.positions || [] // this.options.height = (options.height || options.height === 0) ? options.height : (this.options.line.positions[0] ? this.options.line.positions[0].alt : 0) this.options.height = this.options.line.positions[0] ? this.options.line.positions[0].alt : 0 this.options.height = Number(this.options.height.toFixed(2)) this.options.line.show = options.line.show || options.line.show === false ? options.line.show : true this.options.model.show = options.model.show || options.model.show === false ? options.model.show : true this.options.model.url = options.model.url || '' this.options.model.pixelSize = options.model.pixelSize || 70 this.options.model.heading = options.model.heading || 0 this.options.model.pitch = options.model.pitch || 0 this.options.model.roll = options.model.roll || 0 this.options.model.scale = (options.model.scale || options.model.scale === 0) ? options.model.scale : 1 this.options.model.animate = options.model.animate || '无' this.options.line.smooth = options.line.smooth ? options.line.smooth : false this.options.line.noseToTail = options.line.noseToTail ? options.line.noseToTail : false this.positions_smooth = [] this.options.ground = options.ground || false this.options.state = (options.state || options.state === false) ? options.state : true this.options.routeDirection = (options.routeDirection || options.routeDirection === false) ? options.routeDirection : true this.keyPoints = [] this.realTimePositions = [] this._elms = {}; this.Dialog = _Dialog this.realTimeRouteArray = [] // this.options.firstPerson = false this.distance // this.addModel() options.label = options.label || {} this.options.label = { text: this.options.name, show: options.label.show || false, fontSize: (options.label.fontSize || options.label.fontSize === 0) ? options.label.fontSize : 20, fontFamily: options.label.fontFamily ? options.label.fontFamily : 0, color: options.label.color || '#ffffff', lineWidth: (options.label.lineWidth || options.label.lineWidth === 0) ? options.label.lineWidth : 4, pixelOffset: (options.label.pixelOffset || options.label.pixelOffset === 0) ? options.label.pixelOffset : 20, backgroundColor: options.label.backgroundColor || ['#42c6ef', '#42c6ef'], lineColor: options.label.lineColor || '#00ffff80', scaleByDistance: options.label.scaleByDistance || false, near: (options.label.near || options.label.near === 0) ? options.label.near : 2000, far: (options.label.far || options.label.far === 0) ? options.label.far : 100000, } if (this.options.line.positions.length < 2) { this._error = '最少需要两个坐标!' console.warn(this._error) window.ELEMENT && window.ELEMENT.Message({ message: this._error, type: 'warning', duration: 1500 }); } else { this.sdk.addIncetance(this.options.id, this) this.ControllerObject = new Controller(this.sdk) this._EventBinding = new EventBinding() this.options.viewFollow = false this.options.firstPersonView = false TrajectoryMotion.addLine(this) this.firstPersonView = false // this.options.viewFollowOrientation = options.viewFollowOrientation } // animateUpdate() // function animateUpdate() { // requestAnimationFrame(animateUpdate); // TWEEN.update(); // } } get type() { return 'TrajectoryMotion' } get show() { return this.options.show } set show(v) { if (typeof v === "boolean") { this.options.show = v if (this.originalOptions) { this.originalOptions.show = v } if (v) { if (this.firstPersonView) { this.model.show = false } else { this.model.show = this.modelShow } this.line.polyline.material = this.lineShow ? new Cesium.PolylineDashMaterialProperty({ color: new Cesium.Color.fromCssColorString('#00ffff'), dashLength: 20, }) : new Cesium.PolylineDashMaterialProperty({ color: new Cesium.Color.fromCssColorString('#00ffff00'), dashLength: 20, }) for (let i = 0; i < this.keyPoints.length; i++) { this.keyPoints[i].show = this.keyPointShow } if (this.realTimeRoute) { this.realTimeLine && (this.realTimeLine.show = true) } this.label && (this.label.show = this.options.label.show) } else { this.model.show = v this.realTimeLine && (this.realTimeLine.show = false) this.line.polyline.material = v ? new Cesium.PolylineDashMaterialProperty({ color: new Cesium.Color.fromCssColorString('#00ffff'), dashLength: 20, }) : new Cesium.PolylineDashMaterialProperty({ color: new Cesium.Color.fromCssColorString('#00ffff00'), dashLength: 20, }) for (let i = 0; i < this.keyPoints.length; i++) { this.keyPoints[i].show = v } this.label && (this.label.show = false) this.viewFollow = false } if (this._DialogObject && this._DialogObject.showBtn) { this._DialogObject.showBtn.checked = v } syncData(this.sdk, this.options.id) syncSplitData(this.sdk, this.options.id) } else { console.error("参数必须为boolean") } } get height() { return this.options.height } set height(v) { if (this.ground) { return } let difference = this.options.height - Number(v.toFixed(2)) this.options.height = Number(v.toFixed(2)) if (this.line) { if (this.ground) { } else { let dvalue = this.options.height - this.options.line.positions[0].alt this.line.polyline.clampToGround = false for (let i = 0; i < this.keyPoints.length; i++) { this.options.line.positions[i].alt += dvalue this.keyPoints[i].position = Cesium.Cartesian3.fromDegrees(this.options.line.positions[i].lng, this.options.line.positions[i].lat, this.options.line.positions[i].alt) } } } if (this.model && this.model.position) { let heading = this.model.heading let pitch = this.model.pitch let roll = this.model.roll if (isNaN(heading) || isNaN(pitch) || isNaN(roll)) { return } let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(this.model.position) Cesium.Matrix4.multiplyByTranslation(matrix, new Cesium.Cartesian3(0, 0, -difference), matrix) Cesium.Matrix4.getTranslation(matrix, this.model.position) Cesium.Matrix4.multiplyByMatrix3(matrix, Cesium.Matrix3.fromHeadingPitchRoll(Cesium.HeadingPitchRoll.fromDegrees(heading, pitch, roll)), this.entity.modelMatrix) // Cesium.Matrix4.multiplyByTranslation(this.model.modelMatrix, new Cesium.Cartesian3(0, 0, -difference), this.model.modelMatrix) // Cesium.Matrix4.getTranslation(this.model.modelMatrix, this.model.position) this.label && (this.label.show = this.label.show) if (this.options.label.position) { setTimeout(() => { if (this.options.label.position.alt) { this.label && (this.label.position = [this.options.label.position.lng, this.options.label.position.lat, this.options.label.position.alt]) } else { this.getClampToHeight({ lng: this.options.label.position.lng, lat: this.options.label.position.lat }).then((height) => { this.label && (this.label.position = [this.options.label.position.lng, this.options.label.position.lat, height]) }) } }, 0) } } let positions_smooth = this.renewLinePositions(this.options.line.positions) this.line.polyline.positions = positions_smooth this._elms.height && this._elms.height.forEach((item) => { item.value = Number(v.toFixed(2)) }) } get ground() { return this.options.ground } set ground(v) { this.lineEdit = false this.options.ground = v this.realTimeLine.polyline.clampToGround = v this.height = this.options.height if (this.line) { if (v) { this.line.polyline.clampToGround = true for (let i = 0; i < this.keyPoints.length; i++) { this.sdk.viewer.scene.clampToHeightMostDetailed([new Cesium.Cartesian3.fromDegrees(this.options.line.positions[i].lng, this.options.line.positions[i].lat)]).then((result) => { this.keyPoints[i].position = result[0] }) } } } setTimeout(() => { if (this.TweenAnimate && this.TweenAnimate._isPlaying) { this.setMovePositionByDistance(this.TweenAnimate._object.distance) } else { this.setMovePositionByDistance(0) } }, 200); // let _this = this // let positions = this.renewLinePositions(this.options.line.positions) // let startDistance = this.TweenAnimate._object.distance // let lineString = [] // for (let i = 0; i < positions.length; i++) { // let position = this.cartesian3Towgs84(positions[i], _this.sdk.viewer) // lineString.push([position.lng, position.lat, position.alt]) // } // let line = turf.lineString(lineString); // this.distance = turf.length(line, { units: 'kilometers' }); // setPosition(startDistance) // async function setPosition(distance) { // let start = 0; // let stop = distance; // let coordinates // let sliced = line // if (stop) { // sliced = await turf.lineSliceAlong(line, start, stop, { units: 'kilometers' }); // // _this.realTimeRouteArray = sliced+ // coordinates = [...sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1]] // } // else { // coordinates = [...line.geometry.coordinates[0]] // } // let position // let positionCamera // if (_this.ground) { // // if (viewer.terrainProvider.availability) { // // let result = await new Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, [Cesium.Cartographic.fromDegrees(coordinates[0], coordinates[1])]); // // position = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], result[0].height) // // positionCamera = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], result[0].height + 1) // // } // // else { // // position = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1]) // // positionCamera = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], 1) // // } // let filterEntitys = [] // // for (let [key, value] of _this.sdk.entityMap) { // // if (!value.type || (value.type !== 'glb' && value.type!== 'bim' && value.type!== 'tileset' && value.type!== 'TrajectoryMotion' && value.entity)) { // // console.log(value.entity) // // filterEntitys.push(value.entity.id) // // } // // } // // console.log('8888888888',_this.model, ...filterEntitys) // let result // let sdk2D = get2DView() // if (sdk2D && _this.sdk == sdk2D) { // result = new Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1]) // position = result // } // else { // result = await _this.sdk.viewer.scene.clampToHeight(new Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1]), [_this.model, ...filterEntitys]) // position = result // } // if (!result) { // position = new Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1]) // } // let pos3 = _this.cartesian3Towgs84(position, _this.sdk.viewer); // let height2 = 0 // try { // let position2 = await Cesium.sampleTerrainMostDetailed( // _this.sdk.viewer.scene.terrainProvider, // [Cesium.Cartographic.fromDegrees(pos3.lng, pos3.lat)] // ) // height2 = position2[0].height // } catch (error) { // height2 = 0 // } // if (pos3.alt < height2) { // pos3.alt = height2 // } // pos3.alt = Number(pos3.alt.toFixed(1)) // position = Cesium.Cartesian3.fromDegrees(pos3.lng, pos3.lat, pos3.alt) // positionCamera = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], _this.cartesian3Towgs84(position, _this.sdk.viewer).alt + 1.8) // let fromDegreesArray = [] // for (let i = 0; i < sliced.geometry.coordinates.length; i++) { // fromDegreesArray.push(sliced.geometry.coordinates[i][0], sliced.geometry.coordinates[i][1]) // } // _this.realTimePositions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray) // // _this.realTimeLine.polyline.positions = // } // else { // let cartesian3 = _this.spline.evaluate(distance / _this.distance) // if (!cartesian3) { // return // } // coordinates = _this.cartesian3Towgs84(cartesian3, _this.sdk.viewer); // position = cartesian3 // positionCamera = Cesium.Cartesian3.fromDegrees(coordinates.lng, coordinates.lat, coordinates.alt + 1.8) // let positions_smooth = [] // for (let i = 0; i <= 1000; i++) { // if ((i / 1000) > (distance / _this.distance)) { // break // } // let cartesian3 = _this.spline.evaluate(i / 1000); // positions_smooth.push(cartesian3); // } // positions_smooth.push(cartesian3) // _this.realTimePositions = positions_smooth // } // HeadingPitchRoll = getHeadingPitchRoll(_this.model.position, position) // if (previous && previous.position) { // HeadingPitchRoll2 = getHeadingPitchRoll(previous.position, position) // HeadingPitchRoll.pitch = HeadingPitchRoll2.pitch // } // previous.position = _this.model.position // let modeHeadingPitchRoll = Cesium.HeadingPitchRoll.fromDegrees(_this.options.model.heading, _this.options.model.pitch, _this.options.model.roll) // let heading = 0 // let pitch = 0 // let roll = 0 // let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position) // if (_this.options.routeDirection && !_this.lineEdit) { // heading = (HeadingPitchRoll.heading) * (180 / Math.PI) - 90 - _this.options.model.heading // pitch = (HeadingPitchRoll.pitch) * (180 / Math.PI) - _this.options.model.pitch // roll = _this.options.model.roll // if (isNaN(heading) || isNaN(pitch) || isNaN(roll)) { // return // } // _this.model.modelMatrix = Cesium.Matrix4.multiplyByMatrix3(matrix, Cesium.Matrix3.fromHeadingPitchRoll(Cesium.HeadingPitchRoll.fromDegrees(heading, pitch, roll)), _this.model.modelMatrix) // } // else { // if (_this.entity) { // heading = _this.options.model.heading // pitch = _this.options.model.pitch // roll = _this.options.model.roll // if (isNaN(heading) || isNaN(pitch) || isNaN(roll)) { // return // } // // 旋转 // let mx = Cesium.Matrix3.fromRotationX( // Cesium.Math.toRadians(roll) // ) // let my = Cesium.Matrix3.fromRotationY( // Cesium.Math.toRadians(pitch) // ) // let mz = Cesium.Matrix3.fromRotationZ( // Cesium.Math.toRadians(heading) // ) // let rotationX = Cesium.Matrix4.fromRotationTranslation(mx) // let rotationY = Cesium.Matrix4.fromRotationTranslation(my) // let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz) // let originalMatrix = new Cesium.Matrix4() // Cesium.Matrix4.multiply(matrix, rotationX, originalMatrix) // Cesium.Matrix4.multiply(originalMatrix, rotationY, originalMatrix) // Cesium.Matrix4.multiply(originalMatrix, rotationZ, _this.entity.modelMatrix) // } // } // // console.log((HeadingPitchRoll.heading - modeHeadingPitchRoll.heading) * (180 / Math.PI)) // _this.model.position = position // if (!position) { // return // } // let labelPosition = _this.cartesian3Towgs84(position, _this.sdk.viewer) // _this.label.position = [labelPosition.lng, labelPosition.lat, labelPosition.alt] // lastDistance = distance // // console.log(position) // _this.realTimeRouteArray.push(position) // if (_this.viewFollow) { // // console.log(Cesium.Math.toDegrees(_this.sdk.viewer.camera.pitch)) // if (_this.options.firstPersonView) { // _this.sdk.viewer.camera.setView({ // destination: positionCamera, // orientation: { // heading: Cesium.Math.toRadians(heading + 90 + _this.firstPersonHeadingPitch.heading), // pitch: Cesium.Math.toRadians(_this.firstPersonHeadingPitch.pitch), // roll: 0 // } // }) // } // else { // if (_this.sdk.viewer.scene.mode === 3) { // if (_this.sdk.viewer.trackedEntity) { // _this.sdk.viewer.trackedEntity.position = position // // _this.sdk.viewer.camera.position = position // } // } // else { // if (_this.sdk.viewer.trackedEntity) { // _this.sdk.viewer.camera.setView({ // destination: Cesium.Cartesian3.fromDegrees(coordinates.lng, coordinates.lat, _this.sdk.viewer.camera.positionCartographic.height), // orientation: { // heading: Cesium.Math.toRadians(-90), // pitch: 0, // roll: 0 // } // }) // } // } // } // } // } if (v) { this._elms.heightBox && (this._elms.heightBox.className = 'input-number input-number-unit-1 height-box disabled'); } else { this._elms.heightBox && (this._elms.heightBox.className = 'input-number input-number-unit-1 height-box'); } this._elms.ground && this._elms.ground.forEach((item) => { item.checked = v }) } get modelPixelSize() { return this.options.model.pixelSize } set modelPixelSize(v) { this.options.model.pixelSize = v if (this.model) { this.model.minimumPixelSize = v } this._elms.modelPixelSize && this._elms.modelPixelSize.forEach((item) => { item.value = v }) } get scale() { return this.options.model.scale } set scale(v) { this.options.model.scale = Number(v) if (this.model) { this.model.scale = v this.model.customScale = { x: this.options.model.scale, y: this.options.model.scale, z: this.options.model.scale }; } this._elms.scale && this._elms.scale.forEach((item) => { item.value = v }) } get speed() { return this.options.speed } set speed(v) { if (v <= 0) { v = 0.01 } this.options.speed = v if (this.state && this.TweenAnimate && this.TweenAnimate._isPlaying) { this.setMovePositionByDistance(this.TweenAnimate._object.distance) } // let totalTime = (this.distance * 1000) / this.options.speed * 1000 // // this.TweenAnimate._object.distance/this.TweenAnimate._valuesEnd.distance // this.TweenAnimate._duration = totalTime this._elms.speed && this._elms.speed.forEach((item) => { item.value = v }) } get smooth() { return this.options.line.smooth } set smooth(v) { this.lineEdit = false this.options.line.smooth = v let positions = this.renewLinePositions(this.options.line.positions) this.line.polyline.positions = positions this.model.position = positions[0] this.modelMove(positions) this._elms.smooth && this._elms.smooth.forEach((item) => { item.checked = v }) } get delay() { return this.options.delay } set delay(v) { this.options.delay = v if (this.TweenAnimate && this.TweenAnimate._isPlaying) { this.TweenAnimate.delay(this.delay) } this._elms.delay && this._elms.delay.forEach((item) => { item.value = v }) } get state() { return this.options.state } set state(v) { this.options.state = v cancelAnimationFrame(this.#_requestAnimationFrameEventId) if (this.editObj) { this.editObj.destroy() this.editObj = null if (this._DialogObject && this._DialogObject._element && this._DialogObject._element.content) { this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0].innerHTML = '开始调整' this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0].className = 'btn model-rotate-btn' } } if (this.TweenAnimate && this.TweenAnimate._isPlaying) { clearTimeout(this.TweenAnimate.timeout) if (v) { this.lineEdit = false if (this.TweenAnimate.isPlaying()) { this.TweenAnimate.timeout = setTimeout(() => { this.TweenAnimate.resume() }, this.options.delay); } else { this.TweenAnimate.delay(this.delay).start() } this.speed = this.speed } else { let positionCamera = { ...this.sdk.viewer.camera._position } let _this = this this.#_requestAnimationFrameEventId = requestAnimationFrame(function fn() { if (_this.firstPersonView) { _this.sdk.viewer.camera.setView({ destination: { ...positionCamera }, orientation: { heading: _this.sdk.viewer.camera.heading, pitch: _this.sdk.viewer.camera.pitch, roll: _this.sdk.viewer.camera.roll } }) } _this.#_requestAnimationFrameEventId = requestAnimationFrame(fn) }) this.TweenAnimate.pause() setTimeout(() => { _this.model.isMove = false }, 200); } } else { if (v) { let positions = this.renewLinePositions(this.options.line.positions) this.modelMove(positions) } } this._elms.state && this._elms.state.forEach((item) => { item.checked = v }) } get modelShow() { return this.options.model.show } set modelShow(v) { this.options.model.show = v if (this.model && this.show) { this.model.show = v } this._elms.modelShow && this._elms.modelShow.forEach((item) => { item.checked = v }) } get modelAnimate() { return this.options.model.animate } set modelAnimate(v) { this.options.model.animate = v if (!this.model || !this.model.loader.components) { return } let animations = this.model.loader.components.animations this.model.activeAnimations.removeAll() if (animations && animations.length > 0) { for (let i = 0; i < animations.length; i++) { if (animations[i].name == v) { this.model.activeAnimations.add({ index: i, loop: Cesium.ModelAnimationLoop.REPEAT, speedup: 1, reverse: false }) break } } } this._elms.modelAnimate && this._elms.modelAnimate.forEach((item) => { item.value = v }) } get noseToTail() { return this.options.line.noseToTail } set noseToTail(v) { this.lineEdit = false this.options.line.noseToTail = v let fromDegreesArrayHeights = [] for (let i = 0; i < this.options.line.positions.length; i++) { fromDegreesArrayHeights.push(this.options.line.positions[i].lng, this.options.line.positions[i].lat, this.options.line.positions[i].alt) } let nosmooth = Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArrayHeights) if (this.line) { let positions_smooth = this.renewLinePositions(this.options.line.positions) this.line.polyline.positions = positions_smooth this.model.position = positions_smooth[0] this.modelMove(positions_smooth) } this._elms.noseToTail && this._elms.noseToTail.forEach((item) => { item.checked = v }) } get lineShow() { return this.options.line.show } set lineShow(v) { if (v) { this.realTimeRoute = false } this.options.line.show = v if (this.line && this.show) { this.line.polyline.material = v ? new Cesium.PolylineDashMaterialProperty({ color: new Cesium.Color.fromCssColorString('#00ffff'), dashLength: 20, //短划线长度 }) : new Cesium.PolylineDashMaterialProperty({ color: new Cesium.Color.fromCssColorString('#00ffff00'), dashLength: 20, //短划线长度 }) } this._elms.lineShow && this._elms.lineShow.forEach((item) => { item.checked = v }) } get realTimeRoute() { return this.options.realTimeRoute } set realTimeRoute(v) { if (v) { this.lineShow = false this.keyPointShow = false } this.options.realTimeRoute = v if (this.realTimeLine && this.show) { this.realTimeLine.show = v } this._elms.realTimeRoute && this._elms.realTimeRoute.forEach((item) => { item.checked = v }) } get keyPointShow() { return this.options.line.keyPoint } set keyPointShow(v) { this.options.line.keyPoint = v for (let i = 0; i < this.keyPoints.length; i++) { if (this.show) { this.keyPoints[i].show = v } } this._elms.keyPointShow && this._elms.keyPointShow.forEach((item) => { item.checked = v }) if (!v && this.lineEdit) { // 关闭线编辑 this.#lineEdit = v YJ.Measure.SetMeasureStatus(false) this.event && this.event.destroy() this.ControllerObject && this.ControllerObject.destroy() this.tip && this.tip.destroy() this.tip = null this._elms.lineEdit && this._elms.lineEdit.forEach((item) => { item.checked = v }) } } get lineEdit() { return this.#lineEdit } set lineEdit(v) { let linePositions = [] let computePositionsSmooth = (positions) => { linePositions = this.renewLinePositions(positions) this.model.position = linePositions[0] this.modelMove(linePositions) } if (v) { this.viewFollow = false if (YJ.Measure.GetMeasureStatus()) { console.warn('上一次测量未结束') this.lineEdit = false return } else { this.ground = false this.smooth = false this.state = false YJ.Measure.SetMeasureStatus(true) this.event && this.event.destroy() this.tip && this.tip.destroy() this.tip = new MouseTip('请选择一个顶点,右键取消', this.sdk) this.event = new MouseEvent(this.sdk) let selectPoint computePositionsSmooth([...this.options.line.positions]) let leftEvent = (movement, cartesian) => { let pick = this.sdk.viewer.scene.pick(movement.position); if (pick && pick.id && pick.id.name && pick.id.name === 'node-secondary-edit-point') { for (let i = 0; i < this.keyPoints.length; i++) { if (this.keyPoints[i].id === pick.id.id) { // this.keyPoints[i].show = false selectPoint = pick.id this.ControllerObject.position = this.options.line.positions[selectPoint.index] this.ControllerObject.editTranslational() this.tip && this.tip.destroy() this.tip = null this.ControllerObject.controllerCallBack = (params) => { // console.log('params', params) this.options.line.positions[selectPoint.index] = params.position if (selectPoint.index === 0) { this.options.height = this.options.line.positions[selectPoint.index].alt this._elms.height && this._elms.height.forEach((item) => { item.value = Number(this.options.height.toFixed(2)) }) } selectPoint.position = Cesium.Cartesian3.fromDegrees(params.position.lng, params.position.lat, params.position.alt) computePositionsSmooth([...this.options.line.positions]) } break } } // originalPosition = this.cartesian3Towgs84(cartesian, this.sdk.viewer) } } this.event.mouse_left(leftEvent) this.event.mouse_right((movement, cartesian) => { this.keyPointShow = false YJ.Measure.SetMeasureStatus(false) this.event.destroy() this.tip && this.tip.destroy() this.tip = null this.ControllerObject.destroy() }) this.event.mouse_move((movement, cartesian) => { this.tip && this.tip.setPosition( cartesian, movement.endPosition.x, movement.endPosition.y ) }) this.event.gesture_pinck_start((movement, cartesian) => { let startTime = new Date() let pos = { position: { x: (movement.position1.x + movement.position2.x) / 2, y: (movement.position1.y + movement.position2.y) / 2 } } this.event.gesture_pinck_end(() => { let endTime = new Date() if (endTime - startTime >= 500) { // 长按取消 this.keyPointShow = false YJ.Measure.SetMeasureStatus(false) this.event.destroy() this.tip && this.tip.destroy() this.tip = null this.ControllerObject.destroy() } else { leftEvent(pos, cartesian) } }) }) this.line.polyline.positions = new Cesium.CallbackProperty(function () { return linePositions }, false) } // 显示关键点 this.keyPointShow = v } else { if (this.lineEdit) { YJ.Measure.SetMeasureStatus(false) this.event.destroy() this.tip && this.tip.destroy() this.tip = null } // 隐藏关键点 this.keyPointShow = v this.ControllerObject.destroy() } this.#lineEdit = v this._elms.lineEdit && this._elms.lineEdit.forEach((item) => { item.checked = v }) } get routeDirection() { return this.options.routeDirection } set routeDirection(v) { this.options.routeDirection = v this._elms.routeDirection && this._elms.routeDirection.forEach((item) => { item.checked = v }) } get loop() { return this.options.loop } set loop(v) { this.options.loop = v if (this.TweenAnimate && this.TweenAnimate._isPlaying) { if (v) { this.TweenAnimate.repeat(Infinity) } else { this.TweenAnimate.repeat() } } this._elms.loop && this._elms.loop.forEach((item) => { item.checked = v }) } get firstPersonView() { return this.options.firstPersonView } set firstPersonView(v) { // this.state = true let splitSdk = getSdk() if (get2DView() || splitSdk.sdkD || !this.show) { v = false } cancelAnimationFrame(this.#_requestAnimationFrameEventId) this.#firstPersonViewEvent && this.#firstPersonViewEvent.destroy() this.sdk.viewer._firstPersonView = v this.options.firstPersonView = v if (this.options.firstPersonView) { this.viewFollow = true this.firstPersonHeadingPitch = { heading: 0, pitch: -10 } this.state = true this.model && (this.model.show = false) if (this._DialogObject && this._DialogObject._element.content) { let e_firstPerson = this._DialogObject._element.content.querySelectorAll("button[name='firstPerson']") e_firstPerson[0].className = 'btn is-active' e_firstPerson[1].className = 'btn' } if (this.sdk.viewer.trackedEntity) { this.sdk.viewer.entities.remove(this.sdk.viewer.trackedEntity) this.sdk.viewer.trackedEntity = null } CameraController(this.sdk, false) let splitSdk = getSdk() let targetSdk if (this.sdk === splitSdk.sdkP) { targetSdk = splitSdk.sdkD } else { targetSdk = splitSdk.sdkP } let targetEntity = targetSdk ? targetSdk.entityMap.get(this.options.id) : undefined if (this.sdk) this.#firstPersonViewEvent = new MouseEvent(this.sdk) this.#firstPersonViewEvent.mouse_right_down((movement, cartesian) => { let startPosition = { ...movement.position } this.#firstPersonViewEvent.mouse_move((movement2, cartesian2) => { this.firstPersonHeadingPitch.heading = this.firstPersonHeadingPitch.heading + ((movement2.endPosition.x - startPosition.x) / 20) this.firstPersonHeadingPitch.pitch = this.firstPersonHeadingPitch.pitch + ((startPosition.y - movement2.endPosition.y) / 10) targetEntity && (targetEntity.firstPersonHeadingPitch = { ...this.firstPersonHeadingPitch }) startPosition = { ...movement2.endPosition } }, true) }, true) this.#firstPersonViewEvent.mouse_right_up((movement, cartesian) => { this.#firstPersonViewEvent.mouse_move(() => { }) }, true) } else { CameraController(this.sdk, true) if (this.model && this.modelShow && this.show) { this.model.show = true } if (this._DialogObject && this._DialogObject._element.content) { let e_firstPerson = this._DialogObject._element.content.querySelectorAll("button[name='firstPerson']") if (e_firstPerson[0] && e_firstPerson[1]) { e_firstPerson[0].className = 'btn' e_firstPerson[1].className = 'btn is-active' } } if (this.viewFollow && this.show) { if (this.sdk.viewer.trackedEntity) { this.sdk.viewer.entities.remove(this.sdk.viewer.trackedEntity) } if (this.sdk.viewer.scene.mode === 3) { let pointEntity = this.sdk.viewer.entities.add({ // show: false, position: this.positions_smooth[0], // position of the point point: { color: Cesium.Color.RED.withAlpha(0), // color of the point pixelSize: 0 } }); this.sdk.viewer.trackedEntity = pointEntity; } this.viewFollow = this.viewFollow } } syncSplitData(this.sdk, this.options.id) } get viewFollow() { return this.options.viewFollow } set viewFollow(v) { let splitSdk = getSdk() let sdk2D = get2DView() // if (sdk2D || splitSdk.sdkD) { // v = false // } if (!this.show) { v = false } this.options.viewFollow = v if (!this.options.viewFollow) { this.firstPersonView = false } else { if (this.editObj) { this.editObj.destroy() this.editObj = null if (this._DialogObject && this._DialogObject._element && this._DialogObject._element.content) { this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0].innerHTML = '开始调整' this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0].className = 'btn model-rotate-btn' } } closeRotateAround(this.sdk) this.lineEdit = false } if (this.options.firstPersonView) { if (this.sdk.viewer.trackedEntity) { this.sdk.viewer.entities.remove(this.sdk.viewer.trackedEntity) this.sdk.viewer.trackedEntity = null } if (this._DialogObject && this._DialogObject._element.content) { let e_firstPerson = this._DialogObject._element.content.querySelectorAll("button[name='firstPerson']") if (e_firstPerson[0] && e_firstPerson[1]) { e_firstPerson[0].className = 'btn' e_firstPerson[1].className = 'btn is-active' } } } else { if (this.sdk.viewer.trackedEntity) { this.sdk.viewer.entities.remove(this.sdk.viewer.trackedEntity) this.sdk.viewer.trackedEntity = null } if (v && this.show && this.model) { let pointEntity = this.sdk.viewer.entities.add({ // show: false, position: this.model.position, // position of the point point: { color: Cesium.Color.RED.withAlpha(0), // color of the point pixelSize: 0 } }); this.sdk.viewer.trackedEntity = pointEntity; } } let sdk3D = get3DView() if (sdk3D) { if (this.sdk != sdk3D) { let that3D = sdk3D.entityMap.get(this.options.id) if (that3D && that3D.viewFollow != v) { that3D.viewFollow = v } } else { if (sdk2D) { let that2D = sdk2D.entityMap.get(this.options.id) if (that2D && that2D.viewFollow != v) { that2D.viewFollow = v if (this.TweenAnimate && this.TweenAnimate._isPlaying) { that2D.setMovePositionByDistance(this.TweenAnimate._object.distance) } } } } } syncSplitData(this.sdk, this.options.id) this._elms.viewFollow && this._elms.viewFollow.forEach((item) => { item.checked = v }) } get labelShow() { return this.options.label.show } set labelShow(v) { this.options.label.show = v if (this.show) { this.label && (this.label.show = v) if (this.options.label.position) { setTimeout(() => { if (this.options.label.position.alt) { this.label && (this.label.position = [this.options.label.position.lng, this.options.label.position.lat, this.options.label.position.alt]) } else { this.getClampToHeight({ lng: this.options.label.position.lng, lat: this.options.label.position.lat }).then((height) => { this.label && (this.label.position = [this.options.label.position.lng, this.options.label.position.lat, height]) }) } }, 0); } } else { this.label && (this.label.show = false) } this._elms.labelShow && this._elms.labelShow.forEach((item) => { item.checked = v }) } get labelFontFamily() { return this.options.label.fontFamily } set labelFontFamily(v) { this.options.label.fontFamily = v || 0 this.label && (this.label.fontFamily = this.options.label.fontFamily) let name = getFontFamilyName(this.labelFontFamily) || '' this._elms.labelFontFamily && this._elms.labelFontFamily.forEach(item => { item.value = name }) } get labelColor() { return this.options.label.color } set labelColor(v) { this.options.label.color = v this.label && (this.label.color = v) if (this._elms.labelColor) { this._elms.labelColor.forEach((item, i) => { let labelColorPicker = new YJColorPicker({ el: item.el, size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: this.labelColor, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (color) => { this.labelColor = color },//点击确认按钮事件回调 clear: () => { this.labelColor = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) this._elms.labelColor[i] = labelColorPicker }) } } get labelFontSize() { return this.options.label.fontSize } set labelFontSize(v) { this.options.label.fontSize = v this.label && (this.label.fontSize = v) this._elms.labelFontSize && this._elms.labelFontSize.forEach((item) => { item.value = v }) } get labelScaleByDistance() { return this.options.label.scaleByDistance } set labelScaleByDistance(v) { this.options.label.scaleByDistance = v this.label && (this.label.scaleByDistance = v) this._elms.labelScaleByDistance && this._elms.labelScaleByDistance.forEach((item) => { item.checked = v }) } get labelNear() { return this.options.label.near } set labelNear(v) { let near = v if (near > this.labelFar) { near = this.labelFar } this.options.label.near = near this.label && (this.label.near = near) this._elms.labelNear && this._elms.labelNear.forEach((item) => { item.value = near }) } get labelFar() { return this.options.label.far } set labelFar(v) { let far = v if (far < this.labelNear) { far = this.labelNear } this.options.label.far = far this.label && (this.label.far = far) this._elms.labelFar && this._elms.labelFar.forEach((item) => { item.value = far }) } // 创建路径 static addLine(that) { let positions_smooth = that.renewLinePositions(that.options.line.positions) let show if (that.options.show) { show = that.options.line.show } else { show = false } that.sdk.viewer.entities.removeById(that.options.id + '-2') that.sdk.viewer.entities.removeById(that.options.id + '-3') that.line = that.sdk.viewer.entities.add({ id: that.options.id + '-2', polyline: { positions: positions_smooth, width: 2, clampToGround: that.ground, material: show ? new Cesium.PolylineDashMaterialProperty({ color: new Cesium.Color.fromCssColorString('#00ffff'), dashLength: 20, //短划线长度 }) : new Cesium.PolylineDashMaterialProperty({ color: new Cesium.Color.fromCssColorString('#00ffff00'), dashLength: 20, //短划线长度 }), zIndex: that.sdk._entityZIndex }, }) that.realTimeLine = that.sdk.viewer.entities.add({ id: that.options.id + '-3', show: that.options.realTimeRoute ? that.options.realTimeRoute : false, polyline: { positions: new Cesium.CallbackProperty(function () { return that.realTimePositions }, false), width: 2, clampToGround: that.ground, material: Cesium.Color.fromCssColorString('#ff0000'), zIndex: that.sdk._entityZIndex }, }) that.sdk._entityZIndex++ if (that.#mouseRightevent) { that.#mouseRightevent.destroy() } that.#mouseRightevent = new MouseEvent(that.sdk) that.#mouseRightevent.mouse_right((movement, cartesian) => { let splitSdk = getSdk() let targetSdk if (that.sdk === splitSdk.sdkP) { targetSdk = splitSdk.sdkD } else { targetSdk = splitSdk.sdkP } let targetEntity = targetSdk ? targetSdk.entityMap.get(that.options.id) : undefined targetEntity && (targetEntity.viewFollow = false) that.viewFollow = false }, true) TrajectoryMotion.addModel(that) TrajectoryMotion.addKeyPoint(that) that.noseToTail = that.options.line.noseToTail that.smooth = that.options.line.smooth syncData(that.sdk, that.options.id) if (that.options.show) { setSplitDirection(0, that.options.id) } } // 创建模型 static async addModel(that) { let url = that.replaceHost(that.options.model.url, that.options.host) let options = { id: that.options.id, url: url, show: that.options.show ? that.options.model.show : false, scale: that.options.model.scale, // minimumPixelSize: that.options.model.pixelSize, // maximumScale: 100000, // allowPicking: false } if (Number(Cesium.VERSION.split('.')[1]) >= 107) { that.model = await Cesium.Model.fromGltfAsync(options) that.model.originalBoundingSphereRadius = 0 that.sdk.viewer.scene.primitives.add(that.model) that.model.readyEvent.addEventListener(() => { that.model.originalBoundingSphereRadius = that.model.boundingSphere.radius that.modelAnimate = that.options.model.animate }) } else { that.model = that.sdk.viewer.scene.primitives.add( Cesium.Model.fromGltf(options) ); that.model.originalBoundingSphereRadius = 0 that.model.readyPromise.then(() => { that.model.originalBoundingSphereRadius = that.model.boundingSphere.radius that.modelAnimate = that.options.model.animate }) } that.model.imageBasedLighting.luminanceAtZenith = 0.6 // 设置模型的旋转角度,使其水平放置于地面 let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(that.positions_smooth[0]) that.model.modelMatrix = matrix that.model.position = that.positions_smooth[0] that.model.customScale = { x: that.options.model.scale, y: that.options.model.scale, z: that.options.model.scale }; // 模型大小比例 // Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(0.1, 0.1, 0.1), this.entity.modelMatrix) let positions = that.options.line.positions let fromDegreesArrayHeights = [] for (let i = 0; i < positions.length; i++) { fromDegreesArrayHeights.push(positions[i].lng, positions[i].lat, positions[i].alt) } let pos = that.smooth ? that.positions_smooth : Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArrayHeights) TrajectoryMotion.createLabel(that) that.modelMove(pos) that.entity = that.model } static async createLabel(that) { let labelPosition = that.cartesian3Towgs84(that.model.position, that.sdk.viewer) that.label = new LabelObject(that.sdk, { show: that.options.show ? (that.options.model.show ? that.options.label.show : false) : false, position: [labelPosition.lng, labelPosition.lat, labelPosition.alt], text: that.options.name, fontSize: that.options.label.fontSize, fontFamily: that.options.label.fontFamily, color: that.options.label.color, pixelOffset: that.options.label.pixelOffset, backgroundColor: that.options.label.backgroundColor, lineColor: that.options.label.lineColor, lineWidth: that.options.label.lineWidth, scaleByDistance: that.options.label.scaleByDistance, near: that.options.label.near, far: that.options.label.far }, that.model) } // 创建关键点 static async addKeyPoint(that) { for (let i = 0; i < that.options.line.positions.length; i++) { let height = await that.getClampToHeight(that.options.line.positions[i]) let result = await Cesium.Cartesian3.fromDegrees(that.options.line.positions[i].lng, that.options.line.positions[i].lat, height) let entity = that.sdk.viewer.entities.add({ name: 'node-secondary-edit-point', index: i, show: that.options.line.keyPoint || false, position: that.ground ? result : Cesium.Cartesian3.fromDegrees(that.options.line.positions[i].lng, that.options.line.positions[i].lat, that.options.line.positions[i].alt), billboard: { image: that.getSourceRootPath() + '/img/point.png', width: 15, height: 15, disableDepthTestDistance: Number.POSITIVE_INFINITY, color: Cesium.Color.WHITE.withAlpha(0.99) }, }) that.keyPoints.push(entity) } } // 模型移动 async modelMove(positions, option = { time: 0 }) { cancelAnimationFrame(this.#_requestAnimationFrameEventId) let _this = this let time = option.time || 0 let startDistance = option.distance let viewer = this.sdk.viewer if (!this.model || !this.sdk || !this.sdk.viewer) { return } this.removeModelAnimate() let lineString = [] for (let i = 0; i < positions.length; i++) { let position = this.cartesian3Towgs84(positions[i], viewer) lineString.push([position.lng, position.lat, position.alt]) } // console.log(lineString) let line = turf.lineString(lineString); this.distance = turf.length(line, { units: 'kilometers' }); let totalTime = (this.distance * 1000) / this.options.speed // 总耗时(秒) if (!startDistance && startDistance !== 0) { startDistance = 0.000001 if (time) { if (time > totalTime) { time = totalTime } startDistance = (time / totalTime) * this.distance } } else { if (startDistance > this.distance) { startDistance = this.distance } time = (startDistance / this.distance) * totalTime } // console.log(totalTime) let lastDistance = 0 let motionArray = [] let HeadingPitchRoll let HeadingPitchRoll2 let previous = {} let m = 0 this.TweenAnimate = new TWEEN.Tween({ distance: startDistance }).to({ distance: this.distance }, (totalTime - time) * 1000).delay(this.delay).easing(TWEEN.Easing.Linear.None).repeat(this.options.loop ? Infinity : 0).onRepeat(() => { if (time || startDistance) { this.modelMove(positions) } }).onUpdate(async (r, a) => { if (this.TweenAnimate._duration == Infinity) { return } m++ if (!this.sdk.viewer) { this.removeModelAnimate() return } if (!isNaN(r.distance)) { setPosition(r.distance) } }).onEveryStart(() => { this.realTimeRouteArray = [] }).onComplete((d) => { this.state = false // this.removeModelAnimate() // let runtimeAnimation = this.model._activeAnimations._runtimeAnimations // // let animations = await this.model.readyPromise // for (let i = runtimeAnimation.length - 1; i >= 0; i--) { // switch (runtimeAnimation[i].name) { // case '跑': // this.model.activeAnimations.remove(runtimeAnimation[i]) // break; // default: // } // } }); if (this.state) { this.TweenAnimate.start() } else { setPosition(startDistance) setTimeout(() => { _this.model.isMove = false }, 500); animateUpdate() function animateUpdate() { _this.#_requestAnimationFrameEventId2 = requestAnimationFrame( animateUpdate ) if (_this.options.firstPersonView) { let positionCamera = { ..._this.sdk.viewer.camera._position } _this.sdk.viewer.camera.setView({ destination: positionCamera, orientation: { heading: Cesium.Math.toRadians(_this.model.heading + 90 + _this.firstPersonHeadingPitch.heading), pitch: Cesium.Math.toRadians(_this.firstPersonHeadingPitch.pitch), roll: 0 } }) } } } async function setPosition(distance) { _this.model.isMove = true let sdk2D = get2DView() let splitSdk = getSdk() if (!_this.sdk.viewer || !_this.sdk.viewer.scene) { _this.removeModelAnimate() return } let start = 0; let stop = distance; let coordinates let sliced = line if (stop) { sliced = await turf.lineSliceAlong(line, start, stop, { units: 'kilometers' }); // _this.realTimeRouteArray = sliced+ coordinates = [...sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1]] } else { coordinates = [...line.geometry.coordinates[0]] } let position let positionCamera if (_this.ground) { // if (viewer.terrainProvider.availability) { // let result = await new Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, [Cesium.Cartographic.fromDegrees(coordinates[0], coordinates[1])]); // position = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], result[0].height) // positionCamera = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], result[0].height + 1) // } // else { // position = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1]) // positionCamera = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], 1) // } let filterEntitys = [] for (let [key, value] of _this.sdk.entityMap) { if (!value.type || (value.type !== 'glb' && value.type !== 'bim' && value.type !== 'tileset' && value.type !== 'TrajectoryMotion' && value.type !== 'ParticleEffects' && value.entity)) { // if(value.type === 'ParticleEffects') { // for (let i = 0; i < value.entity._particles.length; i++) { // filterEntitys.push(value.entity._particles[i]._billboard) // } // } filterEntitys.push(value.entity) if (value.label && value.label.entity) { filterEntitys.push(value.label.entity) } } } if (_this.label && _this.label.entity) { filterEntitys.push(_this.label.entity) } // let point1 = new Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], -10000); // let point2 = new Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], 10000000000); // let direction = Cesium.Cartesian3.subtract(point2, point1, new Cesium.Cartesian3()); // let c = Cesium.Cartesian3.normalize(direction, direction); // console.log('射线方向:', c); // let ray = new Cesium.Ray(point1, c); // let pickedObjects = this.sdk.viewer.scene.pickFromRay(ray); // console.log('pickedObjects', pickedObjects) // console.log('height', Cesium.Cartographic.fromCartesian(pickedObjects.position).height) let result let sdk2D = get2DView() if (sdk2D && _this.sdk == sdk2D) { result = new Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1]) position = result } else { result = await _this.sdk.viewer.scene.clampToHeight(new Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1]), [_this.model, ...filterEntitys]) position = result } if (!result) { position = new Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1]) } let pos3 = _this.cartesian3Towgs84(position, viewer); let height2 = 0 try { let position2 = await Cesium.sampleTerrainMostDetailed( _this.sdk.viewer.scene.terrainProvider, [Cesium.Cartographic.fromDegrees(pos3.lng, pos3.lat)] ) height2 = position2[0].height } catch (error) { height2 = 0 } if (pos3.alt < height2) { pos3.alt = height2 } pos3.alt = Number(pos3.alt.toFixed(1)) position = Cesium.Cartesian3.fromDegrees(pos3.lng, pos3.lat, pos3.alt) if (!_this.sdk.viewer || !_this.sdk.viewer.scene) { _this.removeModelAnimate() return } positionCamera = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], _this.cartesian3Towgs84(position, _this.sdk.viewer).alt + 1.8) let fromDegreesArray = [] for (let i = 0; i < sliced.geometry.coordinates.length; i++) { fromDegreesArray.push(sliced.geometry.coordinates[i][0], sliced.geometry.coordinates[i][1]) } _this.realTimePositions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray) // _this.realTimeLine.polyline.positions = } else { let cartesian3 = _this.spline.evaluate(distance / _this.distance) if (!cartesian3) { return } coordinates = _this.cartesian3Towgs84(cartesian3, viewer); position = cartesian3 positionCamera = Cesium.Cartesian3.fromDegrees(coordinates.lng, coordinates.lat, coordinates.alt + 1.8) let positions_smooth = [] for (let i = 0; i <= 1000; i++) { if ((i / 1000) > (distance / _this.distance)) { break } let cartesian3 = _this.spline.evaluate(i / 1000); positions_smooth.push(cartesian3); } positions_smooth.push(cartesian3) _this.realTimePositions = positions_smooth } HeadingPitchRoll = getHeadingPitchRoll(_this.model.position, position) if (previous && previous.position) { HeadingPitchRoll2 = getHeadingPitchRoll(previous.position, position) HeadingPitchRoll.pitch = HeadingPitchRoll2.pitch } previous.position = _this.model.position let modeHeadingPitchRoll = Cesium.HeadingPitchRoll.fromDegrees(_this.options.model.heading, _this.options.model.pitch, _this.options.model.roll) let heading = 0 let pitch = 0 let roll = 0 let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position) if (_this.options.routeDirection && !_this.lineEdit) { heading = (HeadingPitchRoll.heading) * (180 / Math.PI) - 90 - _this.options.model.heading pitch = (HeadingPitchRoll.pitch) * (180 / Math.PI) - _this.options.model.pitch roll = _this.options.model.roll let that3D if (get3DView()) { that3D = get3DView().entityMap.get(_this.options.id) } else { that3D = (splitSdk.sdkP && splitSdk.sdkP.entityMap.get(_this.options.id)) } if (!_this.state) { if (that3D && ((sdk2D && sdk2D === _this.sdk) || (splitSdk.sdkD && splitSdk.sdkD === _this.sdk))) { heading = that3D.model.heading pitch = that3D.model.pitch roll = that3D.model.roll } } if (isNaN(heading) || isNaN(pitch) || isNaN(roll)) { return } if (!_this.state) { if (that3D && ((sdk2D && sdk2D === _this.sdk) || (splitSdk.sdkD && splitSdk.sdkD === _this.sdk))) { heading = that3D.model.heading pitch = that3D.model.pitch roll = that3D.model.roll } else { heading = (_this.model.heading || _this.model.heading === 0) ? _this.model.heading : _this.options.model.heading pitch = (_this.model.pitch || _this.model.pitch === 0) ? _this.model.pitch : _this.options.model.pitch roll = (_this.model.roll || _this.model.roll === 0) ? _this.model.roll : _this.options.model.roll } } _this.model.modelMatrix = Cesium.Matrix4.multiplyByMatrix3(matrix, Cesium.Matrix3.fromHeadingPitchRoll(Cesium.HeadingPitchRoll.fromDegrees(heading, pitch, roll)), _this.model.modelMatrix) } else { if (_this.entity) { heading = _this.options.model.heading pitch = _this.options.model.pitch roll = _this.options.model.roll if (isNaN(heading) || isNaN(pitch) || isNaN(roll)) { return } // 旋转 let mx = Cesium.Matrix3.fromRotationX( Cesium.Math.toRadians(roll) ) let my = Cesium.Matrix3.fromRotationY( Cesium.Math.toRadians(pitch) ) let mz = Cesium.Matrix3.fromRotationZ( Cesium.Math.toRadians(heading) ) let rotationX = Cesium.Matrix4.fromRotationTranslation(mx) let rotationY = Cesium.Matrix4.fromRotationTranslation(my) let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz) let originalMatrix = new Cesium.Matrix4() Cesium.Matrix4.multiply(matrix, rotationX, originalMatrix) Cesium.Matrix4.multiply(originalMatrix, rotationY, originalMatrix) Cesium.Matrix4.multiply(originalMatrix, rotationZ, _this.entity.modelMatrix) } } // console.log((HeadingPitchRoll.heading - modeHeadingPitchRoll.heading) * (180 / Math.PI)) _this.model.position = position _this.model.roll = roll _this.model.pitch = pitch _this.model.heading = heading if (!position) { return } let labelPosition = _this.cartesian3Towgs84(position, _this.sdk.viewer) _this.label.position = [labelPosition.lng, labelPosition.lat, labelPosition.alt] lastDistance = distance // console.log(position) _this.realTimeRouteArray.push(position) if (_this.viewFollow) { // console.log(Cesium.Math.toDegrees(_this.sdk.viewer.camera.pitch)) if (_this.options.firstPersonView) { _this.sdk.viewer.camera.setView({ destination: positionCamera, orientation: { heading: Cesium.Math.toRadians(heading + 90 + _this.firstPersonHeadingPitch.heading), pitch: Cesium.Math.toRadians(_this.firstPersonHeadingPitch.pitch), roll: 0 } }) } else { if (_this.sdk.viewer.scene.mode === 3) { if (_this.sdk.viewer.trackedEntity) { _this.sdk.viewer.trackedEntity.position = position // _this.sdk.viewer.camera.position = position } } else { if (_this.sdk.viewer.trackedEntity) { _this.sdk.viewer.camera.setView({ destination: Cesium.Cartesian3.fromDegrees(coordinates.lng, coordinates.lat, _this.sdk.viewer.camera.positionCartographic.height), orientation: { heading: Cesium.Math.toRadians(-90), pitch: 0, roll: 0 } }) } } } } } // function executeAnimate() { // } // setTimeout(() => { // let i = 0 // function animate() { // if (i < motionArray.length) { // let result = motionArray[i].result; // console.log(result) // result.then((res) => { // let position = Cesium.Cartesian3.fromDegrees(motionArray[i].lng, motionArray[i].lat, res[0].height) // let HeadingPitchRoll = getHeadingPitchRoll(_this.model.position, position) // let modeHeadingPitchRoll = Cesium.HeadingPitchRoll.fromDegrees(_this.options.model.heading, _this.options.model.pitch, _this.options.model.roll) // let heading = 0 // let pitch = 0 // let roll = 0 // if (_this.options.routeDirection) { // heading = (HeadingPitchRoll.heading - modeHeadingPitchRoll.heading) * (180 / Math.PI) - 90 // pitch = (HeadingPitchRoll.pitch - modeHeadingPitchRoll.pitch) * (180 / Math.PI) // } // else { // heading = - _this.options.model.heading // pitch = - _this.options.model.pitch // } // roll = - _this.options.model.roll // // console.log(heading) // let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position) // _this.model.modelMatrix = Cesium.Matrix4.multiplyByMatrix3(matrix, Cesium.Matrix3.fromHeadingPitchRoll(Cesium.HeadingPitchRoll.fromDegrees(heading, pitch, roll)), _this.model.modelMatrix) // _this.model.position = position // if (_this.sdk.viewer.trackedEntity) { // _this.sdk.viewer.trackedEntity.position = position // } // i++ // requestAnimationFrame(animate); // }) // } // } // animate(); // }, 2000); // 根据两个坐标点,获取Heading(朝向) function getHeadingPitchRoll(pointA, pointB) { // console.log(distance, _this.cartesian3Towgs84(pointA, viewer), _this.cartesian3Towgs84(pointB, viewer)) //建立以点A为原点,X轴为east,Y轴为north,Z轴朝上的坐标系 const transform = Cesium.Transforms.eastNorthUpToFixedFrame(pointA); //向量AB if (!pointB) { return } const positionvector = Cesium.Cartesian3.subtract(pointB, pointA, new Cesium.Cartesian3()); //因transform是将A为原点的eastNorthUp坐标系中的点转换到世界坐标系的矩阵 //AB为世界坐标中的向量 //因此将AB向量转换为A原点坐标系中的向量,需乘以transform的逆矩阵。 const vector = Cesium.Matrix4.multiplyByPointAsVector( Cesium.Matrix4.inverse(transform, new Cesium.Matrix4()), positionvector, new Cesium.Cartesian3() ); //归一化 const direction = Cesium.Cartesian3.normalize(vector, new Cesium.Cartesian3()); // console.log(direction) //heading const heading = Math.atan2(direction.y, direction.x) - Cesium.Math.PI_OVER_TWO; const pitch = Cesium.Math.PI_OVER_TWO - Cesium.Math.acosClamped(direction.z); // console.log(pitch * (180 / Math.PI)) const roll = Cesium.Math.fastApproximateAtan2(direction.x, direction.z); // console.log({heading: heading * (180 / Math.PI), pitch: pitch * (180 / Math.PI), roll: roll * (180 / Math.PI)}) return { heading: Cesium.Math.TWO_PI - Cesium.Math.zeroToTwoPi(heading), pitch: pitch, roll: roll }; } } setMovePositionByDistance(distance) { let positions_smooth = this.renewLinePositions(this.options.line.positions) this.modelMove(positions_smooth, { distance: distance }) } setMovePositionByTime(time) { let positions_smooth = this.renewLinePositions(this.options.line.positions) this.modelMove(positions_smooth, { time: time }) } // 编辑框 async edit(state) { if (this._error) { return } let _this = this this.originalOptions = this.deepCopyObj(this.options) if (this._DialogObject && this._DialogObject.close) { this._DialogObject.close() this._DialogObject = null } if (state) { this._DialogObject = await new Dialog(this.sdk, this.options, { title: '轨迹运动属性', left: '180px', top: '100px', confirmCallBack: (options) => { this.name = this.name.trim() if (!this.name) { this.name = '未命名对象' } this.originalOptions = this.deepCopyObj(this.options) // this.options.viewFollowOrientation = {} // this.options.viewFollowOrientation.heading = Cesium.Math.toDegrees(this.sdk.viewer.camera.heading) // this.options.viewFollowOrientation.pitch = Cesium.Math.toDegrees(this.sdk.viewer.camera.pitch) // this.options.viewFollowOrientation.roll = Cesium.Math.toDegrees(this.sdk.viewer.camera.roll) // this.options.viewFollowOrientation.direction = this.sdk.viewer.camera.direction this._DialogObject.close() let cdoptions = this.deepCopyObj(this.options) cdoptions.host = '' this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(cdoptions) syncData(this.sdk, this.options.id) syncSplitData(this.sdk, this.options.id) }, removeCallBack: () => { if (this.sdk.viewer.trackedEntity) { this.sdk.viewer.entities.remove(this.sdk.viewer.trackedEntity) this.sdk.viewer.trackedEntity = null } this.Dialog.removeCallBack && this.Dialog.removeCallBack() }, closeCallBack: () => { this._DialogObject = null this.reset() this.Dialog.closeCallBack && this.Dialog.closeCallBack() if (this.editObj) { this.editObj.destroy() this.editObj = null } this.keyPointShow = false this.event && this.event.destroy() this.tip && this.tip.destroy() this.tip = null this.ControllerObject.destroy() if(this.firstPersonView !== this.originalOptions.firstPersonView) { this.firstPersonView = this.originalOptions.firstPersonView; } if(this.firstPersonView && this.modelShow) { this.model && (this.model.show = false) } }, showCallBack: (show) => { this.show = show this.Dialog.showCallBack && this.Dialog.showCallBack() // this.options.show = show // this.model && (this.model.show = show) // this.line && (this.line.show = show) } }) this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' trajectory-motion' let contentElm = document.createElement('div'); contentElm.innerHTML = html() this._DialogObject.contentAppChild(contentElm) if (this.editObj) { this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0].innerHTML = '结束调整' this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0].className = 'btn model-rotate-btn is-active' } else { this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0].innerHTML = '开始调整' this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0].className = 'btn model-rotate-btn' } let labelColorPicker = new YJColorPicker({ el: contentElm.getElementsByClassName("labelColor")[0], size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: this.labelColor, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (color) => { this.labelColor = color },//点击确认按钮事件回调 clear: () => { this.labelColor = '' },//点击清空按钮事件回调 }) let heightBoxElm = this._DialogObject._element.content.getElementsByClassName('height-box')[0] let all_elm = contentElm.getElementsByTagName("*") this._EventBinding.on(this, all_elm) this._elms = this._EventBinding.element this._elms.heightBox = heightBoxElm this._elms.labelColor = [labelColorPicker] if (this.model) { const getAnimationsList = () => { let animations = this.model.loader.components.animations if (this._DialogObject) { if (animations) { let tagData = [ { name: '无', value: '无', } ] for (let i = 0; i < animations.length; i++) { tagData.push( { name: animations[i].name, value: animations[i].name } ) } legp(this._DialogObject._element.content, ".model-animate-select").legp_search(tagData) } let selectElm = contentElm.getElementsByClassName('model-animate-select')[0].getElementsByTagName('input')[0] selectElm.value = this.modelAnimate selectElm.addEventListener('input', (e, c) => { this.modelAnimate = selectElm.value }) } } if (Number(Cesium.VERSION.split('.')[1]) >= 107) { if (this.model.ready) { getAnimationsList() } else { this.model.readyEvent.addEventListener(() => { getAnimationsList() }) } } else { this.model.readyPromise.then((entity) => { getAnimationsList() }) } } if (this.ground) { this._elms.heightBox && (this._elms.heightBox.className = 'input-number input-number-unit-1 height-box disabled'); } else { this._elms.heightBox && (this._elms.heightBox.className = 'input-number input-number-unit-1 height-box'); } let e_firstPerson = contentElm.querySelectorAll("button[name='firstPerson']") e_firstPerson[0].addEventListener('click', (e) => { let splitSdk = getSdk() if (!get2DView() && !splitSdk.sdkD) { if (!this.firstPersonView) { this.viewFollow = true } this.firstPersonView = true } }) e_firstPerson[1].addEventListener('click', (e) => { if (this.firstPersonView) { this.viewFollow = true } this.firstPersonView = false }) if (this.options.firstPersonView) { e_firstPerson[0].className = 'btn is-active' e_firstPerson[1].className = 'btn' if (this.sdk.viewer.trackedEntity) { this.sdk.viewer.entities.remove(this.sdk.viewer.trackedEntity) this.sdk.viewer.trackedEntity = null } } else { e_firstPerson[0].className = 'btn' e_firstPerson[1].className = 'btn is-active' } let rubricElm = document.createElement('div') rubricElm.className = 'custom-rubric-box' rubricElm.style.transformOrigin = 'center bottom' rubricElm.style.position = 'absolute'; rubricElm.style.top = '180px'; rubricElm.style.right = '3px'; rubricElm.style.padding = '5px 10px'; rubricElm.style.backgroundColor = '#3e4249'; rubricElm.style.borderRadius = '5px'; rubricElm.style.fontSize = '12px'; rubricElm.style.color = '#ff5733'; rubricElm.style.display = 'none' rubricElm.innerHTML = `场景正北方向为轨迹前进正方向
` let iconRubric = contentElm.getElementsByClassName('icon-rubric')[0] iconRubric.addEventListener('mouseenter', (e) => { rubricElm.style.display = 'block' }) document.addEventListener('mousemove', (event) => { // 检查点击的元素是否在模态框内容区域之外 if (!iconRubric.contains(event.target)) { rubricElm.style.display = 'none'; } }); this._DialogObject._element.content.appendChild(rubricElm) setTimeout(() => { let fontData = getFontList() let fontObject = legp( this._DialogObject._element.content.getElementsByClassName( 'font-select-box' )[0], '.font-select' ) if (fontObject) { fontObject.legp_search(fontData) let fontDataLegpElm = this._DialogObject._element.content .getElementsByClassName('font-select')[0] .getElementsByTagName('input')[0] fontDataLegpElm.value = fontData[this.labelFontFamily].value for (let i = 0; i < fontData.length; i++) { if (fontData[i].value == fontDataLegpElm.value) { fontObject.legp_searchActive(fontData[i].value) break } } fontDataLegpElm.addEventListener('input', () => { for (let i = 0; i < fontData.length; i++) { if (fontData[i].value === fontDataLegpElm.value) { this.labelFontFamily = fontData[i].key break } } }) this._elms.labelFontFamily = [fontDataLegpElm] } }, 0) } } flyTo(options = {}) { setActiveViewer(0) closeRotateAround(this.sdk) if (this.options.customView) { this.sdk.viewer.camera.flyTo({ destination: this.options.customView.position, orientation: this.options.customView.orientation }) } else { this.line && this.sdk.viewer.flyTo(this.line, { offset: options.orientation || { heading: Cesium.Math.toRadians(0.0), pitch: Cesium.Math.toRadians(-60.0), roll: Cesium.Math.toRadians(0.0) } }) } } async remove() { this.event && this.event.destroy() this.tip && this.tip.destroy() this.sdk.viewer.scene.primitives.remove(this.model) this.sdk.viewer.entities.remove(this.line) this.sdk.viewer.entities.remove(this.realTimeLine) this.label && this.label.remove() for (let i = 0; i < this.keyPointShow.length; i++) { this.sdk.viewer.entities.remove(this.keyPointShow[i]) } this.line = null this.realTimeLine = null this.model = null this.label = null if (this._DialogObject && !this._DialogObject.isDestroy) { this._DialogObject.close() this._DialogObject = null } if (this.#mouseRightevent) { this.#mouseRightevent.destroy() } this.removeModelAnimate() let sdk2D = get2DView() if (!sdk2D || sdk2D !== this.sdk) { this.viewFollow = false } cancelAnimationFrame(this.#_requestAnimationFrameEventId) await this.sdk.removeIncetance(this.options.id) await syncData(this.sdk, this.options.id) } async reset() { (this.options.model.url !== this.originalOptions.model.url) && this.changeModelUrl(this.originalOptions.model.url); this.name = this.originalOptions.name; if (JSON.stringify(this.options.line.positions) !== JSON.stringify(this.originalOptions.line.positions)) { this.options.line.positions = this.deepCopyObj(this.originalOptions.line.positions); let positions = this.renewLinePositions(this.options.line.positions) this.line.polyline.positions = positions setTimeout(() => { this.model.position = positions[0]; this.modelMove(positions) }, 0); } this.modelShow = this.originalOptions.model.show; (this.noseToTail !== this.originalOptions.line.noseToTail) && (this.noseToTail = this.originalOptions.line.noseToTail); (this.height !== this.originalOptions.height) && (this.height = this.originalOptions.height); (this.lineShow !== this.originalOptions.line.show) && (this.lineShow = this.originalOptions.line.show); this.keyPointShow = this.originalOptions.line.keyPoint; this.routeDirection = this.originalOptions.routeDirection; this.scale = this.originalOptions.model.scale; (this.loop !== this.originalOptions.loop) && (this.loop = this.originalOptions.loop); this.viewFollow = this.originalOptions.viewFollow; this.state = this.originalOptions.state; this.speed = this.originalOptions.speed; (this.smooth !== this.originalOptions.line.smooth) && (this.smooth = this.originalOptions.line.smooth); this.realTimeRoute = this.originalOptions.realTimeRoute; this.modelAnimate = this.originalOptions.model.animate; this.delay = this.originalOptions.delay; (this.ground !== this.originalOptions.ground) && (this.ground = this.originalOptions.ground); if(this.firstPersonView !== this.originalOptions.firstPersonView) { this.firstPersonView = this.originalOptions.firstPersonView; } if(this.firstPersonView && this.modelShow) { this.model && (this.model.show = false) } this.labelShow = this.originalOptions.label.show this.labelColor = this.originalOptions.label.color this.labelFontSize = this.originalOptions.label.fontSize this.labelFontFamily = this.originalOptions.label.fontFamily this.labelScaleByDistance = this.originalOptions.label.scaleByDistance this.labelNear = this.originalOptions.label.near this.labelFar = this.originalOptions.label.far this.labelLineWidth = this.originalOptions.label.lineWidth this.labelPixelOffset = this.originalOptions.label.pixelOffset this.labelLineColor = this.originalOptions.label.lineColor this.labelBackgroundColorStart = this.originalOptions.label.backgroundColor[0] this.labelBackgroundColorEnd = this.originalOptions.label.backgroundColor[1] this.options = this.deepCopyObj(this.originalOptions); } // viewFollow(e) { // if (e.target.checked) { // var pointEntity = this.sdk.viewer.entities.add({ // // show: false, // position: this.positions_smooth[0], // position of the point // point: { // color: Cesium.Color.RED.withAlpha(0), // color of the point // pixelSize: 0 // } // }); // this.sdk.viewer.trackedEntity = pointEntity; // } // else { // this.sdk.viewer.entities.remove(this.sdk.viewer.trackedEntity) // this.sdk.viewer.trackedEntity = null // } // } modelRotate() { if (this.editObj) { this.editObj.destroy() this.editObj = null if (this._DialogObject && this._DialogObject._element && this._DialogObject._element.content) { this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0].innerHTML = '开始调整' this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0].className = 'btn model-rotate-btn' } } else { if (this.viewFollow) { if (window.ELEMENT) { window.ELEMENT.Message.closeAll(); window.ELEMENT.Message({ message: '关闭视角跟随后可调整模型方向!', type: 'warning', duration: 1500 }); console.warn('关闭视角跟随后可调整模型方向!') } } else { if (this._DialogObject && this._DialogObject._element && this._DialogObject._element.content) { this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0].innerHTML = '结束调整' this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0].className = 'btn model-rotate-btn is-active' } console.log(this._DialogObject._element.content, this._DialogObject._element.content.getElementsByClassName('model-rotate-btn')[0]) this.state = false this.editObj = new EditGltf(this.sdk, this.model) this.editObj.editRtation() this.editObj.transformCallBack = this.rotationEditingCallBack this.routeDirection = false let heading = this.options.model.heading let pitch = this.options.model.pitch let roll = this.options.model.roll if (isNaN(heading) || isNaN(pitch) || isNaN(roll)) { return } let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(this.model.position) // 旋转 let mx = Cesium.Matrix3.fromRotationX( Cesium.Math.toRadians(roll) ) let my = Cesium.Matrix3.fromRotationY( Cesium.Math.toRadians(pitch) ) let mz = Cesium.Matrix3.fromRotationZ( Cesium.Math.toRadians(heading) ) let rotationX = Cesium.Matrix4.fromRotationTranslation(mx) let rotationY = Cesium.Matrix4.fromRotationTranslation(my) let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz) let originalMatrix = new Cesium.Matrix4() Cesium.Matrix4.multiply(matrix, rotationX, originalMatrix) Cesium.Matrix4.multiply(originalMatrix, rotationY, originalMatrix) Cesium.Matrix4.multiply(originalMatrix, rotationZ, this.entity.modelMatrix) } } } clickChangeModel() { this.Dialog.changeModelCallBack && this.Dialog.changeModelCallBack() } //旋转时,坐标信息变化的回调 set rotationEditingCallBack(callback) { this._rotationEditingCallBack = callback } get rotationEditingCallBack() { return (params) => { this.options.model.heading = params.rz this.options.model.pitch = params.ry this.options.model.roll = params.rx this._rotationEditingCallBack && this._rotationEditingCallBack(this.editObj._params) this.entity && (this.entity.isMove = true) clearTimeout(this.#timeoutEventObject) this.#timeoutEventObject = setTimeout(() => { this.entity && (this.entity.isMove = false) }, 500); } } async changeModelUrl(url) { this.sdk.viewer.scene.primitives.remove(this.model) this.options.model.url = this.replaceHost(url, this.options.host) let matrix = this.model.modelMatrix let position = this.model.position let options = { id: this.options.id, url: this.options.model.url, show: this.options.model.show, scale: this.options.model.scale, // minimumPixelSize: this.options.model.pixelSize, // maximumScale: 100000, } const getAnimationsList = () => { if (this.options.model.url === this.originalOptions.model.url) { this.modelAnimate = this.originalOptions.model.animate } else { this.options.model.animate = '无' } let animations = this.model.loader.components.animations if (this._DialogObject) { if (animations) { let tagData = [ { name: '无', value: '无', } ] for (let i = 0; i < animations.length; i++) { tagData.push( { name: animations[i].name, value: animations[i].name } ) } legp(this._DialogObject._element.content, ".model-animate-select").legp_search(tagData) } let selectElm = this._DialogObject._element.content.getElementsByClassName('model-animate-select')[0].getElementsByTagName('input')[0] selectElm.value = this.modelAnimate selectElm.addEventListener('input', (e, c) => { this.modelAnimate = selectElm.value }) } } if (Number(Cesium.VERSION.split('.')[1]) >= 107) { this.model = await Cesium.Model.fromGltfAsync(options) this.model.position = position this.sdk.viewer.scene.primitives.add(this.model) this.model.readyEvent.addEventListener(() => { getAnimationsList() this.model.modelMatrix = matrix }) } else { this.model = this.sdk.viewer.scene.primitives.add( Cesium.Model.fromGltf(options) ); this.model.position = position this.model.readyPromise.then((entity) => { getAnimationsList() this.model.modelMatrix = matrix }) } this.model.imageBasedLighting.luminanceAtZenith = 0.6 } // 移除动画 removeModelAnimate() { if (this.TweenAnimate) { clearTimeout(this.TweenAnimate.timeout) TWEEN.remove(this.TweenAnimate) this.TweenAnimate = null } // if (modelPrimitive && modelPrimitive._activeAnimations && modelPrimitive._activeAnimations._runtimeAnimations) { // let runtimeAnimation = modelPrimitive._activeAnimations._runtimeAnimations // for (let i = runtimeAnimation.length - 1; i >= 0; i--) { // switch (runtimeAnimation[i].name) { // case '跑': // modelPrimitive.activeAnimations.remove(runtimeAnimation[i]) // break; // default: // } // } // } } set controllerCallBack(callback) { this._controllerCallBack = callback } get controllerCallBack() { return (params) => { } } // 更新坐标 renewLinePositions(pos) { let positions = pos if (this.noseToTail) { positions = [...pos, pos[0]] } let fromDegreesArrayHeights = [] let time = [] let positions_smooth = [] for (let i = 0; i < positions.length; i++) { fromDegreesArrayHeights.push(positions[i].lng, positions[i].lat, positions[i].alt) time.push(i / (positions.length - 1)) } if (this.smooth) { this.spline = new Cesium.CatmullRomSpline({ times: time, points: Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArrayHeights) }); } else { this.spline = new Cesium.LinearSpline({ times: time, points: Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArrayHeights) }); } for (let i = 0; i <= 1000; i++) { let cartesian3 = this.spline.evaluate(i / 1000); positions_smooth.push(cartesian3); } this.positions_smooth = positions_smooth return positions_smooth } flicker() { } } export default TrajectoryMotion