delphigeolocationgeospatial

How do I calculate the Azimuth (angle to north) between two WGS84 coordinates


I have got two WGS84 coordinates, latitude and longitude in degrees. These points are rather close together, e.g. only one metre apart.

Is there an easy way to calculate the azimuth of the line between these points, that is, the angle to north?

The naive approach would be to assume a Cartesian coordinate system (because these points are so close together) and just use

sin(a) = abs(L2-L1) / sqrt(sqr(L2-L1) + sqr(B2-B1))

a = azimuth L1, L2 = longitude B1, B2 = latitude

The error will be larger as the coordinates move away from the equator because there the distance between two longitudinal degrees becomes increasingly smaller than the one between two latitudinal degrees (which remains constant).

I found some quite complex formulas which I don't really want to implement because they seem to be overkill for points that are that close together and I don't need very high precision (two decimals are enough, one is probably fine either since there are other factors that reduce precision anyway, like the one the GPS returns).

Maybe I could just determine an approximate longitudinal correction factor depending on latitude and use somthing like this:

sin(a) = abs(L2*f-L1*f) / sqrt(sqr(L2*f-L1*f) + sqr(B2-B1))

where f is the correction factor

Any hints?

(I don't want to use any libraries for this, especially not ones that require runtime licenses. Any MPLed Delphi Source would be great.)


Solution

  • The formulas that you refer to in the text are to calculate the great circle distance between 2 points. Here's how I calculate the angle between points:

    uses Math, ...;
    ...
    
    const
      cNO_ANGLE=-999;
    
    ...
    
    function getAngleBetweenPoints(X1,Y1,X2,Y2:double):double;
    var
      dx,dy:double;
    begin
      dx := X2 - X1;
      dy := Y2 - Y1;
    
      if (dx > 0) then  result := (Pi*0.5) - ArcTan(dy/dx)   else
      if (dx < 0) then  result := (Pi*1.5) - ArcTan(dy/dx)   else
      if (dy > 0) then  result := 0                          else
      if (dy < 0) then  result := Pi                         else
                        result := cNO_ANGLE; // the 2 points are equal
    
      result := RadToDeg(result);
    end;