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); }
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import javax.annotation.Resource; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import com.alibaba.fastjson.JSONObject;
import com.longge.core.util.BeanMapper;
import com.longge.goods.api.BuildingService;
import com.longge.goods.api.LbsService;
import com.longge.goods.constants.BuildingConstant;
import com.longge.goods.dto.BuildingDto;
import com.longge.goods.dto.BuildingLbsDto;
import com.longge.goods.util.GoodsRedisKeyUtils; import lombok.extern.slf4j.Slf4j; @Service
@Slf4j
public class LbsServiceImpl implements LbsService {
@Autowired
private BuildingService buildingService;
// 搜索范围
@Value("${lbs.distance:3}")
private Double lbsDistance;
@Resource
private StringRedisTemplate redisTemplate; @Override
public void saveBuildingLonAndLat(BuildingDto buildDto) {
log.info("开始处理楼宇的经纬度数据,楼宇:{}", JSONObject.toJSONString(buildDto));
GeoOperations<String, String> ops = redisTemplate.opsForGeo();
String member = String.valueOf(buildDto.getId());
// 查询楼宇的geo数据是否存在
List<String> list = ops.hash(GoodsRedisKeyUtils.getBuildingLbsKey(), member);
if (!CollectionUtils.isEmpty(list)) {
log.info("该楼宇数据存在,先进行删除操作");
// 存在,先删除,后新增
ops.remove(GoodsRedisKeyUtils.getBuildingLbsKey(), member);
}
ops.add(GoodsRedisKeyUtils.getBuildingLbsKey(),
new RedisGeoCommands.GeoLocation<String>(member, new Point(buildDto.getLon(), buildDto.getLat())));
log.info("楼宇经纬度信息处理完成");
} @Override
public List<BuildingLbsDto> listNearbyBuilding(double lon, double lat, int limit) {
log.info("查询LBS楼宇信息,经度:{},纬度:{},条数:{}", lon, lat, limit);
GeoOperations<String, String> ops = redisTemplate.opsForGeo(); // 获取redis里全局的配置,实现参数动态化
String redisLbsDistance = (String)RedisCache.hGet("config:global", "lbsDistance");
if(StringUtils.isNotBlank(redisLbsDistance)) {
lbsDistance = Double.valueOf(redisLbsDistance);
} Point center = new Point(lon, lat);
Distance radius = new Distance(lbsDistance, Metrics.KILOMETERS);
Circle within = new Circle(center, radius);
// order by 距离 limit 20 ,同时返回距离中心点的距离
GeoRadiusCommandArgs args = GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().limit(limit).sortAscending(); GeoResults<GeoLocation<String>> result = ops.radius(GoodsRedisKeyUtils.getBuildingLbsKey(), within, args);
log.info("查询redis后的经纬度数据:{}", JSONObject.toJSONString(result));
if(null != result) {
Map<Long, Double> data = new HashMap<>();
List<Long> buildings = new ArrayList<>(); result.forEach(item -> {
data.put(Long.valueOf(item.getContent().getName()), item.getDistance().getValue());
buildings.add(Long.valueOf(item.getContent().getName()));
});
if(!CollectionUtils.isEmpty(buildings)) {
List<BuildingDto> buildingList = buildingService.getBuildList(buildings);
if(!CollectionUtils.isEmpty(buildingList)) {
List<BuildingLbsDto> resp = new ArrayList<>();
buildingList.stream().forEach(item -> {
BuildingLbsDto dto = BeanMapper.map(item, BuildingLbsDto.class);
if(BuildingConstant.BuildingStatusEnum.OPENED.getValue() == dto.getStatus()) {
dto.setDistance(data.get(item.getId()));
resp.add(dto);
}
});
log.info("查询LBS楼宇信息的结果:{}", JSONObject.toJSONString(resp));
return resp;
}
}
}
log.warn("未查询LBS楼宇信息");
return null;
}
}
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;
}
SpringBoot集成redis的LBS功能的更多相关文章
- springBoot集成Redis遇到的坑(择库)源码分析为什么择库失败
提示: springboot提供了一套链接redis的api,也就是个jar包,用到的连接类叫做LettuceConnectionConfiguration,所以我们引入pom时是这样的 <de ...
- 【springBoot】springBoot集成redis的key,value序列化的相关问题
使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>o ...
- SpringBoot集成redis的key,value序列化的相关问题
使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>o ...
- springboot集成redis(mybatis、分布式session)
安装Redis请参考:<CentOS快速安装Redis> 一.springboot集成redis并实现DB与缓存同步 1.添加redis及数据库相关依赖(pom.xml) <depe ...
- Windows环境下springboot集成redis的安装与使用
一,redis安装 首先我们需要下载Windows版本的redis压缩包地址如下: https://github.com/MicrosoftArchive/redis/releases 连接打开后如下 ...
- SpringBoot | 集成Redis
Windows下安装: https://github.com/MicrosoftArchive/redis/releases zip下就解包到自定义目录下,msi就跟着步骤安装 进入安装目录下运行命令 ...
- springboot集成redis使用redis作为session报错ClassNotFoundException类RememberMeServices
springboot 集成redis使用redis作为缓存,会报错的问题. 错误信息: java.lang.IllegalStateException: Error processing condit ...
- SpringBoot整合Redis实现常用功能
SpringBoot整合Redis实现常用功能 建议大小伙们,在写业务的时候,提前画好流程图,思路会清晰很多. 文末有解决缓存穿透和击穿的通用工具类. 1 登陆功能 我想,登陆功能是每个项目必备的功能 ...
- SpringBoot集成Redis来实现缓存技术方案
概述 在我们的日常项目开发过程中缓存是无处不在的,因为它可以极大的提高系统的访问速度,关于缓存的框架也种类繁多,今天主要介绍的是使用现在非常流行的NoSQL数据库(Redis)来实现我们的缓存需求. ...
随机推荐
- ERP退货系统管理(四十五)
添加的存储过程:(添加退货申请信息的存储过程) CREATE PROCEDURE [dbo].[BioBackSendGoods_ADD] @SendBackID INT OUTPUT, ), @Ap ...
- 在django中使用FormView,success_url死活不能生效的问题
真的不知道是怎么回事, 以前都是手动的, form使用modelform. view使用createview. 今天写新系统时,为了更灵活. form使用form,(这样一来,可以在form是随便按数 ...
- mySQL 增量备份方案
1.在 /etc/my.cnf 下面设置开启bin-log 编辑 vim /etc/my.cnf [mysqld] binlog_format = MIXED ...
- java:冒泡排序、选择排序、插入排序实现
整数排序 给一组整数,按照升序排序,使用选择排序,冒泡排序,插入排序或者任何 O(n2) 的排序算法. 样例 样例 1: 输入: [3, 2, 1, 4, 5] 输出: [1, 2, 3, 4, 5] ...
- C#编程的语法积累(一)
1.自动属性 之前的实现方式: private int id; public int Id { set {id = value;} get {return id;} } 现在可通过自动属性实现: pu ...
- 009 搭建Spark的maven本地windows开发环境以及测试
在看完下面的细节之后,就会发现,spark的开发,只需要hdfs加上带有scala的IDEA环境即可. 当run运行程序时,很快就可以运行结束. 为了可以看4040界面,需要将程序加上暂定程序,然后 ...
- Java各种对象(PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans)的区分
PO:持久对象 (persistent object),po(persistent object)就是在Object/Relation Mapping框架中的Entity,po的每个属性基本上都对应数 ...
- java中函数传值和传地址的问题
记录一下这个难过的双休,2019.3.16-2019.3.17,16号上午字节跳动笔试,四道题只做出1道半,输入输出搞的半死,第三题类似于leetcode上的分糖问题,数组初始化的时候全部赋为0了,要 ...
- Java线程池深入理解
之前面试baba系时遇到一个相对简单的多线程编程题,即"3个线程循环输出ADC",自己答的并不是很好,深感内疚,决定更加仔细的学习<并发编程的艺术>一书,到达掌握的强度 ...
- myeclipse maven的联系
本文非完整的maven安装步骤,这些只是我看的资料的一点点而已,做出一些总结,纯属以后可以看看我的学习经历.如有需要,可以下载我分享的Maven实战(有目录的),书中源代码下载. 设置myclipse ...