from math import radians from django.db.models import F, Value from django.db.models.functions import Radians, Sin, ATan2, Sqrt, Cos def calculate_distance(qs, client_lat: float, client_lon: float): """ Based on stackoverflow question: https://stackoverflow.com/a/19412565/10261581 Distance Unit is in Kilometres R = 6373.0 lat1 = radians(52.2296756) lon1 = radians(21.0122287) lat2 = radians(52.406374) lon2 = radians(16.9251681) dlon = lon2 - lon1 dlat = lat2 - lat1 a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2 c = 2 * atan2(sqrt(a), sqrt(1 - a)) distance = R * c print("Result: ", distance) print("Should be: ", 278.546, "km") """ earth_radius = 6373.0 client_lat, client_lon = radians(float(client_lat)), radians(float(client_lon)) if not client_lat: return qs.annotate( distance=Value(0), ) return qs.annotate( rlat=Radians('latitude'), rlon=Radians('longitude'), # a=sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2 # c = 2 * atan2(sqrt(a), sqrt(1 - a)) lat_diff=F('rlat') - client_lat, lon_diff=F('rlon') - client_lon, a=Sin(F('lat_diff') / 2.0) ** 2.0 + Cos(client_lat) * Cos(F('rlat')) * Sin( F('lon_diff') / 2.0) ** 2.0, c=2.0 * ATan2(Sqrt(F('a')), Sqrt(1.0 - F('a'))), distance=F('c') * earth_radius )