| | |
| | | import com.ruoyi.common.constant.CacheConstants; |
| | | import com.ruoyi.common.core.redis.RedisCache; |
| | | import com.ruoyi.common.utils.DateUtils; |
| | | import com.ruoyi.common.utils.DictUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.constant.CamPriority; |
| | | import com.ruoyi.device.external.domain.ArdEquipExternal; |
| | | import com.ruoyi.device.external.mapper.ArdEquipExternalMapper; |
| | | import com.ruoyi.utils.tools.ArdTool; |
| | |
| | | import com.ruoyi.system.service.ISysConfigService; |
| | | import com.ruoyi.utils.tube.GeoPoint; |
| | | import com.ruoyi.utils.tube.TubeTools; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.scheduling.annotation.Async; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | import javax.annotation.Resource; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | import java.util.concurrent.PriorityBlockingQueue; |
| | | import java.util.concurrent.ExecutionException; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | | |
| | | |
| | | /** |
| | | * @Description: 全局报警业务 |
| | |
| | | @Resource |
| | | private QueueManager queueManager; |
| | | //endregion |
| | | //每个点位未引导次数 |
| | | private Map<String, Integer> unGuideCountMap = new HashMap<>(); |
| | | |
| | | /** |
| | | * @描述 查询所有报警的当前数量 |
| | |
| | | } |
| | | } |
| | | |
| | | private Map<String,Integer> guideCountMap=new HashMap<>(); |
| | | /** |
| | | * @描述 异步处理接收的报警 |
| | | * @参数 [topic, message] |
| | |
| | | //region 处理通用光电报警 |
| | | ArdAlarmCamera ardAlarmCamera = JSONObject.parseObject(message, ArdAlarmCamera.class); |
| | | ardAlarmCamera.setId(IdUtils.simpleUUID()); |
| | | ardAlarmCamera.setCreateTime(new Date()); |
| | | int aac = ardAlarmCameraMapper.insertArdAlarmCamera(ardAlarmCamera); |
| | | if (aac > 0) { |
| | | log.debug("camera入库成功:" + ardAlarmCamera); |
| | |
| | | break; |
| | | case "radar": |
| | | //region 处理雷达报警 |
| | | // 开始时间 |
| | | long stime = System.currentTimeMillis(); |
| | | RadarAlarmData radarAlarmData = JSONObject.parseObject(message, RadarAlarmData.class); |
| | | List<ArdAlarmRadar> ardAlarmRadars = radarAlarmData.getArdAlarmRadars(); |
| | | for (ArdAlarmRadar ardAlarmRadar : ardAlarmRadars) { |
| | |
| | | ardAlarmRadar.setName(ardAlarmRadar.getName() + "(" + radarAlarmData.getRadarName() + ")");//报警点名称 |
| | | ardAlarmRadar.setCreateTime(new Date());//接收时间 |
| | | |
| | | String alarmType = ""; |
| | | switch (ardAlarmRadar.getAlarmType()) { |
| | | case "运动目标检测": |
| | | alarmType = "sys_radar_move"; |
| | | String alarmType = "sys_radar_move"; |
| | | break; |
| | | case "热源检测": |
| | | alarmType = "sys_radar_fire"; |
| | |
| | | } |
| | | break; |
| | | } |
| | | //入库 |
| | | ardAlarmRadarMapper.insertArdAlarmRadar(ardAlarmRadar); |
| | | |
| | | } |
| | | //按兴趣点去重,然后按引导逻辑进行引导入队 |
| | | ardAlarmRadars = ardAlarmRadars.stream() |
| | | .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new java.util.TreeSet<>(java.util.Comparator.comparing(ArdAlarmRadar::getName))), ArrayList::new)); |
| | | for(ArdAlarmRadar ardAlarmRadar : ardAlarmRadars) |
| | | { |
| | | //遍历报警数据进行引导 |
| | | if (StringUtils.isNull(ardAlarmRadar.getLongitude()) || StringUtils.isNull(ardAlarmRadar.getLatitude())) { |
| | | //坐标为空不引导 |
| | | continue; |
| | | } |
| | | double[] coordinate = new double[]{ardAlarmRadar.getLongitude(), ardAlarmRadar.getLatitude()};//报警坐标 |
| | | //从redis中取出当前报警点的5分钟内是否有引导 |
| | | ArdAlarmRadar AlarmRadar = redisCache.getCacheObject("global_alarm:" + ardAlarmRadar.getName());//从redis中取出最新引导的报警数据 |
| | | if (AlarmRadar == null) { |
| | | //5分钟内redis中没有数据,说明5分钟内没有引导数据 |
| | | ardAlarmRadar.setGuideFlag(1); |
| | | //将引导数据写入redis 设置5分钟过期 |
| | | redisCache.setCacheObject("global_alarm:" + ardAlarmRadar.getName(), ardAlarmRadar, 5, TimeUnit.MINUTES);//引导数据写入redis |
| | | unGuideCountMap.put(ardAlarmRadar.getName(), 0); |
| | | //引导入队 |
| | | radarGuide(radarAlarmData.getRadarId(), ardAlarmRadar.getName(), ardAlarmRadar.getAlarmType(), ardAlarmRadar.getCreateTime(), coordinate); |
| | | |
| | | //判断当前报警点5分钟内是否已引导 |
| | | ardAlarmRadar.setGuideFlag(1); |
| | | // ArdAlarmRadar AlarmRadar = ardAlarmRadarMapper.getArdAlarmRadarWithGuide(ardAlarmRadar); |
| | | ArdAlarmRadar AlarmRadar = redisCache.getCacheObject("global_alarm:"+ardAlarmRadar.getName());//从redis中取出最新引导的报警数据 |
| | | if (AlarmRadar==null) { |
| | | //5分钟内未引导直接入库 |
| | | ardAlarmRadarMapper.insertArdAlarmRadar(ardAlarmRadar); |
| | | redisCache.setCacheObject("global_alarm:"+ardAlarmRadar.getName(),ardAlarmRadar,5, TimeUnit.MINUTES);//引导数据写入redis |
| | | guideCountMap.put(ardAlarmRadar.getName(),0); |
| | | //获取雷达所在塔上的大光电 |
| | | String cameraIdWithTower = ardAlarmRadarMapper.getCameraByRadar(radarAlarmData.getRadarId()); |
| | | if (StringUtils.isNotNull(cameraIdWithTower) && StringUtils.isNotEmpty(cameraIdWithTower)) { |
| | | log.info("获取到雷达塔上的光电:" + cameraIdWithTower); |
| | | //如果雷达塔上有光电 |
| | | messagesEnqueued(cameraIdWithTower, uuid, alarmType, ardAlarmRadar.getCreateTime(), 1, 1, coordinate); |
| | | } |
| | | //获取报警点关联的大光电 |
| | | ArdAlarmpointsWell ardAlarmpointsWell = ardAlarmpointsWellMapper.selectArdAlarmpointsWellByWellId(alarmpointName); |
| | | if (StringUtils.isNotNull(ardAlarmpointsWell) && StringUtils.isNotEmpty(ardAlarmpointsWell.getCameraId())) { |
| | | String cameraId = ardAlarmpointsWell.getCameraId(); |
| | | if (cameraId.equals(cameraIdWithTower)) { |
| | | return; |
| | | } |
| | | log.info("获取到报警点关联的光电:" + cameraId); |
| | | //如果报警点关联了光电 |
| | | messagesEnqueued(cameraId, uuid, alarmType, ardAlarmRadar.getCreateTime(), 1, 2, coordinate); |
| | | } |
| | | } else { |
| | | //获取当前报警点的未引导次数 |
| | | Integer count = guideCountMap.get(ardAlarmRadar.getName()); |
| | | if(count!=null) |
| | | { |
| | | if(count>2) |
| | | { |
| | | //5分钟内redis中有数据,说明5分钟内有引导数据,获取当前报警点的未引导次数 |
| | | Integer count = unGuideCountMap.get(ardAlarmRadar.getName()); |
| | | if (count != null) { |
| | | if (count > 2) { |
| | | //未引导次数3次后进行引导 |
| | | ardAlarmRadar.setGuideFlag(1); |
| | | redisCache.setCacheObject("global_alarm:"+ardAlarmRadar.getName(),ardAlarmRadar,5, TimeUnit.MINUTES);//引导数据写入redis |
| | | count=0; |
| | | |
| | | //获取雷达所在塔上的大光电 |
| | | String cameraIdWithTower = ardAlarmRadarMapper.getCameraByRadar(radarAlarmData.getRadarId()); |
| | | if (StringUtils.isNotNull(cameraIdWithTower) && StringUtils.isNotEmpty(cameraIdWithTower)) { |
| | | log.info("获取到雷达塔上的光电:" + cameraIdWithTower); |
| | | //如果雷达塔上有光电 |
| | | messagesEnqueued(cameraIdWithTower, uuid, alarmType, ardAlarmRadar.getCreateTime(), count, 1, coordinate); |
| | | } |
| | | //获取报警点关联的大光电 |
| | | ArdAlarmpointsWell ardAlarmpointsWell = ardAlarmpointsWellMapper.selectArdAlarmpointsWellByWellId(alarmpointName); |
| | | if (StringUtils.isNotNull(ardAlarmpointsWell) && StringUtils.isNotEmpty(ardAlarmpointsWell.getCameraId())) { |
| | | String cameraId = ardAlarmpointsWell.getCameraId(); |
| | | if (cameraId.equals(cameraIdWithTower)) { |
| | | return; |
| | | } |
| | | log.info("获取到报警点关联的光电:" + cameraId); |
| | | //如果报警点关联了光电 |
| | | messagesEnqueued(cameraId, uuid, alarmType, ardAlarmRadar.getCreateTime(), count, 2, coordinate); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | //将引导数据写入redis 设置5分钟过期 |
| | | redisCache.setCacheObject("global_alarm:" + ardAlarmRadar.getName(), ardAlarmRadar, 5, TimeUnit.MINUTES); |
| | | count = 0; |
| | | //引导入队 |
| | | radarGuide(radarAlarmData.getRadarId(), ardAlarmRadar.getName(), ardAlarmRadar.getAlarmType(), ardAlarmRadar.getCreateTime(), coordinate); |
| | | } else { |
| | | ardAlarmRadar.setGuideFlag(0); |
| | | count++; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | } else { |
| | | ardAlarmRadar.setGuideFlag(0); |
| | | count=0; |
| | | count = 0; |
| | | } |
| | | guideCountMap.put(ardAlarmRadar.getName(),count); |
| | | ardAlarmRadarMapper.insertArdAlarmRadar(ardAlarmRadar); |
| | | unGuideCountMap.put(ardAlarmRadar.getName(), count); |
| | | //更新 |
| | | ardAlarmRadarMapper.updateArdAlarmRadar(ardAlarmRadar); |
| | | } |
| | | // 结束时间 |
| | | long etime = System.currentTimeMillis(); |
| | | // 计算执行时间 |
| | | log.info("雷达报警处理时长:"+(etime-stime)+"毫秒"); |
| | | } |
| | | |
| | | //endregion |
| | | break; |
| | | case "external": |
| | |
| | | log.info("相机:" + cameraId + "未开启报警引导功能"); |
| | | return; |
| | | } |
| | | |
| | | SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); |
| | | GuideTask guideTask = new GuideTask(); |
| | | //相机ID |
| | |
| | | //接收时间 |
| | | guideTask.setReceiveTime(fmt.format(receiveTime)); |
| | | //报警优先级(通过优先级字典) |
| | | Integer priority = CamPriority.priorityMap.get(alarmType); |
| | | guideTask.setPriority(priority); |
| | | String priority = DictUtils.getDictValue("cameras_priority", alarmType); |
| | | if (StringUtils.isEmpty(priority)) { |
| | | log.debug("未匹配到优先级,请检查优先级字典配置"); |
| | | return; |
| | | } |
| | | guideTask.setPriority(Integer.valueOf(priority)); |
| | | //报警次数 |
| | | guideTask.setNum(num); |
| | | //录像存储位置 |
| | |
| | | private Boolean IsEnableGuide(String cameraId) { |
| | | boolean enabled = false; |
| | | ArdCameras ardCameras = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId); |
| | | if(ardCameras!=null) { |
| | | if (ardCameras != null) { |
| | | if (ardCameras.getCamAlarmGuideEnable().equals(1)) { |
| | | enabled = true; |
| | | } |
| | |
| | | */ |
| | | private String getNearbyCamera(double[] targetPosition) { |
| | | String minDistanceCameraId = ""; |
| | | //获取所有大光电 |
| | | List<ArdCameras> ardCamerasList = ardCamerasMapper.selectArdCamerasList(new ArdCameras("1")); |
| | | //统计所有大光电可视范围内与报警点的距离 |
| | | Map<String, Double> distanceMap = new HashMap<>(); |
| | | Map<String, Integer> guideMap = new HashMap<>(); |
| | | for (ArdCameras camera : ardCamerasList) { |
| | | double[] camPosition = new double[]{camera.getLongitude(), camera.getLatitude()}; |
| | | double distance = GisTool.getDistance(targetPosition, camPosition); |
| | | if (distance != 0.0 && distance <= camera.getCamMaxVisibleDistance()) { |
| | | distanceMap.put(camera.getId(), distance); |
| | | if (StringUtils.isNull(camera.getCamAlarmGuideEnable())) { |
| | | camera.setCamAlarmGuideEnable(0); |
| | | try { |
| | | //获取所有大光电 |
| | | List<ArdCameras> ardCamerasList = ardCamerasMapper.selectArdCamerasList(new ArdCameras("1")); |
| | | //统计所有大光电可视范围内与报警点的距离 |
| | | Map<String, Double> distanceMap = new HashMap<>(); |
| | | Map<String, Integer> guideMap = new HashMap<>(); |
| | | for (ArdCameras camera : ardCamerasList) { |
| | | if (camera.getCamMaxVisibleDistance() == null) { |
| | | continue; |
| | | } |
| | | guideMap.put(camera.getId(), camera.getCamAlarmGuideEnable()); |
| | | double[] camPosition = new double[]{camera.getLongitude(), camera.getLatitude()}; |
| | | double distance = GisTool.getDistance(targetPosition, camPosition); |
| | | if (distance != 0.0 && distance <= camera.getCamMaxVisibleDistance()) { |
| | | distanceMap.put(camera.getId(), distance); |
| | | if (StringUtils.isNull(camera.getCamAlarmGuideEnable())) { |
| | | camera.setCamAlarmGuideEnable(0); |
| | | } |
| | | guideMap.put(camera.getId(), camera.getCamAlarmGuideEnable()); |
| | | } |
| | | } |
| | | if (distanceMap.size() > 0) { |
| | | log.debug("尝试查找最近光电"); |
| | | //获取距离字典中最近的一个相机ID |
| | | minDistanceCameraId = ArdTool.getKeyByMinValue(distanceMap); |
| | | log.debug("查找到最近光电:" + minDistanceCameraId); |
| | | if (guideMap.get(minDistanceCameraId).equals(0)) { |
| | | log.debug("该光电未开启报警引导"); |
| | | return " "; |
| | | } |
| | | } |
| | | } |
| | | if (distanceMap.size() > 0) { |
| | | log.debug("尝试查找最近光电"); |
| | | //获取距离字典中最近的一个相机ID |
| | | minDistanceCameraId = ArdTool.getKeyByMinValue(distanceMap); |
| | | log.debug("查找到最近光电:" + minDistanceCameraId); |
| | | if (guideMap.get(minDistanceCameraId).equals(0)) { |
| | | log.debug("该光电未开启报警引导"); |
| | | return " "; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.error("获取附近开启报警引导功能光电异常:"+ex.getMessage()); |
| | | } |
| | | return minDistanceCameraId; |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | Comparator<Obj> PriorityDescCom = Comparator.comparingInt(Obj::getPriority).reversed(); |
| | | Comparator<Obj> NumDescCom = Comparator.comparingInt(Obj::getNum).reversed(); |
| | | Comparator<Obj> receiveTimeAscCom = Comparator.comparing(Obj::getAlarmTime); |
| | | Comparator<Obj> comparator = PriorityDescCom.thenComparing(NumDescCom).thenComparing(receiveTimeAscCom); |
| | | |
| | | PriorityBlockingQueue<Obj> priorityQueue = new PriorityBlockingQueue<>(1000, comparator); |
| | | |
| | | priorityQueue.add(new Obj(999, 1, "2023-07-01 16:00:01")); |
| | | priorityQueue.add(new Obj(999, 2, "2023-07-01 16:00:01")); |
| | | priorityQueue.add(new Obj(999, 3, "2023-07-01 16:00:01")); |
| | | |
| | | List<Obj> elements = new ArrayList<>(priorityQueue); |
| | | elements.sort(priorityQueue.comparator()); // 使用队列的比较器进行排序 |
| | | for (Obj task : elements) { |
| | | log.info("正在排队【priority】" + task.getPriority() + "【num】" + task.getNum() + "【alarmTime】" + task.getAlarmTime()); |
| | | /** |
| | | * 雷达引导入队 |
| | | */ |
| | | private void radarGuide(String radarId, String alarmpointName, String alarmType, Date createTime, double[] coordinate) { |
| | | String uuid = IdUtils.simpleUUID(); |
| | | //获取雷达所在塔上的大光电 |
| | | String cameraIdWithTower = ardAlarmRadarMapper.getCameraByRadar(radarId); |
| | | if (StringUtils.isNotNull(cameraIdWithTower) && StringUtils.isNotEmpty(cameraIdWithTower)) { |
| | | log.info("获取到雷达塔上的光电:" + cameraIdWithTower); |
| | | //如果雷达塔上有光电 |
| | | messagesEnqueued(cameraIdWithTower, uuid, alarmType, createTime, 1, 1, coordinate); |
| | | } |
| | | log.info("==================================================================="); |
| | | priorityQueue.add(new Obj(999, 5, "2023-07-01 16:00:01")); |
| | | PriorityBlockingQueue queue = new PriorityBlockingQueue<>(priorityQueue); |
| | | while (queue.size() > 0) { |
| | | Obj task = (Obj) queue.poll(); |
| | | log.info("正在排队【priority】" + task.getPriority() + "【num】" + task.getNum() + "【alarmTime】" + task.getAlarmTime()); |
| | | //获取报警点关联的大光电 |
| | | ArdAlarmpointsWell ardAlarmpointsWell = ardAlarmpointsWellMapper.selectArdAlarmpointsWellByWellId(alarmpointName); |
| | | if (StringUtils.isNotNull(ardAlarmpointsWell) && StringUtils.isNotEmpty(ardAlarmpointsWell.getCameraId())) { |
| | | String cameraId = ardAlarmpointsWell.getCameraId(); |
| | | if (cameraId.equals(cameraIdWithTower)) { |
| | | return; |
| | | } |
| | | log.info("获取到报警点关联的光电:" + cameraId); |
| | | //如果报警点关联了光电 |
| | | messagesEnqueued(cameraId, uuid, alarmType, createTime, 1, 2, coordinate); |
| | | } |
| | | } |
| | | |
| | | @Data |
| | | @AllArgsConstructor |
| | | static class Obj { |
| | | Integer priority; |
| | | Integer num; |
| | | String alarmTime; |
| | | } |
| | | } |