下面的代码实现了添加经纬度数据 和 搜索经纬度数据的功能:

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功能的更多相关文章

  1. springBoot集成Redis遇到的坑(择库)源码分析为什么择库失败

    提示: springboot提供了一套链接redis的api,也就是个jar包,用到的连接类叫做LettuceConnectionConfiguration,所以我们引入pom时是这样的 <de ...

  2. 【springBoot】springBoot集成redis的key,value序列化的相关问题

    使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>o ...

  3. SpringBoot集成redis的key,value序列化的相关问题

    使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>o ...

  4. springboot集成redis(mybatis、分布式session)

    安装Redis请参考:<CentOS快速安装Redis> 一.springboot集成redis并实现DB与缓存同步 1.添加redis及数据库相关依赖(pom.xml) <depe ...

  5. Windows环境下springboot集成redis的安装与使用

    一,redis安装 首先我们需要下载Windows版本的redis压缩包地址如下: https://github.com/MicrosoftArchive/redis/releases 连接打开后如下 ...

  6. SpringBoot | 集成Redis

    Windows下安装: https://github.com/MicrosoftArchive/redis/releases zip下就解包到自定义目录下,msi就跟着步骤安装 进入安装目录下运行命令 ...

  7. springboot集成redis使用redis作为session报错ClassNotFoundException类RememberMeServices

    springboot 集成redis使用redis作为缓存,会报错的问题. 错误信息: java.lang.IllegalStateException: Error processing condit ...

  8. SpringBoot整合Redis实现常用功能

    SpringBoot整合Redis实现常用功能 建议大小伙们,在写业务的时候,提前画好流程图,思路会清晰很多. 文末有解决缓存穿透和击穿的通用工具类. 1 登陆功能 我想,登陆功能是每个项目必备的功能 ...

  9. SpringBoot集成Redis来实现缓存技术方案

    概述 在我们的日常项目开发过程中缓存是无处不在的,因为它可以极大的提高系统的访问速度,关于缓存的框架也种类繁多,今天主要介绍的是使用现在非常流行的NoSQL数据库(Redis)来实现我们的缓存需求. ...

随机推荐

  1. js在字符串中提取数字

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 《剑指offer》-中序遍历下一个节点

    题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. /* struct TreeLinkNode { in ...

  3. 依赖注入与Unity

    关于控制反转(Inversion of Control)和依赖注入(Dependency Injection)大家网上可以找下相关概念,在<小菜学习设计模式(五)-控制反转(Ioc)>这篇 ...

  4. HTML5游戏 围住神经猫 开发

    所有文章搬运自我的个人主页:sheilasun.me 去年风靡微信朋友圈的小游戏"围住神经猫",我也试着做了一下,可以戳这里试玩→围住神经猫.游戏是用Egret引擎开发的,因为Eg ...

  5. 【深入spring】IoC容器的实现

    本文乃学习整理参考而来 IoC概述: 在spring中,IoC容器实现了依赖控制反转,它可以再对象生成或初始化时直接将数据注入到对象中,也可以通过将对象引用注入到对象数据域中的方式来注入方法调用的依赖 ...

  6. User Agent 设置

    感谢版主回复,版主贴的方法网上到处都是,我试了很多次都是不行的,有用的方法都几乎这个到处转贴的信息淹没了. 今天我总算在一个博客找了到可行的方法,转过来和大家分享 Windows Registry E ...

  7. 077 Apache的HBase与cdh的hue集成(不建议不同版本之间的集成)

    1.修改hue的配置文件hue.ini [hbase] # Use full hostname with security. hbase_clusters=(Cluster|linux-hadoop3 ...

  8. STL容器底层数据结构的实现

    C++ STL 的实现: 1.vector      底层数据结构为数组 ,支持快速随机访问   2.list            底层数据结构为双向链表,支持快速增删   3.deque     ...

  9. Ubuntu18.04更换国内源

    Ubuntu18.04更换国内源 Ubuntu本身的源使用的是国内的源,下载速度比较慢,不像CentOS一样yum安装的时候对镜像站点进项选择, 所以选择了更换成国内的源. 以下内容整合自网络 备份/ ...

  10. hdu 1276士兵队列问题【queue】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1276 士兵队列训练问题                                         ...