Redis 提供了GEO地理信息定位功能,地理空间项(经度、纬度、名称),实现查找附近的人、上班打卡、自行车租赁、摇一摇等相关与地理位置信息的功能。 Redis 地理空间索引可让您存储坐标并搜索它们。 此数据结构对于查找给定半径或边界框内的附近点非常有用。
将指定的地理空间项(经度、纬度、名称)添加到指定的键。数据作为排序集存储到键中,这样就可以使用 GEOSEARCH 命令查询项目。
该命令采用标准格式 x,y 的参数,因此必须在纬度之前指定经度。可索引的坐标存在限制:非常靠近极点的区域不可索引。
当用户尝试索引指定范围之外的坐标时,该命令将报告错误。
通常,Redis 使用 Geohash 的变体来表示元素的位置 使用 52 位整数对位置进行编码的技术。编码是 与标准相比也不同,因为初始最小值和最大值 编码和解码过程中使用的坐标是不同的。
longitude 经度 、latitude 纬度、member 成员
GEOADD key [NX | XX] [CH] longitude latitude member [longitude
latitude member ...]
以下添加5个城市经纬度到 键 cities:geo, 如果已经存在则返回0,如果需要更新地理位置,同样使用GEOADD命令(仅管返回0)。
# 北京
192.168.88.11:6380> GEOADD cities:geo 116.28 39.54 beijing
(integer) 1
# 天津
192.168.88.11:6380> GEOADD cities:geo 117.10 39.10 tianjin
(integer) 1
# 广州
192.168.88.11:6380> GEOADD cities:geo 113.18 23.10 guangzhou
(integer) 1
# 杭州
192.168.88.11:6380> GEOADD cities:geo 120.10 30.15 hangzhou
(integer) 1
# 长沙
192.168.88.11:6380> GEOADD cities:geo 112.55 28.12 changsha
(integer) 1
注意:没有GEODEL命令,因为您可以使用ZREM 删除元素。 Geo索引结构只是一个排序集。本质是 zset 数据类型。
# 查看成员
192.168.88.11:6380> ZRANGE cities:geo 0 5
1) "guangzhou"
2) "changsha"
3) "hangzhou"
4) "beijing"
5) "tianjin"
# 查看成员带分数
192.168.88.11:6380> ZRANGE cities:geo 0 5 withscores
1) "guangzhou"
2) "4046510568184210"
3) "changsha"
4) "4050880415755396"
5) "hangzhou"
6) "4054121680734333"
7) "beijing"
8) "4069140601296155"
9) "tianjin"
10) "4069185531597821"
# 集合大小: 5
192.168.88.11:6380> ZCARD cities:geo
(integer) 5
# 删除两个元素
192.168.88.11:6380> ZREM cities:geo changsha hangzhou
(integer) 2
# 集合大小: 3
192.168.88.11:6380> ZCARD cities:geo
(integer) 3
如何计算 “beijing” 经纬度(116.28, 39.54) 的分值 4069140601296155 ? 排序集的填充方式是使用一种叫做Geohash的技术。经度位和纬度位相互交错,形成一个唯一的52位整数。
EPSG:900913 / EPSG:3785 / OSGEO:41001 指定的确切限制如下:
按下面的编码为N=26位二进制值 ,然后把经纬度交叉组成52位二进制值即可。 (偶数位为经度、奇数位为纬度)
这里,可以通过python脚本定义两个列表,然后不断拆分区间,最后做交叉合拼两个列表。结果如下:
root@ubuntu-x64_01:/opt# python3 redis_geo_bit.py
guangzhou---> 1110011000000100011110101000111111110001100110010010
changsha ---> 1110011001000100000100011000001101010110110010000100
hangzhou ---> 1110011001110011001111000010101010000000100001111101
beijing ---> 1110011101001101110010100000000101001101010100011011
tianjin ---> 1110011101001110011100010110001000101101001111111101
再转换成十进制,就是 zset 的分数值,比如 guangzhou (1110011000000100011110101000111111110001100110010010)对应十进制 : 4046510568184210
192.168.88.11:6380> ZRANGE cities:geo 0 0 withscores
1) "guangzhou"
2) "4046510568184210"
返回有效的Geohash 字符串,表示一个或多个元素在表示地理空间索引的排序集值中的位置(其中元素是使用GEOADD)。
该命令返回11个字符的Geohash字符串,因此与Redis内部52位表示相比,没有精度损失。
字符串越长,表示的位置更精确,例如geohash长度为8时,精度在19米左右。
下面操作返回 beijing 的 geohash 值,如下:
192.168.88.11:6380> GEOHASH cities:geo beijing
1) "wx48yn090q0"
可以在geohash.org url中使用它们: http://geohash.org/wx48yn090q0
返回由排序集key表示的地理空间索引中所有指定成员的位置(经度、纬度)。当通过GEOADD填充地理空间索引时,坐标被转换为52位geohash,因此返回的坐标可能不完全是用于添加元素的坐标,但可能会引入小误差。
192.168.88.11:6380> GEOPOS cities:geo guangzhou
1) 1) "113.18000167608261108"
2) "23.10000005307264104"
192.168.88.11:6380> GEOPOS cities:geo changsha
1) 1) "112.54999905824661255"
2) "28.12000010081647616"
192.168.88.11:6380> GEOPOS cities:geo hangzhou
1) 1) "120.09999901056289673"
2) "30.14999997874437554"
192.168.88.11:6380> GEOPOS cities:geo beijing
1) 1) "116.28000229597091675"
2) "39.54000124957348561"
192.168.88.11:6380> GEOPOS cities:geo tianjin
1) 1) "117.10000187158584595"
2) "39.09999900352384117"
返回由排序集表示的地理空间索引中两个成员之间的距离。
给定一个表示地理空间索引的排序集,使用GEOADD命令填充,该命令返回指定单元中两个指定成员之间的距离。
如果缺少一个或两个成员,则该命令返回NULL。
单位必须为以下之一,默认为米:
如计算北京与天津之间的距离,并以公里为单位返回,如下:
192.168.88.11:6380> GEODIST cities:geo beijing tianjin km
"85.8689"
获取指定位置范围内的地理信息位置集合,返回使用GEOADD填充地理空间信息的已排序集合的成员,这些成员位于用中心位置和到中心的最大距离(半径)指定的区域的边界内。
该命令的常见用例是检索指定点附近的地理空间项目,距离不超过给定的米(或其他单位)。例如,这允许向应用程序附近的移动用户提供建议。
单位必须为以下之一,默认为米:
GEORADIUS key longitude latitude radius <M | KM | FT | MI>
[WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC | DESC]
[STORE key | STOREDIST key]
该命令可以使用以下选项返回附加信息:
该命令默认返回未排序的项。可以使用以下两个选项调用两种不同的排序方法:
默认情况下,返回所有匹配项。通过使用COUNT < COUNT >选项,可以将结果限制为前N个匹配项。
默认情况下,该命令将条目返回给客户端。可以使用以下选项之一来存储结果:
如,计算距离 北京 200公里 以内的城市:
192.168.88.11:6380> GEORADIUS cities:geo 116.28 39.54 200 km
1) "beijing"
2) "tianjin"
192.168.88.11:6380> GEORADIUS cities:geo 116.28 39.54 200 km WITHCOORD WITHDIST WITHHASH
1) 1) "beijing"
2) "0.0002"
3) (integer) 4069140601296155
4) 1) "116.28000229597091675"
2) "39.54000124957348561"
2) 1) "tianjin"
2) "85.8690"
3) (integer) 4069185531597821
4) 1) "117.10000187158584595"
2) "39.09999900352384117"
192.168.88.11:6380> GEORADIUS cities:geo 116.28 39.54 200 km WITHCOORD WITHDIST WITHHASH COUNT 1 DESC
1) 1) "tianjin"
2) "85.8690"
3) (integer) 4069185531597821
4) 1) "117.10000187158584595"
2) "39.09999900352384117"
# 将项目存储在使用其地理空间信息填充的已排序集合中。
192.168.88.11:6380> GEORADIUS cities:geo 116.28 39.54 200 km COUNT 1 DESC STORE cities:georadius
(integer) 1
192.168.88.11:6380> type cities:georadius
zset
192.168.88.11:6380> ZRANGE cities:georadius 0 5 withscores
1) "tianjin"
2) "4069185531597821"