springboot 实现附近好友

redis版本需要大于3.2 此代码测试于windows(5.0.14) centos(6.2.1)

用到的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

redisUtil类

@Component
@RequiredArgsConstructor
public class RedisUtil {
    private final StringRedisTemplate redisTemplate;
    /**
     * 向指定key中添加经纬度信息
     * @param key 存储的键值
     * @param longitude  经度
     * @param latitude 纬度
     * @param member 成员名称(数据的标识 比如userID)
     * @return 添加成功的条数
     */
    public long geoAdd(String key,Double longitude,Double latitude,String member){
       return redisTemplate.opsForGeo().add(key,new Point(longitude,latitude),member);
    }

    /**
     * 向指定key中添加经纬度信息
     * @param key
     * @param locations
     * @return
     */
    public long geoAddList(String key, List<RedisGeoCommands.GeoLocation<String>> locations){
        return redisTemplate.opsForGeo().add(key,locations);
    }

    /**
     * 获取成员之间的距离
     * @param key 存储的键值
     * @param member1 成员名称
     * @param member2 成员名称
     * @return
     */
    public Distance geoDist(String key, String member1, String member2){
        return redisTemplate.opsForGeo().distance(key,member1,member2);
    }

    /**
     * 获取指定key值的所有成员列表
     * @param key
     * @return
     */
    public List<String> geoHash(String key){
        return redisTemplate.opsForGeo().hash(key);
    }

    /**
     * 获取指定成员的位置信息
     * @param key 存储的键值
     * @param member 成员名称
     * @return
     */
    public Point geoPos(String key, String member){
        return (redisTemplate.opsForGeo().position(key,member)).get(0);
    }

    /**
     * 获取指定成员 范围内的位置信息
     * @param key 存储的键值
     * @param member 成员名称
     * @param distance 距离
     * @return
     */
    public GeoResults<RedisGeoCommands.GeoLocation<String>> geoRadius(String key, String member, double distance){
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending();
       return  redisTemplate.opsForGeo().radius(key,member,new Distance(distance,Metrics.KILOMETERS),args);
    }
}

使用测试类TestController

@RestController
@RequestMapping("test")
@RequiredArgsConstructor
public class TestController {

    private final RedisUtil redisUtil;

    @PostMapping("a_geo")
    public Result addGeo(String ln, String lat) {
        List<RedisGeoCommands.GeoLocation<String>> list = new ArrayList<>();
        double [] points = {104.75558360809327,30.683943274847753,
                103.87427409881593,30.867270286581444,
                103.89573177093507,30.872279951526178,
                103.9498051046753,30.86005001477394,
                104.01743968719484,30.847523763824523,
                104.06584819549562,30.828510210939427,
                104.10155376190187,30.798582032501155,
                104.12678798431398,30.77793647809215,
                104.16506847137452,30.760236761209416,
                104.33896144622804,30.75227082663582};
        for (int i = 0; i < 20; i += 2) {
            RedisGeoCommands.GeoLocation location = new RedisGeoCommands.GeoLocation("name_"+i/2,new Point(points[i],points[i+1]));
            list.add(location);
        }
        long count = redisUtil.geoAddList(RKey.USER_ONLINE_LOCATION,list);
        return ResultUtil.successResult(count);
    }

    @GetMapping("q_geo")
    public Result getGeo(String member, double distance) {
        GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisUtil.geoRadius(RKey.USER_ONLINE_LOCATION, member, distance);
        return ResultUtil.successResult(geoResults);
    }

    @GetMapping("geo_dist")
    public Result distMember(String member1,String member2){
        Distance distance = redisUtil.geoDist(RKey.USER_ONLINE_LOCATION, member1, member2);
        return ResultUtil.successResult(distance);
    }
}

接口调用结果示例

// 添加位置信息 返回成功添加的条数
url:test/a_geo
{
    "code": 200,
    "msg": "SUCCESS",
    "data": 10
}
// 获取指定成员间的距离
url:/test/geo_dist?member1=name_3&member2=name_2
{
    "code": 200,
    "msg": "SUCCESS",
    "data": {
        "value": 5338.7572,
        "metric": "METERS" 
    }
}
// RedisGeoCommands.GeoRadiusCommandArgs 中可以指定排序和返回条数limit
url:/test/q_geo?member=name_3&distance=10
{
    "code": 200,
    "msg": "SUCCESS",
    "data": {
        "averageDistance": {
            "value": 4.80035,
            "metric": "KILOMETERS"
        },
        "content": [
            {
                "content": {
                    "name": "name_3",
                    "point": {
                        "x": 103.94980698823929,
                        "y": 30.86004888238883
                    }
                },
                "distance": {
                    "value": 0.0,
                    "metric": "KILOMETERS"
                }
            },
            {
                "content": {
                    "name": "name_2",
                    "point": {
                        "x": 103.89573365449905,
                        "y": 30.872278911982647
                    }
                },
                "distance": {
                    "value": 5.3388,
                    "metric": "KILOMETERS"
                }
            }
        ]
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值