三种特殊数据类型之geospatial地理位置

172 阅读5分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

geospatial地理位置

朋友的人定位,附件的人,打车距离计算?

Redis的Geo在redis3.2版本就推出了 ,

GEOADD

时间复杂度: 每一个元素添加是O(log(N)) ,N是sorted set的元素数量

  • 将指定的地理空间位置(纬度、经度、名称)添加到指定的`key`中。这些数据将会存储到`sorted set`这样的目的是为了方便使用[GEORADIUS](http://redis.cn/commands/georadius.html)或者[GEORADIUSBYMEMBER](http://redis.cn/commands/georadiusbymember.html)命令对数据进行半径查询等操作。
    ​
    该命令以采用标准格式的参数x,y,所以经度必须在纬度之前。这些坐标的限制是可以被编入索引的,区域面积可以很接近极点但是不能索引。具体的限制,由EPSG:900913 / EPSG:3785 / OSGEO:41001 规定如下:
    ​
    - 有效的经度从-180度到180度。
    - 有效的纬度从-85.05112878度到85.05112878度。
    

当坐标位置超出上述指定范围时,该命令将会返回一个错误

例子

127.0.0.1:6379> geoadd chain:city  104.10194 30.65984 chengdu
(integer) 1
127.0.0.1:6379> geoadd china:city  104.10194 30.65984 chengdu
(integer) 1
127.0.0.1:6379> geoadd china:city 121.48941 31.40527 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 116.23128 40.22077 beijing
127.0.0.1:6379> geoadd china:city 120.21201 30.2084 hangzhou
(integer) 1
127.0.0.1:6379> geoadd china:city 118.03394 24.48405 xiamen

GEODIST key member1 member2 [unit]

时间复杂度: O(log(N))

返回两个给定位置之间的距离。
​
如果两个位置之间的其中一个不存在, 那么命令返回空值。
​
指定单位的参数 unit 必须是以下单位的其中一个:
​
- **m** 表示单位为米。
- **km** 表示单位为千米。
- **mi** 表示单位为英里。
- **ft** 表示单位为英尺。
​
如果用户没有显式地指定单位参数, 那么 `GEODIST` 默认使用米作为单位。
​
`GEODIST` 命令在计算距离时会假设地球为完美的球形, 在极限情况下, 这一假设最大会造成 0.5% 的误差。

例子

127.0.0.1:6379> geodist china:city xiamen hangzhou km
"672.0259"
127.0.0.1:6379> geodist china:city hangzhou beijing km
"1170.5529"

GEOPOS key member [member ...]

时间复杂度: O(log(N)) for each member requested, where N is the number of elements in the sorted set.

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

例子

127.0.0.1:6379> geopos china:city hangzhou
1) 1) "120.21200805902481079"
   2) "30.20839995425554747"

GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]

时间复杂度: O(N+log(M)) where N is the number of elements inside the bounding box of the circular area delimited by center and radius and M is the number of items inside the index.

以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。

范围可以使用以下其中一个单位:

  • m 表示单位为米。
  • km 表示单位为千米。
  • mi 表示单位为英里。
  • ft 表示单位为英尺。

在给定以下可选项时, 命令会返回额外的信息:

  • WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
  • WITHCOORD: 将位置元素的经度和维度也一并返回。
  • WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。

例子

127.0.0.1:6379> georadius china:city 110 56 5000 km
1) "chengdu"
2) "xiamen"
3) "hangzhou"
4) "shanghai"
5) "beijing"
127.0.0.1:6379> georadius china:city 110 56 2000 km
1) "beijing"

GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]

时间复杂度: O(N+log(M)) where N is the number of elements inside the bounding box of the circular area delimited by center and radius and M is the number of items inside the index.

这个命令和 GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是 GEORADIUSBYMEMBER 的中心点是由给定的位置元素决定的, 而不是像 GEORADIUS 那样, 使用输入的经度和纬度来决定中心点

指定成员的位置被用作查询的中心。

例子

127.0.0.1:6379> georadiusbymember china:city hangzhou 2000 km
1) "chengdu"
2) "xiamen"
3) "hangzhou"
4) "shanghai"
5) "beijing"
127.0.0.1:6379> georadiusbymember china:city hangzhou 1000 km
1) "xiamen"
2) "hangzhou"
3) "shanghai"

GEOHASH key member [member ...]

时间复杂度: O(log(N)) for each member requested, where N is the number of elements in the sorted set.

返回一个或多个位置元素的 Geohash 表示。

通常使用表示位置的元素使用不同的技术,使用Geohash位置52点整数编码。由于编码和解码过程中所使用的初始最小和最大坐标不同,编码的编码也不同于标准。此命令返回一个标准的Geohash,在维基百科geohash.org网站都有相关描述

Geohash字符串属性

该命令将返回11个字符的Geohash字符串,所以没有精度Geohash,损失相比,使用内部52位表示。返回的geohashes具有以下特性:

  1. 他们可以缩短从右边的字符。它将失去精度,但仍将指向同一地区。
  2. 它可以在 geohash.org 网站使用,网址 http://geohash.org/<geohash-string>。查询例子:geohash.org/sqdtr74hyu0.
  3. 与类似的前缀字符串是附近,但相反的是不正确的,这是可能的,用不同的前缀字符串附近。

例子

127.0.0.1:6379> geohash china:city hangzhou beijing
1) "wtm7z7r8wv0"
2) "wx4sucvncn0

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

我附近的人

GEOHASH

#将二维经纬度转换为一维的字符串

GEO底层的实现原理其实就是Zset