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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GeoHash -------寻找附近人

發(fā)布時(shí)間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GeoHash -------寻找附近人 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
當(dāng)兩個(gè)元素的距離不是很遠(yuǎn)時(shí),可以直接使?勾股定理就能算得元素之間的距離。我們平時(shí)使?的「附近的?」的功能,元素距離都不是很?,勾股定理算距離?矣。不過需要注意的是,經(jīng)緯度坐標(biāo)的密度不?樣 (地球是?個(gè)橢圓),勾股定律計(jì)算平?差時(shí)之后再求和時(shí),需要按?定的系數(shù)?加權(quán)求和,如果不求精確的話,也可以不必加權(quán)。 業(yè)界?較通?的地理位置距離排序算法是 GeoHash 算法,Redis 也使? GeoHash 算法。GeoHash 算法將?維的經(jīng)緯度數(shù)據(jù)映射到?維的整數(shù),這樣所有的元素都將在掛載到?條線上,距離靠近的?維坐標(biāo)映射到?維后的點(diǎn)之間距離也會(huì)很接近。當(dāng)我們想要計(jì)算「附近的?時(shí)」,?先將?標(biāo)位置映射到這條線上,然后在這個(gè)?維的線上獲取附近的點(diǎn)就?了。那這個(gè)映射算法具體是怎樣的呢?它將整個(gè)地球看成?個(gè)?維平?,然后劃分成了?系列正?形的?格,就好?圍棋棋盤。所有的地圖元素坐標(biāo)都將放置于唯?的?格中。?格越?,坐標(biāo)越精確。然后對(duì)這些?格進(jìn)?整數(shù)編碼,越是靠近的?格編碼越是接近。那如何編碼呢??個(gè)最簡單的?案就是切蛋糕法。設(shè)想?個(gè)正?形的蛋糕擺在你?前,??下去均分分成四塊?正?形,這四個(gè)?正?形可以分別標(biāo)記為 00,01,10,11 四個(gè)?進(jìn)制整數(shù)。然后對(duì)每?個(gè)?正?形繼續(xù)???法切割?下,這時(shí)每個(gè)??正?形就可以使? 4bit 的?進(jìn)制整數(shù)予以表示。然后繼續(xù)切下去,正?形就會(huì)越來越?,?進(jìn)制整數(shù)也會(huì)越來越?,精確度就會(huì)越來越?。

增加

geoadd 指令攜帶集合名稱以及多個(gè)經(jīng)緯度名稱三元組,注意這?可以加?多個(gè)三元組 127.0.0.1:6379> geoadd company 116.48105 39.996794 juejin (integer) 1 127.0.0.1:6379> geoadd company 116.514203 (error) ERR wrong number of arguments for 'geoadd' command 127.0.0.1:6379> geoadd company 116.514203 39.905409 ireader (integer) 1 127.0.0.1:6379> geoadd company 116.489033 40.007669 meituan (integer) 1 127.0.0.1:6379> geoadd company 116.562108 39.787602 jd 116.334255 40.027400 xiaomi (integer) 2 也許你會(huì)問為什么 Redis 沒有提供 geo 刪除指令?前?我們提到 geo 存儲(chǔ)結(jié)構(gòu)上使?的是 zset,意味著我們可以使? zset 相關(guān)的 指令來操作 geo 數(shù)據(jù),所以刪除指令可以直接使? zrem 指令即 可。

距離

geodist 指令可以?來計(jì)算兩個(gè)元素之間的距離,攜帶集合名稱、2個(gè)名稱和距離單位。距離單位可以是m、km、ml、ft,分別代表?、千?、英?和尺。 127.0.0.1:6379> geodist company juejin ireader km "10.5501" 127.0.0.1:6379> geodist company juejin meituan km "1.3878" 127.0.0.1:6379> geodist company juejin xiaomi km "12.9606"

獲取元素位置

geopos 指令可以獲取集合中任意元素的經(jīng)緯度坐標(biāo),可以?次獲取多個(gè)。 127.0.0.1:6379> geopos company juejin 1) 1) "116.48104995489120483"2) "39.99679348858259686" 127.0.0.1:6379> geopos company juejin ireader 1) 1) "116.48104995489120483"2) "39.99679348858259686" 2) 1) "116.5142020583152771"2) "39.90540918662494363"

獲取元素的 hash 值

geohash 可以獲取元素的經(jīng)緯度編碼字符串,上?已經(jīng)提到,它是base32 編碼。你可以使?這個(gè)編碼值去 http://geohash.org/${hash}中進(jìn)?直接定位,它是 geohash 的標(biāo)準(zhǔn)編碼值。

geohash計(jì)算過程依據(jù)上述原理,接下來詳細(xì)介紹一下geohash的計(jì)算過程,這里拿經(jīng)緯度(116.389550, 39.928167)進(jìn)行算法說明。

a. 緯度計(jì)算
中學(xué)學(xué)過的地理知識(shí)知道,地球分為南緯與北緯,分別都是0~90°,但是在計(jì)算機(jī)中,用文字定義南緯與北緯較為麻煩,所以計(jì)算機(jī)中用區(qū)間定義[-90,0)與[0,90]分為南北緯,同時(shí)叫做左右區(qū)間。區(qū)分了左右區(qū)間,接下來就是整個(gè)計(jì)算過程:

判斷當(dāng)前緯度39.928167是在左區(qū)間還是右區(qū)間,發(fā)現(xiàn)是在右區(qū)間[0,90]中,在右區(qū)間標(biāo)識(shí)為1;接著將區(qū)間[0,90]進(jìn)行左右區(qū)間二分,二分后為 [0,45),[45,90],可以確定39.928167屬于左區(qū)間 [0,45),標(biāo)記為0;不斷重復(fù)上述過程39.928167總是屬于某個(gè)區(qū)間[a,b]。隨著每次迭代區(qū)間[a,b]總在縮小,并越來越逼近39.928167;依據(jù)最大精度,定義一個(gè)最大重復(fù)次數(shù),這里我們定義為15,這樣就能得出一個(gè)01字串;

b. 全局計(jì)算
經(jīng)度計(jì)算與緯度計(jì)算類似,也是依據(jù)區(qū)間劃分,左右判斷來進(jìn)行,這里就不在復(fù)述了,給出最終計(jì)算結(jié)果為:1 1 0 1 0 0 1 0 1 1 0 0 0 1 0,接下來就是如何通過經(jīng)度與緯度的01字串,編碼成相應(yīng)的字母+數(shù)字的組合。將經(jīng)度與緯度的01字串進(jìn)行合并,合并方法為:基數(shù)為放緯度,偶數(shù)位放經(jīng)度

  • 最終字串為:11011, 01110, 00010, 01111, 00001, 00100
  • 將字串轉(zhuǎn)換成十進(jìn)制,得到:27, 14, 2, 15, 1, 4
  • 對(duì)應(yīng)base32編碼表

轉(zhuǎn)載于:https://www.cnblogs.com/hanmengya/p/10967457.html

總結(jié)

以上是生活随笔為你收集整理的GeoHash -------寻找附近人的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。