Search code examples
pythonmathgeometrygisangle

Difference in calculating bearing


I am trying to calculate the bearing between true north and a point in the ocean (lat, long) of (38.16418244422394, -38.933453981070926)

I read this post and this post and saw many different suggestions.

Using geographiclib, I get a value of -38.806138500542176. However calculating manually, I get 297.9944573116836. Why am I getting two different answers? Which one is correct?

Minimal example:

import math
from geographiclib.geodesic import Geodesic

def get_bearing(lat1,lon1,lat2,lon2):
    dLon = lon2 - lon1
    y = math.sin(dLon) * math.cos(lat2)
    x = math.cos(lat1)*math.sin(lat2) - math.sin(lat1)*math.cos(lat2)*math.cos(dLon)
    brng = np.rad2deg(math.atan2(y, x))
    if brng < 0: brng+= 360
    return brng

def get_bearing_geodesic(lat1, lon1, lat2, lon2):
    Geodesic.WGS84.Inverse(lat1, lon1, lat2, lon2)
    return Geodesic.WGS84.Inverse(lat1, lon1, lat2, lon2)['azi1']

true_north_lat = 0
true_north_lon = 0
oil_rig_lat = 38.16418244422394
oil_rig_lon = -38.933453981070926

print("Manually: {}".format(get_bearing(true_north_lat, true_north_lon, oil_rig_lat, oil_rig_lon)))
print("Geodesic: {}".format(get_bearing_geodesic(true_north_lat, true_north_lon, oil_rig_lat, oil_rig_lon)))

Which is the correct answer? Why are they different? Which answer produces the angle in degrees from true north to the oil rig?


Solution

  • math.sin and math.cos take radians as arguments. Change the manual function to this (returning degrees at the end):

    def get_bearing(lat1,lon1,lat2,lon2):
        dLon = lon2 - lon1
        y = math.cos(math.radians(lat1)) * math.sin(math.radians(lat2)) - math.sin(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.cos(math.radians(dLon))
        x = math.cos(math.radians(lat2)) * math.sin(math.radians(dLon))
        brng = math.degrees(math.atan2(x, y))
        if brng < 0: brng+= 360
        return brng
    
    >>> get_bearing(true_north_lat, true_north_lon, oil_rig_lat, oil_rig_lon)
    321.3540270387211