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)来实现我们的缓存需求. ...
随机推荐
- 设计模式【转自JackFrost的博客】
首先,感谢作者对知识的分享 使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.设计模式使代码编制真正工程化,是软件工程的基石脉络,如同大厦的结构一样. 文章结构:1.单一职责原则( ...
- 【C语言】字节对齐(内存对齐)
数据对齐 1. 对齐原则: [原则1]数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma p ...
- otter部署【原创】
环境IP:10.10.6.171 部署:mysql源库IP:10.10.6.172 部署:mysql目标库IP:10.10.6.173 部署:zookeeper,manager,node,canal ...
- [转] Web MVC简介
http://blog.csdn.net/zk_software/article/details/8141843
- #5【BZOJ4275】[ONTAK2015]Badania
Description 给定三个数字串A,B,C,请找到一个A,B的最长公共子序列,满足C是该子序列的子串. Input 第一行包含一个正整数n(1<=n<=3000),表示A串的长度. ...
- hdu 1542
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 题意: 求所给矩形的覆盖面积 题解: 利用扫描线的思想,先将坐标离散化,之后以y轴分成多个矩形求解, ...
- python全栈开发day15-递归函数、二分查找
1.昨日内容回顾 主要内置函数: map(func,iter1):返回迭代器 filter(func,iter1):返回迭代器 sorted(iter,key=,reverse=):返回列表 reve ...
- HDU 6114 Chess【逆元+组合数】(组合数模板题)
<题目链接> 题目大意: 車是中国象棋中的一种棋子,它能攻击同一行或同一列中没有其他棋子阻隔的棋子.一天,小度在棋盘上摆起了许多車……他想知道,在一共N×M个点的矩形棋盘中摆最多个数的車使 ...
- AJP认证信息爆破ajp_brute
AJP认证信息爆破ajp_brute 一旦AJP服务启用身份认证后,就可以使用Nmap提供的ajp-brute脚本实施爆破.该脚本使用Nmap自带的用户名字典和密码字典实施爆破.在破解前,用户应该 ...
- Chrome for Mac键盘快捷键!来自Google Chrome官网!
⌘-N 打开新窗口. ⌘-T 打开新标签页. ⌘-Shift-N 在隐身模式下打开新窗口. 按 ⌘-O,然后选择文件. 在 Google Chrome 浏览器中打开计算机中的文件. 按住 ⌘ 键,然后 ...