Instantly share code, notes, and snippets.

# jeromer/compassbearing.py

Last active February 21, 2024 13:31
Show Gist options
• Save jeromer/2005586 to your computer and use it in GitHub Desktop.
compass bearing between two points in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 # LICENSE: public domain def calculate_initial_compass_bearing(pointA, pointB): """ Calculates the bearing between two points. The formulae used is the following: θ = atan2(sin(Δlong).cos(lat2), cos(lat1).sin(lat2) − sin(lat1).cos(lat2).cos(Δlong)) :Parameters: - `pointA: The tuple representing the latitude/longitude for the first point. Latitude and longitude must be in decimal degrees - `pointB: The tuple representing the latitude/longitude for the second point. Latitude and longitude must be in decimal degrees :Returns: The bearing in degrees :Returns Type: float """ if (type(pointA) != tuple) or (type(pointB) != tuple): raise TypeError("Only tuples are supported as arguments") lat1 = math.radians(pointA[0]) lat2 = math.radians(pointB[0]) diffLong = math.radians(pointB[1] - pointA[1]) x = math.sin(diffLong) * math.cos(lat2) y = math.cos(lat1) * math.sin(lat2) - (math.sin(lat1) * math.cos(lat2) * math.cos(diffLong)) initial_bearing = math.atan2(x, y) # Now we have the initial bearing but math.atan2 return values # from -180° to + 180° which is not what we want for a compass bearing # The solution is to normalize the initial bearing as shown below initial_bearing = math.degrees(initial_bearing) compass_bearing = (initial_bearing + 360) % 360 return compass_bearing

Thank you very much 🥇

### pedrocamargo commented Apr 23, 2017

What is the license for this code, @jeromer?

up !

### fredvollmer commented May 26, 2017

Very nice, especially all the explanation. Thank you!

thank you

### mapcloud commented Jul 27, 2017

Thank you for sharing!

great

Great!!

awesome work man

Thanks!

### zaarcvon commented Feb 9, 2018

Thank you for sharing!

I have an issue with that, the output is different then expected: A = (-73.933781942,40.7062912231)
B = (-73.93390547,40.7062643692)
bearing is 183.44288775507985 but it should be nearly 270
when BA: bearing is 3.4429135601084795 but it should be almost 90
could it be that there is a wired 90 degree changing required somewhere?

Update yes @schicks you are right, i messed up the x and y and i wasn't aware that i can use the wgs84 coordinates without transforming to a 2D
Now it gives back 253.99863197083152 what is expected

### schicks commented Feb 27, 2018

@blackgis, I think you may have the arguments a little messed up. They should be (lat, lon), not (lon, lat).

thank you!

### Amytipple commented May 25, 2018

Thanks!

import math
x = math.sin(longdifference) * math.cos(lat2)
y = math.cos(lat1) * math.sin(lat2) - (math.sin(lat1)* math.cos(lat2) * math.cos(longdifference))
initial_bearing = math.atan2(x, y)
initial_bearing = math.degrees(initial_bearing)
compass_bearing = (initial_bearing + 360) % 360
print(initial_bearing, "°")

Output:
Lattitude1:47.5606
Lattitude2:47.594719
Longitude1:-52.743099
Longitude2:-52.685001

Result: 1.1481674985452277 ° this should be 49°, why i am getting wrong value ?

### tboutaour commented Jul 9, 2019

Great work! It's what I looking for. Thank you

Good job!

### Mantej-Singh commented Nov 12, 2019

Thanks for this method, really helped me in a project

Thank you!

### ErPraveenSingh commented Sep 10, 2020

Thanks for providing a good option. It is a really helpful for us.

### neeveermoree commented Dec 22, 2020

Dude, I want to have kids from you <3. Excellent work!!!

### gmazet commented Feb 16, 2021

Much faster than importing obspy.geodetics.gps2dist_azimuth
Thanks a lot

### GAnagno commented Jun 7, 2021

Great work! Thanks very much 👍

### tobixen commented Jun 24, 2021

This is good enough for me, though I think the algorithm is a bit simplified. It will probably give inaccurate results when used over long distances or when one is close to the poles. I find it strange that there isn't anything easily available through the geopy library.

Excellent work

### normanheckscher commented Feb 17, 2022

Thanks. Fixed my problem with this one.

### HCaspari commented Mar 6, 2023

Thank you this worked 👯

### BritishTechGuru commented Aug 23, 2023

I like this. I'll combine this with Vincenty's formula to return bearing and distance.