---
title: 图形绘制工具
source: https://vjmap.com/guide/draw.html
---

# 图形绘制工具


## 开始

```js
const draw = new vjmap.Draw.Tool();
map.addControl(draw, 'top-right');
```



## 选项

以下所有选项都是可选的。

- `keybindings`, boolean (default `true`): 是否启用用于绘图的键盘交互。
- `touchEnabled`, boolean (default `true`): 是否为绘图启用触摸交互。
- `boxSelect`，boolean（缺省`true`）：是否启用与功能框选择`shift`\+ `click`+阻力。如果`false`，`shift`\+ `click`+drag 放大区域。
- `clickBuffer`, number (default: `2`): 任何特征或顶点（在每个方向）周围的像素数，这些像素会响应点击。
- `touchBuffer`, number (default: `25`): 顶点的任何特征（在每个方向）周围的像素数，这些特征将响应触摸。
- `controls`, Object：隐藏或显示单个控件。每个属性的名称是一个控件，值是一个布尔值，指示控件是打开还是关闭。可用的控制名称`point`,`line_string`,`polygon`,`trash`,`combine_features`,`uncombine_features`,`drawCircle`,`snap_mode_snap`,`snap_mode_grid`,`splitLine`,`cutPolygon`,`drawRectangle`,`redo`,`undo`,`snap_mode_snap`,`snap_mode_grid`。默认情况下，所有控件都打开。要更改该默认值，请使用`displayControlsDefault`.
- `displayControlsDefault`, boolean (default: `true`): 的默认值`controls`。例如，如果您希望所有控件默认_关闭_，并使用 指定允许列表`controls`，请使用`displayControlsDefault: false`。
- `styles`, Array<Object>：地图样式对象的数组。默认情况下，Draw 为您提供了一种地图样式。
- `modes`, Object：用您自己的方式覆盖默认模式。
- `defaultMode`, String (default: `'simple_select'`):`modes`用户将首先登陆的模式（来自）。
- `snap`, boolean（默认值：）`true`：是否启用捕捉节点
- `guides`, boolean（默认值：）`true`：是否启用捕捉网格
- `snapOptions` Object, 捕捉选项,缺省为({snapPx: 15, snapToMidPoints: false, snapVertexPriorityDistance: 1.25, snapGridPx: 2000(捕捉网格线像素长度))
- `addControls` Array<Object>：要增加的控件
- `api` Object api方法，可通过属性`getSnapFeatures`设置额外捕捉的实体
- `isActionDrawMode` 设置为true的时候，按钮工具栏将不会创建，只能通过命令来调用 

::: tip 提示
绘制时，按往 Alt 键，将临时取消捕捉模式
绘制时，按往 Ctrl 键，将临时启用正交模式，只能绘制相对视口的水平或垂直线
:::

捕捉样式图例说明

<div align="left">
  <img :src="$withBase('/assets/images/snapstyle.png')" />
</div>

## 模式


模式名称字符串可作为枚举使用`Draw.modes`。
### `static`
 非编辑模式，是非编辑模式下，用户不能编辑图形，可以高亮或点击图形。

需要在非编辑模式下高亮实体，需给实体设置`hoverPointer`属性为`true`,如果要自定义高亮的透明度，设置`hover_opacity`属性。默认高亮透明度为`0.55`

非编辑模式下面的事件有
- draw.static.setup 开始
- draw.static.click 点击
- draw.static.mousedown
- draw.static.mouseup
- draw.static.mouseout
- draw.static.keyup
- draw.static.keydown
- draw.static.mouseenter
- draw.static.mouseleave
- draw.static.contextmenu
- draw.static.tap
- draw.static.stop 结束

例如可以响应上面事件，在非编辑模式下面提示信息框
```js
// 创建完后修改颜色
map.on("draw.create", function (e) {
    let color = vjmap.randomColor();
    for(let i = 0; i <  e.features.length; i++) {
        let id = e.features[i].id;
        if (!draw.get(id)) continue;
        draw.setFeatureProperty(id, "color", color);
        draw.setFeatureProperty(id, "hoverPointer", true); // 允许非编辑模式下高亮
    }
});

 const popup = new vjmap.Popup({
     closeButton: false
 });
// 非编辑模式下，鼠标悬浮时，显示信息提示内容
map.on("draw.static.mouseenter", e => {
    if (e.event.featureTarget) {
        popup.setLngLat(e.event.lngLat);
        popup.setHTML(JSON.stringify(e.event.featureTarget.properties, null, 4));
        popup.addTo(map);
    }
});

map.on("draw.static.mouseleave", e => {
   if (popup) popup.remove();
});

map.on("draw.static.click", e => {
   alert(`您点击了id为：${e.event.featureTarget.properties.id} 的实体`)
});
```


### `simple_select`

`Draw.modes.SIMPLE_SELECT === 'simple_select'`

用于选择、删除和拖动要素。

在此模式下，用户可以更改功能的选定状态。

绘图`simple_select`默认处于`simple_select`模式，每次用户完成绘制特征或退出`direct_select`模式时，都会自动再次转换为模式。

### `direct_select`

`Draw.modes.DIRECT_SELECT === 'direct_select'`

允许您选择、删除和拖动顶点；和拖动功能。

`direct_select` 模式不适用于点要素，因为它们没有顶点。

`direct_select`当用户单击所选线或多边形的顶点时，Draw 进入模式。所以`direct_select`模式通常遵循`simple_select`模式。

### `draw_line_string`

`Draw.modes.DRAW_LINE_STRING === 'draw_line_string'`

允许您绘制 LineString 要素。按 `退格键backspace`会删除上一个点

### `draw_polygon`

`Draw.modes.DRAW_POLYGON === 'draw_polygon'`

允许您绘制多边形特征。按 `退格键backspace`会删除上一个点

### `draw_point`

`Draw.modes.DRAW_POINT === 'draw_point'`

用于绘制点要素。

### `draw_circle`

用于绘制圆要素。

### `draw_rectangle`

用于绘制矩形要素。

### `splitLineMode`

用于分割线要素。

### `cutPolygonMode`

用于分割多边形要素。

```js
var addControls = [
{
   id: "drawCircle",
   title: '绘制圆',
   className: "vjmap-map-draw_circle",
   onActivate: function (ctx){
     ctx.api.changeMode('draw_circle');
   }
},
{
    id: "drawRectangle",
    title: '绘制矩形',
    className: "vjmap-map-draw_rectangle",
    onActivate: function (ctx){
      ctx.api.changeMode('draw_rectangle');
    }
 },
{
    id: "splitLine",
    title: '分割线',
    className: "vjmap-map-draw-cut-line",
    onActivate: function (ctx){
      ctx.api.changeMode('splitLineMode', { spliter: 'line_string' });
    }
 },
 {
    id: "cutPolygon",
    title: '分割多边形',
    className: "vjmap-map-draw-cut-polygon",
    onActivate: function (ctx){
      ctx.api.changeMode('cutPolygonMode');
    }
 },
 {
    id: "undo",
    title: '撤销上一步操作',
    className: "vjmap-map-draw_undo",
    onActivate: function (ctx){
      ctx.api.undo();
    }
},
  {
    id: "redo",
    title: '重复上一步操作',
    className: "vjmap-map-draw_redo",
    onActivate: function (ctx){
      ctx.api.redo();
    }
},
{
    id: "snap_mode_snap",
    title: '捕捉点',
    className: "snap_mode_snap",
    isCheckbox: true,
    checked: true,
    onActivate: function (ctx, e){
        ctx.options.snap = e.target.checked;
    }
 },
 {
     id: "snap_mode_grid",
     title: '捕捉网格',
     isCheckbox: true,
     checked: true,
     className: "snap_mode_grid",
     onActivate: function (ctx, e){
        ctx.options.guides = e.target.checked;
     }
  }
  ]
```



## API 方法

`var draw = new vjmap.Draw.Tool()` 将返回以下API:

### `add(geojson: Object) => Array<string>`

此方法采用 GeoJSON Feature、FeatureCollection 或 Geometry 并将其添加到 Draw。它返回一个 id 数组，用于与添加的功能进行交互。如果某个功能没有自己的 id，则会自动生成一个。

支持的以GeoJSON特征类型的支持：`Point`，`LineString`，`Polygon`，`MultiPoint`， `MultiLineString`，和`MultiPolygon`。

如果您`add()`的功能的 id 已在使用中，则现有功能将被更新，并且不会添加新功能。

没有指定功能 ID 的示例：

```js
var feature = { type: 'Point', coordinates: [0, 0] };
var featureIds = draw.add(feature);
console.log(featureIds);
//=> ['some-random-string']
```

具有指定功能 ID 的示例：

```js
var feature = {
  id: 'unique-id',
  type: 'Feature',
  properties: {},
  geometry: { type: 'Point', coordinates: [0, 0] }
};
var featureIds = draw.add(feature);
console.log(featureIds)
//=> ['unique-id']
```

---
### `get(featureId: string): ?Feature`

返回 Draw 中具有指定 id 的 GeoJSON 功能，或者`undefined`如果 id 不匹配任何功能。

例子：

```js
var featureIds = draw.add({ type: 'Point', coordinates: [0, 0] });
var pointId = featureIds[0];
console.log(draw.get(pointId));
//=> { type: 'Feature', geometry: { type: 'Point', coordinates: [0, 0] } }
```

---
### `getFeatureIdsAt(point: { x: number, y: number }): Array<string>`

返回当前在指定点呈现的功能的功能 ID 数组。

请注意，该`point`参数需要`x`，`y`从像素空间，而不是经度，纬度坐标的坐标。

有了这个函数，你可以使用鼠标事件提供的坐标从 Draw 中获取信息。

```js
var featureIds = Draw.getFeatureIdsAt({x: 20, y: 20});
console.log(featureIds)
//=> ['top-feature-at-20-20', 'another-feature-at-20-20']
```
---
### `getSelectedIds(): Array<string>`

返回当前所选功能的功能 ID 数组。

---
### `getSelected(): FeatureCollection`

返回当前选择的所有功能的 FeatureCollection。

---
### `getSelectedPoints(): FeatureCollection`

返回代表当前选择的所有顶点的 FeatureCollection 点。

---
### `getAll(): FeatureCollection`

返回所有功能的 FeatureCollection。

Example:

```js
draw.add({ type: 'Point', coordinates: [0, 0] });
draw.add({ type: 'Point', coordinates: [1, 1] });
draw.add({ type: 'Point', coordinates: [2, 2] });
console.log(draw.getAll());
// {
//   type: 'FeatureCollection',
//   features: [
//     {
//       id: 'random-0'
//       type: 'Feature',
//       geometry: {
//         type: 'Point',
//         coordinates: [0, 0]
//       }
//     },
//     {
//       id: 'random-1'
//       type: 'Feature',
//       geometry: {
//         type: 'Point',
//         coordinates: [1, 1]
//       }
//     },
//     {
//       id: 'random-2'
//       type: 'Feature',
//       geometry: {
//         type: 'Point',
//         coordinates: [2, 2]
//       }
//     }
//   ]
// }
```
---

### `delete(ids: string | Array<string>): draw`

删除具有指定 ID 的功能。返回用于链接的绘制实例。

在`direct_select`模式下，删除活动特征将退出该模式并恢复到该`simple_select`模式。

例子：

```js
var feature = { type: 'Point', coordinates: [0, 0] };
var ids = draw.add(feature);
draw
  .delete(ids)
  .getAll();
// { type: 'FeatureCollection', features: [] }
```

---

### `deleteAll(): draw`

删除所有功能。返回用于链接的绘制实例。

例子：

```js
draw.add({ type: 'Point', coordinates: [0, 0] });
draw
  .deleteAll()
  .getAll();
// { type: 'FeatureCollection', features: [] }
```

---

### `forceRefresh`

强制刷新

例子：

```js
draw.forceRefresh();
```

---

### `undo`

撤销

例子：

```js
draw.undo();
```
---

### `redo`

重做

例子：

```js
draw.redo();
```

---

### `clearHistory`

清空历史记录

例子：

```js
draw.clearHistory();
```
---

### `set(featureCollection: FeatureCollection): Array<string>`

将 Draw 的功能设置为指定 FeatureCollection 中的功能。

执行任何必要的删除、创建和更新操作，以使 Draw 的功能与指定的 FeatureCollection 匹配。实际上，这与`Draw.deleteAll()`后跟相同，`Draw.add(featureCollection)`只是它不会对性能产生太大影响。

例子：

```js
var ids = draw.set({
  type: 'FeatureCollection',
  features: [{
    type: 'Feature',
    properties: {},
    id: 'example-id',
    geometry: { type: 'Point', coordinates: [0, 0] }
  }]
});
// ['example-id']
```

---

### `trash(): draw`

调用当前模式的`trash`操作。返回用于链接的绘制实例。

在`simple_select`模式下，这将删除所有选定的功能。

在`direct_select`模式下，这将删除选定的顶点。

在绘图模式下，这会取消绘图并将绘图恢复为`simple_select`模式。

如果您想删除特征而不考虑当前模式，请使用`delete`或`deleteAll`功能。

---

### `combineFeatures(): draw`

调用当前模式的`combineFeatures`操作。返回用于链接的绘制实例。

在`simple_select`模式下，这会将所有选定的特征组合成一个 Multi\* 特征，_只要它们都是相同的几何类型_。例如：

- 选择是两个 LineStrings => MultiLineString
- 选择是一个 MultiLineString 和一个 LineString => MultiLineString
- 选择是两个 MultiLineStrings => MultiLineString

在选择不同几何类型的特征时调用此函数不会导致任何更改。例如：

- 选择是一个点和一个 LineString => 没有采取任何行动
- 选择是一个 MultiLineString 和一个 MultiPoint => 没有采取任何行动

在`direct_select`模式和绘图模式下，不执行任何操作。

---

### `uncombineFeatures(): draw`

调用当前模式的`uncombineFeatures`操作。返回用于链接的绘制实例。

在`simple_select`模式下，这会将每个选定的 Multi\* 特征拆分为其组成特征部分，并保持非多特征不变。例如：

- 选择是两部分的 MultiLineString => LineString, LineString
- 选择是三部分的 MultiLineString => LineString, LineString, LineString
- 选择是由两部分和一个 Point 组成的 MultiLineString => LineString, LineString, Point
- 选择是 LineString => LineString

在`direct_select`和 绘图模式下，不执行任何操作。

---

### `getMode(): string`

返回 Draw 的当前模式。

---

### `changeMode(mode: string, options?: Object): draw`

将绘图更改为另一种模式。返回用于链接的绘制实例。

所述`mode`参数必须是以上描述并在所列举的模式名称之一`Draw.modes`。

```js
// `simple_select` options
{
  // Array of ids of features that will be initially selected
  featureIds: Array<string>
}
```

```js
// `direct_select` options
{
  // The id of the feature that will be directly selected (required)
  featureId: string
}
```

```js
// `draw_line_string` options
{
  // The id of the LineString to continue drawing
  featureId: string,
  // The point to continue drawing from
  from: Feature<Point>|Point|Array<number>
}
```

---

### `setFeatureProperty(featureId: string, property: string, value: any): draw`

设置具有指定 id 的要素的属性值。返回用于链接的绘制实例。

如果您使用 Draw 的功能作为应用程序中的主要数据存储，这将很有帮助。

例如设置颜色，可以通过
```js
draw.setFeatureProperty(featureId, "color", color);
```

默认样式下，支持的属性有

点

```js
// 圆符号

draw.setFeatureProperty(featureId, "stroke_color_active", "#fff"); // 编辑模式活动状态下边框圆的颜色
draw.setFeatureProperty(featureId, "stroke_radius_active", 7); // 编辑模式活动状态下边框圆的大小
draw.setFeatureProperty(featureId, "color_active", "#fbb03b"); // 编辑模式活动状态下填充圆的颜色
draw.setFeatureProperty(featureId, "radius_active", 5); // 编辑模式活动状态下填充圆的大小

draw.setFeatureProperty(featureId, "stroke_color_inactive", "#fff"); // 编辑模式非活动状态下边框圆的颜色
draw.setFeatureProperty(featureId, "stroke_radius_inactive", 5); // 编辑模式非活动状态下边框圆的大小
draw.setFeatureProperty(featureId, "color_inactive", "#3bb2d0"); // 编辑模式非活动状态下填充圆的颜色
draw.setFeatureProperty(featureId, "radius_inactive", 3); // 编辑模式非活动状态下填充圆的大小

draw.setFeatureProperty(featureId, "color_static", "#3bb2d0"); // 非编辑模式下填充圆的颜色
draw.setFeatureProperty(featureId, "radius_static", 5); // 非编辑模式下边框圆的大小

// 图标符号
draw.setFeatureProperty(featureId, "icon_image", "xxx");
draw.setFeatureProperty(featureId, "icon_size", 1); // 放大倍数
draw.setFeatureProperty(featureId, "icon_rotate", "xxx");
draw.setFeatureProperty(featureId, "text", "xxx"); // 文本值
draw.setFeatureProperty(featureId, "text_rotate", "xxx");// 文本旋转角度 
draw.setFeatureProperty(featureId, "text_opacity", "xxx"); // 文本透明度
draw.setFeatureProperty(featureId, "text_size", "xxx"); //文本大小（默认22)
draw.setFeatureProperty(featureId, "symbol", true|false); // 有图标和文本
draw.setFeatureProperty(featureId, "onlyText", true|false);  // 没有图标，只有文本
```
线

```js
draw.setFeatureProperty(featureId, "color", "xxx");
draw.setFeatureProperty(featureId, "line_width", "xxx");
```

面
```js
draw.setFeatureProperty(featureId, "opacity", "xxx");
draw.setFeatureProperty(featureId, "color", "xxx");
draw.setFeatureProperty(featureId, "line_width", "xxx");
```

修改坐标
```js
draw.setFeatureProperty(featureId, "coordinates", [xxx]);
```

内置特殊属性如下

- 设置实体显示或隐藏
隐藏设置
```js
draw.setFeatureProperty(featureId, "isOff", true); // isOff属性设置为true，即为隐藏了
```

显示设置
```js
 draw.setFeatureProperty(feature.id, "isOff", undefined); // isOff属性移除了。默认就是显示
```


- 设置实体锁定与不锁定，(锁定的实体只可见，不可编辑)
  锁定设置
```js
draw.setFeatureProperty(featureId, "isLocked", true); // isLocked属性设置为true，即为锁定了
```

不锁定设置
```js
 draw.setFeatureProperty(feature.id, "isLocked", undefined); // isLocked属性移除了。默认就是不锁定了
```

设置绘图时不对此实体对象进行捕捉
```js
draw.setFeatureProperty(featureId, "noSnap", true); // noSnap属性设置为true，设置绘图时不对此实体对象进行捕捉
```

设置绘图时选择实体后，再次点击时不允许进行编辑.(如想编辑，可同时按Ctrl键点击) 允许拖动
```js
draw.setFeatureProperty(featureId, "disableDirectEdit", true); //disableDirectEdit属性设置为true，选择实体后，再次点击时不允许进行编辑
```

设置绘图时选择实体后不允许进行编辑.(不允许拖动，也不允许编辑）
```js
draw.setFeatureProperty(featureId, "disable_edit", true); //disable_edit属性设置为true，不允许编辑。设置为undefined允许编辑
```
和`disableDirectEdit` 的区别在于

disableDirectEdit 允许拖动 默认不允许编辑夹点，按Ctrl键可允许编辑

disable_edit     不允许拖动 也不允许编辑夹点


- 设置实体在不同缩放级别下显示
```js
draw.setFeatureProperty(id, "minZoom", 5); // 表示5级以下才显示此实体
draw.setFeatureProperty(id, "maxZoom", 10); // 表示10级以上不会显示此实体
```

- 设置实体颜色
```js
draw.setFeatureProperty(id, "color", color);

draw.setFeatureProperty(id, "fillColor", color); // 填充色，只对多边形有效（如果不填，将使用color属性的颜色)
draw.setFeatureProperty(id, "outlineColor", color);// 边框色，只对多边形有效（如果不填，将使用color属性的颜色)

draw.setFeatureProperty(id, "noneOutline", true);// 不显示多边形边框，只对多边形有效
```

- 设置实体允许浏览模式(非编辑模式)下高亮
```js
draw.setFeatureProperty(id, "hoverPointer", true); // 允许非编辑模式下高亮
draw.setFeatureProperty(id, "hover_color", "#f00"); // 设置高亮颜色
draw.setFeatureProperty(id, "hover_opacity", 0.3); // 设置高亮透明度
```

- 设置多边形为拉伸实体
```js
draw.setFeatureProperty(id, "extrusionHeight", 100000); // 如果多边形有高度属性，则会变为拉伸实体
// draw.setFeatureProperty(id, "extrusionHeight", undefined); // 去掉高度属性，还原为多边形
```

- 符号文本有关属性
```js
draw.setFeatureProperty(featureId, "symbol", true); // 设置为symbol为true时，还会显示符号文本，否则是一个小圆点
draw.setFeatureProperty(featureId, "text", ""); // 文本内容
draw.setFeatureProperty(featureId, "icon_image", ""); // 图标
// 设置旋转角度
draw.setFeatureProperty(featureId, "text_rotate", angle);
draw.setFeatureProperty(featureId, "icon_rotate", angle);
```


```js
map.setCustomKeyValue("_disable_drawkey_backspacekey", true); // 绘图时禁用删除键
map.setCustomKeyValue("_disable_drawkey_escapekey", true); // 绘图时禁用esc取消键
map.setCustomKeyValue("_disable_drawkey_enterkey", true); // 绘图时禁用回车键
```

如果需要扩展更多的属性，需要自定义样式，默认样式见本文最后面

## 事件

Draw 会触发许多事件。所有这些事件都以命名空间命名，`draw.`并从 地图对象发出。所有事件都是由用户交互触发的。

```js
map.on('draw.create', function (e) {
  console.log(e.features);
});
```

**如果您以编程方式调用 Draw API中的函数，则不会触发_与_该函数_直接对应的_任何事件。**例如，如果您调用`draw.delete()`，则不会有相应的`draw.delete`事件，因为您已经知道自己做了什么。但是，可能会触发不直接对应于调用函数的后续事件。例如，如果您选择了一个功能然后调用`draw.changeMode('draw_polygon')`，您将_不会_看到一个`draw.modechange`事件（因为它直接对应于调用的函数），但您_会_看到一个`draw.selectionchange`事件，因为通过更改模式您间接取消了一个功能的选择。

### `draw.create`

创建特征时触发。以下交互将触发此事件：

- 完成绘制要素。只需单击即可创建一个点。LineString 或 Polygon 仅在用户完成绘制时创建——即双击最后一个顶点或按 Enter——并且绘制的特征有效。

事件数据是一个具有以下形状的对象：

```js
{
  // Array of GeoJSON objects representing the features that were created
  features: Array<Object>
}
```

### `draw.delete`

删除一项或多项功能时触发。以下交互将触发此事件：

- 在`simple_select`模式中选择一项或多项功能时，单击垃圾箱按钮。
- 在模式中选择一项或多项功能时，按<kbd>Backspace</kbd>或<kbd>Delete</kbd>键`simple_select`。
- `draw.trash()`当您在`simple_select`mode 中选择了一个功能时调用。

事件数据是一个具有以下形状的对象：

```js
{
  // Array of GeoJSON objects representing the features that were deleted
  features: Array<Feature>
}
```

### `draw.combine`

组合特征时触发。以下交互将触发此事件：

- 当在`simple_select`模式中选择了多个特征时，单击组合按钮。
- `draw.combineFeatures()`在`simple_select`mode中选择多个功能时调用。

事件数据是一个具有以下形状的对象：

```js
{
  deletedFeatures: Array<Feature>, // Array of deleted features (those incorporated into new multifeatures)
  createdFeatures: Array<Feature> // Array of created multifeatures
}
```

### `draw.uncombine`

当特征未组合时触发。以下交互将触发此事件：

- 在`simple_select`模式中选择一个或多个多重特征时，单击取消组合按钮。也可以选择非多重特征。
- `draw.uncombineFeatures()`在`simple_select`mode中选择一个或多个多特征时调用。也可以选择非多重特征。

事件数据是一个具有以下形状的对象：

```js
{
  deletedFeatures: Array<Object>, // Array of deleted multifeatures (split into features)
  createdFeatures: Array<Object> // Array of created features
}
```

### `draw.update`

当一项或多项功能更新时触发。以下交互将触发此事件，可以按以下方式进行细分`action`：

- `action: 'move'`
    - 在`simple_select`模式中完成移动一个或多个选定要素。该事件只会在移动完成时触发（即当用户释放鼠标按钮或点击时<kbd>Enter</kbd>）。
- `action: 'change_coordinates'`
    - 在`direct_select`模式中完成移动选定要素的一个或多个顶点。该事件只会在移动完成时触发（即当用户释放鼠标按钮或点击<kbd>Enter</kbd>，或者她的鼠标离开地图容器时）。
    - 在`direct_select`mode 中删除选定要素的一个或多个顶点，这可以通过按<kbd>Backspace</kbd>或<kbd>Delete</kbd>键、单击垃圾箱按钮或调用 来完成`draw.trash()`。
    - 通过在`direct_select`模式中单击该要素上的中点，将顶点添加到所选要素。

创建或删除要素时_不会_触发此事件。要跟踪这些交互，请侦听`draw.create`和`draw.delete`事件。

事件数据是一个具有以下形状的对象：

```js
{  
  features: Array<Feature>, // Array of features that were updated
  action: string // Name of the action that triggered the update
}
```

### `draw.selectionchange`

更改选择时（即选择或取消选择一个或多个功能）。以下交互将触发此事件：

- 单击一个特征以选择它。
- 当一个特征已被选中时，按住 Shift 键并单击另一个特征以将其添加到选择中。
- 单击一个顶点以选择它。
- 当一个顶点已被选中时，按住 Shift 键并单击另一个顶点以将其添加到选择中。
- 创建一个包含至少一个特征的框选择。
- 单击所选要素外部以取消选择。
- 在远离选定顶点的地方单击以取消选择。
- 完成绘制要素（要素在创建后立即被选中）。
- 当一个功能已经被选中时，调用`draw.changeMode()`使得该功能被取消选中。
- 使用`draw.changeMode('simple_select', { featureIds: [..] })`切换到`simple_select`模式，并立即选择指定的功能。
- 使用`draw.delete`,`draw.deleteAll`或`draw.trash`删除特征。

事件数据是一个具有以下形状的对象：

```js
{
  features: Array<Feature> // Array of features that are selected after the change
}
```

### `draw.modechange`

当模式改变时触发。以下交互将触发此事件：

- 单击点、线或多边形按钮开始绘制（输入`draw_*`模式）。
- 完成绘制要素（进入`simple_select`模式）。
- 在`simple_select`模式下，单击已选择的功能（进入`direct_select`模式）。
- 在`direct_select`模式下，在所有要素外单击（进入`simple_select`模式）。

此事件在当前模式停止之后和下一个模式开始之前触发。直到所有事件处理程序都被触发后才会发生渲染，因此您可以通过`draw.changeMode()`在`draw.modechange`处理程序内部调用来强制模式重定向。

事件数据是一个具有以下形状的对象：

```js
{  
  mode: string // The next mode, i.e. the mode that Draw is changing to
}
```

`simple_select`和`direct_select`模式可以使用特定于该模式的选项启动（见上文）。

### `draw.render`

`setData()`在 地图上的Draw 调用之后触发。这并不意味着 set data 调用已完成更新地图，只是地图正在更新。


### `draw.actionable`

当 Draw 的状态改变以启用和禁用不同的动作时触发。在这个事件将让你知道，如果`draw.trash()`，`draw.combineFeatures()`并`draw.uncombineFeatures()`会产生效果。

```js
{
  actions: {
    trash: true
    combineFeatures: false,
    uncombineFeatures: false
  }
}
```

### `draw.updatecoordinate`

绘制过程中实时更新点坐标

### `draw.simpleselect.contextmenu`

选择模式下上下文菜单事件

### `draw.directselect.contextmenu`

选中编辑夹点模式下上下文菜单事件

### `draw.custom`
其他自定义事件，如要点击锁定的图形，需提示为锁定图形，可用如下代码
```
map.on('draw.custom', e=> {
  if (e.customName === "clickedlocked") {
    console.log(e)
  }
})
```


## 绘图动作Action

### actionDraw

根据参数绘制不同的图形动作

- draw_point 绘制点
- draw_line_string 绘制线
- draw_polygon 绘制多边形
- draw_rectangle 绘制矩形
- draw_slant_rectangle 绘制斜矩形
- draw_circle 绘制圆

如调用绘制点

```js
await vjmap.Draw.actionDraw(map, 'draw_point', {})
```
在绘制过程中，按`ESC`键或`Enter`键可以取消或结束绘制,如果也可以通过代码来主动取消或结束
```js
// 给地图发送ESC键消息即可取消，模拟按ESC键
map.fire("keyup", {keyCode:27})

// 给地图发送Enter键消息即可确认，模拟按Enter键
map.fire("keyup", {keyCode:13})
```
### actionDrawPoint

绘制一个点，返回一个Promise，直到绘制结束，可通过传递回调参数 `updatecoordinate` 得到实时更新的坐标，如果取消，则返回 `cancel`为 `true`, 如

```js
let ellipse = new vjmap.EllipseFill({
    center: center,
    majorAxisRadius: 0,
    minorAxisRadius: 0,
    fillColor: 'green',
    fillOpacity: 0.8,
    fillOutlineColor: "#f00"
});
ellipse.addTo(map);
let ellipseMajorAxisPt = await vjmap.Draw.actionDrawPoint(map, {
    updatecoordinate: (e) => {
        if (!e.lnglat) return;
        const co = map.fromLngLat(e.lnglat);
        ellipse.setMinorAxisRadius(center.distanceTo(co));
        ellipse.setMajorAxisRadius(center.distanceTo(co));
    }
});
if (ellipseMajorAxisPt.cancel) {
    ellipse.remove()
    return ;// 取消操作
}
```

### actionDrawLineSting

绘制一条线，返回一个Promise，直到绘制结束，可通过传递回调参数 `updatecoordinate` 得到实时更新的坐标，如果取消，则返回 `cancel`为 `true`, 如

如果要绘制直线，可以设置 `pointCount` 点数为2。（也可以自定义要绘制的点数，当达到这个点数时，自动结束）


如果要绘制绘制一条闭合的折线，可以设置 `isClosed` 为true
```js

let res = await vjmap.Draw.actionDrawLineSting(map, {
    //pointCount: 2, // 绘制直线,有两个点时，自动结束
    // isClosed: true, // 自动闭合
    api: {
        getSnapFeatures: snapObj //要捕捉的数据项在后面，通过属性features赋值
    },
    updatecoordinate: (e) => {
        // 点坐标实时更新回调
        if (!e.lnglat) return;
        
    },contextMenu: (e) => {
        // 上下文右键菜单回调
    }
});
if (res.cancel) {
    return ;// 取消操作
}
```

如需要设置绘制时的线宽和颜色，可用如下代码
```js
// 获取默认的样式
const opts = vjmap.cloneDeep(vjmap.Draw.defaultOptions());
let styles = opts.styles
// 修改线宽
styles[7]["paint"]["line-width"] = ["case",['has', 'line_width'],['get', 'line_width'], 8]
// 修改颜色
styles[7]["paint"]["line-color"] = "#00ffff"
let line = await vjmap.Draw.actionDrawLineSting(map, {
    styles
});
if (line.cancel) {
    return
}
// 获取绘制的点坐标
let coords = map.fromLngLat(line.features[0].geometry.coordinates).map(pt => pt.toArray())
```
### actionDrawPolygon

绘制一个多边形，返回一个Promise，直到绘制结束，可通过传递回调参数 `updatecoordinate` 得到实时更新的坐标，如果取消，则返回 `cancel`为 `true`, 如
如果要绘制直线，可以设置 `pointCount` 点数为3。（也可以自定义要绘制的点数，当达到这个点数时，自动结束）
```js

let res = await vjmap.Draw.actionDrawPolygon(map, {
  //pointCount: 3, // 绘制三角形,有三个点时，自动结束
    api: {
        getSnapFeatures: snapObj //要捕捉的数据项在后面，通过属性features赋值
    },
    updatecoordinate: (e) => {
      // 点坐标实时更新回调
      if (!e.lnglat) return;
  
    },contextMenu: (e) => {
      // 上下文右键菜单回调
    }
});
if (res.cancel) {
    return ;// 取消操作
}
```

### actionDrawRectangle


绘制一个矩形，返回一个Promise，直到绘制结束，可通过传递回调参数 `updatecoordinate` 得到实时更新的坐标，如果取消，则返回 `cancel`为 `true`, 如

```js

let res = await vjmap.Draw.actionDrawRectangle(map, {
    api: {
        getSnapFeatures: snapObj //要捕捉的数据项在后面，通过属性features赋值
    },
    updatecoordinate: (e) => {
      // 点坐标实时更新回调
      if (!e.lnglat) return;
  
    },contextMenu: (e) => {
      // 上下文右键菜单回调
    }
});
if (res.cancel) {
    return ;// 取消操作
}
```

### actionDrawSlantRectangle


绘制一个斜矩形，返回一个Promise，直到绘制结束，可通过传递回调参数 `updatecoordinate` 得到实时更新的坐标，如果取消，则返回 `cancel`为 `true`, 如

```js

let res = await vjmap.Draw.actionDrawSlantRectangle(map, {
    api: {
        getSnapFeatures: snapObj //要捕捉的数据项在后面，通过属性features赋值
    },
    updatecoordinate: (e) => {
      // 点坐标实时更新回调
      if (!e.lnglat) return;
  
    },contextMenu: (e) => {
      // 上下文右键菜单回调
    }
});
if (res.cancel) {
    return ;// 取消操作
}
```



### actionDrawCircle

绘制一个圆，返回一个Promise，直到绘制结束，可通过传递回调参数 `updatecoordinate` 得到实时更新的坐标，如果取消，则返回 `cancel`为 `true`, 如

```js

let res = await vjmap.Draw.actionDrawCircle(map, {
    api: {
        getSnapFeatures: snapObj //要捕捉的数据项在后面，通过属性features赋值
    },
    updatecoordinate: (e) => {
      // 点坐标实时更新回调
      if (!e.lnglat) return;
  
    },contextMenu: (e) => {
      // 上下文右键菜单回调
    }
});
if (res.cancel) {
    return ;// 取消操作
}
```
### actionSelect

选择实体，返回一个Promise，直到右键选择结束，可通过传递回调参数 `selectSingle` 来决定只选择一个实体就返回。选择结束后返回选择的实体数组, 如

```js
// draw为要选择的DrawTool对象，选择这里面的实体
let selected = await vjmap.Draw.actionSelect(map, draw,
        {
          selectSingle: false // 可以选择多个，直至右键结果；如果true，则选择一个就返回
        }
);
console.log(selected.features) // 返回选中的实体数组
```


在上面的方法绘制过程中，如果需要手动输入坐标，可以给地图map对象，发送`draw.input.click`事件，格式如
```js
map.fire("draw.input.click", {
    lngLat: map.toLngLat([x, 1]), 
    styleId: "当前的样式id" // 可以通过options中写回调函数 statusChange 来获取
})

如
await vjdraw.actionDrawPoint(map, {
  statusChange: e => {
    if (e.isStart) {
        // 开始绘制了，可获取当前的样式id
        let styleId = e.styleId
    } else if (e.isEnd) {
       // 结束绘制了，可获取当前的样式id
       let styleId = e.styleId
    }
  }
})
```

## 默认样式

```js
const opts = vjmap.Draw.defaultOptions();
opts.styles = "新的样式"
```
## 修改默认样式

如修改默认样式，不允许编辑的时候显示线的中点
```js
const opts = vjmap.Draw.defaultOptions()
opts.midpoints = false;
const draw = new vjmap.Draw.Tool(opts);
// 或 map.getDrawLayer(opts);
```
