+++ /dev/null
-L.Control.Locate = L.Control.extend({
- options: {
- position: 'topleft',
- drawCircle: true,
- follow: false, // follow with zoom and pan the user's location
- // range circle
- circleStyle: {
- color: '#136AEC',
- fillColor: '#136AEC',
- fillOpacity: 0.15,
- weight: 2,
- opacity: 0.5
- },
- // inner marker
- markerStyle: {
- color: '#136AEC',
- fillColor: '#2A93EE',
- fillOpacity: 0.7,
- weight: 2,
- opacity: 0.9,
- radius: 4
- },
- metric: true,
- debug: false,
- onLocationError: function(err) {
- alert(err.message);
- },
- title: "Show me where I am",
- popupText: ["You are within ", " from this point"],
- setView: true, // automatically sets the map view to the user's location
- locateOptions: {}
- },
-
- onAdd: function (map) {
- var className = 'control-locate',
- container = L.DomUtil.create('div', className);
-
- 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
- });
-
- var link = L.DomUtil.create('a', 'control-button', container);
- link.innerHTML = "<span class='icon geolocate'></span>";
- link.href = '#';
- link.title = this.options.title;
-
- var _log = function(data) {
- if (self.options.debug) {
- console.log(data);
- }
- };
-
- 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)) {
- stopLocate();
- } else {
- if (self.options.setView) {
- self._locateOnNextLocationFound = true;
- }
- if(!self._active) {
- map.locate(self._locateOptions);
- }
- self._active = true;
- if (!self._event) {
- L.DomUtil.addClass(self._container, "requesting");
- } else {
- visualizeLocation();
- }
- }
- })
- .on(link, 'dblclick', L.DomEvent.stopPropagation);
-
- var onLocationFound = function (e) {
- _log('onLocationFound');
-
- self._active = true;
-
- if (self._event &&
- (self._event.latlng.lat != e.latlng.lat ||
- self._event.latlng.lng != e.latlng.lng)) {
- _log('location has changed');
- }
-
- self._event = e;
-
- if (self.options.follow) {
- self._locateOnNextLocationFound = true;
- }
-
- visualizeLocation();
- };
-
- var visualizeLocation = function() {
- _log('visualizeLocation,' + 'setView:' + self._locateOnNextLocationFound);
-
- var radius = self._event.accuracy / 2;
-
- if (self._locateOnNextLocationFound) {
- map.fitBounds(self._event.bounds);
- self._locateOnNextLocationFound = false;
- }
-
- self._layer.clearLayers();
-
- // circle with the radius of the location's accuracy
- if (self.options.drawCircle) {
- L.circle(self._event.latlng, radius, self.options.circleStyle)
- .addTo(self._layer);
- }
-
- var distance, unit;
- if (self.options.metric) {
- distance = radius.toFixed(0);
- unit = "meters";
- } else {
- distance = (radius * 3.2808399).toFixed(0);
- unit = "feet";
- }
-
- // 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);
-
- if (!self._container)
- return;
-
- L.DomUtil.removeClass(self._container, "requesting");
- L.DomUtil.addClass(self._container, "active");
- };
-
- var resetVariables = function() {
- self._active = false;
- self._locateOnNextLocationFound = true;
- };
-
- resetVariables();
-
- var stopLocate = function() {
- _log('stopLocate');
- map.stopLocate();
-
- L.DomUtil.removeClass(self._container, "requesting");
- L.DomUtil.removeClass(self._container, "active");
-
- resetVariables();
-
- self._layer.clearLayers();
- };
-
-
- var onLocationError = function (err) {
- _log('onLocationError');
-
- // ignore timeout error if the location is watched
- if (err.code==3 && this._locateOptions.watch) {
- return;
- }
-
- stopLocate();
- self.options.onLocationError(err);
- };
-
- // event hooks
- map.on('locationfound', onLocationFound, self);
- map.on('locationerror', onLocationError, self);
-
- return container;
- }
-});
-
-L.Map.addInitHook(function () {
- if (this.options.locateControl) {
- this.locateControl = L.control.locate();
- this.addControl(this.locateControl);
- }
-});
-
-L.control.locate = function (options) {
- return new L.Control.Locate(options);
-};