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