Redis GEO地理位置信息的应用
Redis GEO地理位置信息的应用
- Redis GEO
- 概述
- 应用场景
- Redis GEO命令
- GEO命令演示
- Redis GEO实现附近人的功能
- 基础类
- API接口
- 接口实现
- 执行测试
Redis GEO
概述
Redis的GEO操作是一种基于地理位置信息进行操作的功能。它使用经度和纬度坐标来表示地理位置,支持存储地理位置信息用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能。
应用场景
地理围栏:通过设置地理位置的经纬度信息,可以将用户或者车辆等实体绑定在地理围栏内,当实体进出围栏时,可以触发相应的事件。附近的人:在类似于约会、社交、旅游等场景下,可以通过Redis GEO快速查询周围的人员或景点。配送服务:通过获取配送地址的经纬度信息,可以找到距离最近的配送员或仓库,并对订单进行分配。地址查找:在地图应用中,可以通过Redis GEO快速查询某个地址周围的商家或服务设施。动态信息:在滴滴、Uber等打车应用中,可以实时更新车辆的位置信息,以提供更加准确的车辆推荐和路线规划服务
Redis GEO命令
1.GEOADD添加位置信息
将一个或多个指定的地理位置(经度、纬度、名称)添加到指定的键中。
GEOADD key longitude latitude member [longitude latitude member ...]
添加一个名为cities的键,并将北京、上海、广州三个城市的经纬度和名称添加到该键中
GEOADD cities 116.4074 39.9042 Beijing 121.4737 31.2304 Shanghai 113.2644 23.1291 Guangzhou
GEOADD命令对于经纬度是有要求的:
有效的经度从-180度到180度有效的纬度从-85.05112878度到85.05112878度
2.GEODIST查询距离
返回两个位置之间的距离。可以选择以米或千米为单位。
GEODIST key member1 member2 [unit]
可选参数unit用于指定计算距离时的单位:
m 表示单位为米km 表示单位为千米mi 表示单位为英里ft 表示单位为英尺
查询北京和上海之间的距离,单位为千米
GEODIST cities Beijing Shanghai km
3.GEOHASH获取指定位置的Geohash值
返回一个或多个位置的Geohash值,该值用于对地理位置进行更快速的范围查找。
GEOHASH key member [member ...]
获取北京的Geohash值
GEOHASH cities Beijing
4.GEOPOS查询地理位置坐标
返回一个或多个位置的经度和纬度。
GEOPOS key member [member ...]
查询广州的经纬度
GEOPOS cities Guangzhou
5.GEORADIUS查找指定范围内的元素
查询给定坐标范围内的所有元素。可以通过设置排序选项来获取按距离排序的结果。
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [ASC|DESC] [COUNT count]
查找距离北京1000公里以内的城市,并按距离升序排列
GEORADIUS cities 116.4074 39.9042 1000 km ASC
6.GEORADIUSBYMEMBER查询给定成员周围的所有元素
查询给定成员周围的所有元素。可以通过设置排序选项来获取按距离排序的结果。
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [ASC|DESC] [COUNT count]
查找距离上海最近的城市,并返回它们的名称和距离
GEORADIUSBYMEMBER cities Shanghai 100 km WITHDIST
7.ZREM删除成员
从指定键中删除一个或多个成员。
ZREM key member [member ...]
从cities键中删除广州
ZREM cities Guangzhou
GEO命令演示
# 添加位置信息
本机:0>geoadd user:location 121.48941 31.40527 'shagnhai'
"1"
# 添加多个位置信息
本机:0>geoadd user:location 121.47941 31.41527 'shanghai1' 121.47941 31.43527 'shagnhai2' 121.47941 31.40527 'shagnhai3'
"3"# 计算距离,单位有m km ft(英尺) mi(英里)
# 计算两点间的距离,单位m
本机:0>geodist user:location shanghai shanghai1 m
"1462.1834"
# 千米:km
本机:0>geodist user:location shanghai shanghai1 km
"1.4622"# geohash 返回一个或多个位置元素的geohash,保存Redis中是用geohash位置52点整数编码
# geohash 将二维经纬度转换成字符串,每个字符串代表一个矩形区域,该矩形区域内的经纬度点都共享一个相同的geohash字符串。
本机:0>geohash user:location shanghai shanghai1
1) "wtw6st1uuq0"
2) "wtw6sqfx5q0"# geopos 从key里返回指定成员的位置信息
本机:0>geopos user:location shanghai shanghai1
1) 1) "121.48941010236740112"2) "31.40526993848380499"2) 1) "121.47941082715988159"2) "31.41526941345740198"# georadius:给定经纬度为中心,返回键包含的位置元素中,与中心的距离不超过给定最大距离的所有位置元素
# 范围单位:m km mi ft
# withcoord:将位置元素的经纬度一并返回
本机:0>georadius user:location 121.48941 31.40527 3000 m withcoord
1) 1) "shagnhai3"2) 1) "121.47941082715988159"2) "31.40526993848380499"2) 1) "shanghai1"2) 1) "121.47941082715988159"2) "31.41526941345740198"3) 1) "shanghai"2) 1) "121.48941010236740112"2) "31.40526993848380499"# withdist:返回位置元素的同时,将位置元素与中心点间的距离一并返回
本机:0>georadius user:location 121.48941 31.40527 3000 m withdist
1) 1) "shagnhai3"2) "949.2411"2) 1) "shanghai1"2) "1462.1719"3) 1) "shanghai"2) "0.0119"# asc:根据中心位置,按照从近到远的方式返回位置元素
本机:0>georadius user:location 121.48941 31.40527 3000 m withdist asc
1) 1) "shanghai"2) "0.0119"2) 1) "shagnhai3"2) "949.2411"3) 1) "shanghai1"2) "1462.1719"# desc: 根据中心位置,按照从远到近的方式返回位置元素
本机:0>georadius user:location 121.48941 31.40527 3000 m withdist desc
1) 1) "shanghai1"2) "1462.1719"2) 1) "shagnhai3"2) "949.2411"3) 1) "shanghai"2) "0.0119"# count:获取指定数量的元素
本机:0>georadius user:location 121.48941 31.40527 3000 m withdist desc count 2
1) 1) "shanghai1"2) "1462.1719"2) 1) "shagnhai3"2) "949.2411"# georadiusbymember:和georadius命令类似,都可以找出指定位置范围内的元素,但是georadiusbymember的中心点是由给定位置元素决定的,而不像georadius使用经纬度决定中心点
本机:0>georadiusbymember user:location shanghai 3 km
1) "shagnhai3"
2) "shanghai1"
3) "shanghai"
Redis GEO实现附近人的功能
基础类
创建NearMeUserVO
视图对象,封装响应视图的基本数据信息
@Data
public class NearMeUserVO {public Integer id;/*** 距离*/public String distance;
}
创建User
对象模拟操作用户
@Datapublic class User {private int id;}
API接口
创建添加、更新用户位置信息
与查询附近用户信息
的2个API接口
@RestController
public class NearMeUserController {@Autowiredprivate INearMeUserService nearMeUserService;/*** 添加、更新坐标** @param lon* @param lat* @return*/@PostMapping("/updateUserLocation")public String updateUserLocation(@RequestParam Float lon, @RequestParam Float lat) {nearMeUserService.updateUserLocation(lon, lat);return "OK";}/*** 获取附近的人* 查询距离指定经纬度一定范围内的用户,并返回结果列表** @param radius* @param lon* @param lat* @return*/@GetMapping("/getNearMe")public Object nearMe(Integer radius, Float lon, Float lat) {List<NearMeUserVO> nearMe = nearMeUserService.findNearMe(radius, lon, lat);return nearMe;}
}
接口实现
public interface INearMeUserService {/*** 更新坐标** @param lon 经度* @param lat 纬度*/void updateUserLocation(Float lon, Float lat);/*** 获取附近的人** @param radius 半径,默认 1000m* @param lon 经度* @param lat 纬度* @return*/List<NearMeUserVO> findNearMe(Integer radius, Float lon, Float lat);
}
@Service
public class NearMeUserServiceImpl implements INearMeUserService {@Autowiredprivate RedisTemplate<Object, Object> redisTemplate;/*** 用户定位信息cKEY*/private static final String USER_LOCATION_KEY = "user:location";public void updateUserLocation(Float lon, Float lat) {if (lon == null || lat == null) {throw new RuntimeException("获取经度、维度失败");}// 获取登录用户信息User user = this.getLoginUser();// 定义keyString key = "user:location";// 将用户地理位置信息存入 RedisRedisGeoCommands.GeoLocation geoLocation = new RedisGeoCommands.GeoLocation(user.getId(), new Point(lon, lat));redisTemplate.opsForGeo().add(key, geoLocation);}/*** 获取附近的人** @param radius 半径,默认 1000m* @param lon 经度* @param lat 纬度* @return*/public List<NearMeUserVO> findNearMe(Integer radius, Float lon, Float lat) {// 获取登录用户信息User user = this.getLoginUser();int userId = user.getId();// 处理半径,默认 1000mif (radius == null) {radius = 1000;}// 获取用户经纬度Point point = null;if (lon == null || lat == null) {// 如果经纬度没传,那么从 Redis 中获取List<Point> points = redisTemplate.opsForGeo().position(USER_LOCATION_KEY, userId);if (points == null || points.isEmpty()) {throw new RuntimeException("获取经纬度失败");}point = points.get(0);} else {point = new Point(lon, lat);}// 初始化距离对象,单位 mDistance distance = new Distance(radius, RedisGeoCommands.DistanceUnit.METERS);// 初始化 Geo 命令参数对象RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();// 附近的人限制3,包含距离,按由近到远排序args.limit(3).includeDistance().sortAscending();// 以用户经纬度为圆心,范围 1000mCircle circle = new Circle(point, distance);// 获取附近的人 GeoLocation 信息GeoResults<RedisGeoCommands.GeoLocation<Object>> geoResult = redisTemplate.opsForGeo().radius(USER_LOCATION_KEY, circle, args);// 构建有序 MapMap<Integer, NearMeUserVO> nearMeUserVOMap = Maps.newLinkedHashMap();// 完善用户信息geoResult.forEach(result -> {RedisGeoCommands.GeoLocation<Object> geoLocation = result.getContent();// 初始化Vo对象NearMeUserVO nearMeUserVO = new NearMeUserVO();nearMeUserVO.setId((Integer) geoLocation.getName());// 获取距离Double dist = result.getDistance().getValue();// 四舍五入精确到小数点后 1 位,方便客户端显示String distanceStr = NumberUtil.round(dist, 1).toString() + "m";nearMeUserVO.setDistance(distanceStr);nearMeUserVOMap.put((Integer) geoLocation.getName(), nearMeUserVO);});// 附近的人,可进一步完善用户信息
// Integer[] userIds = nearMeUserVOMap.keySet().toArray(new Integer[0]);ArrayList<NearMeUserVO> nearMeUserVO = Lists.newArrayList(nearMeUserVOMap.values());return nearMeUserVO;}/*** 模拟获取真实登录用户信息** @return*/public User getLoginUser() {User user = new User();user.setId(1);return user;}
}
执行测试
访问执行添加用户地理位置数据
接口,得到如下所示数据:
访问执行获取附近人
接口,得到如下所示数据:
"data": [{"id": 1,"distance": "0.0m"},{"id": 3,"distance": "949.3m"},{"id": 2,"distance": "1462.2m"}]
Redis GEO地理位置信息的应用相关推荐
- redis:地理位置信息geo
简介 redis3.2版本提供了GEO(地理信息定位)功能,支持存储地理位置信息. 可以用来实现比如附近位置,摇一摇这类依附于地理位置的功能 GEO功能是 Redis 的另一位作者Matt Stanc ...
- java redis geo_redis学习计划(九)redis GEO地理位置
redis目前已经到了3.2版本,3.2版本里面新增的一个功能就是对GEO(地理位置)的支持. 地理位置大概提供了6个命令,分别为: GEOADD GEODIST GEOHASH GEOPOS GEO ...
- 基于Redis GEO(地理位置) 实现附近的人,商家等相关功能实现 使用SpringBoot Redis工具类
Redis GEO 1.基本介绍 1.Redis GEO 2.基础语法 GEOADD GEOPOS GEODIST GEORADIUS GEOHASH 2.可用于实现的功能 3.SpringBoot实 ...
- [LBS学习笔记3]redis geo地理位置查询分析
1.redis geo命令 1.1 redis6.2版本geo命令简介 redis自3.2版本开始,提供了地理位置相关的命令: GEOADD:添加空间元素 GEOPOS: 获取某个地理位置的坐标 GE ...
- redis 附近的人_Redis GEO地理位置信息,查看附近的人
在之前的一篇文章<SpringBoot入门教程(五)Java基于MySQL实现附近的人>,我们介绍了Java基于MySQL实现查找附近的人的功能.今天就来研究研究"查找附近的人& ...
- Redis之GEO存储地理位置信息
在外卖软件中的附近的美食店铺.外卖小哥的距离,打车软件附近的车辆,交友软件中附近的小姐姐.我们都可以利用redis的GEO地理位置计算得出. 1.Redis 的 Geo 是在 3.2 版本才有的 2. ...
- redis学习--三种特殊数据类型,GEO地理位置,HyperLogLog,BitMap
三种特殊数据类型,GEO地理位置,HyperLogLog,BitMap GEO地理位置 简介 Redis 的 GEO 特性在 Redis 3.2 版本中推出, 这个功能可以将用户给定的地理位置信息储存 ...
- redis 的geo地理位置及实现附近的人的功能
前言 redis在3.2版本里面新增的一个功能就是对GEO(地理位置)的支持. 理位置大概提供了6个命令,分别为: GEOADD GEODIST GEOHASH GEOPOS GEORADIUS GE ...
- Geo Location 地理位置信息小结
周末调研了一下Geo Location 地理位置信息方面的内容,自己小结一下. 一.通过 IP 地址获得用户的地理位置信息 也就是根据用户的IP,通过IP数据库查询获得信息.一般IP数据库中, 每条记 ...
最新文章
- 鲍尔默说:你的东西再大 微软也装得下
- tomcat压力测试、优化
- html5 将id的值用于top_web前端分享HTML5常见面试题集锦四
- 15 | 二分查找(上):如何用最省内存的方式实现快速查找功能?
- 原linux的字符文件作用,linux特殊字符及其作用大全
- java三年技术差_3年经验Java程序员面阿里P6 差距在哪里
- PYPL 1 月 IDE 榜单:Visual Studio Code 猛追 IntelliJ
- centos 6.2安装mysql_centos6.2安装mysql
- [转载] python-TypeError: Object of type ‘Decimal‘ is not JSON serializable 报错
- SIR模型的应用(2) - Influence maximization in social networks based on TOPSIS(3)
- 应该根据哪些判断云服务器的好坏
- Playing games
- 量子信息-学习记录13
- 从iPhone6S发售谈富士康电商富连网
- VC++获取系统当前时间并显示
- 在深度OS中编译MRtrix步骤
- 红牛的广告:你的能量超乎你的想象
- certbot为NGINX配置SSL证书
- 封禁135、137、139、445端口
- Ruby 日期和时间(和 Python3 日期和时间对比)