From 22f80ba79735ab9897530b79e34889d2082cedbc Mon Sep 17 00:00:00 2001
From: wuww <252740454@qq.com>
Date: 星期四, 08 五月 2025 16:25:40 +0800
Subject: [PATCH] 开发根据参数生成降雨文件接口

---
 src/main/java/com/se/nsl/controller/SimuController.java |   23 +++++++
 src/main/resources/mapper/SimuMapper.xml                |   29 +++++++++
 src/main/java/com/se/nsl/domain/po/SimuData.java        |    1 
 src/main/java/com/se/nsl/service/ResolveService.java    |   94 +++++++++++++++++++++++++++++--
 src/main/java/com/se/nsl/mapper/SimuMapper.java         |    2 
 src/main/java/com/se/nsl/config/PropertiesConfig.java   |   10 +++
 src/main/resources/application-dev.yml                  |    1 
 src/main/java/com/se/nsl/service/SimuService.java       |    6 +
 8 files changed, 158 insertions(+), 8 deletions(-)

diff --git a/src/main/java/com/se/nsl/config/PropertiesConfig.java b/src/main/java/com/se/nsl/config/PropertiesConfig.java
index 48b5b8d..3540064 100644
--- a/src/main/java/com/se/nsl/config/PropertiesConfig.java
+++ b/src/main/java/com/se/nsl/config/PropertiesConfig.java
@@ -88,6 +88,8 @@
 
     private Integer landuse;
 
+    private Integer epsg;
+
     public String getVer() {
         return ver;
     }
@@ -403,4 +405,12 @@
     public void setCreateRainfall(String createRainfall) {
         this.createRainfall = createRainfall;
     }
+
+    public Integer getEpsg() {
+        return epsg;
+    }
+
+    public void setEpsg(Integer epsg) {
+        this.epsg = epsg;
+    }
 }
diff --git a/src/main/java/com/se/nsl/controller/SimuController.java b/src/main/java/com/se/nsl/controller/SimuController.java
index 3abe23e..0028a67 100644
--- a/src/main/java/com/se/nsl/controller/SimuController.java
+++ b/src/main/java/com/se/nsl/controller/SimuController.java
@@ -11,6 +11,8 @@
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.gdal.ogr.Geometry;
+import org.gdal.ogr.ogr;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
 
@@ -85,8 +87,17 @@
 
             SimuData data = JSON.parseObject(simu.getData(), SimuData.class);
             if (null == data) return fail("data鏁版嵁鏍煎紡(JSON)涓嶆纭�");
+            if (StringUtils.isEmpty(simu.getGeom())) return fail("geom瀛楃涓蹭笉鏄疻KT鏍煎紡");
+
+            Geometry geom = Geometry.CreateFromWkt(simu.getGeom());
+            if (!(geom.GetGeometryType() == ogr.wkbMultiPolygon || geom.GetGeometryType() == ogr.wkbPolygon))
+                return fail("geom瀵硅薄涓嶆槸澶氳竟褰�");
 
             int rows = simuService.insert(simu);
+            if (rows > 0 && (null == data.getRainfalls() || data.getRainfalls().size() < 2)) {
+                resolveService.createRainfall(simu);
+                simuService.updateById(simu);
+            }
 
             return success(rows);
         } catch (Exception ex) {
@@ -128,6 +139,18 @@
     @PutMapping(value = "/updateById", produces = "application/json; charset=UTF-8")
     public R<Object> updateById(@RequestBody Simu simu) {
         try {
+            if (StringUtils.isEmpty(simu.getData())) return fail("data涓虹┖");
+
+            SimuData data = JSON.parseObject(simu.getData(), SimuData.class);
+            if (null == data) return fail("data鏁版嵁鏍煎紡(JSON)涓嶆纭�");
+            if (StringUtils.isEmpty(simu.getGeom())) return fail("geom瀛楃涓蹭笉鏄疻KT鏍煎紡");
+
+            Geometry geom = Geometry.CreateFromWkt(simu.getGeom());
+            if (!(geom.GetGeometryType() == ogr.wkbMultiPolygon || geom.GetGeometryType() == ogr.wkbPolygon))
+                return fail("geom瀵硅薄涓嶆槸澶氳竟褰�");
+
+            if (null == data.getRainfalls() || data.getRainfalls().size() < 2) resolveService.createRainfall(simu);
+
             return success(simuService.updateById(simu));
         } catch (Exception ex) {
             return fail(ex, null);
diff --git a/src/main/java/com/se/nsl/domain/po/SimuData.java b/src/main/java/com/se/nsl/domain/po/SimuData.java
index 69282da..1b5dfac 100644
--- a/src/main/java/com/se/nsl/domain/po/SimuData.java
+++ b/src/main/java/com/se/nsl/domain/po/SimuData.java
@@ -102,6 +102,7 @@
         return minx + "," + miny + "," + maxx + "," + maxy;
     }
 
+    @JSONField(serialize = false)
     public SpatialReference getSpatialReference() {
         return GdalHelper.createSpatialReference(this.getEpsg());
     }
diff --git a/src/main/java/com/se/nsl/mapper/SimuMapper.java b/src/main/java/com/se/nsl/mapper/SimuMapper.java
index 67c19b4..fbaf140 100644
--- a/src/main/java/com/se/nsl/mapper/SimuMapper.java
+++ b/src/main/java/com/se/nsl/mapper/SimuMapper.java
@@ -13,6 +13,8 @@
 @Repository
 @SuppressWarnings("ALL")
 public interface SimuMapper extends BaseMapper<Simu> {
+    int insert(Simu simu);
+
     int inserts(@Param("list") List<Simu> list);
 
     int updates(@Param("list") List<Simu> list);
diff --git a/src/main/java/com/se/nsl/service/ResolveService.java b/src/main/java/com/se/nsl/service/ResolveService.java
index 1234ecf..8c84496 100644
--- a/src/main/java/com/se/nsl/service/ResolveService.java
+++ b/src/main/java/com/se/nsl/service/ResolveService.java
@@ -22,6 +22,8 @@
 import javax.annotation.Resource;
 import java.io.File;
 import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Paths;
@@ -31,6 +33,7 @@
 import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -52,6 +55,8 @@
 
     SimpleDateFormat YYYYMDHM = new SimpleDateFormat("yyyy M d H m ");
 
+    List<String> MODES = new ArrayList<>(Arrays.asList("姝f�佸垎甯�", "骞冲潎鍒嗗竷", "娉㈠姩骞冲潎鍒嗗竷", "鎸佺画涓婂崌"));
+
     public int start(Simu simu) {
         Date now = new Date();
         String date = StringHelper.YMDHMS2_FORMAT.format(now);
@@ -67,8 +72,8 @@
         SimuData data = JSON.parseObject(simu.getData(), SimuData.class);
         data.setInPath(date);
         data.setOutPath(date);
-        data.setEpsg(4548);
         data.setEnvelope(envelope);
+        data.setEpsg(config.getEpsg());
 
         simu.setData(JSON.toJSONString(data));
         simu.setServiceName(date);
@@ -101,7 +106,7 @@
 
             update(simu, 1, "鍒濆鍖栧弬鏁�");
             initArgs(data);
-            createRainfallFile(data);
+            createRainfallFile(simu, data);
 
             update(simu, 2, "璋冪敤姹傝В鍣�");
             callUwSolver(data);
@@ -152,9 +157,16 @@
         f.mkdirs();
     }
 
-    private void createRainfallFile(SimuData data) throws Exception {
+    private void createRainfallFile(Simu simu, SimuData data) throws Exception {
         List<Rainfall> rainfalls = data.getRainfalls();
-        if (null == rainfalls || rainfalls.size() < 2) return; // CollUtil.isEmpty
+        if (null == rainfalls || rainfalls.size() < 2) createRainfall(simu);
+
+        String dat = config.getInPath() + File.separator + "Rainfalls" + File.separator + simu.getId() + ".dat";
+        String rainfallFile = config.getInPath() + File.separator + data.getInPath() + File.separator + "rainfall.dat";
+        if (new File(dat).exists()) {
+            Files.copy(Paths.get(dat), Paths.get(rainfallFile), StandardCopyOption.REPLACE_EXISTING);
+            return;
+        }
 
         List<String> list = new ArrayList<>();
         list.add(config.getRainfallTitle());
@@ -174,7 +186,6 @@
         //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)));
 
-        String rainfallFile = config.getInPath() + File.separator + data.getInPath() + File.separator + "rainfall.dat";
         Files.write(Paths.get(rainfallFile), list, StandardCharsets.UTF_8);
     }
 
@@ -294,10 +305,79 @@
         }
     }
 
-    public String createRainfallCsv(String csvPath, String type, double total, double intensity, int hours) {
+    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, type, total, intensity, hours * 60);
+        String cmd = String.format("%s \"%s\" \"%s\" %f %f %d", config.getCreateRainfall(), csvPath, mode, total, intensity, hours * 60);
 
         return callBat(cmd);
     }
+
+    public void createRainfall(Simu simu) throws Exception {
+        SimuData data = JSON.parseObject(simu.getData(), SimuData.class);
+        if (null == data.getMode() || MODES.contains(data.getMode())) data.setMode(MODES.get(0));
+        if (StringUtils.isEmpty(data.getIntensityUnit())) data.setIntensityUnit("mm/h");
+
+        Geometry geom = Geometry.CreateFromWkt(simu.getGeom());
+        if (geom.GetGeometryType() == ogr.wkbMultiPolygon) geom = geom.GetGeometryRef(0);
+        double[] envelope = new double[4];
+        geom.GetEnvelope(envelope);
+        data.setEnvelope(envelope);
+        data.setEpsg(config.getEpsg());
+
+        String basePath = config.getInPath() + File.separator + "Rainfalls";
+        if (!new File(basePath).exists()) new File(basePath).mkdirs();
+        if (null == simu.getCreateTime()) simu.setCreateTime(new Timestamp(new Date().getTime()));
+
+        String csvPath = basePath + File.separator + simu.getId() + ".csv";
+        int unit = StringUtils.isEmpty(data.getIntensityUnit()) || "mm/h".equals(data.getIntensityUnit()) ? 60 : 5;
+        createRainfallCsv(csvPath, data.getMode(), data.getTotal(), data.getIntensity() / unit, data.getDuration());
+
+        List<Double> list = getValues(csvPath);
+        if (!CollUtil.isEmpty(list)) {
+            data.setRainfalls(new ArrayList<>());
+            setRainfalls(simu, data, list);
+        }
+
+        simu.setData(JSON.toJSONString(data));
+    }
+
+    private List<Double> getValues(String csvPath) throws Exception {
+        if (!new File(csvPath).exists()) return null;
+
+        List<String> list = Files.readAllLines(Paths.get(csvPath));
+        list.remove(0);
+        //list.remove(list.size() - 1);
+
+        return list.stream()
+                .map(s -> new BigDecimal(s).setScale(6, RoundingMode.HALF_DOWN).doubleValue())
+                .collect(Collectors.toList());
+    }
+
+    private void setRainfalls(Simu simu, SimuData data, List<Double> vals) throws Exception {
+        String basePath = config.getInPath() + File.separator + "Rainfalls";
+        String dat = basePath + File.separator + simu.getId() + ".dat";
+
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(data.getStartTime());
+
+        List<String> list = new ArrayList<>();
+        list.add(config.getRainfallTitle());
+
+        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 + " ";
+
+        Double total = 0.0;
+        for (int i = 0, c = vals.size(); i < c; i++) {
+            total += vals.get(i);
+            if (i % 15 == 0) {
+                data.getRainfalls().add(new Rainfall(cal.getTime(), vals.get(i), total));
+            }
+            list.add(String.format("%s%s%f", prefix, YYYYMDHM.format(cal.getTime()), vals.get(i)));
+
+            cal.add(Calendar.MINUTE, 1);
+        }
+
+        Files.write(Paths.get(dat), list, StandardCharsets.UTF_8);
+    }
 }
diff --git a/src/main/java/com/se/nsl/service/SimuService.java b/src/main/java/com/se/nsl/service/SimuService.java
index 6dc5dad..c218828 100644
--- a/src/main/java/com/se/nsl/service/SimuService.java
+++ b/src/main/java/com/se/nsl/service/SimuService.java
@@ -82,7 +82,11 @@
      * @return 鏂板鎴愬姛鐨勮褰曟暟
      */
     public int insert(Simu simu) {
-        return simuMapper.inserts(Collections.singletonList(simu));
+        return simuMapper.insert(simu);
+    }
+
+    public int inserts(List<Simu> list) {
+        return simuMapper.inserts(list);
     }
 
     /**
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index 299141b..e60c586 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -147,6 +147,7 @@
   createRainfall: '"C:\Program Files\Python310\python.exe" D:\terrait\NslServer\data\CreatRainfall.py'
   rainfallTitle: Station Longitude Latitude Year Month Day Hour Minute Intensity
   rainfallSite: beijing
+  epsg: 4548
   saveFrames: 10
   # 鍦熷湴鍒╃敤锛�1-Cropland,2-Forest,3-Shrub,4-Grassland,5-Water,6-Snow/Ice,7-Barren,8-Impervious,9-Wetland
   landuse: 2
diff --git a/src/main/resources/mapper/SimuMapper.xml b/src/main/resources/mapper/SimuMapper.xml
index bdf2487..c6bf931 100644
--- a/src/main/resources/mapper/SimuMapper.xml
+++ b/src/main/resources/mapper/SimuMapper.xml
@@ -1,6 +1,35 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.se.nsl.mapper.SimuMapper">
+    <insert id="insert" parameterType="com.se.nsl.domain.po.Simu">
+        <selectKey resultType="java.lang.Long" order="AFTER" keyProperty="id">
+            select currval('nsl.simu_id_seq'::regclass) as id
+        </selectKey>
+
+        insert into nsl.simu (
+            name, service_name, type, area_type, data, status, result, create_time, create_user, bak, geom)
+        values (
+            #{name},
+            #{serviceName},
+            #{type},
+            #{areaType},
+            #{data},
+            #{status},
+            #{result},
+            now(),
+            #{createUser},
+            #{bak},
+            <choose>
+                <when test="geom != null and geom != ''">
+                    ST_GeomFromText('${geom}')
+                </when>
+                <otherwise>
+                    null
+                </otherwise>
+            </choose>
+        )
+    </insert>
+
     <insert id="inserts" parameterType="com.se.nsl.domain.po.Simu">
         insert into nsl.simu (
             name, service_name, type, area_type, data, status, result, create_time, create_user, bak, geom)

--
Gitblit v1.9.3