如何使用redis实现附近的人功能,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
Redis自3.2版本开始提供了GEO(geograph)功能,支持地理位置相关操作,以实现诸如附近的人这类依赖于地理位置信息的功能。
拾取坐标系统
120.70012 28.00135 温州
120.207686 30.253359 杭州
121.482537 31.238034 上海
118.793117 32.068407 南京
1. geoadd
为了进行地理位置相关操作,我们首先需要将具体的地理位置记录起来,可以通过执行geoadd 命令来完成 命令格式如下
GEOADD 集合名称 经度 纬度 名称 [longitude latitude name...] //添加集合 geoadd citys 120.70012 28.00135 wenzhou 120.207686 30.253359 hanghzou
查看已添加集合
2.geopos
此命令根据输入的位置名称获取位置的信息坐标,语法如下
GEOPOS 集合名称 位置 [name...] geopos address wuyue
查看坐标信息
3.geodist
此命令用于计算两个位置之间的距离,语法如下
geodist 集合名称 位置1 位置2 [unit] //计算杭州到南京之间的距离 geodist citys hanghzredis:0>ou nanjing km
可选参数:unit用于指定计算距离时的单位,他的值可以是以下单位的其中一个
m :表示米
km:表示千米
mi:表示英里
ft:表示英尺。
4.georadius
georadius使用用户给定的经纬度作为计算范围时的中心点,
georadius 集合名称 精度 纬度 radius m|km|ft|mi| [WITHCOORD] [WITHDIST] [ASC|DESC] [COUNT count] //查询据我100km之内的城市 georadius citys 120.754274 27.983296 100 km
radius:距离
WITHCOORD:返回坐标
由于版本原因可能为空
WITHDIST:同时返回距离
ASC|DESC:排序
count:取多少长度
5. georadiusbymember
georadiusbymember使用存储在位置集合里的某个地点作为中心点
georadiusbymember 地址集合 地点名称 距离 单位 //查询距离wuyue五公里之内的地点 georadiusbymember address wuyue 5 km
实体类
package com.jiale.web.controller.pojo; import lombok.Data; import java.io.Serializable; /** * @Author: Hello World * @Date: 2021/9/16 16:12 * @Description: */ @Data public class AddressInfo implements Serializable { /**网点名称*/ private String title; /**网点地址*/ private String address; /**网点联系方式*/ private String phone; /**网点坐标-精度*/ private double x; /**网点坐标-纬度*/ private double y; }
package com.jiale; import com.jiale.common.config.JialeGlobal; import com.jiale.web.controller.pojo.AddressInfo; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.geo.*; import org.springframework.data.redis.connection.RedisGeoCommands; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.RequestMapping; import java.math.BigDecimal; import java.util.List; /** * @Author: Hello World * @Date: 2021/9/15 17:47 * @Description: */ @SpringBootTest public class JialeTests { @Autowired RedisTemplate redisTemplate; @Test public void test1(){ System.out.println(JialeGlobal.getUploadPath()); } /** * 一.向redis中添加位置信息 * 1.网店位置信息-geo * 2.网点详细信息 */ @Test public void geoAdd(){ //1.网点位置信息存储120.653208,28.032606 Point point = new Point(120.653208, 28.032606); redisTemplate.boundGeoOps("outlets").add(point,"江心屿"); //2.网点详细信息 AddressInfo addressInfo = new AddressInfo(); addressInfo.setTitle("江心屿"); addressInfo.setAddress("浙江省温州市鹿城区江心屿景区内"); addressInfo.setPhone("(0577)88201281"); addressInfo.setX(120.653208); addressInfo.setY(28.032606); redisTemplate.boundHashOps("outletsInfo").put("江心屿",addressInfo); } /** * 二.获取位置坐标信息 */ @Test public void geoPos(){ //传入位置名称查询位置信息 List<Point> position = redisTemplate.boundGeoOps("outlets").position("南塘五组团"); for (Point point : position) { System.out.println(point); } } /** * 三.计算两个位置信息 */ @Test public void geoDist(){ /** Distance distance = redisTemplate.boundGeoOps("outlets").distance("江心屿", "温州乐园"); //距离 double value = distance.getValue(); //单位 String unit = distance.getUnit(); System.out.println("两点相距:"+value+unit); */ //以km展示 /** Distance distance = redisTemplate.boundGeoOps("outlets").distance("江心屿", "温州乐园", Metrics.KILOMETERS); //距离 double value = distance.getValue(); //单位 String unit = distance.getUnit(); System.out.println("两点相距:"+value+unit);*/ //保留两位小数 Distance distance = redisTemplate.boundGeoOps("outlets").distance("江心屿", "温州乐园", Metrics.KILOMETERS); //距离 double value = distance.getValue(); //单位 String unit = distance.getUnit(); System.out.println("两点相距:"+new BigDecimal(value).setScale(2,BigDecimal.ROUND_HALF_UP) +unit); } /** * 四.按照给定的经纬度查找指定范围的位置 */ @Test public void geoRadius(){ //指定位置 Point point = new Point(120.754274, 27.983296); //构建条件-10km Distance distance = new Distance(10, Metrics.KILOMETERS); Circle circle = new Circle(point,distance); //RedisGeoCommands RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs(); //包含位置信息 args.includeDistance(); //存放的是查询到的网址位置信息 GeoResults<RedisGeoCommands.GeoLocation<String>> outlets = redisTemplate.boundGeoOps("outlets").radius(circle, args); for (GeoResult<RedisGeoCommands.GeoLocation<String>> outlet : outlets) { //获取距离信息 Distance outletDistance = outlet.getDistance(); //距离 double value = outletDistance.getValue(); //单位 String unit = outletDistance.getUnit(); System.out.println("当前坐标距离:"+outlet.getContent().getName()+value+unit); } } /** * 五.按照指定元素(必须在集合中存在)查找指定范围位置 */ @Test public void geoRadiusByMember(){ //构建条件 Distance distance = new Distance(10, Metrics.KILOMETERS); //构建条件-包含位置信息 RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs(); args.includeDistance(); //参数 key 构建的条件 其他条件 GeoResults<RedisGeoCommands.GeoLocation<String>> outlets = redisTemplate.boundGeoOps("outlets").radius("江心屿", distance,args); for (GeoResult<RedisGeoCommands.GeoLocation<String>> outlet : outlets) { //获取距离信息 Distance outletDistance = outlet.getDistance(); //距离 double value = outletDistance.getValue(); //单位 String unit = outletDistance.getUnit(); System.out.println("江心屿距离:"+outlet.getContent().getName()+value+unit); } } }
关于如何使用redis实现附近的人功能问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。