12.Geospatial
12.1 简介
基于位置信息服务(Location-Based Service,LBS)的应用。Redis3.2版本后增加了对GEO类型的支持。主要来维护元素的经纬度。redis基于这种类型,提供了经纬度设置、查询、范围查询、距离查询、经纬度hash等一些相关操作
12.2 GEO底层结构
- 约车系统,针对每一辆车,有一个唯一编号,车辆有行驶的经纬度
- 呼叫车辆,会暴露用户的经纬度,根据经纬度进行范围查找,进行匹配
- 把附近车辆找到后,车辆信息获取,将信息反馈给用户
第一种方式,可以使用hash来存储,但hash没有排序功能
第二种方式,geo底层结束 zset 来实现。需要将经纬度放在一起,生成一个权重的分数,按这个分数进行排序
GEOHash编码:
编码的过程:
- 经度-180,180之间,按给定位数做N次二分区操作。
-
例如,N=5,做5次二分区操作,例如,坐标116.40
-
对经度进行编码 116.40
次数 最小 中间 最大 区间 编码 1 -180 0 180 [0,180] 1 2 0 90 180 [90,180] 1 3 90 135 180 [90,135] 0 4 90 112.5 135 [112.5,135] 1 5 112.5 123.75 135 [112.5,123.75] 0 11010
-
对纬度进行编码 39.96
次数 最小 中间 最大 区间 编码 1 -90 0 90 [0,90] 1 2 0 45 90 [0,45] 0 3 0 22.5 45 [22.5,45] 1 4 22.5 33.75 45 [33.75,45] 1 5 33.75 39.75 45 [39.375,45] 1 10111
-
经度:11010
纬度:10111
最后合成的编码:1110011101
12.3 GEO操作指令
geoadd < key> < longitude>< latitude>< member> [longitude latitude member…]:添加地理位置
(key 经度 纬度 位置名称)
geopos < key>< member>[member…]:获取指定的位置坐标值
geodist < key>< member1>< member2>:获取两个位置之间的直线距离。单位:m 米 km 千米 ft英尺 mi英里
georadius < key>< longitude> < latitue> radius [m | km| fm| mi],以经定的经纬度做为中心,找出
给定半径内的位置
12.4 查找附近的人案例
geoadd nearby 116.511023 39.945711 person1 116.508257 39.946735 person2 116.513395
39.948035 person3 116.51415 39.945131 person4 116.508724 39.943194 person5 116.511526
39.943775 person6 116.509802 39.94419 person7 116.512317 39.946928 person8 116.505166
39.946265 person9 116.506316 39.946375 person10
georadius nearby 116.506316 39.946375 500 m desc count 10 倒序附近500米的前10个