Redsi通过geo计算距离

一. 前言

前段时间,小熙赶项目比较忙。趁此机会记录下遇到的后端距离计算实现,app端会有实时的经纬度回传到Redis中,PC端和H5需要实时查看位置和距离,所以想下Redis是否支持此类计算。

二. Redis的geo介绍

  1. 版本支持:

        redis在3.2版本中开始支持geo功能
    
  2. 命令介绍:
    (1) geoadd 添加地址

     sms-center:5>geoadd cityLocationGeo 116.405285 39.904989 北京
     1
    
      sms-center:5>geoadd cityLocationGeo 121.472644 31.231706 上海
     1
    

    (2)geodist 计算距离(默认是米,可以指定单位千米)

      sms-center:5>geodist cityLocationGeo 北京 上海
      1067597.9668
    
      sms-center:5>geodist cityLocationGeo 北京 上海 km
      1067.5980
    

    (3)geohash 获取地址的hash值(可用于判断是否存在)

       sms-center:5>geohash cityLocationGeo 上海 北京
       wtw3sjt9vg0
       wx4g0b7xrt0
    

    (4)geopos 获取地理位置(经纬度)

        sms-center:5>geopos cityLocationGeo 北京
        1) "116.40528291463851929"
        2) "39.9049884229125027"
    

    (5)zrem 删除某个地址(redis中没有geodel命令)

         sms-center:5>zrem cityLocationGeo 北京
         1
    

其他更多详细命令请查询文档

三. redisTemplate 使用 geo

这里的storeKey和memberKey是两个地理位置的keyName,可任意替换。

  1. 添加geo

       /**
         * 向redis中添加geo计算数据
         *
         * @param prefixName
         * @param caseDetail
         * @param latitude
         * @param longitude
         * @param name
         * @return
         */
        private String addGeoData(String prefixName, CaseDetail caseDetail, String latitude, String longitude, String name) {
            String geoKey = prefixName + "_" + caseDetail.getStoreNo() + "_" + caseDetail.getCaseNo() + "_LatitudeAndLongitude";
            Point point = new Point(Double.valueOf(longitude), Double.valueOf(latitude));
            redisTemplate.opsForGeo()
                .add(geoKey, point, name);
            redisTemplate.expire(geoKey, 30, TimeUnit.SECONDS);
         return geoKey;
      }
    
  2. 计算距离

         // 计算距离
         Distance distance = redisTemplate.boundGeoOps(geoKey).distance(storeKey, memberKey, RedisGeoCommands.DistanceUnit.KILOMETERS);
         double value = distance.getValue();
    
  3. 获取hash地址

          List hash = redisTemplate.boundGeoOps(geoKey).hash(storeKey);
    
  4. 获取地理位置(经纬度)

          List<Point> position = (List<Point>) redisTemplate.boundGeoOps(geoKey).position(memberKey)
                .stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList()); 
    
  5. 删除某个地理位置

          Long remove = redisTemplate.boundGeoOps(geoKey).remove(storeKey);
    

四. 后语

基本开发以上的可以了,如果想了解更多,可以查看文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值