- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined'
- ? (module.exports = factory())
- : typeof define === 'function' && define.amd
- ? define(factory)
- : ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
- (global.mapboxgl1.MeatureTool = factory(global.mapboxgl1)));
- })(window, function (mapboxgl) {
- const css = `
- /* Override default control style */
- .mapbox-gl-draw_ctrl-bottom-left,
- .mapbox-gl-draw_ctrl-top-left {
- margin-left:0;
- border-radius:0 4px 4px 0;
- }
- .mapbox-gl-draw_ctrl-top-right,
- .mapbox-gl-draw_ctrl-bottom-right {
- margin-right:0;
- border-radius:4px 0 0 4px;
- }
-
- .mapbox-gl-draw_ctrl-draw-btn {
- border-color:rgba(0,0,0,0.9);
- color:rgba(255,255,255,0.5);
- width:30px;
- height:30px;
- }
-
- .mapbox-gl-draw_ctrl-draw-btn.active,
- .mapbox-gl-draw_ctrl-draw-btn.active:hover {
- background-color:rgb(0 0 0/5%);
- }
- .mapbox-gl-draw_ctrl-draw-btn {
- background-repeat: no-repeat;
- background-position: center;
- }
-
- .mapbox-gl-draw_point {
- background-image: url('data:image/svg+xml;utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="20" height="20">%3Cpath d="m10 2c-3.3 0-6 2.7-6 6s6 9 6 9 6-5.7 6-9-2.7-6-6-6zm0 2c2.1 0 3.8 1.7 3.8 3.8 0 1.5-1.8 3.9-2.9 5.2h-1.7c-1.1-1.4-2.9-3.8-2.9-5.2-.1-2.1 1.6-3.8 3.7-3.8z"/>%3C/svg>');
- }
- .mapbox-gl-draw_polygon {
- background-image: url('data:image/svg+xml;utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="20" height="20">%3Cpath d="m15 12.3v-4.6c.6-.3 1-1 1-1.7 0-1.1-.9-2-2-2-.7 0-1.4.4-1.7 1h-4.6c-.3-.6-1-1-1.7-1-1.1 0-2 .9-2 2 0 .7.4 1.4 1 1.7v4.6c-.6.3-1 1-1 1.7 0 1.1.9 2 2 2 .7 0 1.4-.4 1.7-1h4.6c.3.6 1 1 1.7 1 1.1 0 2-.9 2-2 0-.7-.4-1.4-1-1.7zm-8-.3v-4l1-1h4l1 1v4l-1 1h-4z"/>%3C/svg>');
- }
- .mapbox-gl-draw_line {
- background-image: url('data:image/svg+xml;utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="20" height="20">%3Cpath d="m13.5 3.5c-1.4 0-2.5 1.1-2.5 2.5 0 .3 0 .6.2.9l-3.8 3.8c-.3-.1-.6-.2-.9-.2-1.4 0-2.5 1.1-2.5 2.5s1.1 2.5 2.5 2.5 2.5-1.1 2.5-2.5c0-.3 0-.6-.2-.9l3.8-3.8c.3.1.6.2.9.2 1.4 0 2.5-1.1 2.5-2.5s-1.1-2.5-2.5-2.5z"/>%3C/svg>');
- }
- .mapbox-gl-draw_trash {
- background-image: url('data:image/svg+xml;utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="20" height="20">%3Cpath d="M10,3.4 c-0.8,0-1.5,0.5-1.8,1.2H5l-1,1v1h12v-1l-1-1h-3.2C11.5,3.9,10.8,3.4,10,3.4z M5,8v7c0,1,1,2,2,2h6c1,0,2-1,2-2V8h-2v5.5h-1.5V8h-3 v5.5H7V8H5z"/>%3C/svg>');
- }
- .mapbox-gl-draw_uncombine {
- background-image: url('data:image/svg+xml;utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="20" height="20">%3Cpath d="m12 2c-.3 0-.5.1-.7.3l-1 1c-.4.4-.4 1 0 1.4l1 1c.4.4 1 .4 1.4 0l1-1c.4-.4.4-1 0-1.4l-1-1c-.2-.2-.4-.3-.7-.3zm4 4c-.3 0-.5.1-.7.3l-1 1c-.4.4-.4 1 0 1.4l1 1c.4.4 1 .4 1.4 0l1-1c.4-.4.4-1 0-1.4l-1-1c-.2-.2-.4-.3-.7-.3zm-7 1c-1 0-1 1-.5 1.5.3.3 1 1 1 1l-1 1s-.5.5 0 1 1 0 1 0l1-1 1 1c.5.5 1.5.5 1.5-.5v-4zm-5 3c-.3 0-.5.1-.7.3l-1 1c-.4.4-.4 1 0 1.4l4.9 4.9c.4.4 1 .4 1.4 0l1-1c.4-.4.4-1 0-1.4l-4.9-4.9c-.1-.2-.4-.3-.7-.3z"/>%3C/svg>');
- }
- .mapbox-gl-draw_combine {
- background-image: url('data:image/svg+xml;utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" width="20" height="20">%3Cpath d="M12.1,2c-0.3,0-0.5,0.1-0.7,0.3l-1,1c-0.4,0.4-0.4,1,0,1.4l4.9,4.9c0.4,0.4,1,0.4,1.4,0l1-1 c0.4-0.4,0.4-1,0-1.4l-4.9-4.9C12.6,2.1,12.3,2,12.1,2z M8,8C7,8,7,9,7.5,9.5c0.3,0.3,1,1,1,1l-1,1c0,0-0.5,0.5,0,1s1,0,1,0l1-1l1,1 C11,13,12,13,12,12V8H8z M4,10c-0.3,0-0.5,0.1-0.7,0.3l-1,1c-0.4,0.4-0.4,1,0,1.4l1,1c0.4,0.4,1,0.4,1.4,0l1-1c0.4-0.4,0.4-1,0-1.4 l-1-1C4.5,10.1,4.3,10,4,10z M8,14c-0.3,0-0.5,0.1-0.7,0.3l-1,1c-0.4,0.4-0.4,1,0,1.4l1,1c0.4,0.4,1,0.4,1.4,0l1-1 c0.4-0.4,0.4-1,0-1.4l-1-1C8.5,14.1,8.3,14,8,14z"/>%3C/svg>');
- }
-
- .mapboxgl-map.mouse-pointer .mapboxgl-canvas-container.mapboxgl-interactive {
- cursor: pointer;
- }
- .mapboxgl-map.mouse-move .mapboxgl-canvas-container.mapboxgl-interactive {
- cursor: move;
- }
- .mapboxgl-map.mouse-add .mapboxgl-canvas-container.mapboxgl-interactive {
- cursor: crosshair;
- }
- .mapboxgl-map.mouse-move.mode-direct_select .mapboxgl-canvas-container.mapboxgl-interactive {
- cursor: grab;
- cursor: -moz-grab;
- cursor: -webkit-grab;
- }
- .mapboxgl-map.mode-direct_select.feature-vertex.mouse-move .mapboxgl-canvas-container.mapboxgl-interactive {
- cursor: move;
- }
- .mapboxgl-map.mode-direct_select.feature-midpoint.mouse-pointer .mapboxgl-canvas-container.mapboxgl-interactive {
- cursor: cell;
- }
- .mapboxgl-map.mode-direct_select.feature-feature.mouse-move .mapboxgl-canvas-container.mapboxgl-interactive {
- cursor: move;
- }
- .mapboxgl-map.mode-static.mouse-pointer .mapboxgl-canvas-container.mapboxgl-interactive {
- cursor: grab;
- cursor: -moz-grab;
- cursor: -webkit-grab;
- }
-
- .mapbox-gl-draw_boxselect {
- pointer-events: none;
- position: absolute;
- top: 0;
- left: 0;
- width: 0;
- height: 0;
- background: rgba(0,0,0,.1);
- border: 2px dotted #fff;
- opacity: 0.5;
- }
- .measure-move {
- border-radius: 3px;
- height: 16px;
- line-height: 16px;
- padding: 0 3px;
- font-size: 12px;
- box-shadow: 0 0 0 1px #ccc;
- float: right;
- cursor: default;
- }
-
- .measure-result {
- border-radius: 3px;
- height: 16px;
- line-height: 16px;
- padding: 0 3px;
- font-size: 12px;
- box-shadow: 0 0 0 1px #ccc;
- float: right;
- cursor: default;
- z-index: 10;
- }
-
- .close {
- width: 3px;
- height: 14px;
- text-align: center;
- border-radius: 3px;
- padding-top: 0px;
- padding-right: 10px;
- box-shadow: 0 0 0 0px #ccc;
- cursor: pointer;
- background: url(../measureicon/close.png) no-repeat center;
- border: 1px solid rgba(100, 100, 100, 0)
- }
-
- .clear {
- width: 3px;
- height: 14px;
- text-align: center;
- border-radius: 3px;
- padding-right: 10px;
- box-shadow: 0 0 0 0px #ccc;
- cursor: pointer;
- float: right;
- background: url(../measureicon/delete.png) no-repeat center;
- border: 1px solid rgba(100, 100, 100, 0)
- }
-
- .edit {
- width: 3px;
- height: 14px;
- text-align: center;
- border-radius: 3px;
- padding-right: 10px;
- box-shadow: 0 0 0 0px #ccc;
- cursor: pointer;
- float: right;
- background: url(../measureicon/edit.png) no-repeat center;
- border: 1px solid rgba(100, 100, 100, 0)
- }
-
- .close:hover {
- border: 1px solid rgba(52, 98, 152, 1);
- }
-
- .clear:hover {
- border: 1px solid rgba(52, 98, 152, 1);
- }
-
- .edit:hover {
- border: 1px solid rgba(52, 98, 152, 1);
- }
- `;
- document.write(`<style type='text/css'>${css}</style>`);
-
- return class {
- constructor(map) {
- this.map = map;
- }
-
- layerDistanceList = [];
- layerAreaList = [];
- layerPointList = [];
- setDistance = () => {};
- setArea = () => {};
-
- /**
- * 测量距离
- * @param {*} layerId
- */
- measureDistance(layerId, isP = true, callback = () => {}) {
- this.layerDistanceList.push(layerId);
- var isMeasure = true;
- const map = this.map;
- map.doubleClickZoom.disable();
- let catchMark = null;
- let isEdit = false;
- let Geolist = [];
- let dragPointOrder = 0;
- let pointOnLine = [0, 0];
-
- const jsonPoint = {
- type: 'FeatureCollection',
- features: [],
- };
- const jsonLine = {
- type: 'FeatureCollection',
- features: [],
- };
-
- // 添加测量结果弹窗
- const ele = document.createElement('div');
- ele.setAttribute('class', 'measure-move');
- const option = {
- element: ele,
- anchor: 'left',
- offset: [8, 0],
- };
- const tooltip = new mapboxgl.Marker(option).setLngLat([0, 0]);
- if (isP) tooltip.addTo(map);
-
- // 添加测量图层
- map.addSource('points' + layerId, {
- type: 'geojson',
- data: jsonPoint,
- });
- map.addSource('point-move' + layerId, {
- type: 'geojson',
- data: jsonPoint,
- });
- map.addSource('line' + layerId, {
- type: 'geojson',
- data: jsonLine,
- });
- map.addSource('line-move' + layerId, {
- type: 'geojson',
- data: jsonLine,
- });
- map.addSource('point-follow' + layerId, {
- type: 'geojson',
- data: jsonPoint,
- });
- map.addLayer({
- id: 'line' + layerId,
- type: 'line',
- source: 'line' + layerId,
- paint: {
- 'line-color': '#ff0000',
- 'line-width': 2,
- 'line-opacity': 0.65,
- },
- });
- map.addLayer({
- id: 'line-move' + layerId,
- type: 'line',
- source: 'line-move' + layerId,
- paint: {
- 'line-color': '#ff0000',
- 'line-width': 2,
- 'line-opacity': 0.65,
- 'line-dasharray': [5, 2],
- },
- });
- map.addLayer({
- id: 'points' + layerId,
- type: 'circle',
- source: 'points' + layerId,
- paint: {
- 'circle-color': '#ffffff',
- 'circle-radius': 3.5,
- 'circle-stroke-width': 1.5,
- 'circle-stroke-color': '#ff0000',
- },
- });
- map.addLayer({
- id: 'point-move' + layerId,
- type: 'circle',
- source: 'point-move' + layerId,
- paint: {
- 'circle-color': '#ffffff',
- 'circle-radius': 3.5,
- 'circle-stroke-width': 1.5,
- 'circle-stroke-color': '#ff0000',
- },
- });
- // 活动点可以选择用图层,也可以选择用Mark
- map.addLayer({
- id: 'point-follow' + layerId,
- type: 'circle',
- source: 'point-follow' + layerId,
- paint: {
- 'circle-color': '#199afc',
- 'circle-radius': 5.5,
- 'circle-stroke-width': 1.5,
- 'circle-stroke-color': '#ffffff',
- },
- });
-
- // 清除面积测量
- this.setArea = () => {
- isMeasure = false;
- if (map.getLayer('point-move' + layerId)) map.removeLayer('point-move' + layerId);
- if (map.getLayer('line-move' + layerId)) map.removeLayer('line-move' + layerId);
-
- return isMeasure;
- };
-
- /**
- * 添加点
- * @param {*} _e
- */
- function addPointforJSON(_e) {
- if (isMeasure) {
- const point = {
- type: 'Feature',
- geometry: {
- type: 'Point',
- coordinates: [_e.lngLat.lng, _e.lngLat.lat],
- },
- properties: {
- id: String(new Date().getTime()),
- },
- };
- jsonPoint.features.push(point);
- map.getSource('points' + layerId).setData(jsonPoint);
- drawLine(jsonPoint);
- addMeasureRes(jsonPoint);
- }
- }
-
- /**
- * 绘制线
- * @param {*} jsonPoint
- */
- function drawLine(jsonPoint) {
- if (jsonPoint.features.length > 1) {
- jsonLine.features = [];
- for (let i = 0; i < jsonPoint.features.length - 1; i++) {
- const coords = jsonPoint.features[i].geometry.coordinates;
- const next_coords = jsonPoint.features[i + 1].geometry.coordinates;
- jsonLine.features.push({
- type: 'Feature',
- geometry: {
- type: 'LineString',
- coordinates: [coords, next_coords],
- },
- });
- }
- map.getSource('line' + layerId).setData(jsonLine);
- }
- }
-
- /**
- * 添加dom
- * @param {*} jsonPoint 点集
- */
- function addMeasureRes(jsonPoint) {
- if (isP && jsonPoint.features.length > 0) {
- removedom();
- const pointList = [];
- for (let i = 0; i < jsonPoint.features.length; i++) {
- const coords = jsonPoint.features[i].geometry.coordinates;
- pointList.push(coords);
-
- const close = document.createElement('div');
- close.setAttribute('class', `measure-result ${layerId} close`);
- close.onclick = __e => {
- // 移除点
- __e.stopPropagation();
- removePoint(coords);
- map.off('mousemove', onMouseMove);
- map.off('mousedown', onmousedown);
- if (catchMark) {
- catchMark.remove();
- }
- };
-
- const clear = document.createElement('div');
- clear.setAttribute('class', `measure-result ${layerId} clear`);
- clear.onclick = __e => {
- // 全部删除
- __e.stopPropagation();
- removeLayer();
- map.off('mousemove', onMouseMove);
- map.off('mousedown', onmousedown);
- if (catchMark) {
- catchMark.remove();
- }
- };
-
- const edit = document.createElement('div');
- edit.setAttribute('class', `measure-result ${layerId} edit`);
- edit.onclick = __e => {
- // 编辑线
- __e.stopPropagation();
- map.off('mousemove', onMouseMove);
- map.off('mousedown', onmousedown);
- if (catchMark) {
- catchMark.remove();
- }
- editLine();
- };
-
- const element = document.createElement('div');
- element.setAttribute('class', 'measure-result ' + layerId);
- const option = {
- element: element,
- anchor: 'left',
- offset: [8, 0],
- };
- element.innerHTML = i === 0 ? '起点' : getLength(pointList);
- if ((jsonPoint.features.length === i + 1) & !isMeasure) {
- element.appendChild(edit);
- element.appendChild(clear);
- }
- element.appendChild(close);
- new mapboxgl.Marker(option).setLngLat(coords).addTo(map);
- }
- }
- }
-
- /**
- * 移除点
- * @param {*} coords 点坐标
- */
- function removePoint(coords) {
- if (jsonPoint.features.length > 0) {
- if (jsonPoint.features.length === 2) {
- jsonPoint.features = [];
- jsonLine.features = [];
- map.getSource('points' + layerId).setData(jsonPoint);
- map.getSource('line' + layerId).setData(jsonLine);
- removedom();
- } else {
- for (let i = 0; i < jsonPoint.features.length; i++) {
- if (
- (jsonPoint.features[i].geometry.coordinates[0] === coords[0]) &
- (jsonPoint.features[i].geometry.coordinates[1] === coords[1])
- ) {
- jsonPoint.features.splice(i, 1);
- }
- }
- drawLine(jsonPoint);
- addMeasureRes(jsonPoint);
- map.getSource('points' + layerId).setData(jsonPoint);
- }
- }
- }
-
- /**
- * 计算长度
- * @param {*} pointList
- * @returns
- */
- function getLength(pointList) {
- const line = turf.lineString(pointList);
- let len = turf.length(line);
- if (len < 1) {
- len = Math.round(len * 1000) + '米';
- } else {
- len = len.toFixed(2) + '公里';
- }
- return len;
- }
-
- /**
- * 移除dom
- */
- function removedom() {
- const dom = document.getElementsByClassName('measure-result ' + layerId);
- const len = dom.length;
- if (len) {
- for (let i = len - 1; i >= 0; i--) {
- if (dom[i]) dom[i].remove();
- }
- }
- }
-
- /**
- * 移除图层
- */
- function removeLayer() {
- jsonPoint.features = [];
- jsonLine.features = [];
- if (map.getLayer('points' + layerId)) map.removeLayer('points' + layerId);
- if (map.getLayer('line' + layerId)) map.removeLayer('line' + layerId);
- removedom();
- }
-
- /**
- * 鼠标move事件
- * @param {} _e
- */
- function mouseMove(_e) {
- if (isMeasure) {
- map.getCanvas().style.cursor = 'default';
- var coords = [_e.lngLat.lng, _e.lngLat.lat];
- const jsonp = {
- type: 'Feature',
- geometry: {
- type: 'Point',
- coordinates: coords,
- },
- };
- map.getSource('point-move' + layerId).setData(jsonp);
-
- if (jsonPoint.features.length > 0) {
- const pointList = [];
- for (let i = 0; i < jsonPoint.features.length; i++) {
- const coord = jsonPoint.features[i].geometry.coordinates;
- pointList.push(coord);
- }
- pointList.push(coords);
- const prev = jsonPoint.features[jsonPoint.features.length - 1];
- const jsonl = {
- type: 'Feature',
- geometry: {
- type: 'LineString',
- coordinates: [prev.geometry.coordinates, coords],
- },
- };
- map.getSource('line-move' + layerId).setData(jsonl);
- ele.innerHTML = getLength(pointList);
- tooltip.setLngLat(coords);
- }
- }
- }
-
- /**
- * 绘制完成
- * @param {*} _e
- */
- function finish(_e) {
- if (isMeasure) {
- isMeasure = false;
- var coords = [_e.lngLat.lng, _e.lngLat.lat];
- removePoint(coords);
- if (map.getLayer('point-move' + layerId)) map.removeLayer('point-move' + layerId);
- if (map.getLayer('line-move' + layerId)) map.removeLayer('line-move' + layerId);
- map.getCanvas().style.cursor = 'default';
- tooltip.remove();
- let features = map.getSource('line' + layerId)._data.features;
- let coordinates = features.map(i => turf.coordAll(i)[0]);
- if (coordinates.length == 1) coordinates = turf.coordAll(features[0]);
- callback(turf.lineString(coordinates));
- }
- }
-
- map.on('click', function (_e) {
- addPointforJSON(_e);
- });
-
- map.on('mousemove', function (_e) {
- mouseMove(_e);
- });
-
- map.on('dblclick', function (_e) {
- finish(_e);
- });
-
- /**
- * 编辑测量线
- */
- function editLine() {
- catchMark = createMarker();
- UpdataGeolist();
-
- map.on('mousemove', onMouseMove);
- map.on('mousedown', onmousedown);
- }
-
- function onMouseMove(e) {
- const moveCoord = [e.lngLat.lng, e.lngLat.lat];
-
- if (jsonPoint.features.length > 1) {
- // 计算当前指针与线段最近的点
- pointOnLine = getNearestPointOnLine(Geolist, moveCoord); // 自己计算
- const screenOnLine = Object.values(map.project(pointOnLine)); // 线上屏幕坐标
- const screenP = [e.point.x, e.point.y];
- const screenDist = screenDistance(screenOnLine, screenP); // 距离
- if (screenDist < 15) {
- isEdit = true;
- catchMark.setLngLat(pointOnLine).addTo(map);
- catchMark.getElement().style.display = 'block';
- } else {
- isEdit = false;
- catchMark.getElement().style.display = 'none';
- }
- } else {
- isEdit = false;
- catchMark.getElement().style.display = 'none';
- map.dragPan.enable();
- }
- }
-
- function onmousedown(e) {
- if (isEdit) {
- map.dragPan.disable();
- let isExist = false;
-
- // 首先判断编辑点是否是存在(存在修改原来点,不存在新加点)
- for (let i = 0; i < jsonPoint.features.length; i++) {
- const coord = jsonPoint.features[i].geometry.coordinates;
- if (coord[0] === pointOnLine[0] && coord[1] === pointOnLine[1]) {
- isExist = true;
- }
- }
-
- // 获取编辑点在列表中的位置
- dragPointOrder = getDragCoords(pointOnLine, Geolist);
-
- if (!isExist) {
- // 添加编辑点
- const point = {
- type: 'Feature',
- geometry: {
- type: 'Point',
- coordinates: pointOnLine,
- },
- properties: {
- id: String(new Date().getTime()),
- },
- };
- jsonPoint.features.splice(dragPointOrder, 0, point);
-
- // 更新绘制要素
- updataFeature();
- }
-
- map.on('mousemove', onDrag);
- map.on('mouseup', onMouseup);
- }
- }
-
- function onDrag(e) {
- // 开始计时
- // var start = new Date().getTime()
- const movePoint = [e.lngLat.lng, e.lngLat.lat];
-
- // 点跟随鼠标移动
- jsonPoint.features[dragPointOrder].geometry.coordinates = movePoint;
-
- // 更新绘制要素
- updataFeature();
-
- // 计时结束
- // var end1 = new Date().getTime()
- // console.log('渲染时间:', end1 - start + 'ms')
- }
-
- // 更新绘制要素
- function updataFeature() {
- UpdataGeolist();
- map.getSource('points' + layerId).setData(jsonPoint);
- drawLine(jsonPoint);
- addMeasureRes(jsonPoint);
- }
-
- function onMouseup(e) {
- map.off('mousemove', onDrag);
- map.dragPan.enable();
- }
-
- // 创建Marker
- function createMarker() {
- const markerParam = {
- map: this.map,
- lngLat: [0, 0],
- height: 13,
- width: 13,
- size: 13,
- isDrag: false,
- cursor: 'default',
- };
- return new mapboxgl.Marker().setLngLat(markerParam.lngLat).setDraggable(false).addTo(markerParam.map);
- }
-
- // 更新点集
- function UpdataGeolist() {
- Geolist = [];
- for (let i = 0; i < jsonPoint.features.length; i++) {
- const coord = jsonPoint.features[i].geometry.coordinates;
- Geolist.push(coord);
- }
- }
-
- // 计算点到直线最近距离的点
- function getNearestPointOnLine(list, moveCoord) {
- var dis, point1, point2;
- for (let i = 0; i < list.length - 1; i++) {
- const distance = getNearestDistance(moveCoord, list[i], list[i + 1]);
- if (i === 0) {
- dis = distance;
- point1 = list[i];
- point2 = list[i + 1];
- } else {
- if (distance < dis) {
- dis = distance;
- point1 = list[i];
- point2 = list[i + 1];
- }
- }
- }
- const Point = getNearestPoint(moveCoord, point1, point2);
- return Point;
- }
-
- // 计算点point到线段point1, point2最近距离
- function getNearestDistance(point, point1, point2) {
- const P = {};
- const A = {};
- const B = {};
- P.x = point[0];
- P.y = point[1];
- A.x = point1[0];
- A.y = point1[1];
- B.x = point2[0];
- B.y = point2[1];
- // 计算向量AP和向量AB的点积
- const dotProduct = (P.x - A.x) * (B.x - A.x) + (P.y - A.y) * (B.y - A.y);
- // 计算向量AB的长度的平方
- const lengthSquare = (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y);
- // 计算点P到线段AB的投影点C
- const t = dotProduct / lengthSquare;
- const C = { x: A.x + t * (B.x - A.x), y: A.y + t * (B.y - A.y) };
- // 如果点C在线段AB内,则点P到线段AB的最近距离为PC的长度;否则,点P到线段AB的最近距离为PA或PB中的较小值。
- const isInside = dotProduct >= 0 && dotProduct <= lengthSquare;
- if (isInside) {
- return Math.sqrt((P.x - C.x) * (P.x - C.x) + (P.y - C.y) * (P.y - C.y));
- } else {
- return Math.min(
- Math.sqrt((P.x - A.x) * (P.x - A.x) + (P.y - A.y) * (P.y - A.y)),
- Math.sqrt((P.x - B.x) * (P.x - B.x) + (P.y - B.y) * (P.y - B.y))
- );
- }
- }
-
- // 计算点到直线最近的点 point点坐标,point1, point2直线两个端点
- function getNearestPoint(point, point1, point2) {
- var x, y, x0, y0, x1, y1, x2, y2;
- x0 = point[0];
- y0 = point[1];
- x1 = point1[0];
- y1 = point1[1];
- x2 = point2[0];
- y2 = point2[1];
-
- if (x1 !== x2 && y1 !== y2) {
- const a = (y2 - y1) / (x2 - x1);
- const b = y1 - a * x1;
- const k2 = -1 / a;
- const b2 = y0 - k2 * x0;
- x = (b2 - b) / (a - k2);
- y = a * x + b;
- } else if (x1 === x2) {
- x = x1;
- y = y0;
- } else if (y1 === y2) {
- x = x0;
- y = y1;
- }
-
- // 点不能超出线段
- if (x1 < x2) {
- if (x2 < x) {
- x = x2;
- } else if (x < x1) {
- x = x1;
- }
- } else {
- if (x1 < x) {
- x = x1;
- } else if (x < x2) {
- x = x2;
- }
- }
- if (y1 < y2) {
- if (y2 < y) {
- y = y2;
- } else if (y < y1) {
- y = y1;
- }
- } else {
- if (y1 < y) {
- y = y1;
- } else if (y < y2) {
- y = y2;
- }
- }
-
- // 点吸附端点
- const screenX0 = Object.values(map.project([x0, y0])); // 屏幕坐标
- const screenX1 = Object.values(map.project([x1, y1])); // 屏幕坐标
- const screenX2 = Object.values(map.project([x2, y2])); // 屏幕坐标
- const screenDistX1 = screenDistance(screenX0, screenX1); // 距离
- const screenDistX2 = screenDistance(screenX0, screenX2); // 距离
- if (screenDistX1 < 10) {
- x = x1;
- y = y1;
- }
- if (screenDistX2 < 10) {
- x = x2;
- y = y2;
- }
-
- return [x, y];
- }
-
- // 屏幕距离
- function screenDistance(point1, point2) {
- const x2 = Math.pow(point1[0] - point2[0], 2);
- const y2 = Math.pow(point1[1] - point2[1], 2);
- const dist = Math.sqrt(x2 + y2);
-
- return dist;
- }
-
- // 计算编辑点在线段上的添加位置
- function getDragCoords(coords, list) {
- var x, y, x1, y1, x2, y2;
- let index = 0;
- x = coords[0];
- y = coords[1];
-
- for (let i = 0; i < list.length - 1; i++) {
- x1 = list[i][0];
- y1 = list[i][1];
- x2 = list[i + 1][0];
- y2 = list[i + 1][1];
-
- if (x === x1 && y === y1) {
- index = i;
- break;
- } else {
- // 计算线段的长度
- const length = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
- // 计算点到线段起点的距离
- const distance1 = Math.sqrt(Math.pow(x - x1, 2) + Math.pow(y - y1, 2));
- // 计算点到线段终点的距离
- const distance2 = Math.sqrt(Math.pow(x - x2, 2) + Math.pow(y - y2, 2));
- // 如果点到线段两个端点的距离之和等于线段的长度,则点在线段上
- if (Math.abs(length - distance1 - distance2) < 0.00001) {
- index = i + 1;
- break;
- }
- }
- }
- return index;
- }
- }
-
- /**
- * 测量面积
- * @param {*} layerId
- */
- measureArea(layerId, isP = true, callback = () => {}) {
- this.layerAreaList.push(layerId);
- var isMeasure = true;
- const map = this.map;
- map.doubleClickZoom.disable();
- let catchMark = null;
- let isEdit = false;
- let Geolist = [];
- let dragPointOrder = 0;
- let pointOnLine = [0, 0];
-
- const jsonPoint = {
- type: 'FeatureCollection',
- features: [],
- };
- const jsonLine = {
- type: 'FeatureCollection',
- features: [],
- };
-
- const ele = document.createElement('div');
- ele.setAttribute('class', 'measure-move');
- const option = {
- element: ele,
- anchor: 'left',
- offset: [8, 0],
- };
- const tooltip = new mapboxgl.Marker(option).setLngLat([0, 0]);
- if (isP) tooltip.addTo(map);
- map.addSource('points-area' + layerId, {
- type: 'geojson',
- data: jsonPoint,
- });
- map.addSource('point-move' + layerId, {
- type: 'geojson',
- data: jsonPoint,
- });
- map.addSource('line-area' + layerId, {
- type: 'geojson',
- data: jsonLine,
- });
- map.addSource('line-move' + layerId, {
- type: 'geojson',
- data: jsonLine,
- });
- map.addLayer({
- id: 'line-move' + layerId,
- type: 'line',
- source: 'line-move' + layerId,
- paint: {
- 'line-color': '#ff0000',
- 'line-width': 2,
- 'line-opacity': 0.65,
- 'line-dasharray': [5, 2],
- },
- });
- map.addLayer({
- id: 'line-area' + layerId,
- type: 'fill',
- source: 'line-area' + layerId,
- paint: {
- 'fill-color': '#ff0000',
- 'fill-opacity': 0.1,
- },
- });
- map.addLayer({
- id: 'line-area-stroke' + layerId,
- type: 'line',
- source: 'line-area' + layerId,
- paint: {
- 'line-color': '#ff0000',
- 'line-width': 2,
- 'line-opacity': 0.65,
- },
- });
- map.addLayer({
- id: 'points-area' + layerId,
- type: 'circle',
- source: 'points-area' + layerId,
- paint: {
- 'circle-color': '#ffffff',
- 'circle-radius': 3.5,
- 'circle-stroke-width': 1.5,
- 'circle-stroke-color': '#ff0000',
- },
- });
- map.addLayer({
- id: 'point-move' + layerId,
- type: 'circle',
- source: 'point-move' + layerId,
- paint: {
- 'circle-color': '#ffffff',
- 'circle-radius': 3.5,
- 'circle-stroke-width': 1.5,
- 'circle-stroke-color': '#ff0000',
- },
- });
-
- this.setDistance = () => {
- isMeasure = false;
- if (map.getLayer('point-move' + layerId)) map.removeLayer('point-move' + layerId);
- if (map.getLayer('line-move' + layerId)) map.removeLayer('line-move' + layerId);
-
- return isMeasure;
- };
-
- /**
- * 添加点
- * @param {*} _e
- */
- function addPointforJSON(_e) {
- if (isMeasure) {
- const point = {
- type: 'Feature',
- geometry: {
- type: 'Point',
- coordinates: [_e.lngLat.lng, _e.lngLat.lat],
- },
- properties: {
- id: String(new Date().getTime()),
- },
- };
- jsonPoint.features.push(point);
- map.getSource('points-area' + layerId).setData(jsonPoint);
- addMeasureRes(jsonPoint);
- }
- }
-
- /**
- * 添加dom
- * @param {*} jsonPoint 点集
- */
- function addMeasureRes(jsonPoint) {
- if (isP && jsonPoint.features.length > 0) {
- removedom();
- const pointList = [];
- for (let i = 0; i < jsonPoint.features.length; i++) {
- const coords = jsonPoint.features[i].geometry.coordinates;
- pointList.push(coords);
-
- const close = document.createElement('div');
- close.setAttribute('class', `measure-result ${layerId} close`);
- close.onclick = __e => {
- // 移除点
- __e.stopPropagation();
- removePoint(coords);
- map.off('mousemove', onMouseMove);
- map.off('mousedown', onmousedown);
- if (catchMark) {
- catchMark.remove();
- }
- };
- if ((jsonPoint.features.length === i + 1) & !isMeasure) {
- const clear = document.createElement('div');
- clear.setAttribute('class', `measure-result ${layerId} clear`);
- clear.onclick = __e => {
- // 全部移除
- __e.stopPropagation();
- removeLayer();
- map.off('mousemove', onMouseMove);
- map.off('mousedown', onmousedown);
- if (catchMark) {
- catchMark.remove();
- }
- };
-
- const edit = document.createElement('div');
- edit.setAttribute('class', `measure-result ${layerId} edit`);
- edit.onclick = __e => {
- // 编辑
- __e.stopPropagation();
- map.off('mousemove', onMouseMove);
- map.off('mousedown', onmousedown);
- if (catchMark) {
- catchMark.remove();
- }
- editArea();
- };
-
- const element = document.createElement('div');
- element.setAttribute('class', 'measure-result ' + layerId);
- const option = {
- element: element,
- anchor: 'left',
- offset: [0, 0],
- };
- element.innerHTML = getArea(pointList);
- element.appendChild(edit);
- element.appendChild(clear);
- element.appendChild(close);
- new mapboxgl.Marker(option).setLngLat(coords).addTo(map);
- } else {
- const option = {
- element: close,
- anchor: 'left',
- offset: [5, -15],
- };
- new mapboxgl.Marker(option).setLngLat(coords).addTo(map);
- }
- }
- }
- }
-
- /**
- * 计算面积
- * @param {*} pointList
- * @returns
- */
- function getArea(pointList) {
- pointList.push(pointList[0]);
- const polygon = turf.polygon([pointList]);
- let area = turf.area(polygon);
- if (area < 10000) {
- area = Math.round(area) + '平方米';
- } else {
- area = (area / 1000000).toFixed(5) + '平方公里';
- }
- return area;
- }
-
- /**
- * 移除点
- * @param {*} coords 点坐标
- */
- function removePoint(coords) {
- if (jsonPoint.features.length > 0) {
- if (jsonPoint.features.length === 3) {
- jsonPoint.features = [];
- jsonLine.features = [];
- map.getSource('points-area' + layerId).setData(jsonPoint);
- map.getSource('line-area' + layerId).setData(jsonLine);
- removedom();
- } else {
- for (let i = 0; i < jsonPoint.features.length; i++) {
- if (
- (jsonPoint.features[i].geometry.coordinates[0] === coords[0]) &
- (jsonPoint.features[i].geometry.coordinates[1] === coords[1])
- ) {
- jsonPoint.features.splice(i, 1);
- }
- }
- addMeasureRes(jsonPoint);
- map.getSource('points-area' + layerId).setData(jsonPoint);
-
- const pointList = [];
- for (let i = 0; i < jsonPoint.features.length; i++) {
- const coord = jsonPoint.features[i].geometry.coordinates;
- pointList.push(coord);
- }
- const pts = pointList.concat([pointList[0]]);
- const jsona = {
- type: 'Feature',
- geometry: {
- type: 'Polygon',
- coordinates: [pts],
- },
- };
- map.getSource('line-area' + layerId).setData(jsona);
- }
- }
- }
-
- /**
- * 移除dom
- */
- function removedom() {
- const dom = document.getElementsByClassName('measure-result ' + layerId);
- const len = dom.length;
- if (len) {
- for (let i = len - 1; i >= 0; i--) {
- if (dom[i]) dom[i].remove();
- }
- }
- }
-
- /**
- * 移除图层
- */
- function removeLayer() {
- jsonPoint.features = [];
- jsonLine.features = [];
- if (map.getLayer('points-area' + layerId)) map.removeLayer('points-area' + layerId);
- if (map.getLayer('line-area' + layerId)) map.removeLayer('line-area' + layerId);
- if (map.getLayer('line-area-stroke' + layerId)) map.removeLayer('line-area-stroke' + layerId);
- removedom();
- }
-
- /**
- * 鼠标move事件
- * @param {} _e
- */
- function mouseMove(_e) {
- if (isMeasure) {
- map.getCanvas().style.cursor = 'default';
- const coords = [_e.lngLat.lng, _e.lngLat.lat];
- const jsonp = {
- type: 'Feature',
- geometry: {
- type: 'Point',
- coordinates: coords,
- },
- };
- map.getSource('point-move' + layerId).setData(jsonp);
-
- if (jsonPoint.features.length > 0) {
- if (jsonPoint.features.length === 1) {
- const prev = jsonPoint.features[jsonPoint.features.length - 1];
- const jsonl = {
- type: 'Feature',
- geometry: {
- type: 'LineString',
- coordinates: [prev.geometry.coordinates, coords],
- },
- };
- map.getSource('line-move' + layerId).setData(jsonl);
- } else {
- const json = {
- type: 'FeatureCollection',
- features: [],
- };
- map.getSource('line-move' + layerId).setData(json);
-
- const pointList = [];
- for (let i = 0; i < jsonPoint.features.length; i++) {
- const coord = jsonPoint.features[i].geometry.coordinates;
- pointList.push(coord);
- }
- pointList.push(coords);
- const pts = pointList.concat([pointList[0]]);
- const jsona = {
- type: 'Feature',
- geometry: {
- type: 'Polygon',
- coordinates: [pts],
- },
- };
- map.getSource('line-area' + layerId).setData(jsona);
- ele.innerHTML = getArea(pointList);
- tooltip.setLngLat(coords);
- }
- }
- }
- }
-
- /**
- * 绘制完成
- * @param {*} _e
- */
- function finish(_e) {
- if (isMeasure) {
- isMeasure = false;
- const coords = [_e.lngLat.lng, _e.lngLat.lat];
- removePoint(coords);
- if (map.getLayer('point-move' + layerId)) map.removeLayer('point-move' + layerId);
- if (map.getLayer('line-move' + layerId)) map.removeLayer('line-move' + layerId);
- map.getCanvas().style.cursor = 'default';
- tooltip.remove();
- callback(map.getSource('line-area' + layerId)._data);
- }
- }
-
- map.on('click', function (_e) {
- addPointforJSON(_e);
- });
-
- map.on('dblclick', function (_e) {
- finish(_e);
- });
-
- map.on('mousemove', function (_e) {
- mouseMove(_e);
- });
-
- /**
- * 编辑测量面
- */
- function editArea() {
- catchMark = createMarker();
- UpdataGeolist();
-
- map.on('mousemove', onMouseMove);
- map.on('mousedown', onmousedown);
- }
-
- function onMouseMove(e) {
- const moveCoord = [e.lngLat.lng, e.lngLat.lat];
-
- if (jsonPoint.features.length > 1) {
- // 计算当前指针与线段的距离
- pointOnLine = getNearestPointOnLine(Geolist, moveCoord); // 线上实际坐标
- const screenOnLine = Object.values(map.project(pointOnLine)); // 线上屏幕坐标
- const screenP = [e.point.x, e.point.y];
- const screenDist = screenDistance(screenOnLine, screenP); // 距离
- if (screenDist < 15) {
- isEdit = true;
- catchMark.setLngLat(pointOnLine).addTo(map);
- catchMark.getElement().style.display = 'block';
- } else {
- isEdit = false;
- catchMark.getElement().style.display = 'none';
- }
- } else {
- isEdit = false;
- catchMark.getElement().style.display = 'none';
- map.dragPan.enable();
- }
- }
-
- function onmousedown(e) {
- if (isEdit) {
- map.dragPan.disable();
- let isExist = false;
-
- // 首先判断编辑点是否是存在(存在修改原来点,不存在新加点)
- for (let i = 0; i < jsonPoint.features.length; i++) {
- const coord = jsonPoint.features[i].geometry.coordinates;
- if (coord[0] === pointOnLine[0] && coord[1] === pointOnLine[1]) {
- isExist = true;
- }
- }
-
- // 获取编辑点在列表中的位置
- dragPointOrder = getDragCoords(pointOnLine, Geolist);
-
- if (!isExist) {
- // 添加编辑点
- const point = {
- type: 'Feature',
- geometry: {
- type: 'Point',
- coordinates: pointOnLine,
- },
- properties: {
- id: String(new Date().getTime()),
- },
- };
- jsonPoint.features.splice(dragPointOrder, 0, point);
-
- // 更新绘制要素
- updataFeature();
- }
-
- map.on('mousemove', onDrag);
- map.on('mouseup', onMouseup);
- }
- }
-
- function onDrag(e) {
- const movePoint = [e.lngLat.lng, e.lngLat.lat];
-
- // 点跟随鼠标移动
- jsonPoint.features[dragPointOrder].geometry.coordinates = movePoint;
-
- // 更新绘制要素
- updataFeature();
- }
-
- // 更新绘制要素
- function updataFeature() {
- UpdataGeolist();
- const pts = Geolist;
- const jsona = {
- type: 'Feature',
- geometry: {
- type: 'Polygon',
- coordinates: [pts],
- },
- };
- map.getSource('line-area' + layerId).setData(jsona);
- map.getSource('points-area' + layerId).setData(jsonPoint);
- addMeasureRes(jsonPoint);
- }
-
- function onMouseup(e) {
- map.off('mousemove', onDrag);
- map.dragPan.enable();
- }
-
- // 创建Marker
- function createMarker() {
- const markerParam = {
- map: this.map,
- lngLat: [0, 0],
- height: 13,
- width: 13,
- size: 13,
- isDrag: false,
- cursor: 'default',
- };
- return new mapboxgl.Marker().setLngLat(markerParam.lngLat).setDraggable(false).addTo(markerParam.map);
- }
-
- // 更新点集
- function UpdataGeolist() {
- Geolist = [];
- for (let i = 0; i < jsonPoint.features.length; i++) {
- const coord = jsonPoint.features[i].geometry.coordinates;
- Geolist.push(coord);
- }
- Geolist.push(Geolist[0]);
- }
-
- // 计算点到直线最近距离的点
- function getNearestPointOnLine(list, moveCoord) {
- var dis, point1, point2;
- for (let i = 0; i < list.length - 1; i++) {
- const distance = getNearestDistance(moveCoord, list[i], list[i + 1]);
- if (i === 0) {
- dis = distance;
- point1 = list[i];
- point2 = list[i + 1];
- } else {
- if (distance < dis) {
- dis = distance;
- point1 = list[i];
- point2 = list[i + 1];
- }
- }
- }
- const Point = getNearestPoint(moveCoord, point1, point2);
- return Point;
- }
-
- // 计算点point到线段point1, point2最近距离
- function getNearestDistance(point, point1, point2) {
- const P = {};
- const A = {};
- const B = {};
- P.x = point[0];
- P.y = point[1];
- A.x = point1[0];
- A.y = point1[1];
- B.x = point2[0];
- B.y = point2[1];
- // 计算向量AP和向量AB的点积
- const dotProduct = (P.x - A.x) * (B.x - A.x) + (P.y - A.y) * (B.y - A.y);
- // 计算向量AB的长度的平方
- const lengthSquare = (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y);
- // 计算点P到线段AB的投影点C
- const t = dotProduct / lengthSquare;
- const C = { x: A.x + t * (B.x - A.x), y: A.y + t * (B.y - A.y) };
- // 如果点C在线段AB内,则点P到线段AB的最近距离为PC的长度;否则,点P到线段AB的最近距离为PA或PB中的较小值。
- const isInside = dotProduct >= 0 && dotProduct <= lengthSquare;
- if (isInside) {
- return Math.sqrt((P.x - C.x) * (P.x - C.x) + (P.y - C.y) * (P.y - C.y));
- } else {
- return Math.min(
- Math.sqrt((P.x - A.x) * (P.x - A.x) + (P.y - A.y) * (P.y - A.y)),
- Math.sqrt((P.x - B.x) * (P.x - B.x) + (P.y - B.y) * (P.y - B.y))
- );
- }
- }
-
- // 计算点到直线最近的点 point点坐标,point1, point2直线两个端点
- function getNearestPoint(point, point1, point2) {
- var x, y, x0, y0, x1, y1, x2, y2;
- x0 = point[0];
- y0 = point[1];
- x1 = point1[0];
- y1 = point1[1];
- x2 = point2[0];
- y2 = point2[1];
-
- if (x1 !== x2 && y1 !== y2) {
- const a = (y2 - y1) / (x2 - x1);
- const b = y1 - a * x1;
- const k2 = -1 / a;
- const b2 = y0 - k2 * x0;
- x = (b2 - b) / (a - k2);
- y = a * x + b;
- } else if (x1 === x2) {
- x = x1;
- y = y0;
- } else if (y1 === y2) {
- x = x0;
- y = y1;
- }
-
- // 点不能超出线段
- if (x1 < x2) {
- if (x2 < x) {
- x = x2;
- } else if (x < x1) {
- x = x1;
- }
- } else {
- if (x1 < x) {
- x = x1;
- } else if (x < x2) {
- x = x2;
- }
- }
- if (y1 < y2) {
- if (y2 < y) {
- y = y2;
- } else if (y < y1) {
- y = y1;
- }
- } else {
- if (y1 < y) {
- y = y1;
- } else if (y < y2) {
- y = y2;
- }
- }
-
- // 点吸附端点
- const screenX0 = Object.values(map.project([x0, y0])); // 屏幕坐标
- const screenX1 = Object.values(map.project([x1, y1])); // 屏幕坐标
- const screenX2 = Object.values(map.project([x2, y2])); // 屏幕坐标
- const screenDistX1 = screenDistance(screenX0, screenX1); // 距离
- const screenDistX2 = screenDistance(screenX0, screenX2); // 距离
- if (screenDistX1 < 10) {
- x = x1;
- y = y1;
- }
- if (screenDistX2 < 10) {
- x = x2;
- y = y2;
- }
-
- return [x, y];
- }
-
- // 屏幕距离
- function screenDistance(point1, point2) {
- const x2 = Math.pow(point1[0] - point2[0], 2);
- const y2 = Math.pow(point1[1] - point2[1], 2);
- const dist = Math.sqrt(x2 + y2);
-
- return dist;
- }
-
- // 计算编辑点在线段上的添加位置
- function getDragCoords(coords, list) {
- var x, y, x1, y1, x2, y2;
- let index = 0;
- x = coords[0];
- y = coords[1];
-
- for (let i = 0; i < list.length - 1; i++) {
- x1 = list[i][0];
- y1 = list[i][1];
- x2 = list[i + 1][0];
- y2 = list[i + 1][1];
-
- if (x === x1 && y === y1) {
- index = i;
- break;
- } else {
- // 计算线段的长度
- const length = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
- // 计算点到线段起点的距离
- const distance1 = Math.sqrt(Math.pow(x - x1, 2) + Math.pow(y - y1, 2));
- // 计算点到线段终点的距离
- const distance2 = Math.sqrt(Math.pow(x - x2, 2) + Math.pow(y - y2, 2));
- // 如果点到线段两个端点的距离之和等于线段的长度,则点在线段上
- if (Math.abs(length - distance1 - distance2) < 0.00001) {
- index = i + 1;
- break;
- }
- }
- }
- return index;
- }
- }
-
- drawPoint(layerId, callback = () => {}) {
- this.layerPointList.push(layerId);
- const map = this.map;
- map.doubleClickZoom.disable();
- const jsonPoint = {
- type: 'FeatureCollection',
- features: [],
- };
- map.addSource('points' + layerId, {
- type: 'geojson',
- data: jsonPoint,
- });
- map.addLayer({
- id: 'points' + layerId,
- type: 'circle',
- source: 'points' + layerId,
- paint: {
- 'circle-color': '#ffffff',
- 'circle-radius': 3.5,
- 'circle-stroke-width': 1.5,
- 'circle-stroke-color': '#ff0000',
- },
- });
-
- /**
- * 添加点
- * @param {*} _e
- */
- function addPointforJSON(_e) {
- const point = {
- type: 'Feature',
- geometry: {
- type: 'Point',
- coordinates: [_e.lngLat.lng, _e.lngLat.lat],
- },
- properties: {
- id: String(new Date().getTime()),
- },
- };
- jsonPoint.features.push(point);
- map.getSource('points' + layerId).setData(jsonPoint);
- map.off('click', addPointforJSON);
- callback(point);
- }
- map.on('click', addPointforJSON);
- }
-
- drawRectangle(layerId, callback = () => {}) {
- this.layerPointList.push(layerId);
- const map = this.map;
- map.doubleClickZoom.disable();
- const jsonPoint = {
- type: 'FeatureCollection',
- features: [],
- };
- const jsonArea = {
- type: 'FeatureCollection',
- features: [],
- };
- map.addSource('points' + layerId, {
- type: 'geojson',
- data: jsonPoint,
- });
- map.addSource('line-area' + layerId, {
- type: 'geojson',
- data: jsonArea,
- });
- map.addLayer({
- id: 'line-area' + layerId,
- type: 'fill',
- source: 'line-area' + layerId,
- paint: {
- 'fill-color': '#ff0000',
- 'fill-opacity': 0.1,
- },
- });
- map.addLayer({
- id: 'points' + layerId,
- type: 'circle',
- source: 'points' + layerId,
- paint: {
- 'circle-color': '#ffffff',
- 'circle-radius': 3.5,
- 'circle-stroke-width': 1.5,
- 'circle-stroke-color': '#ff0000',
- },
- });
-
- /**
- * 添加点
- * @param {*} _e
- */
- function addPointforJSON(_e) {
- const point = {
- type: 'Feature',
- geometry: {
- type: 'Point',
- coordinates: [_e.lngLat.lng, _e.lngLat.lat],
- },
- properties: {
- id: String(new Date().getTime()),
- },
- };
- jsonPoint.features.push(point);
- if (jsonPoint.features.length == 2) {
- map.off('click', addPointforJSON);
- map.off('mousemove', mouseRectangle);
- callback(jsonArea.features[0]);
- }
- map.getSource('points' + layerId).setData(jsonPoint);
- }
-
- function mouseRectangle(_e) {
- if (!jsonPoint.features.length) {
- const point = {
- type: 'Feature',
- geometry: {
- type: 'Point',
- coordinates: [_e.lngLat.lng, _e.lngLat.lat],
- },
- properties: {
- id: String(new Date().getTime()),
- },
- };
- return map.getSource('points' + layerId).setData({ type: 'FeatureCollection', features: [point] });
- }
- let coordinates = jsonPoint.features[0].geometry.coordinates;
- let bbox = coordinates.concat([_e.lngLat.lng, _e.lngLat.lat]).sort((a, b) => a - b);
- let polygon = turf.bboxPolygon([bbox[2], bbox[0], bbox[3], bbox[1]]);
- jsonArea.features = [polygon];
- map.getSource('line-area' + layerId).setData(jsonArea);
- }
-
- map.on('click', addPointforJSON);
-
- map.on('mousemove', mouseRectangle);
- }
-
- /**
- * 清除所有测量要素
- */
- clearMeasureAll() {
- const dom = document.getElementsByClassName('measure-result');
- const len = dom.length;
- if (len) {
- for (let i = len - 1; i >= 0; i--) {
- if (dom[i]) dom[i].remove();
- }
- }
- if (this.layerDistanceList) {
- for (let i = 0; i < this.layerDistanceList.length; i++) {
- const layerid = this.layerDistanceList[i];
- try {
- if (this.map.getLayer('points' + layerid)) this.map.removeLayer('points' + layerid);
- if (this.map.getLayer('line' + layerid)) this.map.removeLayer('line' + layerid);
- if (this.map.getLayer('point-move' + layerid)) this.map.removeLayer('point-move' + layerid);
- if (this.map.getLayer('line-move' + layerid)) this.map.removeLayer('line-move' + layerid);
- } catch (error) {
- console.log(error);
- }
- }
- }
- this.layerDistanceList = [];
- if (this.layerAreaList) {
- for (let i = 0; i < this.layerAreaList.length; i++) {
- const layerid = this.layerAreaList[i];
- try {
- if (this.map.getLayer('points-area' + layerid)) this.map.removeLayer('points-area' + layerid);
- if (this.map.getLayer('line-area' + layerid)) this.map.removeLayer('line-area' + layerid);
- if (this.map.getLayer('line-area-stroke' + layerid)) this.map.removeLayer('line-area-stroke' + layerid);
- if (this.map.getLayer('point-move' + layerid)) this.map.removeLayer('point-move' + layerid);
- if (this.map.getLayer('line-move' + layerid)) this.map.removeLayer('line-move' + layerid);
- } catch (error) {
- console.log(error);
- }
- }
- }
- this.layerAreaList = [];
- if (this.layerPointList) {
- for (let i = 0; i < this.layerPointList.length; i++) {
- const layerid = this.layerPointList[i];
- try {
- if (this.map.getLayer('points' + layerid)) this.map.removeLayer('points' + layerid);
- if (this.map.getLayer('line-area' + layerid)) this.map.removeLayer('line-area' + layerid);
- } catch (error) {
- console.log(error);
- }
- }
- }
- this.layerPointList = [];
- this.map.doubleClickZoom.enable();
- }
- };
- });