]> git.openstreetmap.org Git - rails.git/blob - vendor/assets/leaflet/leaflet.locate.js
Fix locate button style
[rails.git] / vendor / assets / leaflet / leaflet.locate.js
1 L.Control.Locate = L.Control.extend({
2     options: {
3         position: 'topleft',
4         drawCircle: true,
5         follow: false,  // follow with zoom and pan the user's location
6         // range circle
7         circleStyle: {
8                 color: '#136AEC',
9                 fillColor: '#136AEC',
10                 fillOpacity: 0.15,
11                 weight: 2,
12                 opacity: 0.5
13             },
14         // inner marker
15         markerStyle: {
16             color: '#136AEC',
17             fillColor: '#2A93EE',
18             fillOpacity: 0.7,
19             weight: 2,
20             opacity: 0.9,
21             radius: 4
22         },
23         metric: true,
24         debug: false,
25         onLocationError: function(err) {
26             alert(err.message);
27         },
28         title: "Show me where I am",
29         popupText: ["You are within ", " from this point"],
30         setView: true, // automatically sets the map view to the user's location
31         locateOptions: {}
32     },
33
34     onAdd: function (map) {
35         var className = 'control-locate',
36             container = L.DomUtil.create('div', className);
37
38         var self = this;
39         this._layer = new L.LayerGroup();
40         this._layer.addTo(map);
41         this._event = undefined;
42         // nested extend so that the first can overwrite the second
43         // and the second can overwrite the third
44         this._locateOptions = L.extend(L.extend({
45             'setView': false // have to set this to false because we have to
46                              // do setView manually
47         }, this.options.locateOptions), {
48             'watch': true  // if you overwrite this, visualization cannot be updated
49         });
50
51         var link = L.DomUtil.create('a', 'control-button', container);
52         link.innerHTML = "<span class='icon geolocate'></span>";
53         link.href = '#';
54         link.title = this.options.title;
55
56         var _log = function(data) {
57             if (self.options.debug) {
58                 console.log(data);
59             }
60         };
61
62         L.DomEvent
63             .on(link, 'click', L.DomEvent.stopPropagation)
64             .on(link, 'click', L.DomEvent.preventDefault)
65             .on(link, 'click', function() {
66                 if (self._active && (map.getBounds().contains(self._event.latlng) || !self.options.setView)) {
67                     stopLocate();
68                 } else {
69                     if (self.options.setView) {
70                         self._locateOnNextLocationFound = true;
71                     }
72                     if(!self._active) {
73                         map.locate(self._locateOptions);
74                     }
75                     self._active = true;
76                     if (!self._event) {
77                         L.DomUtil.addClass(self._container, "requesting");
78                     } else {
79                         visualizeLocation();
80                     }
81                 }
82             })
83             .on(link, 'dblclick', L.DomEvent.stopPropagation);
84
85         var onLocationFound = function (e) {
86             _log('onLocationFound');
87
88             self._active = true;
89
90             if (self._event &&
91                 (self._event.latlng.lat != e.latlng.lat ||
92                  self._event.latlng.lng != e.latlng.lng)) {
93                 _log('location has changed');
94             }
95
96             self._event = e;
97
98             if (self.options.follow) {
99                 self._locateOnNextLocationFound = true;
100             }
101
102             visualizeLocation();
103         };
104
105         var visualizeLocation = function() {
106             _log('visualizeLocation,' + 'setView:' + self._locateOnNextLocationFound);
107
108             var radius = self._event.accuracy / 2;
109
110             if (self._locateOnNextLocationFound) {
111                 map.fitBounds(self._event.bounds);
112                 self._locateOnNextLocationFound = false;
113             }
114
115             self._layer.clearLayers();
116
117             // circle with the radius of the location's accuracy
118             if (self.options.drawCircle) {
119                 L.circle(self._event.latlng, radius, self.options.circleStyle)
120                     .addTo(self._layer);
121             }
122
123             var distance, unit;
124             if (self.options.metric) {
125                 distance = radius.toFixed(0);
126                 unit = "meters";
127             } else {
128                 distance = (radius * 3.2808399).toFixed(0);
129                 unit = "feet";
130             }
131
132             // small inner marker
133             var t = self.options.popupText;
134             L.circleMarker(self._event.latlng, self.options.markerStyle)
135                 .bindPopup(t[0] + distance + " " + unit  + t[1])
136                 .addTo(self._layer);
137
138             if (!self._container)
139                 return;
140
141             L.DomUtil.removeClass(self._container, "requesting");
142             L.DomUtil.addClass(self._container, "active");
143         };
144
145         var resetVariables = function() {
146             self._active = false;
147             self._locateOnNextLocationFound = true;
148         };
149
150         resetVariables();
151
152         var stopLocate = function() {
153             _log('stopLocate');
154             map.stopLocate();
155
156             L.DomUtil.removeClass(self._container, "requesting");
157             L.DomUtil.removeClass(self._container, "active");
158
159             resetVariables();
160
161             self._layer.clearLayers();
162         };
163
164
165         var onLocationError = function (err) {
166             _log('onLocationError');
167
168             // ignore timeout error if the location is watched
169             if (err.code==3 && this._locateOptions.watch) {
170                 return;
171             }
172
173             stopLocate();
174             self.options.onLocationError(err);
175         };
176
177         // event hooks
178         map.on('locationfound', onLocationFound, self);
179         map.on('locationerror', onLocationError, self);
180
181         return container;
182     }
183 });
184
185 L.Map.addInitHook(function () {
186     if (this.options.locateControl) {
187         this.locateControl = L.control.locate();
188         this.addControl(this.locateControl);
189     }
190 });
191
192 L.control.locate = function (options) {
193     return new L.Control.Locate(options);
194 };