    import { Feature, ViewEventType, Projection } from '../../base'
    import { Polygon, Point, LineString } from '../../base/geometry'
    import { defaultValue } from '../../util'
    import SketchStage from './SketchStage'
    import SketchBaseDrawTool from './SketchBaseDrawTool'
    import Color from '../../base/Color'
    import SketchPointDrawTool from './SketchPointDrawTool'
    import SketchStyle from './SketchStyle'
    import SketchSnappingTool from './SketchSnappingTool'
    import { SimpleLineSymbol } from '../../base/symbol'
    /**
     * 面绘图工具类
     * @class SketchPolygonDrawTool
     * @moduleEX SketchEditorModule
     * @extends SketchBaseDrawTool
     * @param {Object} options 构造参数
     * @param {MapView}  [options.mapView]  地图视图对象
     * @param {GraphicsLayer}  [options.layer]  草图图层管对象
     * @param {SketchStyle}  [options.sketchStyle]  草图符号
     * @param {Function}  [options._hitTestEvent]  草图拾取事件
     */
    class SketchPolygonDrawTool extends SketchBaseDrawTool {
      constructor(options) {
        super(options)
        /**
         * 地图视图
         * @member {MapView|SecenView} SketchEditor.prototype._mapView
         */
        this._mapView = options.mapView
        /**
         * 草图图层
         * @member {GraphicsLayer} SketchEditor.prototype._layer
         */
        this._layer = defaultValue(options.layer, undefined)
        /**
         * 草图绘图形集合
         * @member {SketchStage} SketchEditor.prototype._sketchStage
         */
        this._sketchStage = new SketchStage()
        /**
         * 草图符号
         * @member {SketchStyle} SketchEditor.prototype._sketchStyle
         */
        this._sketchStyle = defaultValue(options.sketchStyle, new SketchStyle())
        // this._mouseEventHandlers = null
        this._currentVertexIndexOnMultiPoint = null
        /**
         * 草图编辑状态
         * 0:没有画图或编辑状态
         * 1:图形编辑
         * 2:节点编辑
         * 3:画图中
         * @member {MapView|SecenView} SketchEditor.prototype._editMode
         */
        this._editMode = 0
        /**
         * 草图捕获配置项
         * @member {Object} SketchEditor.prototype.snappingOption
         * @param {Object} [snappingOption.showSelectBox = {}] 捕捉时是否展示选中编辑框
         * @param {Object} [snappingOption.showSelectVertex = {}] 捕捉时是否展示顶点可编辑图形
         * @param {Object} [snappingOption._hitTestMode = {}] 捕捉拾取方式，0：click鼠标拾取。1：mouseDown鼠标按下拾取
         */
        const snappingOption = {
          showSelectBox: true,
          showSelectVertex: false,
          canEditFeature: false,
          canEditVertex: false,
          _hitTestMode: 0
        }
        this.snappingOption = defaultValue(options.snappingOption, snappingOption)
        /**
         * 所属父级绘图工具
         * @member {GraphicsLayer} SketchEditor.prototype._layer
         */
        this._parent = defaultValue(options._parent, undefined)
        // 初始化
        this.sketchSnappingTool = new SketchSnappingTool(this.snappingOption)
        /**
         * 初始化事件
         */
        this._initEvent()
        this.undoRedoManager = defaultValue(options.undoRedoManager, undefined)
        this._drawTools = [this]
        this._otherDrawTools = []
      }

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

      /**
       * @description 鼠标绘制图形：鼠标单击绘制区的一个顶点；鼠标移动，区图形随鼠标位置变动；鼠标双击，完成区图形绘制。
       */
      drawFeature() {
        // 鼠标事件位置信息
        let movePosition = null
        // 控制鼠标移动事件频率
        const timer = null
        // 鼠标点击两次以上，即有两个以上的点构成区时，触发鼠标移动时逻辑
        let isStartDrawing = false
        // 鼠标移动过程中，控制鼠标移动逻辑触发次数
        let moving = false
        // 当前正在绘制的图形对象
        let feature = null
        let pixelCoords = []
        // 绘制过程中所有的端点
        let polygonSpots = []
        // 绘制过程中所有所有线段的斜率
        const polygonSpotSlopes = []
        // timer判断是单击事件、双击事件
        let clickTimer = null
        // 区分单击、双击事件，若为双击事件，则阻止单击事件逻辑触发
        let preventClick = false
        // 获取两点斜率
        const getSlope = function (point1, point2) {
          return (point1[1] - point2[1]) / (point1[0] - point2[0])
        }
        let lastMouseEvent = null
        const snapPoint = null
        // 处理鼠标点击事件。点击后渲染端点图形，渲染区图形
        const handlerClick = (options) => {
          clickTimer = setTimeout(() => {
            preventClick = false
          }, 300)
          // 判断是否为单击事件
          if (preventClick) return

          clearTimeout(timer)
          this._editMode = 3
          const position = options.pointer
            ? options.pointer
            : { x: options.x, y: options.y }
          const pixelCoord = { x: position.x, y: position.y }
          const geoCoord = this._mapView.toMap({ x: pixelCoord.x, y: pixelCoord.y })
          pixelCoords.push(pixelCoord)
          polygonSpots.push(geoCoord.coordinates)
          // // 如果有捕获结果，则此时坐标点选取捕获的坐标点
          // if (snapPoint) {
          //   polygonSpots[polygonSpots.length - 1] = snapPoint.coordinates
          // }
          if (!feature) {
            if (polygonSpots.length > 2) {
              feature = this._getFeature()
              feature.geometry._pixelCoords = [...pixelCoords, pixelCoords[0]]
              feature.geometry.coordinates = [[...polygonSpots, polygonSpots[0]]]
              // 保存当前编辑中的geometry
              this._polygonGeometry = feature
            } else if (polygonSpots.length === 2) {
              pixelCoords.push(pixelCoords[0])
              polygonSpots.push(polygonSpots[0])
              feature = this._getFeature()
              feature.geometry._pixelCoords = [...pixelCoords, pixelCoords[0]]
              feature.geometry.coordinates = [[...polygonSpots, polygonSpots[0]]]
            } else {
              isStartDrawing = false
            }
          }

          const pointDrawTool = new SketchPointDrawTool({
            mapView: this._mapView,
            layer: this._layer,
            _parent: this,
            _hitTestEvent: this._hitTestEvent,
            sketchStyle: this._sketchStyle
          })
          pointDrawTool.addFeature(geoCoord)
          const vertexGraphic = pointDrawTool._sketchStage.entityGraphic
          this._sketchStage.entityGraphic = feature
          this._sketchStage.vertexGraphics.push(vertexGraphic)

          if (feature) {
            isStartDrawing = true
          }
          preventClick = true
          // 计算线段斜率
          if (polygonSpots.length > 3) {
            polygonSpotSlopes.push(
              getSlope(
                polygonSpots[polygonSpots.length - 2],
                polygonSpots[polygonSpots.length - 3]
              )
            )
          } else if (polygonSpots.length > 2) {
            polygonSpotSlopes.push(getSlope(polygonSpots[0], polygonSpots[1]))
          }
          lastMouseEvent = 'click'
        }
        let isFirstAdd = true
        // 处理平移时，鼠标移动时逻辑。鼠标移动时根据鼠标坐标实时更新区图形。
        const handlerMove = (options) => {
          if (!isStartDrawing || moving) {
            return
          }
          clearTimeout(timer)
          moving = true
          // 清除上一次的捕获效果
          if (this._sketchStage.snapGraphics.length > 0) {
            this._sketchStage.snapGraphics.forEach((feature) => {
              this._removeFeatureFromMap(feature)
            })
            this._sketchStage.snapGraphics = []
          }

          movePosition = options.pointer
            ? options.pointer
            : { x: options.x, y: options.y }
          const pixelCoord = { x: movePosition.x, y: movePosition.y }
          pixelCoords[pixelCoords.length - 1] = pixelCoord
          const geoCoord = this._mapView.toMap({ x: pixelCoord.x, y: pixelCoord.y })
          polygonSpots[polygonSpots.length - 1] = geoCoord.coordinates
          this._sketchStage.entityGraphic = feature

          // 鼠标移动时，去捕获重合点、点在线上、平行线、垂直线
          // snapPoint = this.getSnapGraphics(
          //   geoCoord,
          //   polygonSpots,
          //   polygonSpotSlopes
          // )
          // if (snapPoint) {
          //   polygonSpots[polygonSpots.length - 1] = snapPoint.coordinates // geoCoord.coordinates
          // }

          // 更新草图图层
          feature.geometry._pixelCoords = [...pixelCoords, pixelCoords[0]]
          feature.geometry.coordinates = [[...polygonSpots, polygonSpots[0]]]
          if (isFirstAdd) {
            this._addFeaturesToMap(feature)
            isFirstAdd = false
          }
          moving = false

          lastMouseEvent = 'mouseMove'
        }
        // 处理鼠标双击时，处理逻辑
        const handlerDoubleClick = () => {
          clearTimeout(clickTimer)
          clearTimeout(timer)
          preventClick = true

          if (!isStartDrawing) {
            feature = null
            polygonSpots = []
            pixelCoords = []
            return
          }

          if (
            lastMouseEvent === 'mouseMove' &&
            feature.geometry.coordinates[0].length > 4
          ) {
            // console.log('is Move before dbClick')
            feature.geometry._pixelCoords.splice(-2, 1)
            feature.geometry.coordinates[0].splice(-2, 1)
          }
          polygonSpots = []
          pixelCoords = []
          isStartDrawing = false
          // 停止绘制
          this.stop()
          // 绘制完成后，移除顶点
          this._sketchStage.vertexGraphics.forEach((feature) => {
            this._removeFeatureFromMap(feature)
          })
          this._sketchStage.vertexGraphics = []

          // 注册hitTest拾取草图事件
          this._hitTestEvent()
          this._editMode = 0
          lastMouseEvent = 'doubleClick'
          // 发送绘制完成事件
          this.fire('drawn', { geometry: feature.geometry }, self)
        }

        this._mouseEventHandlers = this._mouseEventHandlers
          ? this._mouseEventHandlers
          : []
        // 移除绘制事件
        this._mouseEventHandlers.push(handlerClick, handlerMove, handlerDoubleClick)
        this._mapView.on(ViewEventType.click, handlerClick)
        this._mapView.on(ViewEventType.mouseMove, handlerMove)
        this._mapView.on(ViewEventType.doubleClick, handlerDoubleClick)
      }

      /**
       * @description 添加图形
       * @param {Array} points 生成面的点地理坐标集
       * @param {SketchStyle} sketchStyle 面的符号样式
       */
      addFeature(points, sketchStyle, attributes) {
        let fillStyle = null
        if (!sketchStyle || !sketchStyle.fillStyle) {
          fillStyle = this._sketchStyle._fillStyle
        } else {
          fillStyle = sketchStyle.fillStyle
        }

        const feature = this._getFeature(points, fillStyle)
        if (attributes) {
          feature.attributes = attributes
        }
        this._sketchStage.entityGraphic = feature
        // 更新图层图形
        this._addFeaturesToMap(feature)
      }

      addFeatureByGeometry(geometry, sketchStyle, attributes) {
        let symbol = null
        if (!sketchStyle || !sketchStyle.fillStyle) {
          symbol = this._sketchStyle._fillStyle
        } else {
          symbol = sketchStyle.fillStyle
        }

        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(points) {
        if (!points) {
          points = [
            [0, 0],
            [0, 0],
            [0, 0],
            [0, 0]
          ]
        }
        const geometry = new Polygon({
          coordinates: [points],
          spatialReference: this._spatialReference
        })
        const symbol = this._sketchStyle.fillStyle
        const polygonGeometry = new Feature({
          geometry,
          symbol
        })
        polygonGeometry.isShowArea = this._sketchStyle.isShowArea
        if (polygonGeometry.isShowArea) {
          polygonGeometry._textStyle = this._sketchStyle.textStyle
        }
        return polygonGeometry
      }

      /**
       * @description 捕获草图
       * @private
       * @param {Feature} feature 被选中feature对象
       */
      _hitTestFeature(feature, event) {
        if (!this._parent && this.snappingOption.showSelectBox) {
          if (this._editMode === 0) {
            this._editMode = 1
          } else if (this._editMode === 2) {
            // 临时，把clickMap的事件删掉，否则在图形都被删掉时会被触发
            this._mapView.off(ViewEventType.click, this._mapClickEvent)
            this._mapClickEvent = null
            this._editMode = 1
          }
          // 进入图形编辑状态，高亮点元素,用新图形代替高亮，展示选中图形时的辅助图形
          this.selectFeature(feature)
        }
        if (this._parent && this._parent._editMode === 1) {
          // 注册图形编辑时的事件，平移图形
          this.startPanGraphics(feature, event)
        } else if (this._parent && this._parent._editMode === 2) {
          // 进入顶点编辑状态，添加顶点+中点辅助图形
          // 调用辅助图形的父级图形的selectFeatureVertex，
          // 1.添加顶点编辑状态的辅助图形
          // 2.删除当前编辑图形状态的辅助图形
          // this._parent.selectFeatureVertex(this._parent.entityGraphic)
        }
      }

      /**
       * @description 选中草图feature
       * @param {Feature} feature 被选中草图feature对象
       */
      selectFeature(feature) {
        if (!this.snappingOption.showSelectBox) return
        // 1.删除当前编辑图形状态的辅助图形
        // 2.添加顶点编辑状态的辅助图形
        this._clearEditGraphics(2)
        // 加载选时的辅助图形，外包盒
        const extent = feature.geometry.extent
        const polygonDrawTool = new SketchPolygonDrawTool({
          mapView: this._mapView,
          layer: this._layer,
          sketchStyle: new SketchStyle({
            fillStyle: this._sketchStyle._selectBoxStyle,
            isShowSegmentLength: true,
            isShowArea: true
          }),
          snappingOption: {
            showSelectBox: false,
            _hitTestMode: 1
          },
          _parent: this, // 或者只传父级相应pan的事件
          _hitTestEvent: this._hitTestEvent
        })
        polygonDrawTool.addFeature([
          [extent.xmax, extent.ymax],
          [extent.xmax, extent.ymin],
          [extent.xmin, extent.ymin],
          [extent.xmin, extent.ymax],
          [extent.xmax, extent.ymax]
        ])
        this._sketchStage.selectBoxGraphics = [
          polygonDrawTool._sketchStage.entityGraphic
        ]
        // 外包盒顶点和终点
        const boxVertexPoints = [
          {
            point: new Point({
              coordinates: [extent.xmax, extent.ymax],
              spatialReference: this._spatialReference
            }),
            direction: 'ne'
          },
          {
            point: new Point({
              coordinates: [extent.xmax, extent.ymin],
              spatialReference: this._spatialReference
            }),
            direction: 'se'
          },
          {
            point: new Point({
              coordinates: [extent.xmin, extent.ymin],
              spatialReference: this._spatialReference
            }),
            direction: 'sw'
          },
          {
            point: new Point({
              coordinates: [extent.xmin, extent.ymax],
              spatialReference: this._spatialReference
            }),
            direction: 'nw'
          },
          // midPoint
          {
            point: new Point({
              coordinates: [(extent.xmax + extent.xmin) / 2, extent.ymax],
              spatialReference: this._spatialReference
            }),
            direction: 'n',
            type: 'midVertex'
          },
          {
            point: new Point({
              coordinates: [(extent.xmax + extent.xmin) / 2, extent.ymin],
              spatialReference: this._spatialReference
            }),
            direction: 's',
            type: 'midVertex'
          },
          {
            point: new Point({
              coordinates: [extent.xmax, (extent.ymax + extent.ymin) / 2],
              spatialReference: this._spatialReference
            }),
            direction: 'e',

            type: 'midVertex'
          },
          {
            point: new Point({
              coordinates: [extent.xmin, (extent.ymax + extent.ymin) / 2],
              spatialReference: this._spatialReference
            }),
            direction: 'w',
            type: 'midVertex'
          }
        ]
        const pointDrawTools = []
        const boxVertexGraphics = []
        boxVertexPoints.forEach((item) => {
          const pointDrawTool = new SketchPointDrawTool({
            mapView: this._mapView,
            layer: this._layer,
            sketchStyle: new SketchStyle({
              vertexStyle: this._sketchStyle._selectBoxVertexStyle
            }),
            snappingOption: {
              showSelectBox: false,
              _hitTestMode: 1
            },
            _parent: this, // 或者只传父级相应pan的事件
            _hitTestEvent: this._hitTestEvent
          })
          pointDrawTool.addFeature(item.point, this._sketchStage, {
            direction: item.direction,
            type: item.type
          })
          pointDrawTools.push(pointDrawTool)
          boxVertexGraphics.push(pointDrawTool._sketchStage.entityGraphic)
        })
        this._sketchStage.selectBoxVertexGraphics = boxVertexGraphics
        // 注册hitTest事件移动图形
        this._hitTestDrawToolStack.push(polygonDrawTool)
        pointDrawTools.forEach((drawTool) => {
          this._hitTestDrawToolStack.push(drawTool)
        })
        if (this._otherDrawTools) {
          this._otherDrawTools.push(polygonDrawTool)
        } else {
          this._otherDrawTools = [polygonDrawTool]
        }
        this._otherDrawTools = this._otherDrawTools.concat(pointDrawTools)
        this._drawTools.push(polygonDrawTool)
        this._drawTools = this._drawTools.concat(pointDrawTools)

        // 添加到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
              .concat(this._sketchStage.selectBoxVertexGraphics)
              .concat(this._sketchStage.vertexGraphics)
              .concat(this._sketchStage.midVertexGraphics)
            removedFeatures.forEach((feature) => {
              this._removeFeatureFromMap(feature)
            })
            this._mapView.off(ViewEventType.click, this._mapClickEvent)
            if (this._enableMapDrag) {
              this._enableMapDrag()
            }
            this._mapClickEvent = null
            // 发送草图没有被选中状态
            this.fire('selected', { isSelected: false }, self)
            this._sketchStage.selectBoxGraphics = []
            this._sketchStage.selectBoxVertexGraphics = []
            this._sketchStage.vertexGraphics = []
            this._sketchStage.midVertexGraphics = []
          }
          setTimeout(() => {
            this._hitTestEventHandlers.push(this._mapClickEvent)
            this._mapView.on(ViewEventType.click, this._mapClickEvent)
          }, 200)
        }
      }

      /**
       * @description 选中feature图形顶点
       * @private
       * @param {Feature} feature 被选中feature对象
       */
      selectFeatureVertex(feature) {
        // 1.删除当前编辑图形状态的辅助图形
        // 2.添加顶点编辑状态的辅助图形
        this._clearEditGraphics(1)

        const pointDrawTools = []
        const midPointDrawTools = []
        feature.geometry.coordinates[0].forEach((coordinate, i) => {
          // 区集合坐标集比区顶点多（最后）一个坐标，添加顶点时读取到倒数第二个坐标
          if (i < feature.geometry.coordinates[0].length - 1) {
            // 渲染区的每一个顶点
            const pointDrawTool = new SketchPointDrawTool({
              mapView: this._mapView,
              layer: this._layer,
              sketchStyle: new SketchStyle({
                vertexStyle: this._sketchStyle._selectVertexStyle
              }),
              snappingOption: {
                showSelectBox: false,
                _hitTestMode: 1
              },
              _parent: this, // 或者只传父级相应pan的事件
              _hitTestEvent: this._hitTestEvent
            })
            const point = new Point({
              coordinates: coordinate,
              spatialReference: this._spatialReference
            })

            pointDrawTool.addFeature(point, undefined, {
              vertexIndex: i
            })
            pointDrawTools.push(pointDrawTool)
            this._sketchStage.vertexGraphics.push(
              pointDrawTool._sketchStage.entityGraphic
            )
          }
          // 渲染顶点之间的每一个中点
          if (i > 0) {
            const midPointDrawTool = new SketchPointDrawTool({
              mapView: this._mapView,
              layer: this._layer,
              sketchStyle: new SketchStyle({
                vertexStyle: this._sketchStyle._selectMidVertexStyle
              }),
              snappingOption: {
                showSelectBox: false,
                _hitTestMode: 1
              },
              _parent: this, // 或者只传父级相应pan的事件
              _hitTestEvent: this._hitTestEvent
            })
            midPointDrawTools.push(midPointDrawTool)
            const lastCoordinate = feature.geometry.coordinates[0][i - 1]
            const point = new Point({
              coordinates: [
                (coordinate[0] + lastCoordinate[0]) / 2,
                (coordinate[1] + lastCoordinate[1]) / 2
              ],
              spatialReference: this._spatialReference
            })
            midPointDrawTool.addFeature(point, undefined, {
              vertexIndex: i - 1,
              type: 'midVertex'
            })
            this._sketchStage.midVertexGraphics.push(
              midPointDrawTool._sketchStage.entityGraphic
            )
          }
        })
        // 注册hitTest事件移动图形
        pointDrawTools.forEach((drawTool) => {
          this._hitTestDrawToolStack.push(drawTool)
        })
        midPointDrawTools.forEach((drawTool) => {
          this._hitTestDrawToolStack.push(drawTool)
        })
        const drawTools = pointDrawTools.concat(midPointDrawTools)
        this._otherDrawTools = this._otherDrawTools
          ? this._otherDrawTools.concat(drawTools)
          : drawTools
        this._drawTools = this._drawTools.concat(drawTools)
        // 添加到undoRedoManager中
        if (this.undoRedoManager) {
          this.undoRedoManager.addProcess('add', this._sketchStage)
        }
      }

      /**
       * @description 删除某编辑状态的辅助图形
       * @private
       * @param {Number} editMode 编辑状态码
       */
      _clearEditGraphics(editMode) {
        if (editMode === 1) {
          const features = this._sketchStage.selectBoxGraphics.concat(
            this._sketchStage.selectBoxVertexGraphics
          )
          features.forEach((feature) => {
            this._removeFeatureFromMap(feature)
          })

          this._otherDrawTools = []
          this._sketchStage.selectBoxGraphics = []
          this._sketchStage.selectBoxVertexGraphics = []
        } else if (editMode === 2) {
          let target = null
          if (this._parent) {
            target = this._parent
          } else {
            target = this
          }

          const features = target._sketchStage.vertexGraphics.concat(
            target._sketchStage.midVertexGraphics
          )
          features.forEach((feature) => {
            target._removeFeatureFromMap(feature)
          })

          target._otherDrawTools = []
          target._sketchStage.vertexGraphics = []
          target._sketchStage.midVertexGraphics = []
        }
      }

      /**
       * @description 平移图形
       * @param {Feature} feature 被选中feature对象
       * @param {Object} event 拾取事件
       */
      startPanGraphics(feature, event) {
        const timer = null
        let moving = false
        this._startPan = true
        let startPoint = Projection.project(
          new Point({
            coordinates: [event.lon, event.lat]
          }),
          this._spatialReference
        )
        let isClickEvent = true
        const isClickTimer = setTimeout(() => {
          isClickEvent = false
        }, 200)
        // 移除父级草图地图点击事件。点图形仍然会触发mapClick事件。
        if (this._parent && this._parent._mapClickEvent) {
          this._mapView.off(ViewEventType.click, this._mapClickEvent)
        }

        // 处理平移时，鼠标移动时逻辑。
        const handlerMove = (options) => {
          if (moving || !this._startPan || !this._editMode === 1) {
            return
          }
          if (isClickEvent) {
            return
          }
          clearTimeout(timer)
          moving = true

          const movePosition = options.pointer
            ? options.pointer
            : { x: options.x, y: options.y }

          const pixelCoord = { x: movePosition.x, y: movePosition.y }
          const movePoint = this._mapView.toMap({
            x: pixelCoord.x,
            y: pixelCoord.y
          })
          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 coordinates = []
          feature.geometry.coordinates[0].forEach((coordinate) => {
            coordinates.push(this.getPanCoordinates(coordinate, deltaX, deltaY))
          })
          const newGeometry = new Polygon({
            coordinates: [coordinates],
            spatialReference: this._spatialReference
          })

          startPoint = movePoint
          // 发送平移事件给父级草图
          this._dispatchEvent(
            'pan',
            { deltaPosition: { x: deltaX, y: deltaY } },
            this
          )
          this.updateFeature(newGeometry, feature)
          moving = false
        }
        // 处理平移时，鼠标按下后抬起逻辑。
        const handlerUp = () => {
          if (!this._editMode === 1) {
            return
          }
          if (!this._startPan) {
            return
          }
          if (isClickEvent && this._parent && this._parent._editMode === 1) {
            this._parent._editMode = 2
            clearTimeout(isClickTimer)
            // 在图形编辑状态时，当鼠标单击时，进入顶点编辑状态，添加顶点+中点辅助图形，调用辅助图形的父级图形的selectFeatureVertex。
            // 当鼠标移动时，则是平移事件
            this._parent.selectFeatureVertex(
              this._parent._sketchStage.entityGraphic
            )
            if (this._parent && this._parent._mapClickEvent) {
              this._mapView.on(ViewEventType.click, this._parent._mapClickEvent)
            }
            // pan事件移除
            this._mapView.off(ViewEventType.mouseMove, handlerMove)
            this._mapView.off(ViewEventType.mouseUp, handlerUp)
            return
          }
          // this._stopHitTest()
          this._editMode = 0
          this._startPan = false
          if (this._enableMapDrag) {
            this._enableMapDrag()
          }
          this._mapView.off(ViewEventType.mouseMove, handlerMove)
          this._mapView.off(ViewEventType.mouseUp, handlerUp)

          // 添加到undoRedoManager中
          if (this._parent && this._parent.undoRedoManager) {
            this._parent.undoRedoManager.addProcess(
              'update',
              this._parent._sketchStage
            )
          }
          // 重新注册父级草图地图点击事件
          if (this._parent && this._parent._mapClickEvent) {
            setTimeout(() => {
              this._mapView.on(ViewEventType.click, this._parent._mapClickEvent)
            }, 0)
          }
        }
        // 注册平移时鼠标相关事件
        this._hitTestEventHandlers.push(handlerMove)
        this._hitTestEventHandlers.push(handlerUp)
        this._mapView.on(ViewEventType.mouseUp, handlerUp)
        this._mapView.on(ViewEventType.mouseMove, handlerMove)
      }

      /**
       * @description 响应图形平移事件
       * @private
       * @param {Object} event 拾取事件参数
       */
      _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 === 'vertexMove') {
          // 处理移动顶点逻辑
          this._handlerVertexMoveEvent(event)
        } else if (event.type === 'midVertexAdd') {
          // 处理中点位置增加顶点逻辑
          this._handlerMidVertexAddEvent(event)
        }
      }

      /**
       * @description 响应平移事件
       * @private
       * @param {Object} event 拾取事件参数
       */
      _handlerPanEvent(event) {
        // 更新当前草图的图形位置
        const newCoordinates = []
        this._sketchStage.entityGraphic.geometry.coordinates[0].forEach(
          (coordinate) => {
            newCoordinates.push(
              this.getPanCoordinates(
                coordinate,
                event.deltaPosition.x,
                event.deltaPosition.y
              )
            )
          }
        )
        const newGeometry = new Polygon({
          coordinates: [newCoordinates],
          spatialReference: this._spatialReference
        })
        this._sketchStage.entityGraphic.geometry = newGeometry
        // 更新同级的辅助草图的图形位置
        if (this._otherDrawTools) {
          this._otherDrawTools.forEach((drawTool) => {
            drawTool._processEvent(event)
          })
        }
      }

      /**
       * @description 响应顶点缩放事件
       * @private
       * @param {Object} event 传入事件参数
       */
      _handlerVertexScaleEvent(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[0]
              )
            )
            this._sketchStage.entityGraphic.attributes.lastCoordinates =
              oriCoordinates
          }
          const newCoordinates = this.getScaleCoordinates(
            this._sketchStage.entityGraphic.geometry.coordinates[0],
            event.direction,
            event.extent,
            // this._sketchStage.entityGraphic.geometry.extent,
            event.startPoint,
            event.movePoint,
            this._sketchStage.entityGraphic.attributes.lastCoordinates
          )
          newGeometry = new Polygon({
            coordinates: [newCoordinates],
            spatialReference: this._spatialReference
          })
          this._sketchStage.entityGraphic.geometry = newGeometry
          // extent = item.geometry.extent
          // 更新同级的辅助草图的图形位置
          if (this._otherDrawTools) {
            this._otherDrawTools.forEach((drawTool) => {
              // 传给子草图的extent应该是草图改变前的，不是草图改变后的extent
              // event.extent = extent
              // if (drawTool._sketchStage.entityGraphic.id !== event.feature.id) {
              drawTool._processEvent(event)
              // }
            })
          }
        }
        if (event.action === 'stop') {
          if (this._sketchStage.entityGraphic.attributes.lastCoordinates) {
            this._sketchStage.entityGraphic.attributes.lastCoordinates = undefined
          }
          if (this._otherDrawTools) {
            this._otherDrawTools.forEach((drawTool) => {
              // if (drawTool._sketchStage.entityGraphic.id !== event.feature.id) {
              drawTool._processEvent(event)
              // }
            })
          }
        }
      }

      /**
       * @description 响应中点缩放事件
       * @private
       * @param {Object} event 传入事件参数
       */
      _handlerMidVertexScaleEvent(event) {
        // 更新当前草图的图形位置
        let newGeometry = null
        if (!this._sketchStage.entityGraphic.attributes.lastCoordinates) {
          const oriCoordinates = JSON.parse(
            JSON.stringify(this._sketchStage.entityGraphic.geometry.coordinates[0])
          )
          this._sketchStage.entityGraphic.attributes.lastCoordinates =
            oriCoordinates
        }
        const newCoordinates = this.getMidScaleCoordinates(
          this._sketchStage.entityGraphic.geometry.coordinates[0],
          event.direction,
          event.extent,
          // item.geometry.extent,
          event.startPoint,
          event.movePoint,
          this._sketchStage.entityGraphic.attributes.lastCoordinates
        )
        newGeometry = new Polygon({
          coordinates: [newCoordinates],
          spatialReference: this._spatialReference
        })
        this._sketchStage.entityGraphic.geometry = newGeometry
        // extent = item.geometry.extent
        // newEntityGraphic = this._sketchStage.entityGraphic

        // this._sketchStage.entityGraphic = newEntityGraphic
        // 更新同级的辅助草图的图形位置
        if (this._otherDrawTools) {
          this._otherDrawTools.forEach((drawTool) => {
            // 传给子草图的extent应该是草图改变前的，不是草图改变后的extent
            // event.extent = extent
            drawTool._processEvent(event)
          })
        }
        if (event.action === 'stop') {
          if (this._sketchStage.entityGraphic.attributes.lastCoordinates) {
            this._sketchStage.entityGraphic.attributes.lastCoordinates = undefined
          }
          if (this._otherDrawTools) {
            this._otherDrawTools.forEach((drawTool) => {
              // if (drawTool._sketchStage.entityGraphic.id !== event.feature.id) {
              drawTool._processEvent(event)
              // }
            })
          }
        }
      }

      /**
       * @description 响应移动顶点事件
       * @private
       * @param {Object} event 传入事件参数
       */
      _handlerVertexMoveEvent(event) {
        // 更新当前草图的图形位置
        this._sketchStage.currentVertexIndex = event.vertexIndex
        const entityGraphic = this._sketchStage.entityGraphic
        const originCoordinates = entityGraphic.geometry.coordinates[0]
        entityGraphic.geometry.coordinates[0][event.vertexIndex] =
          event.movePoint.coordinates
        // 当被移动的顶点是区的最后一个点，则需同步改变区的第一个顶点坐标。
        // 当被移动的顶点是区的第一个点，则需同步改变区的最后一个顶点坐标。
        if (
          entityGraphic.geometry.coordinates[0].length - 1 ===
          event.vertexIndex
        ) {
          entityGraphic.geometry.coordinates[0][0] = event.movePoint.coordinates
        } else if (event.vertexIndex === 0) {
          entityGraphic.geometry.coordinates[0][
            entityGraphic.geometry.coordinates[0].length - 1
          ] = event.movePoint.coordinates
        }
        entityGraphic.geometry = new Polygon({
          coordinates: entityGraphic.geometry.coordinates,
          spatialReference: this._spatialReference
        })
        // 更新同级的辅助草图的图形位置
        if (this._otherDrawTools) {
          const curIndex = event.vertexIndex
          const lastIndex =
            curIndex === 0
              ? curIndex - 1 + this._sketchStage.midVertexGraphics.length
              : curIndex - 1
          const nextIndex =
            curIndex === this._sketchStage.midVertexGraphics.length - 1
              ? 0
              : curIndex + 1
          const feature = this._sketchStage.midVertexGraphics[curIndex]
          const featureLast = this._sketchStage.midVertexGraphics[lastIndex]
          const pLast = originCoordinates[lastIndex]
          const p = originCoordinates[curIndex]
          const pNext = originCoordinates[nextIndex]
          feature.geometry.coordinates = [
            (pNext[0] + p[0]) / 2,
            (pNext[1] + p[1]) / 2
          ]
          feature.geometry = new Point({
            coordinates: feature.geometry.coordinates,
            spatialReference: this._spatialReference
          })
          featureLast.geometry.coordinates = [
            (pLast[0] + p[0]) / 2,
            (pLast[1] + p[1]) / 2
          ]
          featureLast.geometry = new Point({
            coordinates: featureLast.geometry.coordinates,
            spatialReference: this._spatialReference
          })
        }
      }

      /**
       * @description 响应中点位置增加顶点事件
       * @private
       * @param {Object} event 传入事件参数
       */
      _handlerMidVertexAddEvent(event) {
        if (event.action === 'changeFeature') {
          // 向当前草图几何对象中插入一个顶点
          this._sketchStage.entityGraphic.geometry.coordinates[0].splice(
            event.vertexIndex + 1,
            0,
            event.point.coordinates
          )
          this._sketchStage.entityGraphic.geometry = new Polygon({
            coordinates: [this._sketchStage.entityGraphic.geometry.coordinates[0]],
            spatialReference: this._spatialReference
          })
        }
        if (event.action === 'moveMidVertex') {
          // 根据移动的顶点实时位置，更新当前草图图形顶点坐标
          this._sketchStage.currentVertexIndex = event.vertexIndex
          this._sketchStage.entityGraphic.geometry.coordinates[0][
            event.vertexIndex + 1
          ] = event.movePoint.coordinates
          this._sketchStage.entityGraphic.geometry = new Polygon({
            coordinates: this._sketchStage.entityGraphic.geometry.coordinates,
            spatialReference: this._spatialReference
          })
        }
        if (event.action === 'addVertex') {
          // 更新同级的辅助草图的图形顶点
          // 增加一个新的顶点和两个中点图形
          const oldMidId =
            this._sketchStage.midVertexGraphics[event.vertexIndex].id.toString()
          const pointDrawTool = new SketchPointDrawTool({
            mapView: this._mapView,
            layer: this._layer,
            sketchStyle: new SketchStyle({
              vertexStyle: this._sketchStyle._selectVertexStyle
            }),
            snappingOption: {
              showSelectBox: false,
              _hitTestMode: 1
            },
            _parent: this, // 或者只传父级相应pan的事件
            _hitTestEvent: this._hitTestEvent
          })
          pointDrawTool.addFeature(event.point)
          this._hitTestDrawToolStack.push(pointDrawTool)
          this._sketchStage.vertexGraphics.splice(
            event.vertexIndex + 1,
            0,
            pointDrawTool._sketchStage.entityGraphic
          )

          // 添加第一个中点
          const p =
            this._sketchStage.entityGraphic.geometry.coordinates[0][
              event.vertexIndex
            ]
          const newMidPoint1 = new Point({
            coordinates: [
              (p[0] + event.point.coordinates[0]) / 2,
              (p[1] + event.point.coordinates[1]) / 2
            ],
            spatialReference: this._spatialReference
          })
          const midPointDrawTool1 = new SketchPointDrawTool({
            mapView: this._mapView,
            layer: this._layer,
            sketchStyle: new SketchStyle({
              vertexStyle: this._sketchStyle._selectMidVertexStyle
            }),
            snappingOption: {
              showSelectBox: false,
              _hitTestMode: 1
            },
            _parent: this, // 或者只传父级相应pan的事件
            _hitTestEvent: this._hitTestEvent
          })
          midPointDrawTool1.addFeature(newMidPoint1, undefined, {
            type: 'midVertex'
          })
          this._hitTestDrawToolStack.push(midPointDrawTool1)
          // 下标为vertexIndex的元素被替换掉
          this._sketchStage.midVertexGraphics.splice(
            event.vertexIndex,
            1,
            midPointDrawTool1._sketchStage.entityGraphic
          )
          // 添加第二个中点
          const pNext =
            this._sketchStage.entityGraphic.geometry.coordinates[0][
              event.vertexIndex + 2
            ]
          const newMidPoint2 = new Point({
            coordinates: [
              (pNext[0] + event.point.coordinates[0]) / 2,
              (pNext[1] + event.point.coordinates[1]) / 2
            ],
            spatialReference: this._spatialReference
          })
          const midPointDrawTool2 = new SketchPointDrawTool({
            mapView: this._mapView,
            layer: this._layer,
            sketchStyle: new SketchStyle({
              vertexStyle: this._sketchStyle._selectMidVertexStyle
            }),
            snappingOption: {
              showSelectBox: false,
              _hitTestMode: 1
            },
            _parent: this, // 或者只传父级相应pan的事件
            _hitTestEvent: this._hitTestEvent
          })
          midPointDrawTool2.addFeature(newMidPoint2, undefined, {
            type: 'midVertex'
          })
          this._hitTestDrawToolStack.push(midPointDrawTool2)
          // 下标为vertexIndex的元素后面添加一个新元素
          this._sketchStage.midVertexGraphics.splice(
            event.vertexIndex + 1,
            0,
            midPointDrawTool2._sketchStage.entityGraphic
          )
          // 更新每个feature的VertexIndex
          this._sketchStage.vertexGraphics.forEach((feature, i) => {
            if (feature.attributes) {
              feature.attributes.vertexIndex = i
            } else {
              feature.attributes = {
                vertexIndex: i
              }
            }
          })
          this._sketchStage.midVertexGraphics.forEach((feature, i) => {
            if (feature.attributes) {
              feature.attributes.vertexIndex = i
            } else {
              feature.attributes = {
                vertexIndex: i
              }
            }
          })
          // 移除被选中的中点（中点被新增的顶点替代）
          // let existIndex = -1
          this._otherDrawTools.forEach((drawTool, i) => {
            if (drawTool._sketchStage.entityGraphic.id === oldMidId) {
              // existIndex = i
              this._removeFeatureFromMap(drawTool._sketchStage.entityGraphic)
            }
          })
          // if (existIndex > -1) {
          //   this._otherDrawTools.splice(existIndex, 1)
          // }
          this._otherDrawTools.push(pointDrawTool)
          this._otherDrawTools.push(midPointDrawTool1)
          this._otherDrawTools.push(midPointDrawTool2)
          this._drawTools = this._drawTools.concat([
            pointDrawTool,
            midPointDrawTool1,
            midPointDrawTool2
          ])
        }
      }

      /**
       * 图形捕获，捕获重合点、点在线上、平行线、垂直线
       * @private
       * @param {Point} geoCoord 当前坐标点
       * @param {Array} polygonSpots 被捕获的顶点数据组
       * @param {Array} polygonSpotSlopes 被捕获的直线斜率数据组
       */
      getSnapGraphics(geoCoord, polygonSpots, polygonSpotSlopes) {
        let realPoint = null
        const tolerance = this.getDistanceByPixel
          ? this.getDistanceByPixel(this.sketchSnappingTool.pixelTolerance)
          : 200
        // 获取捕获结果
        const snapResult = this.sketchSnappingTool.drawingSnap(
          geoCoord,
          new LineString({
            coordinates: polygonSpots.slice(polygonSpots.length - 2)
          }),
          this._sketchStage.entityGraphic.geometry.coordinates[0].slice(
            0,
            polygonSpots.length - 1
          ),
          polygonSpotSlopes,
          tolerance
        )
        if (snapResult.coincidentPoint) {
          const pointFeature = new Feature({
            geometry: snapResult.coincidentPoint,
            symbol: this._sketchStyle._coincidentPointStyle
          })
          this._sketchStage.snapGraphics.push(pointFeature)
          realPoint = snapResult.coincidentPoint
        }
        // 点在线上捕获上图
        if (snapResult.pointInLine) {
          if (
            snapResult.pointInLine.line &&
            snapResult.pointInLine.line.length > 0
          ) {
            snapResult.pointInLine.line.forEach((line) => {
              const lineFeature = new Feature({
                geometry: line,
                symbol: new SimpleLineSymbol({
                  color: new Color(255, 255, 0, 0.8),
                  width: 3
                })
              })
              this._sketchStage.snapGraphics.push(lineFeature)
            })
          }
          const pointFeature = new Feature({
            geometry: snapResult.pointInLine.realPoint,
            symbol: this._sketchStyle._selectVertexStyle
          })
          this._sketchStage.snapGraphics.push(pointFeature)
          realPoint = snapResult.pointInLine.realPoint
        }
        // 平行捕获结果上图
        if (snapResult.parallelLines && snapResult.parallelLines.length > 0) {
          snapResult.parallelLines.forEach((perpendicularLine, i) => {
            const lineFeature = new Feature({
              geometry: perpendicularLine.line,
              symbol: new SimpleLineSymbol({
                color: new Color(0, 255, 0, 0.8),
                width: 3
              })
            })
            this._sketchStage.snapGraphics.push(lineFeature)
            // 渲染高亮平行
            const symbolFeature = new Feature({
              geometry: perpendicularLine.symbolGeometry,
              symbol: new SimpleLineSymbol({
                color: new Color(255, 0, 0, 0.8),
                width: 3
              })
            })
            this._sketchStage.snapGraphics.push(symbolFeature)
            if (i === 0) {
              realPoint = perpendicularLine.realPoint
            }
          })
        }
        // // 垂直捕获结果上图
        // if (
        //   snapResult.perpendicularLines &&
        //   snapResult.perpendicularLines.length > 0
        // ) {
        //   snapResult.perpendicularLines.forEach((perpendicularLine) => {
        //     const lineFeature = new Feature({
        //       geometry: perpendicularLine.line,
        //       symbol: new SimpleLineSymbol({
        //         color: new Color(255, 0, 0, 0.8),
        //         width: 3
        //       })
        //     })
        //     this._sketchStage.snapGraphics.push(lineFeature)
        //     const pointFeature = new Feature({
        //       geometry: perpendicularLine.perpendicularPoint,
        //       symbol: this._sketchStyle._selectVertexStyle
        //     })
        //     this._sketchStage.snapGraphics.push(pointFeature)
        //     // 渲染高亮垂直、垂足
        //     const symbolFeature = new Feature({
        //       geometry: perpendicularLine.symbolGeometry,
        //       symbol: new SimpleLineSymbol({
        //         color: new Color(255, 0, 0, 0.8),
        //         width: 3
        //       })
        //     })

        //     this._sketchStage.snapGraphics.push(symbolFeature)
        //   })
        // }
        this._sketchStage.snapGraphics.forEach((feature) => {
          this._addFeaturesToMap(feature)
        })
        return realPoint
      }

      /**
       * @description 选中图形顶点
       * @private
       */
      selectVertex() {}

      /**
       * @description 选中图形中点点
       */
      addMidVertex(index, point) {
        const midPointDrawTool = new SketchPointDrawTool()
        midPointDrawTool.addPoint(point)
        this._sketchStage.midVertexGraphics = midPointDrawTool
      }

      /**
       * 当前草图图形中插入新的顶点
       * @private
       * @param {Point} point 新增/插入顶点
       * @param {Number} index 新增/新增点的序号,从1开始
       */
      addVertex(point, index) {
        index--
        let newGeometry = null
        if (index > -1) {
          let vertexCount = 0
          let newCoordinates = []

          vertexCount =
            this._sketchStage.entityGraphic.geometry.coordinates[0].length - 1
          if (index < vertexCount) {
            // 向当前草图几何对象中插入一个顶点
            newCoordinates = this._sketchStage.entityGraphic.geometry.coordinates[0]
            newCoordinates.splice(index, 0, point.coordinates)
            if (index === 0) {
              newCoordinates[newCoordinates.length - 1] = point.coordinates
            } else if (index === newCoordinates.length - 1) {
              newCoordinates.splice(0, 0, point.coordinates)
            }
            this._sketchStage.entityGraphic.geometry.coordinates = [newCoordinates]
            newGeometry = this._sketchStage.entityGraphic.geometry
            // 更新同级的辅助草图的图形顶点
            let pointDrawTool = undefined
            let midPointDrawTool2 = undefined
            const extent = this._sketchStage.entityGraphic.geometry.extent
            if (this._sketchStage.selectBoxGraphics.length > 0) {
              this._sketchStage.selectBoxGraphics.forEach((feature) => {
                feature.geometry.coordinates = [
                  [
                    [extent.xmax, extent.ymax],
                    [extent.xmax, extent.ymin],
                    [extent.xmin, extent.ymin],
                    [extent.xmin, extent.ymax],
                    [extent.xmax, extent.ymax]
                  ]
                ]
              })
            }
            if (this._sketchStage.selectBoxVertexGraphics.length > 0) {
              const points = [
                [extent.xmax, extent.ymax],
                [extent.xmax, extent.ymin],
                [extent.xmin, extent.ymin],
                [extent.xmin, extent.ymax],
                [(extent.xmax + extent.xmin) / 2, extent.ymax],
                [(extent.xmax + extent.xmin) / 2, extent.ymin],
                [extent.xmax, (extent.ymax + extent.ymin) / 2],
                [extent.xmin, (extent.ymax + extent.ymin) / 2]
              ]
              this._sketchStage.selectBoxVertexGraphics.forEach((feature, i) => {
                feature.geometry.coordinates = points[i]
              })
            }
            // 增加一个新的顶点
            if (this._sketchStage.vertexGraphics.length > 0) {
              pointDrawTool = new SketchPointDrawTool({
                mapView: this._mapView,
                layer: this._layer,
                sketchStyle: new SketchStyle({
                  vertexStyle: this._sketchStyle._selectVertexStyle
                }),
                snappingOption: {
                  showSelectBox: false,
                  _hitTestMode: 1
                },
                _parent: this, // 或者只传父级相应pan的事件
                _hitTestEvent: this._hitTestEvent
              })
              pointDrawTool.addFeatureByGeometry(point)
              this._hitTestDrawToolStack.push(pointDrawTool)
              this._sketchStage.vertexGraphics.splice(
                index,
                0,
                pointDrawTool._sketchStage.entityGraphic
              )
              // 更新每个feature的VertexIndex
              this._sketchStage.vertexGraphics.forEach((feature, i) => {
                if (feature.attributes) {
                  feature.attributes.vertexIndex = i
                } else {
                  feature.attributes = {
                    vertexIndex: i
                  }
                }
              })
            }
            // 修改第一个中点坐标，增加第二个新的中点
            if (this._sketchStage.midVertexGraphics.length > 0) {
              let replaceIndex = -1
              let addIndex = -1
              let pLast = null
              let pNext = null
              if (index === 0) {
                addIndex = 0
                replaceIndex = this._sketchStage.midVertexGraphics.length - 1
                pLast =
                  this._sketchStage.entityGraphic.geometry.coordinates[0][
                    this._sketchStage.entityGraphic.geometry.coordinates[0].length -
                      2
                  ]
                pNext = this._sketchStage.entityGraphic.geometry.coordinates[0][1]
              }
              // else if (index === this._sketchStage.midVertexGraphics.length - 2) {
              //   nextIndex = 0
              // }
              else {
                replaceIndex = index - 1
                addIndex = index + 1
                pLast =
                  this._sketchStage.entityGraphic.geometry.coordinates[0][
                    replaceIndex
                  ]
                pNext =
                  this._sketchStage.entityGraphic.geometry.coordinates[0][addIndex]
              }
              // 修改第一个中点
              const newMidPoint1 = new Point({
                coordinates: [
                  (pLast[0] + point.coordinates[0]) / 2,
                  (pLast[1] + point.coordinates[1]) / 2
                ],
                spatialReference: this._spatialReference
              })
              // 下标为Index的上一个点坐标被替换掉新坐标
              this._sketchStage.midVertexGraphics[
                replaceIndex
              ].geometry.coordinates = newMidPoint1.coordinates
              // 添加第二个中点
              const newMidPoint2 = new Point({
                coordinates: [
                  (pNext[0] + point.coordinates[0]) / 2,
                  (pNext[1] + point.coordinates[1]) / 2
                ],
                spatialReference: this._spatialReference
              })
              midPointDrawTool2 = new SketchPointDrawTool({
                mapView: this._mapView,
                layer: this._layer,
                sketchStyle: new SketchStyle({
                  vertexStyle: this._sketchStyle._selectMidVertexStyle
                }),
                snappingOption: {
                  showSelectBox: false,
                  _hitTestMode: 1
                },
                _parent: this, // 或者只传父级相应pan的事件
                _hitTestEvent: this._hitTestEvent
              })
              midPointDrawTool2.addFeatureByGeometry(newMidPoint2, undefined, {
                type: 'midVertex'
              })
              this._hitTestDrawToolStack.push(midPointDrawTool2)
              // 下标为Index的元素后面添加一个新元素
              this._sketchStage.midVertexGraphics.splice(
                index,
                0,
                midPointDrawTool2._sketchStage.entityGraphic
              )
              this._sketchStage.midVertexGraphics.forEach((feature, i) => {
                if (feature.attributes) {
                  feature.attributes.vertexIndex = i
                } else {
                  feature.attributes = {
                    vertexIndex: i
                  }
                }
              })
            }
            // 修改drawTool集合中增加一个顶点两个中点
            if (pointDrawTool) {
              this._otherDrawTools.push(pointDrawTool)
              this._drawTools.push(pointDrawTool)
            }
            if (midPointDrawTool2) {
              this._otherDrawTools.push(midPointDrawTool2)
              this._drawTools.push(midPointDrawTool2)
            }
            this.undoRedoManager.addProcess('update', this._sketchStage)
          }
          return newGeometry
        }
      }

      /**
       * 更新当前草图图形的某个顶点
       * @param {Point} point 新的顶点
       * @param {Number} index 需更新的顶点的序号
       */
      updateVertex(point, index) {
        index--
        let newGeometry = null
        if (index > -1) {
          const vertexCount =
            this._sketchStage.entityGraphic.geometry.coordinates[0].length - 1
          if (index < vertexCount) {
            // 当前草图几何对象中更新顶点，更新草图实体图形
            const entityGraphic = this._sketchStage.entityGraphic
            const newCoordinates = entityGraphic.geometry.coordinates[0]
            entityGraphic.geometry.coordinates = [newCoordinates]
            this.currentVertexIndex = index

            newCoordinates[index] = point.coordinates
            if (newCoordinates.length - 1 === index) {
              newCoordinates[0] = point.coordinates
            } else if (index === 0) {
              newCoordinates[newCoordinates.length - 1] = point.coordinates
            }
            entityGraphic.geometry = new Polygon({
              coordinates: entityGraphic.geometry.coordinates,
              spatialReference: this._spatialReference
            })
            newGeometry = entityGraphic.geometry

            const extent = entityGraphic.geometry.extent
            if (this._sketchStage.selectBoxGraphics.length > 0) {
              this._sketchStage.selectBoxGraphics.forEach((feature) => {
                feature.geometry.coordinates = [
                  [
                    [extent.xmax, extent.ymax],
                    [extent.xmax, extent.ymin],
                    [extent.xmin, extent.ymin],
                    [extent.xmin, extent.ymax],
                    [extent.xmax, extent.ymax]
                  ]
                ]
              })
            }
            if (this._sketchStage.selectBoxVertexGraphics.length > 0) {
              const points = [
                [extent.xmax, extent.ymax],
                [extent.xmax, extent.ymin],
                [extent.xmin, extent.ymin],
                [extent.xmin, extent.ymax],
                [(extent.xmax + extent.xmin) / 2, extent.ymax],
                [(extent.xmax + extent.xmin) / 2, extent.ymin],
                [extent.xmax, (extent.ymax + extent.ymin) / 2],
                [extent.xmin, (extent.ymax + extent.ymin) / 2]
              ]
              this._sketchStage.selectBoxVertexGraphics.forEach((feature, i) => {
                feature.geometry.coordinates = points[i]
              })
            }
            // 更新顶点图形
            if (this._sketchStage.vertexGraphics.length > 0) {
              this._sketchStage.vertexGraphics[index].geometry.coordinates =
                point.coordinates
            }
            // 更新中点图形
            if (this._sketchStage.midVertexGraphics.length > 0) {
              const curIndex = index
              const lastIndex =
                curIndex === 0
                  ? curIndex - 1 + this._sketchStage.midVertexGraphics.length
                  : curIndex - 1
              const nextIndex =
                curIndex === this._sketchStage.midVertexGraphics.length - 1
                  ? 0
                  : curIndex + 1
              const feature = this._sketchStage.midVertexGraphics[curIndex]
              const featureLast = this._sketchStage.midVertexGraphics[lastIndex]
              const pLast = newCoordinates[lastIndex]
              const p = newCoordinates[curIndex]
              const pNext = newCoordinates[nextIndex]
              feature.geometry.coordinates = [
                (pNext[0] + p[0]) / 2,
                (pNext[1] + p[1]) / 2
              ]
              feature.geometry = new Point({
                coordinates: feature.geometry.coordinates,
                spatialReference: this._spatialReference
              })
              featureLast.geometry.coordinates = [
                (pLast[0] + p[0]) / 2,
                (pLast[1] + p[1]) / 2
              ]
              featureLast.geometry = new Point({
                coordinates: featureLast.geometry.coordinates,
                spatialReference: this._spatialReference
              })
            }
          }
          this.undoRedoManager.addProcess('update', this._sketchStage)
        }
        return newGeometry
      }

      /**
       * 移除草图图形的某个顶点
       * @param {Number} index 需更新的顶点的序号
       */
      removeVertex(index) {
        index--
        let newGeometry = null
        if (index > -1) {
          const vertexCount =
            this._sketchStage.entityGraphic.geometry.coordinates[0].length - 1
          if (vertexCount > 3 && index < vertexCount) {
            const newCoordinates =
              this._sketchStage.entityGraphic.geometry.coordinates[0]
            // 更新草图实体图形
            newCoordinates.splice(index, 1)
            if (index === 0) {
              newCoordinates.splice(newCoordinates.length - 1, 1, newCoordinates[0])
            }
            // else if (index === vertexCount - 1) {
            //   newCoordinates.splice(index - 1, 1)
            //   newCoordinates.splice(0, 1)
            // }
            newGeometry = new Polygon({
              coordinates: [newCoordinates],
              spatialReference: this._spatialReference
            })
            this._sketchStage.entityGraphic.geometry = newGeometry
            // 更新草图辅助图形
            const extent = this._sketchStage.entityGraphic.geometry.extent
            if (this._sketchStage.selectBoxGraphics.length > 0) {
              this._sketchStage.selectBoxGraphics.forEach((feature) => {
                feature.geometry.coordinates = [
                  [
                    [extent.xmax, extent.ymax],
                    [extent.xmax, extent.ymin],
                    [extent.xmin, extent.ymin],
                    [extent.xmin, extent.ymax],
                    [extent.xmax, extent.ymax]
                  ]
                ]
              })
            }
            if (this._sketchStage.selectBoxVertexGraphics.length > 0) {
              const points = [
                [extent.xmax, extent.ymax],
                [extent.xmax, extent.ymin],
                [extent.xmin, extent.ymin],
                [extent.xmin, extent.ymax],
                [(extent.xmax + extent.xmin) / 2, extent.ymax],
                [(extent.xmax + extent.xmin) / 2, extent.ymin],
                [extent.xmax, (extent.ymax + extent.ymin) / 2],
                [extent.xmin, (extent.ymax + extent.ymin) / 2]
              ]
              this._sketchStage.selectBoxVertexGraphics.forEach((feature, i) => {
                feature.geometry.coordinates = points[i]
              })
            }
            if (this._sketchStage.vertexGraphics.length > 0) {
              const oriFeatureId =
                this._sketchStage.vertexGraphics[index].id.toString()
              this._removeFeatureFromMap(this._sketchStage.vertexGraphics[index])
              this._sketchStage.vertexGraphics.splice(index, 1)
              this._sketchStage.vertexGraphics.forEach((feature, i) => {
                if (feature.attributes) {
                  feature.attributes.vertexIndex = i
                } else {
                  feature.attributes = {
                    vertexIndex: i
                  }
                }
              })
              this._otherDrawTools = this._otherDrawTools.filter((drawTool) => {
                if (drawTool._sketchStage.entityGraphic.id !== oriFeatureId) {
                  return drawTool
                }
              })
            }
            if (this._sketchStage.midVertexGraphics.length > 0) {
              let newMidCoordinates = []
              let updateIndex = -1
              if (index === 0) {
                // newMidCoordinates = [
                //   (newGeometry[newGeometry.length - 1][0] + newGeometry[index][0]) /
                //     2,
                //   (newGeometry[newGeometry.length - 1 - 1][1] +
                //     newGeometry[index][1]) /
                //     2
                // ]
                newMidCoordinates = [
                  (newGeometry.coordinates[0][
                    newGeometry.coordinates[0].length - 2
                  ][0] +
                    newGeometry.coordinates[0][index][0]) /
                    2,
                  (newGeometry.coordinates[0][
                    newGeometry.coordinates[0].length - 2
                  ][1] +
                    newGeometry.coordinates[0][index][1]) /
                    2
                ]
                updateIndex = this._sketchStage.midVertexGraphics.length - 1
              }
              // else if (index  === vertexCount - 1) {
              //   newMidCoordinates = [
              //     (newGeometry[newGeometry.length - 1][0] + newGeometry[index][0]) /
              //       2,
              //     (newGeometry[newGeometry.length - 1 - 1][1] +
              //       newGeometry[index][1]) /
              //       2
              //   ]
              // }
              else {
                newMidCoordinates = [
                  (newGeometry.coordinates[0][index - 1][0] +
                    newGeometry.coordinates[0][index][0]) /
                    2,
                  (newGeometry.coordinates[0][index - 1][1] +
                    newGeometry.coordinates[0][index][1]) /
                    2
                ]
                updateIndex = index - 1
              }
              this._sketchStage.midVertexGraphics[updateIndex].geometry = new Point(
                {
                  coordinates: newMidCoordinates,
                  spatialReference: this._spatialReference
                }
              )
              const oriFeatureId =
                this._sketchStage.vertexGraphics[index].id.toString()
              this._removeFeatureFromMap(this._sketchStage.midVertexGraphics[index])
              this._sketchStage.midVertexGraphics.splice(index, 1)
              // this._otherDrawTools.filter(drawTool => drawTool._sketchStage.entityGraphic.id!= )
              this._sketchStage.midVertexGraphics.forEach((feature, i) => {
                if (feature.attributes) {
                  feature.attributes.vertexIndex = i
                } else {
                  feature.attributes = {
                    vertexIndex: i
                  }
                }
              })
              this._otherDrawTools = this._otherDrawTools.filter((drawTool) => {
                if (drawTool._sketchStage.entityGraphic.id !== oriFeatureId) {
                  return drawTool
                }
              })
            }
          }
          this.undoRedoManager.addProcess('update', this._sketchStage)
        }
        return newGeometry
      }
    }
    export default SketchPolygonDrawTool