Files
sdk4.0_new/src/Obj/AirLine/pointRoute.js
2025-09-01 16:17:11 +08:00

360 lines
11 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 FRUSTUN from './frustum.js'
import BillordPointLine from './billord_point_line'
export default class PointRoute {
constructor(options = {}, viewer, viewer1) {
this.options = { ...options }
this.viewer = viewer
this.viewer1 = viewer1
this.entity = null
this.frustum = null
this.billordPointLineMaps = []
this.index = 0
this.positions = []
PointRoute.setDefaultValue(this)
this.create()
}
static setDefaultValue(that) {
that.options.positions = that.options.positions || []
that.options.show = that.options.show || true
that.options.color = that.options.color || '#00d590'
that.options.height = that.options.height || 500
that.options.speed = that.options.speed || 1
that.options.frustumShow = that.options.frustumShow ?? true
that.options.saveFun = that.options.saveFun || null
that.options.selectFun = that.options.selectFun || null
that.options.keyboard = that.options.keyboard ?? true
that.options.normalHeight = that.options.normalHeight || 100
that.options.airHeight = that.options.airHeight || 100
}
create() {
if (this.options.positions.length < 2) {
return
}
let that = this
let { frustumShow } = that.options
this.entity = this.viewer.entities.add({
show: this.options.show,
polyline: {
positions: new Cesium.CallbackProperty(() => {
let positions = []
for (let i = 0; i < this.billordPointLineMaps.length; i++) {
const element = this.billordPointLineMaps[i]
positions.push(element.billboardEntity.position.getValue())
}
return positions
}, false),
width: 3,
material: Cesium.Color.fromCssColorString(this.options.color)
}
})
// 创建点、线、billbord
for (let i = 0; i < this.options.positions.length; i++) {
const element = this.options.positions[i]
// console.log("elementelementelement", element);
if (frustumShow && i == this.index) {
this.frustum = new FRUSTUN(
{
position: element,
show: false,
arr: this.options.positions,
index: i,
normalHeight: this.options.normalHeight
},
this.viewer,
this.viewer1
)
}
let op = new BillordPointLine(
{
positions: element,
index: i + 1,
saveFun: that.options.saveFun,
selectFun: that.options.selectFun,
keyboard: that.options.keyboard,
updateFrustumFun: that.updateFrustumPosition,
normalHeight: that.options.normalHeight,
frustum: that.frustum,
airHeight: that.options.airHeight
},
this.viewer
)
this.billordPointLineMaps.push(op)
}
this.onKey()
}
get show() {
return this.options.show
}
set show(bool) {
if (typeof bool === 'boolean') {
this.frustum.currentFrustumOutline.show = bool
this.billordPointLineMaps.forEach(item => {
item.show = bool
})
this.entity.show = bool
}
}
// 监听键盘事件
onKey() {
let that = this
document.addEventListener('keydown', function(event) {
switch (event.key) {
case 'ArrowUp':
that.index += 1
that.updateFrustum(true)
break
case 'ArrowDown':
that.index -= 1
that.updateFrustum(false)
break
}
})
}
// 更新frustum
updateFrustum(flag) {
console.log(this.index)
let obj
if (this.index > this.options.positions.length - 1 || this.index < 0) {
let str = this.index > 0 ? '已选中最后一个航点' : '已选中第一个航点'
alert(str)
return
}
for (let i = 0; i < this.billordPointLineMaps.length; i++) {
const element = this.billordPointLineMaps[i]
const hpr = null
if (i == this.index) {
let position = element.billboardEntity.position.getValue()
if (this.index !== 0) {
obj = this.direction(
this.billordPointLineMaps[
i - 1
].billboardEntity.position.getValue(),
element.billboardEntity.position.getValue()
)
hpr = obj.hpr
}
if (this.index == 0) {
obj = this.direction(
this.billordPointLineMaps[0].billboardEntity.position.getValue(),
this.billordPointLineMaps[1].billboardEntity.position.getValue()
)
hpr = obj.hpr
}
if (hpr) {
this.frustum.updateFrustumHPR(
hpr.heading,
this.frustum.pitch,
hpr.roll
)
}
if (position) {
this.frustum.updateFrustumPosition('update', position)
}
}
}
}
cartesian3Towgs84(cartesian) {
var ellipsoid = this.viewer.scene.globe.ellipsoid
var cartesian3 = new Cesium.Cartesian3(
cartesian.x,
cartesian.y,
cartesian.z
)
var cartographic = ellipsoid.cartesianToCartographic(cartesian3)
var lat = Cesium.Math.toDegrees(cartographic.latitude)
var lng = Cesium.Math.toDegrees(cartographic.longitude)
var alt = cartographic.height < 0 ? 0 : cartographic.height
return {
lng: lng,
lat: lat,
alt: alt
}
}
// 计算一个到另一个点的方向
direction(pointA, pointB) {
//向量AB
const vector2 = Cesium.Cartesian3.subtract(
pointA,
pointB,
new Cesium.Cartesian3()
)
//归一化
const normal = Cesium.Cartesian3.normalize(vector2, new Cesium.Cartesian3())
//旋转矩阵 rotationMatrixFromPositionVelocity源码中有并未出现在cesiumAPI中
const rotationMatrix3 = Cesium.Transforms.rotationMatrixFromPositionVelocity(
pointA,
normal,
Cesium.Ellipsoid.WGS84
)
const modelMatrix4 = Cesium.Matrix4.fromRotationTranslation(
rotationMatrix3,
pointA
)
// 获取getHeadingPitchRoll
let m1 = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Matrix4.getTranslation(modelMatrix4, new Cesium.Cartesian3()),
Cesium.Ellipsoid.WGS84,
new Cesium.Matrix4()
)
// 矩阵相除
let m3 = Cesium.Matrix4.multiply(
Cesium.Matrix4.inverse(m1, new Cesium.Matrix4()),
modelMatrix4,
new Cesium.Matrix4()
)
// 得到旋转矩阵
let mat3 = Cesium.Matrix4.getMatrix3(m3, new Cesium.Matrix3())
// 计算四元数
let q = Cesium.Quaternion.fromRotationMatrix(mat3)
// 计算旋转角(弧度)
let hpr = Cesium.HeadingPitchRoll.fromQuaternion(q)
// hpr.pitch = hpr.pitch + 3.14 / 2 + 3.14;
hpr.pitch = 90
let orientation = Cesium.Transforms.headingPitchRollQuaternion(pointA, hpr)
return { hpr, orientation }
}
/**
*
* @param {index} 索引
*/
// 删除航点
delPosition(index) {
this.options.positions.splice(index, 1)
// this.options.positions = this.options.positions.filter((item, index) => index !== i);
this.remove()
this.create()
}
// 获取最新的positions
getNewPositions() {
let positions = []
for (let i = 0; i < this.billordPointLineMaps.length; i++) {
const element = this.billordPointLineMaps[i]
let position = this.cartesian3Towgs84(
element.billboardEntity.position.getValue()
)
positions.push(position)
}
return positions
}
// 删除
remove() {
this.billordPointLineMaps.forEach((item, i) => {
item.remove()
})
if (this.frustum) {
this.frustum.remove()
}
this.viewer.entities.remove(this.entity)
this.billordPointLineMaps = []
}
/**
*
* @param {String} type
* @param {Number} index
* @param {Array} position
*/
// 新增航点 beforeafterend
addPoint(positions) {
this.options.positions = positions
this.remove()
this.create()
}
// 根据选中的点更新视锥的位置
updateFrustumPosition(index) {
if (!this.billordPointLineMaps || this.billordPointLineMaps.length === 0)
return
if (this.frustum) {
this.frustum.show = true
}
let current = this.billordPointLineMaps[
index
].billboardEntity.position.getValue()
if (index !== 0) {
let obj
let after =
index === this.billordPointLineMaps.length - 1
? this.billordPointLineMaps[
index - 1
].billboardEntity.position.getValue() // 获取前一个位置
: this.billordPointLineMaps[
index + 1
].billboardEntity.position.getValue() // 获取下一个位置
obj = this.direction(
index === this.billordPointLineMaps.length - 1 ? after : current,
index === this.billordPointLineMaps.length - 1 ? current : after
)
let { hpr } = obj
this.frustum.updateFrustumHPR(
hpr.heading,
Cesium.Math.toRadians(this.frustum.pitch),
hpr.roll
)
} else {
let obj
let after = this.billordPointLineMaps[1].billboardEntity.position.getValue()
obj = this.direction(current, after)
let { hpr } = obj
this.frustum.updateFrustumHPR(
hpr.heading,
Cesium.Math.toRadians(this.frustum.pitch),
hpr.roll
)
}
if (current) {
this.frustum.updateFrustumPosition('update', current)
}
let position = this.cartesian3Towgs84(current)
this.billordPointLineMaps.forEach(item => {
item.billboardEntity.label.show = false // 先将所有元素的 label.show 设置为 false
})
const targetItem = this.billordPointLineMaps.find(
item => item.billboardEntity.index == index + 1
)
if (targetItem) {
targetItem.billboardEntity.label.show = true // 然后找到匹配的 index 设置为 true
}
return position
}
flyTo() {
let positionArray = []
for (let i = 0; i < this.options.positions.length; i++) {
let a = Cesium.Cartesian3.fromDegrees(
this.options.positions[i].lng,
this.options.positions[i].lat,
this.options.positions[i].alt + this.options.height
)
positionArray.push(a.x, a.y, a.z)
}
let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray)
this.viewer.camera.flyToBoundingSphere(BoundingSphere, {
offset: {
heading: Cesium.Math.toRadians(0.0),
pitch: Cesium.Math.toRadians(-80.0),
roll: Cesium.Math.toRadians(0.0)
}
})
}
//计算航线的长度
countLength() {
if (this.options.positions.length < 2) {
return 0
} else {
let lineString = []
this.options.positions.forEach(item => {
lineString.push([item.lng, item.lat])
})
var line = turf.lineString(lineString)
return (turf.length(line) * 1000).toFixed(2)
}
}
//计算航线时间
countTime() {
let time = Math.floor(Number(this.countLength())) / this.options.speed
let s = Math.floor(time % 60)
let m = Math.floor(time / 60)
let str = m + '分' + s + '秒'
return str
}
}