文章目录
Redis学习笔记-GEO经纬度编码原理&地理划分
在日常生活中,我们经常使用手机搜索附近的餐馆,或者在打车软件上打车,都需要获取用户和服务商之间位置信息,而 Redis
提供了一种可以查询地理位置信息的数据结构 GEO
,其底层实现原理和 有序集合(Sorted Set)
的原理一样,我们知道有序集合数据特点就是每个值有对应的权重(score)
,这篇文章学习一下 GEO
如何对经纬度编码,然后通过这种编码实现 有序集合(Sorted Set)
中就有了权重(score)
了,这样就能快速找到相邻经纬度信息的数据了。
1.笔记图
2.GEO 应用场景
- 搜索附近的餐馆
- 在打车软件上叫车
3.GEO 数据特点举例
- 网约车都有编号(如
33
),网约车要将自己的经纬度信息(如116.034579 39.000452
)发给叫车应用 - 用户叫车的时候,叫车应用会根据用户的位置(如
116.054579,39.030452
)查找附近车辆 key
(例如车ID
)对应一个value
(一组经纬度)
4.GeoHash 的编码方法(二分区间,区间编码)
- 对经度值的范围做多次分区,当做完
N
次二分区后,经度值就可以用N bit
的数来表示了 - 第一次二分区:经度范围
[-180,180]
会被分成两个子区间:[-180,0)
和[0,180](左、右分区)
,要查询的经度落在左分区就用0``表示,否则用
1表示,如经度
115第一次二分区编码
1` - 第二次分区:如经度
115
第一次落在[0,180]
区间,第二次二分区就把[0,180]
分成[0,90)
和[90,180]
,115
落在[90,180]
,第二次分区的编码1
- 第三次二分区:如经度
115
第二次落在[90,180]
区间,第三次二分区就把[90,180]
分成[90,135)
和[135,180]
,115
落在[90,135)
,第三次分区的编码0
- 第四次二分区:如经度
115
第三次落在[90,135)
区间,第四次二分区就把[90,135)
分成[90,112.5)
和[112.5,135]
,115
落在[112.5,135]
,第四次分区的编码1
- 第五次二分区:如经度
115
第四次落在[112.5,135]
区间,第五次二分区就把[112.5,135]
分成[112.5,123.75)
和[123.75,135]
,115
落在[112.5,123.75)
,第五次分区的编码0
- 五次编码综合:
11010
Tips:维度的编码和经度类似,维度范围是
[-90,90]
。
5.GEO 经纬度编码组合
- 组合规则:最终编码值的偶数位上依次是经度的编码值,奇数位上依次是纬度的编码值,偶数从第
0
位开始,奇数从第1
位开始 - 作用:原来无法用一个权重分数表示的一组经纬度
(116.37,39.86)
就可以用1110011101
这一个值来表示,就可以保存为Sorted Set
的权重分数了,这样在查找附近的数据时就很方便了。
6.地理位置划分举例
-
使用
GeoHash
编码后,相当于把整个地球地理空间划分成了一个个方格,每个方格对应了GeoHash
中的一个分区,举例: -
把经度区间
[-180,180]
做一次二分区,把纬度区间[-90,90]
做一次二分区,就会得到4
个分区
- 分区一:
[-180,0)
和[-90,0)
,编码00
- 分区一:
[-180,0)
和[-90,0)
,编码00
- 分区二:
[-180,0)
和[0,90]
,编码01
- 分区三:
[0,180]
和[-90,0)
,编码10
- 分区四:
[0,180]
和[0,90]
,编码11
- 分区一:
-
作用:使用
Sorted Set
范围查询得到的相近编码值,在实际的地理空间上,也是相邻的方格,这就可以实现搜索附近的人或物
的功能了 -
特殊情况处理:
-
有的编码值虽然在大小上接近,但实际对应的方格却距离比较远
-
为了避免查询不准确问题,我们可以同时查询给定经纬度所在的方格周围的
4
个或8
个方格
-
7.GEO 相关命令
- GEOADD 命令:
- 用于把一组经纬度信息和相对应的一个
ID
记录到GEO
类型集合中 - 假设车辆
ID
是33
,经纬度位置是(116.034579,39.030452)
,我们可以用一个GEO
集合保存所有车辆的经纬度,集合key
是cars:locations
GEOADD cars:locations 116.034579 39.030452 33
- GEORADIUS 命令:
- 用户想要寻找自己附近的网约车时,
LBS
应用就可以使用GEORADIUS
命令 - 查找以这个经纬度为中心的
5
公里内的车辆信息,并返回给LBS
应用
GEORADIUS cars:locations 116.054579 39.030452 5 km ASC COUNT 10
扫码关注