Files
sdk4.0_new/src/Obj/Base/TrajectoryMotionObject/index.js

1198 lines
41 KiB
JavaScript
Raw Normal View History

2025-09-01 16:17:11 +08:00
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._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.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.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