在生活中我们有时候需要点外卖、骑共享单车等等,我们打开软件找到附近餐厅、离我最近的单车,那么他们是怎么快速定位到的呢?我们把地图看作一个二维平面,我们在某个点上然后找到附近10km内的所有餐厅,这时候我们知道求两点直接的距离是需要一个公式,且需要知道两点的x,y轴坐标才能计算出距离,通过计算出距离然后进行排列,那么我们就能过找到离我最近的一个餐厅了。

那么这里我们考虑几个问题,我每次搜索的时候需要计算我离餐厅的距离,那么我们能不能把这个距离保存起来呢?如果我保存了,我下次在另一个地方那是不是还得重新计算?所以在数量级小的时候可以考虑这个做法,但是数量级起来了这个方法不是一个好的方法。

我们打开地图发现地图并不是一开始把所有的细节都显示,比如我首先看到的是中国,然后放大看到的是广东,再放大看到的是深圳,那么我们假设这个是一个大盒子,里面有很多个小盒子,小盒子里面有很多更小的盒子,每个小盒子都用二进制标记比如小盒子里:00,01,10,11....

我们通过把(x,y)转换成的编码连接起来,如上图所示,是不是就可以把他们转换成一个一维的线性结构,那么对于我们的排序非常有利。那么这个就是我们今天所说的GeoHash。

GeoHash算法分为三步

第一步:把经纬度转换成二进制

第二步:把二进制的经纬度合并

第三步:按照base32进行编码

Base32编码表的其中一种如下,是用0-9、b-z(去掉a, i, l, o)这32个字母进行编码。具体操作是先将上一步得到的合并后二进制转换为10进制数据,然后对应生成Base32码。需要注意的是,将5个二进制位转换成一个base32码。在Redis中经纬度使用52位的整数进行编码,最后的结果放在zset里面,ZSet的value是元素的key,score是GeoHash的52位数值,这里注意score是一个浮点型,但是对于52位的整形是无损存储。Redis给我们提供6个Geo命令,下面我们就开始使用这个Geo命令了

查询

这里我们注意添加是geoadd,可以添加多个点,删除就是直接使用zrem即可

> geoadd name 110.50000 30.50000 zhangsan(integer) 1> geoadd name 110.60000 30.60000 lisi(integer) 1> geoadd name 120.50000 30.60000 wangwu(integer) 1> geoadd name 111.45000 29.90000 zhaoliu 111.50000 30.10000 mango(integer) 2

距离

geodist 指令可以用来计算两个元素之间的距离,携带集合名称、两个名称和距离单位,距离单位可以是 m、 km、ml 和丘,分别代表米、干米、英里和尺。

> geodist name zhangsan mango km"105.8372"

获取元素位置

geopos 指令可以获取

> geopos name zhangsan1) 1) "110.49999743700027"   2) "30.499999345868211"

获取元素hash值

GeoHash 可以获取元素的经纬度编码字符串,上面已经提到,它是 base32 编码。你可以使用这个编码值去http://geohash.org/$ {hash}上进行直接定位,它是 GeoHash的标准编码值。

> geohash name zhangsan1) "wmqtd2reke0"

附近的元素

georadiusbymember指令是最为关键的指令之一,它可以用来查询指定元素附近的其他元素,它的参数非常复杂 。

#### 获取据离zhangsan20km最近的三个人> georadiusbymember name zhangsan 20 km count 3 asc1) "zhangsan"2) "lisi"#### withcoord withdist withhash三个可选参数> georadiusbymember name zhangsan 20 km withcoord withdist withhash count 31) 1) "zhangsan"   2) "0.0000"   3) (integer) 4028187045502241   4) 1) "110.49999743700027"      2) "30.499999345868211"2) 1) "lisi"   2) "14.6789"   3) (integer) 4028372360456825   4) 1) "110.60000091791153"      2) "30.599999165046462"

除了georadiusbyrnember指令根据元素查询附近的元素,Redis还提供了根据坐标值来查询附近的元素的指令georadius,这个指令更加有用,它可以根据用户的定位来计算附近的餐馆”等。它的参数和georadiusbyrnernber基本一致,唯一的差别是将目标元素改成经纬度坐标值。

> georadius name 110.50000 30.50000 20 km count 31) "zhangsan"2) "lisi"

注意:这里的GeoHash虽然好用,它实际上还是个ZSet,数据量超过一定的阈值后查询速度会减慢,那么我们在处理这些问题的时候需要对地图进行切割或者进行分块处理。

一名正在抢救的coder

笔名:mangolove

CSDN地址:https://blog.csdn.net/mango_love

GitHub地址:https://github.com/mangoloveYu

Redis之GeoHash相关推荐

  1. 【学习笔记】Redis的geohash数据结构介绍

    geohash介绍 ⾃Redis 3.2开始,Redis基于geohash和有序集合提供了地理位置相关功能.Redis Geo模块包含了以下6个命令: ▶GEOADD: 将给定的位置对象(纬度.经度. ...

  2. Redis数据结构 GeoHash

    目录 使用数据库实现查找附近的人 GeoHash 算法简述 在 Redis 中使用 Geo 增加 距离 获取元素位置 获取元素的 hash 值 附近的公司 注意事项 注意:本文参考  Redis(6) ...

  3. 地理位置处理---Redis的GeoHash和MySQL的geography类型(之后有空再详细介绍)

    地理位置处理-Redis的GeoHash和MySQL的geography类型(之后有空再详细介绍) 最近比较忙,本来很早就想写对比文章了,这里先大致写写,等之后有空再详细介绍吧.这个文章我本地MD笔记 ...

  4. Redis之GeoHash算法

    Redis之GeoHash算法 1 GeoHash 2 GeoHash在Redis中的使用 Redis3.2开始提供了GEO模块,该模块也使用GeoHash算法.(通用的) 功能:查看附件的酒店.加油 ...

  5. Redis(6)——GeoHash查找附近的人

    像微信 "附近的人",美团 "附近的餐厅",支付宝共享单车 "附近的车" 是怎么设计实现的呢? 一.使用数据库实现查找附近的人 我们都知道, ...

  6. Redis Geohash指令与位置服务应用

    目录 0.Redis 命令 增加 距离 获取元素位置 获取元素的 hash 值 附近的公司 1.为什么要GeoHash? 2 Redis GEO API 2.1 增加地理位置信息 2.2 获取地理位置 ...

  7. geohash redis mysql_geohash

    geohash GEOHASH key member [member ...] 自3.2.0起可用. 时间复杂度:每个请求成员的 O(log(N)),其中 N 是有序集合中元素的数量. 返回表示地理空 ...

  8. Redis核心数据结构ZSET、GeoHash 、 Stream--排行榜、消息Pull推送、附近搜索、布隆过滤器 、IM聊天室

    ZSET.Geo . Stream redis zset数据结构 常用命令 排行榜 步骤一.初始化1个月的历史数据 步骤二:定时刷新数据 步骤3:排行榜查询接口 GeoHash 命令 附近酒店搜索实现 ...

  9. Redis持久化讲解

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 一.持久化简介 Redis 的数据 全部存储 在 内存 中,如果 ...

最新文章

  1. NeHe教程Qt实现——lesson16
  2. with error 126:找不到指定的模块
  3. 【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 重写 MetaClass#invokeMethod 方法拦截 JDK 中已经定义的函数 )
  4. Xshell连接Ubuntu报错 “服务器发送了一个意外的数据包”
  5. windows api 枚举进程pid
  6. 水平输送水汽通量matlab,分享:水汽通量散度
  7. Maven入门指南② :Maven 常用命令,手动创建第一个 Maven 项目
  8. C++语言打印汉字表
  9. redis 清空db下_PHP操作redis实现的分页列表
  10. Mybatis-04-结果集映射resultMap/动态SQL/关联查询
  11. 动态规划-最长不下降子序列
  12. 全民战“疫”,ZStack ZCCT在线认证疫情期间免费开放!
  13. div+css视频教程大全免费下载更有html5教程
  14. Ant Design Pro学习记录—默认主题配色修改
  15. android 动画卡顿分析工具
  16. 科学减肥新方法——红光光浴#大健康#红光光浴#红光#种光光学
  17. matlab光学几何光学模拟,matlab在几何光学仿真 实验中的应用.doc
  18. DSO Framer 使用介绍(ZZ)转
  19. GeneXus学习(三)数据库操作【可视化低代码的迁移项目】
  20. 同轴线传输网络摄像机信号2KM

热门文章

  1. 【C语言笔记进阶篇】第一章:指针进阶
  2. (计算机组成原理)第一章计算机系统概述-第四节:计算机的性能指标
  3. 3-1:HTTP协议之应用层协议了解
  4. Linux系统编程30:进程信号之产生信号的四种方式(Core Dump,kill,raise)
  5. 1-6:学习shell之重定向
  6. Linux 压缩与解压
  7. Please, commit your changes or stash them before you can merge.
  8. Qt:Qt使用WM_COPYDATA消息进行进程通信
  9. mysql基本介绍和优化技巧
  10. iFit—Smart Cardio Equipment 简介与下载