package club.newtech.qbike.trip.domain.service;

import club.newtech.qbike.trip.domain.core.Status;
import club.newtech.qbike.trip.domain.core.root.DriverStatus;
import club.newtech.qbike.trip.domain.core.vo.Driver;
import club.newtech.qbike.trip.domain.core.vo.Position;
import club.newtech.qbike.trip.domain.repository.DriverStatusRepo;
import club.newtech.qbike.trip.domain.repository.PositionRepository;
import club.newtech.qbike.trip.infrastructure.UserRibbonHystrixApi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import static java.util.stream.Collectors.toList;

@Service
@Transactional
public class PositionService {
private static final Logger LOGGER = LoggerFactory.getLogger(PositionService.class);
@Autowired
DriverStatusRepo driverStatusRepo;
@Autowired
UserRibbonHystrixApi userService;
@Autowired
RedisTemplate<String, String> redisTemplate;
@Autowired
PositionRepository positionRepository;

/**
* 上传位置
*
* @param driverId
* @param longitude
* @param latitude
*/
public void updatePosition(Integer driverId, Double longitude, Double latitude) {
//先记录轨迹
Date current = new Date();
Position position = new Position();
position.setDriverId(String.valueOf(driverId));
position.setPositionLongitude(longitude);
position.setPositionLatitude(latitude);
//TODO 目前没有上传上下线状态
position.setStatus(Status.ONLINE);
position.setUploadTime(current);

//保存位置信息
positionRepository.save(position);

//更新状态表
DriverStatus driverStatus = driverStatusRepo.findByDriver_Id(driverId);
if (driverStatus != null) {
driverStatus.setCurrentLongitude(longitude);
driverStatus.setCurrentLatitude(latitude);
driverStatus.setUpdateTime(current);
driverStatusRepo.save(driverStatus);
} else {
Driver driver = userService.findById(driverId);
driverStatus = new DriverStatus();
driverStatus.setDriver(driver);
driverStatus.setCurrentLongitude(longitude);
driverStatus.setCurrentLatitude(latitude);
driverStatus.setUpdateTime(current);
driverStatus.setStatus(Status.ONLINE);
driverStatus.setDId(driverId);
driverStatusRepo.save(driverStatus);
}
//更新Redis中的坐标数据,GeoHash
redisTemplate.opsForGeo().geoAdd("Drivers", new Point(longitude, latitude), String.valueOf(driverId));
LOGGER.info("position update " + driverStatus);

}

/**
* 匹配司机
*
* @param longitude
* @param latitude
* @return
*/
public Collection<DriverStatus> matchDriver(double longitude, double latitude) {
Circle circle = new Circle(new Point(longitude, latitude), //
new Distance(500, RedisGeoCommands.DistanceUnit.METERS));
GeoResults<RedisGeoCommands.GeoLocation<String>> result =
redisTemplate.opsForGeo().geoRadius("Drivers", circle);
if (result.getContent().size() == 0) {
LOGGER.info("没找到匹配司机");
return new ArrayList<>();

} else {
List<String> drivers = result.getContent()
.stream()
.map(x -> x.getContent().getName())
.collect(toList());
LOGGER.info("获取附近司机为{}", drivers);
return drivers.stream().map(Integer::parseInt)
.map(id -> driverStatusRepo.findByDriver_Id(id)).collect(toList());
}
}
}

redis geo操作的更多相关文章

  1. Redis数据类型:Hashes、Geo操作指令

    Redis数据类型:Hashes.Geo操作指令 Hashes常用操作指令 Redis Hashes是一个键值对的映射表,最对能存储2^32-1(约40亿)个键值对. HSET HGET HSET:将 ...

  2. Redis GEO 功能使用场景

    本文来源:https://www.dazhuanlan.com/2020/02/05/5e3a0a3110649/ 背景 前段时间自己在做附近直播相关业务,其中有一个核心的点就是检索用户附近的主播,也 ...

  3. Redis GEO 地理位置

    目录 GEO指令 GEOADD GEODIST GEOPOP GEOHASH GEORADIUS GEORADIUSBYMEMBER 指令补充 删除操作 避免单集合数量过多 存储原理 GEOADD存储 ...

  4. Redis Geo: Redis新增位置查询功能

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/144.html 移动互联网增进了人与人之间的联系,其中基于位置信息的服务( ...

  5. spring data redis RedisTemplate操作redis相关用法

    http://blog.mkfree.com/posts/515835d1975a30cc561dc35d spring-data-redis API:http://docs.spring.io/sp ...

  6. Spring Framework 中启动 Redis 事务操作

    背景: 项目中遇到有一系列对Redis的操作,并需要保持事务处理. 环境: Spring version 4.1.8.RELEASE Redis Server 2.6.12 (64位) spring- ...

  7. php的redis 操作类,适用于单台或多台、多组redis服务器操作

    redis 操作类,包括单台或多台.多组redis服务器操作,适用于业务复杂.高性能要求的 php web 应用. redis.php: <?php /* redis 操作类,适用于单台或多台. ...

  8. 转:Redis Geo: Redis新增位置查询功能

    原文来自于:http://www.infoq.com/cn/news/2015/07/redis-geo 移动互联网增进了人与人之间的联系,其中基于位置信息的服务(Location Based Ser ...

  9. 【springboot】【redis】springboot结合redis,操作List集合实现时间轴功能

    springboot结合redis,操作List集合实现时间轴功能

随机推荐

  1. SpringBoot 使用WebSocket打造在线聊天室

    教程: https://www.jianshu.com/p/55cfc9fcb69e https://wallimn.iteye.com/blog/2425666 关于websocket基础普及见:h ...

  2. 使用pycharm开发web——django2.1.5(三)创建models并进入交互界面shell做一些简单操作

    这里model可以认为是数据对象本身 相当于在写java代码时候model目录下创建的实体类,models.py 中可以包含多个实体类,感觉这个操作挺骚的 下面是polls app里面的models, ...

  3. hdu 1024 最大m段不相交线段和

    题目传送门//res tp hdu 数据范围1e6,若是开二维会爆 考虑用滚动数组优化 #include<iostream> #include<cstdio> #include ...

  4. Pots(POJ-3414)【BFS】

    题意:有两个有着固定容量的茶壶,初始时都为空,要求用FILL,POUR,DROP三种操作来准确地得到C值,输出最少次数及操作方案. 思路:比赛的时候真是脑子不好使,根本没想到是搜索,看了别人的题解用搜 ...

  5. 手机设置Fiddler代理后无法访问Https网络的解决办法

    第一种方法: 首先,下载最新版本的Fiddler,将手机和PC设置为统一局域网(手机链接PC的wifi) 打开手机设置-无线网络设置,设置代理为手动,输入pc的ip和Fillder的端口8888(Fi ...

  6. python爬取信息并保存至csv

    import csv import requests from bs4 import BeautifulSoup res=requests.get('http://books.toscrape.com ...

  7. 守护服务Supervisor的安装和使用

    Supervisor(http://supervisord.org/)是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统 ...

  8. [NOIP10.5模拟赛]3.c题解--思维

    题目链接 这次不咕了 https://www.luogu.org/problemnew/show/AT2389 闲扯 考场20分爆搜走人 \cy 话说这几天T3都很考验思维啊 分析 我们先钦定一只鸡( ...

  9. [转载]Pytorch详解NLLLoss和CrossEntropyLoss

    [转载]Pytorch详解NLLLoss和CrossEntropyLoss 来源:https://blog.csdn.net/qq_22210253/article/details/85229988 ...

  10. Oracle学习笔记:rank、dense_rank、row_number、ntile等排序算法

    在 oracle 中有很多函数可以实现排序的功能,但是不尽相同.下面一一解说. row_number函数 功能:可实现分组排序,为数据行添加序号,多用于分页查询. 语法:row_number() ov ...