气象查询提交

This commit is contained in:
hekaiyu 2025-12-04 16:35:49 +08:00
parent 9080e2f29e
commit 8d615a8411
8 changed files with 202 additions and 265 deletions

View File

@ -2,31 +2,35 @@ package org.jeecg.common.constant;
public class EventConstants {
public static final String DOSE_FACTOR_NAME = "doseFactor.txt";
public static final String SOURCE_DATA_NAME = "sourceData.txt";
public static final String GK_NAME = "combined_factors.xlsx";
public static final String WRF_DIR = "wrf";
public static final String CONC_DIR = "cctm";
public static final String METCR03D_DIR = "mcip";
public static final String METCRO3D_DIR = "mcip";
public static final String EMIS_DIR = "data/emis/d03";
public static final String GK_NAME = "data_48.xlsx";
public static final String MERGE_RESULTS = "merge_results_to_nc.py";
public static final String SUM_DRY_WET = "sum_dry_wet_to_nc.py";
public static final String DOSE_CALCULATOR = "dose_calculator.py";
public static final String CONVERT_CONC_TO_DOSE = "convert_conc_to_dose.py";
public static final String DEP_VNAMES = "ASIJ";
public static final String WRF_VNAMES = "XLAT,XLONG,HGT,U,V,W";
public static final String CONC_VNAMES = "CO,ASIJ";
public static final String METCR03D_VNAMES = "TA,PRES";
public static final String METCRO3D_VNAMES = "TA,PRES";
public static final String EMIS_VNAMES = "CO,PSI";
public static final String WRF_PATTERN = "wrfout_d03_{YYYY-MM-DD}_00_00_00";
public static final String CONC_PATTERN = "CCTM.CONC.d03.{YYYYMMDD";
public static final String METCR03D_PATTERN = "METCR03D_d03_{YYYYMMDD}";
public static final String CONC_PATTERN = "CCTM.CONC.d03.{YYYYMMDD}";
public static final String METCRO3D_PATTERN = "METCRO3D_d03_{YYYYMMDD}";
public static final String EMIS_PATTERN = "emis_{YYYYMMDD}";
public static final String DEP_OUT_PREFIX = "out_dep_";
public static final String WRF_OUT_PREFIX = "out_wrf_";
public static final String CONC_OUT_PREFIX = "out_conc_";
public static final String METCR03D_OUT_PREFIX = "out_metcr03d_";
public static final String METCRO3D_OUT_PREFIX = "out_metcro3d_";
public static final String EMIS_OUT_PREFIX = "out_emis_";
public static final String DOSE_OUT_PREFIX = "out_dose_";

View File

@ -114,14 +114,4 @@ public class EventCoefficientController extends JeecgController<EventCoefficient
}
return Result.OK(eventCoefficient);
}
public double calculateActivity(int power,int runTime,double halfLife,double heatSpectrum){
double activity;
if(halfLife < power){
activity = 310 * heatSpectrum * 100 * power * 1000000000000l;
}else{
activity = 210 * heatSpectrum * 100 * runTime * power * 1000000000000l / halfLife;
}
return activity;
}
}

View File

@ -19,4 +19,5 @@ public interface EventTypeService extends IService<EventType> {
void delEventType(Integer id);
void editCoefficientType(List<EventCoefficientVO> eventCoefficientVOs);
EventResultVO queryCoefficients();
void genSourceItemFile(Integer eventTypeId, String resultFilePath);
}

View File

@ -3,13 +3,17 @@ package org.jeecg.eventType.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.RequiredArgsConstructor;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.EventConstants;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.eventCoefficient.service.EventCoefficientService;
import org.jeecg.eventType.vo.EventCoefficientVO;
import org.jeecg.eventType.vo.EventResultVO;
import org.jeecg.modules.base.entity.DoseFactor;
import org.jeecg.modules.base.entity.EventCoefficient;
import org.jeecg.modules.base.entity.EventType;
import org.jeecg.modules.base.entity.NuclideType;
import org.jeecg.modules.base.mapper.EngineeringMapper;
import org.jeecg.modules.base.mapper.EventCoefficientMapper;
import org.jeecg.modules.base.mapper.EventTypeMapper;
import org.jeecg.eventType.service.EventTypeService;
@ -19,7 +23,11 @@ import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -38,6 +46,7 @@ public class EventTypeServiceImpl extends ServiceImpl<EventTypeMapper, EventType
public final EventCoefficientMapper eventCoefficientMapper;
public final NuclideTypeMapper nuclideTypeMapper;
public final EngineeringMapper engineeringMapper;
@Override
@Transactional(rollbackFor = Exception.class)
@ -221,6 +230,104 @@ public class EventTypeServiceImpl extends ServiceImpl<EventTypeMapper, EventType
return vo;
}
@Override
public void genSourceItemFile(Integer eventTypeId, String resultFilePath){
genDoseFactorFile(resultFilePath);
genSourceDataFile(eventTypeId, resultFilePath);
}
/**
* 生成剂量因子文件 (doseFactor.txt)
*/
public void genDoseFactorFile(String resultFilePath) {
List<DoseFactor> doseFactors = engineeringMapper.getDoseFactor();
try (BufferedWriter writer = new BufferedWriter(new FileWriter(resultFilePath + EventConstants.DOSE_FACTOR_NAME))) {
// 写入DoseFactor 数据
for (DoseFactor factor : doseFactors) {
if (factor != null) { // 安全检查避免 NullPointerException
// 使用 \t 分割不控制格式
writer.write(
valueOrEmpty(factor.getHalfLife()) + "\t" +
valueOrEmpty(factor.getCef()) + "\t" +
valueOrEmpty(factor.getSef()) + "\t" +
valueOrEmpty(factor.getRif())
);
writer.newLine(); // 写入换行符
}
}
} catch (IOException e) {
e.printStackTrace();
throw new JeecgBootException("生成doseFactor.txt文件失败: " + e.getMessage());
} catch (NullPointerException e) {
e.printStackTrace();
throw new JeecgBootException("生成doseFactor.txt文件时发生空指针异常: " + e.getMessage());
}
}
/**
* 生成源数据文件 (sourceData.txt)
*/
public void genSourceDataFile(Integer eventTypeId, String resultFilePath) {
// 获取事件类型数据用于计算
EventType eventType = this.baseMapper.selectById(eventTypeId);
List<NuclideType> nuclideTypes = nuclideTypeMapper.selectList(
new LambdaQueryWrapper<NuclideType>().orderByAsc(NuclideType::getCreateTime)
);
try (BufferedWriter writer = new BufferedWriter(new FileWriter(resultFilePath + EventConstants.SOURCE_DATA_NAME))) {
// 计算并写入 activity
if (eventType != null && nuclideTypes != null) {
for (NuclideType nuclideType : nuclideTypes) {
if (nuclideType != null) {
Double power = eventType.getPower();
Long runTime = eventType.getRunTime();
Double halfLife = nuclideType.getHalfLife();
Double heatSpectrum = nuclideType.getHeatSpectrum();
// 检查必要的参数是否为null
if (power != null && runTime != null && halfLife != null && heatSpectrum != null) {
double value = calculateActivity(power, runTime, halfLife, heatSpectrum);
writer.write(valueOrEmpty(value));
writer.newLine(); // 写入换行符
} else {
throw new JeecgBootException("核素 " + (nuclideType.getNuclideName() != null ? nuclideType.getNuclideName() : "未知") + " - 缺少必要参数");
}
}
}
} else {
throw new JeecgBootException("无法获取事件类型或核素类型数据");
}
} catch (IOException e) {
e.printStackTrace();
throw new JeecgBootException("生成sourceData.txt文件失败: " + e.getMessage());
} catch (NullPointerException e) {
e.printStackTrace();
throw new JeecgBootException("生成sourceData.txt文件时发生空指针异常: " + e.getMessage());
} catch (JeecgBootException e) {
e.printStackTrace();
throw new JeecgBootException("生成sourceData.txt文件时发生业务异常: " + e.getMessage());
}
}
public double calculateActivity(double power, long runTime, double halfLife, double heatSpectrum) {
double activity;
if (halfLife < runTime) {
activity = 310 * heatSpectrum * 100 * power * 1000000000000L;
} else {
activity = 210 * heatSpectrum * 100 * runTime * power * 1000000000000L / halfLife;
}
return activity;
}
private String valueOrEmpty(Double value) {
return (value != null) ? value.toString() : " ";
}
}

View File

@ -70,41 +70,4 @@ public class RunProcessController {
return Result.OK("运行成功!");
}
/**
* 运行wrf所有程序
*
* @param
* @return
*/
@GetMapping(value = "/test")
public Result<?> test() {
List<DoseFactor> doseFactors = engineeringService.getDoseFactor();
try (BufferedWriter writer = new BufferedWriter(new FileWriter("D:\\hky_word\\Projectlibrary\\resultFile\\dose\\py\\doseFactor.txt"))) {
for (DoseFactor factor : doseFactors) {
if (factor != null) { // 安全检查避免 NullPointerException
// *** 关键修改点使用 \t 分割不控制格式 ***
writer.write(
valueOrEmpty(factor.getHalfLife()) + "\t" +
valueOrEmpty(factor.getCef()) + "\t" +
valueOrEmpty(factor.getSef()) + "\t" +
valueOrEmpty(factor.getRif())
);
writer.newLine(); // 写入换行符
}
}
System.out.println("文件DoseFactor已成功生成。");
} catch (IOException e) {
System.err.println("生成文件时出错: " + e.getMessage());
e.printStackTrace();
} catch (NullPointerException e) {
System.err.println("处理数据时出现空指针异常: " + e.getMessage());
e.printStackTrace();
}
return Result.OK("运行成功!");
}
private String valueOrEmpty(Double value) {
return (value != null) ? value.toString() : " ";
}
}

View File

@ -51,19 +51,19 @@ public class TestMain {
ProcessBuilder concBuilder = new ProcessBuilder(cmd_cmaq);
ExecutePyUtils.executePythonProcess(concBuilder, "conc");
String[] cmd_metcr03d = {
String[] cmd_metcro3d = {
"python",
"D:\\hky_word\\Projectlibrary\\resultFile\\dose\\py\\merge_results_to_nc.py",
"TA,PRES",
"D:\\hky_word\\Projectlibrary\\resultFile\\admin\\工程002",
"D:\\hky_word\\Projectlibrary\\resultFile\\dose\\工程002",
"out_metcr03d_20160701",
"out_metcro3d_20160701",
"20160701",
"20160702",
"METCRO3D_d03_{YYYYMMDD}" // 使用占位符
};
ProcessBuilder metcr03dBuilder = new ProcessBuilder(cmd_metcr03d);
ExecutePyUtils.executePythonProcess(metcr03dBuilder, "metcr03d");
ProcessBuilder metcro3dBuilder = new ProcessBuilder(cmd_metcro3d);
ExecutePyUtils.executePythonProcess(metcro3dBuilder, "metcro3d");
String[] cmd_emis = {
"python",
@ -90,7 +90,7 @@ public class TestMain {
"out_dep_20160701",
"out_wrf_20160701",
"out_conc_20160701",
"out_metcr03d_20160701",
"out_metcro3d_20160701",
"out_emis_20160701",
"out_dose_20160701",
};

View File

@ -9,6 +9,7 @@ import org.jeecg.common.constant.EventConstants;
import org.jeecg.common.properties.EventServerProperties;
import org.jeecg.common.util.ExecutePyUtils;
import org.jeecg.engineering.service.EngineeringService;
import org.jeecg.eventType.service.EventTypeService;
import org.jeecg.modules.base.entity.Engineering;
import org.jeecg.modules.base.entity.Wrf;
import org.jeecg.runProcess.VO.RunProcessParamVO;
@ -33,6 +34,7 @@ public class RunProcessServiceImpl implements RunProcessService {
private final EngineeringService engineeringService;
private final BaseAPIService baseAPIService;
private final EventServerProperties eventServerProperties;
private final EventTypeService eventTypeService;
@Override
public Result<String> runAllExe(RunProcessParamVO paramVO){
@ -63,8 +65,8 @@ public class RunProcessServiceImpl implements RunProcessService {
// return cmaqResult;
// }
String sDate = wrf.getStartTime().substring(0, 10);
String eDate = wrf.getEndTime().substring(0, 10);
String sDate = wrf.getStartTime().substring(0, 10).replace("-","");
String eDate = LocalDateTime.parse( wrf.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
exeDepPy(sDate, eDate, EventConstants.DEP_VNAMES,
workDirPath + EventConstants.CONC_DIR, resultFilePath,
@ -78,15 +80,19 @@ public class RunProcessServiceImpl implements RunProcessService {
workDirPath + EventConstants.CONC_DIR, resultFilePath,
EventConstants.CONC_OUT_PREFIX, EventConstants.CONC_PATTERN, "合并CONC结果数据");
exePyScript(sDate, eDate, EventConstants.METCR03D_VNAMES,
workDirPath + EventConstants.METCR03D_DIR, resultFilePath,
EventConstants.METCR03D_OUT_PREFIX, EventConstants.METCR03D_PATTERN, "合并METCR03D结果数据");
exePyScript(sDate, eDate, EventConstants.METCRO3D_VNAMES,
workDirPath + EventConstants.METCRO3D_DIR, resultFilePath,
EventConstants.METCRO3D_OUT_PREFIX, EventConstants.METCRO3D_PATTERN, "合并METCRO3D结果数据");
exePyScript(sDate, eDate, EventConstants.EMIS_VNAMES,
workDirPath + EventConstants.EMIS_DIR, resultFilePath,
allRunPath + EventConstants.EMIS_DIR, resultFilePath,
EventConstants.EMIS_OUT_PREFIX, EventConstants.EMIS_PATTERN, "合并EMIS结果数据");
exeDosePy(sDate, eDate, resultFilePath, resultFilePath, scriptsPath,"执行剂量转换");
//生成计算剂量转换系数入参文件
eventTypeService.genSourceItemFile(engineering.getEventType(), resultFilePath);
exeDoseCalculator(wrf.getAnalogTime(), resultFilePath, "计算剂量转换系数");
exeDosePy(sDate, eDate, resultFilePath,"执行剂量转换");
}catch (Exception e){
e.printStackTrace();
@ -169,9 +175,9 @@ public class RunProcessServiceImpl implements RunProcessService {
eventServerProperties.getBaseHome() + File.separator +
eventServerProperties.getPythonPath() + File.separator + EventConstants.MERGE_RESULTS,
vNames,
eventServerProperties.getBaseHome() + File.separator + inputPath,
inputPath,
outputPath,
outFileName,
outFileName + sDate,
sDate,
eDate,
pattern // 使用占位符
@ -190,9 +196,9 @@ public class RunProcessServiceImpl implements RunProcessService {
eventServerProperties.getBaseHome() + File.separator +
eventServerProperties.getPythonPath() + File.separator + EventConstants.SUM_DRY_WET,
vNames,
eventServerProperties.getBaseHome() + File.separator + inputPath,
inputPath,
outputPath,
outFileName,
outFileName + sDate,
sDate,
eDate
};
@ -200,23 +206,42 @@ public class RunProcessServiceImpl implements RunProcessService {
ExecutePyUtils.executePythonProcess(processBuilder, desc);
}
/**
* 计算剂量转换系数
*/
private void exeDoseCalculator(String analogTime, String resultFilePath, String desc) {
String[] command = {
"python",
eventServerProperties.getBaseHome() + File.separator +
eventServerProperties.getPythonPath() + File.separator + EventConstants.DOSE_CALCULATOR,
analogTime,
resultFilePath,
resultFilePath,
EventConstants.DOSE_FACTOR_NAME,
EventConstants.SOURCE_DATA_NAME,
EventConstants.GK_NAME,
};
ProcessBuilder processBuilder = new ProcessBuilder(command);
ExecutePyUtils.executePythonProcess(processBuilder, desc);
}
/**
* 执行浓度转剂量Python脚本
*/
private void exeDosePy(String sDate, String eDate, String inputPath, String outputPath, String gkPath, String desc) {
private void exeDosePy(String sDate, String eDate, String resultFilePath, String desc) {
String[] command = {
"python",
eventServerProperties.getBaseHome() + File.separator +
eventServerProperties.getPythonPath() + File.separator + EventConstants.CONVERT_CONC_TO_DOSE,
sDate,
eDate,
eventServerProperties.getBaseHome() + File.separator + inputPath,
eventServerProperties.getBaseHome() + File.separator + outputPath,
gkPath + File.separator + EventConstants.GK_NAME,
resultFilePath,
resultFilePath,
EventConstants.GK_NAME,
EventConstants.DEP_OUT_PREFIX + sDate,
EventConstants.WRF_OUT_PREFIX + sDate,
EventConstants.CONC_OUT_PREFIX + sDate,
EventConstants.METCR03D_OUT_PREFIX + sDate,
EventConstants.METCRO3D_OUT_PREFIX + sDate,
EventConstants.EMIS_OUT_PREFIX + sDate,
EventConstants.DOSE_OUT_PREFIX + sDate
};

View File

@ -167,11 +167,10 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
// 循环处理每个时间点的数据
LocalDateTime currentTime = startTime;
while (!currentTime.isAfter(endTime)) {
String filePath = getWeatherFilePath(weatherDataList, currentTime, WeatherTypeEnum.TEMPERATURE.getKey(),
WeatherDataSourceEnum.getInfoByKey(dataType));
String filePath = getWeatherFilePath(weatherDataList, currentTime);
if (isFileValid(filePath)) {
try {
processCommonData(weatherDataList, filePath, gridIndex, currentTime, timeList, temperatureList,
processCommonData(filePath, gridIndex, currentTime, timeList, temperatureList,
pressureList, humidityList, windSpeedList, dataType);
} catch (Exception e) {
log.error("处理时间点 {} 数据时出错: {}", currentTime, e.getMessage(), e);
@ -255,30 +254,13 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
LocalDateTime currentTime = startTime;
while (!currentTime.isAfter(endTime)) {
try {
if (WeatherDataSourceEnum.CRA40.getKey().equals(dataType)) {
// CRA40数据源UV分量在不同文件
String uFilePath = getWeatherFilePath(weatherDataList, currentTime,
WeatherTypeEnum.WIND.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String vFilePath = getWeatherFilePath(weatherDataList, currentTime,
WeatherTypeEnum.WIND.getKey() + 1, WeatherDataSourceEnum.getInfoByKey(dataType));
// 标准数据源UV分量在同一文件
String filePath = getWeatherFilePath(weatherDataList, currentTime);
if (isFileValid(uFilePath) && isFileValid(vFilePath)) {
try (NetcdfFile uNcFile = NetcdfFile.open(uFilePath);
NetcdfFile vNcFile = NetcdfFile.open(vFilePath)) {
uValues.add(getNcValueByIndex(uNcFile, variables.get("windU"), gridIndex[0], gridIndex[1]));
vValues.add(getNcValueByIndex(vNcFile, variables.get("windV"), gridIndex[0], gridIndex[1]));
}
}
} else {
// 标准数据源UV分量在同一文件
String filePath = getWeatherFilePath(weatherDataList, currentTime,
WeatherTypeEnum.WIND.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
if (isFileValid(filePath)) {
try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
uValues.add(getNcValueByIndex(ncFile, variables.get("windU"), gridIndex[0], gridIndex[1]));
vValues.add(getNcValueByIndex(ncFile, variables.get("windV"), gridIndex[0], gridIndex[1]));
}
if (isFileValid(filePath)) {
try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
uValues.add(getNcValueByIndex(ncFile, variables.get("windU"), gridIndex[0], gridIndex[1]));
vValues.add(getNcValueByIndex(ncFile, variables.get("windV"), gridIndex[0], gridIndex[1]));
}
}
} catch (Exception e) {
@ -651,64 +633,23 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
/**
* 通用数据处理方法
*/
private void processCommonData(List<WeatherData> weatherDataList, String filePath, int[] gridIndex, LocalDateTime currentTime,
private void processCommonData(String filePath, int[] gridIndex, LocalDateTime currentTime,
List<String> timeList, List<String> temperatureList,
List<String> pressureList, List<String> humidityList,
List<String> windSpeedList, Integer dataType) throws IOException {
// 使用与第一个方法相同的变量名获取方式
Map<String, String> variables = getVariableNames(dataType);
if(WeatherDataSourceEnum.CRA40.getKey() != dataType){
try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
Double tValue = getNcValueByIndex(ncFile, variables.get("temperature"), gridIndex[0], gridIndex[1]) - 273.15;
Double pValue = getNcValueByIndex(ncFile, variables.get("pressure"), gridIndex[0], gridIndex[1]) / 1000;
Double hValue = getNcValueByIndex(ncFile, variables.get("humidity"), gridIndex[0], gridIndex[1]);
Double uValue = getNcValueByIndex(ncFile, variables.get("windU"), gridIndex[0], gridIndex[1]);
Double vValue = getNcValueByIndex(ncFile, variables.get("windV"), gridIndex[0], gridIndex[1]);
Double windSpeed = Math.sqrt(uValue * uValue + vValue * vValue);
// 添加格式化数据
addFormattedData(currentTime, timeList, temperatureList, pressureList,
humidityList, windSpeedList, tValue, pValue, hValue, windSpeed);
}
}else {
// 循环处理每个时间点的数据
try {
String tFilePath = getWeatherFilePath(weatherDataList, currentTime, WeatherTypeEnum.TEMPERATURE.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String pFilePath = getWeatherFilePath(weatherDataList, currentTime, WeatherTypeEnum.PRESSURE.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String hFilePath = getWeatherFilePath(weatherDataList, currentTime, WeatherTypeEnum.HUMIDITY.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String uFilePath = getWeatherFilePath(weatherDataList, currentTime, WeatherTypeEnum.WIND.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String vFilePath = getWeatherFilePath(weatherDataList, currentTime,WeatherTypeEnum.WIND.getKey() + 1, WeatherDataSourceEnum.getInfoByKey(dataType));
Double tValue = null;
Double pValue = null;
Double hValue = null;
Double windSpeed = null;
if (isFileValid(tFilePath)) {
NetcdfFile ncFile = NetcdfFile.open(tFilePath);
tValue = getNcValueByIndex(ncFile, variables.get("temperature"), gridIndex[0], gridIndex[1]) - 273.15;
}
if (isFileValid(pFilePath)) {
NetcdfFile ncFile = NetcdfFile.open(pFilePath);
pValue = getNcValueByIndex(ncFile, variables.get("pressure"), gridIndex[0], gridIndex[1]) / 1000;
}
if (isFileValid(hFilePath)) {
NetcdfFile ncFile = NetcdfFile.open(hFilePath);
hValue = getNcValueByIndex(ncFile, variables.get("humidity"), gridIndex[0], gridIndex[1]);
}
if (isFileValid(uFilePath) && isFileValid(vFilePath)) {
NetcdfFile uNcFile = NetcdfFile.open(uFilePath);
NetcdfFile vNcFile = NetcdfFile.open(vFilePath);
Double uValue = getNcValueByIndex(uNcFile, variables.get("windU"), gridIndex[0], gridIndex[1]);
Double vValue = getNcValueByIndex(vNcFile, variables.get("windV"), gridIndex[0], gridIndex[1]);
windSpeed = Math.sqrt(uValue * uValue + vValue * vValue);
}
// 添加格式化数据
addFormattedData(currentTime, timeList, temperatureList, pressureList,
humidityList, windSpeedList, tValue, pValue, hValue, windSpeed);
}catch (Exception e) {
e.printStackTrace();
throw new JeecgBootException("处理气象数据失败!");
}
try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
Double tValue = getNcValueByIndex(ncFile, variables.get("temperature"), gridIndex[0], gridIndex[1]) - 273.15;
Double pValue = getNcValueByIndex(ncFile, variables.get("pressure"), gridIndex[0], gridIndex[1]) / 1000;
Double hValue = getNcValueByIndex(ncFile, variables.get("humidity"), gridIndex[0], gridIndex[1]);
Double uValue = getNcValueByIndex(ncFile, variables.get("windU"), gridIndex[0], gridIndex[1]);
Double vValue = getNcValueByIndex(ncFile, variables.get("windV"), gridIndex[0], gridIndex[1]);
Double windSpeed = Math.sqrt(uValue * uValue + vValue * vValue);
// 添加格式化数据
addFormattedData(currentTime, timeList, temperatureList, pressureList,
humidityList, windSpeedList, tValue, pValue, hValue, windSpeed);
}
}
@ -781,7 +722,7 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
List<WeatherData> weatherDataList = weatherDataMapper.selectList(new LambdaQueryWrapper<WeatherData>().
eq(WeatherData::getDataStartTime, targetTime).eq(WeatherData::getDataSource,dataTypeEnum.getKey()));
WeatherResultVO weatherResultVO = new WeatherResultVO();
String filePath = getWeatherFilePath(weatherDataList, targetTime, weatherType, dataTypeEnum);
String filePath = getWeatherFilePath(weatherDataList, targetTime);
validateFile(filePath);
try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
@ -792,7 +733,7 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
ValueConverter converter = null;
if (WeatherTypeEnum.WIND.getKey().equals(weatherType)) {
converter = value -> value;
List<List<List<Double>>> windDataList = processWindData(weatherDataList, weatherType, targetTime, dataTypeEnum);
List<List<List<Double>>> windDataList = processWindData(weatherDataList, targetTime, dataTypeEnum);
processResultDataInternal(weatherResultVO, null, windDataList.get(0), windDataList.get(1), lonData, latData, converter);
}else{
List<List<Double>> dataList;
@ -821,44 +762,22 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
/**
* 处理风场数据
*/
private List<List<List<Double>>> processWindData(List<WeatherData> weatherDataList, Integer weatherType, LocalDateTime targetTime,
private List<List<List<Double>>> processWindData(List<WeatherData> weatherDataList, LocalDateTime targetTime,
WeatherDataSourceEnum dataTypeEnum) {
List<List<List<Double>>> windDataList = new ArrayList<>();
if (!WeatherDataSourceEnum.CRA40.equals(dataTypeEnum)) {
String filePath = getWeatherFilePath(weatherDataList, targetTime, weatherType, dataTypeEnum);
validateFile(filePath);
String filePath = getWeatherFilePath(weatherDataList, targetTime);
validateFile(filePath);
try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
List<List<Double>> u = NcUtil.get2DNCByName(ncFile,
WeatherVariableNameEnum.getValueByTypeAndKey(dataTypeEnum.getKey(), WeatherTypeEnum.WIND.getKey()), 0, 0);
List<List<Double>> v = NcUtil.get2DNCByName(ncFile,
WeatherVariableNameEnum.getValueByTypeAndKey(dataTypeEnum.getKey(), WeatherTypeEnum.WIND.getKey() + 1), 0, 0);
windDataList.add(u);
windDataList.add(v);
} catch (IOException e) {
log.error("NetCDF文件处理失败", e);
throw new JeecgBootException("文件读取失败", e);
}
} else {
String uFilePath = getWeatherFilePath(weatherDataList, targetTime, weatherType, dataTypeEnum);
String vFilePath = getWeatherFilePath(weatherDataList, targetTime,weatherType + 1, dataTypeEnum);
validateFile(uFilePath);
validateFile(vFilePath);
try (NetcdfFile uNcFile = NetcdfFile.open(uFilePath);
NetcdfFile vNcFile = NetcdfFile.open(vFilePath)) {
List<List<Double>> u = NcUtil.get2DNCByName(uNcFile,
WeatherVariableNameEnum.getValueByTypeAndKey(dataTypeEnum.getKey(), WeatherTypeEnum.WIND.getKey()), 0, 0);
List<List<Double>> v = NcUtil.get2DNCByName(vNcFile,
WeatherVariableNameEnum.getValueByTypeAndKey(dataTypeEnum.getKey(), WeatherTypeEnum.WIND.getKey() + 1), 0, 0);
windDataList.add(u);
windDataList.add(v);
} catch (IOException e) {
log.error("NetCDF文件处理失败", e);
throw new JeecgBootException("文件读取失败", e);
}
try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
List<List<Double>> u = NcUtil.get2DNCByName(ncFile,
WeatherVariableNameEnum.getValueByTypeAndKey(dataTypeEnum.getKey(), WeatherTypeEnum.WIND.getKey()), 0, 0);
List<List<Double>> v = NcUtil.get2DNCByName(ncFile,
WeatherVariableNameEnum.getValueByTypeAndKey(dataTypeEnum.getKey(), WeatherTypeEnum.WIND.getKey() + 1), 0, 0);
windDataList.add(u);
windDataList.add(v);
} catch (IOException e) {
log.error("NetCDF文件处理失败", e);
throw new JeecgBootException("文件读取失败", e);
}
return windDataList;
}
@ -880,89 +799,17 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
* 查询文件目录
* @param weatherDataList
* @param currentTime
* @param weatherType
* @param dataTypeEnum
* @return
*/
public String getWeatherFilePath(List<WeatherData> weatherDataList, LocalDateTime currentTime, Integer weatherType, WeatherDataSourceEnum dataTypeEnum){
if (WeatherDataSourceEnum.CRA40.equals(dataTypeEnum)) {
for (WeatherData weatherData : weatherDataList) {
if(weatherData.getFileName().contains(Cra40FilePrefixEnum.getValueByKey(weatherType)) && weatherData.getDataStartTime().equals(currentTime)){
return weatherData.getFilePath();
}
}
} else {
for (WeatherData weatherData : weatherDataList) {
if(weatherData.getDataStartTime().equals(currentTime)){
return weatherData.getFilePath();
}
public String getWeatherFilePath(List<WeatherData> weatherDataList, LocalDateTime currentTime){
for (WeatherData weatherData : weatherDataList) {
if(weatherData.getDataStartTime().equals(currentTime)){
return weatherData.getFilePath();
}
}
throw new RuntimeException("未找到气象数据:" + currentTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
/**
* 构建文件路径(废案)
*/
private String buildFilePath(LocalDateTime targetTime, Integer weatherType, WeatherDataSourceEnum dataTypeEnum) {
StringBuilder storagePath = new StringBuilder()
.append(this.systemStorageProperties.getRootPath())
.append(File.separator);
if (WeatherDataSourceEnum.PANGU.equals(dataTypeEnum)) {
storagePath.append(systemStorageProperties.getPangu())
.append(File.separator)
.append(targetTime.getYear())
.append(File.separator)
.append(WeatherPrefixConstants.PANGU_PREFIX)
.append(targetTime.format(DateTimeFormatter.ofPattern("yyyyMMddHH")))
.append(".")
.append(WeatherFileSuffixEnum.GRIB.getValue());
} else if (WeatherDataSourceEnum.CRA40.equals(dataTypeEnum)) {
storagePath.append(systemStorageProperties.getCra40())
.append(File.separator)
.append(targetTime.getYear())
.append(File.separator)
.append(WeatherPrefixConstants.CRA40_PREFIX)
.append(Cra40FilePrefixEnum.getValueByKey(weatherType))
.append("_")
.append(targetTime.format(DateTimeFormatter.ofPattern("yyyyMMddHH")))
.append(WeatherSuffixConstants.CRA40_SUFFIX)
.append(".")
.append(WeatherFileSuffixEnum.GRIB2.getValue());
} else if (WeatherDataSourceEnum.NCEP.equals(dataTypeEnum)) {
storagePath.append(systemStorageProperties.getNcep())
.append(File.separator)
.append(targetTime.getYear())
.append(File.separator)
.append(targetTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm")))
.append(".")
.append(WeatherPrefixConstants.NCEP_PREFIX)
.append(".")
.append(minus6HoursAndFormat(targetTime))
.append(".")
.append(WeatherSuffixConstants.NCEP_SUFFIX)
.append(".")
.append(WeatherFileSuffixEnum.GRB2.getValue());
} else if (WeatherDataSourceEnum.FNL.equals(dataTypeEnum)) {
storagePath.append(systemStorageProperties.getFnl())
.append(File.separator)
.append(WeatherPrefixConstants.FNL_PREFIX)
.append(targetTime.format(DateTimeFormatter.ofPattern("yyyyMMdd_HH_mm")))
.append(".")
.append(WeatherFileSuffixEnum.GRIB2.getValue());
} else if (WeatherDataSourceEnum.T1H.equals(dataTypeEnum)) {
storagePath.append(systemStorageProperties.getT1h())
.append(File.separator)
.append(WeatherPrefixConstants.T1H_PREFIX)
.append(targetTime.format(DateTimeFormatter.ofPattern("yyyyMMdd_HH")))
.append(".")
.append(WeatherFileSuffixEnum.NC.getValue());
}
return storagePath.toString();
}
/**
* 减六小时取yyyyMMddHH
* @param targetTime