Browse Source

首页气象预测逻辑调整为没有数据获取历史预测D+1的数据,以及加入每个站获取准确率最好的模型数据。

xusl 5 months ago
parent
commit
5df4e0460d

+ 136 - 7
cpp-admin/src/main/java/com/cpp/web/controller/largeScreen/LargeScreenController.java

@@ -37,6 +37,7 @@ import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.LocalDate;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 
 
@@ -322,6 +323,49 @@ public class LargeScreenController {
         }
         }
         stationMap.put("gf", gfStationCodeList);
         stationMap.put("gf", gfStationCodeList);
         stationMap.put("wind", windStationCodeList);
         stationMap.put("wind", windStationCodeList);
+
+        // 获取所有站30天内最好的预测模型
+        Date accuracyStartTime = DateTimeUtil.getDayStartTime(System.currentTimeMillis() - 30 * 24 * 60 * 60 * 1000L);
+        Date accuracyEndTime = DateTimeUtil.getDayStartTime(System.currentTimeMillis() - 24 * 60 * 60 * 1000L);
+        Map<String,String> stationModelMap = new HashMap();
+        // 查询近一个月内平均准确率高的预测模型
+        QueryWrapper accuracyWrapper = new QueryWrapper<>();
+        accuracyWrapper.between("time", accuracyStartTime, accuracyEndTime);
+        accuracyWrapper.eq("data_sources","E2");
+        accuracyWrapper.eq("forecast_how_long_ago",1);
+        accuracyWrapper.eq("forecast_type","dq");
+        List<AccuracyPassRate> accuracyPassRateList = accuracyPassRateService.list(accuracyWrapper);
+        Map<String,List<AccuracyPassRate>> accuracyMap = accuracyPassRateList.stream().collect(Collectors.groupingBy(n -> n.getStationCode(), Collectors.toList()));
+        // 遍历每个站
+        Iterator<Map.Entry<String, List<AccuracyPassRate>>> accuracyIterator = accuracyMap.entrySet().iterator();
+        while (accuracyIterator.hasNext()) {
+            Map.Entry<String, List<AccuracyPassRate>> accuracyEntry = accuracyIterator.next();
+            List<AccuracyPassRate> accuracyList = accuracyEntry.getValue();
+
+            if (null != accuracyList && accuracyList.size() > 0) {
+                accuracyList = accuracyList.stream().filter(f -> !"无可用数据计算".equals(f.getAccuracy()) && !"无计算公式".equals(f.getAccuracy())).collect(Collectors.toList());
+                Function<String, Double> stringToDouble = s -> {
+                    String numberStr = s.replace("%", "");
+                    return Double.parseDouble(numberStr);
+                };
+                if (accuracyList.size()>0){
+                    Map<String, Double> averageByCategory = accuracyList.stream()
+                            .collect(Collectors.groupingBy(
+                                    AccuracyPassRate::getForecastModel,
+                                    Collectors.averagingDouble(apr -> stringToDouble.apply(apr.getAccuracy()))
+                            ));
+                    // 找出平均值最大的那一组
+                    Optional<Map.Entry<String, Double>> maxAverageEntry = averageByCategory.entrySet().stream().max(Map.Entry.comparingByValue());
+                    // 获取模型
+                    String forecastModel = maxAverageEntry.get().getKey();
+                    stationModelMap.put(accuracyEntry.getKey(),forecastModel);
+                }
+                else{
+                    stationModelMap.put(accuracyEntry.getKey(),"JY");
+                }
+            }
+        }
+
         Map<String, List> forecastWeatherAvgDataMap = new HashMap<>();
         Map<String, List> forecastWeatherAvgDataMap = new HashMap<>();
         // 循环光和风
         // 循环光和风
         Iterator<Map.Entry<String, List>> stationIterator = stationMap.entrySet().iterator();
         Iterator<Map.Entry<String, List>> stationIterator = stationMap.entrySet().iterator();
@@ -347,10 +391,31 @@ public class LargeScreenController {
                     nwpCloudQueryWrapper.between("time", dayStartTime, dayEndTime);
                     nwpCloudQueryWrapper.between("time", dayStartTime, dayEndTime);
                     nwpCloudQueryWrapper.in("station_code", stationCodeList);
                     nwpCloudQueryWrapper.in("station_code", stationCodeList);
                     List<NwpCloud> nwpCloudList = nwpCloudService.list(nwpCloudQueryWrapper);
                     List<NwpCloud> nwpCloudList = nwpCloudService.list(nwpCloudQueryWrapper);
+                    List<NwpCloud> finalNwpCloudList = new ArrayList<>();
                     if (!nwpCloudList.isEmpty()) {
                     if (!nwpCloudList.isEmpty()) {
-                        nwpCloudMap = nwpCloudList.stream().collect(Collectors.groupingBy(n -> n.getTime().getTime(), Collectors.toList()));
-                        // 查出数据,并且有今日的预测数据,就退出当前循环。
-                        break;
+                        // 先按场站分组
+                        Map<String,List<NwpCloud>> nwpCloudMapByStationCode = nwpCloudList.stream().collect(Collectors.groupingBy(n -> n.getStationCode(), Collectors.toList()));
+                        // 遍历场站分组过滤出最好的模型数据
+                        Iterator<Map.Entry<String, List<NwpCloud>>> nwpCloudIterator = nwpCloudMapByStationCode.entrySet().iterator();
+                        while (nwpCloudIterator.hasNext()) {
+                            Map.Entry<String, List<NwpCloud>> nwpEntry = nwpCloudIterator.next();
+                            String stationCode = nwpEntry.getKey();
+                            if (stationModelMap.get(stationCode)!=null){
+                                List<NwpCloud> nwpCloudListByModel = nwpEntry.getValue();
+                                List modelFilterList = nwpCloudListByModel.stream().filter(f -> f.getForecastModel().equals(stationModelMap.get(stationCode))).collect(Collectors.toList());
+                                if (modelFilterList.size()>0){
+                                    finalNwpCloudList.addAll(modelFilterList);
+                                }
+                            }
+                        }
+                        if (finalNwpCloudList.size()>0){
+                            nwpCloudMap = finalNwpCloudList.stream().collect(Collectors.groupingBy(n -> n.getTime().getTime(), Collectors.toList()));
+                            // 查出数据,并且有今日的预测数据,就退出当前循环。
+                            break;
+                        }
+                        else{
+                            // 查询出的数据没有对应的模型,日期往前推一天,再查
+                        }
                     } else {
                     } else {
                         // 否则,日期往前推一天,再查
                         // 否则,日期往前推一天,再查
                     }
                     }
@@ -391,7 +456,7 @@ public class LargeScreenController {
                             sum = sum.add(nwpCloud.getSwr());
                             sum = sum.add(nwpCloud.getSwr());
                         }
                         }
                     }
                     }
-                    totalForecastNwpDto.setValue(sum);
+                    totalForecastNwpDto.setValue(sum.divide(BigDecimal.valueOf(nwpCloudList.size()), 2, BigDecimal.ROUND_HALF_UP));
                 } else {
                 } else {
                     // 时间点位为空
                     // 时间点位为空
                     totalForecastNwpDto.setValue(BigDecimal.ZERO);
                     totalForecastNwpDto.setValue(BigDecimal.ZERO);
@@ -435,6 +500,49 @@ public class LargeScreenController {
         for (ElectricField electricField : list) {
         for (ElectricField electricField : list) {
             stationCodeList.add(electricField.getStationCode());
             stationCodeList.add(electricField.getStationCode());
         }
         }
+
+        // 获取所有站30天内最好的预测模型
+        Date accuracyStartTime = DateTimeUtil.getDayStartTime(System.currentTimeMillis() - 30 * 24 * 60 * 60 * 1000L);
+        Date accuracyEndTime = DateTimeUtil.getDayStartTime(System.currentTimeMillis() - 24 * 60 * 60 * 1000L);
+        Map<String,String> stationModelMap = new HashMap();
+        // 查询近一个月内平均准确率高的预测模型
+        QueryWrapper accuracyWrapper = new QueryWrapper<>();
+        accuracyWrapper.between("time", accuracyStartTime, accuracyEndTime);
+        accuracyWrapper.eq("data_sources","E2");
+        accuracyWrapper.eq("forecast_how_long_ago",1);
+        accuracyWrapper.eq("forecast_type","dq");
+        List<AccuracyPassRate> accuracyPassRateList = accuracyPassRateService.list(accuracyWrapper);
+        Map<String,List<AccuracyPassRate>> accuracyMap = accuracyPassRateList.stream().collect(Collectors.groupingBy(n -> n.getStationCode(), Collectors.toList()));
+        // 遍历每个站
+        Iterator<Map.Entry<String, List<AccuracyPassRate>>> accuracyIterator = accuracyMap.entrySet().iterator();
+        while (accuracyIterator.hasNext()) {
+            Map.Entry<String, List<AccuracyPassRate>> accuracyEntry = accuracyIterator.next();
+            List<AccuracyPassRate> accuracyList = accuracyEntry.getValue();
+
+            if (null != accuracyList && accuracyList.size() > 0) {
+                accuracyList = accuracyList.stream().filter(f -> !"无可用数据计算".equals(f.getAccuracy()) && !"无计算公式".equals(f.getAccuracy())).collect(Collectors.toList());
+                Function<String, Double> stringToDouble = s -> {
+                    String numberStr = s.replace("%", "");
+                    return Double.parseDouble(numberStr);
+                };
+                if (accuracyList.size()>0){
+                    Map<String, Double> averageByCategory = accuracyList.stream()
+                            .collect(Collectors.groupingBy(
+                                    AccuracyPassRate::getForecastModel,
+                                    Collectors.averagingDouble(apr -> stringToDouble.apply(apr.getAccuracy()))
+                            ));
+                    // 找出平均值最大的那一组
+                    Optional<Map.Entry<String, Double>> maxAverageEntry = averageByCategory.entrySet().stream().max(Map.Entry.comparingByValue());
+                    // 获取模型
+                    String forecastModel = maxAverageEntry.get().getKey();
+                    stationModelMap.put(accuracyEntry.getKey(),forecastModel);
+                }
+                else{
+                    stationModelMap.put(accuracyEntry.getKey(),"JY");
+                }
+            }
+        }
+
         // 查询当日所有站的nwp数据
         // 查询当日所有站的nwp数据
         Date dayStartTime = DateTimeUtil.getDayStartTime(System.currentTimeMillis());
         Date dayStartTime = DateTimeUtil.getDayStartTime(System.currentTimeMillis());
         Date dayEndTime = DateTimeUtil.getDayLastTime(System.currentTimeMillis());
         Date dayEndTime = DateTimeUtil.getDayLastTime(System.currentTimeMillis());
@@ -447,10 +555,31 @@ public class LargeScreenController {
                 nwpCloudQueryWrapper.between("time", dayStartTime, dayEndTime);
                 nwpCloudQueryWrapper.between("time", dayStartTime, dayEndTime);
                 nwpCloudQueryWrapper.in("station_code", stationCodeList);
                 nwpCloudQueryWrapper.in("station_code", stationCodeList);
                 List<NwpCloud> nwpCloudList = nwpCloudService.list(nwpCloudQueryWrapper);
                 List<NwpCloud> nwpCloudList = nwpCloudService.list(nwpCloudQueryWrapper);
+                List<NwpCloud> finalNwpCloudList = new ArrayList<>();
                 if (!nwpCloudList.isEmpty()) {
                 if (!nwpCloudList.isEmpty()) {
-                    nwpCloudMap = nwpCloudList.stream().collect(Collectors.groupingBy(n -> n.getStationCode(), Collectors.toList()));
-                    // 查出数据,并且有今日的预测数据,就退出当前循环。
-                    break;
+                    // 先按场站分组
+                    Map<String,List<NwpCloud>> nwpCloudMapByStationCode = nwpCloudList.stream().collect(Collectors.groupingBy(n -> n.getStationCode(), Collectors.toList()));
+                    // 遍历场站分组过滤出最好的模型数据
+                    Iterator<Map.Entry<String, List<NwpCloud>>> nwpCloudIterator = nwpCloudMapByStationCode.entrySet().iterator();
+                    while (nwpCloudIterator.hasNext()) {
+                        Map.Entry<String, List<NwpCloud>> nwpEntry = nwpCloudIterator.next();
+                        String stationCode = nwpEntry.getKey();
+                        if (stationModelMap.get(stationCode)!=null){
+                            List<NwpCloud> nwpCloudListByModel = nwpEntry.getValue();
+                            List modelFilterList = nwpCloudListByModel.stream().filter(f -> f.getForecastModel().equals(stationModelMap.get(stationCode))).collect(Collectors.toList());
+                            if (modelFilterList.size()>0){
+                                finalNwpCloudList.addAll(modelFilterList);
+                            }
+                        }
+                    }
+                    if (finalNwpCloudList.size()>0){
+                        nwpCloudMap = finalNwpCloudList.stream().collect(Collectors.groupingBy(n -> n.getStationCode(), Collectors.toList()));
+                        // 查出数据,并且有今日的预测数据,就退出当前循环。
+                        break;
+                    }
+                    else{
+                        // 查询出的数据没有对应的模型,日期往前推一天,再查
+                    }
                 } else {
                 } else {
                     // 否则,日期往前推一天,再查
                     // 否则,日期往前推一天,再查
                 }
                 }

+ 2 - 2
cpp-admin/src/main/java/com/cpp/web/job/ScheduledJob.java

@@ -163,7 +163,7 @@ public class ScheduledJob implements ApplicationRunner {
     /**
     /**
      *  云端发电量
      *  云端发电量
      */
      */
-    @Scheduled(cron = "0 0/1 * * * ?")
+//    @Scheduled(cron = "0 0/1 * * * ?")
     public void generateYdPowerGeneration(){
     public void generateYdPowerGeneration(){
         log.info("-------------------------开始执行计算云端发电量定时任务-------------------------");
         log.info("-------------------------开始执行计算云端发电量定时任务-------------------------");
         List<ElectricField> electricFieldList = electricFieldService.list();
         List<ElectricField> electricFieldList = electricFieldService.list();
@@ -179,7 +179,7 @@ public class ScheduledJob implements ApplicationRunner {
     /**
     /**
      *  云端发电量
      *  云端发电量
      */
      */
-    @Scheduled(cron = "0 0/1 * * * ?")
+//    @Scheduled(cron = "0 0/1 * * * ?")
     public void generateZdPowerGeneration(){
     public void generateZdPowerGeneration(){
         log.info("-------------------------开始执行计算站端上传发电量定时任务-------------------------");
         log.info("-------------------------开始执行计算站端上传发电量定时任务-------------------------");
         List<ElectricField> electricFieldList = electricFieldService.list();
         List<ElectricField> electricFieldList = electricFieldService.list();