package com.xiaopeng.operation.service.impl;
|
|
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
|
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
|
import com.xiaopeng.operation.repository.XpGeoQueryEntityRepository;
|
import com.xiaopeng.operation.service.IXpGeoQueryEntityService;
|
import org.springframework.beans.factory.annotation.Autowired;
|
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.mongodb.core.MongoTemplate;
|
import org.springframework.data.mongodb.core.query.Criteria;
|
import org.springframework.data.mongodb.core.query.NearQuery;
|
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;
|
import java.util.stream.Collectors;
|
|
/**
|
* 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,
|
"xp_geo_query_entity" // 明确指定集合名,避免映射错误
|
);
|
|
// 5. 提取结果
|
return geoResults.getContent().stream()
|
.map(geoResult -> geoResult.getContent())
|
.collect(Collectors.toList());
|
|
}
|
|
/**
|
* 保存地理查询实体
|
* @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();
|
}
|
}
|