django 按经纬度计算距离排序

django 按经纬度计算距离排序

需求: 实现离用户距离最近的店铺排序

公式:
在这里插入图片描述
公式解释如下:

  1. Lung1 Lat1表示A点经纬度, Lung2 Lat2表示B点经纬度;
  2. a=Lat1–Lat2 为两点纬度之差,b=Long1-Long2为两点经度之差;
  3. 6378.137为地球半径,单位为千米;
  4. 计算出来的结果单位为千米,若将半径改为米为单位则计算的结果单位为米;
  5. 计算精度与谷歌地图的距离精度差不多,相差范围在0.2米以下.

公式参考

SQL

postgresql
在这里插入图片描述

"6371 * acos(least(greatest(cos(radians(%s)) * cos(radians(lat)) * cos(radians(lng) - radians(%s)) + sin(radians(%s)) * sin(radians(lat)) , -1), 1))"

参数说明

  • lat : 纬度字段
  • lng: 精度字段

classmethod实现返回queryset

# 根据经纬度计算出距离排序
@classmethod
def get_locations_queryset(cls, queryset, lng, lat, max_distance):
    """
    queryset: 查询集
    latitude: 纬度
    longitude: 精度
    max_distance:最大距离
    """

    gcd_formula = "6371 * acos(least(greatest(\
    cos(radians(%s)) * cos(radians(lat)) \
    * cos(radians(lng) - radians(%s)) + \
    sin(radians(%s)) * sin(radians(lat)) \
    , -1), 1))"

    sql = RawSQL(gcd_formula, (lat, lng, lat))

    qs = queryset.annotate(distance=sql).order_by('distance')
	if max_instance:
		qs = qs.filter(distance__lt=max_instance)
    return qs

总结

  1. 上面classmethod方法也可以做扩展 比如超过范围的queryset不返回 加一个距离限制参数 用distance比较 (可以做超出配送范围过滤)
  2. 也可以使用GeoDjango去做 GeoDjango限制还挺多的有兴趣的可以去看看"
  3. 内容借鉴地址 自己做了个简单的业务封装 有兴趣可以去了解其它的实现方式
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tuple-Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值