Filter zipcodes by proximity in Django with the Spherical Law of Cosines

后端 未结 6 955
轮回少年
轮回少年 2020-12-07 21:49

I\'m trying to handle proximity search for a basic store locater in Django. Rather than haul PostGIS around with my app just so I can use GeoDjango\'s distance filter, I\'d

6条回答
  •  猫巷女王i
    2020-12-07 21:59

    To follow up on Tom, if you want to have a query that also works in postgresql, you can not use AS because you will get an error saying 'distance' does not exist.

    You should put the whole spherical law expresion in the WHERE clause, like this (It also works in mysql):

    import math
    from django.db import connection, transaction
    from django.conf import settings
    
    from django .db import models
    
    class LocationManager(models.Manager):
        def nearby_locations(self, latitude, longitude, radius, use_miles=False):
            if use_miles:
                distance_unit = 3959
            else:
                distance_unit = 6371
    
            cursor = connection.cursor()
    
            sql = """SELECT id, latitude, longitude FROM locations_location WHERE (%f * acos( cos( radians(%f) ) * cos( radians( latitude ) ) *
                cos( radians( longitude ) - radians(%f) ) + sin( radians(%f) ) * sin( radians( latitude ) ) ) ) < %d
                """ % (distance_unit, latitude, longitude, latitude, int(radius))
            cursor.execute(sql)
            ids = [row[0] for row in cursor.fetchall()]
    
            return self.filter(id__in=ids)
    

    Please note that you have to select the latitude and longitude, otherwise you can not use it in the WHERE clause.

提交回复
热议问题