【第三章 小功能大用处】3.8、GEO

in with 0 comment

GEO

Redis3.2版本提供了GEO(地理信息定位)功能,支持存储地理位置信息用来实现诸 如附近位置、摇一摇这类依赖于地理位置信息的功能,对于需要实现这些功能的开发 者来说是一个福音。GEO功能是Redis的另一位作者Matt Stancliff借鉴NoSQL数据 库Ardb实现的,Ardb的作者是来自中国,它供了优秀的GEO功能。

  1. 增加地理位置信息

    geoadd key longitude latitude member [longitude latitude member ...]

    longitude、latitude、member分别是该地理位置的经度、纬度、成员,下表 展示了5个城市的经纬度

    城市经度纬度成员
    北京116.2839.55beijing
    天津117.1239.08tianjin
    石家庄114.2938.02shijiazhuang
    唐山118.0139.38tangshan
    保定115.2938.51baoding

    cities:locations是上面5个城市地理位置信息的几个,现向其添加北京的地 理位置信息:

    1270.0.0.1:6379> geoadd cities:locations 116.28 39.55 beijing
    (integer) 1
    

    返回结果代表添加成功的个数,如果cities:locations没有包含beijing,那 么返回结果为1,如果已经存在则返回0:

    1270.0.0.1:6379> geoadd cities:locations 116.28 39.55 beijing
    (integer) 0
    

    如果需要更新地理位置信息,仍然可以使用geoadd命令,虽然返回结果为 0.geoadd命令可以同时添加多个地理位置信息:

    1270.0.0.1:6379> geoadd cities:locations 117.12 39.08 tianjin 114.29 38.02 shijiazhuang 118.01 39.38 tangshan 115.29 38.51 baoding
    (integer) 4
    
  2. 获取地理位置信息

    geopos key member [member ...]

    下面操作会获取天津的经纬度:

    1270.0.0.1:6379> geopos cities:location tianjian
    1) 1) "117.12000042200088501"
       2) "39.0800000535766543"
    
  3. 获取两个地理位置的距离

    geodist key member1 member2 [unit]

    其中unit代表返回结果的单位,包含以下四中:

    • m(meters)代表米
    • km(kilometers)代表千米
    • mi(miles)代表英尺
    • ft(feet)代表尺

    下面操作用于计算天津到北京的距离,并以公里为单位:

    1270.0.0.1:6379> geodist cities:location tianjin beijing km
    "89.2061"
    
  4. 获取指定位置范围内的地理信息位置集合

    georadius key longitude latitude radiusm|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]
    
    georadiusbymember key member radiusm|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]
    

    georadisu和georadiusbymember两个命令的作用是一样的,都是以一个地理 位置为中心算出指定半径内的其他地理信息位置,不同的是georadius命令的中 心位置给出了具体的经纬度,georadiusbymember只需给出成员即可。其中 radiusm|km|ft|mi是必需参数,指定了半径(带单位),这两个命令有很多可 选参数,如下所示:

    • withcoord:返回结果中包含经纬度。
    • withdist:返回结果中包含离中心节点位置的距离。
    • withhash:返回结果中包含geohash,有关geohash后面介绍。
    • COUNT count:指定返回结果的数量。
    • asc|desc:返回结果按照离中心节点的距离做升序或者降序。
    • store key:将返回结果的地理位置信息保存到指定键。
    • storedist key:将返回结果离中心节点的距离保存到指定键。

    下面操作计算第五座城市中,距离北京150公里以内的城市:

    127.0.0.1:6379> georadiusbymember cities:location beijing 150 km
    1) "beijing"
    2) "tianjin"
    3) "tangshan"
    4) "baoding"
    
  5. 获取geohash

    geohash key member [member ...]

    Redis使用geohash将二维经纬度转换为一维字符串,下面操作会返回beijing 的geohash值。

    127.0.0.1:6379> geohash cities:locations beijing
    1) "wx4ww02w070"
    

    geohash有如下特点:

    • GEO的数据类型zset,Redis将所有地理位置信息的geohash存放在zset中。

      127.0.0.1:6379> type cities:locations
      zset
      
    • 字符串越长,表示的位置更精确,下表给出了字符串长度对应的精度,例如 geohash长度为9时,精度在2米左右。

      geohash长度精确度(km)
      12500
      2630
      378
      420
      52.4
      60.61
      70.076
      80.019
      90.002
    • 两个字符串越相似,它们之间的距离越近,Redis利用字符串前缀匹配算法实 现相关的命令。

    • geohash编码和经纬度是可以相互转换的。

    Redis正式使用有序集合并结合geohash的特性实现了GEO的若干命令。

  6. 删除地理位置信息

    zrem key member

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