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)来实现我们的缓存需求. ...
随机推荐
- C#中decimal ,double,float的区别
浮点型 Name CTS Type Description Significant Figures Range (approximate) float System.Single 32-bit sin ...
- zjoi 网络
题解: 很显然会发现对于每种颜色分开处理这是一颗树 然后就是裸的lct 有个坑就是判断操作1 可能颜色改成跟原先一样的 代码: #include <bits/stdc++.h> using ...
- asp.net core 微信获取用户openid
获取openid流程为首先根据微信开发参数构造AuthorizeUrl认证链接,用户跳转到该链接进行授权,授权完成将跳转到回调页(首次认证需要授权,后面将直接再跳转至回调页),此时回调页中带上一个GE ...
- python全栈开发day20-类的三大特性继承、多态、封装
1 继承 1.怎么继承,父类和子类 class 类名(父类):pass 除了__init__下对象属性不能自动继承外,其他的类属性和动态方法,子类对象都可以访问到. 2.子类对象查找属性的顺序,对象现 ...
- Codeforces Round #319 (Div. 2) E - Points on Plane
题目大意:在一个平面里有n个点,点坐标的值在1-1e6之间,让你给出一个遍历所有点的顺序,要求每个点走一次,且 曼哈顿距离之和小于25*1e8. 思路:想了一会就有了思路,我们可以把1e6的x,y坐标 ...
- streaming优化:spark.streaming.receiver.maxRate
使用spark.streaming.receiver.maxRate来限制你的吞吐的最大信息量. 因为当streaming程序的数据源的数据量突然变大巨大,可能会导致streaming被撑住导致吞吐不 ...
- 【Java】 剑指offer(45) 把数组排成最小的数
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接 ...
- 033 关于YARN的HA
一:准备 1.规划 namenode namenode ZKFC ZKFC journalnode journalnode jou ...
- Manjaro 初始配置----anaconda-pycharm-opencv-tensorflow
1.安装蟒蛇 1)安装 yaourt anaconda source /opt/anaconda/bin/active root 2)添加环境变量 在〜/ .bashrc中添加 export PATH ...
- 收缩自编码器(CAE)
自编码器是一种很好的降维技术,它可以学习到数据中非常有用的信息.而收缩自编码器作为正则自编码器的一种,其非线性降维效果非常好,并且它的过程可以通过流形知识来解释. 基础知识 1.自编码器 自编码器是一 ...