Wednesday 24 July 2013

Phonegap Geo Location Library



#This Library is used to get  Latitude-Longitude at given time intervals for mobile hybrid application using phonegap.

#Just Include this code in a  js  file   and call 'gpsLib.getLocation(successCallback,failurecallBack,option)' function  once when document gets ready.
  
#make ensure that cordova js must be included in your  file.

#The function has first two mandatory parameters( call back functions) and the last one is optional parameter.

#option: {'_intervals':60000,'_accuracy':150,'_speed':120,'_minIntervals':15*1000}

    _intervals : Time interval(in milli seconds) to return data.
   _accuracy : (in meters) only accept gps data which accuracy  will be less than given value( say here 150)
   _speed      :  Speed of the device must be less than given speed.
_minIntervals: It defines  within this time interval ,we select a most accurate data.

#Output :   [{'lat':8.00054656,'lng': 7.9567565865,'timestamp':4564356746546},              {'lat':8.05454656,'lng': 7.567565865,'timestamp':4564356746556}]

--------------------------------------------------------------------------------------------------------------------------
   var gpsLib={};

  gpsLib.getLocation = function(success,failure,option){
 var _success = success;
  var _failure = failure;
var _options = option;
var _gpsObjArray=[];
var _latLongObjArray=[];
var _watchId = null;
  var _timeoutId=null;
 
  var _init = function (){
         _initOptions();
       _initCallBack();
_initGPS();
       _timeoutId = window.setTimeout(_filterGPS,10*1000);
  };

var _initOptions = function (){
     if(_options==null){
         //intervals is time interval for callback
       _options =  {'_intervals':60000,'_accuracy':150,'_speed':120,'_minIntervals':15*1000};
}else{
       // intervals must be at least 30 seconds
if(typeof(_options._intervals)=='undefined' || _options._intervals < 30000){
_options._intervals = 60000;
}
   if(typeof(_options._accuracy)=='undefined'){
_options._accuracy = 150;
}
if(typeof(_options._speed)=='undefined'){
_options._speed = 120;
}
if(typeof(_options._minIntervals)=='undefined'){
_options._minIntervals = 15*1000;//15 sec
}
}
};

var _initCallBack = function (){
if(_success==null){
    _success =function(){};
   }
if(_failure==null){
   _failure = function(){};;
}
 };

 var _initGPS = function (){

 _stopGPS();
    _gpsObjArray.length=0;
 _latLongObjArray.length=0;
    _getGPS();
    _timeoutId = window.setTimeout(_filterGPS,_options._intervals);
 };

var _getGPS = function (){
  var tempGpsObjArray=[];
    var prevTimestamp = 0;

 _watchId = navigator.geolocation.watchPosition(
     //success
      function(position){
 var position =JSON.parse(JSON.stringify(position));
     position.timestamp = new Date().getTime();
  //select the data which has accuracy at least given value
 if(position.coords.accuracy <= _options._accuracy){

 if((position.timestamp - prevTimestamp) >= _options._minIntervals){
         prevTimestamp = position.timestamp;
         var bestPosition = position;
 var counter = tempGpsObjArray.length;
         tempGpsObjArray.push(position);

 for(var i=0; i< counter; i++){
 if(tempGpsObjArray[i].coords.accuracy < bestPosition.coords.accuracy){
bestPosition = tempGpsObjArray[i];
 }
 }

       _gpsObjArray.push(bestPosition);
       tempGpsObjArray.length=0;
 }else{
        tempGpsObjArray.push(position);
 }

 
 }
 },
 // Error
 function(error){
      console.log('watchPosition:'+error);
 },
 // Settings
 { maximumAge: 5000, timeout: 7000,enableHighAccuracy: true }
  );
  };

var _filterGPS = function (){
 var speed;
    var timeDiff;
if(_gpsObjArray.length==1){
_latLongObjArray.push({'lat':_gpsObjArray[0].coords.latitude,'lng':          _gpsObjArray[0].coords.longitude,'timestamp':_gpsObjArray[0].timestamp});
}else{
     for(var i = 0; i < _gpsObjArray.length; i++){
if(i == (_gpsObjArray.length - 1)){
           break;
          }
 timeDiff=_gpsObjArray[i+1].timestamp - _gpsObjArray[i].timestamp;
         speed =  _calSpeed(_gpsObjArray[i].coords.latitude, _gpsObjArray[i].coords.longitude,      _gpsObjArray[i+1].coords.latitude, _gpsObjArray[i+1].coords.longitude,timeDiff);
 
   if(speed <= _options._speed){
  _latLongObjArray.push({'lat':_gpsObjArray[i].coords.latitude,'lng':              _gpsObjArray[i].coords.longitude,'timestamp':_gpsObjArray[i].timestamp});
   }else{
_gpsObjArray.splice(i+1,1);
i--;
}
     }//end for loop
}//end else

_sendGPS();
     };

var _sendGPS = function (){

if(_latLongObjArray.length >0){
  _success(_latLongObjArray);
  _initGPS();
}else{
navigator.geolocation.getCurrentPosition(
    function(position){
 if(position.coords.accuracy <= _options._accuracy){
   var timestamp = new Date().getTime();
   console.log('lat Val:'+position.coords.latitude+' lng value:'+ position.coords.longitude+' timestamp:'+timestamp);
      _success([{'lat':position.coords.latitude,'lng': position.coords.longitude,'timestamp':timestamp}]);
 }else{
_failure();
 }

 _initGPS();
},
function(error){

console.log('CurrentPosition:'+error);
   _failure();
_initGPS();
},
{maximumAge: 5000, timeout: 7000,enableHighAccuracy: true }
);
}

     };

var _stopGPS = function (){
if(_watchId != null){
 navigator.geolocation.clearWatch(_watchId);
}

if(_timeoutId != null){
  clearTimeout(_timeoutId);
}

     };

 // return speed in km/hr
var _calSpeed= function(lat1, lon1, lat2, lon2,interval){
 var R = 6371; // km
 var dLat = (lat2-lat1) * (Math.PI / 180);
 var dLon = (lon2-lon1) * (Math.PI / 180);
 var lat1 = lat1 * (Math.PI / 180);
 var lat2 = lat2 * (Math.PI / 180);

 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));
 //get distance
 var d = R * c;
          //get speed(Km/hr)
 var s = (d * 1000 * 60 * 60) / interval;
          return s;
}

    _init();
};
--------------------------------------------------------------------------------------------------------------------------