Codebase list leaflet / d0879e1
move geolocation methods to Map.js Vladimir Agafonkin 7 years ago
3 changed file(s) with 102 addition(s) and 118 deletion(s). Raw diff Collapse all Expand all
250250 ],
251251 deps: ['AnimationPan'],
252252 desc: 'Smooth zooming animation. Works only on browsers that support CSS3 Transitions.'
253 },
254
255 Geolocation: {
256 src: ['map/ext/Map.Geolocation.js'],
257 desc: 'Adds Map#locate method and related events to make geolocation easier.',
258 heading: 'Misc'
259253 }
260254 };
261255
378378 return this._stop();
379379 },
380380
381 // @section Geolocation methods
382 // @method locate(options?: Locate options): this
383 // Tries to locate the user using the Geolocation API, firing a [`locationfound`](#map-locationfound)
384 // event with location data on success or a [`locationerror`](#map-locationerror) event on failure,
385 // and optionally sets the map view to the user's location with respect to
386 // detection accuracy (or to the world view if geolocation failed).
387 // Note that, if your page doesn't use HTTPS, this method will fail in
388 // modern browsers ([Chrome 50 and newer](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins))
389 // See `Locate options` for more details.
390 locate: function (options) {
391
392 options = this._locateOptions = L.extend({
393 timeout: 10000,
394 watch: false
395 // setView: false
396 // maxZoom: <Number>
397 // maximumAge: 0
398 // enableHighAccuracy: false
399 }, options);
400
401 if (!('geolocation' in navigator)) {
402 this._handleGeolocationError({
403 code: 0,
404 message: 'Geolocation not supported.'
405 });
406 return this;
407 }
408
409 var onResponse = L.bind(this._handleGeolocationResponse, this),
410 onError = L.bind(this._handleGeolocationError, this);
411
412 if (options.watch) {
413 this._locationWatchId =
414 navigator.geolocation.watchPosition(onResponse, onError, options);
415 } else {
416 navigator.geolocation.getCurrentPosition(onResponse, onError, options);
417 }
418 return this;
419 },
420
421 // @method stopLocate(): this
422 // Stops watching location previously initiated by `map.locate({watch: true})`
423 // and aborts resetting the map view if map.locate was called with
424 // `{setView: true}`.
425 stopLocate: function () {
426 if (navigator.geolocation && navigator.geolocation.clearWatch) {
427 navigator.geolocation.clearWatch(this._locationWatchId);
428 }
429 if (this._locateOptions) {
430 this._locateOptions.setView = false;
431 }
432 return this;
433 },
434
435 _handleGeolocationError: function (error) {
436 var c = error.code,
437 message = error.message ||
438 (c === 1 ? 'permission denied' :
439 (c === 2 ? 'position unavailable' : 'timeout'));
440
441 if (this._locateOptions.setView && !this._loaded) {
442 this.fitWorld();
443 }
444
445 // @section Location events
446 // @event locationerror: ErrorEvent
447 // Fired when geolocation (using the [`locate`](#map-locate) method) failed.
448 this.fire('locationerror', {
449 code: c,
450 message: 'Geolocation error: ' + message + '.'
451 });
452 },
453
454 _handleGeolocationResponse: function (pos) {
455 var lat = pos.coords.latitude,
456 lng = pos.coords.longitude,
457 latlng = new L.LatLng(lat, lng),
458 bounds = latlng.toBounds(pos.coords.accuracy),
459 options = this._locateOptions;
460
461 if (options.setView) {
462 var zoom = this.getBoundsZoom(bounds);
463 this.setView(latlng, options.maxZoom ? Math.min(zoom, options.maxZoom) : zoom);
464 }
465
466 var data = {
467 latlng: latlng,
468 bounds: bounds,
469 timestamp: pos.timestamp
470 };
471
472 for (var i in pos.coords) {
473 if (typeof pos.coords[i] === 'number') {
474 data[i] = pos.coords[i];
475 }
476 }
477
478 // @event locationfound: LocationEvent
479 // Fired when geolocation (using the [`locate`](#map-locate) method)
480 // went successfully.
481 this.fire('locationfound', data);
482 },
381483
382484 // TODO handler.addTo
383485 // TODO Appropiate docs section?
+0
-112
src/map/ext/Map.Geolocation.js less more
0 /*
1 * Provides L.Map with convenient shortcuts for using browser geolocation features.
2 */
3
4 // @namespace Map
5
6 L.Map.include({
7 // @section Geolocation methods
8 _defaultLocateOptions: {
9 timeout: 10000,
10 watch: false
11 // setView: false
12 // maxZoom: <Number>
13 // maximumAge: 0
14 // enableHighAccuracy: false
15 },
16
17 // @method locate(options?: Locate options): this
18 // Tries to locate the user using the Geolocation API, firing a [`locationfound`](#map-locationfound)
19 // event with location data on success or a [`locationerror`](#map-locationerror) event on failure,
20 // and optionally sets the map view to the user's location with respect to
21 // detection accuracy (or to the world view if geolocation failed).
22 // Note that, if your page doesn't use HTTPS, this method will fail in
23 // modern browsers ([Chrome 50 and newer](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins))
24 // See `Locate options` for more details.
25 locate: function (options) {
26
27 options = this._locateOptions = L.extend({}, this._defaultLocateOptions, options);
28
29 if (!('geolocation' in navigator)) {
30 this._handleGeolocationError({
31 code: 0,
32 message: 'Geolocation not supported.'
33 });
34 return this;
35 }
36
37 var onResponse = L.bind(this._handleGeolocationResponse, this),
38 onError = L.bind(this._handleGeolocationError, this);
39
40 if (options.watch) {
41 this._locationWatchId =
42 navigator.geolocation.watchPosition(onResponse, onError, options);
43 } else {
44 navigator.geolocation.getCurrentPosition(onResponse, onError, options);
45 }
46 return this;
47 },
48
49 // @method stopLocate(): this
50 // Stops watching location previously initiated by `map.locate({watch: true})`
51 // and aborts resetting the map view if map.locate was called with
52 // `{setView: true}`.
53 stopLocate: function () {
54 if (navigator.geolocation && navigator.geolocation.clearWatch) {
55 navigator.geolocation.clearWatch(this._locationWatchId);
56 }
57 if (this._locateOptions) {
58 this._locateOptions.setView = false;
59 }
60 return this;
61 },
62
63 _handleGeolocationError: function (error) {
64 var c = error.code,
65 message = error.message ||
66 (c === 1 ? 'permission denied' :
67 (c === 2 ? 'position unavailable' : 'timeout'));
68
69 if (this._locateOptions.setView && !this._loaded) {
70 this.fitWorld();
71 }
72
73 // @section Location events
74 // @event locationerror: ErrorEvent
75 // Fired when geolocation (using the [`locate`](#map-locate) method) failed.
76 this.fire('locationerror', {
77 code: c,
78 message: 'Geolocation error: ' + message + '.'
79 });
80 },
81
82 _handleGeolocationResponse: function (pos) {
83 var lat = pos.coords.latitude,
84 lng = pos.coords.longitude,
85 latlng = new L.LatLng(lat, lng),
86 bounds = latlng.toBounds(pos.coords.accuracy),
87 options = this._locateOptions;
88
89 if (options.setView) {
90 var zoom = this.getBoundsZoom(bounds);
91 this.setView(latlng, options.maxZoom ? Math.min(zoom, options.maxZoom) : zoom);
92 }
93
94 var data = {
95 latlng: latlng,
96 bounds: bounds,
97 timestamp: pos.timestamp
98 };
99
100 for (var i in pos.coords) {
101 if (typeof pos.coords[i] === 'number') {
102 data[i] = pos.coords[i];
103 }
104 }
105
106 // @event locationfound: LocationEvent
107 // Fired when geolocation (using the [`locate`](#map-locate) method)
108 // went successfully.
109 this.fire('locationfound', data);
110 }
111 });