X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/1b2738af809843a07361b657c0b64e27732effca..6c34885fe73dfdcff1de4e3c9eb7b2931efd6b81:/vendor/assets/leaflet/leaflet.locate.js diff --git a/vendor/assets/leaflet/leaflet.locate.js b/vendor/assets/leaflet/leaflet.locate.js index 64fb144d4..822b24da2 100644 --- a/vendor/assets/leaflet/leaflet.locate.js +++ b/vendor/assets/leaflet/leaflet.locate.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2013 Dominik Moritz +Copyright (c) 2014 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 @@ -9,7 +9,7 @@ L.Control.Locate = L.Control.extend({ 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 + stopFollowingOnDrag: false, // if follow is true, stop following when map is dragged (deprecated) // range circle circleStyle: { color: '#136AEC', @@ -34,37 +34,43 @@ L.Control.Locate = L.Control.extend({ //color: '#FFA500', //fillColor: '#FFB000' }, + icon: 'icon-location', // icon-location or icon-direction + iconLoading: 'icon-spinner animate-spin', + circlePadding: [0, 0], metric: true, onLocationError: function(err) { // this event is called in case of any location error // that is not a time out error. alert(err.message); }, - onLocationOutsideMapBounds: function(context) { + onLocationOutsideMapBounds: function(control) { // this event is repeatedly called when the location changes + control.stopLocate(); alert(context.options.strings.outsideMapBoundsMsg); }, setView: true, // automatically sets the map view to the user's location + // keep the current map zoom level when displaying the user's location. (if 'false', use maxZoom) + keepCurrentZoomLevel: false, 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: {} + locateOptions: { + maxZoom: Infinity, + watch: true // if you overwrite this, visualization cannot be updated + } }, onAdd: function (map) { - var container = L.DomUtil.create('div', - 'leaflet-control-locate leaflet-bar leaflet-control'); + var container = L.DomUtil.create('div', 'control-locate'); var self = this; this._layer = new L.LayerGroup(); this._layer.addTo(map); this._event = undefined; - this._locateOptions = { - watch: true // if you overwrite this, visualization cannot be updated - }; + this._locateOptions = this.options.locateOptions; L.extend(this._locateOptions, this.options.locateOptions); L.extend(this._locateOptions, { setView: false // have to set this to false because we have to @@ -79,7 +85,8 @@ L.Control.Locate = L.Control.extend({ L.extend(tmp, this.options.circleStyle, this.options.followCircleStyle); this.options.followCircleStyle = tmp; - var link = L.DomUtil.create('a', 'leaflet-bar-part leaflet-bar-part-single', container); + var link = L.DomUtil.create('a', 'control-button ' + this.options.icon, container); + link.innerHTML = ""; link.href = '#'; link.title = this.options.strings.title; @@ -87,36 +94,39 @@ L.Control.Locate = L.Control.extend({ .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 && (self._event === undefined || map.getBounds().contains(self._event.latlng) || !self.options.setView || isOutsideMapBounds())) { stopLocate(); } else { - if (self.options.setView) { - self._locateOnNextLocationFound = true; - } - if(!self._active) { - 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(); - } + locate(); } }) .on(link, 'dblclick', L.DomEvent.stopPropagation); + var locate = function () { + if (self.options.setView) { + self._locateOnNextLocationFound = true; + } + if(!self._active) { + map.locate(self._locateOptions); + } + self._active = true; + if (self.options.follow) { + startFollowing(); + } + if (!self._event) { + setClasses('requesting'); + } else { + visualizeLocation(); + } + }; + var onLocationFound = function (e) { // 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)) { + (self._event.latlng.lat === e.latlng.lat && + self._event.latlng.lng === e.latlng.lng && + self._event.accuracy === e.accuracy)) { return; } @@ -134,6 +144,7 @@ L.Control.Locate = L.Control.extend({ }; var startFollowing = function() { + map.fire('startfollowing', self); self._following = true; if (self.options.stopFollowingOnDrag) { map.on('dragstart', stopFollowing); @@ -141,6 +152,7 @@ L.Control.Locate = L.Control.extend({ }; var stopFollowing = function() { + map.fire('stopfollowing', self); self._following = false; if (self.options.stopFollowingOnDrag) { map.off('dragstart', stopFollowing); @@ -164,13 +176,16 @@ L.Control.Locate = L.Control.extend({ if (isOutsideMapBounds()) { self.options.onLocationOutsideMapBounds(self); } else { - map.fitBounds(self._event.bounds); + map.fitBounds(self._event.bounds, { + padding: self.options.circlePadding, + maxZoom: self.options.keepCurrentZoomLevel ? map.getZoom() : self._locateOptions.maxZoom + }); } self._locateOnNextLocationFound = false; } // circle with the radius of the location's accuracy - var style; + var style, o; if (self.options.drawCircle) { if (self._following) { style = self.options.followCircleStyle; @@ -183,6 +198,9 @@ L.Control.Locate = L.Control.extend({ .addTo(self._layer); } else { self._circle.setLatLng(self._event.latlng).setRadius(radius); + for (o in style) { + self._circle.options[o] = style[o]; + } } } @@ -196,37 +214,58 @@ L.Control.Locate = L.Control.extend({ } // small inner marker - var m; + var mStyle; if (self._following) { - m = self.options.followMarkerStyle; + mStyle = self.options.followMarkerStyle; } else { - m = self.options.markerStyle; + mStyle = self.options.markerStyle; } var t = self.options.strings.popup; if (!self._circleMarker) { - self._circleMarker = L.circleMarker(self._event.latlng, m) + self._circleMarker = L.circleMarker(self._event.latlng, mStyle) .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); + for (o in mStyle) { + self._circleMarker.options[o] = mStyle[o]; + } } if (!self._container) return; if (self._following) { - L.DomUtil.removeClass(self._container, "requesting"); - L.DomUtil.addClass(self._container, "active"); - L.DomUtil.addClass(self._container, "following"); + setClasses('following'); } else { - L.DomUtil.removeClass(self._container, "requesting"); - L.DomUtil.addClass(self._container, "active"); - L.DomUtil.removeClass(self._container, "following"); + setClasses('active'); } }; + var setClasses = function(state) { + if (state == 'requesting') { + L.DomUtil.removeClasses(self._container, "active following"); + L.DomUtil.addClasses(self._container, "requesting"); + + L.DomUtil.removeClasses(link, self.options.icon); + L.DomUtil.addClasses(link, self.options.iconLoading); + } else if (state == 'active') { + L.DomUtil.removeClasses(self._container, "requesting following"); + L.DomUtil.addClasses(self._container, "active"); + + L.DomUtil.removeClasses(link, self.options.iconLoading); + L.DomUtil.addClasses(link, self.options.icon); + } else if (state == 'following') { + L.DomUtil.removeClasses(self._container, "requesting"); + L.DomUtil.addClasses(self._container, "active following"); + + L.DomUtil.removeClasses(link, self.options.iconLoading); + L.DomUtil.addClasses(link, self.options.icon); + } + } + var resetVariables = function() { self._active = false; self._locateOnNextLocationFound = self.options.setView; @@ -238,6 +277,9 @@ L.Control.Locate = L.Control.extend({ var stopLocate = function() { map.stopLocate(); map.off('dragstart', stopFollowing); + if (self.options.follow && self._following) { + stopFollowing(); + } L.DomUtil.removeClass(self._container, "requesting"); L.DomUtil.removeClass(self._container, "active"); @@ -251,7 +293,7 @@ L.Control.Locate = L.Control.extend({ var onLocationError = function (err) { // ignore time out error if the location is watched - if (err.code == 3 && this._locateOptions.watch) { + if (err.code == 3 && self._locateOptions.watch) { return; } @@ -263,6 +305,11 @@ L.Control.Locate = L.Control.extend({ map.on('locationfound', onLocationFound, self); map.on('locationerror', onLocationError, self); + // make locate functions available to outside world + this.locate = locate; + this.stopLocate = stopLocate; + this.stopFollowing = stopFollowing; + return container; } }); @@ -277,3 +324,17 @@ L.Map.addInitHook(function () { L.control.locate = function (options) { return new L.Control.Locate(options); }; + +(function(){ + // leaflet.js raises bug when trying to addClass / removeClass multiple classes at once + // Let's create a wrapper on it which fixes it. + var LDomUtilApplyClassesMethod = function(method, element, classNames) { + classNames = classNames.split(' '); + classNames.forEach(function(className) { + L.DomUtil[method].call(this, element, className); + }); + }; + + L.DomUtil.addClasses = function(el, names) { LDomUtilApplyClassesMethod('addClass', el, names); } + L.DomUtil.removeClasses = function(el, names) { LDomUtilApplyClassesMethod('removeClass', el, names); } +})();