文章目录

  • 地理空间(geospatial)
  • 相关操作
  • 原理



地理空间(geospatial)

  1. 将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。这些数据将会存储到sorted set这样的目的是为了方便使用GEORADIUS或者GEORADIUSBYMEMBER命令对数据进行半径查询等操作。
  2. 该命令以采用标准格式的参数x,y,所以经度必须在纬度之前。这些坐标的限制是可以被编入索引的,区域面积可以很接近极点但是不能索引。具体的限制,由EPSG:900913 / EPSG:3785 / OSGEO:41001 规定如下:
  • 有效的经度从-180度到180度。
  • 有效的纬度从-85.05112878度到85.05112878度。
  • 当坐标位置超出上述指定范围时,该命令将会返回一个错误。
  1. 相关命令
  • GEOADD
  • GEODIST
  • GEOHASH
  • GEOPOS
  • GEORADIUS
  • GEORADIUSBYMEMBER

相关操作

  1. 添加地理位置:geoadd key value(经度 纬度 名称)
127.0.0.1:6379> geoadd china:city 116.40 39.90 beijing  # 北京
(integer) 1
127.0.0.1:6379> geoadd china:city 112.93 28.23 changsha #长沙
(integer) 1
127.0.0.1:6379> geoadd china:city 112.32 28.60 yiyang 121.47 31.23 shanghai #益阳 上海
(integer) 2
  1. 获取指定城市的精度和纬度:geopos从key里返回所有给定位置元素的位置(经度和纬度)。
127.0.0.1:6379> geopos china:city beijing
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
127.0.0.1:6379> geopos china:city changsha
1) 1) "112.92999833822250366"
   2) "28.2299993949683099"
127.0.0.1:6379> geopos china:city shanghai
1) 1) "121.47000163793563843"
   2) "31.22999903975783553"
  1. 返回两个给定位置之间的距离GEODIST
  • 如果两个位置之间的其中一个不存在, 那么命令返回空值。
  • 指定单位的参数 unit 必须是以下单位的其中一个:
  • m 表示单位为米。
  • km 表示单位为千米。
  • mi 表示单位为英里。
  • ft 表示单位为英尺。
  • 如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位。
  • GEODIST 命令在计算距离时会假设地球为完美的球形, 在极限情况下, 这一假设最大会造成 0.5% 的误差。
127.0.0.1:6379> GEODIST china:city beijing shanghai  #北京到上海 单位m
"1067378.7564"
127.0.0.1:6379> GEODIST china:city beijing shanghai km #北京到上海 单位km
"1067.3788"
127.0.0.1:6379> GEODIST china:city changsha yiyang km  #长沙到益阳 单位km
"72.4885"
  1. GEORADIUS以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
  • 范围可以使用以下其中一个单位:
  • m 表示单位为米。
  • km 表示单位为千米。
  • mi 表示单位为英里。
  • ft 表示单位为英尺。
  • 在给定以下可选项时, 命令会返回额外的信息:
    - WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
    - WITHCOORD: 将位置元素的经度和维度也一并返回。
    - WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。
  • 在默认情况下, GEORADIUS 命令会返回所有匹配的位置元素。 虽然用户可以使用 COUNT <count> 选项去获取前 N 个匹配元素, 但是因为命令在内部可能会需要对所有被匹配的元素进行处理, 所以在对一个非常大的区域进行搜索时, 即使只使用 COUNT 选项去获取少量元素, 命令的执行速度也可能会非常慢。
127.0.0.1:6379> GEORADIUS china:city 120 35 1000 km
1) "beijing"
2) "shanghai"
127.0.0.1:6379> GEORADIUS china:city 120 35 1000 km withdist
1) 1) "beijing"
   2) "630.7947"
2) 1) "shanghai"
   2) "441.1015"
127.0.0.1:6379> GEORADIUS china:city 120 35 1000 km withdist count 1
1) 1) "shanghai"
   2) "441.1015"
127.0.0.1:6379> GEORADIUS china:city 120 35 1000 km withdist count 2
1) 1) "shanghai"
   2) "441.1015"
2) 1) "beijing"
   2) "630.7947"
127.0.0.1:6379> GEORADIUS china:city 120 35 1000 km withdist count 3
1) 1) "shanghai"
   2) "441.1015"
2) 1) "beijing"
   2) "630.7947"
  1. GEORADIUSBYMEMBER:
    和 GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是 GEORADIUSBYMEMBER 的中心点是由给定的位置元素决定的, 而不是像 GEORADIUS 那样, 使用输入的经度和纬度来决定中心点,指定成员的位置被用作查询的中心。
127.0.0.1:6379> GEORADIUSBYMEMBER china:city changsha 100 km withdist
1) 1) "changsha"
   2) "0.0000"
2) 1) "yiyang"
   2) "72.4885"

原理

GEO地理空间是基于zset有序集合实现的,也就是说我们可以通过zset命令来操作。

127.0.0.1:6379> ZRANGE china:city 0 -1 #查看已添加的所有城市
1) "yiyang"
2) "changsha"
3) "shanghai"
4) "beijing"
127.0.0.1:6379> zrem china:city shanghai #删除某一个
(integer) 1
127.0.0.1:6379> ZRANGE china:city 0 -1
1) "yiyang"
2) "changsha"
3) "beijing"