バックグラウンド
- 周辺情報を入手する;近くの人?近くの会社?近くのレストラン?近くのスターバックス?
- 2つの座標位置間の距離を取得しますか?
成し遂げる
redis、mongo、mysqlを使用して、座標の取得と変換を実行できます。redisの該当するバージョン:> = 3.2.0
GEOアルゴリズム
ウィキ:https://en.wikipedia.org/wiki/Geohash
Redisは、処理に一般的なGeoHashアルゴリズムを使用し、最初に上海の駅座標(121.455708、31.249574)があると想定し、次に二分法(左マーク0、右マーク1)に従います。
- [-90,0)、[0,90]に分割された緯度[-90,90]は、左右の間隔と呼ばれます。31.249574は右の間隔[0,90]に属し、1としてマークされていると判断できます。
- 次に、右の間隔[0,90]を[0,45)、[45,90]の左と右の間隔に分割すると、31.249574が左の間隔[0,90]に属していると判断し、0としてマークできます。
- 類推すると、最終的には特定の座標31.249574に無限に近づく可能性があり、経度は同じです。
- 最後の:緯度のpvが:10101 10001、経度のpvが:11010 11001であり、pvの長さが指定された間隔の分割数に関連しているとします。
- 置く緯度経度と奇数で偶数を、再配置及び最終結果組み合わせ:11011 00110 11010 00011を
- 再配置された結果は、10進数の27、6、2、3に変換され、base32エンコーディングに32文字の0〜9、bz(a、i、l、oを削除)が使用されます。結果は次のとおりです。v6u3 (注:以下の参照コードを参照してください)
- Redisでは、経度と緯度は52ビットの整数を使用してエンコードされ、zsetに格納されます。zsetの値は要素のキーであり、スコアはGeoHashの52ビットの整数値です。zsetのスコアは浮動小数点数ですが、52ビットの整数値に対して無損失で保存できます。
経度pv除算の計算:
pv | 分 | 半ば | 最大 |
1 | -90 | 0 | 90 |
0 | 0 | 45 | 90 |
1 | 0.000 | 22.5 | 45 |
0 | 22.5 | 33.75 | 45 |
1 | 22.5 | 28.125 | 33.75 |
1 | 28.125 | 30.9375 | 33.75 |
0 | 30.9375 | 32.34375 | 33.75 |
0 | 30.9375 | 31.640625 | 32.34375 |
0 | 30.9375 | 31.2890625 | 31.640625 |
1 | 30.9375 | 31.11328125 | 31.2890625 |
緯度PV分割計算:
pv | 分 | 半ば | 最大 |
1 | -180 | 0 | 180 |
1 | 0 | 90 | 180 |
0 | 90 | 135 | 180 |
1 | 90 | 112.5 | 135 |
0 | 112.5 | 123.75 | 135 |
1 | 112.5 | 118.125 | 123.75 |
1 | 118.125 | 120.9375 | 123.75 |
0 | 120.9375 | 122.34375 | 123.75 |
0 | 120.9375 | 121.640625 | 122.34375 |
1 | 120.9375 | 121.2890625 | 121.640625 |
Base32ビットエンコーディングリファレンス:
Redisシェルコマンド
注:時間の複雑さ:追加される各要素の複雑さはO(log(N))です。ここで、Nはキーに含まれる位置要素の数です。
1. GEOADD -----座標コマンドを追加します(最初に経度、次に緯度)
GEOADD key longitude latitude member [longitude latitude member …]
例えば:
192.168.0.102:4>geoadd coordinate 121.455708 31.249574 "上海站" 121.475164 31.228816 "上海人民广场"
"2"
192.168.0.102:4>geoadd coordinate 121.499717 31.239702 "东方明珠塔"
"1"
2. GEOPOS -----クエリ座標情報
GEOPOS key member [member …]
例えば:
192.168.0.102:4>geopos coordinate "东方明珠塔"
1) 1) "121.49971514940261841"
2) "31.23970195235578018"
192.168.0.102:4>geopos coordinate "东方明珠塔" "上海站"
1) 1) "121.49971514940261841"
2) "31.23970195235578018"
2) 1) "121.45570546388626099"
2) "31.24957469127141252"
3. GEODIST -----指定された位置間の距離を照会します
注:指定された単位のパラメーターはunit
、次のいずれかの単位である 必要があります。デフォルトはmです。
-
m
単位はメーター(デフォルト)です。 -
km
単位はキロメートルです。 -
mi
単位はマイルです。 -
ft
単位はフィートです。
GEODIST key member1 member2 [unit]
例えば:
192.168.0.102:4>geodist coordinate "上海站" "东方明珠塔"
"4326.7279"
192.168.0.102:4>geodist coordinate "上海站" "东方明珠塔" km
"4.3267"
4. GEORADIUS -----周囲の情報を照会する
注:指定された経度と緯度を中心として、中心までの距離がキーに含まれるロケーション要素間の指定された最大距離を超えないすべてのロケーション要素を返します。
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]
例えば:
192.168.0.102:4>georadius coordinate 121.458175 31.242564 3 km WITHDIST asc count 5
1) 1) "上海站"
2) "0.8144"
2) 1) "上海人民广场"
2) "2.2245"
192.168.0.102:4>georadius coordinate 121.458175 31.242564 5 km WITHDIST asc count 5
1) 1) "上海站"
2) "0.8144"
2) 1) "上海人民广场"
2) "2.2245"
3) 1) "东方明珠塔"
2) "3.9632"
192.168.0.102:4>
5. GEORADIUS BYMEMBER -----周囲の情報を照会する
注:GEORADIUSと同様に、座標のみが特定の要素に置き換えられます
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]
例えば:
192.168.0.102:4>georadiusbymember coordinate "上海站" 5 km WITHDIST asc count 5
1) 1) "上海站"
2) "0.0000"
2) 1) "上海人民广场"
2) "2.9589"
3) 1) "东方明珠塔"
2) "4.3267"
6. GEOHASH -----クエリハッシュ値
注:通常、開発とデバッグにのみ使用されます
GEOHASH key member [member …]
例えば:
192.168.0.102:4>geohash coordinate "上海站"
1) "wtw3gbc3gn0"
簡単じゃないですか?^ _ ^