package com.se.nsl.service;
|
|
import cn.hutool.core.collection.CollUtil;
|
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.*;
|
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;
|
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;
|
|
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.*;
|
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;
|
import java.util.concurrent.Executors;
|
import java.util.stream.Collectors;
|
|
@Slf4j
|
@Service
|
@SuppressWarnings("ALL")
|
public class ResolveService {
|
@Resource
|
SimuService simuService;
|
|
@Resource
|
PropertiesConfig config;
|
|
@Resource
|
UwService uwService;
|
|
@Resource
|
TestService testService;
|
|
private ObjectMapper mapper = new ObjectMapper();
|
|
Integer DIGIT = 1000000;
|
|
SimpleDateFormat YYYYMDHM = new SimpleDateFormat("yyyy M d H m ");
|
|
List<String> MODES = new ArrayList<>(Arrays.asList("正态分布", "平均分布", "波动平均分布", "持续上升"));
|
|
public int start(Simu simu) {
|
Date now = new Date();
|
String date = StringHelper.YMDHMS2_FORMAT.format(now);
|
|
// 将WKT转换为Geometry对象
|
Geometry geom = Geometry.CreateFromWkt(simu.getGeom());
|
if (geom.GetGeometryType() == ogr.wkbMultiPolygon) {
|
geom = geom.GetGeometryRef(0);
|
}
|
double[] envelope = new double[4];
|
geom.GetEnvelope(envelope);
|
|
SimuData data = JSON.parseObject(simu.getData(), SimuData.class);
|
data.setInPath(date);
|
data.setOutPath(date);
|
data.setEnvelope(envelope);
|
data.setEpsg(config.getEpsg());
|
|
simu.setData(JSON.toJSONString(data));
|
simu.setServiceName(date);
|
simu.setStatus(1); // 0-创建仿真,1-预处理,2-分析中,10-完成,20-出错
|
simu.setUpdateTime(new Timestamp(now.getTime()));
|
|
int rows = simuService.updateById(simu);
|
if (rows > 0) {
|
asyncCall(simu);
|
}
|
|
return rows;
|
}
|
|
private void asyncCall(Simu simu) {
|
ExecutorService executor = Executors.newSingleThreadExecutor();
|
executor.execute(new Runnable() {
|
@Override
|
@SneakyThrows
|
public void run() {
|
cope(simu);
|
}
|
});
|
executor.shutdown();
|
}
|
|
private void cope(Simu simu) {
|
try {
|
SimuData data = JSONUtil.toBean(simu.getData(), SimuData.class);
|
|
update(simu, 1, "初始化参数");
|
initArgs(simu, data);
|
createRainfallFile(simu, data);
|
|
update(simu, 2, "调用求解器");
|
callUwSolver(simu, data);
|
|
update(simu, 3, "调用Zarr转Tif");
|
callZarr2tif(data);
|
|
update(simu, 4, "解析数据");
|
createNsl(data);
|
|
update(simu, 10, "完成");
|
log.info("模拟完成");
|
} catch (Exception ex) {
|
log.error(ex.getMessage(), ex);
|
update(simu, 20, ex.getMessage());
|
}
|
}
|
|
private void update(Simu simu, int status, String rs) {
|
simu.setStatus(status);
|
if (null != rs) simu.setResult(rs);
|
simu.setUpdateTime(WebHelper.getCurrentTimestamp());
|
|
simuService.updateById(simu);
|
}
|
|
/**
|
* 初始化参数
|
*/
|
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());
|
|
Short areaType = simu.getAreaType();
|
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();
|
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();
|
}
|
if (name.toLowerCase().contains("station")) {
|
stationTif = 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();
|
|
if (stationTif != null) {
|
String stationFile = inPath + File.separator + "Station.tif";
|
Dataset dsStation = gdal.Open(stationTif, gdalconstConstants.GA_ReadOnly);
|
ComHelper.Resample(dsStation, null, stationFile, null, wkt, null, null);
|
dsStation.delete();
|
}
|
}
|
|
public void updateTif(Simu simu, SimuData data2) {
|
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(注意Java的byte是有符号的,需处理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); // 设置新Nodata值
|
band.FlushCache(); // 强制写入更改
|
ds.delete();
|
}
|
|
private void createDir(String path) {
|
File f = new File(path);
|
if (f.exists() && f.isDirectory()) {
|
FileUtil.del(f);
|
}
|
f.mkdirs();
|
}
|
|
public void createRainfallFile(Simu simu, SimuData data) throws Exception {
|
List<Rainfall> rainfalls = data.getRainfalls();
|
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());
|
|
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 + " ";
|
//如果没有单位或者单位为mm/h则按照 mm/h计算,否则按照mm/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.getUnit());
|
int unit = rfUnit.getC();
|
int c = rainfalls.size() - 1;
|
for (int i = 0; i < c; i++) {
|
Rainfall r1 = rainfalls.get(i);
|
Rainfall r2 = rainfalls.get(i + 1);
|
|
list.addAll(calcRainfall(r1, r2, prefix, unit));
|
}
|
//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);
|
}
|
|
public static double getMinVal(double val, double radix) {
|
return ((long) Math.floor(val * radix)) / radix;
|
}
|
|
// beijing 116.0 40.0 2025 1 1 0 13 1.666666
|
private List<String> calcRainfall(Rainfall r1, Rainfall r2, String prefix, int unit) {
|
long mins = Math.abs(r2.getTime().getTime() - r1.getTime().getTime()) / (1000 * 60); // 计算分钟数
|
double diff = (r2.getIntensity() - r1.getIntensity()) / mins / unit; //ComHelper.getMinVal((r1.getIntensity() - r2.getIntensity()) / mins / unit, DIGIT);
|
|
Calendar cal = Calendar.getInstance();
|
cal.setTime(r1.getTime());
|
|
List<String> list = new ArrayList<>();
|
double intensity = ComHelper.getMinVal(r1.getIntensity() / unit, DIGIT);
|
for (int i = 0; i < mins; i++) {
|
//list.add(prefix + YYYYMDHM.format(cal.getTime()) + getMinVal((intensity + diff * i), DIGIT));
|
list.add(String.format("%s%s%f", prefix, YYYYMDHM.format(cal.getTime()), getMinVal((intensity + diff * i), DIGIT)));
|
cal.add(Calendar.MINUTE, 1);
|
}
|
|
return list;
|
}
|
|
/**
|
* 调用UWSolver
|
*/
|
public String callUwSolver(Simu simu, SimuData data) throws Exception {
|
File uwBat = new File(config.getUwSolverBat());
|
|
int duration = 3600 * data.getDuration(); // 秒数
|
if (null != data.getRainfalls() && data.getRainfalls().size() > 1) {
|
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.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, landuseFile, terrainFile, rainfallFile, saveName, duration, config.getSaveFrames());
|
Integer saveFrameInterval = config.getSaveFrameInterval();
|
int saveFrames = duration / 60 / 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);
|
String configFile = config.getInPath() + File.separator + data.getInPath() + File.separator + data.getInPath() + ".json";
|
// ComHelper.writeJson(configFile, JSON.toJSONString(vo));
|
mapper.writeValue(new File(configFile), vo);
|
String cmd = String.format("%s \"%s\"", config.getUwSolverBat(), configFile);
|
return callBat2(cmd);
|
}
|
|
/**
|
* 调用zarr2tif
|
*/
|
public String callZarr2tif(SimuData data) throws Exception {
|
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.getTerrainFile();
|
String jsonPath = inPath + File.separator + "zarr2tif.json";
|
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);
|
}
|
|
private String callBat2(String cmd) {
|
try {
|
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", cmd);
|
pb.redirectErrorStream(true); // 合并错误流到标准输出
|
|
Process process = pb.start();
|
process.getOutputStream().close();
|
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"))) {
|
String line;
|
while ((line = reader.readLine()) != null) {
|
log.info(line);
|
}
|
}
|
|
int exitCode = process.waitFor();
|
|
return "ok"; // sb.toString();
|
} catch (Exception ex) {
|
log.error(ex.getMessage(), ex);
|
return null;
|
}
|
}
|
|
private String callBat(String cmd) {
|
try {
|
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", cmd);
|
pb.redirectErrorStream(true); // 合并错误流到标准输出
|
|
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);
|
}
|
}*/
|
|
int exitCode = process.waitFor();
|
|
return "ok"; // sb.toString();
|
} catch (Exception ex) {
|
log.error(ex.getMessage(), ex);
|
return null;
|
}
|
}
|
|
private void createNsl(SimuData data) throws Exception {
|
testService.test(data);
|
}
|
|
private void procTifs(String tifPath, String outPath, Date startTime) {
|
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
|
Calendar calendar = Calendar.getInstance();
|
calendar.setTime(startTime);
|
|
for (File file : new File(tifPath).listFiles()) {
|
if (!file.exists() || !file.isDirectory()) continue;
|
|
File tif = new File(tifPath + "\\" + file.getName() + File.separator + "depth.tif");
|
if (!tif.exists() || tif.isDirectory()) continue;
|
|
calendar.add(Calendar.SECOND, 1);
|
String newName = df.format(calendar.getTime());
|
String newFile = outPath + File.separator + newName + ".tif";
|
|
System.out.println(newFile);
|
tif.renameTo(new File(newFile));
|
file.delete();
|
}
|
}
|
|
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);
|
}
|
|
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);
|
}
|
// list.add(0, "1 " + (list.size() - 1));
|
|
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 File generateNewZarr2TifJson(File serviceNameDir, long currentTime) throws IOException {
|
File srcZarr2TifJson = new File(serviceNameDir, "zarr2tif.json");
|
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";
|
String newZarrPath = serviceNameDir + File.separator + "result.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");
|
ConfigVo configVo = mapper.readValue(configFile, ConfigVo.class);
|
int simulateTime = 300; //模拟时间,默认为5min,即300s
|
int intervalTime = 60; //每帧的间隔时间,默认为60s,60s生成一帧
|
configVo.getRaingage().set(0, newDatFile.getAbsolutePath()); //raingage file
|
ResultVo result = configVo.getResult();
|
Integer oldDuration = configVo.getDuration();
|
// result.setSave_start(oldDuration); //起始时间要在上次时间的基础上开始
|
configVo.setDuration(oldDuration + simulateTime); //固定为5min
|
result.setSave_interval(intervalTime);
|
result.setSave_frames(result.getSave_frames() + (simulateTime / intervalTime)); //保留5帧,在原来的基础上增加5帧
|
// String newZarrPath = serviceNameDir + File.separator + "result_" + currentTime + ".zarr";
|
String newZarrPath = serviceNameDir + File.separator + "result.zarr";
|
result.setSave_name(newZarrPath);
|
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(" ");
|
}
|
}
|