/* * Provides L.Map with convenient shortcuts for using browser geolocation features. */ L.Map.include({ _defaultLocateOptions: { watch: false, setView: false, maxZoom: Infinity, timeout: 10000, maximumAge: 0, enableHighAccuracy: false }, locate: function (/*Object*/ options) { options = this._locateOptions = L.extend(this._defaultLocateOptions, options); if (!navigator.geolocation) { 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; }, stopLocate: function () { if (navigator.geolocation) { 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(); } 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), latAccuracy = 180 * pos.coords.accuracy / 40075017, lngAccuracy = latAccuracy / Math.cos(L.LatLng.DEG_TO_RAD * lat), bounds = L.latLngBounds( [lat - latAccuracy, lng - lngAccuracy], [lat + latAccuracy, lng + lngAccuracy]), options = this._locateOptions; if (options.setView) { var zoom = Math.min(this.getBoundsZoom(bounds), options.maxZoom); this.setView(latlng, 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]; } } this.fire('locationfound', data); } });