From 35d1a18c3936bdd2e7640cd37360d6eff8925e39 Mon Sep 17 00:00:00 2001
From: dcb <xgybdcb@163.com>
Date: 星期五, 30 五月 2025 10:24:19 +0800
Subject: [PATCH] 升级求解器版本到2.1.1

---
 src/main/java/com/se/nsl/service/ResolveService.java |  156 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 138 insertions(+), 18 deletions(-)

diff --git a/src/main/java/com/se/nsl/service/ResolveService.java b/src/main/java/com/se/nsl/service/ResolveService.java
index e7115d5..5edd663 100644
--- a/src/main/java/com/se/nsl/service/ResolveService.java
+++ b/src/main/java/com/se/nsl/service/ResolveService.java
@@ -11,12 +11,20 @@
 import com.se.nsl.domain.po.SimuData;
 import com.se.nsl.domain.vo.ConfigVo;
 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 lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
+import org.gdal.gdal.Band;
+import org.gdal.gdal.Dataset;
+import org.gdal.gdal.gdal;
+import org.gdal.gdalconst.gdalconstConstants;
 import org.gdal.ogr.Geometry;
 import org.gdal.ogr.ogr;
+import org.gdal.osr.CoordinateTransformation;
+import org.gdal.osr.SpatialReference;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
@@ -33,6 +41,8 @@
 import java.nio.file.StandardCopyOption;
 import java.sql.Timestamp;
 import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -108,7 +118,7 @@
             SimuData data = JSONUtil.toBean(simu.getData(), SimuData.class);
 
             update(simu, 1, "鍒濆鍖栧弬鏁�");
-            initArgs(data);
+            initArgs(simu, data);
             createRainfallFile(simu, data);
 
             update(simu, 2, "璋冪敤姹傝В鍣�");
@@ -121,6 +131,7 @@
             createNsl(data);
 
             update(simu, 10, "瀹屾垚");
+            log.info("妯℃嫙瀹屾垚");
         } catch (Exception ex) {
             log.error(ex.getMessage(), ex);
             update(simu, 20, ex.getMessage());
@@ -138,18 +149,85 @@
     /**
      * 鍒濆鍖栧弬鏁�
      */
-    public void initArgs(SimuData data) throws IOException {
+    public void initArgs(Simu simu, SimuData data) throws IOException {
         String inPath = config.getInPath() + File.separator + data.getInPath();
         createDir(inPath);
         createDir(inPath + File.separator + "depth");
         createDir(inPath + File.separator + "velocity");
         createDir(config.getOutPath() + File.separator + data.getOutPath());
 
-        // 涓存椂澶嶅埗楂樼▼tif锛屼互鍚庨渶瑕佽嚜琛屽垏鍓�
-        File uwBat = new File(config.getUwSolverBat());
-        String sourceTif = uwBat.getParent() + File.separator + "case1" + File.separator + "LiuLiMiaoZhen_5m_f32.tif";
-        String targetTif = inPath + File.separator + config.getDemFile();
-        Files.copy(Paths.get(sourceTif), Paths.get(targetTif), StandardCopyOption.REPLACE_EXISTING);
+        Short areaType = simu.getAreaType();
+        AreaType at = AreaType.of(areaType);
+        String terrainTif = config.getSourceDem();
+        String landuseTif = config.getSourceLanduse();
+        if (at == AreaType.KEY_DITCH) {
+            File keyDitchDir = new File(config.getKeyDitch());
+            String areaName = simu.getAreaName();
+            Optional<File> first = Arrays.stream(keyDitchDir.listFiles()).filter(f -> f.getName().equals(areaName)).findFirst();
+            if (first.isPresent()) {
+                File targetTifDir = first.get();
+                File[] files = targetTifDir.listFiles();
+                for (File file : files) {
+                    String name = file.getName();
+                    if (name.toLowerCase().contains("dem")) {
+                        terrainTif = file.getAbsolutePath();
+                    }
+                    if (name.toLowerCase().contains("landuse")) {
+                        landuseTif = file.getAbsolutePath();
+                    }
+                }
+            }
+        }
+
+        Geometry geom = Geometry.CreateFromWkt(simu.getGeom());
+        if (geom.GetGeometryType() == ogr.wkbMultiPolygon) geom = geom.GetGeometryRef(0);
+        SpatialReference dstSR = GdalHelper.createSpatialReference(config.getEpsg());
+
+        CoordinateTransformation ct = CoordinateTransformation.CreateCoordinateTransformation(GdalHelper.SR4326, dstSR);
+        geom.Transform(ct);
+        String wkt = geom.ExportToWkt();
+
+        String terrainFile = inPath + File.separator + config.getTerrainFile();
+
+        Dataset dsDem = gdal.Open(terrainTif, gdalconstConstants.GA_ReadOnly);
+        ComHelper.Resample(dsDem, null, terrainFile, null, wkt, null, null);
+        dsDem.delete();
+
+        String landuseFile = inPath + File.separator + config.getLanduseFile();
+
+        Dataset dsLanduse = gdal.Open(landuseTif, gdalconstConstants.GA_ReadOnly);
+        ComHelper.Resample(dsLanduse, null, landuseFile, null, wkt, null, null);
+        dsLanduse.delete();
+    }
+
+    public void updateTif(Simu simu, SimuData data2) throws IOException {
+        Dataset ds = gdal.Open(config.getSourceLanduse(), gdalconstConstants.GA_Update); // 浠ヨ鍐欐ā寮忔墦寮�TIFF鏂囦欢
+
+        Band band = ds.GetRasterBand(1);
+        if (band.GetRasterDataType() != gdalconstConstants.GDT_Byte) {
+            System.err.println("閿欒锛氶潪Byte绫诲瀷鏁版嵁");
+            ds.delete();
+            return;
+        }
+
+        int width = band.getXSize();
+        int height = band.getYSize();
+
+        // 璇诲彇Byte绫诲瀷鏁版嵁
+        byte[] data = new byte[width * height];
+        band.ReadRaster(0, 0, width, height, data);
+
+        // 鏇挎崲0鍊间负8锛堟敞鎰廕ava鐨刡yte鏄湁绗﹀彿鐨勶紝闇�澶勭悊0-255鑼冨洿锛�
+        for (int i = 0; i < data.length; i++) {
+            if ((data[i] & 0xFF) == 0) {  // 鏃犵鍙锋瘮杈�
+                data[i] = (byte) 8;
+            }
+        }
+
+        band.WriteRaster(0, 0, width, height, data); // 鍐欏洖鏁版嵁骞朵繚瀛�
+        band.SetNoDataValue(8.0);  // 璁剧疆鏂癗odata鍊�
+        band.FlushCache(); // 寮哄埗鍐欏叆鏇存敼
+        ds.delete();
     }
 
     private void createDir(String path) {
@@ -158,6 +236,30 @@
             FileUtil.del(f);
         }
         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 {
@@ -177,8 +279,12 @@
         double centerX = ComHelper.getMinVal((data.getMinx() + data.getMaxx()) / 2, DIGIT);
         double centerY = ComHelper.getMinVal((data.getMiny() + data.getMaxy()) / 2, DIGIT);
         String prefix = config.getRainfallSite() + " " + centerX + " " + centerY + " ";
-        int unit = StringUtils.isEmpty(data.getIntensityUnit()) || "mm/h".equals(data.getIntensityUnit()) ? 60 : 5;
-
+        //濡傛灉娌℃湁鍗曚綅鎴栬�呭崟浣嶄负mm/h鍒欐寜鐓� mm/h璁$畻锛屽惁鍒欐寜鐓m/5min璁$畻
+//        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;
         int c = rainfalls.size() - 1;
         for (int i = 0; i < c; i++) {
             Rainfall r1 = rainfalls.get(i);
@@ -188,6 +294,7 @@
         }
         //list.add(prefix + YYYYMDHM.format(rainfalls.get(c).getTime()) + getMinVal(rainfalls.get(c).getIntensity() / unit, DIGIT));
         list.add(String.format("%s%s%f", prefix, YYYYMDHM.format(rainfalls.get(c).getTime()), getMinVal(rainfalls.get(c).getIntensity() / unit, DIGIT)));
+//        list.add(0, "1 " + (list.size() - 1));
 
         Files.write(Paths.get(rainfallFile), list, StandardCharsets.UTF_8);
     }
@@ -223,19 +330,30 @@
 
         int duration = 3600 * data.getDuration(); // 绉掓暟
         if (null != data.getRainfalls() && data.getRainfalls().size() > 1) {
-            duration = (int) (Math.abs(data.getRainfalls().get(data.getRainfalls().size() - 1).getTime().getTime() - data.getRainfalls().get(0).getTime().getTime()) / 60);
+            List<Rainfall> rainfalls = data.getRainfalls();
+            int size = rainfalls.size();
+            Rainfall last = rainfalls.get(size - 1);
+            Rainfall first = rainfalls.get(0);
+            Instant end = last.getTime().toInstant();
+            Instant start = first.getTime().toInstant();
+            long diff = ChronoUnit.SECONDS.between(end, start);
+            duration = (int) (Math.abs(diff));
         }
 
         String inPath = config.getInPath() + File.separator + data.getInPath();
-        String terrainFile = (inPath + File.separator + config.getDemFile());
+        String terrainFile = inPath + File.separator + config.getTerrainFile();
+        String landuseFile = inPath + File.separator + config.getLanduseFile();
         String rainfallFile = (inPath + File.separator + "rainfall.dat");
         String saveName = inPath + File.separator + "result.zarr";
-        ConfigVo vo = new ConfigVo(terrainFile, terrainFile, terrainFile, rainfallFile, saveName, duration, config.getSaveFrames());
+//        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);
 
         String configFile = config.getInPath() + File.separator + data.getInPath() + File.separator + data.getInPath() + ".json";
         ComHelper.writeJson(configFile, JSON.toJSONString(vo));
 
-        String cmd = String.format("%s %s", config.getUwSolverBat(), configFile);
+        String cmd = String.format("%s \"%s\"", config.getUwSolverBat(), configFile);
 
         return callBat2(cmd);
     }
@@ -247,7 +365,7 @@
         String inPath = config.getInPath() + File.separator + data.getInPath();
         String zarrFile = inPath + File.separator + "result.zarr";
         String geotiffDir = inPath + File.separator + "depth";
-        String terrainFile = inPath + File.separator + config.getDemFile();
+        String terrainFile = inPath + File.separator + config.getTerrainFile();
         String jsonPath = inPath + File.separator + "zarr2tif.json";
 
         Zarr2Tif zarr2Tif = new Zarr2Tif(zarrFile, geotiffDir, terrainFile, data.getStartTime());
@@ -270,8 +388,9 @@
             try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"))) {
                 String line;
                 while ((line = reader.readLine()) != null) {
-                    System.out.println(line);
+//                    System.out.println(line);
                     //sb.append(line);
+                    log.info(line);
                 }
             }
 
@@ -288,7 +407,7 @@
         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.getDemFile();
+        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);
@@ -323,8 +442,8 @@
     }
 
     private void createNsl(SimuData data) throws Exception {
-        String inPath = config.getInPath() + File.separator + data.getInPath() + File.separator + "depth";
-        procTifs(inPath, inPath, data.getStartTime());
+        /*String inPath = config.getInPath() + File.separator + data.getInPath() + File.separator + "depth";
+        procTifs(inPath, inPath, data.getStartTime());*/
 
         testService.test(data);
     }
@@ -422,6 +541,7 @@
 
             cal.add(Calendar.MINUTE, 1);
         }
+//        list.add(0, "1 " + (list.size() - 1));
 
         Files.write(Paths.get(dat), list, StandardCharsets.UTF_8);
     }

--
Gitblit v1.9.3