Files
sdk4.0_new/src/Obj/Base/TrajectoryMotionObject/index.js
2025-12-19 12:34:25 +08:00

1201 lines
41 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import EventBinding from '../../Element/Dialog/eventBinding';
import Base from "../index";
import MouseEvent from '../../../Event/index'
import Controller from "../../../Controller/index";
import MouseTip from '../../../MouseTip'
import { setActiveViewer, closeRotateAround } from '../../../Global/global'
class TrajectoryMotionObject extends Base {
#lineEdit = false
/**
* @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.line {object} 路径参数
* @param options.line.show=true {boolean} 路径显隐
* @param options.line.smooth=false {boolean} 路径圆滑
* @param options.line.noseToTail=false {boolean} 路径收尾相联
* @param {Array.<object>} 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
this.options.totalTime = options.totalTime
if(options.totalTime || options.totalTime===0) {
this.totalTime = options.totalTime
}
this.options.delay = options.delay || 0
this.options.loop = options.loop || options.loop === false ? options.loop : true
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.line.show = options.line.show || options.line.show === false ? options.line.show : true
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._initial = {}
this._current = {
heading: 0,
pitch: 0,
roll: 0
}
// this.options.firstPerson = false
this.distance
// this.addModel()
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.ControllerObject = new Controller(this.sdk)
this._EventBinding = new EventBinding()
TrajectoryMotionObject.addLine(this)
this.firstPersonView = false
this.options.viewFollow = false
}
// animateUpdate()
// function animateUpdate() {
// requestAnimationFrame(animateUpdate);
// TWEEN.update();
// }
}
get type() {
return 'TrajectoryMotionObject'
}
get show() {
return this.options.show
}
set show(v) {
if (typeof v === "boolean") {
this.options.show = v
if (v) {
this.line.show = this.lineShow
for (let i = 0; i < this.keyPoints.length; i++) {
this.keyPoints[i].show = this.keyPointShow
}
}
else {
this.line.show = v
for (let i = 0; i < this.keyPoints.length; i++) {
this.keyPoints[i].show = v
}
}
if (this._DialogObject && this._DialogObject.showBtn) {
this._DialogObject.showBtn.checked = v
}
} else {
console.error("参数必须为boolean")
}
}
get height() {
return this.options.height
}
set height(v) {
this.options.height = v
if (this.line) {
if (this.ground) {
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]
})
}
}
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)
}
}
}
let positions_smooth = this._renewLine(this.options.line.positions)
this.line.polyline.positions = positions_smooth
this._elms.height && this._elms.height.forEach((item) => {
item.value = v
})
}
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
this._elms.ground && this._elms.ground.forEach((item) => {
item.checked = v
})
}
get speed() {
return this.options.speed
}
set speed(v) {
if (v <= 0) {
v = 0.01
}
this.options.speed = v
if (this.distance || this.distance === 0) {
this.options.totalTime = (this.distance*1000) / this.options.speed
// this.TweenAnimate._object.distance/this.TweenAnimate._valuesEnd.distance
if(this.TweenAnimate && this.state) {
this.TweenAnimate && (this.setMovePositionByDistance(this.TweenAnimate._object.distance))
}
this._elms.speed && this._elms.speed.forEach((item) => {
item.value = v
})
this._elms.totalTime && this._elms.totalTime.forEach((item) => {
item.value = this.options.totalTime
})
}
}
get totalTime() {
return this.options.totalTime
}
set totalTime(v) {
this.options.totalTime = v
if (this.distance || this.distance === 0) {
this.options.speed = (this.distance*1000) / this.options.totalTime
this.TweenAnimate && (this.setMovePositionByDistance(this.TweenAnimate._object.distance))
this._elms.totalTime && this._elms.totalTime.forEach((item) => {
item.value = v
})
this._elms.speed && this._elms.speed.forEach((item) => {
item.value = this.options.speed
})
}
}
get smooth() {
return this.options.line.smooth
}
set smooth(v) {
this.lineEdit = false
this.options.line.smooth = v
let positions = this._renewLine(this.options.line.positions)
this.line.polyline.positions = positions
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.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
if (this.editObj) {
this.editObj.destroy()
this.editObj = null
}
if (this.TweenAnimate) {
if (v) {
this.speed = this.speed
}
else {
this.TweenAnimate.pause()
}
}
else {
if (v) {
let positions = this._renewLine(this.options.line.positions)
this.modelMove(positions)
}
}
this._elms.state && this._elms.state.forEach((item) => {
item.checked = 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._renewLine(this.options.line.positions)
this.line.polyline.positions = positions_smooth
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.show = v
}
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._renewLine(positions)
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.tip = new MouseTip('请选择一个顶点,右键取消', this.sdk)
this.event = new MouseEvent(this.sdk)
let selectPoint
computePositionsSmooth([...this.options.line.positions])
this.event.mouse_left((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
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_right((movement, cartesian) => {
// if (selectPoint) {
// let positions = [...this.options.line.positions]
// selectPoint.position = Cesium.Cartesian3.fromDegrees(positions[selectPoint.index].lng, positions[selectPoint.index].lat, positions[selectPoint.index].alt)
// computePositionsSmooth(positions)
// }
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) => {
// if (selectPoint) {
// let positions = [...this.options.line.positions]
// positions[selectPoint.index] = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
// selectPoint.position = cartesian
// computePositionsSmooth(positions)
// // that.options.positions[selectPoint.index] = that.cartesian3Towgs84(cartesian, that.sdk.viewer)
// // let positions = that.options.positions
// // let fromDegreesArray = []
// // for (let i = 0; i < positions.length; i++) {
// // fromDegreesArray.push(positions[i].lng, positions[i].lat, positions[i].alt)
// // }
// // newpositions = Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
// // if (that.options.positions.length === 1) {
// // that.label.position = [that.options.positions[0].lng, that.options.positions[0].lat, that.options.height]
// // }
// }
this.tip && this.tip.setPosition(
cartesian,
movement.endPosition.x,
movement.endPosition.y
)
})
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 (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
this.sdk.viewer._firstPersonView = v
this.options.firstPersonView = v
if (this.options.firstPersonView) {
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
}
}
else {
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) {
if (this.sdk.viewer.trackedEntity) {
this.sdk.viewer.entities.remove(this.sdk.viewer.trackedEntity)
}
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;
}
}
}
get viewFollow() {
return this.options.viewFollow
}
set viewFollow(v) {
this.options.viewFollow = v
if (!this.options.viewFollow) {
this.firstPersonView = false
}
else {
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) {
let pointEntity = this.sdk.viewer.entities.add({
// show: false,
position: this.current.position, // position of the point
point: {
color: Cesium.Color.RED.withAlpha(0), // color of the point
pixelSize: 0
}
});
this.sdk.viewer.trackedEntity = pointEntity;
}
}
this._elms.viewFollow && this._elms.viewFollow.forEach((item) => {
item.checked = v
})
}
moveCallBack(that) {
// if((that.lng || that.lng == 0) && (that.lat || that.lat == 0) && (that.alt || that.lat == 0)) {
// this._initial.position = {
// lng: that.lng,
// lat: that.lat,
// alt: that.alt,
// }
// }
// if(that.rotateX || that.rotateX == 0 ) {
// this._initial.pitch = that.rotateX
// }
// if(that.rotateY || that.rotateY == 0) {
// this._initial.roll = that.rotateY
// }
// if(that.rotateZ || that.rotateZ == 0) {
// this._initial.heading = that.rotateZ
// }
this.setPosition = that.setPosition.bind(that)
}
// get moveCallBack() {
// return this.options.moveCallBack
// }
// set moveCallBack(v) {
// this.options.moveCallBack = v
// }
get current() {
return this._current
}
set current(v) {
this._current = v
let pos = this.cartesian3Towgs84(this._current.position, this.sdk.viewer)
this.setPosition && this.setPosition({ ...this._current, position: { ...pos } })
}
// 创建路径
static addLine(that) {
let positions_smooth = that._renewLine(that.options.line.positions)
that.current.position = positions_smooth[0]
that.line = that.sdk.viewer.entities.add({
id: that.options.id + '-2',
show: that.options.show ? that.options.line.show : false,
polyline: {
positions: positions_smooth,
width: 2,
clampToGround: that.ground,
material: Cesium.Color.fromCssColorString('#ffffff'),
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,
zIndex: that.sdk._entityZIndex,
material: Cesium.Color.fromCssColorString('#ff0000')
},
})
that.sdk._entityZIndex++
let event = new MouseEvent(that.sdk)
event.mouse_right((movement, cartesian) => {
that.viewFollow = false
})
TrajectoryMotionObject.addKeyPoint(that)
that.noseToTail = that.options.line.noseToTail
that.smooth = that.options.line.smooth
}
// 创建模型
static addModel(that) {
// that.model = that.sdk.viewer.scene.primitives.add(
// Cesium.Model.fromGltf({
// id: that.options.id,
// url: that.options.model.url,
// show: that.options.show ? that.options.model.show : false,
// scale: that.options.model.scale,
// // minimumPixelSize: that.options.model.pixelSize,
// // maximumScale: 100000,
// // allowPicking: false
// })
// );
// let cartographic = Cesium.Cartographic.fromDegrees(103, 65, 100);
// let position = that.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
// // 设置模型的旋转角度,使其水平放置于地面
// let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(that.positions_smooth[0])
// that.model.modelMatrix = matrix
// that.model.position = that.positions_smooth[0]
// // 模型大小比例
// // 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)
// that.modelMove(pos)
// that.model.readyPromise.then(() => {
// that.modelAnimate = that.options.model.animate
// })
// that.entity = 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 }) {
let _this = this
let time = option.time || 0
let startDistance = option.distance || 0
let viewer = this.sdk.viewer
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' });
if(!this.totalTime) {
this.totalTime = (this.distance*1000) / this.options.speed // 总耗时(秒)
}
let totalTime = this.totalTime
if (time) {
if (time > totalTime) {
time = totalTime
}
startDistance = (time / totalTime) * this.distance
}
else {
// this._initial.position && (this._current.position = this.positions_smooth[0])
// if(this._initial.pitch || this._initial.pitch === 0) {
// this._current.pitch = this._initial.pitch
// }
// if(this._initial.roll || this._initial.roll === 0) {
// this._current.roll = this._initial.roll
// }
// if(this._initial.heading || this._initial.heading === 0) {
// this._current.heading = this._initial.heading
// }
}
let lastDistance = 0
let motionArray = []
let HeadingPitchRoll
let HeadingPitchRoll2
let previous = {}
let m = 0
let modelArray = []
for (let [key, value] of this.sdk.entityMap) {
if (value.type && value.type === 'glb') {
modelArray.push(value.entity)
}
}
let first = true
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) {
this.modelMove(positions)
}
}).onUpdate(async (r, a) => {
if (this.TweenAnimate._duration == Infinity) {
return
}
m++
if (!this.sdk.viewer) {
this.removeModelAnimate()
return
}
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)
}
async function setPosition(distance) {
let start = 0;
let stop = distance;
let coordinates
let sliced = line
if (stop) {
let 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 result = await _this.sdk.viewer.scene.clampToHeight(new Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1]), modelArray)
position = result
if (!position) {
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)
positionCamera = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], _this.cartesian3Towgs84(position, _this.sdk.viewer).alt + 1)
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)
coordinates = _this.cartesian3Towgs84(cartesian3, viewer);
position = Cesium.Cartesian3.fromDegrees(coordinates.lng, coordinates.lat, coordinates.alt)
positionCamera = Cesium.Cartesian3.fromDegrees(coordinates.lng, coordinates.lat, coordinates.alt + 1)
let positions_smooth = []
for (let i = 0; i <= 100; i++) {
if ((i / 100) > (distance / _this.distance)) {
break
}
let cartesian3 = _this.spline.evaluate(i / 100);
positions_smooth.push(cartesian3);
}
positions_smooth.push(cartesian3)
_this.realTimePositions = positions_smooth
}
HeadingPitchRoll = getHeadingPitchRoll(_this.current.position, position)
if (previous && previous.position) {
HeadingPitchRoll2 = getHeadingPitchRoll(previous.position, position)
HeadingPitchRoll.pitch = HeadingPitchRoll2.pitch
}
previous.position = _this.current.position
let modeHeadingPitchRoll = Cesium.HeadingPitchRoll.fromDegrees(_this.current.heading, _this.current.pitch, _this.current.roll)
let heading = 0
let pitch = 0
let roll = 0
if (_this.options.routeDirection) {
heading = (HeadingPitchRoll.heading - modeHeadingPitchRoll.heading) * (180 / Math.PI) - 90 + _this.current.heading
pitch = HeadingPitchRoll.pitch * (180 / Math.PI)
}
else {
heading = _this.current.heading
pitch = _this.current.pitch
}
roll = _this.current.roll
// console.log((HeadingPitchRoll.heading - modeHeadingPitchRoll.heading) * (180 / Math.PI))
if (isNaN(heading) || isNaN(pitch) || isNaN(roll)) {
return
}
if (heading < 0 || heading > 180) {
pitch = -pitch
}
_this.current = {
position: position,
heading: heading,
pitch: pitch,
roll: roll
}
if (first) {
first = false
_this._first = {
position: position,
heading: heading,
pitch: pitch,
roll: roll
}
}
lastDistance = distance
// console.log(position)
_this.realTimeRouteArray.push(position)
if (_this.viewFollow) {
// console.log(heading)
if (_this.options.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
}
})
}
else {
if (_this.sdk.viewer.trackedEntity) {
_this.sdk.viewer.trackedEntity.position = position
// _this.sdk.viewer.camera.position = position
}
}
}
}
// 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());
//heading
const heading = Math.atan2(direction.y, direction.x) - Cesium.Math.PI_OVER_TWO;
let pitch = Cesium.Math.PI_OVER_TWO - Cesium.Math.acosClamped(direction.z);
let a = pitch * (180 / Math.PI)
if (a < 0) {
// a = (-a)
}
pitch = a * (Math.PI / 180)
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._renewLine(this.options.line.positions)
this.modelMove(positions_smooth, { distance: distance })
}
setMovePositionByTime(time) {
let positions_smooth = this._renewLine(this.options.line.positions)
this.modelMove(positions_smooth, { time: time })
if (!this.state) {
this.modelMove(positions_smooth, { time: time+0.01 })
}
}
// 暂停
pause() {
this.state = false
}
// 继续
resume() {
this.state = true
}
async flyTo(options = {}) {
setActiveViewer(0)
closeRotateAround(this.sdk)
if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) {
let orientation = {
heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0),
pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0),
roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0)
}
let lng = this.options.customView.relativePosition.lng
let lat = this.options.customView.relativePosition.lat
let alt = this.options.customView.relativePosition.alt
let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
let position = { lng: 0, lat: 0 }
position = { ...this.options.line.positions[0] }
// 如果没有高度值,则获取紧贴高度计算
if (!position.hasOwnProperty('alt')) {
position.alt = await this.getClampToHeight(position)
}
lng = this.options.customView.relativePosition.lng + position.lng
lat = this.options.customView.relativePosition.lat + position.lat
alt = this.options.customView.relativePosition.alt + position.alt
destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
this.sdk.viewer.camera.flyTo({
destination: destination,
orientation: 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)
}
})
}
}
remove() {
// this.sdk.viewer.scene.primitives.remove(this.model)
this.event && this.event.destroy()
this.tip && this.tip.destroy()
this.sdk.viewer.entities.remove(this.line)
this.line = null
this.removeModelAnimate()
}
reset() {
this.modelMove(this.line.polyline.positions._value)
this.state = false
this.current = this._first
}
// 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
// }
// }
// 移除动画
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:
// }
// }
// }
}
_renewLine(pos) {
this.options.line.positions = 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 <= 100; i++) {
let cartesian3 = this.spline.evaluate(i / 100);
positions_smooth.push(cartesian3);
}
this.positions_smooth = positions_smooth
return positions_smooth
}
// 更新坐标
renewLinePositions(pos) {
this.options.line.positions = 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 <= 100; i++) {
let cartesian3 = this.spline.evaluate(i / 100);
positions_smooth.push(cartesian3);
}
this.positions_smooth = positions_smooth
if (this.line && this.line.polyline) {
this.line.polyline.positions = positions_smooth
}
return positions_smooth
}
flicker() { }
}
export default TrajectoryMotionObject