| | |
| | | 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.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; |
| | |
| | | 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; |
| | |
| | | |
| | | @Resource |
| | | TestService testService; |
| | | |
| | | private ObjectMapper mapper = new ObjectMapper(); |
| | | |
| | | Integer DIGIT = 1000000; |
| | | |
| | |
| | | createRainfallFile(simu, data); |
| | | |
| | | update(simu, 2, "调用求解器"); |
| | | callUwSolver(data); |
| | | callUwSolver(simu, data); |
| | | |
| | | update(simu, 3, "调用Zarr转Tif"); |
| | | callZarr2tif(data); |
| | |
| | | createNsl(data); |
| | | |
| | | update(simu, 10, "完成"); |
| | | log.info("模拟完成"); |
| | | } catch (Exception ex) { |
| | | log.error(ex.getMessage(), ex); |
| | | update(simu, 20, ex.getMessage()); |
| | |
| | | /** |
| | | * 初始化参数 |
| | | */ |
| | | 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"); |
| | |
| | | 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(); |
| | |
| | | } |
| | | if (name.toLowerCase().contains("landuse")) { |
| | | landuseTif = file.getAbsolutePath(); |
| | | } |
| | | if (name.toLowerCase().contains("station")) { |
| | | stationTif = file.getAbsolutePath(); |
| | | } |
| | | } |
| | | } |
| | |
| | | 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); |
| | |
| | | } |
| | | 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(); |
| | |
| | | // 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); |
| | |
| | | } |
| | | //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)); |
| | | // list.add(0, "1 " + (list.size() - 1)); |
| | | |
| | | Files.write(Paths.get(rainfallFile), list, StandardCharsets.UTF_8); |
| | | } |
| | |
| | | /** |
| | | * 调用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(); |
| | |
| | | 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); |
| | | } |
| | | |
| | |
| | | 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); |
| | |
| | | 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); |
| | | } |
| | | } |
| | | |
| | |
| | | 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 { |
| | |
| | | } |
| | | |
| | | 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); |
| | | } |
| | | |
| | |
| | | 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); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | 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()) |
| | |
| | | |
| | | cal.add(Calendar.MINUTE, 1); |
| | | } |
| | | list.add(0, "1 " + (list.size() - 1)); |
| | | // list.add(0, "1 " + (list.size() - 1)); |
| | | |
| | | 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; |
| | | } |
| | | } |