浏览代码

气象预报数据下载

hdc 2 年之前
父节点
当前提交
4fa6d7ea5d

+ 27 - 5
tongfei_river_data_collection/src/main/java/com/ublinkage/datacollection/ScheduledTaskConfig.java

@@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil;
 import com.ublinkage.datacollection.service.QxybDataService;
 import com.ublinkage.datacollection.service.SatelliteRadarImageDataService;
 import com.ublinkage.datacollection.service.WeatherDataService;
+import org.jetbrains.annotations.NotNull;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.ApplicationRunner;
@@ -50,19 +51,28 @@ public class ScheduledTaskConfig {
             String startTime = DateUtil.format(startDt, "yyyy-MM-dd HH:mm:ss");
             DateTime endDt = DateUtil.parse(ybEndTime, "yyyy_MM_dd_HH_mm_ss");
             String endTime = DateUtil.format(endDt, "yyyy-MM-dd HH:mm:ss");
-            qxybDataService.download(startTime,endTime);
+            qxybDataService.downloadQxybData(startTime,endTime);
         };
     }
 
 
     /**
-     * 每天1,7,13,19点自动下载
+     * 下载气象预报数据
      */
     @Scheduled(cron = "0 0 1,7,13,19 * * ?")
     public void downloadQxybDataTask() {
         String startTime = getLatestPublishTime();
         String endTime = getLatestPublishTime();
-        qxybDataService.download(startTime, endTime);
+        qxybDataService.downloadQxybData(startTime, endTime);
+    }
+
+    /**
+     * 下载澜沧江上游高程带融雪覆盖预报
+     */
+    @Scheduled(cron = "0 0 1,7,13,19 * * ?")
+    public void downloadSnowCoverTask() {
+        String publishDt = getPublishDt();
+        qxybDataService.downloadSnowCover(publishDt);
     }
 
     /**
@@ -92,14 +102,26 @@ public class ScheduledTaskConfig {
 
 
     public static String getLatestPublishTime(){
+        LocalDateTime localDateTime = getLocalDateTime();
+        DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        return pattern.format(localDateTime);
+    }
+
+    @NotNull
+    private static LocalDateTime getLocalDateTime() {
         //LocalDateTime now = LocalDateTime.of(2023, 6, 27, 1, 0);
         LocalDateTime now = LocalDateTime.now(Clock.systemUTC());
         long seconds = now.toEpochSecond(ZoneOffset.of("+8"));
         long hours = seconds / (60 * 60);
         long newHours = (hours / 6) * 6;
         LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(newHours * (60 * 60), 0, ZoneOffset.UTC);
-        localDateTime = localDateTime.plusHours(-6);
-        DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        return localDateTime;
+    }
+
+    public static String getPublishDt(){
+        //LocalDateTime now = LocalDateTime.of(2023, 6, 27, 1, 0);
+        LocalDateTime localDateTime = getLocalDateTime();
+        DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH_192");
         return pattern.format(localDateTime);
     }
 

+ 1 - 1
tongfei_river_data_collection/src/main/java/com/ublinkage/datacollection/controller/QxybController.java

@@ -16,7 +16,7 @@ public class QxybController {
 
     @RequestMapping("/download")
     public String download(@RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {
-        qxybDataService.download(startTime, endTime);
+        qxybDataService.downloadQxybData(startTime, endTime);
         return "OK";
     }
 

+ 2 - 5
tongfei_river_data_collection/src/main/java/com/ublinkage/datacollection/entity/PublishInfo.java

@@ -1,13 +1,10 @@
 package com.ublinkage.datacollection.entity;
 
+import lombok.AllArgsConstructor;
 import lombok.Data;
 
-/**
- * @author Yang Huang
- * @create 2022-11-29-18:45
- * @description TODO
- */
 @Data
+@AllArgsConstructor
 public class PublishInfo {
     private String publishDT;
     private String ensemble;

+ 404 - 227
tongfei_river_data_collection/src/main/java/com/ublinkage/datacollection/service/QxybDataService.java

@@ -1,6 +1,5 @@
 package com.ublinkage.datacollection.service;
 
-import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.io.FileUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.ublinkage.datacollection.entity.PublishInfo;
@@ -14,11 +13,13 @@ import org.springframework.util.StringUtils;
 
 import java.io.File;
 import java.io.IOException;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -29,6 +30,8 @@ import java.util.concurrent.TimeUnit;
 public class QxybDataService {
 
     public static final String BASE_URL = "http://111.198.2.202:6657";
+    public static final DateTimeFormatter DATE_TIME_FORMATTER1 = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH_mm_ss");
+    public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
     /**
      * 下载路径
      */
@@ -40,164 +43,130 @@ public class QxybDataService {
     @Value("${snow.qzk.file}")
     private String snowQzkFile;
 
-    String RDField = "LCJDomain";
-    String domain = "domain02";
-    String ensemble = "mp3_cu3";
-
+    protected static OkHttpClient client = new OkHttpClient().newBuilder()
+            .connectTimeout(60, TimeUnit.SECONDS)
+            .readTimeout(600, TimeUnit.SECONDS)
+            .writeTimeout(180, TimeUnit.SECONDS)
+            .build();
+    protected static String RDField = "LCJDomain";
+    protected static String domain = "domain02";
+    protected static String ensemble = "mp3_cu3";
 
     /**
-     * 执行下载
+     * 下载气象预报数据
      */
-    public void download(String startTime, String endTime) {
+    public void downloadQxybData(String startTime, String endTime) {
 
         log.info("###开始下载气象预报数据:{}-{}", startTime, endTime);
-        CompletableFuture<Void> all = CompletableFuture.allOf(CompletableFuture.runAsync(() -> {
-            log.info("###开始下载融雪数据");
-            this.getDomainSnow();
-            log.info("###结束下载融雪数据");
-        }).handle((result, ex) -> {
-            if (null != ex) {
-                log.error("下载融雪数据异常", ex);
-            }
-            return result;
-        }), CompletableFuture.runAsync(() -> {
-            // 延庆云服务器不能并行
-            try {
-                log.info("###开始下载昌都、曲孜卡温度和降雨:{}-{}", startTime, endTime);
-                this.getDomainTempAndRain(startTime, endTime);
-                log.info("###结束下载昌都、曲孜卡温度和降雨:{}-{}", startTime, endTime);
-            } catch (Exception e) {
-                log.error("下载昌都、曲孜卡温度和降雨异常", e);
-            }
-
-
-            try {
-                log.info("###开始下载温度站点数据:{}-{}", startTime, endTime);
-                this.getForeTempData(startTime, endTime);
-                log.info("###结束下载温度站点数据:{}-{}", startTime, endTime);
-            } catch (Exception e) {
-                log.error("下载温度站点数据异常", e);
-            }
+        // 服务器不能并行
+        try {
+            log.info("###开始下载流域15分区降水预报:{}-{}", startTime, endTime);
+            this.downloadDIVRainData("15", startTime, endTime);
+            log.info("###结束下载流域15分区降水预报:{}-{}", startTime, endTime);
+        } catch (Exception e) {
+            log.error("###下载流域15分区降水预报异常", e);
+        }
 
 
-            try {
-                log.info("###开始下载15分区雨量:{}-{}", startTime, endTime);
-                this.getForecast15Data(startTime, endTime);
-                log.info("###结束下载15分区雨量:{}-{}", startTime, endTime);
-            } catch (Exception e) {
-                log.error("下载15分区雨量异常", e);
-            }
+        try {
+            log.info("###开始下载流域29分区降水预报:{}-{}", startTime, endTime);
+            this.downloadDIVRainData("29", startTime, endTime);
+            log.info("###结束下载流域29分区降水预报:{}-{}", startTime, endTime);
+        } catch (Exception e) {
+            log.error("下载下载流域29分区降水预报异常", e);
+        }
 
 
-            try {
-                log.info("###开始下载29分区雨量:{}-{}", startTime, endTime);
-                this.getForecast29Data(startTime, endTime);
-                log.info("###结束下载29分区雨量:{}-{}", startTime, endTime);
-            } catch (Exception e) {
-                log.error("下载29分区雨量异常", e);
-            }
+        try {
+            log.info("###开始下载网格降水/温度预报:{}-{}", startTime, endTime);
+            this.downloadGridRainAndTempData(startTime, endTime);
+            log.info("###结束下载网格降水/温度预报:{}-{}", startTime, endTime);
+        } catch (Exception e) {
+            log.error("###下载网格降水/温度预报异常", e);
+        }
 
+        try {
+            log.info("###开始下载流域站点气温预报:{}-{}", startTime, endTime);
+            this.downloadStationTempData(startTime, endTime);
+            log.info("###结束下载流域站点气温预报:{}-{}", startTime, endTime);
+        } catch (Exception e) {
+            log.error("###下载流域站点气温预报异常", e);
+        }
 
-            //获取网格数据,包含温度网格,降雨网格
-            try {
-                log.info("###开始下载网格数据:{}-{}", startTime, endTime);
-                this.getGridData(startTime, endTime);
-                log.info("###结束下载网格数据:{}-{}", startTime, endTime);
-            } catch (Exception e) {
-                log.error("下载网格数据异常", e);
-            }
+        try {
+            log.info("###开始下载澜沧江上游高程带温度和降水预报:{}-{}", startTime, endTime);
+            this.getDomainTempAndRain(startTime, endTime);
+            log.info("###结束下载澜沧江上游高程带温度和降水预报:{}-{}", startTime, endTime);
+        } catch (Exception e) {
+            log.error("###下载澜沧江上游高程带温度和降水预报异常", e);
+        }
 
-        }).handle((result, ex) -> {
-            if (null != ex) {
-                log.error("下载延庆云服务器数据异常", ex);
-            }
-            return result;
-        }));
-        all.join();
         log.info("###结束下载气象预报数据:{}-{}", startTime, endTime);
 
     }
 
 
     /**
-     * 获取15分区的数据1h小时数据和24小时
+     * 下载流域15、29分区降水预报
      */
-    private void getForecast15Data(String startTime, String endTime) {
-        String divisionCode = "LCJ_DIV15";
+    private void downloadDIVRainData(String divNum, String startTime, String endTime) {
+        String divisionCode = "LCJ_DIV" + divNum;
         int hour = 1;
-        String url = BASE_URL + "/getForePrecipPublishDT?divisionCode=" + divisionCode + "&hour=" + hour + "&ensemble=" + ensemble + "&startTime=" + startTime + "&endTime=" + endTime;
-        String batchResult = getResult(url);
-        JSONObject json = JSONObject.parseObject(batchResult);
-        Integer code = json.getInteger("code");
-        if (code == 200) {
+        List<PublishInfo> publishList = null;
+        try {
+            String url = BASE_URL + "/getForePrecipPublishDT?divisionCode=" + divisionCode + "&hour=" + hour + "&ensemble=" + ensemble + "&startTime=" + startTime + "&endTime=" + endTime;
+            log.info("下载流域{}分区降水预报批次:{}", divNum, url);
+            String batchResult = getResult(url);
+            JSONObject json = JSONObject.parseObject(batchResult);
+            publishList = json.getJSONArray("data").toJavaList(PublishInfo.class);
             writeFile(batchResult, downloadFilePath + "FRB," + divisionCode + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-            List<PublishInfo> publishList = json.getJSONArray("data").toJavaList(PublishInfo.class);
-            //1小时的数据
+            log.info("下载成功");
+        } catch (Exception e) {
+            log.error("下载失败", e);
+            return;
+        }
+
+        for (PublishInfo publishInfo : publishList) {
             try {
-                for (PublishInfo publishInfo : publishList) {
-                    String result = getResult(BASE_URL + "/getForePrecipData?publishDT=" + publishInfo.getPublishDT() + "&divisionCode=" + divisionCode + "&hour=" + hour + "&ensemble=" + ensemble + "&foreTime=" + 240);
-                    writeFile(result, downloadFilePath + "FRD," + publishInfo.getPublishDT() + "," + divisionCode + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-                }
+                int hour2 = 1;
+                String url2 = BASE_URL + "/getForePrecipData?publishDT=" + publishInfo.getPublishDT() + "&divisionCode=" + divisionCode + "&hour=" + hour2 + "&ensemble=" + ensemble;
+                log.info("下载流域{}分区降水预报数据(小时尺度):{}", divNum, url2);
+                String result = getResult(url2);
+                writeFile(result, downloadFilePath + "FRD," + publishInfo.getPublishDT() + "," + divisionCode + "," + hour2 + "," + ensemble + "," + System.currentTimeMillis() + ".json");
+                log.info("下载成功");
             } catch (Exception e) {
-                log.error("e:{}", e.getMessage());
+                log.warn("下载失败", e);
             }
-
             try {
-                //24小时的数据
-                hour = 24;
-                for (PublishInfo publishInfo : publishList) {
-                    String result = getResult(BASE_URL + "/getForePrecipData?publishDT=" + publishInfo.getPublishDT() + "&divisionCode=" + divisionCode + "&hour=" + hour + "&ensemble=" + ensemble + "&foreTime=" + 240);
-                    writeFile(result, downloadFilePath + "FRD," + publishInfo.getPublishDT() + "," + divisionCode + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-                }
-            } catch (Exception e) {
-                log.error(e.getMessage(), e);
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                // ignore ...
             }
 
-        } else {
-            log.error("获取到预报批次数据异常:{}", code);
-        }
-    }
-
-
-    /**
-     * 获取29分区的数据1h小时数据和24小时
-     */
-    private void getForecast29Data(String startTime, String endTime) {
-        String divisionCode = "LCJ_DIV29";
-        int hour = 1;
-        String url = BASE_URL + "/getForePrecipPublishDT?divisionCode=" + divisionCode + "&hour=" + hour + "&ensemble=" + ensemble + "&startTime=" + startTime + "&endTime=" + endTime;
-        String batchResult = getResult(url);
-        JSONObject json = JSONObject.parseObject(batchResult);
-        Integer code = json.getInteger("code");
-        if (code == 200) {
-            writeFile(batchResult, downloadFilePath + "FRB," + divisionCode + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-            List<PublishInfo> publishList = json.getJSONArray("data").toJavaList(PublishInfo.class);
             try {
-                for (PublishInfo publishInfo : publishList) {
-                    String result = getResult(BASE_URL + "/getForePrecipData?publishDT=" + publishInfo.getPublishDT() + "&divisionCode=" + divisionCode + "&hour=" + hour + "&ensemble=" + ensemble + "&foreTime=" + 240);
-                    writeFile(result, downloadFilePath + "FRD," + publishInfo.getPublishDT() + "," + divisionCode + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-                }
+                int hour2 = 24;
+                String url2 = BASE_URL + "/getForePrecipData?publishDT=" + publishInfo.getPublishDT() + "&divisionCode=" + divisionCode + "&hour=" + hour2 + "&ensemble=" + ensemble;
+                log.info("下载流域{}分区降水预报数据(日尺度):{}", divNum, url2);
+                String result = getResult(url2);
+                writeFile(result, downloadFilePath + "FRD," + publishInfo.getPublishDT() + "," + divisionCode + "," + hour2 + "," + ensemble + "," + System.currentTimeMillis() + ".json");
+                log.info("下载成功");
             } catch (Exception e) {
-                log.error(e.getMessage(), e);
+                log.warn("下载失败", e);
             }
             try {
-                hour = 24;
-                for (PublishInfo publishInfo : publishList) {
-                    String result = getResult(BASE_URL + "/getForePrecipData?publishDT=" + publishInfo.getPublishDT() + "&divisionCode=" + divisionCode + "&hour=" + hour + "&ensemble=" + ensemble + "&foreTime=" + 240);
-                    writeFile(result, downloadFilePath + "FRD," + publishInfo.getPublishDT() + "," + divisionCode + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-                }
-            } catch (Exception e) {
-                log.error(e.getMessage(), e);
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                // ignore ...
             }
-        } else {
-            log.error("获取到预报批次数据异常:{}", code);
         }
     }
 
+
     /**
-     * 获取融雪数据
+     * 下载澜沧江上游高程带融雪覆盖预报
      */
-    private void getDomainSnow() {
+    public void downloadSnowCover(String publishDt) {
+        log.info("###开始下载澜沧江上游高程带融雪覆盖预报");
         //融雪数据从本地获取
         List<String> cdNewList = new LinkedList<>();
         if (new File(snowCdFile).exists()) {
@@ -217,8 +186,8 @@ public class QxybDataService {
             if (StringUtils.isEmpty(first)) {
                 return;
             }
-            String yyyyMMdd = DateUtil.parseLocalDateTime(first.split(",")[0], "yyyy-MM-dd").minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
-            writeFile(cdNewList, downloadFilePath + "DomainSnow,cd," + yyyyMMdd + "_12_192," + ensemble + "," + System.currentTimeMillis() + ".txt");
+            //String yyyyMMdd = DateUtil.parseLocalDateTime(first.split(",")[0], "yyyy-MM-dd").minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+            writeFile(cdNewList, downloadFilePath + "DomainSnow,cd," + publishDt + "," + ensemble + "," + System.currentTimeMillis() + ".txt");
         }
         if (new File(snowQzkFile).exists()) {
             List<String> qzkNewList = new LinkedList<>();
@@ -238,142 +207,214 @@ public class QxybDataService {
             if (StringUtils.isEmpty(first)) {
                 return;
             }
-            String yyyyMMdd = DateUtil.parseLocalDateTime(first.split(",")[0], "yyyy-MM-dd").minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
-            writeFile(qzkNewList, downloadFilePath + "DomainSnow,qzk," + yyyyMMdd + "_12_192," + ensemble + "," + System.currentTimeMillis() + ".txt");
+            //String yyyyMMdd = DateUtil.parseLocalDateTime(first.split(",")[0], "yyyy-MM-dd").minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+            writeFile(qzkNewList, downloadFilePath + "DomainSnow,qzk," + publishDt + "," + ensemble + "," + System.currentTimeMillis() + ".txt");
         }
+        log.info("###结束下载澜沧江上游高程带融雪覆盖预报");
     }
 
     /**
-     * 获取昌都、曲孜卡的13个区域的降雨和温度数据
+     * 下载澜沧江上游高程带降水和气温预报
      */
     private void getDomainTempAndRain(String startTime, String endTime) {
+        List<PublishInfo> publishList = null;
         String divisionCode = "LCJ_DGD";
         int hour = 24;
-        String url = BASE_URL + "/getForePrecipPublishDT?divisionCode=" + divisionCode + "&hour=" + hour + "&ensemble=" + ensemble + "&startTime=" + startTime + "&endTime=" + endTime;
-        String batchResult = getResult(url);
-        JSONObject json = JSONObject.parseObject(batchResult);
-        Integer code = json.getInteger("code");
-        if (code == 200) {
+        try {
+            String url = BASE_URL + "/getForePrecipPublishDT?divisionCode=" + divisionCode + "&hour=" + hour + "&ensemble=" + ensemble + "&startTime=" + startTime + "&endTime=" + endTime;
+            log.info("下载澜沧江上游高程带降水和气温预报批次:{}", url);
+            String batchResult = getResult(url);
+            JSONObject json = JSONObject.parseObject(batchResult);
+            publishList = json.getJSONArray("data").toJavaList(PublishInfo.class);
             writeFile(batchResult, downloadFilePath + "DomainBatch," + divisionCode + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-            List<PublishInfo> publishList = json.getJSONArray("data").toJavaList(PublishInfo.class);
-            //降雨数据
+            log.info("下载成功");
+        } catch (Exception e) {
+            log.warn("下载失败", e);
+            return;
+        }
+
+        for (PublishInfo publishInfo : publishList) {
             try {
-                for (PublishInfo publishInfo : publishList) {
-                    String result = getResult(BASE_URL + "/getForePrecipData?publishDT=" + publishInfo.getPublishDT() + "&divisionCode=" + divisionCode + "&hour=" + hour + "&ensemble=" + ensemble + "&foreTime=" + 240);
-                    writeFile(result, downloadFilePath + "DomainRain," + publishInfo.getPublishDT() + "," + divisionCode + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-                }
+                String url2 = BASE_URL + "/getForePrecipData?publishDT=" + publishInfo.getPublishDT() + "&divisionCode=" + divisionCode + "&hour=" + hour + "&ensemble=" + ensemble;
+                log.info("下载澜沧江上游高程带降水数据(日尺度):{}", url2);
+                String result = getResult(url2);
+                writeFile(result, downloadFilePath + "DomainRain," + publishInfo.getPublishDT() + "," + divisionCode + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
+                log.info("下载成功");
             } catch (Exception e) {
-                log.error(e.getMessage(), e);
+                log.warn("下载失败", e);
+                return;
             }
             try {
-                //温度
-                for (PublishInfo publishInfo : publishList) {
-                    String result = getResult(BASE_URL + "/getT_Forecast_24h_avg_division?divisionCode=" + divisionCode + "&ensemble=" + ensemble + "&publishDT=" + publishInfo.getPublishDT() + "&foreTime=" + 240);
-                    writeFile(result, downloadFilePath + "DomainTemp," + publishInfo.getPublishDT() + "," + divisionCode + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-                }
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                // ignore...
+            }
+        }
+
+        for (PublishInfo publishInfo : publishList) {
+            try {
+                String url2 = BASE_URL + "/getT_Forecast_24h_avg_division?divisionCode=" + divisionCode + "&ensemble=" + ensemble + "&publishDT=" + publishInfo.getPublishDT();
+                log.info("下载澜沧江上游高程带气温数据(日尺度):{}", url2);
+                String result = getResult(url2);
+                writeFile(result, downloadFilePath + "DomainTemp," + publishInfo.getPublishDT() + "," + divisionCode + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
+                log.info("下载成功");
             } catch (Exception e) {
-                log.error(e.getMessage(), e);
+                log.warn("下载失败", e);
+                return;
+            }
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                // ignore...
             }
-        } else {
-            log.error("获取到预报批次数据异常:{}", code);
         }
+
     }
 
     /**
-     * 获取站点温度
+     * 下载流域站点气温预报
      */
-    private void getForeTempData(String startTime, String endTime) {
-        String url = BASE_URL + "/getForeTempPublishDT?RDField=" + RDField + "&ensemble=" + ensemble + "&startTime=" + startTime + "&endTime=" + endTime;
-        String batchResult = getResult(url);
-        JSONObject json = JSONObject.parseObject(batchResult);
-        Integer code = json.getInteger("code");
-        if (code == 200) {
+    private void downloadStationTempData(String startTime, String endTime) {
+        List<PublishInfo> publishList = null;
+        try {
+            String url = BASE_URL + "/getForeTempPublishDT?RDField=" + RDField + "&ensemble=" + ensemble + "&startTime=" + startTime + "&endTime=" + endTime;
+            log.info("下载流域站点气温预报批次:{}", url);
+            String batchResult = getResult(url);
+            JSONObject json = JSONObject.parseObject(batchResult);
+            publishList = json.getJSONArray("data").toJavaList(PublishInfo.class);
             writeFile(batchResult, downloadFilePath + "TempSiteBatch," + this.toyyyy_MM_dd_HH_mm_ss(startTime) + "," + this.toyyyy_MM_dd_HH_mm_ss(endTime) + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-            List<PublishInfo> publishList = json.getJSONArray("data").toJavaList(PublishInfo.class);
+            log.info("下载成功");
+        } catch (Exception e) {
+            log.warn("下载失败", e);
+            return;
+        }
+
+        for (PublishInfo publishInfo : publishList) {
             try {
-                for (PublishInfo publishInfo : publishList) {
-                    int hour = 1;
-                    String getForeTempUrl = BASE_URL + "/getForeTempData?publishDT=" + publishInfo.getPublishDT() + "&RDField=" + RDField + "&ensemble=" + ensemble + "&foreTime=" + 240;
-                    String result = getResult(getForeTempUrl);
-                    writeFile(result, downloadFilePath + "TempSiteData," + publishInfo.getPublishDT() + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-                }
+                int hour = 1;
+                String getForeTempUrl = BASE_URL + "/getForeTempData?publishDT=" + publishInfo.getPublishDT() + "&RDField=" + RDField + "&ensemble=" + ensemble;
+                log.info("下载流域站点气温预报数据(小时尺度):{}", getForeTempUrl);
+                String result = getResult(getForeTempUrl);
+                writeFile(result, downloadFilePath + "TempSiteData," + publishInfo.getPublishDT() + "," + hour + "," + ensemble + "," + System.currentTimeMillis() + ".json");
+                log.info("下载成功");
             } catch (Exception e) {
-                log.error(e.getMessage(), e);
+                log.warn("下载失败", e);
+            }
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                // ignore...
             }
-        } else {
-            log.error("获取到预报批次数据异常:{}", code);
+
         }
+
     }
 
     /**
-     * 获取网格数据,包含温度网格,降雨网格
+     * 网格降水/温度预报
      */
-    private void getGridData(String startTime, String endTime) {
-        String url = BASE_URL + "/getForecastBaseInfo?RDField=" + RDField + "&domain=" + domain + "&ensemble=" + ensemble + "&startTime=" + startTime + "&endTime=" + endTime;
-        String batchResult = getResult(url);
-        JSONObject json = JSONObject.parseObject(batchResult);
-        Integer code = json.getInteger("code");
-        if (code == 200) {
+    private void downloadGridRainAndTempData(String startTime, String endTime) {
+        List<PublishInfo> publishList = null;
+        try {
+            String url = BASE_URL + "/getForecastBaseInfo?RDField=" + RDField + "&domain=" + domain + "&ensemble=" + ensemble + "&startTime=" + startTime + "&endTime=" + endTime;
+            log.info("下载网格降水/温度预报批次:{}", url);
+            String batchResult = getResult(url);
+            JSONObject json = JSONObject.parseObject(batchResult);
+            publishList = json.getJSONObject("data").getJSONArray("publishInfoList").toJavaList(PublishInfo.class);
             writeFile(batchResult, downloadFilePath + "GridBatch," + this.toyyyy_MM_dd_HH_mm_ss(startTime) + "," + this.toyyyy_MM_dd_HH_mm_ss(endTime) + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-            List<PublishInfo> publishInfoList = json.getJSONObject("data").getJSONArray("publishInfoList").toJavaList(PublishInfo.class);
-            //查询1小时的降雨和温度
-            for (PublishInfo publishInfo : publishInfoList) {
-                //获取这个批次的每个时间点数据,根据publishTime的次日0时开始算240个小时
-//                int duration = Integer.parseInt(publishInfo.getPublishDT().split("_")[2]);
-                int duration = 240;
-                LocalDateTime publishTime = LocalDateTime.parse(publishInfo.getPublishTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-//                LocalDateTime st = publishTime.plusHours(12);
-                //网格降水和温度都是从次日1时开始
-                LocalDateTime st = LocalDateTime.of(publishTime.getYear(), publishTime.getMonthValue(), publishTime.getDayOfMonth(), 1, 0, 0).plusDays(1);
+            log.info("下载成功");
+        } catch (Exception e) {
+            log.warn("下载失败", e);
+            return;
+        }
 
+
+        for (PublishInfo publishInfo : publishList) {
+            String publishTime = publishInfo.getPublishTime();
+            String publishDT = publishInfo.getPublishDT();
+            String[] strings = publishDT.split("_");
+            String timeFlg = strings[1];
+            LocalDateTime ldtPulishTime = LocalDateTime.parse(publishTime, DATE_TIME_FORMATTER);
+            LocalDate date = ldtPulishTime.toLocalDate();
+
+            List<LocalDateTime> hoursForGridRain = getHoursForGridRain(timeFlg, date);
+            hoursForGridRain.forEach(hour -> {
                 try {
-                    //1小时雨量
-                    for (int i = 0; i <= duration; i++) {
-//                        int hour = 1;
-//                        String content = "precipitation";
-                        LocalDateTime dateTime = st.plusHours(i);
-                        String dt1 = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH_mm_ss"));
-                        String dt2 = dateTime.plusHours(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH_mm_ss"));
-                        String result = getResult(BASE_URL + "/getForecastMatrixByWrfRDField?RDField=" + RDField + "&publishDT=" + publishInfo.getPublishDT() + "&ensemble=" + publishInfo.getEnsemble() + "&domain=" + domain + "&content=precipitation&DT1=" + dt1 + "&DT2=" + dt2 + "&step=" + 1);
-                        writeFile(result, downloadFilePath + "RainGrid," + publishInfo.getPublishDT() + "," + dt1 + "," + 1 + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-                    }
+                    String dt1 = hour.format(DATE_TIME_FORMATTER1);
+                    String dt2 = hour.plusHours(1).format(DATE_TIME_FORMATTER1);
+                    String url2 = BASE_URL + "/getForecastMatrixByWrfRDField?RDField=" + RDField + "&publishDT=" + publishInfo.getPublishDT() + "&ensemble=" + publishInfo.getEnsemble() + "&domain=" + domain + "&content=precipitation&DT1=" + dt1 + "&DT2=" + dt2 + "&step=" + 1;
+                    log.info("下载网格降水预报数据(小时尺度):{}", url2);
+                    String result = getResult(url2);
+                    writeFile(result, downloadFilePath + "RainGrid," + publishInfo.getPublishDT() + "," + dt1 + "," + 1 + "," + ensemble + "," + System.currentTimeMillis() + ".json");
+                    log.info("下载成功");
                 } catch (Exception e) {
-                    log.error(e.getMessage(), e);
+                    log.warn("下载失败", e);
                 }
                 try {
-                    LocalDateTime st24 = LocalDateTime.of(publishTime.getYear(), publishTime.getMonthValue(), publishTime.getDayOfMonth(), 0, 0, 0).plusDays(1);
-                    //24小时雨量
-                    for (int i = 0; i <= duration / 24; i++) {
-//                        int hour = 24;
-//                        String content = "precipitation";
-                        LocalDateTime dateTime = st24.plusDays(i);
-                        String dt1 = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH_mm_ss"));
-                        String dt2 = dateTime.plusHours(24).format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH_mm_ss"));
-                        String result = getResult(BASE_URL + "/getForecastMatrixByWrfRDField?RDField=" + RDField + "&publishDT=" + publishInfo.getPublishDT() + "&ensemble=" + publishInfo.getEnsemble() + "&domain=" + domain + "&content=precipitation&DT1=" + dt1 + "&DT2=" + dt2 + "&step=" + 24);
-                        writeFile(result, downloadFilePath + "RainGrid," + publishInfo.getPublishDT() + "," + dt1 + "," + 24 + "," + ensemble + "," + System.currentTimeMillis() + ".json");
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                    // ignore...
+                }
+            });
+
+            List<LocalDate> daysForGridRain = getDaysForGridRain(timeFlg, date);
+            daysForGridRain.forEach(day -> {
+                try {
+                    LocalTime time = LocalTime.of(0, 0);
+                    if("00".equals(timeFlg)){
+                        time = LocalTime.of(12, 0);
+                    } else if ("06".equals(timeFlg)) {
+                        time = LocalTime.of(18, 0);
+                    }else if ("12".equals(timeFlg)) {
+                        time = LocalTime.of(0, 0);
+                    }else if ("18".equals(timeFlg)) {
+                        time = LocalTime.of(6, 0);
                     }
+                    String dt1 = LocalDateTime.of(day, time) .format(DATE_TIME_FORMATTER1);
+                    String dt2 = LocalDateTime.of(day.plusDays(1), time).format(DATE_TIME_FORMATTER1);
+                    String url2 = BASE_URL + "/getForecastMatrixByWrfRDField?RDField=" + RDField + "&publishDT=" + publishInfo.getPublishDT() + "&ensemble=" + publishInfo.getEnsemble() + "&domain=" + domain + "&content=precipitation&DT1=" + dt1 + "&DT2=" + dt2 + "&step=" + 24;
+                    log.info("下载网格降水预报数据(日尺度):{}", url2);
+                    String result = getResult(url2);
+                    writeFile(result, downloadFilePath + "RainGrid," + publishInfo.getPublishDT() + "," + dt1 + "," + 24 + "," + ensemble + "," + System.currentTimeMillis() + ".json");
+                    log.info("下载成功");
                 } catch (Exception e) {
-                    log.error(e.getMessage(), e);
+                    log.warn("下载失败", e);
+                }
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                    // ignore...
                 }
+            });
 
+            List<LocalDateTime> hoursForGridTemp = getHoursForGridTemp(timeFlg, date);
+            hoursForGridTemp.forEach(hour -> {
                 try {
-                    //1小时温度
-                    for (int i = 0; i <= duration; i++) {
-//                        int hour = 1;
-//                        String content = "2mTC";
-                        LocalDateTime dateTime = st.plusHours(i);
-                        String dt1 = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH_mm_ss"));
-                        String result = getResult(BASE_URL + "/getForecastMatrixByWrfRDField?RDField=" + RDField + "&publishDT=" + publishInfo.getPublishDT() + "&ensemble=" + publishInfo.getEnsemble() + "&domain=" + domain + "&content=2mTC&DT1=" + dt1 + "&step=" + 1);
-                        writeFile(result, downloadFilePath + "TempGrid," + publishInfo.getPublishDT() + "," + dt1 + "," + 1 + "," + ensemble + "," + System.currentTimeMillis() + ".json");
-                    }
+                    String dt1 = hour.format(DATE_TIME_FORMATTER1);
+                    String url2 = BASE_URL + "/getForecastMatrixByWrfRDField?RDField=" + RDField + "&publishDT="
+                            + publishInfo.getPublishDT() + "&ensemble="
+                            + publishInfo.getEnsemble() + "&domain="
+                            + domain + "&content=2mTC&DT1="
+                            + dt1 + "&step=" + 1;
+                    log.info("下载网格气温预报数据(小时尺度):{}", url2);
+                    String result = getResult(url2);
+                    writeFile(result, downloadFilePath + "TempGrid," + publishInfo.getPublishDT()
+                            + "," + dt1 + "," + 1 + "," + ensemble + ","
+                            + System.currentTimeMillis() + ".json");
+                    log.info("下载成功");
                 } catch (Exception e) {
-                    log.error(e.getMessage(), e);
+                    log.warn("下载失败", e);
                 }
-            }
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                    // ignore...
+                }
+            });
+
 
-        } else {
-            log.error("获取到预报批次数据异常:{}", batchResult);
         }
+
     }
 
     /**
@@ -387,13 +428,6 @@ public class QxybDataService {
     }
 
     private String getResult(String url) {
-        log.info("<< {}", url);
-        OkHttpClient client = new OkHttpClient().newBuilder()
-                .connectTimeout(30, TimeUnit.SECONDS)
-                .readTimeout(600, TimeUnit.SECONDS)
-                .writeTimeout(180, TimeUnit.SECONDS)
-                .build();
-
         Request request = new Request.Builder()
                 .url(url)
                 .get()
@@ -403,20 +437,27 @@ public class QxybDataService {
         try {
             response = client.newCall(request).execute();
             result = response.body().string();
+            JSONObject json = JSONObject.parseObject(result);
+            Integer code = json.getInteger("code");
+            if (code == 200) {
+                return result;
+            } else {
+                throw new RuntimeException(result);
+            }
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
-        return result;
     }
 
-    private File writeFile(List<String> lines, String path){
+    private File writeFile(List<String> lines, String path) {
+        if (lines == null) return null;
         log.info(">> {}", path);
         return FileUtil.writeUtf8Lines(lines, path);
     }
 
     private File writeFile(String content, String path) {
+        if (content == null) return null;
         log.info(">> {}", path);
-
         return FileUtil.writeUtf8String(content, path);
     }
 
@@ -425,6 +466,142 @@ public class QxybDataService {
         return FileUtil.readUtf8Lines(path);
     }
 
+    /**
+     * 流域15分区网格降水预报(日尺度)日期序列
+     *
+     * @param timeFlg 日批次:00、06、12、18
+     * @param date    发布日期
+     * @return
+     */
+    private static List<LocalDate> getDaysForDiv15Rain(String timeFlg, LocalDate date) {
+        List<LocalDate> list = new ArrayList<>();
+        LocalDate startDate = date.plusDays(1);
+        int days = 0;
+        switch (timeFlg) {
+            case "00":
+            case "06":
+            case "18":
+                days = 3;
+                break;
+            case "12":
+                days = 14;
+                break;
+            default:
+                throw new RuntimeException("日批次号无效");
+                //break;
+        }
+        for (int i = 0; i < days; list.add(startDate.plusDays(i++))) ;
+        return list;
+    }
+
+
+    /**
+     * 流域网格降水预报(小时尺度)小时序列
+     *
+     * @param timeFlg 日批次:00、06、12、18
+     * @param date    发布日期
+     * @return
+     */
+    private static List<LocalDateTime> getHoursForGridRain(String timeFlg, LocalDate date) {
+        List<LocalDateTime> list = new ArrayList<>();
+        LocalDateTime startTime = null;
+        int hours = 0;
+        switch (timeFlg) {
+            case "00":
+                hours = 84;
+                startTime = LocalDateTime.of(date, LocalTime.of(12, 0, 0));
+                break;
+            case "06":
+                hours = 84;
+                startTime = LocalDateTime.of(date, LocalTime.of(18, 0, 0));
+                break;
+            case "12":
+                hours = 348;
+                startTime = LocalDateTime.of(date.plusDays(1), LocalTime.of(0, 0, 0));
+                break;
+            case "18":
+                hours = 84;
+                startTime = LocalDateTime.of(date.plusDays(1), LocalTime.of(6, 0, 0));
+                break;
+            default:
+                throw new RuntimeException("日批次号无效");
+                //break;
+        }
+        for (int i = 0; i < hours; list.add(startTime.plusHours(i++))) ;
+        return list;
+    }
+
+    /**
+     * 流域网格气温预报(小时尺度)小时序列
+     *
+     * @param timeFlg 日批次:00、06、12、18
+     * @param date    发布日期
+     * @return
+     */
+    private static List<LocalDateTime> getHoursForGridTemp(String timeFlg, LocalDate date) {
+        List<LocalDateTime> list = new ArrayList<>();
+        LocalDateTime startTime = null;
+        int hours = 0;
+        switch (timeFlg) {
+            case "00":
+                hours = 85;
+                startTime = LocalDateTime.of(date, LocalTime.of(12, 0, 0));
+                break;
+            case "06":
+                hours = 85;
+                startTime = LocalDateTime.of(date, LocalTime.of(18, 0, 0));
+                break;
+            case "12":
+                hours = 340;
+                startTime = LocalDateTime.of(date.plusDays(1), LocalTime.of(0, 0, 0));
+                break;
+            case "18":
+                hours = 85;
+                startTime = LocalDateTime.of(date.plusDays(1), LocalTime.of(6, 0, 0));
+                break;
+            default:
+                throw new RuntimeException("日批次号无效");
+                //break;
+        }
+        for (int i = 0; i < hours; list.add(startTime.plusHours(i++))) ;
+        return list;
+    }
+
+    /**
+     * 流域网格降水预报(日尺度)日期序列
+     *
+     * @param timeFlg 日批次:00、06、12、18
+     * @param date    发布日期
+     * @return
+     */
+    private static List<LocalDate> getDaysForGridRain(String timeFlg, LocalDate date) {
+        List<LocalDate> list = new ArrayList<>();
+
+        LocalDate startDate = null;
+        int days = 0;
+        switch (timeFlg) {
+            case "00":
+                days = 3;
+                startDate = date;
+                break;
+            case "06":
+            case "18":
+                days = 3;
+                startDate = date.plusDays(1);
+                break;
+            case "12":
+                startDate = date.plusDays(1);
+                days = 14;
+                break;
+            default:
+                throw new RuntimeException("日批次号无效");
+                //break;
+        }
+        for (int i = 0; i < days; list.add(startDate.plusDays(i++))) ;
+        return list;
+    }
+
+
 //    public String getYbStartTime() {
 //        if (ybFixedTime) {
 //            DateTime date = DateUtil.parse(ybStartTime, "yyyy_MM_dd_HH_mm_ss");

+ 6 - 5
tongfei_river_data_collection/src/main/java/com/ublinkage/datacollection/service/SatelliteRadarImageDataService.java

@@ -20,6 +20,7 @@ import java.util.List;
 @Service
 public class SatelliteRadarImageDataService {
     public static final String BASE_URL = "http://www.nmc.cn/";
+    public static final int TIMEOUT = 60_000;
 
     @Value("${yb.fixedTime}")
     private Boolean ybFixedTime;
@@ -53,7 +54,7 @@ public class SatelliteRadarImageDataService {
         log.info("下载FY4A红外图片");
         String url = BASE_URL + "publish/satellite/FY4A-infrared.htm";
         try {
-            Document doc = Jsoup.connect(url).timeout(10000).get();
+            Document doc = Jsoup.connect(url).timeout(TIMEOUT).get();
             Elements HYS = doc.getElementsByClass("col-xs-12 time ");
             Elements e = doc.getElementsByClass("col-xs-12 time actived");
             HYS.add(e.get(0));
@@ -116,7 +117,7 @@ public class SatelliteRadarImageDataService {
         log.info("下载FY4A真彩色图片");
         String url = BASE_URL + "publish/satellite/FY4A-true-color.htm";
         try {
-            Document doc = Jsoup.connect(url).timeout(10000).get();
+            Document doc = Jsoup.connect(url).timeout(TIMEOUT).get();
             Elements HYS = doc.getElementsByClass("col-xs-12 time ");
             Elements e = doc.getElementsByClass("col-xs-12 time actived");
             HYS.add(e.get(0));
@@ -180,7 +181,7 @@ public class SatelliteRadarImageDataService {
         log.info("下载FY4A水汽图片");
         String url = BASE_URL + "publish/satellite/FY4A-water-vapour.htm";
         try {
-            Document doc = Jsoup.connect(url).timeout(10000).get();
+            Document doc = Jsoup.connect(url).timeout(TIMEOUT).get();
             Elements HYS = doc.getElementsByClass("col-xs-12 time ");
             Elements e = doc.getElementsByClass("col-xs-12 time actived");
             HYS.add(e.get(0));
@@ -243,7 +244,7 @@ public class SatelliteRadarImageDataService {
         log.info("下载增强图片");
         String url = BASE_URL + "publish/satellite/fy2e/water_vapor.html";
         try {
-            Document doc = Jsoup.connect(url).timeout(10000).get();
+            Document doc = Jsoup.connect(url).timeout(TIMEOUT).get();
             Elements HYS = doc.getElementsByClass("col-xs-12 time ");
             Elements e = doc.getElementsByClass("col-xs-12 time actived");
             HYS.add(e.get(0));
@@ -306,7 +307,7 @@ public class SatelliteRadarImageDataService {
         log.info("下载全国雷达拼图图片");
         String url = BASE_URL + "publish/radar/chinaall.html";
         try {
-            Document doc = Jsoup.connect(url).timeout(10000).get();
+            Document doc = Jsoup.connect(url).timeout(TIMEOUT).get();
             Elements HYS = doc.getElementsByClass("col-xs-12 time ");
             Elements e = doc.getElementsByClass("col-xs-12 time actived");
             HYS.add(e.get(0));