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