Search code examples
geolocationgpslatitude-longitude

how to use direction angle and speed to calculate next time's latitude and longitude


I have know my current position({lat:x,lon:y}) and I know my speed and direction angle; How to predict next position at next time?


Solution

  • First, calculate the distance you will travel based on your current speed and your known time interval ("next time"):

    distance = speed * time
    

    Then you can use this formula to calculate your new position (lat2/lon2):

    lat2 =asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc))
    dlon=atan2(sin(tc)*sin(d)*cos(lat1),cos(d)-sin(lat1)*sin(lat2))
    lon2=mod( lon1-dlon +pi,2*pi )-pi
    

    For an implementation in Javascript, see the function LatLon.prototype.destinationPoint on this page

    Update for those wishing a more fleshed-out implementation of the above, here it is in Javascript:

      /**
      * Returns the destination point from a given point, having travelled the given distance
      * on the given initial bearing.
      *
      * @param   {number} lat - initial latitude in decimal degrees (eg. 50.123)
      * @param   {number} lon - initial longitude in decimal degrees (e.g. -4.321)
      * @param   {number} distance - Distance travelled (metres).
      * @param   {number} bearing - Initial bearing (in degrees from north).
      * @returns {array} destination point as [latitude,longitude] (e.g. [50.123, -4.321])
      *
      * @example
      *     var p = destinationPoint(51.4778, -0.0015, 7794, 300.7); // 51.5135°N, 000.0983°W
      */
      function destinationPoint(lat, lon, distance, bearing) {
         var radius = 6371e3; // (Mean) radius of earth
    
         var toRadians = function(v) { return v * Math.PI / 180; };
         var toDegrees = function(v) { return v * 180 / Math.PI; };
    
         // sinφ2 = sinφ1·cosδ + cosφ1·sinδ·cosθ
         // tanΔλ = sinθ·sinδ·cosφ1 / cosδ−sinφ1·sinφ2
         // see mathforum.org/library/drmath/view/52049.html for derivation
    
         var δ = Number(distance) / radius; // angular distance in radians
         var θ = toRadians(Number(bearing));
    
         var φ1 = toRadians(Number(lat));
         var λ1 = toRadians(Number(lon));
    
         var sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1);
         var sinδ = Math.sin(δ), cosδ = Math.cos(δ);
         var sinθ = Math.sin(θ), cosθ = Math.cos(θ);
    
         var sinφ2 = sinφ1*cosδ + cosφ1*sinδ*cosθ;
         var φ2 = Math.asin(sinφ2);
         var y = sinθ * sinδ * cosφ1;
         var x = cosδ - sinφ1 * sinφ2;
         var λ2 = λ1 + Math.atan2(y, x);
    
         return [toDegrees(φ2), (toDegrees(λ2)+540)%360-180]; // normalise to −180..+180°
      }