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

273 lines
9.3 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.

export default class BillordPointLine {
constructor(options, viewer) {
this.options = { ...options }
this.pointEntity = null
this.billboardEntity = null
this.lineEntity = null
this.updatedPosition = []
this.pointUpdatedPosition = []
this.viewer = viewer
this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
this.pinBuilder = new Cesium.PinBuilder()
this.index = null
//定义屏幕点击事件处理器
BillordPointLine.setDefaultValue(this)
BillordPointLine.init(this)
}
static setDefaultValue(that) {
that.options.positions = that.options.positions || {}
that.options.normalHeight = that.options.normalHeight || 100
that.options.airHeight = that.options.airHeight || 100
that.options.image = that.options.image || '/static/img/cluster2.png'
that.options.show = that.options.show || true
that.options.index = that.options.index || 1
that.options.saveFun = that.options.saveFun || null
that.options.selectFun = that.options.selectFun || null
that.options.keyboard = that.options.keyboard ?? true
that.options.updateFrustumFun = that.options.updateFrustumFun || null
that.options.frustum = that.options.frustum || null
}
static init(that) {
let positions = that.options.positions
// 添加一个Point稍微偏离地面高度使其完全可见
that.pointEntity = that.viewer.entities.add({
show: that.options.show,
position: Cesium.Cartesian3.fromDegrees(positions.lng, positions.lat, 0), // 地面上
point: {
pixelSize: 8,
color: Cesium.Color.WITHE,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, // 使用相对地面或贴地,
disableDepthTestDistance: 0
}
})
//
let pinIndex = that.pinBuilder
.fromText(
that.options.index,
Cesium.Color.fromCssColorString('#00d590'),
36
)
.toDataURL()
let altitude = 0
if (positions.altitude) {
altitude = positions.altitude
} else {
altitude = that.options.normalHeight
}
// 添加一个Billboard
that.billboardEntity = that.viewer.entities.add({
show: that.options.show,
position: Cesium.Cartesian3.fromDegrees(
positions.lng,
positions.lat,
positions.alt + that.options.normalHeight
),
// 判断altitude是否有值
label: {
text: `Lat: ${positions.lng.toFixed(8)}\nLon: ${positions.lat.toFixed(
8
)}\nAlt: ${altitude.toFixed(8)}m`,
font: '14px sans-serif',
fillColor: Cesium.Color.YELLOW,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
pixelOffset: new Cesium.Cartesian2(0, -60), // 标签偏移量,防止重叠
heightReference: Cesium.HeightReference.RELATIVE_TO_TERRAIN, // 确保标签与地面贴合
show: false
},
billboard: {
image: pinIndex, // 示例图像路径
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 图像底部对齐
width: 36,
height: 36
},
index: that.options.index
})
// 创建一个连接Point和Billboard的竖线
that.lineEntity = that.viewer.entities.add({
show: that.options.show,
polyline: {
positions: new Cesium.CallbackProperty(() => {
return [
that.pointEntity.position.getValue(),
that.billboardEntity.position.getValue()
]
}, false),
width: 1,
material: new Cesium.PolylineOutlineMaterialProperty({
outlineColor: Cesium.Color.GAINSBORO,
outlineWidth: 1,
color: Cesium.Color.WITHE
}),
zIndex: 99999999
}
})
if (that.options.keyboard) {
that.changeAltitude()
}
that.handler.setInputAction(function(movement) {
var pickedObject = that.viewer.scene.pick(movement.position)
if (
Cesium.defined(pickedObject) &&
Cesium.defined(pickedObject.id) &&
pickedObject.id === that.billboardEntity
) {
if (that.options.selectFun) {
that.options.selectFun(that.billboardEntity.index - 1)
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
}
// 改变高度
changeAltitude() {
var isMouseDown = false
var startPosition
var initialHeight
let that = this
let HHH = false
// 标识Alt键是否被按下
document.addEventListener('keydown', function(event) {
const key = event.key // 获取按下的键名
// 检查特定键是否被按下
if (key === 'h') {
HHH = true
}
})
document.addEventListener('keyup', function(event) {
HHH = false
})
// 按下鼠标左键
this.handler.setInputAction(function(movement) {
var pickedObject = that.viewer.scene.pick(movement.position)
if (
Cesium.defined(pickedObject) &&
Cesium.defined(pickedObject.id) &&
pickedObject.id === that.billboardEntity
) {
isMouseDown = true
startPosition = movement.position
// 获取Billboard当前的地理高度
var positionCartographic = Cesium.Cartographic.fromCartesian(
that.billboardEntity.position.getValue()
)
initialHeight = positionCartographic.height
}
}, Cesium.ScreenSpaceEventType.LEFT_DOWN)
// 移动鼠标
this.handler.setInputAction(function(movement) {
if (isMouseDown && HHH == false) {
// 移动位置
var newCartesian = that.viewer.scene.pickPosition(movement.endPosition)
that.disableCameraDrag(that.viewer, false)
if (newCartesian) {
var newCartographic = Cesium.Cartographic.fromCartesian(newCartesian)
// 保持高度不变
var newLongitude = newCartographic.longitude
var newLatitude = newCartographic.latitude
var updatedPosition = Cesium.Cartesian3.fromRadians(
newLongitude,
newLatitude,
initialHeight
)
var pointUpdatedPosition = Cesium.Cartesian3.fromRadians(
newLongitude,
newLatitude,
0
)
that.billboardEntity.position = new Cesium.CallbackProperty(() => {
return updatedPosition
}, false)
that.billboardEntity.label.text = `Lat: ${Cesium.Math.toDegrees(
newLongitude
).toFixed(6)}\nLon: ${Cesium.Math.toDegrees(newLatitude).toFixed(
6
)}\nAlt: ${initialHeight.toFixed(2)}m`
that.pointEntity.position = new Cesium.CallbackProperty(() => {
return pointUpdatedPosition
}, false)
}
}
if (isMouseDown && HHH) {
console.log(HHH)
// 改变高度
var endPosition = movement.endPosition
var deltaY = startPosition.y - endPosition.y // 计算Y轴方向上的移动距离
// 根据鼠标移动的距离来调整高度
var newHeight = initialHeight + deltaY
// 更新billboard位置
var positionCartographic = Cesium.Cartographic.fromCartesian(
that.billboardEntity.position.getValue()
)
var newPosition = Cesium.Cartesian3.fromDegrees(
Cesium.Math.toDegrees(positionCartographic.longitude),
Cesium.Math.toDegrees(positionCartographic.latitude),
newHeight
)
// 禁用相机
that.disableCameraDrag(that.viewer, false)
that.billboardEntity.position = new Cesium.CallbackProperty(() => {
return newPosition
}, false)
that.billboardEntity.label.text = `Lat: ${Cesium.Math.toDegrees(
positionCartographic.longitude
).toFixed(6)}\nLon: ${Cesium.Math.toDegrees(
positionCartographic.latitude
).toFixed(6)}\nAlt: ${newHeight.toFixed(2)}m`
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
// 松开鼠标左键
this.handler.setInputAction(function(movement) {
var pickedObject = that.viewer.scene.pick(movement.position)
isMouseDown = false // 禁用相机
HHH = false //
that.disableCameraDrag(that.viewer, true)
// 更新frustum的位置
if (
Cesium.defined(pickedObject) &&
Cesium.defined(pickedObject.id) &&
pickedObject.id === that.billboardEntity
) {
if (that.options.saveFun) {
that.options.saveFun(null, false)
}
if (that.options.selectFun) {
that.options.selectFun(that.billboardEntity.index - 1)
}
that.options.frustum.updatePositionHeight(
that.billboardEntity.position.getValue()
)
}
}, Cesium.ScreenSpaceEventType.LEFT_UP)
}
disableCameraDrag(viewer, bool) {
viewer.scene.screenSpaceCameraController.enableRotate = bool
viewer.scene.screenSpaceCameraController.enableTranslate = bool
viewer.scene.screenSpaceCameraController.enableZoom = bool
viewer.scene.screenSpaceCameraController.enableTilt = bool
viewer.scene.screenSpaceCameraController.enableLook = bool
}
get show() {
return this.options.show
}
/**
* @param {boolean} bool
*/
set show(bool) {
if (typeof bool === 'boolean') {
this.pointEntity.show = bool
this.billboardEntity.show = bool
this.lineEntity.show = bool
}
}
remove() {
this.viewer.entities.remove(this.pointEntity)
this.viewer.entities.remove(this.billboardEntity)
this.viewer.entities.remove(this.lineEntity)
}
}