Python Django过滤边界框内的所有项目(LAT、LNG)

Python Django过滤边界框内的所有项目(LAT、LNG),python,django,postgresql,geometry,coordinates,Python,Django,Postgresql,Geometry,Coordinates,我将Postgres与Django一起使用,我有一个带有坐标字段的模型packet: address_lat = models.DecimalField... address_lat = models.DecimalField... 我正在尝试创建一个方法(在管理器上),该方法返回给定区域内以km为单位的所有地块。我不使用Postgis和GeoDjango,所以它不需要在圆内,可以是正方形。所以我这样做了: def get_bounding_box(lat, lng, km): la

我将
Postgres
Django
一起使用,我有一个带有坐标字段的模型
packet

address_lat = models.DecimalField...
address_lat = models.DecimalField...
我正在尝试创建一个方法(在管理器上),该方法返回给定区域内以km为单位的所有地块。我不使用
Postgis
GeoDjango
,所以它不需要在圆内,可以是正方形。所以我这样做了:

def get_bounding_box(lat, lng, km):

    lat_change = Decimal(km / 111.2)
    lng_change = Decimal(abs(math.cos(lat * (Decimal(math.pi) / Decimal(180)))))
    bounds = {
        'lat_min': lat - lat_change,
        'lng_min': lng - lng_change,
        'lat_max': lat + lat_change,
        'lng_max': lng + lng_change
    }
    return bounds


class ParcelManager(models.Manager):
    def within_area(self, lat, lng, km):
        bounding_box = get_bounding_box(lat, lng, km)
        return self.get_queryset().filter(address_lat__gte=bounding_box['lat_min'],
                                          address_lng__gte=bounding_box['lng_min'],
                                          address_lat__lte=bounding_box['lat_max'],
                                          address_lng__lte=bounding_box['lng_max'],
                                          )
问题是这会返回太多的包裹。对于5cm输入(0.00005),它返回两个包裹,其中一个是同一个包裹,但另一个几乎相距1km

In [1]: p = Parcel.objects.last()

In [2]: p.address_lat
Out[2]: Decimal('34.784954778041')

In [3]: p.address_lng
Out[3]: Decimal('-92.250170096711')

In [4]: Parcel.objects.within_area(p.address_lat,p.address_lng,0.00005)
Out[4]: <QuerySet [<Parcel: Parcel object (42173)>, <Parcel: Parcel object (51764)>]>

In [5]: results = Parcel.objects.within_area(p.address_lat,p.address_lng,0.00005)

In [6]: results.first().address_lat
Out[6]: Decimal('34.784954911726')

In [7]: results.first().address_lng
Out[7]: Decimal('-92.286596972046')
[1]中的
:p=Parcel.objects.last()
在[2]中:p.地址
Out[2]:十进制('34.784954778041')
在[3]中:p.地址
Out[3]:十进制('-92.250170096711')
[4]中:区域内的地块对象(p.address\U lat,p.address\U lng,0.00005)
出[4]:
[5]中:结果=地块区域内的地块对象(p.address\u lat,p.address\u lng,0.00005)
[6]中:results.first().address\u lat
Out[6]:十进制('34.784954911726')
[7]中:results.first()地址
Out[7]:十进制('-92.286596972046')

你知道问题出在哪里吗?

你已经计算了一个考虑了纬度的系数,但是你忘了应用你的缓冲距离

lng_change = Decimal(km / 111.2) * Decimal(abs(math.cos(lat * (Decimal(math.pi) / Decimal(180)))))

PS:使用PostGIS将消除所有/大部分这些错误和麻烦…这是我唯一需要此类计算的地方,您认为仅为此目的安装PostGIS/GeoDjango值得吗?(该项目已投入生产)