GEO地理位置

        简介:


Redis 的 GEO 特性在 Redis 3.2 版本中推出, 这个功能可以将用户给定的地理位置信息储存起来, 并对这些信息进行操作。来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能。geo 的数据类型为zset。


GEO 的数据结构总共有六个常用命令: geoadd 、 geopos 、 geodist 、 georadius 、


georadiusbymember 、 gethash


官方文档: https://www.redis.net.cn/order/3685.html



geoadd



# 语法

geoadd key longitude latitude member ...

# 将给定的空间元素 ( 纬度、经度、名字 ) 添加到指定的键里面。

# 这些数据会以有序集 he 的形式被储存在键里面,从而使得 georadius 和 georadiusbymember 这样的

命令可以在之后通过位置查询取得这些元素。

# geoadd 命令以标准的 x,y 格式接受参数 , 所以用户必须先输入经度 , 然后再输入纬度。

# geoadd 能够记录的坐标是有限的 : 非常接近两极的区域无法被索引。

# 有效的经度介于 -180-180 度之间,有效的纬度介于 -85.05112878 度至 85.05112878 度之间。,

当用户尝试输入一个超出范围的经度或者纬度时 ,geoadd 命令将返回一个错误



测试:百度搜索经纬度查询,模拟真实数据


127.0.0.1:6379> geoadd china:city 116.23 40.22 bj               #北京
(integer) 1
127.0.0.1:6379> geoadd china:city 121.48 31.40 sh 113.88 22.55 sz 120.21 30.20 hz
(integer) 3                #上海 深圳 杭州
127.0.0.1:6379> geoadd china:city 106.54 29.40 cq 108.93 34.23 xa 114.02 30.58 wh
(integer) 3                #重庆 西安 武汉


geopos  解析:



# 语法

geopos key member [member...]

# 从 key 里返回所有给定位置元素的位置(经度和纬度)



测试:


127.0.0.1:6379> geopos china:city bj
1) 1) "116.23000055551528931"
   2) "40.2200010338739844"
127.0.0.1:6379> geopos china:city sh
1) 1) "121.48000091314315796"
   2) "31.40000025319353938"
127.0.0.1:6379> geopos china:city cq  xj
1) 1) "106.54000014066696167"
   2) "29.39999880018641676"
2) (nil)

 


geodist解析:


# 语法

geodist key member1 member2 [unit]

# 返回两个给定位置之间的距离,如果两个位置之间的其中一个不存在 , 那么命令返回空值。

# 指定单位的参数 unit 必须是以下单位的其中一个:

# m 表示单位为米

# km 表示单位为千米

# mi 表示单位为英里

# ft 表示单位为英尺

# 如果用户没有显式地指定单位参数 , 那么 geodist 默认使用米作为单位。

#geodist 命令在计算距离时会假设地球为完美的球形 , 在极限情况下 , 这一假设最大会造成 0.5% 的误差



测试:



127.0.0.1:6379> geodist china:city bj sh
"1088785.4302"
127.0.0.1:6379> geodist china:city bj sh km
"1088.7854"
127.0.0.1:6379> geodist china:city wh sh km
"716.9863"



georadius解析:



# 语法

georadius key longitude latitude radius m|km|ft|mi [withcoord][withdist]

[withhash][asc|desc][count count]

# 以给定的经纬度为中心, 找出某一半径内的元素



测试:重新连接redis-cli,增加参数 --raw,可以强制输出中文。不然会乱码



#在china:city 中寻找坐标100 30 半径为1000km的城市

127.0.0.1:6379> georadius china:city 100 30 1000 km
1) "cq"
2) "xa"


# withdist  返回位置名称和中心距离
127.0.0.1:6379> georadius china:city 100 30 1000 km withdist
1) 1) "cq"
   2) "635.2850"
2) 1) "xa"
   2) "963.3171"



# withcoord 返回位置名称和经纬度
127.0.0.1:6379> georadius china:city 100 30 1000 km withcoord
1) 1) "cq"
   2) 1) "106.54000014066696167"
      2) "29.39999880018641676"
2) 1) "xa"
   2) 1) "108.92999857664108276"
      2) "34.23000121926852302"


#withdist withcoord 返回位置名称  距离  和经纬度 count 限定寻找个数
127.0.0.1:6379> georadius china:city 100 30 1000 km withcoord withdist count 1
1) 1) "cq"
   2) "635.2850"
   3) 1) "106.54000014066696167"
      2) "29.39999880018641676"
127.0.0.1:6379> georadius china:city 100 30 1000 km withcoord withdist count 2
1) 1) "cq"
   2) "635.2850"
   3) 1) "106.54000014066696167"
      2) "29.39999880018641676"
2) 1) "xa"
   2) "963.3171"
   3) 1) "108.92999857664108276"
      2) "34.23000121926852302"



georadiusbymember 解析:



# 语法

georadiusbymember key member radius m|km|ft|mi [withcoord][withdist]

[withhash][asc|desc][count count]

# 找出位于指定范围内的元素,中心点是由给定的位置元素决定



测试:



127.0.0.1:6379> georadiusbymember china:city bj 1000 km
1) "bj"
2) "xa"
127.0.0.1:6379> georadiusbymember china:city sh 400 km
1) "hz"
2) "sh"

 



geohahs解析:



# 语法



geohash key member [member...]



# Redis 使用 geohash 将二维经纬度转换为一维字符串,字符串越长表示位置更精确 , 两个字符串越相似表示距离越近。



测试:



127.0.0.1:6379> geohash china:city bj cq
1) "wx4sucu47r0"
2) "wm5z22h53v0"
127.0.0.1:6379> geohash china:city bj sh
1) "wx4sucu47r0"
2) "wtw6sk5n300"

 

zrem

GEO没有提供删除成员的命令,但是因为GEO的底层实现是zset,所以可以借用zrem命令实现对地理位置信息的删除

127.0.0.1:6379> zrange china:city 0 -1
1) "cq"
2) "xa"
3) "sz"
4) "wh"
5) "hz"
6) "sh"
7) "bj"
127.0.0.1:6379> zrem china:city bj
(integer) 1
127.0.0.1:6379> zrem china:city sh
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "cq"
2) "xa"
3) "sz"
4) "wh"
5) "hz"
127.0.0.1:6379>