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

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. wmiprvse.exe cpu占用高怎么解决

    可以通过在注册表中设置,来禁用该服务,具体步骤如下:         (1)按下“Win+R”组合键呼出运行,在框中输入“CMD”按下回车打开“命令提示符”:       (2)在命令提示符中输入:r ...

  2. zookeeper在dubbo中干什么

    本文旨在表述出自己对于zookeeper在dubbo的作用的初步理解 在对dubbo进行了初步的探索后,对于zookeeper在其中的作用不甚了解,因为本身对zookeeper就没有一个特别具体的概念 ...

  3. poj 3415

    对拍没错..莫名wa了 利用容斥求每个串的重复子串 其实就是找到每个元素能扩展到的最大元素 即(rr-i)*(i-lr)*(w[i]-kk) 就可以了 然后处理这个先离散化再搞 另外是x y要清空 # ...

  4. Einbahnstrasse HDU2923

    基础2923题 处理输入很麻烦 有可能一个城市有多辆破车要拖   应该严谨一点的 考虑所有情况 #include<bits/stdc++.h> using namespace std; ] ...

  5. [OpenCV-Python] OpenCV 中的图像处理 部分 IV (六)

    部分 IVOpenCV 中的图像处理 OpenCV-Python 中文教程(搬运)目录 23 图像变换 23.1 傅里叶变换目标本小节我们将要学习: • 使用 OpenCV 对图像进行傅里叶变换 • ...

  6. mybatis DATE_FORMAT 格式化时间输出

    参考:http://www.cnblogs.com/yangy608/p/3950095.html 一.在oracle中,当想把字符串为‘2011-09-20 08:30:45’的格式转化为日期格式, ...

  7. sublime 自定义快捷代码

    选择打开tools ->developer->new snippet <snippet> <content><![CDATA[Hello, ${1:this} ...

  8. HTML+CSS,让div在屏幕中居中(水平居中+垂直居中)方法总结

    最近写网页经常需要将div在屏幕中居中显示,遂记录下几个常用的方法,都比较简单. 水平居中直接加上<center>标签即可,或者设置margin:auto;当然也可以用下面的方法 下面说两 ...

  9. P1593 因子和

    P1593 因子和新算法:#define ni 逆元先质因数分解,(1+p1^1+p1^2...p1^x)*(1+p2^1+p2^2...p2^x)然后套等比数列公式就可以了. #include< ...

  10. jackson实现java对象转支付宝/微信模板消息

    一.支付宝消息模板大致长这样 { "to_user_id": "", "telephone": "xxxxx", &qu ...