乐趣区

关于redis:redis-九redis之Geospatial

redis 系列文章:
https://liudongdong.top/categ…
本篇起源:
https://liudongdong.top/archi…
公众号:雨中散步撒哈拉
备注:欢送关注公众号,一起学习,共同进步!

一、基本概念

Geospatial 类型,底层实现原理实现为 zset 类型!

1. 应用什么样的地球模型(Earth model)?

这只是假如地球是一个球体,因为应用的间隔公式是 Haversine 公式。这个公式仅实用于地球,而不是一个完满的球体。当在社交网站和其余大多数须要查问半径的利用中应用时,这些偏差都不算问题。然而,在最坏的状况下的偏差可能是 0.5%,所以一些地理位置很要害的利用还是须要审慎思考。

2. 它是如何工作的?

sorted set 应用一种称为 Geohash 的技术进行填充。经度和纬度的位是交织的,以造成一个独特的 52 位整数. 咱们晓得,一个 sorted set 的 double score 能够代表一个 52 位的整数,而不会失去精度。

这种格局容许半径查问查看的 1 + 8 个畛域须要笼罩整个半径,并抛弃元素以外的半径。通过计算该区域的范畴,通过计算所涵盖的范畴,从不太重要的局部的排序集的得分,并计算得分范畴为每个区域的 sorted set 中的查问。

GeoHash 是一种地址编码方法。他可能把二维的空间经纬度数据编码成一个字符串

3. 能够做什么?

  1. 查问某个坐标左近的坐标(左近的人性能)
  2. 查问两点间的间隔
  3. ……

二、命令实际

因为 geo 命令过少,不进行了分类,残缺命令请看官网,本篇命令请看附录!

中国诚恳坐标经纬度查问,进行查问中国城市具体坐标!

1. geoadd 增加经纬元素

将指定的天文空间地位(纬度、经度、名称)增加到指定的 key 中。这些数据将会存储到 sorted set 这样的目标是为了方便使用 GEORADIUS 或者 GEORADIUSBYMEMBER 命令对数据进行半径查问等操作。

该命令以采纳规范格局的参数 x,y, 所以经度必须在纬度之前。这些坐标的限度是能够被编入索引的,区域面积能够很靠近极点然而不能索引。具体的限度,由 EPSG:900913 / EPSG:3785 / OSGEO:41001 规定如下:

无效的经度从 -180 度到 180 度。
无效的纬度从 -85.05112878 度到 85.05112878 度。
当坐标地位超出上述指定范畴时,该命令将会返回一个谬误。

返回值
增加到 sorted set 元素的数目,但不包含已更新 score 的元素。

127.0.0.1:6379> geoadd china 116.408 39.904 beijing
(integer) 1
127.0.0.1:6379> geoadd china 121.445 31.213 shanghai 117.246 39.117 tianjing
(integer) 2
127.0.0.1:6379> zrange china 0 -1
1) "shanghai"
2) "tianjing"
3) "beijing"
127.0.0.1:6379>

2. geodist 获取俩个元素之间直线间隔

如果两个地位之间的其中一个不存在,那么命令返回空值。

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

  1. m 示意单位为米。
  2. km 示意单位为千米。
  3. mi 示意单位为英里。
  4. ft 示意单位为英尺。
    如果用户没有显式地指定单位参数,那么 GEODIST 默认应用米作为单位。

GEODIST 命令在计算间隔时会假如地球为完满的球形,在极限状况下,这一假如最大会造成 0.5% 的误差。

返回值
计算出的间隔会以双精度浮点数的模式被返回。如果给定的地位元素不存在,那么命令返回空值。

127.0.0.1:6379> zrange china 0 -1
1) "shanghai"
2) "tianjing"
3) "beijing"
127.0.0.1:6379> geodist china beijing shanghai m
"1068232.0171"
127.0.0.1:6379> geodist china beijing shanghai km
"1068.2320"
127.0.0.1:6379>

3. geopos 获取指定元素经纬度

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

给定一个 sorted set 示意的空间索引,密集应用 geoadd 命令,它以取得指定成员的坐标往往是无益的。当空间索引填充通过 geoadd 的坐标转换成一个 52 位 Geohash,所以返回的坐标可能不齐全以增加元素的,但小的谬误可能会出台。

因为 GEOPOS 命令承受可变数量的地位元素作为输出,所以即便用户只给定了一个地位元素,命令也会返回数组回复。

返回值
GEOPOS 命令返回一个数组,数组中的每个项都由两个元素组成:第一个元素为给定地位元素的经度,而第二个元素则为给定地位元素的纬度。

当给定的地位元素不存在时,对应的数组项为空值。

127.0.0.1:6379> geopos china beijing
1) 1) "116.40800267457962"
   2) "39.903999881660361"
127.0.0.1:6379> geopos china beijing222
1) (nil)
127.0.0.1:6379>

4. georadius 指定经纬度和半径获取元素(左近人性能)

以给定的经纬度为核心,返回键蕴含的地位元素当中,与核心的间隔不超过给定最大间隔的所有地位元素。

范畴能够应用以下其中一个单位:

  1. m 示意单位为米。
  2. km 示意单位为千米。
  3. mi 示意单位为英里。
  4. ft 示意单位为英尺。
    在给定以下可选项时,命令会返回额定的信息:

WITHDIST: 在返回地位元素的同时,将地位元素与核心之间的间隔也一并返回。间隔的单位和用户给定的范畴单位保持一致。
WITHCOORD: 将地位元素的经度和维度也一并返回。
WITHHASH: 以 52 位有符号整数的模式,返回地位元素通过原始 geohash 编码的有序汇合分值。这个选项次要用于底层利用或者调试,理论中的作用并不大。
命令默认返回未排序的地位元素。通过以下两个参数,用户能够指定被返回地位元素的排序形式:

ASC: 依据核心的地位,依照从近到远的形式返回地位元素。
DESC: 依据核心的地位,依照从远到近的形式返回地位元素。
在默认状况下,GEORADIUS 命令会返回所有匹配的地位元素。尽管用户能够应用 COUNT <count> 选项去获取前 N 个匹配元素,然而因为命令在外部可能会须要对所有被匹配的元素进行解决,所以在对一个十分大的区域进行搜寻时,即便只应用 COUNT 选项去获取大量元素,命令的执行速度也可能会十分慢。然而从另一方面来说,应用 COUNT 选项去缩小须要返回的元素数量,对于缩小带宽来说依然是十分有用的。

返回值
在没有给定任何 WITH 选项的状况下,命令只会返回一个像 [“New York”,”Milan”,”Paris”] 这样的线性(linear)列表。
在指定了 WITHCOORD、WITHDIST、WITHHASH 等选项的状况下,命令返回一个二层嵌套数组,内层的每个子数组就示意一个元素。
在返回嵌套数组时,子数组的第一个元素总是地位元素的名字。至于额定的信息,则会作为子数组的后续元素,依照以下程序被返回:

以浮点数格局返回的核心与地位元素之间的间隔,单位与用户指定范畴时的单位统一。
geohash 整数。
由两个元素组成的坐标,别离为经度和纬度。
举个例子,GEORADIUS Sicily 15 37 200 km WITHCOORD WITHDIST 这样的命令返回的每个子数组都是相似以下格局的:

["Palermo","190.4424",["13.361389338970184","38.115556395496299"]]
# 坐标天津经纬度,半径为 1000km 范畴,进行检索
127.0.0.1:6379> georadius china 117.246 39.117 1000 km withcoord withdist withhash count 3 asc
1) 1) "tianjing"
   2) "0.0001"
   3) (integer) 4069186232887724
   4) 1) "117.24599987268448"
      2) "39.116999378339521"
2) 1) "beijing"
   2) "113.2836"
   3) (integer) 4069885369376452
   4) 1) "116.40800267457962"
      2) "39.903999881660361"
3) 1) "shanghai"
   2) "958.1492"
   3) (integer) 4054756185507317
   4) 1) "121.44499808549881"
      2) "31.213001199663303"
127.0.0.1:6379>

5. georadiusbymember 指定元素和半径进行扫描

这个命令和 GEORADIUS 命令一样,都能够找出位于指定范畴内的元素,然而 GEORADIUSBYMEMBER 的中心点是由给定的地位元素决定的,而不是像 GEORADIUS 那样,应用输出的经度和纬度来决定中心点

指定成员的地位被用作查问的核心。

对于 GEORADIUSBYMEMBER 命令的更多信息,请参考 GEORADIUS 命令的文档。

127.0.0.1:6379> georadiusbymember china tianjing 1000 km withcoord withdist withhash count 3 asc
1) 1) "tianjing"
   2) "0.0000"
   3) (integer) 4069186232887724
   4) 1) "117.24599987268448"
      2) "39.116999378339521"
2) 1) "beijing"
   2) "113.2837"
   3) (integer) 4069885369376452
   4) 1) "116.40800267457962"
      2) "39.903999881660361"
3) 1) "shanghai"
   2) "958.1491"
   3) (integer) 4054756185507317
   4) 1) "121.44499808549881"
      2) "31.213001199663303"
127.0.0.1:6379>

6. geohash 坐标以 hash 示意

返回一个或多个地位元素的 Geohash 示意。

通常应用示意地位的元素应用不同的技术,应用 Geohash 地位 52 点整数编码。因为编码和解码过程中所应用的初始最小和最大坐标不同,编码的编码也不同于规范。此命令返回一个规范的 Geohash,在维基百科和 geohash.org 网站都有相干形容

Geohash 字符串属性
该命令将返回 11 个字符的 Geohash 字符串,所以没有精度 Geohash,损失相比,应用外部 52 位示意。返回的 geohashes 具备以下个性:

他们能够缩短从左边的字符。它将失去精度,但仍将指向同一地区。
它能够在 geohash.org 网站应用,网址 http://geohash.org/<geohash-string>。查问例子:http://geohash.org/sqdtr74hyu0.
与相似的前缀字符串是左近,但相同的是不正确的,这是可能的,用不同的前缀字符串左近。
返回值
一个数组,数组的每个项都是一个 geohash。命令返回的 geohash 的地位与用户给定的地位元素的地位一一对应。

127.0.0.1:6379> zrange china 0 -1
1) "shanghai"
2) "tianjing"
3) "beijing"
127.0.0.1:6379> geohash china beijing tianjing
1) "wx4g0bm9xh0"
2) "wwgqecpcjc0"
127.0.0.1:6379>

附录

命令 形容
Redis GEOHASH 命令 返回一个或多个地位元素的 Geohash 示意
Redis GEOPOS 命令 从 key 里返回所有给定地位元素的地位(经度和纬度)
Redis GEODIST 命令 返回两个给定地位之间的间隔
Redis GEORADIUS 命令 以给定的经纬度为核心,找出某一半径内的元素
Redis GEOADD 命令 将指定的天文空间地位(纬度、经度、名称)增加到指定的 key 中
Redis GEORADIUSBYMEMBER 命令 找出位于指定范畴内的元素,中心点是由给定的地位元素决定
退出移动版