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)
|
||
}
|
||
}
|