[GIS] How to calculate Bearing between two GPS points

cgpsjavascript

The following returns 150 degrees using C# converted from JavaScript Bearing formulas, but Google earth returns 210 degrees for the same values.
The broken code is GetBearing() but I've also included Calculate() to show hard coded test values and ParseCoordinate() to show that I am converting Degree-Minute-Second to radian decimal degrees for GetBearing(). Are the JavaScript Bearing formulas wrong?

double DEG_PER_RAD = (180.0/Math.PI);
// Return Bearing (degrees)
private double GetBearing(double lat1, double lon1, double lat2, double lon2)
{
    var dLon = lon2 - lon1;
    var y = Math.Sin(dLon) * Math.Cos(lat2);
    var x = Math.Cos(lat1)*Math.Sin(lat2)-Math.Sin(lat1)*Math.Cos(lat2)*Math.Cos(dLon);
    return DEG_PER_RAD*Math.Atan2(y, x);
}
private void Calculate()
{
    var lon1 = ParseCoordinate("38 51 30.5");
    var lat1 = ParseCoordinate("78 12 33.8");
    var lon2 = ParseCoordinate("38 45 46.2");
    var lat2 = ParseCoordinate("78 16 46.0");
    var bearing = GetBearing(lat1, lon1, lat2, lon2);
    // Show bearing
    ...
}
// Convert Degree-Minute-Second to Degree.ddd
private double ParseCoordinate(string coordinate)
{
    var dms = coordinate.Split(' ');
    var rVal = 0.0;
    var i = 0;
    foreach (var s in dms)
    {
        double d;
        double.TryParse(s, out d);
        rVal += (d/(Math.Pow(60.0, i++)));
    }
    rVal /= DEG_PER_RAD;
    return rVal;
}

Best Answer

The two numbers are actually just mirrored bearings (360 - 150 = 210), so you either specified the longitude with the wrong sign (maybe it is 38 degrees west) or you're missing a sign in dLon or x calculation.