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