SpringBoot集成redis的LBS功能


下面的代碼實現了添加經緯度數據 和 搜索經緯度數據的功能:

import java.util.List;

import com.longge.goods.dto.BuildingDto;
import com.longge.goods.dto.BuildingLbsDto;

/**
 * LBS相關的服務
 * @author yangzhilong
 *
 */
public interface LbsService {
    /**
     * 新增或者修改樓宇的經緯度
     * @param buildDto
     */
    void saveBuildingLonAndLat(BuildingDto buildDto);
    
    /**
     * 查詢指定經緯度附近的樓宇
     * @param lon 經度
     * @param lat 緯度
     * @param limit 記錄數
     * @return
     */
    List<BuildingLbsDto> listNearbyBuilding(double lon, double lat, int limit);
    
}

 

  1 import java.util.ArrayList;
  2 import java.util.HashMap;
  3 import java.util.List;
  4 import java.util.Map;
  5 
  6 import javax.annotation.Resource;
  7 
  8 import org.apache.commons.lang3.StringUtils;
  9 import org.springframework.beans.factory.annotation.Autowired;
 10 import org.springframework.beans.factory.annotation.Value;
 11 import org.springframework.data.geo.Circle;
 12 import org.springframework.data.geo.Distance;
 13 import org.springframework.data.geo.GeoResults;
 14 import org.springframework.data.geo.Metrics;
 15 import org.springframework.data.geo.Point;
 16 import org.springframework.data.redis.connection.RedisGeoCommands;
 17 import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
 18 import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs;
 19 import org.springframework.data.redis.core.GeoOperations;
 20 import org.springframework.data.redis.core.StringRedisTemplate;
 21 import org.springframework.stereotype.Service;
 22 import org.springframework.util.CollectionUtils;
 23 
 24 import com.alibaba.fastjson.JSONObject;
 25 import com.longge.core.util.BeanMapper;
 26 import com.longge.goods.api.BuildingService;
 27 import com.longge.goods.api.LbsService;
 28 import com.longge.goods.constants.BuildingConstant;
 29 import com.longge.goods.dto.BuildingDto;
 30 import com.longge.goods.dto.BuildingLbsDto;
 31 import com.longge.goods.util.GoodsRedisKeyUtils;
 32 
 33 import lombok.extern.slf4j.Slf4j;
 34 
 35 @Service
 36 @Slf4j
 37 public class LbsServiceImpl implements LbsService {
 38     @Autowired
 39     private BuildingService buildingService;
 40     // 搜索范圍
 41     @Value("${lbs.distance:3}")
 42     private Double lbsDistance;
 43     @Resource
 44     private StringRedisTemplate redisTemplate;
 45 
 46     @Override
 47     public void saveBuildingLonAndLat(BuildingDto buildDto) {
 48         log.info("開始處理樓宇的經緯度數據,樓宇:{}", JSONObject.toJSONString(buildDto));
 49         GeoOperations<String, String> ops = redisTemplate.opsForGeo();
 50         String member = String.valueOf(buildDto.getId());
 51         // 查詢樓宇的geo數據是否存在
 52         List<String> list = ops.hash(GoodsRedisKeyUtils.getBuildingLbsKey(), member);
 53         if (!CollectionUtils.isEmpty(list)) {
 54             log.info("該樓宇數據存在,先進行刪除操作");
 55             // 存在,先刪除,后新增
 56             ops.remove(GoodsRedisKeyUtils.getBuildingLbsKey(), member);
 57         }
 58         ops.add(GoodsRedisKeyUtils.getBuildingLbsKey(),
 59                 new RedisGeoCommands.GeoLocation<String>(member, new Point(buildDto.getLon(), buildDto.getLat())));
 60         log.info("樓宇經緯度信息處理完成");
 61     }
 62 
 63     @Override
 64     public List<BuildingLbsDto> listNearbyBuilding(double lon, double lat, int limit) {
 65         log.info("查詢LBS樓宇信息,經度:{},緯度:{},條數:{}", lon, lat, limit);
 66         GeoOperations<String, String> ops = redisTemplate.opsForGeo();
 67         
 68         // 獲取redis里全局的配置,實現參數動態化
 69         String redisLbsDistance = (String)RedisCache.hGet("config:global", "lbsDistance");
 70         if(StringUtils.isNotBlank(redisLbsDistance)) {
 71             lbsDistance = Double.valueOf(redisLbsDistance);
 72         }
 73         
 74         Point center = new Point(lon, lat);
 75         Distance radius = new Distance(lbsDistance, Metrics.KILOMETERS);
 76         Circle within = new Circle(center, radius);
 77         // order by 距離 limit 20 ,同時返回距離中心點的距離
 78         GeoRadiusCommandArgs args = GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().limit(limit).sortAscending();
 79         
 80         GeoResults<GeoLocation<String>> result = ops.radius(GoodsRedisKeyUtils.getBuildingLbsKey(), within, args);
 81         log.info("查詢redis后的經緯度數據:{}", JSONObject.toJSONString(result));
 82         if(null != result) {
 83             Map<Long, Double> data = new HashMap<>();
 84             List<Long> buildings = new ArrayList<>();
 85             
 86             result.forEach(item -> {
 87                 data.put(Long.valueOf(item.getContent().getName()), item.getDistance().getValue());
 88                 buildings.add(Long.valueOf(item.getContent().getName()));
 89             });
 90             if(!CollectionUtils.isEmpty(buildings)) {
 91                 List<BuildingDto> buildingList = buildingService.getBuildList(buildings);
 92                 if(!CollectionUtils.isEmpty(buildingList)) {
 93                     List<BuildingLbsDto> resp = new ArrayList<>();
 94                     buildingList.stream().forEach(item -> {
 95                         BuildingLbsDto dto = BeanMapper.map(item, BuildingLbsDto.class);
 96                         if(BuildingConstant.BuildingStatusEnum.OPENED.getValue() == dto.getStatus()) {
 97                             dto.setDistance(data.get(item.getId()));
 98                             resp.add(dto);
 99                         }
100                     });
101                     log.info("查詢LBS樓宇信息的結果:{}", JSONObject.toJSONString(resp));
102                     return resp;
103                 }
104             }
105         }
106         log.warn("未查詢LBS樓宇信息");
107         return null;
108     }
109 }
import java.util.Date;

/**
 * 樓宇信息dto
 *
 */
@Data
public class BuildingDto {
    private Long id;

    private Short status;
    /**
     * 緯度
     */
    private Double lat;
    /**
     * 經度
     */
    private Double lon;
}
import java.io.Serializable;

import lombok.Getter;
import lombok.Setter;

/**
 * 包含距離定位點距離的樓宇dto
 * @author yangzhilong
 *
 */
@Getter
@Setter
public class BuildingLbsDto extends BuildingDto implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 3224249189169148012L;
    // 距離,單位:千米
    private Double distance;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM