map.addControl(this.draw, "top-right");
map.on("draw.create", this.createFeature);
map.on("draw.delete", this.delFeature);
map.on("draw.update", this.createFeature);
import DrawRectangle from "./DrawRectangle";
使用在点击事件调用
this.draw.changeMode("draw_rectangle");
MODES
源码:
https://github.com/mapbox/mapbox-gl-draw/blob/main/docs/MODES.md
https://github.com/mapbox/mapbox-gl-draw/blob/main/src/constants.js
DrawRectangle.js
const doubleClickZoom = {
enable: ctx => {
setTimeout(() => {
// First check we've got a map and some context.
!ctx.map ||
!ctx.map.doubleClickZoom ||
!ctx._ctx ||
!ctx._ctx.store ||
!ctx._ctx.store.getInitialConfigValue
return;
// Now check initial state wasn't false (we leave it disabled if so)
if (!ctx._ctx.store.getInitialConfigValue("doubleClickZoom")) return;
ctx.map.doubleClickZoom.enable();
}, 0);
disable(ctx) {
setTimeout(() => {
if (!ctx.map || !ctx.map.doubleClickZoom) return;
// Always disable here, as it's necessary in some cases.
ctx.map.doubleClickZoom.disable();
}, 0);
const DrawRectangle = {
// When the mode starts this function will be called.
onSetup: function (opts) {
const rectangle = this.newFeature({
type: "Feature",
properties: {},
geometry: {
type: "Polygon",
coordinates: [[]]
this.addFeature(rectangle);
this.clearSelectedFeatures();
doubleClickZoom.disable(this);
this.updateUIClasses({ mouse: "add" });
this.setActionableState({
trash: true
return {
rectangle
// support mobile taps
onTap: function (state, e) {
// emulate 'move mouse' to update feature coords
if (state.startPoint) this.onMouseMove(state, e);
// emulate onClick
this.onClick(state, e);
// Whenever a user clicks on the map, Draw will call `onClick`
onClick: function (state, e) {
// if state.startPoint exist, means its second click
//change to simple_select mode
state.startPoint &&
state.startPoint[0] !== e.lngLat.lng &&
state.startPoint[1] !== e.lngLat.lat
this.updateUIClasses({ mouse: "pointer" });
state.endPoint = [e.lngLat.lng, e.lngLat.lat];
this.changeMode("simple_select", { featuresId: state.rectangle.id });
// on first click, save clicked point coords as starting for rectangle
const startPoint = [e.lngLat.lng, e.lngLat.lat];
state.startPoint = startPoint;
onMouseMove: function (state, e) {
// if startPoint, update the feature coordinates, using the bounding box concept
// we are simply using the startingPoint coordinates and the current Mouse Position
// coordinates to calculate the bounding box on the fly, which will be our rectangle
if (state.startPoint) {
state.rectangle.updateCoordinate(
"0.0",
state.startPoint[0],
state.startPoint[1]
); //minX, minY - the starting point
state.rectangle.updateCoordinate(
"0.1",
e.lngLat.lng,
state.startPoint[1]
); // maxX, minY
state.rectangle.updateCoordinate("0.2", e.lngLat.lng, e.lngLat.lat); // maxX, maxY
state.rectangle.updateCoordinate(
"0.3",
state.startPoint[0],
e.lngLat.lat
); // minX,maxY
state.rectangle.updateCoordinate(
"0.4",
state.startPoint[0],
state.startPoint[1]
); //minX,minY - ending point (equals to starting point)
// Whenever a user clicks on a key while focused on the map, it will be sent here
onKeyUp: function (state, e) {
if (e.keyCode === 27) return this.changeMode("simple_select");
onStop: function (state) {
doubleClickZoom.enable(this);
this.updateUIClasses({ mouse: "none" });
this.activateUIButton();
// check to see if we've deleted this feature
if (this.getFeature(state.rectangle.id) === undefined) return;
//remove last added coordinate
state.rectangle.removeCoordinate("0.4");
if (state.rectangle.isValid()) {
this.map.fire("draw.create", {
features: [state.rectangle.toGeoJSON()]
} else {
this.deleteFeature([state.rectangle.id], { silent: true });
this.changeMode("simple_select", {}, { silent: true });
toDisplayFeatures: function (state, geojson, display) {
const isActivePolygon = geojson.properties.id === state.rectangle.id;
geojson.properties.active = isActivePolygon ? "true" : "false";
if (!isActivePolygon) return display(geojson);
// Only render the rectangular polygon if it has the starting point
if (!state.startPoint) return;
return display(geojson);
onTrash: function (state) {
this.deleteFeature([state.rectangle.id], { silent: true });
this.changeMode("simple_select");
export default DrawRectangle;
但是现在的问题是提出来要在点击的第一个位置绘制一个起始点,所以这是修改后的文件
DrawRectangle.js
实现的样式
const doubleClickZoom = {
enable: ctx => {
setTimeout(() => {
// First check we've got a map and some context.
!ctx.map ||
!ctx.map.doubleClickZoom ||
!ctx._ctx ||
!ctx._ctx.store ||
!ctx._ctx.store.getInitialConfigValue
return;
// Now check initial state wasn't false (we leave it disabled if so)
if (!ctx._ctx.store.getInitialConfigValue("doubleClickZoom")) return;
ctx.map.doubleClickZoom.enable();
}, 0);
disable(ctx) {
setTimeout(() => {
if (!ctx.map || !ctx.map.doubleClickZoom) return;
// Always disable here, as it's necessary in some cases.
ctx.map.doubleClickZoom.disable();
}, 0);
const DrawRectangle = {
// When the mode starts this function will be called.
onSetup: function (opts) {
const rectangle = this.newFeature({
type: "Feature",
properties: {},
geometry: {
type: "Polygon",
coordinates: [[]]
this.addFeature(rectangle);
this.clearSelectedFeatures();
doubleClickZoom.disable(this);
this.updateUIClasses({ mouse: "add" });
this.setActionableState({
trash: true
return {
rectangle
// support mobile taps
onTap: function (state, e) {
// emulate 'move mouse' to update feature coords
if (state.startPoint) this.onMouseMove(state, e);
// emulate onClick
this.onClick(state, e);
// Whenever a user clicks on the map, Draw will call `onClick`
onClick: function (state, e) {
// if state.startPoint exist, means its second click
//change to simple_select mode
state.startPoint &&
state.startPoint[0] !== e.lngLat.lng &&
state.startPoint[1] !== e.lngLat.lat
this.updateUIClasses({ mouse: "pointer" });
state.endPoint = [e.lngLat.lng, e.lngLat.lat];
this.changeMode("simple_select", { featuresId: state.rectangle.id });
// on first click, save clicked point coords as starting for rectangle
const startPoint = [e.lngLat.lng, e.lngLat.lat];
state.startPoint = startPoint;
onMouseMove: function (state, e) {
// if startPoint, update the feature coordinates, using the bounding box concept
// we are simply using the startingPoint coordinates and the current Mouse Position
// coordinates to calculate the bounding box on the fly, which will be our rectangle
if (state.startPoint) {
state.rectangle.updateCoordinate(
"0.0",
state.startPoint[0],
state.startPoint[1]
); //minX, minY - the starting point
state.rectangle.updateCoordinate(
"0.1",
e.lngLat.lng,
state.startPoint[1]
); // maxX, minY
state.rectangle.updateCoordinate("0.2", e.lngLat.lng, e.lngLat.lat); // maxX, maxY
state.rectangle.updateCoordinate(
"0.3",
state.startPoint[0],
e.lngLat.lat
); // minX,maxY
state.rectangle.updateCoordinate(
"0.4",
state.startPoint[0],
state.startPoint[1]
); //minX,minY - ending point (equals to starting point)
// Whenever a user clicks on a key while focused on the map, it will be sent here
onKeyUp: function (state, e) {
if (e.keyCode === 27) return this.changeMode("simple_select");
onStop: function (state) {
doubleClickZoom.enable(this);
this.updateUIClasses({ mouse: "none" });
this.activateUIButton();
// check to see if we've deleted this feature
if (this.getFeature(state.rectangle.id) === undefined) return;
//remove last added coordinate
state.rectangle.removeCoordinate("0.4");
if (state.rectangle.isValid()) {
this.map.fire("draw.create", {
features: [state.rectangle.toGeoJSON()]
} else {
this.deleteFeature([state.rectangle.id], { silent: true });
this.changeMode("simple_select", {}, { silent: true });
toDisplayFeatures: function (state, geojson, display) {
const isActivePolygon = geojson.properties.id === state.rectangle.id;
geojson.properties.active = isActivePolygon ? "true" : "false";
if (!isActivePolygon) return display(geojson);
// Only render the rectangular polygon if it has the starting point
if (!state.startPoint) return;
// wxm_new
if (state.startPoint) {
display(this.createVertex(state.rectangle.id, geojson.geometry.coordinates[0][0], `0.0`, false));
// wxm_new
return display(geojson);
onTrash: function (state) {
this.deleteFeature([state.rectangle.id], { silent: true });
this.changeMode("simple_select");
// wxm_new
createVertex: function (parentId, coordinates, path, selected) {
return {
type: "Feature",
properties: {
meta: 'vertex',
parent: parentId,
coord_path: path,
active: (selected) ? 'true' : "false"
geometry: {
type: 'Point',
coordinates
export default DrawRectangle;
添加draw组件 let modes = MapboxDraw.modes; modes.draw_rectangle = DrawRectangle; //添加工具 this.draw = new MapboxDraw({ modes: modes, displayControlsDefault: false, }); map.addControl(this.draw, "top-right")..
增加了对地图上的绘图和编辑功能的支持。
需要 。 兼容版本记录在package.json中
在NPM上,此软件包最近已从
mapbox-gl-draw
移至@mapbox/
mapbox-gl-draw
npm install @mapbox/
mapbox-gl-draw
Draw随CSS一起提供,请确保将其包含在构建中。
Typescript定义文件可作为包的一部分提供。
npm install @types/mapbox__
mapbox-gl-draw
使用模块时
import '@mapbox/
mapbox-gl-draw
/dist/
mapbox-gl-draw
.css'
使用CDN时
< link rel =' stylesheet ' href =' https://api.mapbox.com/mapbox
mapbox自定义
绘制
工具如何使用mapbox
绘制
常用的工具需要引入的资源创建div引入mapbox实例设置circle工具创建 point
绘制
工具创建line
绘制
工具创建polygon(多边形)
绘制
工具创建 rectangle(
矩形
)
绘制
工具清除图层(layer)和资源(source)
如何使用mapbox
绘制
常用的工具
每次在网上查资源,尼玛脑袋疼,好多大神写的啥玩意呀。我们知道,操作地图不外乎就是一些事件,其实mapbox有一些关于
绘制
工具的一些插件,也可以自己定义
绘制
工具。
我这里的demo,就是
一、在index.html全局引入mapbox-gl的js和css包,由于项目中会涉及到部分空间几何对象关系的计算,需借助turf.js,详细使用方法可参考https://blog.csdn.net/weixin_39150852/article/details/116758542
二、创建地图组件,初始化地图
<template>
<div class="map-wrapper" :id="mapId"></div>
</template>
mapbox-gl-draw
API ReferenceTo use DrawOptionsModes
最近工作有一项需求就是在web上进行数据点采集,生成一个geojson的数据。其他框架没细看,之前用过mapbox,就继续用mapbox来实现,参考了mapbox例子之后,发现draw是没什么问题,mapbox主页单独有个这个例子
show draw polygon area,但是问题在我想取d...