类名 common/sketchEditor/base/SketchPointDrawTool.js
import { Feature, ViewEventType, SketchDataType, Projection } from '../../base'
import { Point, Extent } from '../../base/geometry'
import SketchBaseDrawTool from './SketchBaseDrawTool'
import SketchStyle from './SketchStyle'
/**
 * 点绘图工具类
 * @class SketchPointDrawTool
 * @moduleEX SketchEditorModule
 * @extends SketchBaseDrawTool
 * @param {Object} options 构造参数
 * @param {MapView|SceneView}  [options.view]  地图视图对象
 * @param {GraphicsLayer}  [options.layer]  草图图层管对象
 * @param {SketchStyle}  [options.sketchStyle]  草图符号
 */

class SketchPointDrawTool extends SketchBaseDrawTool {
  constructor(options) {
    super(options)
    // 初始化事件
    this._initEvent()
    this._drawTools = [this]
    this._otherDrawTools = []
  }

  /**
   * 初始化事件
   * @private
   */
  _initEvent() {
    this._processEvent = this._processEvent.bind(this)
    this.on('pan', this._processEvent)
  }

  getPanEvent(event, target, type) {
    const _event = {
      event,
      target,
      type
    }
    return _event
  }

  /**
   * @description 鼠标绘制图形
   */
  drawFeature() {
    const handler = (options) => {
      if (!options || !options.x || !options.y) return
      const pixelCoord = { x: options.x, y: options.y }
      const geoCoord = this.view.toMap({ x: pixelCoord.x, y: pixelCoord.y })
      // if (this._hight) {
      //   geoCoord = new Point({
      //     coordinates: [
      //       geoCoord.coordinates[0],
      //       geoCoord.coordinates[1],
      //       this._hight
      //     ],
      //     spatialReference: this._spatialReference
      //   })
      // }
      geoCoord._pixelCoords = pixelCoord
      const feature = this._getFeature(geoCoord)

      this.sketchStage.entityGraphic = feature
      this._addFeaturesToMap(feature)

      this._editMode = 3
      this.stop()
      this._editMode = 0
      // 发送绘制完成事件
      this.fire('drawn', { geometry: feature.geometry }, self)
    }
    this._drawEventHandlers.push(handler)
    this.view.on(ViewEventType.pointerDown, handler)
  }

  /**
   * 删除选中的顶点
   * @private
   */
  deleteSelectedVertex(feature) {}

  updateSelectedVertex() {}

  /**
   * @description 添加图形
   * @param {Point} point 生成图形的点数据
   * @param {SketchStyle} sketchStyle 线的符号样式
   * @param {Object} attributes feature图形的属性
   */
  addFeature(point, sketchStyle, attributes) {
    let vertexStyle = null
    if (!sketchStyle || !sketchStyle.vertexStyle) {
      vertexStyle = this.sketchStyle._vertexStyle
    } else {
      vertexStyle = sketchStyle.vertexStyle
    }

    const feature = this._getFeature(point, vertexStyle)
    if (attributes) {
      feature.attributes = attributes
    }
    this.sketchStage.entityGraphic = feature

    // 更新图层图形
    this._addFeaturesToMap(feature)
  }

  /**
   * @description 添加图形
   * @param {Geometry} geometry 生成图形的点数据
   * @param {SketchStyle} sketchStyle 线的符号样式
   * @param {Object} attributes feature图形的属性
   */
  addFeatureByGeometry(geometry, sketchStyle, attributes) {
    let symbol = null
    if (!sketchStyle || !sketchStyle.vertexStyle) {
      symbol = this.sketchStyle._vertexStyle
    } else {
      symbol = sketchStyle.vertexStyle
    }
    const feature = new Feature({
      geometry,
      symbol
    })
    if (attributes) {
      feature.attributes = attributes
    }
    this.sketchStage.entityGraphic = feature

    // 更新图层图形
    this._addFeaturesToMap(feature)
  }

  /**
   * @description 获取feature实例
   * @private
   * @param {Point} point 生成图形的点数据
   * @param {Symbol} symbol 点的符号样式
   */
  _getFeature(point, symbol) {
    if (!point) {
      point = Projection.project(
        new Point({
          coordinates: [0, 0, 0]
        }),
        this._spatialReference
      )
    }
    if (!symbol) {
      symbol = this.sketchStyle.vertexStyle
    }
    const pointGeometry = new Feature({
      geometry: point,
      symbol
    })

    return pointGeometry
  }

  /**
   * @description 捕获草图
   * @param {Feature} feature 被选中feature对象
   * @param {Object} event 选中事件参数
   */
  hitTestFeature(feature, event) {
    if (this.editOption.showSelectBox) {
      // 高亮点元素,用新图形代替高亮,展示选中图形时的辅助图形
      this._editMode = 1
      this.selectFeature(feature)
    } else {
      // 如果父级草图是点,则是移动点草图。 如果父级草图是区、线,则是缩放区、线草图。
      // eslint-disable-next-line no-lonely-if
      if (this._parent._sketchDataType === SketchDataType.POINT) {
        // 平移事件
        this.startPanGraphics(feature, event)
      } else if (this._parent && this._parent._editMode === 1) {
        if (feature.attributes.type === 'circleVertex') {
          // 圆上点缩放事件
          this.startCircleVertexScaleGraphics(feature, event)
        } else if (feature.attributes.type === 'midVertex') {
          // 边上中点缩放事件
          this.startMidVertexScaleGraphics(feature, event)
        } else {
          // 四个角顶点缩放事件
          this.startVertexScaleGraphics(feature, event)
        }
      } else if (this._parent && this._parent._editMode === 2) {
        // 修改顶点事件
        this.startVertexMoveGraphics(feature, event)
      }
    }
  }

  /**
   * @description 编辑时选中草图这个feature图形
   * @private
   * @param {Feature} feature 被选中feature对象
   */
  selectFeature(feature) {
    if (!this.editOption.showSelectBox) return
    // 加载选时的辅助图形,高亮的点
    const pointDrawTool = new SketchPointDrawTool({
      view: this.view,
      layer: this.layer,
      sketchStyle: new SketchStyle({
        vertexStyle: this.sketchStyle._selectVertexStyle
      }),
      editOption: {
        showSelectBox: false,
        _hitTestMode: 1
      },
      _parent: this // 或者只传父级相应pan的事件
    })
    const point = feature.geometry
    // this._hitTestDrawToolStack.push(pointDrawTool)
    this._drawTools.push(pointDrawTool)
    // 图形加到layer上
    pointDrawTool.addFeatureByGeometry(point)
    // 注册hitTest事件移动图形
    this.sketchStage.selectBoxGraphics = [
      pointDrawTool.sketchStage.entityGraphic
    ]
    this._otherDrawTools.push(pointDrawTool)

    // 添加到undoRedoManager中
    if (this.undoRedoManager) {
      this.undoRedoManager.addProcess('add', this.sketchStage)
    }

    // 点击到地图没有feature图形区域,退出编辑
    if (
      // !this._mapClickEvent &&
      !this._parent ||
      (this._parent && !this._parent._mapClickEvent)
    ) {
      this._mapClickEvent = () => {
        const removedFeatures = this.sketchStage.selectBoxGraphics
        removedFeatures.forEach((feature) => {
          this._removeFeatureFromMap(feature)
        })
        this.view.off(ViewEventType.immediateClick, this._mapClickEvent)
        // this._mapClickEvent = null
        // 发送草图没有被选中状态
        this.fire('selected', { isSelected: false }, self)
        this.sketchStage.selectBoxGraphics = []
      }
      setTimeout(() => {
        this._hitTestEventHandlers.push(this._mapClickEvent)
        this.view.on(ViewEventType.immediateClick, this._mapClickEvent)
      }, 0)
    }
  }

  setSketchStyle(sketchStyle) {
    this.sketchStyle = sketchStyle
  }

  /**
   * @description 平移图形
   * @private
   * @param {Feature} feature 被选中feature对象
   * @param {Object} event
   */
  startPanGraphics(feature, event) {
    this.view._mapActionControl('drag-pan', false)
    const timer = null
    let moving = false
    this._startPan = true
    let startPoint = null
    // if (this._hight) {
    //   startPoint = new Point({
    //     coordinates: [
    //       event.mapPoint.coordinates[0],
    //       event.mapPoint.coordinates[1],
    //       this._hight
    //     ],
    //     spatialReference: this._spatialReference
    //   })
    // } else {
    //   startPoint = event.mapPoint
    // }
    startPoint = event.mapPoint
    // 移除父级草图地图点击事件。点图形仍然会触发mapClick事件。
    if (this._parent && this._parent._mapClickEvent) {
      this.view.off(ViewEventType.immediateClick, this._parent._mapClickEvent)
    }

    // 鼠标平移
    const handlerMove = (options) => {
      if (!options || !options.x || !options.y) return
      if (moving) return
      if (!this._startPan) return
      clearTimeout(timer)
      moving = true

      const pixelCoord = { x: options.x, y: options.y }
      const movePoint = this.view.toMap({
        x: pixelCoord.x,
        y: pixelCoord.y
      })
      // if (this._hight) {
      //   movePoint = new Point({
      //     coordinates: [
      //       movePoint.coordinates[0],
      //       movePoint.coordinates[1],
      //       this._hight
      //     ],
      //     spatialReference: this._spatialReference
      //   })
      // }
      const deltaX = movePoint.coordinates[0] - startPoint.coordinates[0]
      const deltaY = movePoint.coordinates[1] - startPoint.coordinates[1]
      if (deltaX === 0 && deltaY === 0) {
        moving = false
        return
      }
      const newCoordinates = this.getPanCoordinates(
        this.sketchStage.entityGraphic.geometry.coordinates,
        deltaX,
        deltaY
      )
      startPoint.coordinates = newCoordinates
      this.sketchStage.entityGraphic.geometry.coordinates = newCoordinates
      moving = false
    }
    // 鼠标平移完成事件,移除平移事件
    const handlerUp = () => {
      if (!this._startPan) {
        return
      }
      this._startPan = false
      this.view.off(ViewEventType.pointerUp, handlerUp)
      this.view.off(ViewEventType.pointerMove, handlerMove)

      this.view._mapActionControl('drag-pan', true)

      // 添加到undoRedoManager中
      if (this._parent && this._parent.undoRedoManager) {
        this._parent.undoRedoManager.addProcess(
          'update',
          this._parent.sketchStage
        )
      }
      // 重新注册父级草图地图点击事件
      if (this._parent && this._parent._mapClickEvent) {
        this.view.on(ViewEventType.immediateClick, this._parent._mapClickEvent)
      }
      this.view._mapActionControl('drag-pan', true)
    }
    // 注册平移时的鼠标事件事件
    this._hitTestEventHandlers.push(handlerMove)
    this._hitTestEventHandlers.push(handlerUp)
    this.view.on(ViewEventType.pointerUp, handlerUp)
    this.view.on(ViewEventType.pointerMove, handlerMove)
  }

  /**
   * @description 顶点缩放
   * @private
   * @param {Feature} feature 被选中feature对象
   * @param {Object} event
   */
  startVertexScaleGraphics(feature, event) {
    this.view._mapActionControl('drag-pan', false)
    const timer = null
    let moving = false
    this._startPan = true
    let startPoint = null
    // if (this._hight) {
    //   startPoint = new Point({
    //     coordinates: [
    //       event.mapPoint.coordinates[0],
    //       event.mapPoint.coordinates[1],
    //       this._hight
    //     ],
    //     spatialReference: this._spatialReference
    //   })
    // } else {
    //   startPoint = event.mapPoint
    // }
    startPoint = event.mapPoint
    let parentExtent
    if (this._parent.sketchStage.entityGraphic.geometry instanceof Extent) {
      parentExtent = this._parent.sketchStage.entityGraphic.geometry
    } else {
      parentExtent = this._parent.sketchStage.entityGraphic.geometry.extent
    }
    // 移除父级草图地图点击事件。点图形仍然会触发mapClick事件。
    if (this._parent && this._parent._mapClickEvent) {
      this.view.off(ViewEventType.immediateClick, this._mapClickEvent)
    }
    // 获取当前移动点的方位
    // const getDirection = function (xy, extent) {
    //   let direction = null
    //   const centerXY = [
    //     (extent.xmax + extent.xmin) / 2,
    //     (extent.ymax + extent.ymin) / 2
    //   ]
    //   if (xy[0] >= centerXY[0] && xy[1] >= centerXY[1]) {
    //     direction = 'ne'
    //   } else if (xy[0] >= centerXY[0] && xy[1] < centerXY[1]) {
    //     direction = 'se'
    //   } else if (xy[0] < centerXY[0] && xy[1] < centerXY[1]) {
    //     direction = 'sw'
    //   } else if (xy[0] < centerXY[0] && xy[1] >= centerXY[1]) {
    //     direction = 'nw'
    //   }
    //   return direction
    // }
    // const direction = getDirection(feature.geometry.coordinates, parentExtent)
    const direction = feature.attributes.direction

    // 鼠标平移
    const handlerMove = (options) => {
      if (!options || !options.x || !options.y) return
      if (moving || !this._startPan) return
      clearTimeout(timer)
      moving = true

      const pixelCoord = { x: options.x, y: options.y }
      const movePoint = this.view.toMap({
        x: pixelCoord.x,
        y: pixelCoord.y
      })
      // if (this._hight) {
      //   movePoint = new Point({
      //     coordinates: [
      //       movePoint.coordinates[0],
      //       movePoint.coordinates[1],
      //       this._hight
      //     ],
      //     spatialReference: this._spatialReference
      //   })
      // }
      const deltaX = movePoint.coordinates[0] - startPoint.coordinates[0]
      const deltaY = movePoint.coordinates[1] - startPoint.coordinates[1]
      const scaleX = movePoint.coordinates[0] / startPoint.coordinates[0]
      const scaleY = movePoint.coordinates[1] / startPoint.coordinates[1]
      if (deltaX === 0 && deltaY === 0) {
        moving = false
        return
      }
      this._dispatchEvent(
        'vertexScale',
        {
          startPoint,
          movePoint,
          deltaPosition: { x: deltaX, y: deltaY },
          scale: { x: scaleX, y: scaleY },
          direction,
          extent: parentExtent,
          feature,
          action: 'scale'
        },
        this
      )
      moving = false
    }
    const handlerUp = () => {
      if (!this._startPan) {
        return
      }
      this._dispatchEvent(
        'vertexScale',
        {
          action: 'stop'
        },
        this
      )
      this._startPan = false
      this.view.off(ViewEventType.pointerUp, handlerUp)
      this.view.off(ViewEventType.pointerMove, handlerMove)
      // 添加到undoRedoManager中
      if (this._parent && this._parent.undoRedoManager) {
        this._parent.undoRedoManager.addProcess(
          'update',
          this._parent.sketchStage
        )
      }
      // 重新注册父级草图地图点击事件
      if (this._parent && this._parent._mapClickEvent) {
        setTimeout(() => {
          this.view.on(
            ViewEventType.immediateClick,
            this._parent._mapClickEvent
          )
        }, 0)
      }
      this.view._mapActionControl('drag-pan', true)
    }
    // 注册平移时鼠标相关事件
    this._hitTestEventHandlers.push(handlerMove)
    this._hitTestEventHandlers.push(handlerUp)
    this.view.on(ViewEventType.pointerUp, handlerUp)
    this.view.on(ViewEventType.pointerMove, handlerMove)
  }

  startMidVertexScaleGraphics(feature, event) {
    this.view._mapActionControl('drag-pan', false)
    const timer = null
    let moving = false
    this._startPan = true
    let startPoint = null
    // if (this._hight) {
    //   startPoint = new Point({
    //     coordinates: [
    //       event.mapPoint.coordinates[0],
    //       event.mapPoint.coordinates[1],
    //       this._hight
    //     ],
    //     spatialReference: this._spatialReference
    //   })
    // } else {
    //   startPoint = event.mapPoint
    // }
    startPoint = event.mapPoint
    let parentExtent
    if (this._parent.sketchStage.entityGraphic.geometry instanceof Extent) {
      parentExtent = this._parent.sketchStage.entityGraphic.geometry
    } else {
      parentExtent = this._parent.sketchStage.entityGraphic.geometry.extent
    }
    // 移除父级草图地图点击事件。点图形仍然会触发mapClick事件。
    if (this._parent && this._parent._mapClickEvent) {
      this.view.off(ViewEventType.immediateClick, this._parent._mapClickEvent)
    }
    // 获取当前移动点的方位
    // const getDirection = function (xy, extent) {
    //   let direction = null
    //   const centerXY = [
    //     (extent.xmax + extent.xmin) / 2,
    //     (extent.ymax + extent.ymin) / 2
    //   ]
    //   if (Math.abs(xy[0] - centerXY[0]) <= 1e-8 && xy[1] >= centerXY[1]) {
    //     // if (xy[0] === centerXY[0] && xy[1] >= centerXY[1]) {
    //     direction = 'n'
    //   } else if (
    //     xy[0] >= centerXY[0] &&
    //     Math.abs(xy[1] - centerXY[1]) <= 1e-8
    //   ) {
    //     direction = 'e'
    //   } else if (Math.abs(xy[0] - centerXY[0]) <= 1e-8 && xy[1] < centerXY[1]) {
    //     direction = 's'
    //   } else if (xy[0] < centerXY[0] && Math.abs(xy[1] - centerXY[1]) <= 1e-8) {
    //     direction = 'w'
    //   }
    //   return direction
    // }
    // const direction = getDirection(feature.geometry.coordinates, parentExtent)
    const direction = feature.attributes.direction

    // 鼠标平移
    const handlerMove = (options) => {
      if (!options || !options.x || !options.y) return
      if (moving || !this._startPan) return

      clearTimeout(timer)
      moving = true

      const pixelCoord = { x: options.x, y: options.y }
      const movePoint = this.view.toMap({
        x: pixelCoord.x,
        y: pixelCoord.y
      })
      // if (this._hight) {
      //   movePoint = new Point({
      //     coordinates: [
      //       movePoint.coordinates[0],
      //       movePoint.coordinates[1],
      //       this._hight
      //     ],
      //     spatialReference: this._spatialReference
      //   })
      // }

      const deltaX = movePoint.coordinates[0] - startPoint.coordinates[0]
      const deltaY = movePoint.coordinates[1] - startPoint.coordinates[1]
      const scaleX = movePoint.coordinates[0] / startPoint.coordinates[0]
      const scaleY = movePoint.coordinates[1] / startPoint.coordinates[1]
      if (deltaX === 0 && deltaY === 0) {
        moving = false
        return
      }
      this._dispatchEvent(
        'midVertexScale',
        {
          startPoint,
          movePoint,
          deltaPosition: { x: deltaX, y: deltaY },
          scale: { x: scaleX, y: scaleY },
          direction,
          extent: parentExtent,
          action: 'scale'
        },
        this
      )
      moving = false
    }
    const handlerUp = () => {
      if (!this._startPan) {
        return
      }
      this._dispatchEvent(
        'vertexScale',
        {
          action: 'stop'
        },
        this
      )
      this._startPan = false
      this.view.off(ViewEventType.pointerUp, handlerUp)
      this.view.off(ViewEventType.pointerMove, handlerMove)
      this.view._mapActionControl('drag-pan', true)

      // 添加到undoRedoManager中
      if (this._parent && this._parent.undoRedoManager) {
        this._parent.undoRedoManager.addProcess(
          'update',
          this._parent.sketchStage
        )
      }
      // 重新注册父级草图地图点击事件
      if (this._parent && this._parent._mapClickEvent) {
        setTimeout(() => {
          this.view.on(
            ViewEventType.immediateClick,
            this._parent._mapClickEvent
          )
        }, 0)
      }
      this.view._mapActionControl('drag-pan', true)
    }
    // 注册平移时鼠标相关事件
    this._hitTestEventHandlers.push(handlerMove)
    this._hitTestEventHandlers.push(handlerUp)
    this.view.on(ViewEventType.pointerUp, handlerUp)
    this.view.on(ViewEventType.pointerMove, handlerMove)
  }

  startCircleVertexScaleGraphics(feature, event) {
    this.view._mapActionControl('drag-pan', false)
    const timer = null
    let moving = false
    this._startPan = true
    let startPoint = null
    startPoint = event.mapPoint
    const parentExtent = this._parent.sketchStage.entityGraphic.geometry.extent
    // 移除父级草图地图点击事件。点图形仍然会触发mapClick事件。
    if (this._parent && this._parent._mapClickEvent) {
      this.view.off(ViewEventType.immediateClick, this._mapClickEvent)
    }
    const direction = feature.attributes.direction

    // 鼠标平移
    const handlerMove = (options) => {
      if (!options || !options.x || !options.y) return
      if (moving || !this._startPan) return
      clearTimeout(timer)
      moving = true

      const pixelCoord = { x: options.x, y: options.y }
      const movePoint = this.view.toMap({
        x: pixelCoord.x,
        y: pixelCoord.y
      })
      const deltaX = movePoint.coordinates[0] - startPoint.coordinates[0]
      const deltaY = movePoint.coordinates[1] - startPoint.coordinates[1]
      const scaleX = movePoint.coordinates[0] / startPoint.coordinates[0]
      const scaleY = movePoint.coordinates[1] / startPoint.coordinates[1]
      if (deltaX === 0 && deltaY === 0) {
        moving = false
        return
      }
      this._dispatchEvent(
        'circleVertexScale',
        {
          startPoint,
          movePoint,
          // entityGraphic: startParentEntityGraphic,
          deltaPosition: { x: deltaX, y: deltaY },
          scale: { x: scaleX, y: scaleY },
          direction,
          extent: parentExtent,
          feature,
          action: 'scale'
        },
        this
      )
      moving = false
    }
    const handlerUp = () => {
      if (!this._startPan) {
        return
      }
      this._dispatchEvent(
        'circleVertexScale',
        {
          action: 'stop'
        },
        this
      )
      this._startPan = false
      this.view.off(ViewEventType.pointerUp, handlerUp)
      this.view.off(ViewEventType.pointerMove, handlerMove)
      // 添加到undoRedoManager中
      if (this._parent && this._parent.undoRedoManager) {
        this._parent.undoRedoManager.addProcess(
          'update',
          this._parent.sketchStage
        )
      }
      // 重新注册父级草图地图点击事件
      if (this._parent && this._parent._mapClickEvent) {
        setTimeout(() => {
          this.view.on(
            ViewEventType.immediateClick,
            this._parent._mapClickEvent
          )
        }, 0)
      }
      this.view._mapActionControl('drag-pan', true)
    }
    // 注册平移时鼠标相关事件
    this._hitTestEventHandlers.push(handlerMove)
    this._hitTestEventHandlers.push(handlerUp)
    this.view.on(ViewEventType.pointerUp, handlerUp)
    this.view.on(ViewEventType.pointerMove, handlerMove)
  }

  /**
   * @description 移动图形顶点
   * @private
   * @param {Feature} feature 被选中feature对象
   * @param {Object} event
   */
  startVertexMoveGraphics(feature, event) {
    this.view._mapActionControl('drag-pan', false)
    const timer = null
    let moving = false
    this._startPan = true
    let startPoint = null
    // if (this._hight) {
    //   startPoint = new Point({
    //     coordinates: [
    //       event.mapPoint.coordinates[0],
    //       event.mapPoint.coordinates[1],
    //       this._hight
    //     ],
    //     spatialReference: this._spatialReference
    //   })
    // } else {
    //   startPoint = event.mapPoint
    // }
    startPoint = event.mapPoint
    const index = feature.attributes ? feature.attributes.vertexIndex : -2
    // 如果是中点,这要增加一个顶点,并改变相应终点
    if (feature.attributes.type === 'midVertex') {
      this._dispatchEvent(
        'midVertexAdd',
        {
          point: startPoint,
          vertexIndex: feature.attributes ? index : undefined,
          action: 'changeFeature'
        },
        this
      )
      // setTimeout(() => {
      //   this._startPan = true
      // }, 500)
      this._startPan = true
    } else {
      this._startPan = true
    }
    // 移除父级草图地图点击事件。点图形仍然会触发mapClick事件。
    if (this._parent && this._parent._mapClickEvent) {
      this.view.off(ViewEventType.immediateClick, this._parent._mapClickEvent)
    }

    // 鼠标移动,修改父级草图顶点
    const handlerMove = (options) => {
      if (!options || !options.x || !options.y) return
      if (moving || !this._startPan) return

      clearTimeout(timer)
      moving = true

      const pixelCoord = { x: options.x, y: options.y }
      const movePoint = this.view.toMap({
        x: pixelCoord.x,
        y: pixelCoord.y
      })
      // if (this._hight) {
      //   movePoint = new Point({
      //     coordinates: [
      //       movePoint.coordinates[0],
      //       movePoint.coordinates[1],
      //       this._hight
      //     ],
      //     spatialReference: this._spatialReference
      //   })
      // }

      const deltaX = movePoint.coordinates[0] - startPoint.coordinates[0]
      const deltaY = movePoint.coordinates[1] - startPoint.coordinates[1]
      if (deltaX === 0 && deltaY === 0) {
        moving = false
        return
      }
      if (feature.attributes.type === 'midVertex') {
        this._dispatchEvent(
          'midVertexAdd',
          {
            startPoint,
            movePoint,
            vertexIndex: index,
            vertexType: feature.attributes
              ? feature.attributes.type
              : undefined,
            action: 'moveMidVertex'
          },
          this
        )
      } else {
        this._dispatchEvent(
          'vertexMove',
          {
            startPoint,
            movePoint,
            vertexIndex: index,
            vertexType: feature.attributes ? feature.attributes.type : undefined
          },
          this
        )
      }

      startPoint = movePoint
      this.updateFeature(movePoint, feature)
      moving = false
    }
    const handlerUp = (options) => {
      if (!options || !options.x || !options.y) return
      if (!this._startPan) return
      this.view._mapActionControl('drag-pan', false)
      const pixelCoord = { x: options.x, y: options.y }
      // const movePoint = this.view.toMap({
      //   x: pixelCoord.x,
      //   y: pixelCoord.y
      // })
      this._startPan = false
      this.view.off(ViewEventType.pointerUp, handlerUp)
      this.view.off(ViewEventType.pointerMove, handlerMove)
      this.view._mapActionControl('drag-pan', true)
      // 如果是中点,这要增加一个顶点,并改变相应终点
      if (feature.attributes.type === 'midVertex') {
        const index = feature.attributes.vertexIndex
        this._dispatchEvent(
          'midVertexAdd',
          {
            point: startPoint,
            vertexIndex: feature.attributes ? index : undefined,
            action: 'addVertex'
          },
          this
        )
      }

      moving = false
      // 添加到undoRedoManager中
      if (this._parent && this._parent.undoRedoManager) {
        this._parent.undoRedoManager.addProcess(
          'update',
          this._parent.sketchStage
        )
      }
      // 重新注册父级草图地图点击事件
      if (this._parent && this._parent._mapClickEvent) {
        setTimeout(() => {
          this.view.on(
            ViewEventType.immediateClick,
            this._parent._mapClickEvent
          )
        }, 0)
      }
      this.view._mapActionControl('drag-pan', true)
    }
    // 注册平移时鼠标相关事件
    this._hitTestEventHandlers.push(handlerMove)
    this._hitTestEventHandlers.push(handlerUp)
    this.view.on(ViewEventType.pointerUp, handlerUp)
    this.view.on(ViewEventType.pointerMove, handlerMove)
  }

  startVertexAdd() {}

  /**
   * @description 响应图形平移事件
   * @private
   * @param {Feature} feature 被选中feature对象
   */
  _processEvent(event) {
    if (event.type === 'pan') {
      this._handlerPanEvent(event)
    } else if (event.type === 'vertexScale') {
      // 处理顶点缩放逻辑
      this._handlerVertexScaleEvent(event)
    } else if (event.type === 'midVertexScale') {
      // 处理顶点缩放逻辑
      this._handlerMidVertexScaleEvent(event)
    } else if (event.type === 'circleVertexScale') {
      // 处理顶点缩放逻辑
      this._handlerCircleVertexScaleEvent(event)
    }
  }

  /**
   * @description 响应平移事件
   * @private
   * @param {Object} event 传入事件参数
   */
  _handlerPanEvent(event) {
    // 更新当前草图图形
    const newCoordinates = this.getPanCoordinates(
      this.sketchStage.entityGraphic.geometry.coordinates,
      event.deltaPosition.x,
      event.deltaPosition.y
    )
    const newGeometry = new Point({
      coordinates: newCoordinates,
      spatialReference: this._spatialReference
    })
    this.sketchStage.entityGraphic.geometry = newGeometry
  }

  /**
   * @description 响应外包盒四角顶点缩放事件
   * @private
   * @param {Object} event 传入事件参数
   */
  _handlerVertexScaleEvent(event) {
    if (event.action === 'scale') {
      // 更新当前草图的图形位置
      if (!this.sketchStage.entityGraphic.attributes.lastCoordinates) {
        const oriCoordinates = JSON.parse(
          JSON.stringify([this.sketchStage.entityGraphic.geometry.coordinates])
        )
        this.sketchStage.entityGraphic.attributes.lastCoordinates =
          oriCoordinates
      }
      this.sketchStage.entityGraphic.attributes = this.sketchStage.entityGraphic
        .attributes
        ? this.sketchStage.entityGraphic.attributes
        : {}
      const newCoordinates = this.getScaleCoordinates(
        [this.sketchStage.entityGraphic.geometry.coordinates],
        event.direction,
        event.extent,
        event.startPoint,
        event.movePoint,
        this.sketchStage.entityGraphic.attributes.lastCoordinates
      )
      const newGeometry = new Point({
        coordinates: newCoordinates[0],
        spatialReference: this._spatialReference
      })
      this.sketchStage.entityGraphic.geometry = newGeometry
    }
    if (event.action === 'stop') {
      if (this.sketchStage.entityGraphic.attributes.lastCoordinates) {
        this.sketchStage.entityGraphic.attributes.lastCoordinates = undefined
      }
    }
  }

  /**
   * @description 响应外包盒四边终点点缩放事件
   * @private
   * @param {Object} event 传入事件参数
   */
  _handlerMidVertexScaleEvent(event) {
    if (event.action === 'scale') {
      // 更新当前草图的图形位置
      let newGeometry = null
      if (!this.sketchStage.entityGraphic.attributes.lastCoordinates) {
        const oriCoordinates = JSON.parse(
          JSON.stringify([this.sketchStage.entityGraphic.geometry.coordinates])
        )
        this.sketchStage.entityGraphic.attributes.lastCoordinates =
          oriCoordinates
      }
      const newCoordinates = this.getMidScaleCoordinates(
        [this.sketchStage.entityGraphic.geometry.coordinates],
        event.direction,
        event.extent,
        event.startPoint,
        event.movePoint,
        this.sketchStage.entityGraphic.attributes.lastCoordinates
      )
      newGeometry = new Point({
        coordinates: newCoordinates[0],
        spatialReference: this._spatialReference
      })
      this.sketchStage.entityGraphic.geometry = newGeometry
      // 撤销后,在移动中点,有问题,parent的selectBoxVertexGraphics没有被更新。
      // 暂时强制更新
      if (this._parent) {
        this._parent.sketchStage.updateGraphic(this.sketchStage.entityGraphic)
      }
    } else if (event.action === 'stop') {
      if (this.sketchStage.entityGraphic.attributes.lastCoordinates) {
        this.sketchStage.entityGraphic.attributes.lastCoordinates = undefined
      }
    }
  }

  _handlerCircleVertexScaleEvent(event) {
    this._handlerMidVertexScaleEvent(event)
  }

  /**
   * 点击到地图没有feature图形区域,退出编辑,临时方法
   * @private
   */
  removeFeature(feature) {
    if (this.sketchStage.entityGraphic.id !== feature.id) {
      this.sketchStage.entityGraphic = null
    }
    this.view.sketchFeatures = this.view.sketchFeatures.filter(
      (item) => item.id !== feature.id
    )
    this._addFeaturesToMap()
  }
}
export default SketchPointDrawTool
构造函数
成员变量
方法
事件