Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >如何在附近商户中查找离你最近的商家?

如何在附近商户中查找离你最近的商家?

原创
作者头像
天下之猴
发布于 2024-09-16 06:27:18
发布于 2024-09-16 06:27:18
2310
举报

前提背景

  1. 用户位置按照经纬度获取
  2. 用户可选范围内的商家
  3. 查询后的结果按顺序返回给用户
  4. 商户位置以经纬度存储

常用方法

数据库查询筛选

根据用户当前位置和用户所选择范围, 在数据库中查询后将结果在数据库中排序或者在内存中排序, 返回给用户

代码语言:txt
AI代码解释
复制
--longitude 表中经度字段
--latitude 表中维度字段
--lat1 指定点维度
--lon1 指定点经度
-- radius_in_km为用户所选择的范围
select business_id ,   6371 * ACOS(
        COS(RADIANS(lat1)) * COS(RADIANS(latitude)) * COS(RADIANS(longitude) - RADIANS(lon1)) +
        SIN(RADIANS(lat1)) * SIN(RADIANS(latitude)
    ) AS distance 
    from business
    having
    6371 * ACOS(
        COS(RADIANS(lat1)) * COS(RADIANS(latitude)) * COS(RADIANS(longitude) - RADIANS(lon1)) +
        SIN(RADIANS(lat1)) * SIN(RADIANS(latitude)
    ) <= radius_in_km;
    order by distance asc
    limit 0, 20

上述中我们可以给longitude 与latitude 建立联合索引, 方便我们做查询, 另外mysql中还有point类型, 用来表示点的位置, 我们可以利用ST_Distance_Sphere函数来计算店铺点位与用户点位之间的距离, 在做筛选也可

关于数据库查询更优秀的写法大家可以看看这篇文章

附近商家算法-地理空间距离计算优化 - 金泽夕 - 博客园 (cnblogs.com)

利用redis中的geo类型来做范围筛选

可以将用户最大能选范围内的所有商户的经纬度预先存redis中, 之后只需要用户将精度度传递给服务器, 服务器直接在redis中计算之后就可以将商户信息统计返回给用户

代码语言:txt
AI代码解释
复制
GEORADIUS geo:merchants $user_latitude $user_longitude 5 km WITHDIST WITHCOORD

这里userlatitude和user_longitude是用户的当前位置坐标。此命令将返回所有在5公里范围内的商家及其距离和坐标。我们还可以使用GEOFILTER命令对结果进行更复杂的排序和过滤,例如只返回特定类型的商家,或者按照距离排序。

四叉树解决

这里贴一篇某管上关于四叉树的连接,个人认为通俗易懂,https://www.youtube.com/watch?v=gGgyc9O7dqc , 只在这里做简单简述, 一个数四个节点, 每个节点有个容量为n, 节点存储该范围内的数据, 对应我们的场景就是存储商户信息, 每个节点表示大块区域, 节点的子节点表示他父节点中区域的一部分, 方便更细的划分, 比如中国就是根节点, 湖南,湖北, 北京,上海,,,,都是子节点, 长沙, 常德, ,,,,都是湖南的子节点, 然后每个县又是每个市的子节点, 知道划分成为最小区域位置, 比如我的筛选最小区域是1km * 1km,那么我就将中国分为n个1km*1km的小块存在数中, 四叉树的是将中国分为四块, 每块再划分四块, 知道划分为最小块, 之后我们新增商户或者查询的时候都可以在树中查询

查询的时候,我们根据用户位置以及用户筛选的位置, 对四叉树的节点进行遍历, 判断是否相交, 如果相交. 再对相交节点的子节点进行遍历, 与哪些子节点相交. 一直遍历到叶子节点, 之后将叶子节点所有的数据返回即可

另外, 我们可以以县作为根节点, 这样深度更小, 查询更快

业界通用解决方案:Geo Hash

关于geohash网上有更为详细的文章,这里制作简单概述,地图的经纬度范围分别为[-180,180],[90, -90],这里我们以经度为例,将经度分为[-180,0],[0,180],有一个点经纬度为[-121,34],用1表示在[-180,0]区间,0表示[0,180]区间,那么这个点表示为1,之后可以看到这个划分太粗糙了,我们继续对该点位于的区间对半分,分别为,[-180,-90],[-90,0],同样1表示在左边区间,0表示在右边区间,这里第二位仍然为1,继续划分左区间,划分结果为[-180,-135],[-135,-90],1表示在左区间,0表示右区间,这次第三位为0,因此通过110,我们划分三次,就可以知道该经度的范围了 ,同理纬度也按照同样方式获取,之后将维度放奇数为,径度放偶数位,进行base32编码,5位一编码,就能获取一串字符串,这串字符串就是该点所处的区域,想要更精准我们只需要划分更多次,就行了,经纬度各划分25次后,geohash位数经过编码后为10,这时候误差为0.6米,几乎不影响使用,如果需要更高精度,可以继续划分

另外geohash检索时常见的边缘问题,因为geohash是按矩形块检索的,如果一个矩形块内有a,b两点,b与a的距离为10km,相邻矩形块有c点,c与a的距离为5km,由于a与b前缀编码相同位数更多,将会认为a与b的距离更近,因此为了避免边缘问题,我们在检索时,还要将相邻矩形块也一起遍历,,也就是看似在第三层矩形中找距离最近的点实际上由于边缘问题,我们应该在第二层找最近节点

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
附近的人位置距离计算方法
附近的人的位置用经纬度表示,然后通过两点的经纬度计算距离。根据网上的推荐,最终采用geohash。 geohash的实现java版: 1 import java.util.BitSet; 2 import java.util.HashMap; 3 import java.util.Map; 4 5 import org.apache.commons.lang3.StringUtils; 6 7 public class Geohash { 8 9 priva
Ryan-Miao
2018/03/13
2.2K1
附近的人位置距离计算方法
redis georadius源码分析与性能优化
最近接到一个需求,开发中使用了redis georadius命令取附近给定距离内的点。完工后对服务进行压测后发现georadius的性能比预期要差,因此我分析了georadius的源码,并对原始的实现方案进行了优化,总结成了本文。
Orlion
2024/09/02
1190
redis georadius源码分析与性能优化
【GIS - 地理信息系统】经纬度计算 ( 经度、纬度概念 | 地球周长计算 | 地球经线周长计算 | 经纬度相关计算 | 经纬度坐标距离计算公式 | 经纬度与实际距离换算 | 相关代码实现 )
经度 Longitude , 本初子午线 位置 为 0 度经线 , 相当于水平 x 轴 的坐标 , 经度的取值范围 -180 度 ~ +180 度 ;
韩曙亮
2023/10/11
7K0
【GIS - 地理信息系统】经纬度计算 ( 经度、纬度概念 | 地球周长计算 | 地球经线周长计算 | 经纬度相关计算 | 经纬度坐标距离计算公式 | 经纬度与实际距离换算 | 相关代码实现 )
地理位置计算之geohash算法
最近在做共享单车单车的项目,用户打开APP后,如果根据当前的经纬度坐标获取附近的车辆呢?
北溟有鱼QAQ
2020/01/15
4.1K0
微信附近的人,用redis也能实现?(GEO)
我可以很随意的通过我自己的定位能看到我附近的人,并且能看到那个人距离我的距离,大家有没有思考过这个是怎么实现的?
程序员小饭
2021/01/05
6720
微信附近的人,用redis也能实现?(GEO)
MySql常用的Sql语句
–3、 –先去除重复,去除后的数据将重新插入新表中,即就得到了没有重复后的数据了—-
White feathe
2021/12/08
2.6K0
MySql常用的Sql语句
【系统设计】邻近服务
在本文中,我们将设计一个邻近服务,用来发现用户附近的地方,比如餐馆,酒店,商场等。
全球技术精选
2022/09/05
1.1K0
【系统设计】邻近服务
java 根据两个位置的经纬度,来计算两地的距离 经纬度处理
package com.fh.util; import java.util.HashMap; import java.util.Map; /** * 说明:经纬度处理 * 作者:FH Admin * from:fhadmin.cn */ public class MapDistance { private static double EARTH_RADIUS = 6378.137; private static double rad(double d) {
FHAdmin
2021/09/26
9430
Redis 到底是怎么实现“附近的人”这个功能的呢?
针对“附近的人”这一位置服务领域的应用场景,常见的可使用PG、MySQL和MongoDB等多种DB的空间索引进行实现。而Redis另辟蹊径,结合其有序队列zset以及geohash编码,实现了空间搜索功能,且拥有极高的运行效率。本文将从源码角度对其算法原理进行解析,并推算查询时间复杂度。
Nealyang
2019/10/24
1.9K0
Elasticsearch 在地理信息空间索引的探索和演进
本文梳理了Elasticsearch对于数值索引实现方案的升级和优化思考,从2015年至今数值索引的方案经历了多个版本的迭代,实现思路从最初的字符串模拟到KD-Tree,技术越来越复杂,能力越来越强大,应用场景也越来越丰富。从地理位置信息建模到多维坐标,数据检索到数据分析洞察都可以看到Elasticsearch的身影。
2020labs小助手
2022/06/27
1.5K0
geohash实现附近的工作室,php函数实现-tp5
首先,geohash用一个字符串表示经度和纬度两个坐标。某些情况下无法在两列上同时应用索引 (例如MySQL 4之前的版本,Google App Engine的数据层等),利用geohash,只需在一列上应用索引即可。
超级小可爱
2023/02/20
5600
IM里“附近的人”功能实现原理是什么?如何高效率地实现它?
本文引用了饿了么资深开发工程师万汨“Redis 到底是怎么实现“附近的人”这个功能的呢?”一文的内容,感谢原作者的分享,为了提升文章品质,即时通讯收录时有内容补充和修订。
JackJiang
2019/11/13
1.9K0
python练习题(3)——地球数据的计算
随着科技和数据科学的迅速发展,我们可以获取到大量关于地球的数据,这些数据包含了丰富的信息,涉及地理、气候、环境等方方面面。而Python作为一门功能强大且易学的编程语言,为我们提供了处理地球数据的优秀工具和技术。在本文中,我们将探索一道关于地球数据的Python程序练习题,通过实践和应用,发现Python编程的魅力。
老虎也淘气
2024/01/30
6470
使用Python机器学习预测外卖送餐时间!
现在的天气是一天比一天热,好多人周末休息在家的时候,就会选择点外卖,毕竟出去一趟又晒又热。
小F
2023/08/21
4870
使用Python机器学习预测外卖送餐时间!
Redis 实战篇:通过 Geo 类型实现附近的人邂逅女神
码老湿,阅读了你的巧用数据类型实现亿级数据统计之后,我学会了如何游刃有余的使用不同的数据类型(String、Hash、List、Set、Sorted Set、HyperLogLog、Bitmap)去解决不同场景的统计问题。
码哥字节
2021/07/19
1.2K0
基于 Redis Geo 实现地理位置服务(LBS)中查找附近 XXX 的功能
在移动互联网如火如荼的今天,各种 LBS(Location Based Service,基于地理位置服务)应用遍地开花,其核心要素是利用定位技术获取当前移动设备(手机)所在的位置,然后通过移动互联网获取与当前位置相关的资源和信息,典型的 LBS 应用比如高德地图定位当前位置和附近的建筑、微信查找附近的人、陌陌等陌生人社交应用、滴滴打车查询附近的车、大众点评查找附近的餐馆等等,今天学院君将带领大家来探究类似的「查找附近 XXX」的功能是如何实现的。
学院君
2021/01/22
3.8K0
PHP 经纬度坐标相关计算方法
我在 九方广场,手机上的高德地图导航至 中海九号公馆 显示的距离为 3.6公里,计算结果还是很准确的
很酷的站长
2022/12/04
7370
PHP 经纬度坐标相关计算方法
美团如何查询附近商家
我们日常电脑美团或者饿了么点外卖,附近的商家几乎都是秒回的,最简单的理解,我们可以用经纬度来计算。
三哥
2020/04/22
5.3K0
美团如何查询附近商家
一文了解geohash原理,实践实战设计思路
你们有没有遇到被面试官嘲讽的场景;之前有位刚毕业的小学弟在上海魔都某某某大公司面试,二面主要是问了关于redis的相关知识点,回答的也是磕磕绊绊的,其中一个问题是如何实现搜索附近人加好友功能;想跟小伙伴们一起分享、一起探讨下。如果有不正确的地方,欢迎指正批评,共同进步~~~
我是阿沐
2021/06/18
4.5K0
java计算两个经纬度之间的距离
前一阵项目中,有一个需求:是查找附近的人,其实就是查询某个距离内有多少用户。实现方式还是比较简单的,首先用户在APP上开启定位权限,将自己的经纬度都存储到数据库,然后以此经纬度为基准,以特定距离为半径,查找此半径内的所有用户。
一诺千金
2020/04/23
3.1K0
java计算两个经纬度之间的距离
推荐阅读
相关推荐
附近的人位置距离计算方法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档