176 lines
7.6 KiB
JavaScript
Executable File
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();
|
|
}); |