package com.objecteye.service.impl; import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.objecteye.entity.LocusOrbitQueryParams; import com.objecteye.entity.LocusOrbitResultParams; import com.objecteye.entity.PageResult; import com.objecteye.pojo.RabbitMQVehicle; import com.objecteye.service.ILocusOrbitService; import com.objecteye.utils.GlobalUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * 汽车轨迹接口 * * @author liuhaoyu */ @Service public class LocusOrbitServiceImpl implements ILocusOrbitService { private final String URL = "http://192.168.10.4:10002/vehicle/analysisFile"; /** * 车牌置信度界限值 */ private final double NUM_SCORE_LIMIT = 0.9; /** * 抓拍时间需要去重的时间间隔 */ private final Long DISTINCT_TIME_INTERVAL = 60000L; @Autowired private MongoTemplate mongoTemplate; /** * 轨迹分析接口 * * @param locusOrbitQueryParams 请求参数模型 * @return 结果集 key: 车牌号, value: 车牌号对应的轨迹信息 */ @Override public List locusOrbitByPlateNumber(LocusOrbitQueryParams locusOrbitQueryParams) { // 所有符合条件的原始数据 List rabbitMqVehicles = mongoTemplate.find(locusOrbitQueryConditionDbHandle(locusOrbitQueryParams), RabbitMQVehicle.class); return simplePlateNumberHandle(rabbitMqVehicles); } /** * 轨迹分析接口(图片搜索) * * @param gcxh 车辆序号 * @param locusOrbitQueryParams 请求参数模型 * @param multipartFile 文件信息 * @return 车牌号对应的轨迹信息 */ @Override public List locusOrbitByPlateNumber(int gcxh, LocusOrbitQueryParams locusOrbitQueryParams, MultipartFile multipartFile) { String fileName = multipartFile.getOriginalFilename(); String picPath = GlobalUtil.dbPath1() + File.separator + "picture" + File.separator + fileName; File newFile = new File(picPath); try { multipartFile.transferTo(newFile); } catch (IOException e) { e.printStackTrace(); } String response = GlobalUtil.httpExecute(URL, newFile); // 使用完成之后删除文件 newFile.delete(); if (null == response || "".equals(response)) { return null; } JSONObject responseObj = JSON.parseObject(response); JSONArray infoArr = responseObj.getJSONObject("result").getJSONArray("info"); if (null == infoArr || infoArr.size() == 0) { return null; } List infoList = infoArr.toJavaList(JSONObject.class); JSONObject infoObj = infoList.get(gcxh); // 车牌置信度超过0.9 直接用车牌 double numScore = infoObj.getJSONObject("vehicle_plate_det_recg_res").getDoubleValue("numScore"); if (numScore > NUM_SCORE_LIMIT) { JSONArray plateNumParamsArr = infoObj.getJSONObject("vehicle_plate_det_recg_res").getJSONArray("plateNumParams"); StringBuilder plateNumberBuilder = new StringBuilder(); for (int i = 0; i < plateNumParamsArr.size(); i++) { JSONObject plateNumParamObj = plateNumParamsArr.getJSONObject(i); if (null == plateNumParamObj) { continue; } plateNumberBuilder.append(plateNumParamObj.getString("character")); } locusOrbitQueryParams.setPlateNumber(plateNumberBuilder.toString()); } else { return new ArrayList<>(); } return locusOrbitByPlateNumber(locusOrbitQueryParams); } /** * 拼接查询条件 * * @param locusOrbitQueryParams 请求参数模型 * @return mongo用query对象 */ private Query locusOrbitQueryConditionDbHandle(LocusOrbitQueryParams locusOrbitQueryParams) { Criteria criteria = new Criteria(); // 车牌 criteria.and("vehicle_plate_hphm").is(locusOrbitQueryParams.getPlateNumber()); // 开始时间 // 结束时间 Long startTime = locusOrbitQueryParams.getStartTime(); Long endTime = locusOrbitQueryParams.getEndTime(); if (null == startTime) { if (null != endTime) { criteria.and("pictime").lte(endTime); } } else if (null == endTime) { criteria.and("pictime").gte(startTime); } else { criteria.and("pictime").gte(startTime).lte(endTime); } Query query = Query.query(criteria); query.fields().include("id"); query.fields().include("pictime"); query.fields().include("longitude"); query.fields().include("latitude"); query.fields().include("snapshoturl"); query.fields().include("vehicle_plate_hphm"); return query; } /** * 单个车牌时间段去重(去重抓拍时间不超过1分钟的数据) * * @param rabbitMqVehicles 原始数据 * @return 结果集 */ private List simplePlateNumberHandle(List rabbitMqVehicles) { List resultList = new ArrayList<>(); // 倒序排列 rabbitMqVehicles.sort((o1, o2) -> (int) (o2.getPictime() - o1.getPictime())); // 时间游标 Long lastPictime = Long.MAX_VALUE; for (RabbitMQVehicle rabbitMqVehicle : rabbitMqVehicles) { if (null == rabbitMqVehicle || null == rabbitMqVehicle.getPictime()) { continue; } Long currentPictime = rabbitMqVehicle.getPictime(); // 更新时间游标 if (lastPictime - currentPictime > DISTINCT_TIME_INTERVAL) { lastPictime = currentPictime; LocusOrbitResultParams locusOrbitResultParams = new LocusOrbitResultParams(); locusOrbitResultParams.setId(rabbitMqVehicle.getId()); locusOrbitResultParams.setPlateNumber(rabbitMqVehicle.getVehicle_plate_hphm()); locusOrbitResultParams.setPictime(DateUtil.format(new Date(currentPictime), "yyyy-MM-dd HH:mm:ss")); locusOrbitResultParams.setLongitude(rabbitMqVehicle.getLongitude()); locusOrbitResultParams.setLatitude(rabbitMqVehicle.getLatitude()); locusOrbitResultParams.setSnapshotUrl(rabbitMqVehicle.getSnapshoturl()); resultList.add(locusOrbitResultParams); } } // 重新排序 resultList.sort((o1, o2) -> { if (DateUtil.parse(o1.getPictime()).getTime() - DateUtil.parse(o2.getPictime()).getTime() > 0) { return 1; } else if (DateUtil.parse(o1.getPictime()).getTime() - DateUtil.parse(o2.getPictime()).getTime() < 0) { return -1; } else { return 0; } }); return resultList; } /** * 轨迹分析页面列表 * * @param locusOrbitQueryParams 请求参数模型 * @param currentpage 页码 * @param pagevolume 页面容量 * @return 结果集 */ @Override public PageResult locusOrbitTableByPlateNumber(LocusOrbitQueryParams locusOrbitQueryParams, Integer currentpage, Integer pagevolume) { Criteria criteria = new Criteria(); Long startTime = locusOrbitQueryParams.getStartTime(); Long endTime = locusOrbitQueryParams.getEndTime(); if (null != startTime && null != endTime) { criteria.and("pictime").gte(startTime).lte(endTime); } else if (null != startTime) { criteria.and("pictime").gte(startTime); } else if (null != endTime) { criteria.and("pictime").lte(endTime); } criteria.and("vehicle_plate_hphm").is(locusOrbitQueryParams.getPlateNumber()); Query query = Query.query(criteria); query.fields().include("id"); query.fields().include("pictime"); query.fields().include("equipmentName"); query.fields().include("snapshoturl"); query.fields().include("vehicle_plate_hphm"); List rabbitMqVehicles = mongoTemplate.find(query.skip((currentpage - 1) * pagevolume).limit(pagevolume) .with(Sort.by(Sort.Order.asc("pictime"))), RabbitMQVehicle.class); List resultList = new ArrayList<>(); for (RabbitMQVehicle rabbitMqVehicle : rabbitMqVehicles) { LocusOrbitResultParams locusOrbitResultParams = new LocusOrbitResultParams(); if (null != rabbitMqVehicle) { locusOrbitResultParams.setId(rabbitMqVehicle.getId()); locusOrbitResultParams.setSnapshotUrl(rabbitMqVehicle.getSnapshoturl()); locusOrbitResultParams.setPlateNumber(rabbitMqVehicle.getVehicle_plate_hphm()); locusOrbitResultParams.setPictime(DateUtil.format(new Date(rabbitMqVehicle.getPictime()), "yyyy-MM-dd HH:mm:ss")); } resultList.add(locusOrbitResultParams); } long total = mongoTemplate.count(query, RabbitMQVehicle.class); // 总页数 int totalPage = (int) Math.ceil((double) total / pagevolume); return new PageResult<>(totalPage, resultList); } }