How to simulate triggering the 'vertex-add' event of the DrawAction class?

94
0
2 weeks ago
3kmsdistance
New Contributor

After instantiating the DrawAction, I want to manually plot points for drawing. When I call the emitDraw method, I want to trigger the vertex-add event, drawing a point at the center of the map. However, this method does not update _action.vertices, and when I call _action.redo() or _action.undo(), this drawing is not recorded. How to manually draw points step by step and support undo redo?

 

class ArcgisDraw {
  _draw
  _action
  _view
  _type
  constructor(view: MapView, type: ShapeType) {
    this._view = view
    this._type = type
    this.drawAction()
  }
  drawAction() {
    this._draw = new Draw({
      view: this._view
    })
    this._action = this._draw.create(this._type)
    this._view.focus()
    this._action.on(['vertex-add', 'vertex-remove', 'redo', 'undo', 'draw-complete'], (event) => {
      this.createGraphic(event.vertices)
    })
  }

  emitDraw() {
    const center = this._view.center
    const newPoint = [center.longitude, center.latitude]
    let vertices
    if (this._action.vertices.length) {
      vertices = this._action.vertices.concat([newPoint])
    } else {
      vertices = [newPoint]
    }
    this._action.emit('vertex-add', {
      vertices
    })
    // 不会更新 this._action.vertices
  }

  createGraphic(vertices: any) {
    // 添加到 default graphics in the View 不会闪
    // 倘若添加到图层上,就会闪
    const ids = [this.id, this.textId]
    this.removeGraphic(ids)
    this.createLineOrPolygonGraphic(vertices)
    this.createTextGraphic(vertices)
  }

  /**
   * 线,面
   * @param vertices
   */
  createLineOrPolygonGraphic(vertices: any) {
    let symbol
    let geometry
    if (vertices.length === 1) {
      geometry = {
        type: 'point',
        longitude: vertices[0][0],
        latitude: vertices[0][1]
      }
      symbol = {
        type: 'simple-marker', // autocasts as new SimpleMarkerSymbol()
        color: [255, 127, 0],
        size: 10,
        outline: {
          width: '0'
        }
      }
    } else {
      switch (this._type) {
        case 'polyline':
          symbol = {
            type: 'simple-line',
            color: [255, 127, 0],
            width: 4,
            cap: 'round',
            join: 'round'
          }
          geometry = {
            type: 'polyline',
            paths: vertices,
            spatialReference: this._view.spatialReference
          }
          break
        case 'polygon':
          symbol = {
            type: 'simple-fill', // autocasts as SimpleFillSymbol
            color: [244, 206, 164, 0.5],
            style: 'solid',
            outline: {
              // autocasts as SimpleLineSymbol
              color: [255, 127, 0],
              width: 4
            }
          }
          geometry = {
            type: 'polygon', // autocasts as Polygon
            rings: vertices,
            spatialReference: this._view.spatialReference
          }
          break
      }
    }
    const graphic = new Graphic({
      geometry,
      symbol,
      attributes: {
        id: this.id
      }
    })
    this._view.graphics.add(graphic)
  }

  /**
   * 周长或者面积 textSymbol
   * @param vertices
   * @returns
   */
  createTextGraphic(vertices: any) {
    if (vertices.length <= 1) return
    const features = turf.points(vertices)
    const center = turf.center(features)
    let value = 0,
      text = ''
    if (this._type === 'polyline') {
      const line = turf.lineString(vertices)
      value = turf.length(line, { units: 'kilometers' })
      text = value.toFixed(2) + 'km'
    } else if (this._type === 'polygon') {
      if (vertices.length < 3) return
      vertices.push(vertices[0]) // 使得数组闭合
      const polygon = turf.polygon(Array.of(vertices))
      value = turf.area(polygon)
      text = (value * 0.000001).toFixed(2) + 'km²'
    }
    const textGraphic = new Graphic({
      geometry: {
        type: 'point',
        longitude: center.geometry.coordinates[0],
        latitude: center.geometry.coordinates[1]
      },
      symbol: {
        type: 'text', // autocasts as new TextSymbol()
        text,
        color: '#fff',
        haloSize: 2,
        haloColor: '#333',
        font: {
          // autocasts as new Font()
          size: 14,
          family: 'sans-serif',
          weight: 'bold'
        }
      },
      attributes: {
        id: this.textId
      }
    })
    this._view.graphics.add(textGraphic)
  }

}

 

  

0 Kudos
0 Replies