package com.objecteye.service.impl; import com.alibaba.fastjson.JSONObject; import com.objecteye.common.CommonResult; import com.objecteye.dao.MongoTemplates; import com.objecteye.mapper.SyVehicleModelMapper; import com.objecteye.pojo.*; import com.objecteye.service.AreaEquipmentService; import com.objecteye.service.VehicleCurrencyService; import com.objecteye.utils.*; 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.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.CountDownLatch; @Service public class VehicleCurrencyServiceImpl implements VehicleCurrencyService { @Autowired private MongoTemplate mongoTemplate; @Autowired private SyVehicleModelMapper syVehicleModelMapper; @Autowired private AreaEquipmentService areaEquipmentService; @Autowired public MongoTemplates mongoTemplates; @Autowired private RedisTemplate redisTemplate; @Autowired public HttpClientUtils httpClientUtils; @Autowired public VehicleDetailsUtils vehicleDetailsUtils; @Autowired public RabbitMQVehicleTools rabbitMQVehicleTools; @Autowired private CompareDistance compareDistance; private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /** * 多条件查询 * * @param vehicleCurrencyReques * @return */ @Override public JSONObject findByCondition(VehicleCurrencyReques vehicleCurrencyReques) { JSONObject data = new JSONObject(); int totalPage = 0; List vehicleCurrencyResultList = null; try { Query query = new Query(); //必须条件 Criteria c = new Criteria(); int currentpage = vehicleCurrencyReques.getCurrentpage(); int pagevolume = vehicleCurrencyReques.getPagevolume(); String hphm = vehicleCurrencyReques.getHphm(); Long starttime = vehicleCurrencyReques.getStartTime(); Long endtime = vehicleCurrencyReques.getEndTime(); int[] condition = vehicleCurrencyReques.getCondition(); int[] customspass = vehicleCurrencyReques.getCustomspass(); String cllx = vehicleCurrencyReques.getCllx(); Integer csys = vehicleCurrencyReques.getCsys(); String brand = vehicleCurrencyReques.getBrand(); String subbrand = vehicleCurrencyReques.getSubbrand(); String birthday = vehicleCurrencyReques.getBirthday(); Integer njbgs = vehicleCurrencyReques.getNjbgs(); Integer hplx = vehicleCurrencyReques.getHplx(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //模糊号牌检索 if (hphm != null && hphm.length() > 0) { c.and("vehicle_plate_hphm").regex(".*" + hphm + ".*"); } //时间段范围内 if (starttime != 0L && endtime != 0L) { c.and("pictime").gte(starttime).lte(endtime); } //车辆类型检索 if (cllx != null && cllx.length() > 0) { c.and("vehicle_recg_type").is(cllx); } //车身颜色检索 if (csys != null) { c.and("vehicle_color_index").is(csys); } //车辆型号检索 if (brand != null && brand.length() > 0) { //车辆品牌 c.and("vehicle_recg_brand").is(brand); } if (subbrand != null && subbrand.length() > 0) { //车辆品牌 c.and("vehicle_recg_subbrand").is(subbrand); } if (birthday != null && birthday.length() > 0) { //车辆出场日期 c.and("vehicle_recg_issue_year").is(birthday); } //年检标个数检索 if (njbgs != null) { //获取年检标个数 c.and("vehicle_pendant_detect_njbnumber").is(njbgs); } //号牌类型检索 if (hplx != null) { c.and("vehicleplatetype").is(hplx); } /*无号牌(nullhphm):1 污损号牌(stained):2 主驾驶安全带(driverbelt):3 副驾驶安全带(copilotbelt):4 主驾驶打电话(drivercall):5 主驾驶吸烟(driversmoke):6 是否苫盖(cover):7 有挂摆件(pendant): 8 有遮阳板(sunlouver): 9*/ //条件查询 if (condition != null && condition.length > 0) { for (int i : condition) { switch (i) { case 1: //无号牌 c.and("vehicle_plate_numScore").is(0); break; case 2: //污损号牌(stained) //当识别度为负数时认为是污损号牌 c.and("vehicleplatedetectscore").is(-2); //因目前sdk不支持污损号牌检测,所以此处略 break; case 3: //主驾驶未系安全带(driverbelt): c.and("vehicle_illegal_driver_person_status").is(1004); c.and("vehicle_illegal_driver_belt_status").is(1000); break; case 4: //副驾驶未系安全带(copilotbelt):4 c.and("vehicle_illegal_copilot_person_status").is(1004); c.and("vehicle_illegal_copilot_belt_status").is(1000); break; case 5: //主驾驶打电话(drivercall): c.and("vehicle_illegal_driver_person_status").is(1004); c.and("vehicle_illegal_driver_phone_status").is(1000); break; case 6: //主驾驶吸烟(driversmoke): c.and("vehicle_illegal_driver_person_status").is(1004); c.and("vehicle_illegal_driver_smoke_status").is(1000); break; case 7: //是否苫盖(cover): //因目前sdk不支持苫盖,所以此处略 break; case 8: //有挂摆件(pendant): c.and("vehicle_pendant_detect_gjexis").is(1); break; case 9: // 有遮阳板(sunlouver): c.and("vehicle_pendant_detect_zybexis").is(1); break; default: break; } } } //卡口范围 if (customspass != null && customspass.length > 0) { Set alleqids = new HashSet<>(); for (int value : customspass) { List epids = areaEquipmentService.findCaptureById(value); alleqids.addAll(epids); } //获取当前设备id c.and("deviceid").in(alleqids); } query.addCriteria(c); long totalNumber = mongoTemplate.count(query, VehicleCurrencyResult.class, "rabbitMQVehicle"); //按时间进行排序 query.with(Sort.by(Sort.Order.desc("pictime"))); // 分页 query.skip((currentpage - 1) * pagevolume).limit(pagevolume); vehicleCurrencyResultList = mongoTemplate.find(query, VehicleCurrencyResult.class, "rabbitMQVehicle"); //遍历list,转换时间 for (VehicleCurrencyResult vehicleCurrencyResult : vehicleCurrencyResultList) { vehicleCurrencyResult.setPhototime(sdf.format(Long.parseLong(vehicleCurrencyResult.getPhototime()))); //改变原有的全景图为现在的快照图 此处返回快照图的绝对路径 vehicleCurrencyResult.setPicurl(vehicleCurrencyResult.getSnapshoturl()); /*//获取抓拍图的base64 int[] vehicle_detect_syRectParam = vehicleCurrencyResult.getVehicle_detect_syRectParam(); String snapshotBase64 = vehicleDetailsUtils.picToSnapshot(vehicleCurrencyResult.getPicurl(), vehicle_detect_syRectParam[1], vehicle_detect_syRectParam[2], vehicle_detect_syRectParam[3], vehicle_detect_syRectParam[0]); //将抓拍图的base64放入到返回结果中 vehicleCurrencyResult.setSnapshot(snapshotBase64);*/ //此处是返回快照图的base64 } //根据总条数获取到总页数 totalPage = (int) Math.ceil(((double) totalNumber) / pagevolume); data.put("total", totalPage); data.put("row", vehicleCurrencyResultList); } catch (Exception e) { data.put("total", totalPage); data.put("row", vehicleCurrencyResultList); e.printStackTrace(); } return data; } @Override public CommonResult findVehicleByPic(int number, double threshold, int currentpage, int pagevolume, MultipartFile picfile, Long starttime, Long endtime, int[] customspass) throws InterruptedException { //封装结果的对象 if (picfile == null) { return CommonResult.success(201, "图片为空", null); } String vehicleInfoByBase64 = httpClientUtils.multiToVehicle(picfile); JSONObject dataJson = JSONObject.parseObject(vehicleInfoByBase64).getJSONObject("result"); List rabbitMQVehicles = rabbitMQVehicleTools.sdkToRabbitVehicle(dataJson); //获取到用户选中的车辆 int size = rabbitMQVehicles.size(); if (number < size) { RabbitMQVehicle rabbitMqVehicle = rabbitMQVehicles.get(number); List vehcieListBy = mongoTemplates.getVehcieListBy(new VehicleCondition(0, 0, rabbitMqVehicle.getVehicle_plate_hphm(), null, starttime, endtime, customspass, null, rabbitMqVehicle.getVehicle_color_index(), rabbitMqVehicle.getVehicle_recg_issue_year(), rabbitMqVehicle.getVehicle_recg_brand(), rabbitMqVehicle.getVehicle_recg_type(), rabbitMqVehicle.getVehicle_recg_subbrand())); //获取该车辆的特征信息 double[] currentFeature = rabbitMqVehicle.getVehicle_fea_feature(); double currentFea = compareDistance.getDistance(currentFeature); Vector pvc = new Vector<>(); int arrCount = 1000; int threadNumber = (int) Math.ceil((double) vehcieListBy.size() / arrCount); final CountDownLatch countDownLatch = new CountDownLatch(threadNumber); for (int i = 0; i < threadNumber; i++) { int index = i; new Thread(() -> { int fromIndex = index * arrCount; int toIndex = fromIndex + arrCount; toIndex = Math.min(toIndex, vehcieListBy.size()); for (RabbitMQVehicle rmqv : vehcieListBy.subList(fromIndex, toIndex)) { double[] dbFeature = (double[]) redisTemplate.opsForHash().get(GlobalUtil.VEHICLE_FEATURE, rmqv.getId()); if (dbFeature != null) { //进行比对 double dbFea = (double) redisTemplate.opsForHash().get(GlobalUtil.VEHICLE_FEATURE_DISTANCE, rmqv.getId()); double similar = compareDistance.simDistance(currentFeature, currentFea, dbFeature, dbFea); if (threshold <= similar) { if (similar > 1) { similar = 1.00; } PicVehicleCompare picVehicleCompare = new PicVehicleCompare(); picVehicleCompare.setSimilar(similar); picVehicleCompare.setRabbitMQVehicle(rmqv); pvc.add(picVehicleCompare); } } } countDownLatch.countDown(); }).start(); } countDownLatch.await(); //对row进行排序 pvc.sort((o1, o2) -> { if (o2.getSimilar() == o1.getSimilar()) { return 0; } else { double similar = o2.getSimilar(); double similar1 = o1.getSimilar(); return similar > similar1 ? 1 : -1; } }); //对row进行分页查询 ArrayList picVehicleComparesNew = new ArrayList<>(); int startNumber = (currentpage - 1) * pagevolume; int endNumber = startNumber + pagevolume; endNumber = pagevolume > (pvc.size() - startNumber) ? pvc.size() : endNumber; for (int m = startNumber; m < endNumber; m++) { PicVehicleCompare picVehicleCompare = pvc.get(m); picVehicleComparesNew.add(picVehicleCompare); } //获取total(总条数) int total = pvc.size(); //根据总条数获取总页数 int totalPage = (int) Math.ceil(((double) total) / pagevolume); ArrayList picVehicleRows = new ArrayList<>(); for (PicVehicleCompare next : picVehicleComparesNew) { //获取id RabbitMQVehicle rabbitMqVehicle1 = next.getRabbitMQVehicle(); // 新方法,如果不需要四舍五入,可以使用RoundingMode.DOWN double similar = next.getSimilar(); String picurl = rabbitMqVehicle1.getPicurl(); //获取到快照路径 String snapshoturl = rabbitMqVehicle1.getSnapshoturl(); String bg = String.format("%.3f", similar); //因为需要将快照图的值给picurl所以需要下面的返回方式 PicVehicleRow picVehicleRow = new PicVehicleRow(rabbitMqVehicle1.getId(), rabbitMqVehicle1.getRecordid(), rabbitMqVehicle1.getVehicle_plate_hphm(), snapshoturl, picurl, bg, rabbitMqVehicle1.getEquipmentName(), simpleDateFormat.format(new Date(rabbitMqVehicle1.getPictime()))); picVehicleRows.add(picVehicleRow); } PicVehicleDataResult picVehicleDataResult = new PicVehicleDataResult(totalPage, picVehicleRows); if (picVehicleDataResult.getRow().size() <= 0) { return CommonResult.success(201, "没有查询到任何数据", null); } else { return CommonResult.success(picVehicleDataResult); } } return CommonResult.success(202, "没有符合要求的数据", null); } /** * 查询所有的车辆型号首字母 * * @return */ @Override public CommonResult> selectDisplayForInitials() { CommonResult> commonResult = null; try { List initialsArr = syVehicleModelMapper.selectDisplayForInitials(); commonResult = returnCommonResult(initialsArr); } catch (Exception e) { commonResult = CommonResult.success(null, "数据查询失败"); e.printStackTrace(); } return commonResult; } /** * 根据车辆首字母查询所有的车辆品牌 * * @param initials * @return */ @Override public CommonResult> selectDisplayForBrand(String initials) { CommonResult> commonResult = null; try { List brandArr = syVehicleModelMapper.selectDisplayForBrand(initials); commonResult = returnCommonResult(brandArr); } catch (Exception e) { commonResult = CommonResult.success(null, "数据查询失败"); e.printStackTrace(); } return commonResult; } /** * 根据车辆车辆品牌查询所有的车辆子品牌 * * @param brand * @return */ @Override public CommonResult> selectDisplayForSubbrand(String brand) { CommonResult> commonResult = null; try { List subbrandArr = syVehicleModelMapper.selectDisplayForSubbrand(brand); commonResult = returnCommonResult(subbrandArr); } catch (Exception e) { commonResult = CommonResult.success(null, "数据查询失败"); e.printStackTrace(); } return commonResult; } /** * 根据车辆子品牌查询所有的车辆年限 * * @param subbrand * @return */ @Override public CommonResult> selectDisplayForBirthday(String subbrand) { CommonResult> commonResult = null; try { List birthdayArr = syVehicleModelMapper.selectDisplayForBirthday(subbrand); commonResult = returnCommonResult(birthdayArr); } catch (Exception e) { commonResult = CommonResult.success(null, "数据查询失败"); e.printStackTrace(); } return commonResult; } /** * 返回所有车辆类型列表 * * @return */ @Override public CommonResult> displayVehicleTypeList() { CommonResult> commonResult = null; try { List displayVehicleTypeList = syVehicleModelMapper.displayVehicleTypeList(); commonResult = returnCommonResult(displayVehicleTypeList); } catch (Exception e) { commonResult = CommonResult.success(null, "数据查询失败"); e.printStackTrace(); } return commonResult; } /** * 返回所有车辆车身颜色列表 * * @return */ @Override public CommonResult> displayVehicleColorList() { CommonResult> commonResult = null; try { List displayVehicleColorList = syVehicleModelMapper.displayVehicleColorList(); commonResult = returnCommonResult1(displayVehicleColorList); } catch (Exception e) { commonResult = CommonResult.success(null, "数据查询失败"); e.printStackTrace(); } return commonResult; } /** * 返回所有车辆号牌类型列表 * * @return */ @Override public CommonResult> displayVehiclePlateTypeList() { CommonResult> commonResult = null; try { List displayVehiclePlateTypeList = syVehicleModelMapper.displayVehiclePlateTypeList(); commonResult = returnCommonResult1(displayVehiclePlateTypeList); } catch (Exception e) { commonResult = CommonResult.success(null, "数据查询失败"); e.printStackTrace(); } return commonResult; } /** * 返回所有车辆年检标个数列表 * * @return */ @Override public CommonResult> displayVehicleNjbNumberList() { CommonResult> commonResult = null; try { List displayVehicleNjbNumberList = syVehicleModelMapper.displayVehicleNjbNumberList(); commonResult = returnCommonResult(displayVehicleNjbNumberList); } catch (Exception e) { commonResult = CommonResult.success(null, "数据查询失败"); e.printStackTrace(); } return commonResult; } public CommonResult> returnCommonResult(List list) { CommonResult> commonResult; if (list.size() <= 0) { commonResult = CommonResult.success(201, "没有查询到任何数据", null); } else { commonResult = CommonResult.success(list); } return commonResult; } public CommonResult> returnCommonResult1(List list) { CommonResult> commonResult; if (list.size() <= 0) { commonResult = CommonResult.success(201, "没有查询到任何数据", null); } else { commonResult = CommonResult.success(list); } return commonResult; } }