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,272 @@
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)
}
}