refs #34 replace leaflet.measurecontrol with Leaflet.LinearMeasurement
parent
409d71d363
commit
030fe798e7
|
@ -0,0 +1,90 @@
|
||||||
|
.icon-active {
|
||||||
|
background-color: #ffc !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-ruler {
|
||||||
|
cursor: pointer;
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADVSURBVCiRndIxSkMBEIThb18eSLCwV7DRIiRH8AZaWtnYeQIPINhbWIh9Kg+hCN4hEQsLUawsRBFEhLXZgEgUngvT/bOzDBuZqes0nR1dTRHRQPsH0McAw9IIlzhuC+hh7QewjEdco4dTbEMTEQOc4xBbuMcrdrGEE6ziCusVYBEXWKj4Po5q+0ZmmgljDNrMfIuIp9q2g/fM3I+IwENEbNa5w2JWIjNFxAHucFvAqEp4wRST0k1mfszam2LvG3CGSWY+z222ktrM/Pyt/rmmrvOvN/oCjRNGEaC8yE0AAAAASUVORK5CYII=') !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ruler-map {
|
||||||
|
cursor: crosshair !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-popup {
|
||||||
|
width: auto !important;
|
||||||
|
height: auto !important;
|
||||||
|
padding-left: 15px;
|
||||||
|
margin-top: -10px !important;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-popup-content {
|
||||||
|
padding: 1px 7px;
|
||||||
|
background-color: #4D90FE;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
|
.poly-close {
|
||||||
|
display:none;
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
.poly-close {
|
||||||
|
display: inline;
|
||||||
|
margin-left: 10px;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
svg {
|
||||||
|
width: 15px;
|
||||||
|
height: 10px;
|
||||||
|
position: relative !important;
|
||||||
|
top: 0px !important;
|
||||||
|
left: 5px !important;
|
||||||
|
path {
|
||||||
|
stroke: white;
|
||||||
|
fill: transparent;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-width: 7;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-popup-label {
|
||||||
|
padding: 0px;
|
||||||
|
padding-top: 10px;
|
||||||
|
background-color: transparent;
|
||||||
|
text-shadow: 1px 1px 0px rgba(255, 255, 255, 1);
|
||||||
|
color: #4D90FE;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 10px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-label {
|
||||||
|
top: -25px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.azimut {
|
||||||
|
color: blue;
|
||||||
|
text-shadow: 1px 1px 0px white;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.azimut-final {
|
||||||
|
text-shadow: none;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
.leaflet-control-draw-measure {
|
|
||||||
background-image: url(images/measure-control.png);
|
|
||||||
}
|
|
|
@ -0,0 +1,634 @@
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
L.Control.LinearMeasurement = L.Control.extend({
|
||||||
|
|
||||||
|
options: {
|
||||||
|
position: 'topleft',
|
||||||
|
unitSystem: 'imperial', // imperial | metric
|
||||||
|
color: '#4D90FE',
|
||||||
|
contrastingColor: '#fff',
|
||||||
|
show_last_node: false,
|
||||||
|
show_azimut: false
|
||||||
|
},
|
||||||
|
|
||||||
|
clickSpeed: 300,
|
||||||
|
|
||||||
|
onAdd: function (map) {
|
||||||
|
var container = L.DomUtil.create('div', 'leaflet-control leaflet-bar'),
|
||||||
|
link = L.DomUtil.create('a', 'icon-ruler', container),
|
||||||
|
map_container = map.getContainer(),
|
||||||
|
me = this;
|
||||||
|
|
||||||
|
link.href = '#';
|
||||||
|
link.title = 'Toggle measurement tool';
|
||||||
|
|
||||||
|
L.DomEvent.on(link, 'click', L.DomEvent.stop).on(link, 'click', function(){
|
||||||
|
if(L.DomUtil.hasClass(link, 'icon-active')){
|
||||||
|
me.resetRuler(!!me.mainLayer);
|
||||||
|
L.DomUtil.removeClass(link, 'icon-active');
|
||||||
|
L.DomUtil.removeClass(map_container, 'ruler-map');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
me.initRuler();
|
||||||
|
L.DomUtil.addClass(link, 'icon-active');
|
||||||
|
L.DomUtil.addClass(map_container, 'ruler-map');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function contrastingColor(color){
|
||||||
|
return (luma(color) >= 165) ? '000' : 'fff';
|
||||||
|
}
|
||||||
|
|
||||||
|
function luma(color){
|
||||||
|
var rgb = (typeof color === 'string') ? hexToRGBArray(color) : color;
|
||||||
|
return (0.2126 * rgb[0]) + (0.7152 * rgb[1]) + (0.0722 * rgb[2]); // SMPTE C, Rec. 709 weightings
|
||||||
|
}
|
||||||
|
|
||||||
|
function hexToRGBArray(color){
|
||||||
|
if (color.length === 3)
|
||||||
|
color = color.charAt(0) + color.charAt(0) + color.charAt(1) + color.charAt(1) + color.charAt(2) + color.charAt(2);
|
||||||
|
else if (color.length !== 6)
|
||||||
|
throw('Invalid hex color: ' + color);
|
||||||
|
var rgb = [];
|
||||||
|
for (var i = 0; i <= 2; i++)
|
||||||
|
rgb[i] = parseInt(color.substr(i * 2, 2), 16);
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.options.color && this.options.color.indexOf('#') === -1){
|
||||||
|
this.options.color = '#' + this.options.color;
|
||||||
|
} else if(!this.options.color){
|
||||||
|
this.options.color = '#4D90FE';
|
||||||
|
}
|
||||||
|
|
||||||
|
var originalColor = this.options.color.replace('#', '');
|
||||||
|
|
||||||
|
this.options.contrastingColor = '#'+contrastingColor(originalColor);
|
||||||
|
|
||||||
|
return container;
|
||||||
|
},
|
||||||
|
|
||||||
|
onRemove: function(map){
|
||||||
|
this.resetRuler(!!this.mainLayer);
|
||||||
|
},
|
||||||
|
|
||||||
|
initRuler: function(){
|
||||||
|
var me = this,
|
||||||
|
map = this._map;
|
||||||
|
|
||||||
|
this.mainLayer = L.featureGroup();
|
||||||
|
this.mainLayer.addTo(this._map);
|
||||||
|
|
||||||
|
map.touchZoom.disable();
|
||||||
|
map.doubleClickZoom.disable();
|
||||||
|
map.boxZoom.disable();
|
||||||
|
map.keyboard.disable();
|
||||||
|
|
||||||
|
if(map.tap) {
|
||||||
|
map.tap.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dblClickEventFn = function(e){
|
||||||
|
L.DomEvent.stop(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clickEventFn = function(e){
|
||||||
|
if(me.clickHandle){
|
||||||
|
clearTimeout(me.clickHandle);
|
||||||
|
me.clickHandle = 0;
|
||||||
|
|
||||||
|
if(me.options.show_last_node){
|
||||||
|
me.preClick(e);
|
||||||
|
me.getMouseClickHandler(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
me.getDblClickHandler(e);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
me.preClick(e);
|
||||||
|
|
||||||
|
me.clickHandle = setTimeout(function(){
|
||||||
|
me.getMouseClickHandler(e);
|
||||||
|
me.clickHandle = 0;
|
||||||
|
|
||||||
|
}, me.clickSpeed);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.moveEventFn = function(e){
|
||||||
|
if(!me.clickHandle){
|
||||||
|
me.getMouseMoveHandler(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
map.on('click', this.clickEventFn, this);
|
||||||
|
map.on('mousemove', this.moveEventFn, this);
|
||||||
|
|
||||||
|
this.resetRuler();
|
||||||
|
},
|
||||||
|
|
||||||
|
initLayer: function(){
|
||||||
|
this.layer = L.featureGroup();
|
||||||
|
this.layer.addTo(this.mainLayer);
|
||||||
|
this.layer.on('selected', this.layerSelected);
|
||||||
|
this.layer.on('click', this.clickEventFn, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
resetRuler: function(resetLayer){
|
||||||
|
var map = this._map;
|
||||||
|
|
||||||
|
if(resetLayer){
|
||||||
|
map.off('click', this.clickEventFn, this);
|
||||||
|
map.off('mousemove', this.moveEventFn, this);
|
||||||
|
|
||||||
|
if(this.mainLayer){
|
||||||
|
this._map.removeLayer(this.mainLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mainLayer = null;
|
||||||
|
|
||||||
|
this._map.touchZoom.enable();
|
||||||
|
this._map.boxZoom.enable();
|
||||||
|
this._map.keyboard.enable();
|
||||||
|
|
||||||
|
if(this._map.tap) {
|
||||||
|
this._map.tap.enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.layer = null;
|
||||||
|
this.prevLatlng = null;
|
||||||
|
this.poly = null;
|
||||||
|
this.multi = null;
|
||||||
|
this.latlngs = null;
|
||||||
|
this.latlngsList = [];
|
||||||
|
this.sum = 0;
|
||||||
|
this.distance = 0;
|
||||||
|
this.separation = 1;
|
||||||
|
this.last = 0;
|
||||||
|
this.fixedLast = 0;
|
||||||
|
this.totalIcon = null;
|
||||||
|
this.total = null;
|
||||||
|
this.lastCircle = null;
|
||||||
|
|
||||||
|
/* Leaflet return distances in meters */
|
||||||
|
this.UNIT_CONV = 1000;
|
||||||
|
this.SUB_UNIT_CONV = 1000;
|
||||||
|
this.UNIT = 'km';
|
||||||
|
this.SUB_UNIT = 'm';
|
||||||
|
|
||||||
|
if(this.options.unitSystem === 'imperial'){
|
||||||
|
this.UNIT_CONV = 1609.344;
|
||||||
|
this.SUB_UNIT_CONV = 5280;
|
||||||
|
this.UNIT = 'mi';
|
||||||
|
this.SUB_UNIT = 'ft';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.measure = {
|
||||||
|
scalar: 0,
|
||||||
|
unit: this.SUB_UNIT
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
cleanUpMarkers: function(fixed){
|
||||||
|
var layer = this.layer;
|
||||||
|
|
||||||
|
if(layer){
|
||||||
|
layer.eachLayer(function(l){
|
||||||
|
if(l.options && l.options.type === 'tmp'){
|
||||||
|
if(fixed){
|
||||||
|
l.options.type = 'fixed';
|
||||||
|
} else {
|
||||||
|
layer.removeLayer(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
cleanUpFixed: function(){
|
||||||
|
var layer = this.layer;
|
||||||
|
|
||||||
|
if(layer) {
|
||||||
|
layer.eachLayer(function(l){
|
||||||
|
if(l.options && (l.options.type === 'fixed')){
|
||||||
|
layer.removeLayer(l);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
convertDots: function(){
|
||||||
|
var me = this,
|
||||||
|
layer = this.layer;
|
||||||
|
|
||||||
|
if(layer) {
|
||||||
|
layer.eachLayer(function(l){
|
||||||
|
if(l.options && (l.options.type === 'dot')){
|
||||||
|
|
||||||
|
var m = l.options.marker,
|
||||||
|
i = m ? m.options.icon.options : null,
|
||||||
|
il = i ? i.html : '';
|
||||||
|
|
||||||
|
if(il && il.indexOf(me.measure.unit) === -1){
|
||||||
|
var str = l.options.label,
|
||||||
|
s = str.split(' '),
|
||||||
|
e = parseFloat(s[0]),
|
||||||
|
u = s[1],
|
||||||
|
label = '';
|
||||||
|
|
||||||
|
if(l.options.label.indexOf(me.measure.unit) !== -1){
|
||||||
|
label = l.options.label;
|
||||||
|
|
||||||
|
} else if(u === me.UNIT){
|
||||||
|
label = (e * me.SUB_UNIT_CONV).toFixed(2) + ' ' + me.SUB_UNIT;
|
||||||
|
|
||||||
|
} else if(u === me.SUB_UNIT){
|
||||||
|
label = (e / me.SUB_UNIT_CONV).toFixed(2) + ' ' + me.UNIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cicon = L.divIcon({
|
||||||
|
className: 'total-popup-label',
|
||||||
|
html: label
|
||||||
|
});
|
||||||
|
|
||||||
|
m.setIcon(cicon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
displayMarkers: function(latlngs, multi, sum) {
|
||||||
|
var x, y, label, ratio, p,
|
||||||
|
latlng = latlngs[latlngs.length-1],
|
||||||
|
prevLatlng = latlngs[0],
|
||||||
|
original = prevLatlng.distanceTo(latlng)/this.UNIT_CONV,
|
||||||
|
dis = original;
|
||||||
|
|
||||||
|
var p2 = this._map.latLngToContainerPoint(latlng),
|
||||||
|
p1 = this._map.latLngToContainerPoint(prevLatlng),
|
||||||
|
unit = 1;
|
||||||
|
|
||||||
|
if(this.measure.unit === this.SUB_UNIT){
|
||||||
|
unit = this.SUB_UNIT_CONV;
|
||||||
|
dis = dis * unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
var t = (sum * unit) + dis,
|
||||||
|
qu = sum * unit;
|
||||||
|
|
||||||
|
for(var q = Math.floor(qu); q < t; q++){
|
||||||
|
ratio = (t-q) / dis;
|
||||||
|
|
||||||
|
if(q % this.separation || q < qu) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = (p2.x - ratio * (p2.x - p1.x));
|
||||||
|
y = (p2.y - ratio * (p2.y - p1.y));
|
||||||
|
|
||||||
|
p = L.point(x, y);
|
||||||
|
|
||||||
|
/* render a circle spaced by separation */
|
||||||
|
|
||||||
|
latlng = this._map.containerPointToLatLng(p);
|
||||||
|
|
||||||
|
label = (q + ' ' + this.measure.unit);
|
||||||
|
|
||||||
|
this.renderCircle(latlng, 0, this.layer, multi ? 'fixed' : 'tmp', label);
|
||||||
|
|
||||||
|
this.last = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
return original;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderCircle: function(latLng, radius, layer, type, label) {
|
||||||
|
var color = this.options.color,
|
||||||
|
lineColor = this.options.color,
|
||||||
|
azimut = '',
|
||||||
|
nodeCls = '';
|
||||||
|
|
||||||
|
type = type || 'circle';
|
||||||
|
|
||||||
|
linesHTML = [];
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
color: lineColor,
|
||||||
|
fillOpacity: 1,
|
||||||
|
opacity: 1,
|
||||||
|
fill: true,
|
||||||
|
type: type
|
||||||
|
};
|
||||||
|
|
||||||
|
var a = this.prevLatlng ? this._map.latLngToContainerPoint(this.prevLatlng) : null,
|
||||||
|
b = this._map.latLngToContainerPoint(latLng);
|
||||||
|
|
||||||
|
if(type === 'dot'){
|
||||||
|
nodeCls = 'node-label';
|
||||||
|
|
||||||
|
if(a && this.options.show_azimut){
|
||||||
|
azimut = ' <span class="azimut"> '+this.lastAzimut+'°</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p_latLng = this._map.containerPointToLatLng(b);
|
||||||
|
|
||||||
|
if(label){
|
||||||
|
var cicon = L.divIcon({
|
||||||
|
className: 'total-popup-label ' + nodeCls,
|
||||||
|
html: '<span style="color: '+color+';">'+label+azimut+'</span>'
|
||||||
|
});
|
||||||
|
|
||||||
|
options.icon = cicon;
|
||||||
|
options.marker = L.marker(p_latLng, { icon: cicon, type: type }).addTo(layer);
|
||||||
|
options.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
var circle = L.circleMarker(latLng, options);
|
||||||
|
|
||||||
|
circle.setRadius(3);
|
||||||
|
circle.addTo(layer);
|
||||||
|
|
||||||
|
return circle;
|
||||||
|
},
|
||||||
|
|
||||||
|
getAzimut: function(a, b){
|
||||||
|
var deg = 0;
|
||||||
|
|
||||||
|
if(a && b){
|
||||||
|
deg = parseInt(Math.atan2(b.y - a.y, b.x - a.x) * 180 / Math.PI);
|
||||||
|
|
||||||
|
if(deg > 0){
|
||||||
|
deg += 90;
|
||||||
|
} else if(deg < 0){
|
||||||
|
deg = Math.abs(deg);
|
||||||
|
if(deg <= 90){
|
||||||
|
deg = 90 - deg;
|
||||||
|
} else {
|
||||||
|
deg = 360 - (deg - 90);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastAzimut = deg;
|
||||||
|
|
||||||
|
return deg;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderPolyline: function(latLngs, dashArray, layer) {
|
||||||
|
var poly = L.polyline(latLngs, {
|
||||||
|
color: this.options.color,
|
||||||
|
weight: 2,
|
||||||
|
opacity: 1,
|
||||||
|
dashArray: dashArray
|
||||||
|
});
|
||||||
|
|
||||||
|
poly.addTo(layer);
|
||||||
|
|
||||||
|
return poly;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderMultiPolyline: function(latLngs, dashArray, layer) {
|
||||||
|
/* Leaflet version 1+ delegated the concept of multi-poly-line to the polyline */
|
||||||
|
var multi;
|
||||||
|
|
||||||
|
if(L.version.startsWith('0')){
|
||||||
|
multi = L.multiPolyline(latLngs, {
|
||||||
|
color: this.options.color,
|
||||||
|
weight: 2,
|
||||||
|
opacity: 1,
|
||||||
|
dashArray: dashArray
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
multi = L.polyline(latLngs, {
|
||||||
|
color: this.options.color,
|
||||||
|
weight: 2,
|
||||||
|
opacity: 1,
|
||||||
|
dashArray: dashArray
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
multi.addTo(layer);
|
||||||
|
|
||||||
|
return multi;
|
||||||
|
},
|
||||||
|
|
||||||
|
formatDistance: function(distance, precision) {
|
||||||
|
var s = L.Util.formatNum((distance < 1 ? distance*parseFloat(this.SUB_UNIT_CONV) : distance), precision),
|
||||||
|
u = (distance < 1 ? this.SUB_UNIT : this.UNIT);
|
||||||
|
|
||||||
|
return { scalar: s, unit: u };
|
||||||
|
},
|
||||||
|
|
||||||
|
hasClass: function(target, classes){
|
||||||
|
var fn = L.DomUtil.hasClass;
|
||||||
|
|
||||||
|
for(var i in classes){
|
||||||
|
if(fn(target, classes[i])){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
preClick: function(e){
|
||||||
|
var me = this,
|
||||||
|
target = e.originalEvent.target;
|
||||||
|
|
||||||
|
if(this.hasClass(target, ['leaflet-popup', 'total-popup-content'])){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!me.layer){
|
||||||
|
me.initLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
me.cleanUpMarkers(true);
|
||||||
|
|
||||||
|
me.fixedLast = me.last;
|
||||||
|
me.prevLatlng = e.latlng;
|
||||||
|
me.sum = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
getMouseClickHandler: function(e){
|
||||||
|
var me = this;
|
||||||
|
me.fixedLast = me.last;
|
||||||
|
me.sum = 0;
|
||||||
|
|
||||||
|
if(me.poly){
|
||||||
|
me.latlngsList.push(me.latlngs);
|
||||||
|
|
||||||
|
if(!me.multi){
|
||||||
|
me.multi = me.renderMultiPolyline(me.latlngsList, '5 5', me.layer, 'dot');
|
||||||
|
} else {
|
||||||
|
me.multi.setLatLngs(me.latlngsList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var o, dis;
|
||||||
|
for(var l in me.latlngsList){
|
||||||
|
o = me.latlngsList[l];
|
||||||
|
me.sum += o[0].distanceTo(o[1])/me.UNIT_CONV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(me.measure.unit === this.SUB_UNIT){
|
||||||
|
dis = me.sum * me.SUB_UNIT_CONV;
|
||||||
|
} else {
|
||||||
|
dis = me.sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
var s = dis.toFixed(2);
|
||||||
|
|
||||||
|
me.renderCircle(e.latlng, 0, me.layer, 'dot', parseInt(s) ? (s + ' ' + me.measure.unit) : '' );
|
||||||
|
me.prevLatlng = e.latlng;
|
||||||
|
},
|
||||||
|
|
||||||
|
getMouseMoveHandler: function(e){
|
||||||
|
var azimut = '';
|
||||||
|
|
||||||
|
if(this.prevLatlng){
|
||||||
|
var latLng = e.latlng;
|
||||||
|
|
||||||
|
this.latlngs = [this.prevLatlng, e.latlng];
|
||||||
|
|
||||||
|
if(!this.poly){
|
||||||
|
this.poly = this.renderPolyline(this.latlngs, '5 5', this.layer);
|
||||||
|
} else {
|
||||||
|
this.poly.setLatLngs(this.latlngs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Distance in miles/meters */
|
||||||
|
this.distance = parseFloat(this.prevLatlng.distanceTo(e.latlng))/this.UNIT_CONV;
|
||||||
|
|
||||||
|
/* scalar and unit */
|
||||||
|
this.measure = this.formatDistance(this.distance + this.sum, 2);
|
||||||
|
|
||||||
|
var a = this.prevLatlng ? this._map.latLngToContainerPoint(this.prevLatlng) : null,
|
||||||
|
b = this._map.latLngToContainerPoint(latLng);
|
||||||
|
|
||||||
|
if(a && this.options.show_azimut){
|
||||||
|
var style = 'color: '+this.options.contrastingColor+';';
|
||||||
|
azimut = ' <span class="azimut azimut-final" style="'+style+'"> '+this.getAzimut(a, b)+'°</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tooltip with total distance */
|
||||||
|
var label = this.measure.scalar + ' ' + this.measure.unit,
|
||||||
|
html = '<span class="total-popup-content" style="background-color:'+this.options.color+'; color: '+this.options.contrastingColor+'">' + label + azimut + '</span>';
|
||||||
|
|
||||||
|
if(!this.total){
|
||||||
|
this.totalIcon = L.divIcon({ className: 'total-popup', html: html });
|
||||||
|
|
||||||
|
this.total = L.marker(e.latlng, {
|
||||||
|
icon: this.totalIcon,
|
||||||
|
clickable: true
|
||||||
|
}).addTo(this.layer);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.totalIcon = L.divIcon({ className: 'total-popup', html: html });
|
||||||
|
this.total.setLatLng(e.latlng);
|
||||||
|
this.total.setIcon(this.totalIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rules for separation using only distance criteria */
|
||||||
|
var ds = this.measure.scalar,
|
||||||
|
old_separation = this.separation,
|
||||||
|
digits = parseInt(ds).toString().length,
|
||||||
|
num = Math.pow(10, digits),
|
||||||
|
real = ds > (num/2) ? (num/10) : (num/20),
|
||||||
|
dimension = 0;
|
||||||
|
|
||||||
|
this.separation = real;
|
||||||
|
|
||||||
|
/* If there is a change in the segment length we want to re-space
|
||||||
|
the dots on the multi line */
|
||||||
|
if(old_separation !== this.separation && this.fixedLast){
|
||||||
|
this.cleanUpMarkers();
|
||||||
|
this.cleanUpFixed();
|
||||||
|
|
||||||
|
var multi_latlngs = this.multi.getLatLngs();
|
||||||
|
|
||||||
|
for(var s in multi_latlngs){
|
||||||
|
dimension += this.displayMarkers.apply(this, [multi_latlngs[s], true, dimension]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.displayMarkers.apply(this, [this.poly.getLatLngs(), false, this.sum]);
|
||||||
|
|
||||||
|
/* Review that the dots are in correct units */
|
||||||
|
this.convertDots();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.cleanUpMarkers();
|
||||||
|
this.displayMarkers.apply(this, [this.poly.getLatLngs(), false, this.sum]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getDblClickHandler: function(e){
|
||||||
|
var azimut = '',
|
||||||
|
me = this;
|
||||||
|
|
||||||
|
if(!this.total){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.layer.off('click');
|
||||||
|
|
||||||
|
L.DomEvent.stop(e);
|
||||||
|
|
||||||
|
if(this.options.show_azimut){
|
||||||
|
var style = 'color: '+this.options.contrastingColor+';';
|
||||||
|
azimut = ' <span class="azimut azimut-final" style="'+style+'"> '+this.lastAzimut+'°</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
var workspace = this.layer,
|
||||||
|
label = this.measure.scalar + ' ' + this.measure.unit + ' ',
|
||||||
|
total_scalar = this.measure.unit === this.SUB_UNIT ? this.measure.scalar/this.UNIT_CONV : this.measure.scalar,
|
||||||
|
total_latlng = this.total.getLatLng(),
|
||||||
|
total_label = this.total,
|
||||||
|
html = [
|
||||||
|
'<div class="total-popup-content" style="background-color:'+this.options.color+'; color: '+this.options.contrastingColor+'">' + label + azimut,
|
||||||
|
' <svg class="close" viewbox="0 0 45 35">',
|
||||||
|
' <path style="stroke: '+this.options.contrastingColor+'" class="close" d="M 10,10 L 30,30 M 30,10 L 10,30" />',
|
||||||
|
' </svg>',
|
||||||
|
'</div>'
|
||||||
|
].join('');
|
||||||
|
|
||||||
|
this.totalIcon = L.divIcon({ className: 'total-popup', html: html });
|
||||||
|
this.total.setIcon(this.totalIcon);
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
total: this.measure,
|
||||||
|
total_label: total_label,
|
||||||
|
unit: this.UNIT_CONV,
|
||||||
|
sub_unit: this.SUB_UNIT_CONV
|
||||||
|
};
|
||||||
|
|
||||||
|
var fireSelected = function(e){
|
||||||
|
if(L.DomUtil.hasClass(e.originalEvent.target, 'close')){
|
||||||
|
me.mainLayer.removeLayer(workspace);
|
||||||
|
} else {
|
||||||
|
workspace.fireEvent('selected', data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
workspace.on('click', fireSelected);
|
||||||
|
workspace.fireEvent('selected', data);
|
||||||
|
|
||||||
|
this.resetRuler(false);
|
||||||
|
},
|
||||||
|
|
||||||
|
purgeLayers: function(layers){
|
||||||
|
for(var i in layers){
|
||||||
|
if(layers[i]) {
|
||||||
|
this.layer.removeLayer(layers[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
layerSelected: function(e){}
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
|
@ -345,7 +345,11 @@
|
||||||
gpxedit.searchControl.addTo(gpxedit.map);
|
gpxedit.searchControl.addTo(gpxedit.map);
|
||||||
gpxedit.locateControl = L.control.locate({follow: true});
|
gpxedit.locateControl = L.control.locate({follow: true});
|
||||||
gpxedit.locateControl.addTo(gpxedit.map);
|
gpxedit.locateControl.addTo(gpxedit.map);
|
||||||
L.Control.measureControl().addTo(gpxedit.map);
|
gpxedit.map.addControl(new L.Control.LinearMeasurement({
|
||||||
|
unitSystem: 'metric',
|
||||||
|
color: '#FF0080',
|
||||||
|
type: 'line'
|
||||||
|
}));
|
||||||
L.control.sidebar('sidebar').addTo(gpxedit.map);
|
L.control.sidebar('sidebar').addTo(gpxedit.map);
|
||||||
|
|
||||||
gpxedit.map.setView(new L.LatLng(27, 5), 3);
|
gpxedit.map.setView(new L.LatLng(27, 5), 3);
|
||||||
|
|
|
@ -1,173 +0,0 @@
|
||||||
(function (factory, window) {
|
|
||||||
// define an AMD module that relies on 'leaflet'
|
|
||||||
if (typeof define === 'function' && define.amd) {
|
|
||||||
define(['leaflet'], function (L) {
|
|
||||||
factory(L, window.toGeoJSON);
|
|
||||||
});
|
|
||||||
|
|
||||||
// define a Common JS module that relies on 'leaflet'
|
|
||||||
} else if (typeof exports === 'object') {
|
|
||||||
module.exports = function (L) {
|
|
||||||
if (L === undefined) {
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
L = require('leaflet');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
factory(L);
|
|
||||||
return L;
|
|
||||||
};
|
|
||||||
} else if (typeof window !== 'undefined' && window.L) {
|
|
||||||
factory(window.L);
|
|
||||||
}
|
|
||||||
}(function (L) {
|
|
||||||
L.Polyline.Measure = L.Draw.Polyline.extend({
|
|
||||||
addHooks: function () {
|
|
||||||
L.Draw.Polyline.prototype.addHooks.call(this);
|
|
||||||
if (this._map) {
|
|
||||||
this._markerGroup = new L.LayerGroup();
|
|
||||||
this._map.addLayer(this._markerGroup);
|
|
||||||
|
|
||||||
this._markers = [];
|
|
||||||
this._map.on('click', this._onClick, this);
|
|
||||||
this._startShape();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
removeHooks: function () {
|
|
||||||
L.Draw.Polyline.prototype.removeHooks.call(this);
|
|
||||||
|
|
||||||
this._clearHideErrorTimeout();
|
|
||||||
|
|
||||||
// !\ Still useful when control is disabled before any drawing (refactor needed?)
|
|
||||||
this._map
|
|
||||||
.off('pointermove', this._onMouseMove, this)
|
|
||||||
.off('mousemove', this._onMouseMove, this)
|
|
||||||
.off('click', this._onClick, this);
|
|
||||||
|
|
||||||
this._clearGuides();
|
|
||||||
this._container.style.cursor = '';
|
|
||||||
|
|
||||||
this._removeShape();
|
|
||||||
},
|
|
||||||
|
|
||||||
_startShape: function () {
|
|
||||||
this._drawing = true;
|
|
||||||
this._poly = new L.Polyline([], this.options.shapeOptions);
|
|
||||||
// this is added as a placeholder, if leaflet doesn't recieve
|
|
||||||
// this when the tool is turned off all onclick events are removed
|
|
||||||
this._poly._onClick = function () {};
|
|
||||||
|
|
||||||
this._container.style.cursor = 'crosshair';
|
|
||||||
|
|
||||||
this._updateTooltip();
|
|
||||||
this._map
|
|
||||||
.on('pointermove', this._onMouseMove, this)
|
|
||||||
.on('mousemove', this._onMouseMove, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
_finishShape: function () {
|
|
||||||
this._drawing = false;
|
|
||||||
|
|
||||||
this._cleanUpShape();
|
|
||||||
this._clearGuides();
|
|
||||||
|
|
||||||
this._updateTooltip();
|
|
||||||
|
|
||||||
this._map
|
|
||||||
.off('pointermove', this._onMouseMove, this)
|
|
||||||
.off('mousemove', this._onMouseMove, this);
|
|
||||||
|
|
||||||
this._container.style.cursor = '';
|
|
||||||
},
|
|
||||||
|
|
||||||
_removeShape: function () {
|
|
||||||
if (!this._poly) return;
|
|
||||||
this._map.removeLayer(this._poly);
|
|
||||||
delete this._poly;
|
|
||||||
this._markers.splice(0);
|
|
||||||
this._markerGroup.clearLayers();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onClick: function () {
|
|
||||||
if (!this._drawing) {
|
|
||||||
this._removeShape();
|
|
||||||
this._startShape();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getTooltipText: function () {
|
|
||||||
var labelText = L.Draw.Polyline.prototype._getTooltipText.call(this);
|
|
||||||
if (!this._drawing) {
|
|
||||||
labelText.text = '';
|
|
||||||
}
|
|
||||||
return labelText;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.Control.MeasureControl = L.Control.extend({
|
|
||||||
|
|
||||||
statics: {
|
|
||||||
TITLE: 'Measure distances'
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
position: 'topleft',
|
|
||||||
handler: {}
|
|
||||||
},
|
|
||||||
|
|
||||||
toggle: function () {
|
|
||||||
if (this.handler.enabled()) {
|
|
||||||
this.handler.disable.call(this.handler);
|
|
||||||
} else {
|
|
||||||
this.handler.enable.call(this.handler);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onAdd: function (map) {
|
|
||||||
var link = null;
|
|
||||||
var className = 'leaflet-control-draw';
|
|
||||||
|
|
||||||
this._container = L.DomUtil.create('div', 'leaflet-bar');
|
|
||||||
|
|
||||||
this.handler = new L.Polyline.Measure(map, this.options.handler);
|
|
||||||
|
|
||||||
this.handler.on('enabled', function () {
|
|
||||||
this.enabled = true;
|
|
||||||
L.DomUtil.addClass(this._container, 'enabled');
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.handler.on('disabled', function () {
|
|
||||||
delete this.enabled;
|
|
||||||
L.DomUtil.removeClass(this._container, 'enabled');
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
link = L.DomUtil.create('a', className + '-measure', this._container);
|
|
||||||
link.href = '#';
|
|
||||||
link.title = L.Control.MeasureControl.TITLE;
|
|
||||||
|
|
||||||
L.DomEvent
|
|
||||||
.addListener(link, 'click', L.DomEvent.stopPropagation)
|
|
||||||
.addListener(link, 'click', L.DomEvent.preventDefault)
|
|
||||||
.addListener(link, 'click', this.toggle, this);
|
|
||||||
|
|
||||||
return this._container;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
L.Map.mergeOptions({
|
|
||||||
measureControl: false
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
L.Map.addInitHook(function () {
|
|
||||||
if (this.options.measureControl) {
|
|
||||||
this.measureControl = L.Control.measureControl().addTo(this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
L.Control.measureControl = function (options) {
|
|
||||||
return new L.Control.MeasureControl(options);
|
|
||||||
};
|
|
||||||
}, window));
|
|
|
@ -15,7 +15,7 @@ script('gpxedit', 'leaflet.draw-src');
|
||||||
script('gpxedit', 'leaflet.geometryutil');
|
script('gpxedit', 'leaflet.geometryutil');
|
||||||
script('gpxedit', 'leaflet.snap');
|
script('gpxedit', 'leaflet.snap');
|
||||||
script('gpxedit', 'Control.Draw.Plus');
|
script('gpxedit', 'Control.Draw.Plus');
|
||||||
script('gpxedit', 'leaflet.measurecontrol');
|
script('gpxedit', 'Leaflet.LinearMeasurement');
|
||||||
script('gpxedit', 'gpxedit');
|
script('gpxedit', 'gpxedit');
|
||||||
|
|
||||||
style('gpxedit', 'style');
|
style('gpxedit', 'style');
|
||||||
|
@ -29,7 +29,7 @@ style('gpxedit', 'font-awesome.min');
|
||||||
style('gpxedit', 'gpxedit');
|
style('gpxedit', 'gpxedit');
|
||||||
style('gpxedit', 'L.Control.Locate.min');
|
style('gpxedit', 'L.Control.Locate.min');
|
||||||
style('gpxedit', 'leaflet.draw');
|
style('gpxedit', 'leaflet.draw');
|
||||||
style('gpxedit', 'leaflet.measurecontrol');
|
style('gpxedit', 'Leaflet.LinearMeasurement');
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue