Wegwichtel/api/geolocation.js
2026-06-16 09:17:23 +02:00

176 lines
7.6 KiB
JavaScript
Executable File

/****************************************************************************************************************
* CLASS geoLocation: helper-class for fetching geolocation (among others latitude, longitude) *
* implemented as singleton-object *
* *
* methods: init(void):void --> initialize object and start fetching position *
* startWatcher(void):void --> starts intervalled position-watching (ran by init) *
* getPosFromServer(void):void --> fetch GPS-position from server (actually one fixed point) *
* distance(Object{lat:Number ,lon:Number} [,Object{lat:Number ,lon:Number}]):Number *
* └-> distance between two positions (or given and current one, if second one missing) *
* *
* events: body.geoLocationError:Object{ *
* error:Object{ *
* number:Number, *
* message:String *
* }, *
* position:Object{ *
* latitude:Number, *
* longitude:Number, *
* accuracy:Number, *
* timestamp:Number *
* } *
* } *
* body.geoLocationGot:Object{ *
* position:Object{ *
* latitude:Number, *
* longitude:Number, *
* accuracy:Number, *
* timestamp:Number *
* } *
* } *
****************************************************************************************************************/
var geoLocation = { // implement as singleton
latitude: null,
longitude: null,
accuracy: null,
timestamp: null,
_pwatcher: null,
_ptimer: null,
_disableWatcherAt: 50,
_config: {
enableHighAccuracy: true,
maximumAge: 10000, // 10 sec max cache lifetime (if geoposition cached)
timeout: 60000 // 60 sec timeout
},
// event listeners
_geoReady: function(position) {
console.debug('geolocation api present - activate watcher');
// this.startWatcher();
// this._gotLocation(position);
},
_geoError: function(error) {
console.debug('gelocation api not present or error');
this._handle_error(error);
},
_gotLocation: function(position) {
this.latitude = position.coords.latitude;
this.longitude = position.coords.longitude;
this.accuracy = position.coords.accuracy;
this.timestamp = position.timestamp;
if (this.accuracy <= this._disableWatcherAt) // disable with timeout, if accurate location found
{
console.debug('disable watcher for 60 seconds', this._pwatcher);
if (this._pwatcher !== null)
{
console.debug('watcher cleared');
navigator.geolocation.clearWatch(this._pwatcher);
this._pwatcher = null;
}
that = this;
this._ptimer = setTimeout(function() {that.startWatcher.apply(that, arguments);}, 60000);
}
console.debug('got Position: ' + this.latitude + ', ' + this.longitude + '(' + this.accuracy + 'm < ' + this._disableWatcherAt + ': ' + (this.accuracy <= this._disableWatcherAt) + ')');
$('body').trigger('geoLocationGot', {'position':{latitude: this.latitude, longitude: this.longitude, accuracy: this.accuracy, timestamp: this.timestamp}});
},
_handle_error: function(error) {
console.debug(error);
switch(error.code)
{
case error.PERMISSION_DENIED:
if (_pwatcher != 'null') navigator.geolocation.clearWatch(_pwatcher);
_pwatcher = 'null';
break;
case error.POSITION_UNAVAILABLE:
break;
case error.TIMEOUT:
break;
default:
break;
}
$('body').trigger('geoLocationError',{'error':error,'position':{latitude: this.latitude, longitude: this.longitude, accuracy: this.accuracy, timestamp: this.timestamp}});
},
init: function() {
var that = this;
if (navigator.geolocation) {
console.debug('test geolocation api');
navigator.geolocation.getCurrentPosition(
function() {that._geoReady.apply(that, arguments);},
function() {that._geoError.apply(that, arguments);},
this._config
);
}
},
startWatcher: function() {
console.debug('waiting for location');
that = this;
if (this._pwatcher !== null) navigator.geolocation.clearWatch(this._pwatcher);
clearTimeout(this._ptimer);
this._pwatcher = navigator.geolocation.watchPosition(
function() {that._gotLocation.apply(that, arguments);},
function() {that._handle_error.apply(that, arguments);},
this._config
);
console.debug('watcher started',this._pwatcher);
},
getPosFromServer: function() {
console.debug('get position from server');
that = this;
$.getJSON('shippos.php', function(data) {
console.debug('got server response: ',data);
that._gotLocation.call(that, data);
});
},
//haversine formula for distance between two positions in m (see http://www.movable-type.co.uk/scripts/latlong.html)
distance:function(c1,c2)
{
PI180=Math.PI / 180;
if(!c1) return false;
if(!c2){ c2={'latitude':this.latitude, 'longitude':this.longitude}; }
var dLat = (c2.latitude-c1.latitude) * PI180; // delta in rad
var dLon = (c2.longitude-c1.longitude) * PI180;
var lat1 = c1.latitude * PI180;
var lat2 = c2.latitude * PI180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return (6371000 * c); // earth-radius in m * 1000
}
}; // geoLocation
$(document).ready(function() {
$('body').on('geoLocationGot', function(e) {
$('#no-gps').slideUp({duration: 500});
});
$('body').on('geoLocationError',function(e) {
$('#no-gps').slideDown({duration: 500});
});
geoLocation.init();
});