Geospatial 地理位置

HeJin大约 3 分钟数据库技术Redis

朋友的定位、附近的人、打车距离计算。

Redis的Geo在Redis3.2版本就推出了。这个功能可以推算地理位置的信息,两地之间的距离,方圆几里的人。

城市经纬度查询:https://jingweidu.51240.com/open in new window

只有6个命令。

geoadd

http://www.redis.cn/commands/geoadd.htmlopen in new window

  • 有效的经度从-180度到180度。
  • 有效的纬度从-85.05112878度到85.05112878度。
# geoadd 添加城市数据
# 规则:地球两极无法直接添加。一般会下载城市数据,直接通过Java程序一次性导入
# 参数:key 值(精度 维度 城市名称)
127.0.0.1:6379> geoadd china:city 106.82922 27.53625 zunyi
(integer) 1
127.0.0.1:6379> geoadd china:city 116.23128 40.22077 beijin
(integer) 1
127.0.0.1:6379> geoadd china:city 106.54041 29.40268 chongqing 113.88308 22.55329 shenzhen
(integer) 2
127.0.0.1:6379> geoadd china:city 120.21201 30.2084 hangzhou
(integer) 1
127.0.0.1:6379> geoadd china:city 108.93425 34.23053 xian
(integer) 1

geopos

获得当前定位:一定是一个坐标值。

127.0.0.1:6379> geopos china:city zunyi			# 获取指定城市的精度和维度
1) 1) "106.82921737432479858"
   2) "27.53624874837839087"
127.0.0.1:6379> geopos china:city beijin zunyi chongqing	# 获取多个城市的精度和维度
1) 1) "116.23128265142440796"
   2) "40.22076905438526495"
2) 1) "106.82921737432479858"
   2) "27.53624874837839087"
3) 1) "106.54040783643722534"
   2) "29.402680

geodist

指定单位的参数 unit 必须是以下单位的其中一个:

  • m 表示单位为米
  • km 表示单位为千米
  • mi 表示单位为英里
  • ft 表示单位为英尺。
127.0.0.1:6379> geodist china:city zunyi chongqing 			# 遵义到重庆的直线距离。默认单位m
"209507.7798"
127.0.0.1:6379> geodist china:city zunyi chongqing m
"209507.7798"
127.0.0.1:6379> geodist china:city zunyi chongqing km		# 遵义到重庆的直线距离。单位km
"209.5078"
127.0.0.1:6379> geodist china:Lcity beijin chongqing km
(nil)
127.0.0.1:6379> geodist china:city beijin chongqing km
"1491.5364"

georadius 以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。

附近的人?(获得所有附近的人的地址,定位)。通过半径来查询。所有的数据应该都录入china:city,才会让结果更加清晰。

127.0.0.1:6379> georadius china:city 110 30 1000 km	# 获取以(110,30)经纬度为中心,寻找方圆1000km内的城市
1) "zunyi"
2) "chongqing"
3) "xian"
4) "shenzhen"
5) "hangzhou"
127.0.0.1:6379> georadius china:city 110 30 500 km # 获取以(110,30)经纬度为中心,寻找方圆500km内的城市
1) "zunyi"
2) "chongqing"
3) "xian"
127.0.0.1:6379> georadius china:city 110 30 500 km withcoord	# 显示他人的定位信息
1) 1) "zunyi"
   2) 1) "106.82921737432479858"
      2) "27.53624874837839087"
2) 1) "chongqing"
   2) 1) "106.54040783643722534"
      2) "29.40268053517299762"
3) 1) "xian"
   2) 1) "108.93425256013870239"
      2) "34.23053097599082406"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist		# 显示到中心位置的直线距离
1) 1) "zunyi"
   2) "413.0760"
2) 1) "chongqing"
   2) "340.7667"
3) 1) "xian"
   2) "481.1278"
127.0.0.1:6379> georadius china:city 110 30 500 km withhash		# 显示hash
1) 1) "zunyi"
   2) (integer) 4025019788724370
2) 1) "chongqing"
   2) (integer) 4026046519194590
3) 1) "xian"
   2) (integer) 4040115270369361
127.0.0.1:6379> georadius china:city 110 30 500 km withdist count 1		# 筛选出指定的结果
1) 1) "chongqing"
   2) "340.7667"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist count 2
1) 1) "chongqing"
   2) "340.7667"
2) 1) "zunyi"
   2) "413.0760"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist count 3
1) 1) "chongqing"
   2) "340.7667"
2) 1) "zunyi"
   2) "413.0760"
3) 1) "xian"
   2) "481.1278"

georadiusbymember 指定成员的位置被用作查询的中心。

# 找出位于指定元素周围的其他元素
127.0.0.1:6379> georadiusbymember china:city zunyi 1000 km		
1) "zunyi"
2) "chongqing"
3) "xian"
4) "shenzhen"
127.0.0.1:6379> georadiusbymember china:city zunyi 400 km
1) "zunyi"
2) "chongqing"
127.0.0.1:6379> georadiusbymember china:city chongqing 400 km
1) "zunyi"
2) "chongqing"

geohash 返回一个或多个位置元素的 Geohash 表示。

该命令将返回11个字符的Geohash字符串。

# 将二维的经纬度转化为一维的字符串。如果两个字符串越接近,那么则距离越近。
127.0.0.1:6379> geohash china:city beijin chongqing
1) "wx4sucvncn0"
2) "wm5z22s7520"

Geo底层的我实现原理其实就是Zset。我们可以使用Zset命令来操作Geo。

127.0.0.1:6379> zrange china:city 0 -1		# 查看地图中全部元素
1) "zunyi"
2) "chongqing"
3) "xian"
4) "shenzhen"
5) "hangzhou"
6) "beijin"
127.0.0.1:6379> zrem china:city beijin		# 移除地图中指定的元素
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "zunyi"
2) "chongqing"
3) "xian"
4) "shenzhen"
5) "hangzhou"