dcb
2025-07-07 97629da6a002b534da10f828187fd6cd65941aa4
src/main/java/com/se/nsl/service/ResolveService.java
@@ -4,8 +4,9 @@
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;
@@ -15,6 +16,9 @@
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;
@@ -31,14 +35,11 @@
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
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;
@@ -63,6 +64,8 @@
    @Resource
    TestService testService;
    private ObjectMapper mapper = new ObjectMapper();
    Integer DIGIT = 1000000;
@@ -122,7 +125,7 @@
            createRainfallFile(simu, data);
            update(simu, 2, "调用求解器");
            callUwSolver(data);
            callUwSolver(simu, data);
            update(simu, 3, "调用Zarr转Tif");
            callZarr2tif(data);
@@ -149,7 +152,7 @@
    /**
     * 初始化参数
     */
    public void initArgs(Simu simu, SimuData data) throws IOException {
    public void initArgs(Simu simu, SimuData data) {
        String inPath = config.getInPath() + File.separator + data.getInPath();
        createDir(inPath);
        createDir(inPath + File.separator + "depth");
@@ -160,6 +163,7 @@
        AreaType at = AreaType.of(areaType);
        String terrainTif = config.getSourceDem();
        String landuseTif = config.getSourceLanduse();
        String stationTif = null;
        if (at == AreaType.KEY_DITCH) {
            File keyDitchDir = new File(config.getKeyDitch());
            String areaName = simu.getAreaName();
@@ -174,6 +178,9 @@
                    }
                    if (name.toLowerCase().contains("landuse")) {
                        landuseTif = file.getAbsolutePath();
                    }
                    if (name.toLowerCase().contains("station")) {
                        stationTif = file.getAbsolutePath();
                    }
                }
            }
@@ -190,17 +197,24 @@
        String terrainFile = inPath + File.separator + config.getTerrainFile();
        Dataset dsDem = gdal.Open(terrainTif, gdalconstConstants.GA_ReadOnly);
        ComHelper.Resample(dsDem, null, terrainFile, null, wkt, null, null);
        ComHelper.cutAndResample(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);
        ComHelper.cutAndResample(dsLanduse, null, landuseFile, null, wkt, null, null);
        dsLanduse.delete();
        if (stationTif != null) {
            String stationFile = inPath + File.separator + "Station.tif";
            Dataset dsStation = gdal.Open(stationTif, gdalconstConstants.GA_ReadOnly);
            ComHelper.cutAndResample(dsStation, null, stationFile, null, wkt, null, null);
            dsStation.delete();
        }
    }
    public void updateTif(Simu simu, SimuData data2) throws IOException {
    public void updateTif(Simu simu, SimuData data2) {
        Dataset ds = gdal.Open(config.getSourceLanduse(), gdalconstConstants.GA_Update); // 以读写模式打开TIFF文件
        Band band = ds.GetRasterBand(1);
@@ -237,30 +251,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 +273,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,9 +315,7 @@
    /**
     * 调用UWSolver
     */
    public String callUwSolver(SimuData data) throws Exception {
        File uwBat = new File(config.getUwSolverBat());
    public String callUwSolver(Simu simu, SimuData data) throws Exception {
        int duration = 3600 * data.getDuration(); // 秒数
        if (null != data.getRainfalls() && data.getRainfalls().size() > 1) {
            List<Rainfall> rainfalls = data.getRainfalls();
@@ -346,15 +334,20 @@
        String rainfallFile = (inPath + File.separator + "rainfall.dat");
        String saveName = inPath + File.separator + "result.zarr";
//        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);
        Double saveFrameInterval = config.getSaveFrameInterval();
        int saveFrames = (int) (duration / saveFrameInterval);
        Short type = simu.getType();
        SimulateType simulateType = SimulateType.of(type);
        String saveMode = simulateType.getSaveMode();
        String startTime = TimeFormatUtil.formatDate(data.getStartTime());
        ConfigVo vo = new ConfigVo(terrainFile, landuseFile, terrainFile, rainfallFile,
                saveName, duration, saveFrames, saveMode, startTime);
        vo.setEvaporation(config.getEvaporation());
        vo.getResult().setSave_filter(config.getSaveFilter());
        String configFile = config.getInPath() + File.separator + data.getInPath() + File.separator + data.getInPath() + ".json";
        ComHelper.writeJson(configFile, JSON.toJSONString(vo));
//        ComHelper.writeJson(configFile, JSON.toJSONString(vo));
        mapper.writeValue(new File(configFile), vo);
        String cmd = String.format("%s \"%s\"", config.getUwSolverBat(), configFile);
        return callBat2(cmd);
    }
@@ -367,10 +360,9 @@
        String geotiffDir = inPath + File.separator + "depth";
        String terrainFile = inPath + File.separator + config.getTerrainFile();
        String jsonPath = inPath + File.separator + "zarr2tif.json";
        Zarr2Tif zarr2Tif = new Zarr2Tif(zarrFile, geotiffDir, terrainFile, data.getStartTime());
        ComHelper.writeJson(jsonPath, JSON.toJSONString(zarr2Tif));
        Zarr2Tif zarr2Tif = new Zarr2Tif(zarrFile, geotiffDir, terrainFile, Collections.emptyList());
//        ComHelper.writeJson(jsonPath, JSON.toJSONString(zarr2Tif));
        mapper.writeValue(new File(jsonPath), zarr2Tif);
        String cmd = String.format("%s \"%s\"", config.getZarr2tifBat(), jsonPath);
        return callBat2(cmd);
@@ -384,12 +376,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 +391,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 +419,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 +446,6 @@
    public String createRainfallCsv(String csvPath, String mode, double total, double intensity, int hours) {
        // python 脚本名.py <参数1-csv文件名> <参数2-降雨模式:正态分布|平均分布|波动平均分布|持续上升> <参数3-降雨总量> <参数4-最大雨强> <参数5-降雨时间(分钟)>
        String cmd = String.format("%s \"%s\" \"%s\" %f %f %d", config.getCreateRainfall(), csvPath, mode, total, intensity, hours * 60);
        return callBat(cmd);
    }
@@ -506,11 +479,10 @@
    }
    private List<Double> getValues(String csvPath) throws Exception {
        if (!new File(csvPath).exists()) return null;
        if (!new File(csvPath).exists()) return Collections.emptyList();
        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())
@@ -545,4 +517,18 @@
        Files.write(Paths.get(dat), list, StandardCharsets.UTF_8);
    }
    public List<String> simulationResults(String serviceName) {
        String outPath = config.getOutPath();
        File serviceNameDir = new File(outPath, serviceName);
        List<String> res = new ArrayList<>();
        File[] files = serviceNameDir.listFiles();
        for (File file : files) {
            String name = file.getName();
            if (name.startsWith("layer")) {
                res.add(name);
            }
        }
        return res;
    }
}