let mousemove2Status = true; let LControlDraw = L.Control.extend({ //是否初始化 _initialized: false, //统计 _lC: 0, //测量对象集合 _measureObjs: {}, //是否完成当前测绘 _finished: true, //新测量 isNewElevation: true, moveMarker: false, //测量参数 options: { position: "topright", autoZIndex: true, offset: [0, 0], 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 (mousemove2Status) { 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 () { let _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("draw2-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("draw2-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("draw2-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]; } } });