Add geolocation button which uses device GPS
This commit is contained in:
parent
57c9fcc5aa
commit
a566ab6725
6 changed files with 299 additions and 32 deletions
133
vendor/Leaflet.AccuratePosition.js
vendored
Normal file
133
vendor/Leaflet.AccuratePosition.js
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
/**
|
||||
* 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 + '.'
|
||||
});
|
||||
}
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue