Redis GEO地理信息定位功能
GEO
Redis 提供了GEO地理信息定位功能,地理空間項(經度、緯度、名稱),實現查找附近的人、上班打卡、自行車租賃、搖一搖等相關與地理位置信息的功能。 Redis 地理空間索引可讓您存儲坐標并搜索它們。 此數據結構對于查找給定半徑或邊界框內的附近點非常有用。
基本命令
- GEOADD將位置添加到給定的地理空間索引(請注意,使用此命令時,經度位于緯度之前)。
- GEOSEARCH返回具有給定半徑或邊界框的位置。
GEOADD
將指定的地理空間項(經度、緯度、名稱)添加到指定的鍵。數據作為排序集存儲到鍵中,這樣就可以使用 GEOSEARCH 命令查詢項目。
該命令采用標準格式 x,y 的參數,因此必須在緯度之前指定經度??伤饕淖鴺舜嬖谙拗疲悍浅?拷鼧O點的區(qū)域不可索引。
當用戶嘗試索引指定范圍之外的坐標時,該命令將報告錯誤。
通常,Redis 使用 Geohash 的變體來表示元素的位置 使用 52 位整數對位置進行編碼的技術。編碼是 與標準相比也不同,因為初始最小值和最大值 編碼和解碼過程中使用的坐標是不同的。
longitude 經度 、latitude 緯度、member 成員
GEOADD key [NX | XX] [CH] longitude latitude member [longitude latitude member ...]
以下添加5個城市經緯度到 鍵 cities:geo, 如果已經存在則返回0,如果需要更新地理位置,同樣使用GEOADD命令(僅管返回0)。
# 北京 192.168.88.11:6380> GEOADD cities:geo 116.28 39.54 beijing (integer) 1 # 天津 192.168.88.11:6380> GEOADD cities:geo 117.10 39.10 tianjin (integer) 1 # 廣州 192.168.88.11:6380> GEOADD cities:geo 113.18 23.10 guangzhou (integer) 1 # 杭州 192.168.88.11:6380> GEOADD cities:geo 120.10 30.15 hangzhou (integer) 1 # 長沙 192.168.88.11:6380> GEOADD cities:geo 112.55 28.12 changsha (integer) 1
注意:沒有GEODEL命令,因為您可以使用ZREM 刪除元素。 Geo索引結構只是一個排序集。本質是 zset 數據類型。
# 查看成員 192.168.88.11:6380> ZRANGE cities:geo 0 5 1) "guangzhou" 2) "changsha" 3) "hangzhou" 4) "beijing" 5) "tianjin" # 查看成員帶分數 192.168.88.11:6380> ZRANGE cities:geo 0 5 withscores 1) "guangzhou" 2) "4046510568184210" 3) "changsha" 4) "4050880415755396" 5) "hangzhou" 6) "4054121680734333" 7) "beijing" 8) "4069140601296155" 9) "tianjin" 10) "4069185531597821" # 集合大小: 5 192.168.88.11:6380> ZCARD cities:geo (integer) 5 # 刪除兩個元素 192.168.88.11:6380> ZREM cities:geo changsha hangzhou (integer) 2 # 集合大小: 3 192.168.88.11:6380> ZCARD cities:geo (integer) 3
如何計算 “beijing” 經緯度(116.28, 39.54) 的分值 4069140601296155 ? 排序集的填充方式是使用一種叫做Geohash的技術。經度位和緯度位相互交錯,形成一個唯一的52位整數。
EPSG:900913 / EPSG:3785 / OSGEO:41001 指定的確切限制如下:
- 有效經度范圍為 -180 到 180 度。
- 有效緯度范圍為 -85.05112878 到 85.05112878 度。
按下面的編碼為N=26位二進制值 ,然后把經緯度交叉組成52位二進制值即可。 (偶數位為經度、奇數位為緯度)

這里,可以通過python腳本定義兩個列表,然后不斷拆分區(qū)間,最后做交叉合拼兩個列表。結果如下:
root@ubuntu-x64_01:/opt# python3 redis_geo_bit.py
guangzhou---> 1110011000000100011110101000111111110001100110010010
changsha ---> 1110011001000100000100011000001101010110110010000100
hangzhou ---> 1110011001110011001111000010101010000000100001111101
beijing ---> 1110011101001101110010100000000101001101010100011011
tianjin ---> 1110011101001110011100010110001000101101001111111101
再轉換成十進制,就是 zset 的分數值,比如 guangzhou (1110011000000100011110101000111111110001100110010010)對應十進制 : 4046510568184210
192.168.88.11:6380> ZRANGE cities:geo 0 0 withscores 1) "guangzhou" 2) "4046510568184210"
GEOHASH
返回有效的Geohash 字符串,表示一個或多個元素在表示地理空間索引的排序集值中的位置(其中元素是使用GEOADD)。
該命令返回11個字符的Geohash字符串,因此與Redis內部52位表示相比,沒有精度損失。
- 他們可以縮短,從右邊刪除字符。它將失去精度,但仍然指向相同的區(qū)域。
- 可以在geohash.org url中使用它們,例如http://geohash.org/<geohash-string>。
- 具有相似前綴的字符串在附近,但反之則不成立,具有不同前綴的字符串也可能在附近。
字符串越長,表示的位置更精確,例如geohash長度為8時,精度在19米左右。

下面操作返回 beijing 的 geohash 值,如下:
192.168.88.11:6380> GEOHASH cities:geo beijing 1) "wx48yn090q0"
可以在geohash.org url中使用它們: http://geohash.org/wx48yn090q0

GEOPOS
返回由排序集key表示的地理空間索引中所有指定成員的位置(經度、緯度)。當通過GEOADD填充地理空間索引時,坐標被轉換為52位geohash,因此返回的坐標可能不完全是用于添加元素的坐標,但可能會引入小誤差。
192.168.88.11:6380> GEOPOS cities:geo guangzhou 1) 1) "113.18000167608261108" 2) "23.10000005307264104" 192.168.88.11:6380> GEOPOS cities:geo changsha 1) 1) "112.54999905824661255" 2) "28.12000010081647616" 192.168.88.11:6380> GEOPOS cities:geo hangzhou 1) 1) "120.09999901056289673" 2) "30.14999997874437554" 192.168.88.11:6380> GEOPOS cities:geo beijing 1) 1) "116.28000229597091675" 2) "39.54000124957348561" 192.168.88.11:6380> GEOPOS cities:geo tianjin 1) 1) "117.10000187158584595" 2) "39.09999900352384117"
GEODIST
返回由排序集表示的地理空間索引中兩個成員之間的距離。
給定一個表示地理空間索引的排序集,使用GEOADD命令填充,該命令返回指定單元中兩個指定成員之間的距離。
如果缺少一個或兩個成員,則該命令返回NULL。
單位必須為以下之一,默認為米:
- m for meters. 代表米
- km for kilometers. 代表公里
- mi for miles.代表英里
- ft for feet. 代表尺
如計算北京與天津之間的距離,并以公里為單位返回,如下:
192.168.88.11:6380> GEODIST cities:geo beijing tianjin km "85.8689"
GEORADIUS
獲取指定位置范圍內的地理信息位置集合,返回使用GEOADD填充地理空間信息的已排序集合的成員,這些成員位于用中心位置和到中心的最大距離(半徑)指定的區(qū)域的邊界內。
該命令的常見用例是檢索指定點附近的地理空間項目,距離不超過給定的米(或其他單位)。例如,這允許向應用程序附近的移動用戶提供建議。
單位必須為以下之一,默認為米:
- m for meters. 代表米
- km for kilometers. 代表公里
- mi for miles.代表英里
- ft for feet. 代表尺:
GEORADIUS key longitude latitude radius <M | KM | FT | MI> [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC | DESC] [STORE key | STOREDIST key]
該命令可以使用以下選項返回附加信息:
- WITHDIST: 返回結果中包含到指定中心的距離。返回的距離單位與命令的radius參數指定的單位相同。
- WITHCOORD: 返回結果中包含經度、緯度坐標。
- WITHHASH: 以52位無符號整數的形式返回該項的原始geohash編碼的排序集分數。
該命令默認返回未排序的項??梢允褂靡韵聝蓚€選項調用兩種不同的排序方法:
- ASC: 對返回的項目進行排序,從最近到最遠,相對于中心。
- DESC: 相對于中心,從最遠到最近對返回項進行排序。
默認情況下,返回所有匹配項。通過使用COUNT < COUNT >選項,可以將結果限制為前N個匹配項。
- 當提供ANY時,只要找到足夠的匹配項,命令就會返回,因此結果可能不是最接近指定點的結果,但另一方面,服務器投入的精力大大降低了。
- 當沒有提供ANY時,該命令將執(zhí)行與指定區(qū)域匹配的項數成比例的工作,并對它們進行排序,因此使用非常小的COUNT選項查詢非常大的區(qū)域可能很慢,即使只返回幾個結果。
默認情況下,該命令將條目返回給客戶端??梢允褂靡韵逻x項之一來存儲結果:
- STORE:將項目存儲在使用其地理空間信息填充的已排序集合中。
- STOREDIST:將項目存儲在一個排序的集合中,該集合以與中心的距離作為浮點數填充,在半徑中指定的相同單位中
如,計算距離 北京 200公里 以內的城市:
192.168.88.11:6380> GEORADIUS cities:geo 116.28 39.54 200 km
1) "beijing"
2) "tianjin"
192.168.88.11:6380> GEORADIUS cities:geo 116.28 39.54 200 km WITHCOORD WITHDIST WITHHASH
1) 1) "beijing"
2) "0.0002"
3) (integer) 4069140601296155
4) 1) "116.28000229597091675"
2) "39.54000124957348561"
2) 1) "tianjin"
2) "85.8690"
3) (integer) 4069185531597821
4) 1) "117.10000187158584595"
2) "39.09999900352384117"
192.168.88.11:6380> GEORADIUS cities:geo 116.28 39.54 200 km WITHCOORD WITHDIST WITHHASH COUNT 1 DESC
1) 1) "tianjin"
2) "85.8690"
3) (integer) 4069185531597821
4) 1) "117.10000187158584595"
2) "39.09999900352384117"
# 將項目存儲在使用其地理空間信息填充的已排序集合中。
192.168.88.11:6380> GEORADIUS cities:geo 116.28 39.54 200 km COUNT 1 DESC STORE cities:georadius
(integer) 1
192.168.88.11:6380> type cities:georadius
zset
192.168.88.11:6380> ZRANGE cities:georadius 0 5 withscores
1) "tianjin"
2) "4069185531597821"小結
- 沒有GEODEL命令,因為您可以使用它ZREM來刪除元素。Geo索引結構只是一個排序集。GEO沒有提供刪除成員的命令,因為GEO的底層實現是zset,如果要刪除成員,請使用 zrem 命令來對地理位置信息進行刪除。
- 當通過GEOADD填充地理空間索引時,坐標被轉換為52位geohash,因此返回的坐標可能不完全是用于添加元素的坐標,即可能會引入小誤差。
- 填充排序集的方式是使用一種稱為 Geohash的技術。緯度和經度位交錯形成唯一的 52 位整數。
到此這篇關于Redis GEO地理信息定位功能的文章就介紹到這了,更多相關Redis GEO地理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

