package com.objecteye.service.impl; import com.alibaba.fastjson.JSONObject; import com.objecteye.common.CommonResult; import com.objecteye.dao.MongoTemplates; import com.objecteye.entity.SyVehicleModel; import com.objecteye.entity.SyVehicleNjbNumber; import com.objecteye.entity.SyVehicleType; import com.objecteye.pojo.*; 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.ArrayList; import java.util.Date; import java.util.List; import java.util.Vector; import java.util.concurrent.CountDownLatch; import java.util.stream.Collectors; @Service public class VehicleCurrencyServiceImpl implements VehicleCurrencyService { @Autowired private MongoTemplate mongoTemplate; @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(); 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; } } } 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()); } //根据总条数获取到总页数 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) 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, 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, 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 = mongoTemplate.find(new Query(), SyVehicleModel.class).stream() .map(SyVehicleModel::getInitials).distinct().collect(Collectors.toList()); 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 = mongoTemplate.find(Query.query(Criteria.where("initals").is(initials)), SyVehicleModel.class) .stream().map(SyVehicleModel::getBrand).distinct().collect(Collectors.toList()); 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 = mongoTemplate.find(Query.query(Criteria.where("brand").is(brand)), SyVehicleModel.class) .stream().map(SyVehicleModel::getSubbrand).distinct().collect(Collectors.toList()); 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 = mongoTemplate.find(Query.query(Criteria.where("subbrand").is(subbrand)), SyVehicleModel.class) .stream().map(SyVehicleModel::getBirthday).distinct().collect(Collectors.toList()); 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 = mongoTemplate.find(new Query(), SyVehicleType.class) .stream().map(SyVehicleType::getName).distinct().collect(Collectors.toList()); 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 = mongoTemplate.find(new Query(), NameValue.class, "syVehicleColor") .stream().distinct().collect(Collectors.toList()); 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 = mongoTemplate .find(new Query(), NameValue.class, "syVehiclePlateType").stream().distinct().collect(Collectors.toList()); 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 = mongoTemplate.find(new Query(), SyVehicleNjbNumber.class) .stream().map(syVehicleNjbNumber -> String.valueOf(syVehicleNjbNumber.getNjbNumber())) .distinct().collect(Collectors.toList()); 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; } }