package com.xiaopeng.itinerary.service.impl;
|
|
|
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
|
import com.xiaopeng.itinerary.repository.XpGeoQueryEntityRepository;
|
import com.xiaopeng.itinerary.service.IXpGeoQueryEntityService;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.data.geo.Circle;
|
import org.springframework.data.geo.Distance;
|
import org.springframework.data.geo.Metrics;
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
|
import org.springframework.data.mongodb.core.query.Criteria;
|
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.mongodb.core.query.Update;
|
import org.springframework.stereotype.Service;
|
|
import java.util.Calendar;
|
import java.util.Date;
|
import java.util.List;
|
|
/**
|
* MongoDB 地理查询服务实现类
|
*/
|
@Service
|
public class XpGeoQueryEntityServiceImpl implements IXpGeoQueryEntityService {
|
|
@Autowired
|
private XpGeoQueryEntityRepository repository;
|
|
@Autowired
|
private MongoTemplate mongoTemplate;
|
|
/**
|
* 通过经纬度查询固定范围500米内、一周内、指定时段的数据
|
* @param longitude 经度
|
* @param latitude 纬度
|
* @param time 时段(格式:HH-HH,例如:19-20)
|
* @return 符合条件的实体列表
|
*/
|
@Override
|
public List<XpGeoQueryEntity> findByLocationWithin500MetersAndLastWeekAndStatusGreater(
|
double longitude,
|
double latitude,
|
String time
|
) {
|
// // 计算一周前的时间
|
Calendar calendar = Calendar.getInstance();
|
calendar.setTime(new Date());
|
calendar.add(Calendar.DAY_OF_YEAR, -7);
|
Long startTime = calendar.getTime().getTime();
|
|
// 1. 创建查询点
|
// Point referencePoint = new Point(longitude, latitude);
|
//
|
// // 2. 构建 NearQuery - 完全使用 NearQuery 的 API
|
// NearQuery nearQuery = NearQuery.near(referencePoint, Metrics.KILOMETERS)
|
// .maxDistance(0.5) // 转成公里
|
// .spherical(true);
|
//
|
//
|
// // 3.时间>startTime time = time参数
|
// // 3. 创建额外的查询条件
|
// Query query = new Query();
|
// query.addCriteria(Criteria.where("timestamp").gte(startTime));
|
// query.addCriteria(Criteria.where("time").is(time));
|
//
|
// // 将 NearQuery 和额外的查询条件合并
|
// nearQuery.query(query);
|
//
|
//
|
// // 4. 执行查询 - 明确指定集合名
|
// GeoResults<XpGeoQueryEntity> geoResults = mongoTemplate.geoNear(nearQuery, XpGeoQueryEntity.class);
|
//
|
// // 5. 提取结果
|
// return geoResults.getContent().stream()
|
// .map(geoResult -> geoResult.getContent())
|
// .collect(Collectors.toList());
|
|
//找到中心点
|
GeoJsonPoint geoJsonPoint = new GeoJsonPoint(longitude, latitude);
|
//构造半径
|
Distance distanceR = new Distance(5, Metrics.KILOMETERS);
|
//画圆
|
Circle circle = new Circle(geoJsonPoint, distanceR);
|
// 构造query对象
|
Query query = Query.query(Criteria.where("location").withinSphere(circle));
|
query.addCriteria(Criteria.where("timestamp").gte(startTime));
|
query.addCriteria(Criteria.where("time").is(time));
|
List<XpGeoQueryEntity> driverPositions = mongoTemplate.find(query, XpGeoQueryEntity.class);
|
|
return driverPositions;
|
}
|
|
/**
|
* 保存地理查询实体
|
* @param entity 地理查询实体
|
* @return 保存后的实体
|
*/
|
@Override
|
public XpGeoQueryEntity save(XpGeoQueryEntity entity) {
|
return repository.save(entity);
|
}
|
|
|
|
@Override
|
public XpGeoQueryEntity updateByOrderId(String orderId) {
|
Query query = new Query(Criteria.where("orderId").is(orderId));
|
|
XpGeoQueryEntity xpGeoQueryEntity = mongoTemplate.findOne(query, XpGeoQueryEntity.class);
|
Long timestamp = xpGeoQueryEntity.getTimestamp();
|
long time = new Date().getTime();
|
// 计算2个时间的秒数差
|
long seconds = (time- timestamp) / 1000;
|
Update update = new Update().set("seconds", seconds).set("status", 1);
|
if(xpGeoQueryEntity.getStatus()==0){
|
mongoTemplate.findAndModify(query, update, XpGeoQueryEntity.class);
|
}
|
return null;
|
|
}
|
|
/**
|
* 根据ID查询实体
|
* @param id 实体ID
|
* @return 实体
|
*/
|
@Override
|
public XpGeoQueryEntity findById(String id) {
|
return repository.findById(id).orElse(null);
|
}
|
|
/**
|
* 删除实体
|
* @param id 实体ID
|
*/
|
@Override
|
public void deleteById(String id) {
|
repository.deleteById(id);
|
}
|
|
/**
|
* 查询所有实体
|
* @return 实体列表
|
*/
|
@Override
|
public List<XpGeoQueryEntity> findAll() {
|
return repository.findAll();
|
}
|
}
|