L.Control.MeasureDistance = L.Control.extend({
//是否初始化
_initialized:false,
//统计
_lC:0,
//测
_measureObjs:{},
//是否完成当前测绘
_finished:true,
isNewElevation:true,
options:{
position:'topright',
autoZIndex:true,
offset:[10,10],
background:"#000",
color:"#fff",
size:14,
closeButton:true
},
initialize:function(options){
L.setOptions(this, options);
return this;
},
onAdd:function(map){
this._map = map;
this._createControl();
this._map.on('measure-area-start',this.stop,this);
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-distance');
var link = L.DomUtil.create('a','leaflet-control-measure-distance-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){
if(_this._measureObjs[_this._lC].distancePoints.length > 0){
_this._onFinishClick();
}
_this._finished = true;
L.DomUtil.removeClass(_this._container,'active');
_this._removeMeasureGroup();
map2DViewer.map.fire('measure-distance-stop');
map2DViewer.map.getContainer().style.cursor = 'auto';
}else {
_this._finished = false;
L.DomUtil.addClass(_this._container,'active');
_this._addMeasureGroup();
map2DViewer.map.fire('measure-distance-start');
if(L.Browser.ie || L.Browser.firefox){
_this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur),auto';
}else{
_this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur) 5 5,auto';
}
}
})
_this.start();
},
start:function(){
var _this = this;
if(!_this._finished){
if(_this._measureObjs[_this._lC].distancePoints.length > 0){
_this._onFinishClick();
}
_this._finished = true;
L.DomUtil.removeClass(_this._container,'active');
_this._removeMeasureGroup();
map2DViewer.map.fire('measure-distance-stop');
}
_this._finished = false;
L.DomUtil.addClass(_this._container,'active');
_this._addMeasureGroup();
map2DViewer.map.fire('measure-distance-start');
if(L.Browser.ie || L.Browser.firefox){
_this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur),auto';
}else{
_this._map.getContainer().style.cursor = 'url('+L.DefaultImagePath+'/cur-ruler.cur) 5 5,auto';
}
_this._map.doubleClickZoom.disable();
},
stopMasuring:function(){
var _this = this;
_this._finished = true;
L.DomUtil.removeClass(_this._container,'active');
_this._removeMeasureGroup();
map2DViewer.map.getContainer().style.cursor = 'auto';
},
stop:function(){
var _this = this;
if(!_this._finished){
if(_this._measureObjs[_this._lC].distancePoints.length > 0){
_this._onFinishClick();
}
_this._finished = true;
L.DomUtil.removeClass(_this._container,'active');
_this._removeMeasureGroup();
map2DViewer.map.fire('measure-distance-stop');
map2DViewer.map.getContainer().style.cursor = 'auto';
}
},
measurePoints:function(startPoint,endPoint){
var _this = this;
_this.start();
_this._onClickPoint({latlng:startPoint});
_this._onClickPoint({latlng:endPoint});
},
updatelC:function(lC,startPoint,endPoint){
var _this = this;
_this._measureObjs[lC].distancePoints = [startPoint,endPoint];
_this._measureObjs[lC].linePoints = [startPoint,endPoint];
_this._measureObjs[lC].lineDistance = new L.LatLng(startPoint[0],startPoint[1]).distanceTo(new L.LatLng(endPoint[0],endPoint[1]));
var newPos = _this._getCurvePoints([new L.LatLng(startPoint[0],startPoint[1]),new L.LatLng(endPoint[0],endPoint[1])]);
_this._measureObjs[lC].polyLine.setLatLngs(newPos);
_this._measureObjs[lC].polyLine.redraw();
_this._measureObjs[lC].resultMarker.setLatLng(new L.LatLng(endPoint[0],endPoint[1]));
var lineDistance = _this._measureObjs[lC].lineDistance;
var lineDistanceStr = lineDistance > 1000 ? (lineDistance / 1000).toFixed(2) + '公里' : Math.ceil(lineDistance) + '米';
var pointAngle = L.Util.getAngleByLatLng(startPoint[1],startPoint[0],endPoint[1],endPoint[0]);
pointAngle += '度';
//添加结束信息
var pointText = L.DomUtil.create('div','measure-distance-result-text');
pointText.innerHTML = lineDistanceStr+'
'+pointAngle;
pointText.lC = _this._lC;
L.DomEvent.on(pointText, 'dblclick', function(e) {
L.DomEvent.stopPropagation(e);
_this.del(pointText.lC)
});
_this._measureObjs[lC].removeLayer(_this._measureObjs[lC].resultMarker);
_this._measureObjs[lC].resultMarker = L.marker(endPoint,{icon:L.divIcon({iconSize: [5, 5]})}).bindLabel(pointText,
{noHide: true,clickable: true,className:'measure-distance-tip',offset:[0,0]}
).addTo(_this._measureObjs[lC]);
map2DViewer.map.fire('measure-distance-result',{lC:lC,distance:lineDistanceStr,angle:pointAngle,distancePoints:_this._measureObjs[lC].distancePoints});
},
/**
* 清除所有的量算
* @return {[type]} [description]
*/
cleanAllMeasure:function(){
var _this = this;
for(var item in _this._measureObjs){
_this.del(item);
}
},
_addMeasureGroup:function(){
var _this = this;
if(!_this._initialized){
_this._measureGroup = new L.featureGroup();
_this._measureGroup.addTo(map2DViewer.map);
_this._initialized = true;
}
map2DViewer.map.doubleClickZoom.disable();
map2DViewer.map.on('click',_this._onClickPoint,this);
},
_removeMeasureGroup:function(){
var _this = this;
// map2DViewer.map.getContainer().style.cursor = 'auto';
map2DViewer.map.off('mousemove',_this._onMoveLine,this);
map2DViewer.map.off('click',_this._onClickPoint,this);
},
_restartMearing:function(){
var _this = this;
map2DViewer.map.doubleClickZoom.disable();
map2DViewer.map.on('click',_this._onClickPoint,this);
if (L.Browser.ie || L.Browser.firefox) {
_this._map.getContainer().style.cursor = 'url(' + L.DefaultImagePath + '/cur-ruler.cur),auto';
} else {
_this._map.getContainer().style.cursor = 'url(' + L.DefaultImagePath + '/cur-ruler.cur) 5 5,auto';
}
},
/**
* 鼠标单击事件,如果是第一次,则设置为初始点 如果产生第二个点表示测量完成
* @param e
* @returns {boolean}
* @private
*/
_onClickPoint:function(e){
var _this = this;
e.latlng = L.Util.formatEarthLatLng(e.latlng);
if(_this.isNewElevation){
_this._lC++;
_this._measureObjs[_this._lC] = new L.FeatureGroup();
_this._measureObjs[_this._lC].tempLine = new L.Polyline([[0,0],[0,0]],{clickable:false,color:'#ff0000',weight:2,opacity:1}).addTo(_this._measureObjs[_this._lC]);
_this._measureObjs[_this._lC].addTo(_this._measureGroup);
_this._measureObjs[_this._lC].distancePoints = [];
_this._measureObjs[_this._lC].linePoints = [];
_this._measureObjs[_this._lC].lineDistance = 0;
_this.isNewElevation = false;
}
if(_this._measureObjs[_this._lC].distancePoints.length > 0){
_this.dblclickFirst = true;
_this._measureObjs[_this._lC].distancePoints.push(e.latlng);
var _sPoint = _this._measureObjs[_this._lC].distancePoints[_this._measureObjs[_this._lC].distancePoints.length-2];
var qPoints = _this._getCurvePoints([_sPoint, e.latlng]);
_this._measureObjs[_this._lC].linePoints.push(qPoints);
var lineDistance = _sPoint.distanceTo(e.latlng) + _this._measureObjs[_this._lC].lineDistance;
_this._measureObjs[_this._lC].lineDistance = lineDistance;
var _lastPoint = _this._measureObjs[_this._lC].distancePoints[_this._measureObjs[_this._lC].distancePoints.length-1];
_this._measureObjs[_this._lC].lineDistance = lineDistance;
var lineDistanceStr = lineDistance > 1000 ? (lineDistance / 1000).toFixed(2) + '公里' : Math.ceil(lineDistance) + '米';
var pointAngle = L.Util.getAngleByLatLng(_sPoint.lng,_sPoint.lat,_lastPoint.lng,_lastPoint.lat);
//添加结束信息
var oLabelObj = L.DomUtil.create('div','measure-distance-content');
var delLabel = L.DomUtil.create('span','distance-ico-del');
var pointText = L.DomUtil.create('span','measure-distance-result-text');
delLabel.innerHTML = '删除';
delLabel.lC = _this._lC;
L.DomEvent.on(delLabel, 'click', function(e) {
L.DomEvent.stopPropagation(e);
_this.del(delLabel.lC)
});
pointText.innerHTML = lineDistanceStr+'
'+pointAngle+'度';
pointText.lC = _this._lC;
oLabelObj.appendChild(pointText);
_this._measureObjs[_this._lC].resultMarker = _this._buildMarker(_lastPoint).bindLabel(oLabelObj,
{noHide: true,clickable: true,className:'measure-distance-tip',offset:[0,0]}
).addTo(_this._measureObjs[_this._lC]);
_this._onMoveLine(e)
}else {
_this._measureObjs[_this._lC].resultMarker = _this._buildMarker(e.latlng).addTo(_this._measureObjs[_this._lC]);
_this._measureObjs[_this._lC].distancePoints.push(e.latlng);
map2DViewer.map.on('mousemove',_this._onMoveLine,this);
}
_this.editerCSS();
},
/**
* 创建一个marker 并返回该marker
* @type {Function}
* @param obj {Object} {latlng}
* @returns {L.Marker}
* @private
*/
_buildMarker:function(obj){
var _this = this;
var marker = L.marker(
obj,
{icon: L.divIcon({
iconSize: [5, 5]
})}
);
marker.on('click',function(e){
if(_this._measureObjs[_this._lC].distancePoints.length<2){
return false;
}
//与上一个点相同,测量完成
if(e.latlng == _this._measureObjs[_this._lC].distancePoints[_this._measureObjs[_this._lC].distancePoints.length-1] ){
_this._onFinishClick(e);
return false;
}
});
return marker;
},
/**
* 给起始点和目的点的鼠标画线
* @type {Function}
* @param e
* @private
*/
_onMoveLine:function(e){
var _this = this;
if(_this._measureObjs[_this._lC].distancePoints.length > 0){
var length = _this._measureObjs[_this._lC].distancePoints.length;
var _startPoint = _this._measureObjs[_this._lC].distancePoints[length-2];
var _endPoint = e.latlng;
_this._drawLine(_startPoint,_endPoint);
}
},
/**
* 更新画线
* @type {Function}
* @param start {Object} 开始点
* @param end {Object} 结束点
* @private
*/
_drawLine:function(start,end){
var _this = this;
_this._measureObjs[_this._lC].distancePoints.push(end);
var newPos = _this._measureObjs[_this._lC].distancePoints;
_this._measureObjs[_this._lC].tempLine.setLatLngs(newPos);
_this._measureObjs[_this._lC].tempLine.redraw();
var length = _this._measureObjs[_this._lC].distancePoints.length;
_this._measureObjs[_this._lC].distancePoints.splice(length-1,1);
},
_upDateLine:function(lC){
var _this = this;
var linePoints = _this._measureObjs[_this._lC].linePoints;
var allPoints = [];
for(var i = 0,l=linePoints.length;i 1000 ? (lineDistance / 1000).toFixed(2) + '公里' : Math.ceil(lineDistance) + '米';
var pointAngle = L.Util.getAngleByLatLng(_sPoint.lng,_sPoint.lat,_lastPoint.lng,_lastPoint.lat);
//添加结束信息
var oLabelObj = L.DomUtil.create('div','measure-distance-content');
var delLabel = L.DomUtil.create('div','distance-ico-del');
var pointText = L.DomUtil.create('span','measure-distance-result-text');
//delLabel.innerHTML = '删除';
delLabel.lC = _this._lC;
L.DomEvent.on(delLabel, 'click', function(e) {
L.DomEvent.stopPropagation(e);
_this.del(delLabel.lC)
});
pointText.innerHTML = lineDistanceStr+'
'+pointAngle+'度';
pointText.lC = _this._lC;
L.DomEvent.on(pointText, 'dblclick', function(e) {
L.DomEvent.stopPropagation(e);
_this.del(pointText.lC)
});
oLabelObj.appendChild(pointText);
if(_this.options.closeButton){
oLabelObj.appendChild(delLabel);
}
_this._measureObjs[_this._lC].resultMarker.unbindLabel();
_this._measureObjs[_this._lC].resultMarker = L.marker(_lastPoint,{icon:L.divIcon({iconSize: [5, 5]})}).bindLabel(oLabelObj,
{noHide: true,clickable: true,className:'measure-distance-tip',offset:[0,0]}
).addTo(_this._measureObjs[_this._lC]);
}
map2DViewer.map.off('mousemove',_this._onMoveLine,this);
_this.isNewElevation = true;
_this.editerCSS();
_this.stopMasuring();
_this.start();
},
/**
* 修改测距样式
*/
editerCSS:function(){
var _this = this;
$(".measure-distance-content span").css({
"color":_this.options.color,
})
$(".measure-distance-content span").css({
"font-size":_this.options.font_size,
})
$(".measure-distance-content").css({
// "background":_this.options.background
"background":'rgba(255,255,255,0.5)'
});
},
/**
* 合并样式
*/
addCss:function(options){
var _this = this;
_.merge(this.options, options);
_this.editerCSS();
},
/**
* 删除对应lC的测距
*/
del:function(lC){
var _this = this;
if(_this._measureObjs[lC]){
_this._measureGroup.removeLayer(_this._measureObjs[lC]);
delete _this._measureObjs[lC];
map2DViewer.map.fire('measure-distance-delete',{lC:lC});
}
},
/**
* 获取弧线的节点坐标数组
* @type {Function}
* @param points
* @returns {Array}
* @private
*/
_getCurvePoints:function(points){
var _this = this;
var curvePoints = [];
for(var i = 0; i < points.length-1;i++){
if(points[i]['lat'] == points[i+1]['lat'] && points[i]['lng'] == points[i+1]['lng']){
curvePoints = curvePoints.concat(points[i]);
}else {
var p = _this._getCurve(points[i],points[i+1],20);
if(p && p.length > 0){
curvePoints = curvePoints.concat(p);
}
}
}
return curvePoints;
},
/**
* 根据两点获取曲线坐标点数组
* @type {Function}
* @param start {Object} 起点
* @param finish {Object} 终点
* @param segments {Number} 拐点数量
* @returns {*}
* @private
*/
_getCurve:function(start,finish,segments){
var startlat = start.lat;
var startlon = start.lng;
var finishlat = finish.lat;
var finishlon = finish.lng;
var segments = segments;
var curveAry = [];
var lat1 = startlat * (Math.PI / 180);
var lon1 = startlon * (Math.PI / 180);
var lat2 = finishlat * (Math.PI / 180);
var lon2 = finishlon * (Math.PI / 180);
var d = 2 * Math.asin(Math.sqrt(Math.pow((Math.sin((lat1-lat2)/2)),2)+Math.cos(lat1)*Math.cos(lat2)*Math.pow((Math.sin((lon1-lon2)/2)),2)));
for(var n= 0; n