package com.newfiber.api.pc.service.impl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.newfiber.api.pc.controller.newmonitoring.PackRealTimeDataController; import com.newfiber.api.pc.model.entity.RainFallAlarmLevel; import com.newfiber.api.pc.model.entity.RainHistoryData; import com.newfiber.api.pc.model.entity.StationBaseEntity; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; /** * 封装降雨量状态的业务层 * @ClassName RainCommonsService * @Description TODO * @Author 张鸿志 * @Date 2021年7月16日13:35:46 13:35 * Version 1.0 **/ @Service @Slf4j public class RainCommonsService { @Autowired private PackRealTimeDataController packRealTimeDataController; private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public Map<String, RainFallAlarmLevel> getRainData() { Map<String, RainFallAlarmLevel> map = new HashMap<>(); Calendar instance = Calendar.getInstance(); //测试预警报警时用 //instance.setTime(format.parse("2021-05-10 23:45:23")); //获取当前年月日 //结束时间 String endTime = format.format(instance.getTime()); instance.add(Calendar.DATE,-1); //开始时间 String startTime = format.format(instance.getTime()); List<StationBaseEntity> infoToRedis = packRealTimeDataController.getSiteInfoToRedisNew(""); for (StationBaseEntity baseEntity : infoToRedis) { Calendar calendar = Calendar.getInstance(); //获取雨量站去请求历史数据 if (baseEntity.getStationType().equals("水淹报警监测站")) { //查询24H的历史数据 JSONObject historyData = packRealTimeDataController.getHistoryData(baseEntity.getStCode(), 0, 300, startTime, endTime); //计算当前的值是否超标 List<RainHistoryData> rows = JSONArray.parseArray(historyData.get("rows").toString(), RainHistoryData.class); //如果查询到的历史数据为0,直接跳过本次循环 if (rows.size() == 0) { break; } log.info("取出的数据条数为{}", rows.size()); List<String> ttTimeList = rows.stream().map(RainHistoryData::getTtTime).collect(Collectors.toList()); //获取最新一条数据的 总降雨量 BigDecimal currentValue = rows.get(0).getPt(); //获取两小时前的总降雨量 BigDecimal towHourValue = null; //获取三小时前的总降雨量 BigDecimal threeHourValue = null; //获取6小时前的总降雨量 BigDecimal sixHourValue = null; //获取12小时前的总降雨量 BigDecimal twelveHourValue = null; try { //设置当前的观测时间 calendar.setTime(format.parse(rows.get(0).getTtTime())); //给当前观测时间-2小时 calendar.add(Calendar.HOUR, -2); towHourValue = rows.get(binarySearch(ttTimeList, calendar.getTime())).getPt(); //给当前观测时间-1小时 变成3小时 calendar.add(Calendar.HOUR, -1); threeHourValue = rows.get(binarySearch(ttTimeList, calendar.getTime())).getPt(); //给当前观测时间-3小时 变成6小时 calendar.add(Calendar.HOUR, -3); sixHourValue = rows.get(binarySearch(ttTimeList, calendar.getTime())).getPt(); //给当前观测时间-6小时 变成12小时 calendar.add(Calendar.HOUR, -6); twelveHourValue = rows.get(binarySearch(ttTimeList, calendar.getTime())).getPt(); RainFallAlarmLevel judge = judge(currentValue, threeHourValue, sixHourValue, twelveHourValue); judge.setSiteName(baseEntity.getStName()); judge.setSiteAddr(baseEntity.getAddress()); //将警情数据写入返回给客户端的Map中 map.put(baseEntity.getStCode(), judge); } catch (ParseException e) { log.info("在查询雨量站历史报警数据时转换错误!"); } } } return map; } /** * 二分查找法,将查询出来的所有数据的观测时间进行比较,得出2小时,3小时,6小时,12小时的数据 * @Param [ttTimeList, comparTime] * @return {int} * @throws * @author 张鸿志 * @date 2021/5/13 9:22 */ private int binarySearch(List<String> ttTimeList, Date comparTime) throws ParseException { int low = 0; int high = ttTimeList.size() - 1; while(low <= high){ //计算得到该数组的中间位置 int middle = low + (high - low) / 2; Date parse = format.parse(ttTimeList.get(middle)); if(comparTime.compareTo(parse) == 0){ return middle; }else if(comparTime.compareTo(parse) < 0){ low = middle - 1; }else{ high = middle + 1; } } return -1; } /** * 判断 3小时 6小时 12 小时的累计降雨量是否达到什么蓝、黄、橙、红级别 * 注意:这里只考虑累计不考虑预计和持续的判断 * 暴雨预警信号分四级,分别以蓝色、黄色、橙色、红色表示。 * 暴雨蓝色预警信号:12小时内降雨量将达50毫米以上,或者已达50毫米以上且降雨可能持续。 * 暴雨黄色预警信号:6小时内降雨量将达50毫米以上,或者已达50毫米以上且降雨可能持续。 * 暴雨橙色预警信号:3小时内降雨量将达50毫米以上,或者已达50毫米以上且降雨可能持续。 * 暴雨红色预警信号:3小时内降雨量将达100毫米以上,或者已达100毫米以上且降雨可能持续。 * @Param [currentValue, threeHourValue, sixHourValue, twelveHourValue] * @return {com.newfiber.api.pc.model.entity.RainFallAlarmLevel} * @throws * @author 张鸿志 * @date 2021/5/13 15:51 */ private RainFallAlarmLevel judge(BigDecimal currentValue, BigDecimal threeHourValue, BigDecimal sixHourValue, BigDecimal twelveHourValue){ RainFallAlarmLevel rainFallAlarmLevel = new RainFallAlarmLevel(); BigDecimal twelveValue = currentValue.subtract(twelveHourValue); if(twelveValue.compareTo(new BigDecimal(50)) > 0){ rainFallAlarmLevel.setLevel(1); rainFallAlarmLevel.setMessage("暴雨蓝色预警,12小时内降雨量已达50毫米"); } BigDecimal sixValue = currentValue.subtract(sixHourValue); if(sixValue.compareTo(new BigDecimal(50)) > 0){ rainFallAlarmLevel.setLevel(2); rainFallAlarmLevel.setMessage("暴雨黄色预警,6小时内降雨量已达50毫米"); } BigDecimal threeValueOne = currentValue.subtract(threeHourValue); if(threeValueOne.compareTo(new BigDecimal(50)) > 0){ rainFallAlarmLevel.setLevel(3); rainFallAlarmLevel.setMessage("暴雨橙色预警,3小时内降雨量已达50毫米"); } BigDecimal threeValueTow = currentValue.subtract(threeHourValue); if(threeValueTow.compareTo(new BigDecimal(100)) > 0){ rainFallAlarmLevel.setLevel(4); rainFallAlarmLevel.setMessage("暴雨红色预警,3小时内降雨量已达100毫米"); } if(StringUtils.isEmpty(rainFallAlarmLevel.getLevel())){ rainFallAlarmLevel.setLevel(0); rainFallAlarmLevel.setMessage("没有发生任何警情!"); } rainFallAlarmLevel.setCurrentDate(new Date()); return rainFallAlarmLevel; } }