优化洪水预报接口

master
chenxiwang 2024-08-09 09:34:23 +08:00
parent 57190aa39b
commit 26ad44d4a0
4 changed files with 188 additions and 94 deletions

View File

@ -125,8 +125,8 @@ public class ForecastProjectController {
if (Objects.isNull(forecastProject)) {
throw new IllegalArgumentException("当前数据不存在");
}
List<ForecastResults> resultList = forecastResultsService.list(new QueryWrapper<ForecastResults>().eq("project_id", projectId));
if(CollectionUtils.isNotEmpty(resultList)) {
List<ForecastResults> resultList = forecastResultsService.list(new QueryWrapper<ForecastResults>().eq("project_id", projectId).orderBy(true, true, "tm"));
if (CollectionUtils.isNotEmpty(resultList)) {
forecastProject.setVoList(JSON.parseArray(JSON.toJSONString(resultList), ForecastResultVo.class));
forecastResultsService.handleVoList(forecastProject);
}

View File

@ -36,6 +36,7 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@ -55,6 +56,8 @@ public class ForecastResultsService extends ServiceImpl<ForecastResultsMapper, F
private static SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");
private static SimpleDateFormat sdfMinute = new SimpleDateFormat("yyyy-MM-dd HH:mm");
private static SimpleDateFormat eightSdf = new SimpleDateFormat("yyyy-MM-dd 08");
private static SimpleDateFormat sixteenSdf = new SimpleDateFormat("yyyy-MM-dd 16");
@ -116,6 +119,7 @@ public class ForecastResultsService extends ServiceImpl<ForecastResultsMapper, F
Date nowHourTime = calendar.getTime();
forecastTask.setNowTime(nowHourTime);
List<ForecastResultVo> voList = excuteForecast(forecastTask);
voList.sort(Comparator.comparing(ForecastResultVo::getTm));
return voList;
}
@ -127,6 +131,8 @@ public class ForecastResultsService extends ServiceImpl<ForecastResultsMapper, F
* @date: 2024-08-05, , 17:14:52
*/
private List<ForecastResultVo> excuteForecast(ForecastTask forecastTask) throws Exception {
// 获取系统当前的水库站编码、汛限水位
AttResBase attResBase = attResBaseService.getOne(new QueryWrapper<>());
List<ForecastResultVo> voList = new ArrayList<>();
Date nowHourTime = forecastTask.getNowTime();
Date startTime = forecastTask.getStartTime();
@ -137,53 +143,60 @@ public class ForecastResultsService extends ServiceImpl<ForecastResultsMapper, F
QueryWrapper<StPptnR> qwExisted = new QueryWrapper<>();
// 如果结束时间在当前时间之前,降雨序列从历史降雨表获取
if (endTime.compareTo(nowHourTime) <= 0) {
qwExisted = new QueryWrapper<StPptnR>().eq("stcd", "716153201").ge("tm", startTime).le("tm", endTime).orderBy(true, true, "tm");
qwExisted = new QueryWrapper<StPptnR>().eq("stcd", attResBase.getStcd()).ge("tm", startTime).le("tm", endTime).orderBy(true, true, "tm");
} else {
qwExisted = new QueryWrapper<StPptnR>().eq("stcd", "716153201").ge("tm", startTime).le("tm", nowHourTime).orderBy(true, true, "tm");
pptnRFutureList = getForecastDrpData(nowHourTime, "716153201");
qwExisted = new QueryWrapper<StPptnR>().eq("stcd", attResBase.getStcd()).ge("tm", startTime).le("tm", nowHourTime).orderBy(true, true, "tm");
pptnRFutureList = getForecastDrpData(nowHourTime, attResBase.getStcd());
}
List<StPptnR> pptnRExistedList = stPptnRService.list(qwExisted);
pptnRAllList.addAll(pptnRExistedList);
pptnRAllList.addAll(pptnRFutureList);
if (CollectionUtils.isEmpty(pptnRAllList)) {
return voList;
}
// 获取配置参数
List<ForecastUseparam> paramList = forecastUseparamService.list(new QueryWrapper<ForecastUseparam>().isNotNull("param_code").isNotNull("param_value"));
List<ForecastU> uList = forecastUService.list();
if (CollectionUtils.isEmpty(paramList) || CollectionUtils.isEmpty(uList) || CollectionUtils.isEmpty(pptnRAllList)) {
return voList;
if (CollectionUtils.isEmpty(paramList)) {
throw new IllegalArgumentException("温馨提示:当前洪水预报所依赖的数据尚不完整,请检查入参是否缺失。");
}
double dt = 0.0;
double Wm = 0.0;
// 每小时的单位径流量单位m³/s
double[] u = uList.stream().mapToDouble(forecastU -> forecastU.getUValue().doubleValue()).toArray();
Map<String, String> paramMap = paramList.stream().collect(Collectors.toMap(ForecastUseparam::getParamCode, ForecastUseparam::getParamValue));
if (paramMap.get("dt").isEmpty() || paramMap.get("Im").isEmpty()) {
return voList;
if (paramMap.get("dt").isEmpty()) {
throw new IllegalArgumentException("温馨提示当前洪水预报所依赖的数据尚不完整请检查时间单元△T是否缺失。");
}
if (paramMap.get("Im").isEmpty()) {
throw new IllegalArgumentException("温馨提示当前洪水预报所依赖的数据尚不完整请检查最大初损值Im是否缺失。");
}
dt = Double.parseDouble(paramMap.get("dt"));
Wm = Double.parseDouble(paramMap.get("Im"));
List<ForecastU> uList = forecastUService.list();
if (CollectionUtils.isEmpty(uList)) {
throw new IllegalArgumentException("温馨提示当前洪水预报所依赖的数据尚不完整请检查U(I)单位线是否缺失。");
}
// 每小时的单位径流量单位m³/s
double[] u = uList.stream().mapToDouble(forecastU -> forecastU.getUValue().doubleValue()).toArray();
// 根据开始结束时间查询pa
Calendar cal = Calendar.getInstance();
cal.setTime(startTime);
// 将日期往前推一天
cal.add(Calendar.DATE, -1);
List<ForecastPa> paList = forecastPaService.list(new QueryWrapper<ForecastPa>().eq("stcd", "716153201").ge("tm", sdfDay.format(cal.getTime())).le("tm", sdfDay.format(endTime)));
List<ForecastPa> paList = forecastPaService.list(new QueryWrapper<ForecastPa>().eq("stcd", attResBase.getStcd()).ge("tm", sdfDay.format(cal.getTime())).le("tm", sdfDay.format(endTime)));
if (CollectionUtils.isEmpty(paList)) {
return voList;
throw new IllegalArgumentException("温馨提示当前洪水预报所依赖的数据尚不完整请检查每日土壤含水量Pa是否缺失。");
}
Map<String, ForecastPa> paMap = paList.stream().collect(Collectors.toMap(ForecastPa::getTm, entity -> entity));
// 获取预测开始时间前的最后水库水位
double H1 = 0.0;// 初始水库水位可以根据H1->V1,H1->q1得到初始的水库库容和下泄流量
StRsvrR rsvrR = stRsvrRService.getOne(new QueryWrapper<StRsvrR>().eq("stcd", "716153201").le("tm", startTime).orderBy(true, false, "tm").last("limit 1"));
StRsvrR rsvrR = stRsvrRService.getOne(new QueryWrapper<StRsvrR>().eq("stcd", attResBase.getStcd()).le("tm", startTime).orderBy(true, false, "tm").last("limit 1"));
if (ObjectUtils.isEmpty(rsvrR)) {
return voList;
}
H1 = Double.parseDouble(rsvrR.getRz());
// 获取汛限水位
AttResBase attResBase = attResBaseService.getOne(new QueryWrapper<>());
// 泄流量
List<StZqrlB> stZqrlBList = stZqrlBService.list(new QueryWrapper<StZqrlB>().eq("stcd", "716153201"));
List<StZqrlB> stZqrlBList = stZqrlBService.list(new QueryWrapper<StZqrlB>().eq("stcd", attResBase.getStcd()));
// 水位历史数据
List<StRsvrR> rsvrRRealList = stRsvrRService.list(new QueryWrapper<StRsvrR>().eq("stcd", "716153201").ge("tm", startTime).le("tm", endTime));
List<StRsvrR> rsvrRRealList = stRsvrRService.list(new QueryWrapper<StRsvrR>().eq("stcd", attResBase.getStcd()).ge("tm", startTime).le("tm", endTime));
List<StRsvrR> resultList = reorganizeRsvrRData(rsvrRRealList, dt);
List<Date[]> periods = splitByDay8To8(startTime, endTime);
for (Date[] period : periods) {
@ -194,43 +207,40 @@ public class ForecastResultsService extends ServiceImpl<ForecastResultsMapper, F
cal.add(Calendar.DATE, -1);
}
ForecastPa forecastPa = paMap.get(sdfDay.format(cal.getTime()));
// 根据降雨数据按照△t的颗粒度均分
List<String> pResultList = new ArrayList<>();
// 筛选时间段内的降雨数据。第一个条件时间大于等开始时间第二个条件时间小于等于结束时间不包前但包后比如从8点开始就要拆下一个时间9点的数据
List<StPptnR> filterList = pptnRAllList.stream().filter(e -> e.getTm().compareTo(period[0]) >= 0).filter(e -> e.getTm().compareTo(period[1]) <= 0).collect(Collectors.toList());
// 从第二条数据开始
for (int i = 1; i < filterList.size(); i++) {
StPptnR stPptnRLast = filterList.get(i - 1);
StPptnR stPptnR = filterList.get(i);
String drp = stPptnR.getDrp();
// 两条数据的小时差
double diffHours = dateHourDifference(stPptnRLast.getTm(), stPptnR.getTm());
// 两条数据间需要增补几条
int floorNum = (int) Math.floor(diffHours / dt);
for (int j = 0; j < floorNum; j++) {
BigDecimal add = new BigDecimal(drp).divide(BigDecimal.valueOf(floorNum), 2, BigDecimal.ROUND_HALF_UP);
pResultList.add(add.toString());
}
if (ObjectUtils.isEmpty(forecastPa)) {
throw new IllegalArgumentException("温馨提示当前洪水预报所依赖的数据尚不完整请检查每日土壤含水量Pa、K值是否缺失。");
}
double[] PList = pResultList.stream().mapToDouble(Double::parseDouble).toArray();
// 根据降雨数据按照△t的颗粒度均分
// 筛选时间段内的降雨数据。不包前但包后
List<StPptnR> filterList = pptnRAllList.stream().filter(e -> e.getTm().compareTo(period[0]) >= 0).filter(e -> e.getTm().compareTo(period[1]) <= 0).collect(Collectors.toList());
Map<String, List<StPptnR>> retMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(filterList)) {
retMap = reorganizePptnRData(filterList, dt, period[0], period[1]);
}
List<String> pForecastList = retMap.get("listForForecast").stream().map(s -> s.getDrp()).collect(Collectors.toList());
Map<String, String> pRealMap = retMap.get("listForReal").stream().collect(Collectors.toMap(pptnR -> sdfMinute.format(pptnR.getTm()), StPptnR::getDrp));
double[] PList = pForecastList.stream().mapToDouble(Double::parseDouble).toArray();
// 预测执行
List<FloodAlgorithemVo> forecastVoList = RrainfallForecast.getData(sdf.format(period[0]), forecastPa.getK().doubleValue(), forecastPa.getPa0().doubleValue(), Wm, forecastPa.getPt0().doubleValue(), H1, dt,
forecastPa.getPa().doubleValue(), PList, u, "716153201");
forecastPa.getPa().doubleValue(), PList, u, attResBase.getStcd());
if (CollectionUtils.isNotEmpty(forecastVoList)) {
// 筛选同时段的真实水位数据
List<StRsvrR> realRsvrList = resultList.stream().filter(item -> item.getTm().compareTo(period[0]) >=0 && item.getTm().compareTo(period[1]) <=0).collect(Collectors.toList());
List<StRsvrR> realRsvrList = resultList.stream().filter(item -> item.getTm().compareTo(period[0]) >= 0 && item.getTm().compareTo(period[1]) <= 0).collect(Collectors.toList());
Map<String, String> realRsvrMap = realRsvrList.stream().collect(Collectors.toMap(rsvr -> sdfMinute.format(rsvr.getTm()), StRsvrR::getRz));
forecastVoList = forecastVoList.subList(0, PList.length);
for (int j = 0; j < forecastVoList.size(); j++) {
FloodAlgorithemVo floodAlgorithemVo = forecastVoList.get(j);
String dateStr = floodAlgorithemVo.getDateStr();
ForecastResultVo resultVo = new ForecastResultVo();
resultVo.setTm(floodAlgorithemVo.getDateStr());
resultVo.setTm(dateStr);
resultVo.setYcRkQValue(floodAlgorithemVo.getRq());// 预测入库流量
// resultVo.setRealRkQValue();// 暂无真实入库流量
resultVo.setYcCkQValue(floodAlgorithemVo.getCq());// 预测出库流量
resultVo.setYcSwHValue(floodAlgorithemVo.getKh());// 预测水库水位
H1 = resultVo.getYcSwHValue().doubleValue();// 先以预测水位作为下一次预测段起始值
if (j < realRsvrList.size()) {
BigDecimal realSwHValue = new BigDecimal(realRsvrList.get(j).getRz());
String dateMinuteStr = dateStr.substring(0, dateStr.length() - 3);// 年月日 时分
if (realRsvrMap.containsKey(dateMinuteStr)) {
BigDecimal realSwHValue = new BigDecimal(realRsvrMap.get(dateMinuteStr));// 根据时间取更准确
resultVo.setRealSwHValue(realSwHValue);// 真实水库水位
H1 = realSwHValue.doubleValue();// 如果有真实水位,将最后一条的真实水位作为下一次预测段的初始水位
// 真实出库流量=真实水库水位与泄流量曲线差值法
@ -246,7 +256,12 @@ public class ForecastResultsService extends ServiceImpl<ForecastResultsMapper, F
}
}
}
resultVo.setDrp(floodAlgorithemVo.getDrp());
BigDecimal drp = new BigDecimal(pRealMap.get(dateMinuteStr));// 根据时间取更准确
if (drp.compareTo(BigDecimal.ZERO) < 0) {
resultVo.setDrp(null);
} else {
resultVo.setDrp(drp);
}
Date dateTm = sdf.parse(floodAlgorithemVo.getDateStr());
resultVo.setIspreDrp(dateTm.compareTo(nowHourTime) <= 0 ? "0" : "1");// 0真实 1预测
resultVo.setR(floodAlgorithemVo.getR());
@ -357,6 +372,76 @@ public class ForecastResultsService extends ServiceImpl<ForecastResultsMapper, F
return resultList;
}
/**
* @description: T
* @param filterList
* @param dt
* @return: java.util.List<com.gunshi.project.xyt.model.StPptnR>
* @auther: cxw
*/
private Map<String, List<StPptnR>> reorganizePptnRData(List<StPptnR> filterList, double dt, Date startTm, Date endTm) {
Map<String, List<StPptnR>> retMap = new HashMap<>();
Map<String, String> tmDrpMap = filterList.stream().collect(Collectors.toMap(pptnR -> sdfMinute.format(pptnR.getTm()), StPptnR::getDrp));
List<StPptnR> listForForecast = new ArrayList<>();// 传给预测程序使用缺失的数据为0
List<StPptnR> listForReal = new ArrayList<>();// 返回给前端数据使用缺失的数据为null
Calendar calendar = Calendar.getInstance();
calendar.setTime(startTm);
Date dataTm = calendar.getTime();
// 使用时间一直往后加时间
while (dataTm.compareTo(endTm) < 0) {
// 时间加1小时得到应该拆数据的时间后面往前推
calendar.add(Calendar.HOUR_OF_DAY, 1);
String shareDrp = "";// 应该分的drp
// 如果下一小时不为空
if (tmDrpMap.containsKey(sdfMinute.format(calendar.getTime()))) {
StPptnR stPptnRHalf = new StPptnR();
StPptnR stPptnRHour = new StPptnR();
stPptnRHour.setTm(calendar.getTime());// 整点时间
String dataTmDrpHalf = tmDrpMap.get(sdfMinute.format(calendar.getTime()));
BigDecimal drp = new BigDecimal(dataTmDrpHalf).divide(new BigDecimal(2), 2, BigDecimal.ROUND_HALF_UP);
shareDrp = String.valueOf(drp);
stPptnRHalf.setDrp(shareDrp);
stPptnRHour.setDrp(shareDrp);
// 往前推半小时
calendar.add(Calendar.MINUTE, -(int) (dt * 60));
stPptnRHalf.setTm(calendar.getTime());
// 先存半小时数据
listForForecast.add(stPptnRHalf);
listForReal.add(stPptnRHalf);
// 再存整小时数据
listForForecast.add(stPptnRHour);
listForReal.add(stPptnRHour);
} else {
StPptnR stPptnRHalfForecast = new StPptnR();
StPptnR stPptnRHourForecast = new StPptnR();
StPptnR stPptnRHalfReal = new StPptnR();
StPptnR stPptnRHourReal = new StPptnR();
stPptnRHourForecast.setTm(calendar.getTime());// 整点时间
stPptnRHourReal.setTm(calendar.getTime());// 整点时间
// 往前推半小时
calendar.add(Calendar.MINUTE, -(int) (dt * 60));
stPptnRHalfForecast.setTm(calendar.getTime());
stPptnRHalfReal.setTm(calendar.getTime());
// 先存半小时数据
stPptnRHalfForecast.setDrp("0.00");
listForForecast.add(stPptnRHalfForecast);
stPptnRHalfReal.setDrp("-1");
listForReal.add(stPptnRHalfReal);
// 再存整小时数据
stPptnRHourForecast.setDrp("0.00");
listForForecast.add(stPptnRHourForecast);
stPptnRHourReal.setDrp("-1");
listForReal.add(stPptnRHourReal);
}
// 往后推半小时复位
calendar.add(Calendar.MINUTE, (int) (dt * 60));
dataTm = calendar.getTime();
}
retMap.put("listForForecast", listForForecast);
retMap.put("listForReal", listForReal);
return retMap;
}
/**
* @description:
* @param startDate

View File

@ -190,7 +190,7 @@ public class DataTask {
calendar.add(Calendar.DATE, -40);
} else {
calendar.setTime(stm);
calendar.add(Calendar.HOUR, 1);
calendar.add(Calendar.HOUR_OF_DAY, 1);
}
stm = calendar.getTime();
Response resp = client.newCall(new Request.Builder().url(owrsvrPath + hbskpphisRoute)
@ -227,7 +227,7 @@ public class DataTask {
* @date: 2024-07-11, , 14:21:35
*/
@Async
@Scheduled(fixedRate = 5, timeUnit = TimeUnit.MINUTES)
@Scheduled(cron = "0 30 8 * * ?")
public void getSkYqDayData() {
Date now = new Date();
System.out.println("雨情按天定时任务,执行时间:" + sdf.format(now));
@ -352,7 +352,7 @@ public class DataTask {
calendar.add(Calendar.DATE, -40);
} else {
calendar.setTime(stm);
calendar.add(Calendar.HOUR, 1);
calendar.add(Calendar.HOUR_OF_DAY, 1);
}
stm = calendar.getTime();
Response resp = client.newCall(new Request.Builder().url(owrsvrPath + hbskzzhisRoute)
@ -453,7 +453,7 @@ public class DataTask {
calendar.add(Calendar.DATE, -40);
} else {
calendar.setTime(stm);
calendar.add(Calendar.HOUR, 1);
calendar.add(Calendar.HOUR_OF_DAY, 1);
}
stm = calendar.getTime();
Response resp = client.newCall(new Request.Builder().url(owrsvrPath + hbskpichisRoute)

View File

@ -7,10 +7,12 @@ import com.gunshi.algorithm.RunoffService;
import com.gunshi.project.xyt.model.ForecastK;
import com.gunshi.project.xyt.model.ForecastPa;
import com.gunshi.project.xyt.model.ForecastUseparam;
import com.gunshi.project.xyt.model.StStbprpB;
import com.gunshi.project.xyt.service.ForecastKService;
import com.gunshi.project.xyt.service.ForecastPaService;
import com.gunshi.project.xyt.service.ForecastUseparamService;
import com.gunshi.project.xyt.service.StPptnRService;
import com.gunshi.project.xyt.service.StStbprpBService;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -56,6 +58,9 @@ public class PaDataTask {
@Autowired
private StPptnRService stPptnRService;
@Autowired
private StStbprpBService stStbprpBService;
/**
* @description: 830Pa
* @param
@ -73,54 +78,58 @@ public class PaDataTask {
// 获取配置参数
List<ForecastUseparam> paramList = forecastUseparamService.list(new QueryWrapper<ForecastUseparam>().isNotNull("param_code").isNotNull("param_value"));
List<ForecastK> kList = forecastKService.list();
// 获取最新pa
ForecastPa forecastPaLast = forecastPaService.getOne(new QueryWrapper<ForecastPa>().orderBy(true, false, "tm").last("limit 1"));
if (CollectionUtils.isNotEmpty(paramList) && CollectionUtils.isNotEmpty(kList) && ObjectUtils.isNotEmpty(forecastPaLast) && !forecastPaLast.getTm().equals(sdfDay.format(nowTime))) {
String lastTm = forecastPaLast.getTm();
// 获取空缺时间的所有降雨当天8点到第二天8点间的drp和
List<Map<String, Object>> mapList = stPptnRService.getPptnRDataList("716153201", lastTm);
Map<String, Object> pptnrMap;
if (CollectionUtils.isNotEmpty(mapList)) {
pptnrMap = mapList.stream().collect(Collectors.toMap(map -> (String) map.get("tm"), map -> map.get("drp")));
} else {
return;
}
Map<Integer, BigDecimal> kMap = kList.stream().collect(Collectors.toMap(ForecastK::getMonth, ForecastK::getKValue));
Map<String, String> paramMap = paramList.stream().collect(Collectors.toMap(ForecastUseparam::getParamCode, ForecastUseparam::getParamValue));
double Im = Double.parseDouble(paramMap.get("Im"));// 土壤含水量最大值(最大初损值)Im
// 第一次的pa0是最新一条的pa
List<ForecastPa> list = new ArrayList<>();
ForecastPa forecastPa = null;
int i = 0;
while (!lastTm.equals(sdfDay.format(nowTime))){
double lastPa0 = forecastPaLast.getPa().doubleValue();
double lastPt0;
// 第一次使用最新一条的降雨
if(i == 0){
lastPt0 = forecastPaLast.getPt0().doubleValue();
i ++;
} else {
lastPt0 = Double.valueOf(ObjectUtils.isEmpty(pptnrMap.get(lastTm)) ? "0.0" : pptnrMap.get(lastTm).toString());
// 查询所有需要统计pa值的站点
List<StStbprpB> stStbprpBList = stStbprpBService.list(new QueryWrapper<StStbprpB>().eq("source", "SK"));
if (CollectionUtils.isNotEmpty(stStbprpBList)) {
for (StStbprpB stb : stStbprpBList) {
String stcd = stb.getStcd();
// 获取最新pa
ForecastPa forecastPaLast = forecastPaService.getOne(new QueryWrapper<ForecastPa>().eq("stcd", stcd).orderBy(true, false, "tm").last("limit 1"));
if (CollectionUtils.isNotEmpty(paramList) && CollectionUtils.isNotEmpty(kList) && ObjectUtils.isNotEmpty(forecastPaLast) && !forecastPaLast.getTm().equals(sdfDay.format(nowTime))) {
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(sdfDay.parse(forecastPaLast.getTm()));
calendar2.add(Calendar.DAY_OF_MONTH, -3);
String searchTm = sdfDay.format(calendar2.getTime());
String lastTm = forecastPaLast.getTm();
// 获取空缺时间的所有降雨当天8点到第二天8点间的drp和
List<Map<String, Object>> mapList = stPptnRService.getPptnRDataList(stcd, searchTm);
Map<String, Object> pptnrMap;
if (CollectionUtils.isNotEmpty(mapList)) {
pptnrMap = mapList.stream().collect(Collectors.toMap(map -> (String) map.get("tm"), map -> map.get("drp")));
} else {
return;
}
Map<Integer, BigDecimal> kMap = kList.stream().collect(Collectors.toMap(ForecastK::getMonth, ForecastK::getKValue));
Map<String, String> paramMap = paramList.stream().collect(Collectors.toMap(ForecastUseparam::getParamCode, ForecastUseparam::getParamValue));
double Im = Double.parseDouble(paramMap.get("Im"));// 土壤含水量最大值(最大初损值)Im
// 第一次的pa0是最新一条的pa
List<ForecastPa> list = new ArrayList<>();
ForecastPa forecastPa = null;
int i = 0;
while (!lastTm.equals(sdfDay.format(nowTime))) {
double lastPa0 = forecastPaLast.getPa().doubleValue();
double lastPt0 = Double.valueOf(ObjectUtils.isEmpty(pptnrMap.get(lastTm)) ? "0.0" : pptnrMap.get(lastTm).toString());
forecastPa = new ForecastPa();
// 最新加1天
calendar.setTime(sdfDay.parse(lastTm));
calendar.add(Calendar.DAY_OF_MONTH, 1);
lastTm = sdfDay.format(calendar.getTime());
double k = kMap.get(Integer.valueOf(lastTm.substring(5, 7))).doubleValue();
double pa = RunoffService.PaCaculate(k, lastPa0, lastPt0, Im);
forecastPa.setStcd(stcd);
forecastPa.setTm(lastTm);
forecastPa.setK(new BigDecimal(k).setScale(2, BigDecimal.ROUND_HALF_UP));
forecastPa.setPa0(new BigDecimal(lastPa0));
forecastPa.setIm(new BigDecimal(Im));
forecastPa.setPt0(new BigDecimal(lastPt0).setScale(2, BigDecimal.ROUND_HALF_UP));
forecastPa.setPa(new BigDecimal(pa));
list.add(forecastPa);
forecastPaLast = forecastPa;
}
if (CollectionUtils.isNotEmpty(list)) {
forecastPaService.saveBatch(list);
}
}
forecastPa = new ForecastPa();
// 最新加1天
calendar.setTime(sdfDay.parse(lastTm));
calendar.add(Calendar.DAY_OF_MONTH, 1);
lastTm = sdfDay.format(calendar.getTime());
double k = kMap.get(Integer.valueOf(lastTm.substring(5, 7))).doubleValue();
double pa = RunoffService.PaCaculate(k, lastPa0, lastPt0, Im);
forecastPa.setStcd("716153201");
forecastPa.setTm(lastTm);
forecastPa.setK(new BigDecimal(k).setScale(2, BigDecimal.ROUND_HALF_UP));
forecastPa.setPa0(new BigDecimal(lastPa0));
forecastPa.setIm(new BigDecimal(Im));
forecastPa.setPt0(new BigDecimal(lastPt0).setScale(2, BigDecimal.ROUND_HALF_UP));
forecastPa.setPa(new BigDecimal(pa));
list.add(forecastPa);
forecastPaLast = forecastPa;
}
if(CollectionUtils.isNotEmpty(list)){
forecastPaService.saveBatch(list);
}
}
}