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];
}
}
});