UNPKG

leaflet

Version:

JavaScript library for mobile-friendly interactive maps

113 lines (96 loc) 3.52 kB
/* * Provides L.Map with convenient shortcuts for using browser geolocation features. */ // @namespace Map L.Map.include({ // @section Geolocation methods _defaultLocateOptions: { timeout: 10000, watch: false // setView: false // maxZoom: <Number> // maximumAge: 0 // enableHighAccuracy: false }, // @method locate(options?: Locate options): this // Tries to locate the user using the Geolocation API, firing a [`locationfound`](#map-locationfound) // event with location data on success or a [`locationerror`](#map-locationerror) event on failure, // and optionally sets the map view to the user's location with respect to // detection accuracy (or to the world view if geolocation failed). // Note that, if your page doesn't use HTTPS, this method will fail in // modern browsers ([Chrome 50 and newer](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins)) // See `Locate options` for more details. locate: function (options) { options = this._locateOptions = L.extend({}, this._defaultLocateOptions, options); if (!('geolocation' in navigator)) { this._handleGeolocationError({ code: 0, message: 'Geolocation not supported.' }); return this; } var onResponse = L.bind(this._handleGeolocationResponse, this), onError = L.bind(this._handleGeolocationError, this); if (options.watch) { this._locationWatchId = navigator.geolocation.watchPosition(onResponse, onError, options); } else { navigator.geolocation.getCurrentPosition(onResponse, onError, options); } return this; }, // @method stopLocate(): this // Stops watching location previously initiated by `map.locate({watch: true})` // and aborts resetting the map view if map.locate was called with // `{setView: true}`. stopLocate: function () { if (navigator.geolocation && navigator.geolocation.clearWatch) { navigator.geolocation.clearWatch(this._locationWatchId); } if (this._locateOptions) { this._locateOptions.setView = false; } return this; }, _handleGeolocationError: function (error) { var c = error.code, message = error.message || (c === 1 ? 'permission denied' : (c === 2 ? 'position unavailable' : 'timeout')); if (this._locateOptions.setView && !this._loaded) { this.fitWorld(); } // @section Location events // @event locationerror: ErrorEvent // Fired when geolocation (using the [`locate`](#map-locate) method) failed. this.fire('locationerror', { code: c, message: 'Geolocation error: ' + message + '.' }); }, _handleGeolocationResponse: function (pos) { var lat = pos.coords.latitude, lng = pos.coords.longitude, latlng = new L.LatLng(lat, lng), bounds = latlng.toBounds(pos.coords.accuracy), options = this._locateOptions; if (options.setView) { var zoom = this.getBoundsZoom(bounds); this.setView(latlng, options.maxZoom ? Math.min(zoom, options.maxZoom) : zoom); } var data = { latlng: latlng, bounds: bounds, timestamp: pos.timestamp }; for (var i in pos.coords) { if (typeof pos.coords[i] === 'number') { data[i] = pos.coords[i]; } } // @event locationfound: LocationEvent // Fired when geolocation (using the [`locate`](#map-locate) method) // went successfully. this.fire('locationfound', data); } });