package com.objecteye.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.objecteye.dao.MongoTemplates; import com.objecteye.entity.*; import com.objecteye.exception.CustomXException; import com.objecteye.pojo.*; import com.objecteye.service.SpecialtyServices; import com.objecteye.utils.*; import org.apache.commons.codec.binary.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.CountDownLatch; @Service public class SpecialtyServicesImpl implements SpecialtyServices { private final Logger logger = LoggerFactory.getLogger(SpecialtyServicesImpl.class); @Value("${requestBase64}") private String requestBase64; @Autowired private CompareDistance compareDistance; @Autowired private VehicleEngine vehicleEngine; @Autowired public HttpClientUtils httpClientUtils; @Autowired public RabbitMQVehicleTools rabbitMQVehicleTools; @Autowired public MongoTemplates mongoTemplates; @Autowired private VehicleDetailsUtils vehicleDetailsUtils; @Autowired private RedisTemplate redisTemplate; private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Override public VehicleInfoRes findByCondition(VehicleCondition vehicleCondition) { return null; } @Override public JSONObject findByPic(int number, double threshold, int currentpage, int pagevolume, MultipartFile picfile, Long starttime, Long endtime, Integer vehicle_special_type_number) throws InterruptedException { //封装结果的对象 JSONObject result = new JSONObject(); if (picfile == null) { result.put("code", 201); result.put("message", "没有符合要求的数据"); result.put("data", null); return result; } String vehicleInfoByBase64 = 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, vehicle_special_type_number, 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 rabbitMQVehicle : vehcieListBy.subList(fromIndex, toIndex)) { double[] dbFeature = (double[]) redisTemplate.opsForHash().get(GlobalUtil.VEHICLE_FEATURE, rabbitMQVehicle.getId()); if (dbFeature != null) { //进行比对 double dbFea = (double) redisTemplate.opsForHash().get(GlobalUtil.VEHICLE_FEATURE_DISTANCE, rabbitMQVehicle.getId()); double similar = compareDistance.simDistance(currentFeature, currentFea, dbFeature, dbFea); if (threshold <= similar) { similar = (double) Math.round(similar * 100) / 100; if (similar >= 1) { similar = 1; } PicVehicleCompare picVehicleCompare = new PicVehicleCompare(); picVehicleCompare.setSimilar(similar); picVehicleCompare.setRabbitMQVehicle(rabbitMQVehicle); 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进行分页查询 List picVehicleComparesNew = UserTools.getPagedResultByBaseList(pvc, currentpage, pagevolume); //总页数 int totalPage = UserTools.getPageTotalByBaseList(pvc, pagevolume); JSONObject data = new JSONObject(); //获取row数据 JSONArray row = new JSONArray(); for (PicVehicleCompare next : picVehicleComparesNew) { JSONObject rowData = new JSONObject(); //获取id RabbitMQVehicle rabbitMqVehicle1 = next.getRabbitMQVehicle(); rowData.put("id", rabbitMqVehicle1.getId()); rowData.put("hphm", rabbitMqVehicle1.getVehicle_plate_hphm()); rowData.put("phototime", simpleDateFormat.format(new Date(rabbitMqVehicle1.getPictime()))); rowData.put("recordid", rabbitMqVehicle1.getRecordid()); // 新方法,如果不需要四舍五入,可以使用RoundingMode.DOWN double similar = next.getSimilar(); rowData.put("similar", String.format("%.3f", similar)); //添加snapshoturl的值 //此处将原来的全景图url体换成了快照图绝对路径 rowData.put("picurl", rabbitMqVehicle1.getSnapshoturl()); row.add(rowData); } data.put("total", totalPage); data.put("row", row); if (pvc.size() > 0 && row.size() > 0) { result.put("code", 200); result.put("message", "操作成功"); result.put("data", data); } else { result.put("code", 201); result.put("message", "没有符合要求的数据"); data.put("total", pvc.size()); data.put("row", row); result.put("data", data); } return result; } result.put("code", 201); result.put("message", "没有符合要求的数据"); result.put("data", null); return result; } //通过转Base64的方式运行 @Override public JSONObject findCoordinateByPic(MultipartFile picfile, Integer vehicleSpecialTypeNumber) { JSONObject jsonObject = new JSONObject(); try { String base64 = httpClientUtils.MultipartFileToBase64(picfile); BufferedImage bufferedImage = changeBase64StringtoImage(base64); int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight(); JSONObject tpkg = new JSONObject(); tpkg.put("width", width); tpkg.put("height", height); //获取车辆信息 String vehicleInfoByBase64 = multiToVehicle(picfile); JSONArray clxx = null; if (vehicleInfoByBase64 != null) { JSONObject dataJson = JSONObject.parseObject(vehicleInfoByBase64).getJSONObject("result"); List rabbitMQVehicles = rabbitMQVehicleTools.sdkToRabbitVehicle(dataJson); int size = rabbitMQVehicles.size(); clxx = new JSONArray(); for (int i = 0; i < size; i++) { RabbitMQVehicle rabbitMQVehicle = rabbitMQVehicles.get(i); int vehicleSpecialType = rabbitMQVehicle.getVehicle_special_type(); if (vehicleSpecialTypeNumber == -1 || vehicleSpecialType == vehicleSpecialTypeNumber) { int[] vehicleDetectSyrectparam = rabbitMQVehicle.getVehicle_detect_syRectParam(); JSONObject clxxOne = new JSONObject(); clxxOne.put("gcxh", i); clxxOne.put("height", vehicleDetectSyrectparam[0]); clxxOne.put("left", vehicleDetectSyrectparam[1]); clxxOne.put("top", vehicleDetectSyrectparam[2]); clxxOne.put("width", vehicleDetectSyrectparam[3]); clxx.add(clxxOne); } } } JSONObject data = new JSONObject(); data.put("tpkg", tpkg); data.put("clxx", clxx); if (clxx != null && clxx.size() > 0) { jsonObject.put("code", 200); jsonObject.put("message", "success"); jsonObject.put("data", data); } else { jsonObject.put("code", 201); String message = null; if (vehicleSpecialTypeNumber == 1) { message = "图片中没有检索到危化品车"; } else if (vehicleSpecialTypeNumber == 2) { message = "图片中没有检索到渣土车"; } else if (vehicleSpecialTypeNumber == 0) { message = "图片中没有检索到货车"; } else { message = "图片中没有检索到通用车辆"; } jsonObject.put("message", message); jsonObject.put("data", data); } } catch (Exception e) { jsonObject.put("code", 202); jsonObject.put("message", "查询失败"); jsonObject.put("data", ""); e.printStackTrace(); } return jsonObject; } /** * 通过车辆id查询车辆信息 * * @param id * @return */ @Override public JSONObject findById(String id) { JSONObject jsonObject = new JSONObject(); try { RabbitMQVehicle rabbitMQVehicle = mongoTemplates.findById(RabbitMQVehicle.class, id); //将RabbitMQVehicle识别为可读信息 RabbitMQInfo rabbitMQInfo = rabbitMQVehicleTools.rabbitMQToRabbitInfo(rabbitMQVehicle); //=============== if (rabbitMQVehicle != null) { jsonObject.put("code", 200); jsonObject.put("message", "success"); jsonObject.put("data", rabbitMQInfo); } else { jsonObject.put("code", 201); jsonObject.put("message", "没有符合要求的数据"); jsonObject.put("data", rabbitMQInfo); } } catch (Exception e) { jsonObject.put("code", 202); jsonObject.put("message", "请检查数据准确性"); jsonObject.put("data", ""); e.printStackTrace(); } return jsonObject; } //将multipart文件转成车型 public String multiToVehicle(MultipartFile picfile) { String vehicleInfoByBase64 = null; try { String base64 = httpClientUtils.MultipartFileToBase64(picfile); vehicleInfoByBase64 = vehicleEngine.getVehicleInfoByBase64(base64); } catch (Exception e) { e.printStackTrace(); } return vehicleInfoByBase64; } /** * @param base64String base64码字符串 **/ public BufferedImage changeBase64StringtoImage(String base64String) { BufferedImage buffer = null; try { byte[] bytes = Base64.decodeBase64(base64String); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); buffer = ImageIO.read(bais); } catch (IOException e) { e.printStackTrace(); } return buffer; } /** * 通过过车序号查询车辆的信息 * * @param gcxh * @param picfile * @return */ @Override public JSONObject findByGcxh1(int gcxh, MultipartFile picfile) { JSONObject jsonObject = new JSONObject(); try { //获取到车型图片的base64值 String base64 = httpClientUtils.MultipartFileToBase64(picfile); //通过base64结合sdk算法获取到车型的数字化信息 String vehicleInfoByBase64 = vehicleEngine.getVehicleInfoByBase64(base64); JSONObject vehicleSDKJsonData = JSONObject.parseObject(vehicleInfoByBase64); //将base64封装为ArrayList ArrayList vehicleDetailsList = vehicleDetailsUtils.base64ToVehicleDetailsArr(vehicleSDKJsonData); if (vehicleDetailsList != null && vehicleDetailsList.size() > 0) { VehicleDetails vehicleDetails = vehicleDetailsList.get(gcxh); vehicleDetails.setVehicle_fea_res_feature(null); jsonObject.put("code", 200); jsonObject.put("message", "success"); jsonObject.put("data", vehicleDetails); } else { jsonObject.put("code", 201); jsonObject.put("message", "空值"); jsonObject.put("data", null); } } catch (Exception e) { jsonObject.put("code", 202); jsonObject.put("message", "数据不符合正规的json格式或者异常"); jsonObject.put("data", null); e.printStackTrace(); } return jsonObject; } @Override public Map getColorAndBrand(Map map) { String image = map.get("image").toString(); Object request_id = map.get("request_id"); if (!GlobalUtil.checkBase64(image)) { throw new CustomXException(CustomInfoCollections.IMAGE_PARSE_EXCEPTION.getMsg(), CustomInfoCollections.IMAGE_PARSE_EXCEPTION.getCode()); } String vehicleInfoByBase64 = vehicleEngine.getVehicleInfoByBase64(image); ResponseParam responseParam = JSON.parseObject(vehicleInfoByBase64, ResponseParam.class); String s1 = JSON.toJSONString(responseParam.getResult()); VehicleAnalysisResultParam vehicleAnalysisResultParam = JSON.parseObject(s1, VehicleAnalysisResultParam.class); VehicleInfoParam[] info = vehicleAnalysisResultParam.getInfo(); HashMap stringObjectHashMap = new HashMap<>(16); if (info == null) { throw new CustomXException(CustomInfoCollections.DETECT_NOT_FOUND.getMsg(), CustomInfoCollections.DETECT_NOT_FOUND.getCode()); } for (VehicleInfoParam vehicleInfoParam : info) { ResultMsg resultMsg = new ResultMsg(); VehicleColorResultParam vehicle_color_res = vehicleInfoParam.getVehicle_color_res(); int index = vehicle_color_res.getIndex(); float score = vehicle_color_res.getScore(); if (score >= 0.7) { String vehicleColor = RelationMappingUtil.getVehicleColor(index); resultMsg.setVehicle_color(vehicleColor); } else { resultMsg.setVehicle_color("检测失败"); } StringBuilder sb = new StringBuilder(); VehicleRecognizeResultParam vehicle_recg_res = vehicleInfoParam.getVehicle_recg_res(); float name_score = vehicle_recg_res.getName_score(); if (name_score < 0.7) { resultMsg.setVehicle_brand("检测失败"); } String vehicle_recg_brand = vehicle_recg_res.getVehicle_brand(); sb.append(vehicle_recg_brand); String vehicle_recg_subbrand = vehicle_recg_res.getVehicle_subbrand(); if (vehicle_recg_subbrand != null) { sb.append("-").append(vehicle_recg_subbrand); } String vehicle_recg_issue_year = vehicle_recg_res.getVehicle_issue_year(); if (vehicle_recg_issue_year != null) { sb.append("-").append(vehicle_recg_issue_year); } resultMsg.setVehicle_brand(sb.toString()); stringObjectHashMap.put("message", CustomInfoCollections.SUCCESS.getMsg()); stringObjectHashMap.put("rtn", CustomInfoCollections.SUCCESS.getCode()); stringObjectHashMap.put("request_id", request_id); stringObjectHashMap.put("data", resultMsg); } return stringObjectHashMap; } /** * 通过过车序号查询车辆的信息 * * @param gcxh * @param picfile * @return */ @Override public JSONObject findByGcxh(int gcxh, MultipartFile picfile) { JSONObject jsonObject = new JSONObject(); String vehicleInfoByBase64 = null; try { //获取车辆信息 vehicleInfoByBase64 = multiToVehicle(picfile); if (vehicleInfoByBase64 != null) { RabbitMQInfo rabbitMQInfo = null; JSONObject dataJson = JSONObject.parseObject(vehicleInfoByBase64).getJSONObject("result"); int count = dataJson.containsKey("count") ? dataJson.getInteger("count") : 0; if (count > 0) { //将dataJson转成RabbitMQVehicle RabbitMQVehicle rabbitMQVehicle = rabbitMQVehicleTools.sdkToOnlyVehicle(dataJson.getJSONArray("info").getJSONObject(gcxh)); //将RabbitMQVehicle识别为可读信息 rabbitMQInfo = rabbitMQVehicleTools.rabbitMQToRabbitInfo(rabbitMQVehicle); } jsonObject.put("code", 200); jsonObject.put("message", "success"); jsonObject.put("data", rabbitMQInfo); } } catch (Exception e) { jsonObject.put("code", 201); jsonObject.put("message", "没有查询到相关车辆数据"); jsonObject.put("data", ""); e.printStackTrace(); } return jsonObject; } }