
Number.prototype.toRad = function() {  // convert degrees to radians  
   return this * Math.PI / 180;
}

Number.prototype.toDeg = function() {  // convert radians to degrees (signed)  
   return this * 180 / Math.PI;
}

function Position(lon,lat) 
{
   this.Longitude = lon;
   this.Latitude = lat;
   
   this.ToRadians = function()
   {
       return new Position((Math.PI*this.Longitude)/180.0,(Math.PI*this.Latitude)/180.0);
   }
   
    this.ToDegrees = function()
   {
       return new Position((Math.PI*this.Longitude)/180.0,(Math.PI*this.Latitude)/180.0);
   }
   
   this.BearingTo = function(target) 
   {
  
      var p1 = this.ToRadians();
      var p2 = target.ToRadians();
          
      var y = Math.sin(p2.Longitude-p1.Longitude) * Math.cos(p2.Latitude);
      var x = Math.cos(p1.Latitude)*Math.sin(p2.Latitude) -
              Math.sin(p1.Latitude)*Math.cos(p2.Latitude)*Math.cos(p2.Longitude-p1.Longitude);
   
      return (Math.atan2(y, x) * 180 / Math.PI +360) % 360;
   }
   
   this.DistanceTo = function(target) 
   {
       // returns kilometers
      var R = 6371;  // earth's mean radius in km 
  
      var p1 = this.ToRadians();
      var p2 = target.ToRadians();   
 
      var dLat  = p2.Latitude - p1.Latitude;
      var dLong = p2.Longitude - p1.Longitude;

      var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.cos(p1.Latitude) * Math.cos(p2.Latitude) * Math.sin(dLong/2) * Math.sin(dLong/2);
      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      var d = R * c;
	
      return d;
   }
   
   /* * calculate destination point given start point, initial bearing (deg) and distance (km) *   see http://williams.best.vwh.net/avform.htm#LL */
   this.TranslateTo = function(brng, d) {  
      var R = 6371; // earth's mean radius in km 
      
      posRad = this.ToRadians(); 
      
      brng = brng * Math.PI / 180.0; 
      
      var lat2 = Math.asin( Math.sin(posRad.Latitude)*Math.cos(d/R) + Math.cos(posRad.Latitude)*Math.sin(d/R)*Math.cos(brng) );  
          
      var lon2 =  posRad.Longitude + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(posRad.Latitude), Math.cos(d/R)-Math.sin(posRad.Latitude)*Math.sin(lat2));  
      
      lon2 = (lon2+Math.PI)%(2*Math.PI) - Math.PI;  // normalise to -180...+180  
      
      if (isNaN(lat2) || isNaN(lon2)) return null; 
      return new Position(lon2.toDeg(), lat2.toDeg());
   }
} 
