持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情
背景
项目中经常会遇到如下需求
- 1.查询5公里内最近的门店列表,并按照距离的长度排序。
- 2.骑手与顾客直接的距离
- 3.推算地理位置信息等。
针对这些需求,我们将如何实现了?
简介
Redis在3.2版本中加入了地理空间(geospatial)以及索引半径查询的功能,主要用在需要地理位置的应用上。将指定的地理空间位置(经度、纬度、名称)添加到指定的key中,这些数据将会存储到 sorted set,目的是为了方便使用GEORADIUS或者GEORADIUSBYMEMBER命令对数据进行半径查询等操作.
数据结构
Geospatial的底层数据结构是基于zset来实现的,关于zset的数据结构已经在juejin.cn/post/711208… 章节讲解了,本文就不在重复讲解。
GeoHash
简介
geohash用来编码经纬度信息的一种编码方式。
实现原理
1.将经度和维度转换成二进制
北京的经度为:116.404844,将经度转换为二进制
11010010110001101101
同理北京维度为:39.912279,将维度转换为二进制
10111000110000111001
2.将经度和维度的二进制进行合并处理
需要将上述二进制交错合并成一个即可,经度占偶数位,纬度占奇数位,得到最终的二进制:
1110011101001000111100000010110111100011
3.将合并后的二进制做base32编码,最终得到wx4g0cg3vknd
通过geohash处理后成功的将一个二维信息转换成了一维信息,节省存储空间,便于前缀检索。
基础命令
geoAdd 添加一个或多个地理位置元素到key中
基本语法
geoAdd key lng lat member lng1 lat1 member1
示例
说明:分别添加三个门店的经度和维度,门店编号为FJ5003、FJ5022、FJ5002
GeoDist 返回一个key中指定两个位置之间的距离
基本语法
GeoDist key member1 member2
示例
说明:计算两个门店之间的距离,单位为km。
GeoHash 返回一个或多个位置元素的Geohash
基本语法
GeoHash key member member1
示例
说明:
Geopos 返回一个或多个位置的经纬度信息
基本语法
Geopos key member1 member2
示例
说明:获取门店经度和维度。
GeoRadius 以给定位置为中心,半径不超过给定半径的附近所有位置
基本语法
georadius key lopngitude latitude radius unit [WITHCOORD] [WITHDIST] [COUNT count] [ASC|DESC]
说明:
- WITHCOORD:可以返回经纬度
- WITHDIST:可以显示中心距离
- COUNT: 返回指定数量结果
- ASC: 可以根据举例进行排序
示例
说明:距离为10公里了范围的2个门店按照升序排列。
Georadiusbymember 以某个位置作为中心,半径不超过给定半径的附近所有位置
基本语法
georadiusbymember key member radius unit [WITHCOORD] [WITHDIST] [COUNT count] [ASC|DESC]
说明:与georadius的语法基本一致,唯一区别在于Georadiusbymember是以名称为中心,而GeoRadius是以经度和维度为中心。
示例
应用场景
- 1.地址位置信息
- 2.两地之间的距离
- 3.周围N公里的人或者物
总结
本文讲解了Redis的数据结构之Geospatial,有关地理位置相关计算的场景,我们可以采用Redis的Geospatial数据结构来存储和进行相关操作,如有疑问请随时反馈。