let mousemoveStatus = true; // del-刘梦祥-时间(删除点中的角度) "
" + pointAngle + "度" L.Control.Draw = L.Control.extend({ //是否初始化 _initialized: false, //统计 _lC: 0, //测量对象集合 _measureObjs: {}, //是否完成当前测绘 _finished: true, //新测量 isNewElevation: true, moveMarker: false, //测量参数 options: { position: "topright", autoZIndex: true, offset: [10, 10], background: "#000", color: "#fff", size: 14, closeButton: true, iconUrl: "./images/marker-icon.png", }, initialize: function (options) { L.setOptions(this, options); return this; }, onAdd: function (map) { this._map = map; this._createControl(); switch (this.options.position) { case "topleft": this._container.style.marginLeft = this.options.offset[0] + "px"; this._container.style.marginTop = this.options.offset[1] + "px"; break; case "topright": this._container.style.marginRight = this.options.offset[0] + "px"; this._container.style.marginTop = this.options.offset[1] + "px"; break; case "bottomleft": this._container.style.marginLeft = this.options.offset[0] + "px"; this._container.style.marginBottom = this.options.offset[1] + "px"; break; case "bottomright": this._container.style.marginRight = this.options.offset[0] + "px"; this._container.style.marginBottom = this.options.offset[1] + "px"; break; } return this._container; }, _createControl: function () { var _this = this; this._container = L.DomUtil.create( "div", "leaflet-bar leaflet-control-measure" ); var link = L.DomUtil.create( "a", "leaflet-control-measure-link", this._container ); link.title = "测量"; L.DomUtil.create("span", "", link); L.DomEvent.on(this._container, "contextmenu", L.DomEvent.stopPropagation) .on(link, "click", L.DomEvent.stopPropagation) .on(link, "click", function () { if (_this._finished) { //开启新的测量 _this.start(); } else { _this._finished = true; } }); // _this.start(); }, start: function () { var _this = this; _this._finished = false; L.DomUtil.addClass(_this._container, "active"); _this._addMeasureGroup(); }, _addMeasureGroup: function () { var _this = this; if (!_this._initialized) { _this._measureGroup = new L.featureGroup(); _this._measureGroup.addTo(this._map); _this._initialized = true; } if (_this.isNewElevation) { _this._lC++; _this._measureObjs[_this._lC] = new L.FeatureGroup(); _this._measureObjs[_this._lC].addTo(_this._measureGroup); _this.isNewElevation = false; _this._measureObjs[_this._lC].measurePoints = []; } _this.tmpMarkers = []; //关闭地图双击事件 _this._map.doubleClickZoom.disable(); //监听地图单击事件 _this._map.on("click", _this._onClickPoint, this); //监听鼠标移动事件 _this._map.on("mousemove", _this._mousemove, this); }, _mousemove: function (e) { if (mousemoveStatus) { var _this = this; e.latlng = _this.latlngRectifying(e); if (_this.moveMarker) { _this.moveMarker.setLatLng(e.latlng); if (_this._measureObjs[_this._lC].polyline) { _this._measureObjs[_this._lC].measurePoints.push([ e.latlng.lat, e.latlng.lng, ]); var points = _this._measureObjs[_this._lC].measurePoints; if (_this._measureObjs[_this._lC].measurePoints.length == 2) { var radius = L.latLng(points[1]).distanceTo(L.latLng(points[0])); _this._measureObjs[_this._lC].circle.setRadius(radius); } else if ( _this._measureObjs[_this._lC].measurePoints.length == 3 && e.latlng.indexMarker == 1 ) { _this._measureObjs[_this._lC].circle.setStyle({ opacity: 1, }); } else { _this._measureObjs[_this._lC].circle.setStyle({ opacity: 0, }); } if (_this._measureObjs[_this._lC].measurePoints.length > 2) { var coors = _.clone(_this._measureObjs[_this._lC].measurePoints); coors.push( _this._measureObjs[_this._lC].measurePoints[ _this._measureObjs[_this._lC].measurePoints.length - 1 ] ); if (_this._measureObjs[_this._lC].polygon) { _this._measureObjs[_this._lC].polygon.setLatLngs([coors]); } else { _this._measureObjs[_this._lC].polygon = L.polygon([coors], { color: "#fff", weight: 0, fillColor: "#fff", fillOpacity: 0.3, }).addTo(_this._measureObjs[_this._lC]); } } _this._measureObjs[_this._lC].polyline.setLatLngs(points); //实时计算测量数据 var moveData = _.clone(points); _this._moveInfo(moveData); _this._measureObjs[_this._lC].measurePoints.pop(); } } else { _this.moveMarker = L.circleMarker(e.latlng, { radius: 10, color: "#f00", }).addTo(_this._map); } } else { this._map.off("mousemove"); // console.log("lmx"); } }, //测量时,根据鼠标移动点位信息 _moveInfo: function (data) { var _this = this; var lineDistance = 0; for (var i = 1; i < data.length; i++) { var curcoor = data[i]; var prePoint = data[i - 1]; lineDistance += L.latLng(curcoor).distanceTo(prePoint); var lineDistanceStr = lineDistance > 1000 ? (lineDistance / 1000).toFixed(2) + "公里" : Math.ceil(lineDistance) + "米"; if (i == data.length - 1) { var pointAngle = L.Util.getAngleByLatLng( prePoint[1], prePoint[0], curcoor[1], curcoor[0] ); } } //添加分段信息 var oLabelObj = L.DomUtil.create("div", "measure-content"); var pointText = L.DomUtil.create("span", "measure-result-text"); pointText.innerHTML = lineDistanceStr; oLabelObj.appendChild(pointText); if (data.length > 1) { if (_this.tmpMarkers[data.length - 2]) { //如果最后一个点存在,更新最后一个点信息 _this.tmpMarkers[data.length - 2].setLatLng(data[data.length - 1]); _this.tmpMarkers[data.length - 2].label.setContent(oLabelObj); } else { //如果最后一个点不存在,创建点信息 var marker = L.marker(data[data.length - 1], { icon: L.divIcon({ className: "measuremarker", iconSize: [4, 4] }), }); marker.bindLabel(oLabelObj, { noHide: true, clickable: true, className: "measure-tip", offset: [0, 0], }); marker.addTo(_this._measureObjs[_this._lC]); _this.tmpMarkers.push(marker); } } }, /** * 通过坐标点计算面积 * @type {Function} * @returns {Number} 面积 * @private */ _getArea: function (_lc) { var _this = this; var latLngs = _this._measureObjs[_lc].measurePoints; var pointsCount = latLngs.length, area = 0.0, d2r = Math.PI / 180, p1, p2; if (pointsCount > 2) { for (var i = 0; i < pointsCount; i++) { p1 = latLngs[i]; p2 = latLngs[(i + 1) % pointsCount]; area += (p2[1] - p1[1]) * d2r * (2 + Math.sin(p1[0] * d2r) + Math.sin(p2[0] * d2r)); } area = (area * 6378137.0 * 6378137.0) / 2.0; } area = Math.abs(area); if (area > 1000000) { area = (area * 0.000001).toFixed(2) + " 平方公里"; } else { area = area.toFixed(2) + " 平方米"; } return area; }, latlngRectifying: function (e) { var _this = this; var curLatlngs = []; var curpx = e.layerPoint; var length = _this._measureObjs[_this._lC] ? _this._measureObjs[_this._lC].measurePoints.length : 0; var latlng = e.latlng; if (length > 0) { curLatlngs.push({ latlng: _this._measureObjs[_this._lC].measurePoints[0], px: _this._map.latLngToLayerPoint( _this._measureObjs[_this._lC].measurePoints[0] ), }); curLatlngs.push({ latlng: _this._measureObjs[_this._lC].measurePoints[length - 1], px: _this._map.latLngToLayerPoint( _this._measureObjs[_this._lC].measurePoints[length - 1] ), }); } for (var i = 0; i < curLatlngs.length; i++) { var dispx = Math.sqrt( (curpx.x - curLatlngs[i].px.x) * (curpx.x - curLatlngs[i].px.x) + (curpx.y - curLatlngs[i].px.y) * (curpx.y - curLatlngs[i].px.y) ); if (dispx < 10) { latlng = L.latLng(curLatlngs[i].latlng); latlng.reset = true; latlng.indexMarker = i; break; } } return latlng; }, _onClickPoint: function (e) { var _this = this; e.latlng = _this.latlngRectifying(e); if (!e.latlng.reset) { _this._measureObjs[_this._lC].measurePoints.push([ e.latlng.lat, e.latlng.lng, ]); } else { if (e.latlng.indexMarker == 0) { if (_this._measureObjs[_this._lC].polygon) { _this._measureObjs[_this._lC].measurePoints.push([ e.latlng.lat, e.latlng.lng, ]); _this._measureObjs[_this._lC].polygon.setLatLngs( _this._measureObjs[_this._lC].measurePoints ); _this._measureObjs[_this._lC].polygon.setStyle({ fillColor: "#f00", color: "#f00", weight: 0, fillOpacity: 0.3, }); } else { _this._measureObjs[_this._lC].removeLayer( _this._measureObjs[_this._lC].circle ); _this._measureObjs[_this._lC].removeLayer( _this._measureObjs[_this._lC].polyline ); } } else { _this._measureObjs[_this._lC].removeLayer( _this._measureObjs[_this._lC].polygon ); _this._measureObjs[_this._lC].polygon = null; } _this._onFinishClick(); } if ( _this._measureObjs[_this._lC].measurePoints.length == 1 && !_this._finished ) { var latlngs = [ [e.latlng.lat, e.latlng.lng], [e.latlng.lat, e.latlng.lng], ]; _this._measureObjs[_this._lC].polyline = L.polyline(latlngs, { color: "red", dashArray: 10, }).addTo(_this._measureObjs[_this._lC]); _this._measureObjs[_this._lC].circle = L.circle( [e.latlng.lat, e.latlng.lng], { radius: 0, color: "red", fillOpacity: 0 } ).addTo(_this._measureObjs[_this._lC]); } else { // _this._measureObjs[_this._lC].removeLayer(_this._measureObjs[_this._lC].circle); } }, _onFinishClick: function () { _this = this; //关闭地图双击事件 _this._map.doubleClickZoom.enable(); //监听地图单击事件 _this._map.off("click", _this._onClickPoint, this); //监听鼠标移动事件 _this._map.off("mousemove", _this._mousemove, this); _this.isNewElevation = true; _this._finished = true; _this._map.removeLayer(_this.moveMarker); _this.moveMarker = null; for (var i = 0; i < _this.tmpMarkers.length; i++) { _this._measureObjs[_this._lC].removeLayer(_this.tmpMarkers[i]); } _this.tmpMarkers = []; //根据点集合渲染marker点 var coorslength = _this._measureObjs[_this._lC].measurePoints.length; _this._measureObjs[_this._lC].markerObjs = []; var lineDistance = 0; if (coorslength > 1) { for (var i = 0; i < coorslength; i++) { var curcoor = _this._measureObjs[_this._lC].measurePoints[i]; var marker = L.marker(curcoor, { draggable: true, icon: L.divIcon({ className: "measuremarker", iconSize: [10, 10] }), }); if (i > 0) { var prePoint = _this._measureObjs[_this._lC].measurePoints[i - 1]; lineDistance += L.latLng(curcoor).distanceTo(prePoint); var lineDistanceStr = lineDistance > 1000 ? (lineDistance / 1000).toFixed(2) + "公里" : Math.ceil(lineDistance) + "米"; var pointAngle = L.Util.getAngleByLatLng( prePoint[1], prePoint[0], curcoor[1], curcoor[0] ); //添加分段信息 var oLabelObj = L.DomUtil.create("div", "measure-content"); var delLabel = L.DomUtil.create("div", "measure-ico-del"); var saveLabel = L.DomUtil.create("div", "measure-ico-save"); var pointText = L.DomUtil.create("span", "measure-result-text"); pointText.innerHTML = lineDistanceStr; delLabel.lC = _this._lC; saveLabel.lC = _this._lC; L.DomEvent.on(delLabel, "click", function (e) { L.DomEvent.stopPropagation(e); _this.del(delLabel.lC); }); L.DomEvent.on(saveLabel, "click", function (e) { L.DomEvent.stopPropagation(e); _this._map.fire("draw-result", { distance: _this._measureObjs[delLabel.lC].distance, points: _this._measureObjs[delLabel.lC].measurePoints, area: _this._measureObjs[delLabel.lC].area || 0, LC: delLabel.lC, }); }); if (i == coorslength - 1) { //测量面积 if (_this._measureObjs[_this._lC].polygon) { var area = _this._getArea(_this._lC); _this._measureObjs[_this._lC].area = area; pointText.innerHTML = lineDistanceStr + "
" + area; } oLabelObj.appendChild(delLabel); oLabelObj.appendChild(saveLabel); } oLabelObj.appendChild(pointText); marker.bindLabel(oLabelObj, { noHide: true, clickable: true, className: "measure-tip", offset: [0, 0], }); } marker.LC = _this._lC; marker.LIndex = i; marker.addTo(_this._measureObjs[_this._lC]); _this._measureObjs[_this._lC].markerObjs.push(marker); if (!(i == 0 && _this._measureObjs[_this._lC].polygon)) { marker.on("move", function (e) { _this._renderMeasure({ LC: e.target.LC, LIndex: e.target.LIndex, latlng: e.latlng, }); }); } } } else { var curcoor = _this._measureObjs[_this._lC].measurePoints[0]; var myIcon = L.icon({ iconUrl: this.options.iconUrl, iconSize: [25, 41], iconAnchor: [12, 41], }); var marker = L.marker(curcoor, { draggable: true, icon: myIcon }); var oLabelObj = L.DomUtil.create("div", "measure-content"); var delLabel = L.DomUtil.create("div", "measure-ico-del"); var saveLabel = L.DomUtil.create("div", "measure-ico-save"); delLabel.lC = _this._lC; saveLabel.lC = _this._lC; L.DomEvent.on(delLabel, "click", function (e) { L.DomEvent.stopPropagation(e); _this.del(delLabel.lC); }); L.DomEvent.on(saveLabel, "click", function (e) { L.DomEvent.stopPropagation(e); _this._map.fire("draw-result", { distance: _this._measureObjs[delLabel.lC].distance, points: _this._measureObjs[delLabel.lC].measurePoints, area: _this._measureObjs[delLabel.lC].area || 0, LC: delLabel.lC, }); }); oLabelObj.appendChild(delLabel); oLabelObj.appendChild(saveLabel); marker.bindLabel(oLabelObj, { noHide: true, clickable: true, className: "measure-tip", offset: [0, 0], }); marker.LC = _this._lC; marker.LIndex = i; marker.addTo(_this._measureObjs[_this._lC]); _this._measureObjs[_this._lC].markerObjs.push(marker); } _this._measureObjs[_this._lC].distance = lineDistance; }, _renderMeasure: function (data) { var _this = this; var latlng = [data.latlng.lat, data.latlng.lng]; if (_this._measureObjs[data.LC].measurePoints.length == 1) { return false; } _this._measureObjs[data.LC].measurePoints[data.LIndex] = latlng; var curlength = _this._measureObjs[data.LC].measurePoints.length; //如果是面,第一个点和最后一个点位置同时改变 if (_this._measureObjs[data.LC].polygon) { if (data.LIndex == 0) { _this._measureObjs[data.LC].measurePoints[curlength - 1] = latlng; _this._measureObjs[_this._lC].markerObjs[curlength - 1].setLatLng( latlng ); } if (data.LIndex == curlength - 1) { _this._measureObjs[data.LC].measurePoints[0] = latlng; _this._measureObjs[_this._lC].markerObjs[0].setLatLng(latlng); } } var points = _this._measureObjs[data.LC].measurePoints; //更新circle var radius = L.latLng(points[1]).distanceTo(L.latLng(points[0])); _this._measureObjs[data.LC].circle.setRadius(radius); _this._measureObjs[data.LC].circle.setLatLng(points[0]); if (points.length == 2) { _this._measureObjs[data.LC].circle.setStyle({ opacity: 1, }); } //更新线 _this._measureObjs[data.LC].polyline.setLatLngs(points); //更新面 if (_this._measureObjs[data.LC].polygon) { _this._measureObjs[data.LC].polygon.setLatLngs([points]); } var lineDistance = 0; var coorslength = _this._measureObjs[data.LC].measurePoints.length; for (var i = 1; i < coorslength; i++) { var curcoor = _this._measureObjs[data.LC].measurePoints[i]; var prePoint = _this._measureObjs[data.LC].measurePoints[i - 1]; lineDistance += L.latLng(curcoor).distanceTo(prePoint); var lineDistanceStr = lineDistance > 1000 ? (lineDistance / 1000).toFixed(2) + "公里" : Math.ceil(lineDistance) + "米"; var pointAngle = L.Util.getAngleByLatLng( prePoint[1], prePoint[0], curcoor[1], curcoor[0] ); //添加分段信息 var oLabelObj = L.DomUtil.create("div", "measure-content"); var delLabel = L.DomUtil.create("div", "measure-ico-del"); var saveLabel = L.DomUtil.create("div", "measure-ico-save"); var pointText = L.DomUtil.create("span", "measure-result-text"); pointText.innerHTML = lineDistanceStr; delLabel.lC = _this._lC; saveLabel.lC = _this._lC; L.DomEvent.on(delLabel, "click", function (e) { L.DomEvent.stopPropagation(e); _this.del(delLabel.lC); }); L.DomEvent.on(saveLabel, "click", function (e) { L.DomEvent.stopPropagation(e); _this._map.fire("draw-result", { distance: _this._measureObjs[delLabel.lC].distance, points: _this._measureObjs[delLabel.lC].measurePoints, area: _this._measureObjs[delLabel.lC].area || 0, LC: delLabel.lC, }); }); if (i == coorslength - 1) { oLabelObj.appendChild(delLabel); oLabelObj.appendChild(saveLabel); //测量面积 try { if (_this._measureObjs[data.LC].polygon) { var area = _this._getArea(data.LC); _this._measureObjs[data.LC].area; pointText.innerHTML = lineDistanceStr + "
" + area; } } catch (e) { console.error("leaflet.draw.js 测量面积error:", e); } } oLabelObj.appendChild(pointText); _this._measureObjs[_this._lC].distance = lineDistance; _this._measureObjs[data.LC].markerObjs[i].label.setContent(oLabelObj); } }, /** * 删除对应lC的测距 */ del: function (lC) { var _this = this; if (_this._measureObjs[lC]) { _this._measureGroup.removeLayer(_this._measureObjs[lC]); delete _this._measureObjs[lC]; } }, }); /** * 测量工具 */ map2DViewer.drawToolFire = function (data) { }; map2DViewer.setDrawTool = function (options) { mousemoveStatus = true; var defaultData = { action: "add", position: "topleft", offset: [10, 10], background: "#fff", color: "#000", font_size: "14px", closeButton: true, }; _.merge(defaultData, options); switch (defaultData.action) { case "add": this._map = defaultData.map; this.measureTool = new L.Control.Draw({ position: defaultData.position, offset: defaultData.offset, background: defaultData.background, color: defaultData.color, font_size: defaultData.font_size, closeButton: defaultData.closeButton, iconUrl: "/static/plugins/draw-plugin/images/marker-icon.png", }).addTo(this._map); this._map.on("draw-result", map2DViewer.drawToolFire); return this.distanceTool; case "remove": this._map.off("draw-result", map2DViewer.drawToolFire); if (this.measureTool) { // 移除绘制的图形 this.measureTool._measureGroup && this.measureTool._measureGroup.remove(); mousemoveStatus = false; this._map.doubleClickZoom.disable(); this._map.off("click"); if (this.measureTool.moveMarker) { this._map.removeLayer(this.measureTool.moveMarker); this.measureTool.moveMarker = null; } this.measureTool.remove(); this.measureTool = null map2DViewer.measureTool = null; } break; case "start": this.measureTool.start(); break; } };