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?
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