I'm building a world-map and want users to be able to look-up locations and have them be sorted by distance from anywhere in the world. I'm using GeoDjango to calculate distances, however, the distances returned seemed wrong so I checked them against geopy
's calculations.
The distances differ significantly to the point that if the results are sorted by the DB distance values in kilometers vs geopy
values in km they would not be in the same order.
I'm assuming the geopy
values are correct so I'm wondering, is there something wrong with the way I implemented GeoDjango?
Is it working as it should?
Does this have something to do with trying to calculate distances for the entire world and not just a specific area which could have a srid
?
views.py
pnt = GEOSGeometry('POINT({} {})'.format(latitude, longitude), srid=4326)
qs = Place.filter(point__distance_lte=(pnt, D(km=radius*2))).annotate(distance=Distance('point', pnt)).order_by('distance')
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'USER': '',
'NAME': 'places',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
models.py
:
from django.contrib.gis.db import models
from geopy.distance import vincenty
class Place(models.Model):
latitude = models.DecimalField(max_digits=10, decimal_places=6, null=True, blank=True)
longitude = models.DecimalField(max_digits=10, decimal_places=6, null=True, blank=True)
point = models.PointField(null=True, geography=True)
def distance_from_target(self, target_lat, target_lon):
if not target_lat or not target_lon:
return None
instance_point = (self.latitude, self.longitude)
target_point = (target_lat, target_lon)
return vincenty(instance_point, target_point).kilometers