Redis之GeoHash算法

Redis之GeoHash算法

  • 1 GeoHash
  • 2 GeoHash在Redis中的使用

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

1 GeoHash

  1. 核心思想:GeoHash是一种地址编码方法,使用这种方式,能够将二维的空间经纬度数据编码转换成一个一维字符串。

地球上经纬度的划分:

  1. 以经过伦敦的格林尼治天文台的经线为0度经线,向东就是东经,向西就是西经。如果我没将西经定义为负数,那么经度的范围就是[-180,180]
  2. 维度:北纬90度到南纬90度,如果我没将南纬定义为父,则维度的范围就是[-90,90]。
  3. 接下来,以本初子母线和赤道为界,我们可以将地球上的点分配到一个二维坐标中:

具体图片
Redis之GeoHash算法_第1张图片
GeoHash算法就是基于这样的思想,划分的次数越多,区域越多,每个区域的面积范围就越小,精度就更加准确。

GeoHash具体算法:
以北京天安门广场为例(39.9053908600,116.3980007200)

  1. 维度的范围在(-90,90)之间,中间值为0,对于39.9053908600值落在(0,90),因此得到的值为1
  2. (0,90)的中间值为45,39.9053908600落在(0,45)之间,因此得到一个0
  3. (0,45)的中间值为22.5,39.9053908600落在(22.5,45)之间,因此得到一个1
  4. …(可以算得很长)越长越细

这样,我们得到的维度二进制是101;按照同样的步骤,我们可以算出经度的二进制是110

接下来将经纬度合并(经度占偶数位,纬度占奇数位)

111001

按照Base32(0-9,b-z去掉a i l o)对合并后的二进制数据进行编码,先将二进制转换为十进制,然后进行编码。

编码完成后,会得到一个字符串,将编码得到的字符串,可以拿去geohash.org网站上解析

GeoHash有哪些特点:

  1. 用字符串表示经纬度
  2. GeoHash表示的是一个区域,而不是一个点
  3. 编码格式有规律,例如一个地址编码之后的格式是123,另一个地址编码之后的格式是123456,从字符串上可以看出,123456处于123之中。

例子示意图:
Redis之GeoHash算法_第2张图片

2 GeoHash在Redis中的使用

添加地址:

geoadd city 116.3980007200 39.9053908600 beijing
geoadd city 114.0592002900 22.5536230800 shenzhen

查看上面两个地址之间的距离(最后为单位)

127.0.0.1:6379> GEODIST city beijing shenzhen
"1942543.4634"
127.0.0.1:6379> GEODIST city beijing shenzhen km
"1942.5435"

获取元素的位置:

GEOPOS city beijing
1) 1) "116.39800339937210083"
   2) "39.90539144357683909"

GEOHASH进行映射的数据会有轻微的误差(映射后还原会有误差,不影响功能)

127.0.0.1:6379> geohash city beijing
1) "wx4g08w3y00"

获取元素的hash值(Base32转换后)

网址:http://geohash.org/wx4g08w3y00(通过hahs值可以查看定位)
可以获取原来的地址

geoadd city 114.3980007200 37.9053908600 shijiazhuan
geoadd city 116.3980007200 36.9053908600 jianan

查看附件的人:

georadiusbymember city beijing 500 km count 3 asc//(升序)

以北京为中心,方圆500km以内找出来3个,按照远近顺序排序,这个命令不会排除北京。

georadiusbymember city beijing 2000 km count 4 desc//(倒序)

携带距离,坐标,hash值:

127.0.0.1:6379> georadiusbymember city beijing 2000 km withdist withhash withcoord  count 4 desc
1) 1) "shenzhen"
   2) "1942.5435"
   3) (integer) 4046432449017941
   4) 1) "114.05920296907424927"
      2) "22.55362316412901436"

也可以通过经纬度坐标查询(将member换成对应的经纬度)

georadius city 116.39800339937210083 39.90539144357683909  2000 km withdist withhash withcoord  count 4 desc

你可能感兴趣的:(Redis,redis)