import MapboxControl from '@mapbox/mapbox-gl-draw';
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
// import distance from '@turf/distance';
// import circle from '@turf/circle';
// import {point} from '@turf/helpers';
import baseUtil from '../../util/baseUtil';
const turf = require('../../tools/turf');
/**
*@地图绘制控件及绘制方法类
*@author lc
*@date 2018-04-09 16:14:16
*/
class DrawControl {
constructor(map, callback) {
this.callback = callback; //回调
this._map = map; //地图
this.circleID = `unique-drawCircleID-${baseUtil.guid()}`;
this.boxID = `unique-drawBoxID-${baseUtil.guid()}`;
this.mode = MapboxControl.modes;
this.defaultOptions = {
modes: this.mode,
touchEnabled: true,
keybindings: true,
displayControlsDefault: false,
styles: [{
'id': 'gl-draw-polygon-fill-inactive.cold',
'type': 'fill',
'filter': ['all', ['==', 'active', 'false'], ['==', '$type', 'Polygon'], ['!=', 'mode', 'static']],
'paint': {'fill-color': '#3bb2d0', 'fill-outline-color': '#3bb2d0', 'fill-opacity': 0.1},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-polygon-fill-active.cold',
'type': 'fill',
'filter': ['all', ['==', 'active', 'true'], ['==', '$type', 'Polygon']],
'paint': {'fill-color': '#3bb2d0', 'fill-outline-color': '#3bb2d0', 'fill-opacity': 0.1},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-polygon-midpoint.cold',
'type': 'circle',
'filter': ['all', ['==', '$type', 'Point'], ['==', 'meta', 'midpoint']],
'paint': {'circle-radius': 3, 'circle-color': '#3bb2d0'},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-polygon-stroke-inactive.cold',
'type': 'line',
'filter': ['all', ['==', 'active', 'false'], ['==', '$type', 'Polygon'], ['!=', 'mode', 'static']],
'layout': {'line-cap': 'round', 'line-join': 'round'},
'paint': {'line-color': '#3bb2d0', 'line-width': 2},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-polygon-stroke-active.cold',
'type': 'line',
'filter': ['all', ['==', 'active', 'true'], ['==', '$type', 'Polygon']],
'layout': {'line-cap': 'round', 'line-join': 'round'},
'paint': {'line-color': '#3bb2d0', 'line-width': 2},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-line-inactive.cold',
'type': 'line',
'filter': ['all', ['==', 'active', 'false'], ['==', '$type', 'LineString'], ['!=', 'mode', 'static']],
'layout': {'line-cap': 'round', 'line-join': 'round'},
'paint': {'line-color': '#3bb2d0', 'line-width': 2},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-line-active.cold',
'type': 'line',
'filter': ['all', ['==', '$type', 'LineString'], ['==', 'active', 'true']],
'layout': {'line-cap': 'round', 'line-join': 'round'},
'paint': {'line-color': '#3bb2d0', 'line-width': 2},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-polygon-and-line-vertex-stroke-inactive.cold',
'type': 'circle',
'filter': ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point'], ['!=', 'mode', 'static']],
'paint': {'circle-radius': 5, 'circle-color': '#ff431e'},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-polygon-and-line-vertex-inactive.cold',
'type': 'circle',
'filter': ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point'], ['!=', 'mode', 'static']],
'paint': {'circle-radius': 3, 'circle-color': '#f2f2f2'},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-point-point-stroke-inactive.cold',
'type': 'circle',
'filter': ['all', ['==', 'active', 'false'], ['==', '$type', 'Point'], ['==', 'meta', 'feature'], ['!=', 'mode', 'static']],
'paint': {'circle-radius': 5, 'circle-opacity': 1, 'circle-color': '#fff'},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-point-inactive.cold',
'type': 'circle',
'filter': ['all', ['==', 'active', 'false'], ['==', '$type', 'Point'], ['==', 'meta', 'feature'], ['!=', 'mode', 'static']],
'paint': {'circle-radius': 3, 'circle-color': '#3bb2d0'},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-point-stroke-active.cold',
'type': 'circle',
'filter': ['all', ['==', '$type', 'Point'], ['==', 'active', 'true'], ['!=', 'meta', 'midpoint']],
'paint': {'circle-radius': 7, 'circle-color': '#fff'},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-point-active.cold',
'type': 'circle',
'filter': ['all', ['==', '$type', 'Point'], ['!=', 'meta', 'midpoint'], ['==', 'active', 'true']],
'paint': {'circle-radius': 5, 'circle-color': '#3bb2d0'},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-polygon-fill-static.cold',
'type': 'fill',
'filter': ['all', ['==', 'mode', 'static'], ['==', '$type', 'Polygon']],
'paint': {'fill-color': '#404040', 'fill-outline-color': '#404040', 'fill-opacity': 0.1},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-polygon-stroke-static.cold',
'type': 'line',
'filter': ['all', ['==', 'mode', 'static'], ['==', '$type', 'Polygon']],
'layout': {'line-cap': 'round', 'line-join': 'round'},
'paint': {'line-color': '#404040', 'line-width': 2},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-line-static.cold',
'type': 'line',
'filter': ['all', ['==', 'mode', 'static'], ['==', '$type', 'LineString']],
'layout': {'line-cap': 'round', 'line-join': 'round'},
'paint': {'line-color': '#404040', 'line-width': 2},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-point-static.cold',
'type': 'circle',
'filter': ['all', ['==', 'mode', 'static'], ['==', '$type', 'Point']],
'paint': {'circle-radius': 5, 'circle-color': '#404040'},
'source': 'mapbox-gl-draw-cold'
}, {
'id': 'gl-draw-polygon-fill-inactive.hot',
'type': 'fill',
'filter': ['all', ['==', 'active', 'false'], ['==', '$type', 'Polygon'], ['!=', 'mode', 'static']],
'paint': {'fill-color': '#3bb2d0', 'fill-outline-color': '#3bb2d0', 'fill-opacity': 0.1},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-polygon-fill-active.hot',
'type': 'fill',
'filter': ['all', ['==', 'active', 'true'], ['==', '$type', 'Polygon']],
'paint': {'fill-color': '#3bb2d0', 'fill-outline-color': '#3bb2d0', 'fill-opacity': 0.1},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-polygon-midpoint.hot',
'type': 'circle',
'filter': ['all', ['==', '$type', 'Point'], ['==', 'meta', 'midpoint']],
'paint': {'circle-radius': 3, 'circle-color': '#3bb2d0'},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-polygon-stroke-inactive.hot',
'type': 'line',
'filter': ['all', ['==', 'active', 'false'], ['==', '$type', 'Polygon'], ['!=', 'mode', 'static']],
'layout': {'line-cap': 'round', 'line-join': 'round'},
'paint': {'line-color': '#3bb2d0', 'line-width': 2},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-polygon-stroke-active.hot',
'type': 'line',
'filter': ['all', ['==', 'active', 'true'], ['==', '$type', 'Polygon']],
'layout': {'line-cap': 'round', 'line-join': 'round'},
'paint': {'line-color': '#3bb2d0', 'line-width': 2},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-line-inactive.hot',
'type': 'line',
'filter': ['all', ['==', 'active', 'false'], ['==', '$type', 'LineString'], ['!=', 'mode', 'static']],
'layout': {'line-cap': 'round', 'line-join': 'round'},
'paint': {'line-color': '#3bb2d0', 'line-width': 2},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-line-active.hot',
'type': 'line',
'filter': ['all', ['==', '$type', 'LineString'], ['==', 'active', 'true']],
'layout': {'line-cap': 'round', 'line-join': 'round'},
'paint': {'line-color': '#3bb2d0', 'line-width': 2},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-polygon-and-line-vertex-stroke-inactive.hot',
'type': 'circle',
'filter': ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point'], ['!=', 'mode', 'static']],
'paint': {'circle-radius': 5, 'circle-color': '#fff'},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-polygon-and-line-vertex-inactive.hot',
'type': 'circle',
'filter': ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point'], ['!=', 'mode', 'static']],
'paint': {'circle-radius': 3, 'circle-color': '#3bb2d0'},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-point-point-stroke-inactive.hot',
'type': 'circle',
'filter': ['all', ['==', 'active', 'false'], ['==', '$type', 'Point'], ['==', 'meta', 'feature'], ['!=', 'mode', 'static']],
'paint': {'circle-radius': 5, 'circle-opacity': 1, 'circle-color': '#fff'},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-point-inactive.hot',
'type': 'circle',
'filter': ['all', ['==', 'active', 'false'], ['==', '$type', 'Point'], ['==', 'meta', 'feature'], ['!=', 'mode', 'static']],
'paint': {'circle-radius': 3, 'circle-color': '#3bb2d0'},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-point-stroke-active.hot',
'type': 'circle',
'filter': ['all', ['==', '$type', 'Point'], ['==', 'active', 'true'], ['!=', 'meta', 'midpoint']],
'paint': {'circle-radius': 7, 'circle-color': '#fff'},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-point-active.hot',
'type': 'circle',
'filter': ['all', ['==', '$type', 'Point'], ['!=', 'meta', 'midpoint'], ['==', 'active', 'true']],
'paint': {'circle-radius': 5, 'circle-color': '#3bb2d0'},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-polygon-fill-static.hot',
'type': 'fill',
'filter': ['all', ['==', 'mode', 'static'], ['==', '$type', 'Polygon']],
'paint': {'fill-color': '#404040', 'fill-outline-color': '#404040', 'fill-opacity': 0.1},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-polygon-stroke-static.hot',
'type': 'line',
'filter': ['all', ['==', 'mode', 'static'], ['==', '$type', 'Polygon']],
'layout': {'line-cap': 'round', 'line-join': 'round'},
'paint': {'line-color': '#404040', 'line-width': 2},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-line-static.hot',
'type': 'line',
'filter': ['all', ['==', 'mode', 'static'], ['==', '$type', 'LineString']],
'layout': {'line-cap': 'round', 'line-join': 'round'},
'paint': {'line-color': '#404040', 'line-width': 2},
'source': 'mapbox-gl-draw-hot'
}, {
'id': 'gl-draw-point-static.hot',
'type': 'circle',
'filter': ['all', ['==', 'mode', 'static'], ['==', '$type', 'Point']],
'paint': {'circle-radius': 5, 'circle-color': '#404040'},
'source': 'mapbox-gl-draw-hot'
}]
};//默认绘制控件选项
this.Draw = new MapboxControl(this.defaultOptions); //原生绘制控件对象
this._map.addControl(this.Draw);
const geometryCallback = e => {
this.geometrys = {
coordinates: e.features[0].geometry.coordinates //返回绘制图形的几何信息
};
if (this.callback) {
this.callback(this.geometrys);
}
};
this._map.on('draw.create', e => { //对原生绘制控件添加绘制完毕的监听
geometryCallback(e);
});
this._map.on('draw.update', e => { //对原生绘制控件添加绘制更新的监听
geometryCallback(e);
});
}
onAdd() {
//控件模式
this._map.removeControl(this.Draw);
this.defaultOptions.controls = {
'point': 'on',
'line_string': 'on',
'trash': 'on',
'polygon': 'on'
};
this.Draw = new MapboxControl(this.defaultOptions);
this._map.addControl(this.Draw);
//获取原生控件容器
this._container = document.getElementsByClassName('mapbox-gl-draw_ctrl-draw-btn mapbox-gl-draw_trash')[0].parentNode;
//拓展原生控件容器
let drawCircleButton = document.createElement('button'); //添加绘圆按钮
drawCircleButton.className = 'mapbox-gl-draw-extent_circle';
drawCircleButton.onclick = this.drawCircle.bind(this); //绑定点击事件
this._container.appendChild(drawCircleButton);
let drawBoxButton = document.createElement('button'); //添加绘矩形按钮
drawBoxButton.className = 'mapbox-gl-draw-extent_box';
drawBoxButton.onclick = this.drawBox.bind(this); //绑定点击事件
this._container.appendChild(drawBoxButton);
return this._container;
}
onRemove() {
this._container.parentNode.removeChild(this._container);
this._map = undefined;
}
/**
*@绘制圆
*@author lc
*@date 2018-04-09 16:25:42
*/
drawCircle() {
this.drawSpecialGeometry('circle', this.callback);
}
/**
*@绘制矩形
*@author lc
*@date 2018-04-09 16:25:52
*/
drawBox() {
this.drawSpecialGeometry('box', this.callback);
}
/**
* 监听鼠标事件生成坐标点
* @param type('circle','box')
* @param callback
*/
drawSpecialGeometry(type, callback) {
this._map.getCanvas().style.cursor = 'crosshair';
let drawActive = true;
let mouseDown = down => { //鼠标单击事件
let startPoint = down.lngLat;
let mouseMove = move => { //鼠标移动
mouseDown = () => { //重新设置鼠标单击事件
this._map.off('mousemove', mouseMove); //取消鼠标移动事件
mouseMove = null;
this._map.getCanvas().style.cursor = '';
this._map.off('mousedown', mouseDown); //取消鼠标单击事件
mouseDown = null;
if (drawActive) { //结束绘制,执行回调
if (callback) {
callback(this.geometrys);
}
drawActive = false;
}
};
this._map.on('mousedown', mouseDown);
let movePoint = move.lngLat;
switch (type) {
case 'circle':
this.generateCircleGeometry(startPoint, movePoint);
break;
case 'box':
this.generateBoxGeometry(startPoint, movePoint);
break;
}
};
this._map.off('mousedown', mouseDown);
mouseDown = null;
this._map.on('mousemove', mouseMove);
};
this._map.on('mousedown', mouseDown);
}
/**
* 绘制圆
* @param startPoint(起点)
* @param movePoint(移动点)
*/
generateCircleGeometry(startPoint, movePoint) {
let from = turf.point([startPoint.lng, startPoint.lat]);
let to = turf.point([movePoint.lng, movePoint.lat]);
let options = {units: 'kilometers'};
let circleOptions = {steps: 10, units: 'kilometers', properties: {foo: 'bar'}};
let radius = turf.distance(from, to, circleOptions);
radius = radius === 0 ? 0.00000001 : radius;
let circleGeometry = turf.circle([startPoint.lng, startPoint.lat], radius, options);//根据中心点和半径获取圆的坐标串
let coordinates = circleGeometry.geometry.coordinates;
let feature = {
id: this.circleID,
type: 'Feature',
properties: {},
geometry: {
type: 'Polygon', coordinates: coordinates
}
};
this.Draw.add(feature); //通过绘制控件直接添加圆
this.geometrys = { //保存圆的几何信息
coordinates: coordinates,
center: [startPoint.lng, startPoint.lat],
radius: radius * 1000
};
}
/**
* 绘制矩形
* @param startPoint(起点)
* @param movePoint(移动点)
*/
generateBoxGeometry(startPoint, movePoint) {
let coordinates = [[[startPoint.lng, startPoint.lat],
[startPoint.lng, movePoint.lat],
[movePoint.lng, movePoint.lat],
[movePoint.lng, startPoint.lat],
[startPoint.lng, startPoint.lat]]]; //矩形的坐标串
let feature = {
id: this.boxID,
type: 'Feature',
properties: {},
geometry: {
type: 'Polygon', coordinates: coordinates
}
};
this.Draw.add(feature); //通过绘制控件直接添加矩形
this.geometrys = {
coordinates: coordinates
};
}
/**
* 开始绘制几何图形
* @param type ('line':绘制线段,'polygon':绘制多边形,'point':绘制点,'circle':绘制圆,'box':绘制矩形框)
* @param callback(绘制完毕后的回调,返回几何图形的信息)
*/
drawGeometry(type) {
// this.Draw = new MapboxControl(this.defaultOptions);
// this.callback = callback;
// this.Draw.deleteAll();
switch (type) {
case 'line':
this.Draw.changeMode('draw_line_string');
break;
case 'polygon':
this.Draw.changeMode('draw_polygon');
break;
case 'point':
this.Draw.changeMode('draw_point');
break;
default:
this.drawSpecialGeometry(type, this.callback);
break;
}
return this.Draw;
}
getGeometrys() {
return this.geometrys;
}
deleteAll() {
this.Draw.deleteAll();
}
}
export default DrawControl;