日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

redis之GEO使用

發布時間:2024/1/1 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redis之GEO使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

寫在前面

在LBS(location based service)應用,如滴滴打車應用,需要根據用戶的位置信息來獲取某些數據,如獲取距離當前用戶指定距離范圍內的所有車輛信息,該類的應用就可以使用本文我們要學習的GEO了,接下來一起看下。

1:實戰

1.1:geoadd

添加位置信息,格式GEOADD key longitude latitude member [longitude latitude member ...],可以指定多組經度+緯度+位置名稱,如下:

redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania" (integer) 2

1.2:geopos

獲取指定位置的經緯度,如果是不存在的位置則返回nil,格式GEOPOS key member [member ...],如下測試:

redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania" (integer) 2 redis> GEOPOS Sicily Palermo Catania NonExisting 1) 1) "13.36138933897018433"2) "38.11555639549629859" 2) 1) "15.08726745843887329"2) "37.50266842333162032" 3) (nil) redis>

1.3:geodist

geodist 用于返回兩個給定位置之間的距離。geodist 語法格式為GEODIST key member1 member2 [m|km|ft|mi],參數說明如下:

m:米,默認單位。 km:千米。 mi:英里。 ft:英尺。

如果是不存在的地點則返回nil,如下測試:

redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania" (integer) 2 redis> GEODIST Sicily Palermo Catania "166274.1516" redis> GEODIST Sicily Palermo Catania km "166.2742" redis> GEODIST Sicily Palermo Catania mi "103.3182" redis> GEODIST Sicily Foo Bar (nil)

1.4:georadius

以給定的經緯度為中心,并指定距離范圍,返回該距離范圍內的所有地點信息,格式如下:

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

參數說明如下:

m:米,默認單位。 km:千米。 mi:英里。 ft:英尺。 WITHDIST: 在返回位置元素的同時, 將位置元素與中心之間的距離也一并返回。 WITHCOORD: 將位置元素的經度和緯度也一并返回。 WITHHASH: 以 52 位有符號整數的形式, 返回位置元素經過原始 geohash 編碼的有序集合分值。 這個選項主要用于底層應用或者調試, 實際中的作用并不大。 COUNT 限定返回的記錄數。 ASC: 查找結果根據距離從近到遠排序。 DESC: 查找結果根據從遠到近排序。

測試如下:

redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania" (integer) 2 redis> GEORADIUS Sicily 15 37 200 km WITHDIST 1) 1) "Palermo"2) "190.4424" 2) 1) "Catania"2) "56.4413" redis> GEORADIUS Sicily 15 37 200 km WITHCOORD 1) 1) "Palermo"2) 1) "13.36138933897018433"2) "38.11555639549629859" 2) 1) "Catania"2) 1) "15.08726745843887329"2) "37.50266842333162032" redis> GEORADIUS Sicily 15 37 200 km WITHDIST WITHCOORD 1) 1) "Palermo"2) "190.4424"3) 1) "13.36138933897018433"2) "38.11555639549629859" 2) 1) "Catania"2) "56.4413"3) 1) "15.08726745843887329"2) "37.50266842333162032"

1.5:geohash

獲取經緯度對應的geohash值,底層Set中存儲的也是該值,語法格式為GEOHASH key member [member ...],測試如下:

redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania" (integer) 2 redis> GEOHASH Sicily Palermo Catania 1) "sqc8b49rny0" 2) "sqdtr74hyu0"

2:原理

我們知道,經度的范圍是[-180,180],緯度的范圍是[-90,90],我們可以將其想想為如下的一個矩形,矩形中的每個點都有一個經緯度的信息,如下圖:

但是這個圖里每一個點目前都是用經度和緯度來表示的,如果是我們能夠將矩形劃分成很多個區域,然后每個區域使用一個整數來表示,則就很容易方便查找周邊經緯度了,而redis就使用GeoHash編碼方法實現了這個需求,基本原理是二分區間,區間編碼,二分區間的意思是將經度或緯度的范圍平分為兩份,區間編碼就是對每一份給一個編碼,具體的,redis會分別對經度和緯度執行GeoHash,然后將二者的編碼合并為最終的編碼。

GeoHash會將經度和緯度劃分為N位的二進制編碼,其中N就是需要對區間劃分的次數,這里我們假設N為5來編碼,假設要編碼的經緯度是(116.37,39.86)看下這個過程:

首先對經度編碼,如果落在左區間則編碼為0,如果落在右區間則編碼為1:

二分[-180,180]為[-180,0),[0,180]左右兩個區間,116.37落在右區間,所以編碼為1 二分[0,180]為[0,90),[90,180]左右兩個區間,116.37落在右區間,所以編碼為1 二分[90,180]為[90,135),[135,180]左右兩個區間,116.37落在左區間,所以編碼為0 二分[90,135]為[90,112.5),[112.5,135]左右兩個區間,116.37落在右區間,所以編碼為1 二分[112.5,135]為[112.5,123.75),[123.75,135]左右兩個區間,116.37落在左區間,所以編碼為0

所以最終的編碼是11010,該過程也可以用下圖表示:

緯度同該編碼過程,最終結果是10111,該過程可以用下圖表:

最終二者組合的規則是:從左到右偶數位依次取經度的編碼,奇數位依次取緯度的編碼,因此我們先來取經度的編碼,為1?1?0?1?0?,接著我們將其中的?,即奇數位使用緯度的編碼替換,結果就是1110011101,整個過程如下圖:

這樣,一個經緯度就會被轉換為一個整數,而相近的整數在實際的地理位置上也是更接近的,這里我們生成編碼的N如果是越大,則矩形的區域也會被劃分的越細,距離的匹配也會更加精確。

其實GEO底層使用的數據結構正是Set,而DeoHash的結果是作為其score的,這樣當我們查找某地附近的地點時,就可以直接上前向后直接查找了。

3:打車場景

假定用戶打車場景中根據用戶所在定位查找車輛,先模擬庫中的車輛信息:

127.0.0.1:6379> GEOADD car:location 13.361389 38.115556 "張師傅" 15.087269 37.502669 "李師傅" 17.087269 35.502669 "劉師傅" 117.087269 65.502669 "孫小姐"

現在顧客芒果小朋友要打車,假設經緯度是13.361399 38.115565,則查找其5公里范圍內的車輛,如下:

127.0.0.1:6379> GEORADIUS car:location 13.361399 38.115565 5 km 張師傅

可以看到只有張師傅符合要求,那么就可以給張師傅派單了。

寫在后面

參考文章列表:

Redis GEO 。

總結

以上是生活随笔為你收集整理的redis之GEO使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。