dcb
2025-06-06 a2ee6e0dcdcfd9d1b8011a3cecb4e0fc4f6eeea3
实时模拟功能实现
已添加4个文件
已修改7个文件
已删除1个文件
477 ■■■■ 文件已修改
src/main/java/com/se/nsl/controller/SimuController.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/domain/dto/LayerDto.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/domain/vo/ConfigVo.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/domain/vo/RealTimeInput.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/domain/vo/ResultVo.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/helper/HDF5ReaderHelper.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/service/ResolveService.java 190 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/service/SimuService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/service/TestService.java 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/utils/RainFallUnit.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/utils/SimulateType.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/se/nsl/utils/TimeFormatUtil.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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("实时模拟异常");
        }
    }
}
src/main/java/com/se/nsl/domain/dto/LayerDto.java
@@ -6,6 +6,8 @@
public class LayerDto {
    private String version;
    private String name; //生成json的名字,默认位layer.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;
    }
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() {
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;
    }
}
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;
    }
src/main/java/com/se/nsl/helper/HDF5ReaderHelper.java
ÎļþÒÑɾ³ý
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转Tif");
            callZarr2tif(data);
@@ -238,30 +243,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();
        if (null == rainfalls || rainfalls.size() < 2) createRainfall(simu);
@@ -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-降雨模式:正态分布|平均分布|波动平均分布|持续上升> <参数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);
        //生成一个新的生成zarr的配置文件
        File newConfigFile = generateNewZarrConfigFile(serviceNameDir, serviceName, currentTime, newDatFile);
        //执行求解器运算
        String cmd = String.format("%s \"%s\"", config.getUwSolverBat(), newConfigFile);
        callBat2(cmd);
        //生成一个新的zarr转tif的json文件
        File newZarr2TifJson = generateNewZarr2TifJson(serviceNameDir, currentTime);
        //执行zarr转tif
        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(" ");
    }
}
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");
    }
}
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);
    }
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;
    }
}
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;
    }
}
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);
    }
}