273 lines
9.3 KiB
JavaScript
273 lines
9.3 KiB
JavaScript
|
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)
|
|||
|
}
|
|||
|
}
|