Update leaflet.locate (fixes #438)
This commit is contained in:
parent
eee1c2349c
commit
1b2738af80
3 changed files with 150 additions and 61 deletions
205
vendor/assets/leaflet/leaflet.locate.js
vendored
205
vendor/assets/leaflet/leaflet.locate.js
vendored
|
@ -1,16 +1,23 @@
|
|||
/*
|
||||
Copyright (c) 2013 Dominik Moritz
|
||||
|
||||
This file is part of the leaflet locate control. It is licensed under the MIT license.
|
||||
You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
|
||||
*/
|
||||
L.Control.Locate = L.Control.extend({
|
||||
options: {
|
||||
position: 'topleft',
|
||||
drawCircle: true,
|
||||
follow: false, // follow with zoom and pan the user's location
|
||||
stopFollowingOnDrag: false, // if follow is true, stop following when map is dragged
|
||||
// range circle
|
||||
circleStyle: {
|
||||
color: '#136AEC',
|
||||
fillColor: '#136AEC',
|
||||
fillOpacity: 0.15,
|
||||
weight: 2,
|
||||
opacity: 0.5
|
||||
},
|
||||
color: '#136AEC',
|
||||
fillColor: '#136AEC',
|
||||
fillOpacity: 0.15,
|
||||
weight: 2,
|
||||
opacity: 0.5
|
||||
},
|
||||
// inner marker
|
||||
markerStyle: {
|
||||
color: '#136AEC',
|
||||
|
@ -18,52 +25,70 @@ L.Control.Locate = L.Control.extend({
|
|||
fillOpacity: 0.7,
|
||||
weight: 2,
|
||||
opacity: 0.9,
|
||||
radius: 4
|
||||
radius: 5
|
||||
},
|
||||
// changes to range circle and inner marker while following
|
||||
// it is only necessary to provide the things that should change
|
||||
followCircleStyle: {},
|
||||
followMarkerStyle: {
|
||||
//color: '#FFA500',
|
||||
//fillColor: '#FFB000'
|
||||
},
|
||||
metric: true,
|
||||
debug: false,
|
||||
onLocationError: function(err) {
|
||||
// this event is called in case of any location error
|
||||
// that is not a time out error.
|
||||
alert(err.message);
|
||||
},
|
||||
title: "Show me where I am",
|
||||
popupText: ["You are within ", " from this point"],
|
||||
onLocationOutsideMapBounds: function(context) {
|
||||
// this event is repeatedly called when the location changes
|
||||
alert(context.options.strings.outsideMapBoundsMsg);
|
||||
},
|
||||
setView: true, // automatically sets the map view to the user's location
|
||||
strings: {
|
||||
title: "Show me where I am",
|
||||
popup: "You are within {distance} {unit} from this point",
|
||||
outsideMapBoundsMsg: "You seem located outside the boundaries of the map"
|
||||
},
|
||||
locateOptions: {}
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
var className = 'control-locate',
|
||||
container = L.DomUtil.create('div', className);
|
||||
var container = L.DomUtil.create('div',
|
||||
'leaflet-control-locate leaflet-bar leaflet-control');
|
||||
|
||||
var self = this;
|
||||
this._layer = new L.LayerGroup();
|
||||
this._layer.addTo(map);
|
||||
this._event = undefined;
|
||||
// nested extend so that the first can overwrite the second
|
||||
// and the second can overwrite the third
|
||||
this._locateOptions = L.extend(L.extend({
|
||||
'setView': false // have to set this to false because we have to
|
||||
// do setView manually
|
||||
}, this.options.locateOptions), {
|
||||
'watch': true // if you overwrite this, visualization cannot be updated
|
||||
|
||||
this._locateOptions = {
|
||||
watch: true // if you overwrite this, visualization cannot be updated
|
||||
};
|
||||
L.extend(this._locateOptions, this.options.locateOptions);
|
||||
L.extend(this._locateOptions, {
|
||||
setView: false // have to set this to false because we have to
|
||||
// do setView manually
|
||||
});
|
||||
|
||||
var link = L.DomUtil.create('a', 'control-button', container);
|
||||
link.innerHTML = "<span class='icon geolocate'></span>";
|
||||
link.href = '#';
|
||||
link.title = this.options.title;
|
||||
// extend the follow marker style and circle from the normal style
|
||||
var tmp = {};
|
||||
L.extend(tmp, this.options.markerStyle, this.options.followMarkerStyle);
|
||||
this.options.followMarkerStyle = tmp;
|
||||
tmp = {};
|
||||
L.extend(tmp, this.options.circleStyle, this.options.followCircleStyle);
|
||||
this.options.followCircleStyle = tmp;
|
||||
|
||||
var _log = function(data) {
|
||||
if (self.options.debug) {
|
||||
console.log(data);
|
||||
}
|
||||
};
|
||||
var link = L.DomUtil.create('a', 'leaflet-bar-part leaflet-bar-part-single', container);
|
||||
link.href = '#';
|
||||
link.title = this.options.strings.title;
|
||||
|
||||
L.DomEvent
|
||||
.on(link, 'click', L.DomEvent.stopPropagation)
|
||||
.on(link, 'click', L.DomEvent.preventDefault)
|
||||
.on(link, 'click', function() {
|
||||
if (self._active && (map.getBounds().contains(self._event.latlng) || !self.options.setView)) {
|
||||
if (self._active && (map.getBounds().contains(self._event.latlng) || !self.options.setView ||
|
||||
isOutsideMapBounds())) {
|
||||
stopLocate();
|
||||
} else {
|
||||
if (self.options.setView) {
|
||||
|
@ -73,8 +98,13 @@ L.Control.Locate = L.Control.extend({
|
|||
map.locate(self._locateOptions);
|
||||
}
|
||||
self._active = true;
|
||||
if (self.options.follow) {
|
||||
startFollowing();
|
||||
}
|
||||
if (!self._event) {
|
||||
L.DomUtil.addClass(self._container, "requesting");
|
||||
L.DomUtil.removeClass(self._container, "active");
|
||||
L.DomUtil.removeClass(self._container, "following");
|
||||
} else {
|
||||
visualizeLocation();
|
||||
}
|
||||
|
@ -83,41 +113,77 @@ L.Control.Locate = L.Control.extend({
|
|||
.on(link, 'dblclick', L.DomEvent.stopPropagation);
|
||||
|
||||
var onLocationFound = function (e) {
|
||||
_log('onLocationFound');
|
||||
|
||||
self._active = true;
|
||||
|
||||
// no need to do anything if the location has not changed
|
||||
if (self._event &&
|
||||
(self._event.latlng.lat != e.latlng.lat ||
|
||||
self._event.latlng.lng != e.latlng.lng)) {
|
||||
_log('location has changed');
|
||||
(self._event.latlng.lat == e.latlng.lat &&
|
||||
self._event.latlng.lng == e.latlng.lng)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self._active) {
|
||||
return;
|
||||
}
|
||||
|
||||
self._event = e;
|
||||
|
||||
if (self.options.follow) {
|
||||
if (self.options.follow && self._following) {
|
||||
self._locateOnNextLocationFound = true;
|
||||
}
|
||||
|
||||
visualizeLocation();
|
||||
};
|
||||
|
||||
var startFollowing = function() {
|
||||
self._following = true;
|
||||
if (self.options.stopFollowingOnDrag) {
|
||||
map.on('dragstart', stopFollowing);
|
||||
}
|
||||
};
|
||||
|
||||
var stopFollowing = function() {
|
||||
self._following = false;
|
||||
if (self.options.stopFollowingOnDrag) {
|
||||
map.off('dragstart', stopFollowing);
|
||||
}
|
||||
visualizeLocation();
|
||||
};
|
||||
|
||||
var isOutsideMapBounds = function () {
|
||||
if (self._event === undefined)
|
||||
return false;
|
||||
return map.options.maxBounds &&
|
||||
!map.options.maxBounds.contains(self._event.latlng);
|
||||
};
|
||||
|
||||
var visualizeLocation = function() {
|
||||
_log('visualizeLocation,' + 'setView:' + self._locateOnNextLocationFound);
|
||||
|
||||
var radius = self._event.accuracy / 2;
|
||||
if (self._event.accuracy === undefined)
|
||||
self._event.accuracy = 0;
|
||||
|
||||
var radius = self._event.accuracy;
|
||||
if (self._locateOnNextLocationFound) {
|
||||
map.fitBounds(self._event.bounds);
|
||||
if (isOutsideMapBounds()) {
|
||||
self.options.onLocationOutsideMapBounds(self);
|
||||
} else {
|
||||
map.fitBounds(self._event.bounds);
|
||||
}
|
||||
self._locateOnNextLocationFound = false;
|
||||
}
|
||||
|
||||
self._layer.clearLayers();
|
||||
|
||||
// circle with the radius of the location's accuracy
|
||||
var style;
|
||||
if (self.options.drawCircle) {
|
||||
L.circle(self._event.latlng, radius, self.options.circleStyle)
|
||||
.addTo(self._layer);
|
||||
if (self._following) {
|
||||
style = self.options.followCircleStyle;
|
||||
} else {
|
||||
style = self.options.circleStyle;
|
||||
}
|
||||
|
||||
if (!self._circle) {
|
||||
self._circle = L.circle(self._event.latlng, radius, style)
|
||||
.addTo(self._layer);
|
||||
} else {
|
||||
self._circle.setLatLng(self._event.latlng).setRadius(radius);
|
||||
}
|
||||
}
|
||||
|
||||
var distance, unit;
|
||||
|
@ -130,43 +196,62 @@ L.Control.Locate = L.Control.extend({
|
|||
}
|
||||
|
||||
// small inner marker
|
||||
var t = self.options.popupText;
|
||||
L.circleMarker(self._event.latlng, self.options.markerStyle)
|
||||
.bindPopup(t[0] + distance + " " + unit + t[1])
|
||||
.addTo(self._layer);
|
||||
var m;
|
||||
if (self._following) {
|
||||
m = self.options.followMarkerStyle;
|
||||
} else {
|
||||
m = self.options.markerStyle;
|
||||
}
|
||||
|
||||
var t = self.options.strings.popup;
|
||||
if (!self._circleMarker) {
|
||||
self._circleMarker = L.circleMarker(self._event.latlng, m)
|
||||
.bindPopup(L.Util.template(t, {distance: distance, unit: unit}))
|
||||
.addTo(self._layer);
|
||||
} else {
|
||||
self._circleMarker.setLatLng(self._event.latlng)
|
||||
.bindPopup(L.Util.template(t, {distance: distance, unit: unit}))
|
||||
._popup.setLatLng(self._event.latlng);
|
||||
}
|
||||
|
||||
if (!self._container)
|
||||
return;
|
||||
|
||||
L.DomUtil.removeClass(self._container, "requesting");
|
||||
L.DomUtil.addClass(self._container, "active");
|
||||
if (self._following) {
|
||||
L.DomUtil.removeClass(self._container, "requesting");
|
||||
L.DomUtil.addClass(self._container, "active");
|
||||
L.DomUtil.addClass(self._container, "following");
|
||||
} else {
|
||||
L.DomUtil.removeClass(self._container, "requesting");
|
||||
L.DomUtil.addClass(self._container, "active");
|
||||
L.DomUtil.removeClass(self._container, "following");
|
||||
}
|
||||
};
|
||||
|
||||
var resetVariables = function() {
|
||||
self._active = false;
|
||||
self._locateOnNextLocationFound = true;
|
||||
self._locateOnNextLocationFound = self.options.setView;
|
||||
self._following = false;
|
||||
};
|
||||
|
||||
resetVariables();
|
||||
|
||||
var stopLocate = function() {
|
||||
_log('stopLocate');
|
||||
map.stopLocate();
|
||||
map.off('dragstart', stopFollowing);
|
||||
|
||||
L.DomUtil.removeClass(self._container, "requesting");
|
||||
L.DomUtil.removeClass(self._container, "active");
|
||||
|
||||
L.DomUtil.removeClass(self._container, "following");
|
||||
resetVariables();
|
||||
|
||||
self._layer.clearLayers();
|
||||
self._circleMarker = undefined;
|
||||
self._circle = undefined;
|
||||
};
|
||||
|
||||
|
||||
var onLocationError = function (err) {
|
||||
_log('onLocationError');
|
||||
|
||||
// ignore timeout error if the location is watched
|
||||
if (err.code==3 && this._locateOptions.watch) {
|
||||
// ignore time out error if the location is watched
|
||||
if (err.code == 3 && this._locateOptions.watch) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue