Newer
Older
huludao / src / main / java / com / newfiber / api / pc / service / impl / RainCommonsService.java
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;
    }

}