import math class Location: EARTH_RADIUS_METRES = 6.371e6 def __init__(self, latitude, longitude, altitude): self.latitude = latitude self.longitude = longitude self.altitude = altitude @property def latitude_radian(self): return math.radians(self.latitude) @property def longitude_radian(self): return math.radians(self.longitude) @staticmethod def haversine(angle_rad): # http://mathworld.wolfram.com/Haversine.html return math.sin(angle_rad / 2) ** 2 @staticmethod def haversine_inv(hav): # return math.atan2(math.sqrt(hav), math.sqrt(1-hav)) * 2 return math.asin(math.sqrt(hav)) * 2 @staticmethod def haversine_distance_metres(a, b): # https://en.wikipedia.org/wiki/Haversine_formula hav = Location.haversine(b.latitude_radian - a.latitude_radian) \ + math.cos(a.latitude_radian) * math.cos(b.latitude_radian) \ * Location.haversine(b.longitude_radian - a.longitude_radian) return Location.haversine_inv(hav) * Location.EARTH_RADIUS_METRES