This commit is contained in:
zh
2025-09-01 16:17:11 +08:00
parent d802602200
commit 6fa99df21c
1035 changed files with 377083 additions and 1 deletions

View File

@ -0,0 +1,359 @@
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
}
}