forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			134 lines
		
	
	
		
			No EOL
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			No EOL
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | ||
|  * Leaflet.AccuratePosition aims to provide an accurate device location when simply calling map.locate() doesn’t.
 | ||
|  * https://github.com/m165437/Leaflet.AccuratePosition
 | ||
|  *
 | ||
|  * Greg Wilson's getAccurateCurrentPosition() forked to be a Leaflet plugin
 | ||
|  * https://github.com/gwilson/getAccurateCurrentPosition
 | ||
|  *
 | ||
|  * Copyright (C) 2013 Greg Wilson, 2014 Michael Schmidt-Voigt
 | ||
|  */
 | ||
| 
 | ||
| L.Map.include({
 | ||
|     _defaultAccuratePositionOptions: {
 | ||
|         maxWait: 10000,
 | ||
|         desiredAccuracy: 20
 | ||
|     },
 | ||
| 
 | ||
|     findAccuratePosition: function (options) {
 | ||
| 
 | ||
|         if (!navigator.geolocation) {
 | ||
|             this._handleAccuratePositionError({
 | ||
|                 code: 0,
 | ||
|                 message: 'Geolocation not supported.'
 | ||
|             });
 | ||
|             return this;
 | ||
|         }
 | ||
| 
 | ||
|         this._accuratePositionEventCount = 0;
 | ||
|         this._accuratePositionOptions = L.extend(this._defaultAccuratePositionOptions, options);
 | ||
|         this._accuratePositionOptions.enableHighAccuracy = true;
 | ||
|         this._accuratePositionOptions.maximumAge = 0;
 | ||
| 
 | ||
|         if (!this._accuratePositionOptions.timeout)
 | ||
|             this._accuratePositionOptions.timeout = this._accuratePositionOptions.maxWait;
 | ||
| 
 | ||
|         var onResponse = L.bind(this._checkAccuratePosition, this),
 | ||
|             onError = L.bind(this._handleAccuratePositionError, this),
 | ||
|             onTimeout = L.bind(this._handleAccuratePositionTimeout, this);
 | ||
| 
 | ||
|         this._accuratePositionWatchId = navigator.geolocation.watchPosition(
 | ||
|             onResponse,
 | ||
|             onError,
 | ||
|             this._accuratePositionOptions);
 | ||
| 
 | ||
|         this._accuratePositionTimerId = setTimeout(
 | ||
|             onTimeout,
 | ||
|             this._accuratePositionOptions.maxWait);
 | ||
|     },
 | ||
| 
 | ||
|     _handleAccuratePositionTimeout: function() {
 | ||
|         navigator.geolocation.clearWatch(this._accuratePositionWatchId);
 | ||
| 
 | ||
|         if (typeof this._lastCheckedAccuratePosition !== 'undefined') {
 | ||
|             this._handleAccuratePositionResponse(this._lastCheckedAccuratePosition);
 | ||
|         } else {
 | ||
|             this._handleAccuratePositionError({
 | ||
|                 code: 3,
 | ||
|                 message: 'Timeout expired'
 | ||
|             });
 | ||
|         }
 | ||
| 
 | ||
|         return this;
 | ||
|     },
 | ||
| 
 | ||
|     _cleanUpAccuratePositioning: function () {
 | ||
|         clearTimeout(this._accuratePositionTimerId);
 | ||
|         navigator.geolocation.clearWatch(this._accuratePositionWatchId);
 | ||
|     },
 | ||
| 
 | ||
|     _checkAccuratePosition: function (pos) {
 | ||
|         var accuracyReached = pos.coords.accuracy <= this._accuratePositionOptions.desiredAccuracy;
 | ||
| 
 | ||
|         this._lastCheckedAccuratePosition = pos;
 | ||
|         this._accuratePositionEventCount = this._accuratePositionEventCount + 1;
 | ||
| 
 | ||
|         if (accuracyReached && (this._accuratePositionEventCount > 1)) {
 | ||
|             this._cleanUpAccuratePositioning();
 | ||
|             this._handleAccuratePositionResponse(pos);
 | ||
|         } else {
 | ||
|             this._handleAccuratePositionProgress(pos);
 | ||
|         }
 | ||
|     },
 | ||
| 
 | ||
|     _prepareAccuratePositionData: 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(Math.PI / 180 * lat),
 | ||
| 
 | ||
|             bounds = L.latLngBounds(
 | ||
|                 [lat - latAccuracy, lng - lngAccuracy],
 | ||
|                 [lat + latAccuracy, lng + lngAccuracy]);
 | ||
| 
 | ||
|         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];
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         return data;
 | ||
|     },
 | ||
| 
 | ||
|     _handleAccuratePositionProgress: function (pos) {
 | ||
|         var data = this._prepareAccuratePositionData(pos);
 | ||
|         this.fire('accuratepositionprogress', data);
 | ||
|     },
 | ||
| 
 | ||
|     _handleAccuratePositionResponse: function (pos) {
 | ||
|         var data = this._prepareAccuratePositionData(pos);
 | ||
|         this.fire('accuratepositionfound', data);
 | ||
|     },
 | ||
| 
 | ||
|     _handleAccuratePositionError: function (error) {
 | ||
|         var c = error.code,
 | ||
|             message = error.message ||
 | ||
|                 (c === 1 ? 'permission denied' :
 | ||
|                     (c === 2 ? 'position unavailable' : 'timeout'));
 | ||
| 
 | ||
|         this._cleanUpAccuratePositioning();
 | ||
| 
 | ||
|         this.fire('accuratepositionerror', {
 | ||
|             code: c,
 | ||
|             message: 'Geolocation error: ' + message + '.'
 | ||
|         });
 | ||
|     }
 | ||
| });
 | ||
| console.log("Find accurate position script loaded"); |