package com.se.nsl.service;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.se.nsl.config.PropertiesConfig;
|
import com.se.nsl.domain.dto.DeviceInfo;
|
import com.se.nsl.domain.dto.LayerDto;
|
import com.se.nsl.domain.dto.ResultDto;
|
import com.se.nsl.domain.dto.Zarr2Tif;
|
import com.se.nsl.domain.vo.ConfigVo;
|
import com.se.nsl.domain.vo.RealTimeSimuParam;
|
import com.se.nsl.domain.vo.ResultVo;
|
import com.se.nsl.utils.TimeFormatUtil;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.io.*;
|
import java.nio.file.Files;
|
import java.nio.file.Paths;
|
import java.nio.file.StandardOpenOption;
|
import java.time.LocalDateTime;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.List;
|
import java.util.Random;
|
|
@Slf4j
|
@Service
|
public class RealTimeSimulationService {
|
|
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
@Resource
|
PropertiesConfig config;
|
@Resource
|
TestService testService;
|
|
private ObjectMapper mapper = new ObjectMapper();
|
|
public String realTimeSimulate(RealTimeSimuParam input) throws IOException {
|
// List<String> deviceIds = input.getDeviceIds();
|
InputStream stream = RealTimeSimulationService.class.getResourceAsStream("/a_test_device_info.json");
|
List<DeviceInfo> deviceInfos = mapper.readValue(stream,
|
mapper.getTypeFactory().constructCollectionType(List.class, DeviceInfo.class));
|
String startTime = input.getStartTime();
|
long currentTime = TimeFormatUtil.toMillis(startTime, YYYY_MM_DD_HH_MM_SS);
|
//根据服务找到指定的文件夹
|
String serviceName = input.getServiceName();
|
File serviceNameDir = new File(config.getInPath(), serviceName);
|
//根据雨量计读取余量数据
|
File newDatFile = generateNewRainfallFile(deviceInfos, serviceNameDir, currentTime);
|
|
//生成一个新的生成zarr的配置文件
|
ConfigVo configVo = generateNewZarrConfigFile(serviceNameDir, serviceName, currentTime, newDatFile);
|
File newConfigFile = new File(serviceNameDir, serviceName + ".json");
|
mapper.writeValue(newConfigFile, configVo);
|
//执行求解器运算
|
String cmd = String.format("%s \"%s\"", config.getUwSolverBat(), newConfigFile);
|
callBat2(cmd);
|
|
//生成一个新的zarr转tif的json文件
|
ResultVo result = configVo.getResult();
|
Integer fromFrame = result.getLastFrames();
|
Integer toFrame = result.getSave_frames() - 1;
|
File newZarr2TifJson = generateNewZarr2TifJson(serviceNameDir, currentTime, fromFrame, toFrame);
|
//执行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);
|
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, int fromFrame, int toFrame) throws IOException {
|
File srcZarr2TifJson = new File(serviceNameDir, "zarr2tif.json");
|
Zarr2Tif zarr2Tif = mapper.readValue(srcZarr2TifJson, Zarr2Tif.class);
|
//修改zarr2tif对象中的字段
|
zarr2Tif.setRange(Arrays.asList(fromFrame ,toFrame));
|
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 ConfigVo 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);
|
File stationFile = new File(serviceNameDir, "Station.tif");
|
if (stationFile.exists()) {
|
configVo.setStation(stationFile.getAbsolutePath());
|
}
|
int realTimeSimulateTime = 300; //模拟时间,默认为5min,即300s
|
int realTimeInterval = 60; //每帧的间隔时间,默认为60s,60s生成一帧
|
configVo.getRaingage().set(0, newDatFile.getAbsolutePath()); //raingage file
|
ResultVo result = configVo.getResult();
|
Integer lastFrames = result.getLastFrames();
|
if (lastFrames == null) {
|
lastFrames = 0;
|
}
|
Integer saveStart = result.getSave_start();
|
Integer saveInterval = result.getSave_interval();
|
Integer saveFrames = result.getSave_frames();
|
Integer newStartPoint = saveStart + (saveFrames - lastFrames) * saveInterval;
|
int newSaveFrames = saveFrames + (realTimeSimulateTime / realTimeInterval);
|
result.setSave_start(newStartPoint); //起始时间要在上次时间的基础上开始
|
result.setSave_interval(realTimeInterval);
|
result.setLastFrames(saveFrames);
|
result.setSave_frames(newSaveFrames); //保留5帧,在原来的基础上增加5帧
|
result.setSave_mode("continue");
|
result.setSave_timestamp0(TimeFormatUtil.formatTime(currentTime, YYYY_MM_DD_HH_MM_SS));
|
configVo.setDuration(newStartPoint + realTimeSimulateTime);
|
String newZarrPath = serviceNameDir + File.separator + "result.zarr";
|
result.setSave_name(newZarrPath);
|
return configVo;
|
}
|
|
private File generateNewRainfallFile(List<DeviceInfo> deviceInfos,
|
File serviceNameDir, long currentTime) throws IOException {
|
String title = config.getRainfallTitle();
|
List<String> newLines = new ArrayList<>();
|
newLines.add(title);
|
for (DeviceInfo deviceInfo : deviceInfos) {
|
int stationId = deviceInfo.getMappingId();
|
double lon = deviceInfo.getX();
|
double lat = deviceInfo.getY();
|
LocalDateTime dateTime = TimeFormatUtil.toDate(currentTime);
|
int year = dateTime.getYear();
|
int month = dateTime.getMonthValue();
|
int day = dateTime.getDayOfMonth();
|
int hour = dateTime.getHour();
|
int minute = dateTime.getMinute();
|
double intensity = randomIntensity(); //保留指定位数小数
|
String l = String.format("%s %s %s %s %s %s %s %s %s",
|
stationId, lon, lat, year, month, day, hour, minute, String.format("%.6f", intensity));
|
newLines.add(l);
|
LocalDateTime dateTime1 = dateTime.plusMinutes(5);
|
year = dateTime1.getYear();
|
month = dateTime1.getMonthValue();
|
day = dateTime1.getDayOfMonth();
|
hour = dateTime1.getHour();
|
minute = dateTime1.getMinute();
|
intensity = randomIntensity();
|
String l2 = String.format("%s %s %s %s %s %s %s %s %s",
|
stationId, lon, lat, year, month, day, hour, minute, String.format("%.6f", intensity));
|
newLines.add(l2);
|
}
|
File newDatFile = new File(serviceNameDir, "rainfall_" + currentTime + ".dat");
|
if (!newDatFile.exists()) newDatFile.createNewFile();
|
Files.write(newDatFile.toPath(), newLines, StandardOpenOption.TRUNCATE_EXISTING);
|
return newDatFile;
|
}
|
|
private double randomIntensity() {
|
Random random = new Random();
|
// 生成0.2到1之间的随机数
|
double min = 0.2;
|
double max = 1.0;
|
return min + random.nextDouble() * (max - min);
|
}
|
|
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(" ");
|
}
|
|
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;
|
}
|
}
|
|
}
|