From a2ee6e0dcdcfd9d1b8011a3cecb4e0fc4f6eeea3 Mon Sep 17 00:00:00 2001
From: dcb <xgybdcb@163.com>
Date: 星期五, 06 六月 2025 18:10:32 +0800
Subject: [PATCH] 实时模拟功能实现

---
 src/main/java/com/se/nsl/controller/SimuController.java |   40 +++++
 /dev/null                                               |   10 -
 src/main/java/com/se/nsl/domain/vo/ResultVo.java        |   13 +
 src/main/java/com/se/nsl/utils/SimulateType.java        |   35 ++++
 src/main/java/com/se/nsl/service/ResolveService.java    |  190 +++++++++++++++++------
 src/main/java/com/se/nsl/utils/TimeFormatUtil.java      |   33 ++++
 src/main/java/com/se/nsl/service/TestService.java       |   43 ++++-
 src/main/java/com/se/nsl/domain/dto/LayerDto.java       |   12 +
 src/main/java/com/se/nsl/domain/vo/RealTimeInput.java   |   47 +++++
 src/main/java/com/se/nsl/domain/vo/ConfigVo.java        |    6 
 src/main/java/com/se/nsl/service/SimuService.java       |   12 
 src/main/java/com/se/nsl/utils/RainFallUnit.java        |   36 ++++
 12 files changed, 399 insertions(+), 78 deletions(-)

diff --git a/src/main/java/com/se/nsl/controller/SimuController.java b/src/main/java/com/se/nsl/controller/SimuController.java
index 0aa1c78..8477d8b 100644
--- a/src/main/java/com/se/nsl/controller/SimuController.java
+++ b/src/main/java/com/se/nsl/controller/SimuController.java
@@ -6,11 +6,14 @@
 import com.se.nsl.domain.po.Simu;
 import com.se.nsl.domain.po.SimuData;
 import com.se.nsl.domain.vo.R;
+import com.se.nsl.domain.vo.RealTimeInput;
 import com.se.nsl.domain.vo.SimuResult;
 import com.se.nsl.domain.vo.SimuVo;
 import com.se.nsl.service.ResolveService;
 import com.se.nsl.service.SimuService;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.gdal.ogr.Geometry;
@@ -19,6 +22,10 @@
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
 import java.util.List;
 
 @Api(tags = "03锛嶆帹婕旀ā鎷�")
@@ -183,4 +190,37 @@
         }
         return success(result);
     }
+
+    @ApiOperation(value = "realTime")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "date1", value = "5鍒嗛挓鍓嶇殑鏃堕棿锛屾牸寮忎负2025-05-31 14:15:20"),
+            @ApiImplicitParam(name = "rainfall1", value = "5鍒嗛挓鍓嶇殑闄嶉洦寮哄害"),
+            @ApiImplicitParam(name = "date2", value = "褰撳墠鏃堕棿锛屾牸寮忎负2025-05-31 14:20:20"),
+            @ApiImplicitParam(name = "rainfall2", value = "褰撳墠鐨勯檷闆ㄥ己搴�"),
+            @ApiImplicitParam(name = "serviceName", value = "鏈嶅姟鍚�")
+    })
+    @GetMapping("/realTime")
+    public R<Object> realTimeSimulate(String date1, double rainfall1,
+                                      String date2, double rainfall2, String serviceName) {
+        RealTimeInput input = new RealTimeInput();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        LocalDateTime t1 = LocalDateTime.parse(date1, formatter);
+        LocalDateTime t2 = LocalDateTime.parse(date2, formatter);
+        RealTimeInput.RealTimeData d1 = new RealTimeInput.RealTimeData();
+        d1.setDateTime(t1);
+        d1.setIntensity(rainfall1);
+        RealTimeInput.RealTimeData d2 = new RealTimeInput.RealTimeData();
+        d2.setDateTime(t2);
+        d2.setIntensity(rainfall2);
+        input.setData(Arrays.asList(d1, d2));
+        input.setServiceName(serviceName);
+
+        try {
+            String layerJsonName = resolveService.realTimeSimulate(input);
+            return success(layerJsonName);
+        } catch (IOException e) {
+            log.error("real-time simulate exception:", e);
+            return fail("瀹炴椂妯℃嫙寮傚父");
+        }
+    }
 }
diff --git a/src/main/java/com/se/nsl/domain/dto/LayerDto.java b/src/main/java/com/se/nsl/domain/dto/LayerDto.java
index ac0d4b1..1250d2b 100644
--- a/src/main/java/com/se/nsl/domain/dto/LayerDto.java
+++ b/src/main/java/com/se/nsl/domain/dto/LayerDto.java
@@ -6,6 +6,8 @@
 public class LayerDto {
     private String version;
 
+    private String name; //鐢熸垚json鐨勫悕瀛楋紝榛樿浣峫ayer.json
+
     private DurationDto duration;
 
     private ExtensionDto extension;
@@ -19,9 +21,11 @@
     private String flowUrl;
 
     public LayerDto() {
+        this.name = "layer.json";
     }
 
     public LayerDto(String ver, int epsg, List<Integer> sizes) {
+        this();
         this.version = ver;
         this.waters = new WaterDto();
         this.duration = new DurationDto();
@@ -37,6 +41,14 @@
         this.version = version;
     }
 
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
     public DurationDto getDuration() {
         return duration;
     }
diff --git a/src/main/java/com/se/nsl/domain/vo/ConfigVo.java b/src/main/java/com/se/nsl/domain/vo/ConfigVo.java
index a783741..cd8eafe 100644
--- a/src/main/java/com/se/nsl/domain/vo/ConfigVo.java
+++ b/src/main/java/com/se/nsl/domain/vo/ConfigVo.java
@@ -46,7 +46,9 @@
         this.variable_dt = true;
     }
 
-    public ConfigVo(String terrain, String landuse, String station, String raingage, String saveName, int duration, int frames) {
+    public ConfigVo(String terrain, String landuse, String station,
+                    String raingage, String saveName, int duration,
+                    int frames, String saveMode) {
         this();
 
 //        this.terrain.set(0, terrain.replace("\\", "/")); // 鍦板舰楂樼▼鏁版嵁
@@ -58,7 +60,7 @@
         this.raingage = Arrays.asList(raingage, "mm/min");
         this.duration = duration;
         int saveInterval = duration / frames - 5; // 淇鏈�鍚庝竴甯у彲鑳戒负绌烘暟鎹�
-        this.result = new ResultVo(saveName, frames, saveInterval);
+        this.result = new ResultVo(saveName, frames, saveInterval, saveMode);
     }
 
     public String getTerrain() {
diff --git a/src/main/java/com/se/nsl/domain/vo/RealTimeInput.java b/src/main/java/com/se/nsl/domain/vo/RealTimeInput.java
new file mode 100644
index 0000000..eb9c65b
--- /dev/null
+++ b/src/main/java/com/se/nsl/domain/vo/RealTimeInput.java
@@ -0,0 +1,47 @@
+package com.se.nsl.domain.vo;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public class RealTimeInput {
+
+    private List<RealTimeData> data;
+    private String serviceName;
+
+    public static class RealTimeData {
+        private LocalDateTime dateTime;
+        private double intensity;
+
+        public LocalDateTime getDateTime() {
+            return dateTime;
+        }
+
+        public void setDateTime(LocalDateTime dateTime) {
+            this.dateTime = dateTime;
+        }
+
+        public double getIntensity() {
+            return intensity;
+        }
+
+        public void setIntensity(double intensity) {
+            this.intensity = intensity;
+        }
+    }
+
+    public List<RealTimeData> getData() {
+        return data;
+    }
+
+    public void setData(List<RealTimeData> data) {
+        this.data = data;
+    }
+
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    public void setServiceName(String serviceName) {
+        this.serviceName = serviceName;
+    }
+}
diff --git a/src/main/java/com/se/nsl/domain/vo/ResultVo.java b/src/main/java/com/se/nsl/domain/vo/ResultVo.java
index 44356e2..88b7058 100644
--- a/src/main/java/com/se/nsl/domain/vo/ResultVo.java
+++ b/src/main/java/com/se/nsl/domain/vo/ResultVo.java
@@ -8,6 +8,8 @@
 public class ResultVo {
     private String save_name;
 
+    private String save_mode;
+
     private List<String> save_variables;
 
     private Integer save_frames;
@@ -24,13 +26,14 @@
         this.save_filter = 0;
     }
 
-    public ResultVo(String saveName, int frames, int saveInterval) {
+    public ResultVo(String saveName, int frames, int saveInterval, String saveMode) {
         this();
 
         this.save_name = saveName.replace("\\", "/");
         this.save_frames = frames;
         // 缁撴灉鏁版嵁涓浉閭诲抚鐨勬ā鎷熸椂闂撮棿闅旓紙鍗曚綅锛氱锛夛紝save_start + save_frames * save_interval <= duration
         this.save_interval = saveInterval;
+        this.save_mode = saveMode;
     }
 
     public String getSave_name() {
@@ -41,6 +44,14 @@
         this.save_name = save_name;
     }
 
+    public String getSave_mode() {
+        return save_mode;
+    }
+
+    public void setSave_mode(String save_mode) {
+        this.save_mode = save_mode;
+    }
+
     public List<String> getSave_variables() {
         return save_variables;
     }
diff --git a/src/main/java/com/se/nsl/helper/HDF5ReaderHelper.java b/src/main/java/com/se/nsl/helper/HDF5ReaderHelper.java
deleted file mode 100644
index 34d21f0..0000000
--- a/src/main/java/com/se/nsl/helper/HDF5ReaderHelper.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.se.nsl.helper;
-
-public class HDF5ReaderHelper {
-    public static void main(String[] args) {
-
-
-    }
-
-
-}
diff --git a/src/main/java/com/se/nsl/service/ResolveService.java b/src/main/java/com/se/nsl/service/ResolveService.java
index 5edd663..64c27b4 100644
--- a/src/main/java/com/se/nsl/service/ResolveService.java
+++ b/src/main/java/com/se/nsl/service/ResolveService.java
@@ -4,17 +4,23 @@
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.se.nsl.config.PropertiesConfig;
-import com.se.nsl.domain.dto.Zarr2Tif;
+import com.se.nsl.domain.dto.*;
 import com.se.nsl.domain.po.Rainfall;
 import com.se.nsl.domain.po.Simu;
 import com.se.nsl.domain.po.SimuData;
 import com.se.nsl.domain.vo.ConfigVo;
+import com.se.nsl.domain.vo.RealTimeInput;
+import com.se.nsl.domain.vo.ResultVo;
 import com.se.nsl.helper.ComHelper;
 import com.se.nsl.helper.GdalHelper;
 import com.se.nsl.helper.StringHelper;
 import com.se.nsl.helper.WebHelper;
 import com.se.nsl.utils.AreaType;
+import com.se.nsl.utils.RainFallUnit;
+import com.se.nsl.utils.SimulateType;
+import com.se.nsl.utils.TimeFormatUtil;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.gdal.gdal.Band;
@@ -36,12 +42,11 @@
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
+import java.nio.file.*;
 import java.sql.Timestamp;
 import java.text.SimpleDateFormat;
 import java.time.Instant;
+import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.ExecutorService;
@@ -122,7 +127,7 @@
             createRainfallFile(simu, data);
 
             update(simu, 2, "璋冪敤姹傝В鍣�");
-            callUwSolver(data);
+            callUwSolver(simu, data);
 
             update(simu, 3, "璋冪敤Zarr杞琓if");
             callZarr2tif(data);
@@ -237,30 +242,6 @@
         }
         f.mkdirs();
     }
-    
-    enum RainFallUnit {
-        MM_H("mm/h", 60),
-        MM_15MIN("mm/15min", 15),
-        MM_5MIN("mm/5min", 5),
-        MM_MIN("mm/min", 1);
-        private String unit;
-        private int c; //绯绘暟
-        RainFallUnit(String unit, int c) {
-            this.unit = unit;
-            this.c = c;
-        }
-
-        public static RainFallUnit of(String unit) {
-            RainFallUnit[] values = values();
-            for (RainFallUnit v : values) {
-                if (v.unit.equals(unit)) {
-                    return v;
-                }
-            }
-            return MM_H; //榛樿鎸夌収mm/h璁$畻
-        }
-
-    }
 
     public void createRainfallFile(Simu simu, SimuData data) throws Exception {
         List<Rainfall> rainfalls = data.getRainfalls();
@@ -283,8 +264,8 @@
 //        int unit = StringUtils.isEmpty(data.getIntensityUnit()) || "mm/h".equals(data.getIntensityUnit()) ? 60 : 5;
         String iu = data.getIntensityUnit();
         RainFallUnit rfUnit = RainFallUnit.of(iu);
-        data.setIntensityUnit(rfUnit.unit);
-        int unit = rfUnit.c;
+        data.setIntensityUnit(rfUnit.getUnit());
+        int unit = rfUnit.getC();
         int c = rainfalls.size() - 1;
         for (int i = 0; i < c; i++) {
             Rainfall r1 = rainfalls.get(i);
@@ -325,7 +306,7 @@
     /**
      * 璋冪敤UWSolver
      */
-    public String callUwSolver(SimuData data) throws Exception {
+    public String callUwSolver(Simu simu, SimuData data) throws Exception {
         File uwBat = new File(config.getUwSolverBat());
 
         int duration = 3600 * data.getDuration(); // 绉掓暟
@@ -348,7 +329,10 @@
 //        ConfigVo vo = new ConfigVo(terrainFile, landuseFile, terrainFile, rainfallFile, saveName, duration, config.getSaveFrames());
         Integer saveFrameInterval = config.getSaveFrameInterval();
         int saveFrames = duration / 60 / saveFrameInterval;
-        ConfigVo vo = new ConfigVo(terrainFile, landuseFile, terrainFile, rainfallFile, saveName, duration, saveFrames);
+        Short type = simu.getType();
+        SimulateType simulateType = SimulateType.of(type);
+        String saveMode = simulateType.getSaveMode();
+        ConfigVo vo = new ConfigVo(terrainFile, landuseFile, terrainFile, rainfallFile, saveName, duration, saveFrames, saveMode);
 
         String configFile = config.getInPath() + File.separator + data.getInPath() + File.separator + data.getInPath() + ".json";
         ComHelper.writeJson(configFile, JSON.toJSONString(vo));
@@ -384,12 +368,9 @@
             Process process = pb.start();
             process.getOutputStream().close();
 
-            //StringBuilder sb = new StringBuilder();
             try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"))) {
                 String line;
                 while ((line = reader.readLine()) != null) {
-//                    System.out.println(line);
-                    //sb.append(line);
                     log.info(line);
                 }
             }
@@ -402,18 +383,6 @@
             return null;
         }
     }
-
-    /*private String callZarr2tif(SimuData data) throws Exception {
-        File uwBat = new File(config.getUwSolverBat());
-        String zarrFile = uwBat.getParent() + File.separator + "result.zarr";
-        String inPath = config.getInPath() + File.separator + data.getInPath();
-        String terrainFile = inPath + File.separator + config.getTerrainFile();
-        String waterPath = inPath + File.separator + "depth";
-
-        String cmd = String.format("%s \"%s\" \"%s\" \"%s\" \"%s\"", config.getZarr2tifBat(), "depth", zarrFile, terrainFile, waterPath);
-
-        return callBat(cmd);
-    }*/
 
     private String callBat(String cmd) {
         try {
@@ -442,9 +411,6 @@
     }
 
     private void createNsl(SimuData data) throws Exception {
-        /*String inPath = config.getInPath() + File.separator + data.getInPath() + File.separator + "depth";
-        procTifs(inPath, inPath, data.getStartTime());*/
-
         testService.test(data);
     }
 
@@ -472,7 +438,6 @@
     public String createRainfallCsv(String csvPath, String mode, double total, double intensity, int hours) {
         // python 鑴氭湰鍚�.py <鍙傛暟1-csv鏂囦欢鍚�> <鍙傛暟2-闄嶉洦妯″紡:姝f�佸垎甯億骞冲潎鍒嗗竷|娉㈠姩骞冲潎鍒嗗竷|鎸佺画涓婂崌> <鍙傛暟3-闄嶉洦鎬婚噺> <鍙傛暟4-鏈�澶ч洦寮�> <鍙傛暟5-闄嶉洦鏃堕棿(鍒嗛挓)>
         String cmd = String.format("%s \"%s\" \"%s\" %f %f %d", config.getCreateRainfall(), csvPath, mode, total, intensity, hours * 60);
-
         return callBat(cmd);
     }
 
@@ -545,4 +510,125 @@
 
         Files.write(Paths.get(dat), list, StandardCharsets.UTF_8);
     }
+
+    //瀹炴椂妯℃嫙
+    public String realTimeSimulate(RealTimeInput input) throws IOException {
+        long currentTime = System.currentTimeMillis();
+        //鏍规嵁鏈嶅姟鎵惧埌鎸囧畾鐨勬枃浠跺す
+        String serviceName = input.getServiceName();
+        File serviceNameDir = new File(config.getInPath(), serviceName);
+        //鐢熸垚涓�涓柊鐨勯洦閲忔枃浠�,闇�瑕佸師鍏堥洦閲忔枃浠剁殑涓�浜涗俊鎭紝鎵�浠ラ渶瑕佸厛璇诲彇鏃х殑
+        String[] values = readTheOldFirstLineRainfallValue(serviceNameDir);
+        File newDatFile = generateNewRainfallFile(input, values, serviceNameDir, currentTime);
+
+        //鐢熸垚涓�涓柊鐨勭敓鎴恴arr鐨勯厤缃枃浠�
+        File newConfigFile = generateNewZarrConfigFile(serviceNameDir, serviceName, currentTime, newDatFile);
+        //鎵ц姹傝В鍣ㄨ繍绠�
+        String cmd = String.format("%s \"%s\"", config.getUwSolverBat(), newConfigFile);
+        callBat2(cmd);
+
+        //鐢熸垚涓�涓柊鐨剒arr杞瑃if鐨刯son鏂囦欢
+        File newZarr2TifJson = generateNewZarr2TifJson(serviceNameDir, currentTime);
+        //鎵цzarr杞瑃if
+        String zarr2TifCmd = String.format("%s \"%s\"", config.getZarr2tifBat(), newZarr2TifJson);
+        callBat2(zarr2TifCmd);
+        //杩斿洖鏂扮殑layer.json鍚嶇О
+        return generateLayerJsonAndPng(serviceName, serviceNameDir, currentTime);
+
+    }
+
+    private String generateLayerJsonAndPng(String serviceName, File serviceNameDir, long currentTime) throws IOException {
+        ResultDto resultDto = new ResultDto();
+        resultDto.setServiceName(serviceName);
+        File temp = Paths.get(config.getOutPath(), serviceName, "temp").toFile();
+        if (!temp.exists()) temp.mkdir();
+        resultDto.setTemp(temp.getAbsolutePath());
+        resultDto.setOutPath(Paths.get(config.getOutPath(), serviceName).toString());
+        File dem = new File(serviceNameDir, "DEM.tif");
+        resultDto.setTerrainFile(dem.getAbsolutePath());
+        File newDepthDir = new File(serviceNameDir + File.separator + "depth_" + currentTime);
+        File[] files = newDepthDir.listFiles();
+        resultDto.setWaterPath(newDepthDir.getAbsolutePath());
+        LayerDto layerDto = new LayerDto(config.getVer(), 4548, config.getSizes());
+        String newLayerJsonName = "layer_" + currentTime + ".json";
+        layerDto.setName(newLayerJsonName);
+        testService.processRealTime(resultDto, layerDto);
+        return newLayerJsonName;
+    }
+
+//    private static void readDemData(File serviceNameDir, LayerDto layerDto) {
+//        File dem = new File(serviceNameDir, "DEM.tif");
+//        Dataset ds = gdal.Open(dem.getAbsolutePath(), gdalconstConstants.GA_ReadOnly);
+//        Band band = ds.GetRasterBand(1);
+//        int width = ds.getRasterXSize();
+//        int height = ds.getRasterYSize();
+//        float[] buffer = new float[width * height];
+//        band.ReadRaster(0, 0, width, height, buffer);
+//        layerDto.getTerrain().getVals().put(width + "_" + height, buffer);
+//    }
+
+    private static File generateNewZarr2TifJson(File serviceNameDir, long currentTime) throws IOException {
+        File srcZarr2TifJson = new File(serviceNameDir, "zarr2tif.json");
+        ObjectMapper mapper = new ObjectMapper();
+        Zarr2Tif zarr2Tif = mapper.readValue(srcZarr2TifJson, Zarr2Tif.class);
+        //淇敼zarr2tif瀵硅薄涓殑瀛楁
+        String stamp = TimeFormatUtil.formatTime(currentTime, "yyyy-MM-dd HH:mm:ss");
+        zarr2Tif.setStart_timestamp(stamp);
+        String newZarrPath = serviceNameDir + File.separator + "result_" + currentTime + ".zarr";
+        zarr2Tif.setZarr_file(newZarrPath);
+        zarr2Tif.setGeotiff_dir(serviceNameDir + File.separator + "depth_" + currentTime);
+        File newZarr2TifJson = new File(serviceNameDir, "zarr2tif_" + currentTime + ".json");
+        mapper.writeValue(newZarr2TifJson, zarr2Tif);
+        return newZarr2TifJson;
+    }
+
+    private File generateNewZarrConfigFile(File serviceNameDir, String serviceName, long currentTime, File newDatFile) throws IOException {
+        File configFile = new File(serviceNameDir, serviceName + ".json");
+        String str = Files.readAllLines(configFile.toPath()).stream().collect(Collectors.joining());
+        ConfigVo configVo = JSON.parseObject(str, ConfigVo.class);
+        configVo.setDuration(300); //鍥哄畾涓�5min
+        configVo.getRaingage().set(0, newDatFile.getAbsolutePath()); //raingage file
+        ResultVo result = configVo.getResult();
+        result.setSave_interval(60); //60s鐢熸垚涓�甯�
+        result.setSave_frames(5); //淇濈暀5甯�
+        String newZarrPath = serviceNameDir + File.separator + "result_" + currentTime + ".zarr";
+        result.setSave_name(newZarrPath);
+        ObjectMapper mapper = new ObjectMapper();
+        File newConfigFile = new File(serviceNameDir, currentTime + ".json");
+        mapper.writeValue(newConfigFile, configVo);
+        return newConfigFile;
+    }
+
+    private File generateNewRainfallFile(RealTimeInput input, String[] values, File serviceNameDir, long currentTime) throws IOException {
+        String station = values[0];
+        double lon = Double.parseDouble(values[1]);
+        double lat = Double.parseDouble(values[2]);
+        String title = config.getRainfallTitle();
+        List<String> newLines = new ArrayList<>();
+        newLines.add(title);
+        List<RealTimeInput.RealTimeData> data = input.getData();
+        for (RealTimeInput.RealTimeData rd : data) {
+            LocalDateTime dateTime = rd.getDateTime();
+            int year = dateTime.getYear();
+            int month = dateTime.getMonthValue();
+            int day = dateTime.getDayOfMonth();
+            int hour = dateTime.getHour();
+            int minute = dateTime.getMinute();
+            double intensity = rd.getIntensity(); //淇濈暀鎸囧畾浣嶆暟灏忔暟
+            String l = String.format("%s %s %s %s %s %s %s %s %s",
+                    station, lon, lat, year, month, day, hour, minute, String.format("%.6f", intensity));
+            newLines.add(l);
+        }
+        File newDatFile = new File(serviceNameDir, "rainfall_" + currentTime + ".dat");
+        if (!newDatFile.exists()) newDatFile.createNewFile();
+        Files.write(newDatFile.toPath(), newLines, StandardOpenOption.TRUNCATE_EXISTING);
+        return newDatFile;
+    }
+
+    private static String[] readTheOldFirstLineRainfallValue(File serviceNameDir) throws IOException {
+        File srcRailfallFile = new File(serviceNameDir, "rainfall.dat");
+        List<String> lines = Files.readAllLines(srcRailfallFile.toPath());
+        String secondLine = lines.get(1);
+        return secondLine.split(" ");
+    }
 }
diff --git a/src/main/java/com/se/nsl/service/SimuService.java b/src/main/java/com/se/nsl/service/SimuService.java
index 2cbe0bf..1c314bc 100644
--- a/src/main/java/com/se/nsl/service/SimuService.java
+++ b/src/main/java/com/se/nsl/service/SimuService.java
@@ -13,6 +13,7 @@
 import com.se.nsl.helper.StringHelper;
 import com.se.nsl.mapper.SimuMapper;
 import com.se.nsl.utils.CoordinateTransformer;
+import com.se.nsl.utils.TimeFormatUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.gdal.gdal.Band;
 import org.gdal.gdal.Dataset;
@@ -190,7 +191,7 @@
 
         ColumnRow cr = getColumnRow(tifFile, x, y);
         if (cr == null) return null;
-        System.out.println("col:" + cr.col + " ,row:" + cr.row);
+//        System.out.println("col:" + cr.col + " ,row:" + cr.row);
         float depth = readPixelValue(cr.dataset, cr.col, cr.row, 1);
         float velocity = calcVelocity(cr.dataset, cr.col, cr.row);
         SimuResult result = new SimuResult();
@@ -253,10 +254,11 @@
     }
 
     private String formatTime(long time) {
-        Instant instant = Instant.ofEpochMilli(time);
-        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
-        return localDateTime.format(formatter);
+//        Instant instant = Instant.ofEpochMilli(time);
+//        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+//        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+//        return localDateTime.format(formatter);
+        return TimeFormatUtil.formatTime(time, "yyyyMMddHHmmss");
     }
 
 }
diff --git a/src/main/java/com/se/nsl/service/TestService.java b/src/main/java/com/se/nsl/service/TestService.java
index 6408b5f..1cc2825 100644
--- a/src/main/java/com/se/nsl/service/TestService.java
+++ b/src/main/java/com/se/nsl/service/TestService.java
@@ -8,6 +8,7 @@
 import com.se.nsl.domain.vo.BuildingDepthVo;
 import com.se.nsl.helper.ComHelper;
 import com.se.nsl.helper.GdalHelper;
+import com.se.nsl.utils.TimeFormatUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.gdal.gdal.Band;
 import org.gdal.gdal.Dataset;
@@ -42,7 +43,7 @@
 
     public final static SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm");
 
-    public void test(SimuData data) throws Exception {
+    public void test(SimuData data) throws IOException {
         String basePath = config.getInPath() + File.separator + data.getInPath() + File.separator;
         ResultDto dto = new ResultDto(
                 data.getInPath(),
@@ -57,7 +58,7 @@
         process(dto, layer);
     }
 
-    private void process(ResultDto dto, LayerDto layer) throws Exception {
+    private void process(ResultDto dto, LayerDto layer) throws IOException {
         try {
             copeTerrain(dto, layer);
             copeWater(dto, layer);
@@ -71,7 +72,36 @@
         }
     }
 
+    public void processRealTime(ResultDto dto, LayerDto layer) throws IOException {
+        try {
+            copeTerrainRealTime(dto, layer);
+            copeWater(dto, layer);
+            copeFlow(dto, layer);
+            copeLayerJson(dto, layer);
+        } finally {
+            File dir = new File(dto.getTemp());
+            if (dir.exists()) {
+                FileUtil.del(dir);
+            }
+        }
+    }
+
     public void copeTerrain(ResultDto dto, LayerDto layer) {
+        Dataset ds = null;
+        try {
+            ds = gdal.Open(dto.getTerrainFile(), gdalconstConstants.GA_ReadOnly); // gdalconst
+            if (null == ds || 0 == ds.getRasterCount()) return;
+
+            setSizes(ds, layer);
+            setTerrainInfo(ds, layer);
+            setWaterInfo(dto, layer);
+            createTerrainPng(dto, ds, layer);
+        } finally {
+            if (null != ds) ds.delete();
+        }
+    }
+
+    private void copeTerrainRealTime(ResultDto dto, LayerDto layer) {
         Dataset ds = null;
         try {
             ds = gdal.Open(dto.getTerrainFile(), gdalconstConstants.GA_ReadOnly); // gdalconst
@@ -201,12 +231,9 @@
     }
 
     public void setWaterData(LayerDto layer, List<String> files) {
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
         for (String file : files) {
             String fileName = ComHelper.getNameWithExt(file);
-            LocalDateTime dateTime = LocalDateTime.parse(fileName, formatter);
-            Instant instant = dateTime.atZone(ZoneId.systemDefault()).toInstant();
-            long timestamp = instant.toEpochMilli();
+            long timestamp = TimeFormatUtil.toMillis(fileName, "yyyyMMddHHmmss");
             layer.getWaters().getData().add(timestamp);
         }
         layer.getDuration().setStart(layer.getWaters().getData().get(0));
@@ -520,8 +547,8 @@
         layer.setFlowUrl("/hls/f" + path + ".m3u8");
 
         String json = JSON.toJSONString(layer);
-        // String json = JSONUtil.toJsonPrettyStr(layer);
-        String filePath = dto.getOutPath() + File.separator + "layer.json";
+//        String filePath = dto.getOutPath() + File.separator + "layer.json";
+        String filePath = dto.getOutPath() + File.separator + layer.getName();
 
         ComHelper.writeJson(filePath, json);
     }
diff --git a/src/main/java/com/se/nsl/utils/RainFallUnit.java b/src/main/java/com/se/nsl/utils/RainFallUnit.java
new file mode 100644
index 0000000..ee21e03
--- /dev/null
+++ b/src/main/java/com/se/nsl/utils/RainFallUnit.java
@@ -0,0 +1,36 @@
+package com.se.nsl.utils;
+
+/**
+ * @author dcb
+ */
+public enum RainFallUnit {
+    MM_H("mm/h", 60),
+    MM_15MIN("mm/15min", 15),
+    MM_5MIN("mm/5min", 5),
+    MM_MIN("mm/min", 1);
+    private final String unit;
+    private final int c; //绯绘暟
+
+    RainFallUnit(String unit, int c) {
+        this.unit = unit;
+        this.c = c;
+    }
+
+    public static RainFallUnit of(String unit) {
+        RainFallUnit[] values = values();
+        for (RainFallUnit v : values) {
+            if (v.unit.equals(unit)) {
+                return v;
+            }
+        }
+        return MM_H; //榛樿鎸夌収mm/h璁$畻
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public int getC() {
+        return c;
+    }
+}
diff --git a/src/main/java/com/se/nsl/utils/SimulateType.java b/src/main/java/com/se/nsl/utils/SimulateType.java
new file mode 100644
index 0000000..f2f1278
--- /dev/null
+++ b/src/main/java/com/se/nsl/utils/SimulateType.java
@@ -0,0 +1,35 @@
+package com.se.nsl.utils;
+
+/**
+ * @author dcb
+ */
+public enum SimulateType {
+    PREDICTION(1, "continue"), //棰勬祴妯℃嫙
+    REAL_TIME(2, "continue"), //瀹炴椂妯℃嫙
+    HISTORY(3, "new");   //鍘嗗彶妯℃嫙
+
+    private int type;
+    private String saveMode;
+
+    SimulateType(int type, String saveMode) {
+        this.type = type;
+        this.saveMode = saveMode;
+    }
+
+    public static SimulateType of(int type) {
+        for (SimulateType st : values()) {
+            if (type == st.type) {
+                return st;
+            }
+        }
+        return HISTORY;
+    }
+
+    public int getType() {
+        return type;
+    }
+
+    public String getSaveMode() {
+        return saveMode;
+    }
+}
diff --git a/src/main/java/com/se/nsl/utils/TimeFormatUtil.java b/src/main/java/com/se/nsl/utils/TimeFormatUtil.java
new file mode 100644
index 0000000..28f6c38
--- /dev/null
+++ b/src/main/java/com/se/nsl/utils/TimeFormatUtil.java
@@ -0,0 +1,33 @@
+package com.se.nsl.utils;
+
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * @author dcb
+ */
+public class TimeFormatUtil {
+    private TimeFormatUtil() {}
+
+    public static String formatTime(long time, String pattern) {
+        Instant instant = Instant.ofEpochMilli(time);
+        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
+        return localDateTime.format(formatter);
+    }
+
+    public static long toMillis(String time, String pattern) {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
+        LocalDateTime dateTime = LocalDateTime.parse(time, formatter);
+        return dateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
+    }
+
+    public static void main(String[] args) {
+        String s = "20250606142122";
+        String pattern = "yyyyMMddHHmmss";
+        long millis = toMillis(s, pattern);
+        System.out.println("millis:" + millis);
+        String str = formatTime(millis, pattern);
+        System.out.println("str:" + str);
+    }
+}

--
Gitblit v1.9.3