吉安感知网项目-前端
罗广辉
2026-01-12 2dbd3103d91934a6ec6ef48baa288b56a4843472
applications/drone-command/src/utils/cesium/DrawPolygon.js
@@ -88,18 +88,18 @@
   // ============ 发布订阅机制 ============
   // 外部订阅数据变化
   subscribe (key, listener) {
   subscribe(key, listener) {
      this.listeners.push({ key, listener })
   }
   // 通知订阅者
   notify (key, data) {
   notify(key, data) {
      this.listeners.filter(subscriber => subscriber.key === key).forEach(subscriber => subscriber.listener(data))
   }
   // ============ 绘制相关 ============
   // 编辑图斑
   editThePatch (data) {
   editThePatch(data) {
      this.isPreviewMode = data
      // 关闭编辑能力时隐藏端点/中点,并清空中点,避免残留交互
      if (!this.isPreviewMode) {
@@ -117,12 +117,12 @@
      }
   }
   // 删除测区
   deleteTheArea (data) {
   deleteTheArea(data) {
      this.isDeleteTheArea = data
   }
   // 开始绘制
   startDrawing () {
   startDrawing() {
      this.drawingMode = true
      this.curPolygon = new Cesium.PolygonHierarchy()
@@ -150,7 +150,7 @@
   }
   // 创建多边形实体(含边界线)
   createPolygonEntity () {
   createPolygonEntity() {
      this.polygonEntity = this.editPolygonDataSource.entities.add({
         name: DrawPolygon.ENTITY_NAMES.POLYGON,
         id: DrawPolygon.ENTITY_NAMES.POLYGON_ID,
@@ -174,7 +174,7 @@
   }
   // 创建端点实体
   createPointEntity (position, isAdd) {
   createPointEntity(position, isAdd) {
      const pointIndex = isAdd ? this.curPolygon.positions.length - 2 : this.curPolygon.positions.length - 1
      this.editPolygonPointDataSource.entities.add({
@@ -193,7 +193,7 @@
      })
   }
   createMidPointEntity (startInd, position) {
   createMidPointEntity(startInd, position) {
      // 使用 CallbackProperty 让中点位置随端点拖拽实时计算
      // startInd 表示该中点属于边:(startInd) -> (startInd + 1)
      const updatePosition = () => {
@@ -224,7 +224,7 @@
      })
   }
   rebuildEditPoints () {
   rebuildEditPoints() {
      // 插入/删除端点后:端点实体 id 与 customData.ind 需要全量重建,保证索引与 positions 一致
      if (!this.isPreviewMode) return
      if (!this.editPolygonPointDataSource || !this.curPolygon?.positions) return
@@ -248,7 +248,7 @@
      })
   }
   rebuildMidPoints () {
   rebuildMidPoints() {
      // 仅在“顶点数量变化/切换编辑态”时维护中点实体数量
      // 拖拽过程中中点位置由 CallbackProperty 自动更新,不需要重建
      if (!this.isPreviewMode) return
@@ -286,7 +286,7 @@
      })
   }
   insertPointFromMidPoint (midPointEntity) {
   insertPointFromMidPoint(midPointEntity) {
      // 点击中点:在对应边上插入一个新端点(白点),并立即进入拖拽态
      if (!this.isPreviewMode) return
      if (!this.editingMode) return
@@ -319,7 +319,7 @@
      this.notify('getPolygonPositions', this.curPolygon.positions)
   }
   // 清除不在范围内的点
   removeLastInvalidPoint () {
   removeLastInvalidPoint() {
      const posLen = this.curPolygon.positions.length
      if (posLen === 0) return
@@ -348,7 +348,7 @@
      }
   }
   // 添加一个点
   addPosition (position, isAdd = true) {
   addPosition(position, isAdd = true) {
      // 第一个点要重复压入一次,形成动态绘制效果
      if (this.curPolygon.positions.length === 0 && isAdd) {
         this.curPolygon.positions.push(position.clone())
@@ -372,7 +372,7 @@
   // ============ 鼠标事件 ============
   // 鼠标左键按下(选中端点拖动)
   handleLeftDown (movement) {
   handleLeftDown(movement) {
      if (!this.editingMode) return
      const pickedEntity = this.viewer.scene.pick(movement.position)?.id
@@ -393,7 +393,7 @@
   }
   // 鼠标左键抬起(拖拽结束)
   handleLeftUp () {
   handleLeftUp() {
      if (!(this.editingMode && this.curPolygon?.positions && this.draggedEntity)) return
      if (this.currentDragPointIsValid && this.isDragging) {
@@ -426,7 +426,7 @@
   }
   // 鼠标移动
   handleMouseMove (movement) {
   handleMouseMove(movement) {
      if (!this.drawingMode && !this.editingMode) return
      const cartesian = this.viewer.scene.pickPosition(movement.endPosition)
@@ -464,7 +464,7 @@
   }
   // 鼠标左键点击
   handleLeftClick (click) {
   handleLeftClick(click) {
      this.removeMenuPopup()
      const pickedAllEntity = this.viewer.scene.drillPick(click.position).filter(i => i.id)
@@ -520,7 +520,7 @@
   }
   // 鼠标右键点击(弹出菜单)
   handleRightClick (click) {
   handleRightClick(click) {
      const that = this
      if (that.drawingMode) return
@@ -556,7 +556,7 @@
   // ============ 删除相关 ============
   // 删除所有实体
   removeEntities () {
   removeEntities() {
      if (this.editPolygonDataSource) {
         this.editPolygonDataSource.entities.removeAll()
         this.editPolygonDataSource = null
@@ -577,7 +577,7 @@
   }
   // 完成绘制
   finishDrawing () {
   finishDrawing() {
      this.curPolygon.positions.pop()
      if (this.curPolygon.positions.length >= 3) {
@@ -603,20 +603,20 @@
   }
   // 删除多边形
   delPolygon () {
   delPolygon() {
      this.removeEntities()
      this.removeMenuPopup()
      this.notify('getPolygonPositions', [])
      this.startDrawing()
   }
   // 删除图斑
   delSpot () {
   delSpot() {
      this.removeEntities()
      this.isPreviewMode = true
      this.startDrawing()
   }
   // 删除端点
   delPoint () {
   delPoint() {
      if (this.curPolygon.positions.length <= 3) {
         this.removeMenuPopup()
         return ElMessage.warning('端点不可少于3个')
@@ -634,7 +634,7 @@
   // ============ 工具方法 ============
   // 创建右键菜单
   createMenuPopup (type = 'polygon') {
   createMenuPopup(type = 'polygon') {
      const menuPopupVBox = document.createElement('div')
      menuPopupVBox.id = 'planarPolygonEdit'
      menuPopupVBox.className = 'planar-polygon-edit-tooltip'
@@ -660,7 +660,7 @@
   }
   // 移除菜单
   removeMenuPopup () {
   removeMenuPopup() {
      const that = this
      if (that.menuPopup) {
         that.menuPopup.removeEventListener('click', that.delPolygon)
@@ -672,13 +672,13 @@
   }
   // 更新多边形样式(正常/错误)
   updatePolygonAppearance (polygonColor, lineColor) {
   updatePolygonAppearance(polygonColor, lineColor) {
      this.polygonEntity.polygon.material = polygonColor
      this.polygonEntity.polyline.material = lineColor
   }
   // 禁用地图交互
   disableMapControl () {
   disableMapControl() {
      const controller = this.viewer.scene.screenSpaceCameraController
      controller.enableRotate = false
      controller.enableTranslate = false
@@ -686,7 +686,7 @@
   }
   // 启用地图交互
   enableMapControl () {
   enableMapControl() {
      const controller = this.viewer.scene.screenSpaceCameraController
      controller.enableRotate = true
      controller.enableTranslate = true
@@ -694,7 +694,7 @@
   }
   // 检查多边形是否自交
   curDragPointIsValid (positions) {
   curDragPointIsValid(positions) {
      if (positions.length < 3) return true
      const cartographics = Cesium.Ellipsoid.WGS84.cartesianArrayToCartographicArray(positions)
@@ -710,12 +710,12 @@
      return intersections.features.length === 0
   }
   // 初始化已有多边形
   async initPolygon (viewer, positions, isPurePreview = false) {
   async initPolygon(viewer, positions, isPurePreview = false) {
      this.initHandler(viewer)
      this.isPureSpotPreview = isPurePreview
      this.startDrawing()
      let newPosition = positions.map(item => {
         return Cesium.Cartesian3.fromDegrees(Number(item.lng), Number(item.lat), Number(item?.height||0))
         return Cesium.Cartesian3.fromDegrees(Number(item.lng), Number(item.lat), Number(item?.height || 0))
      })
      // 预览航线的时候调用
      if (!this.isPureSpotPreview) {
@@ -737,7 +737,7 @@
         duration: 0.5,
      })
      const pointList = await getPointPositionsHeight(positions, viewer)
      let pointList = await getPointPositionsHeight(positions, viewer)
      flyVisual({ positionsData: pointList.map(item => [item.lng, item.lat, item.ASL]), viewer })
      this.drawingMode = false
@@ -748,7 +748,7 @@
   }
   // 初始化事件处理器
   initHandler (viewer) {
   initHandler(viewer) {
      this.viewer = viewer
      this.startDrawing()
@@ -771,7 +771,7 @@
   }
   // 移除事件处理器
   removeHandler () {
   removeHandler() {
      if (this.handler) {
         const eventTypes = [
            Cesium.ScreenSpaceEventType.LEFT_DOWN,
@@ -792,7 +792,7 @@
   /**
    * 销毁实例,释放资源
    */
   destroy () {
   destroy() {
      if (!this.viewer) return
      this.removeMenuPopup()