优化人工洪水预报接口;增加人工、自动预报结果保存;增加预报方案结果查看接口
parent
09a84fe1b8
commit
46c146b8bb
|
|
@ -1,14 +1,16 @@
|
||||||
package com.gunshi.project.xyt.controller;
|
package com.gunshi.project.xyt.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.gunshi.core.result.R;
|
import com.gunshi.core.result.R;
|
||||||
|
import com.gunshi.project.xyt.entity.vo.ForecastResultVo;
|
||||||
import com.gunshi.project.xyt.model.ForecastProject;
|
import com.gunshi.project.xyt.model.ForecastProject;
|
||||||
import com.gunshi.project.xyt.model.ForecastResults;
|
import com.gunshi.project.xyt.model.ForecastResults;
|
||||||
import com.gunshi.project.xyt.model.ForecastTask;
|
|
||||||
import com.gunshi.project.xyt.service.ForecastProjectService;
|
import com.gunshi.project.xyt.service.ForecastProjectService;
|
||||||
import com.gunshi.project.xyt.service.ForecastResultsService;
|
import com.gunshi.project.xyt.service.ForecastResultsService;
|
||||||
import com.gunshi.project.xyt.validate.markers.Insert;
|
import com.gunshi.project.xyt.validate.markers.Insert;
|
||||||
|
|
@ -18,10 +20,18 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 描述: 预报_预测方案管理表
|
* 描述: 预报_预测方案管理表
|
||||||
* author: cxw
|
* author: cxw
|
||||||
|
|
@ -89,4 +99,33 @@ public class ForecastProjectController {
|
||||||
return R.ok(service.page(forecastProject.getPageSo().toPage(), wrapper));
|
return R.ok(service.page(forecastProject.getPageSo().toPage(), wrapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Operation(summary = "保存人工交互洪水预报结果")
|
||||||
|
@PostMapping("/saveHumanForecastResults")
|
||||||
|
public R<ForecastProject> saveHumanForecastResults(@RequestBody @Validated ForecastProject forecastProject) {
|
||||||
|
if (CollectionUtils.isEmpty(forecastProject.getVoList())) {
|
||||||
|
throw new IllegalArgumentException("数据格式不正确");
|
||||||
|
}
|
||||||
|
forecastProject.setId(IdWorker.getId());
|
||||||
|
boolean result = service.save(forecastProject);
|
||||||
|
if (result) {
|
||||||
|
service.saveForecastResults(forecastProject);
|
||||||
|
}
|
||||||
|
return R.ok(result ? forecastProject : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Operation(summary = "根据方案id查看方案洪水预报结果")
|
||||||
|
@PostMapping("/getForecastProjectResults")
|
||||||
|
public R<ForecastProject> getForecastProjectResults(@Schema(name = "projectId", description = "预测方案id") @RequestParam("projectId") String projectId) {
|
||||||
|
ForecastProject forecastProject = service.getById(projectId);
|
||||||
|
if (Objects.isNull(forecastProject)) {
|
||||||
|
throw new IllegalArgumentException("当前数据不存在");
|
||||||
|
}
|
||||||
|
List<ForecastResults> resultList = forecastResultsService.list(new QueryWrapper<ForecastResults>().eq("project_id", projectId));
|
||||||
|
if(CollectionUtils.isNotEmpty(resultList)) {
|
||||||
|
forecastProject.setVoList(JSON.parseArray(JSON.toJSONString(resultList), ForecastResultVo.class));
|
||||||
|
}
|
||||||
|
return R.ok(forecastProject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,11 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.gunshi.algorithm.RrainfallForecast;
|
|
||||||
import com.gunshi.core.result.R;
|
import com.gunshi.core.result.R;
|
||||||
import com.gunshi.model.vo.FloodAlgorithemVo;
|
|
||||||
import com.gunshi.project.xyt.entity.vo.ForecastResultVo;
|
import com.gunshi.project.xyt.entity.vo.ForecastResultVo;
|
||||||
import com.gunshi.project.xyt.model.ForecastTask;
|
import com.gunshi.project.xyt.model.ForecastProject;
|
||||||
import com.gunshi.project.xyt.model.ForecastResults;
|
import com.gunshi.project.xyt.model.ForecastResults;
|
||||||
import com.gunshi.project.xyt.model.ForecastTask;
|
import com.gunshi.project.xyt.model.ForecastTask;
|
||||||
import com.gunshi.project.xyt.service.ForecastTaskService;
|
|
||||||
import com.gunshi.project.xyt.service.ForecastResultsService;
|
import com.gunshi.project.xyt.service.ForecastResultsService;
|
||||||
import com.gunshi.project.xyt.validate.markers.Insert;
|
import com.gunshi.project.xyt.validate.markers.Insert;
|
||||||
import com.gunshi.project.xyt.validate.markers.Update;
|
import com.gunshi.project.xyt.validate.markers.Update;
|
||||||
|
|
@ -25,12 +22,9 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
/**
|
/**
|
||||||
* 描述: 预报_预测结果表
|
* 描述: 预报_预测结果表
|
||||||
|
|
@ -42,14 +36,9 @@ import java.util.List;
|
||||||
@RequestMapping(value="/forecastResults")
|
@RequestMapping(value="/forecastResults")
|
||||||
public class ForecastResultsController {
|
public class ForecastResultsController {
|
||||||
|
|
||||||
private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ForecastResultsService service;
|
private ForecastResultsService service;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ForecastTaskService forecastTaskService;
|
|
||||||
|
|
||||||
|
|
||||||
@Operation(summary = "新增")
|
@Operation(summary = "新增")
|
||||||
@PostMapping("/insert")
|
@PostMapping("/insert")
|
||||||
|
|
@ -84,7 +73,7 @@ public class ForecastResultsController {
|
||||||
@Operation(summary = "分页")
|
@Operation(summary = "分页")
|
||||||
@PostMapping("/page")
|
@PostMapping("/page")
|
||||||
public R<Page<ForecastResults>> page(@RequestBody @Validated ForecastResults forecastResults) {
|
public R<Page<ForecastResults>> page(@RequestBody @Validated ForecastResults forecastResults) {
|
||||||
QueryWrapper<ForecastResults> wrapper = new QueryWrapper<ForecastResults>();
|
QueryWrapper<ForecastResults> wrapper = new QueryWrapper<>();
|
||||||
if(StringUtils.isNotBlank(forecastResults.getSortField())){
|
if(StringUtils.isNotBlank(forecastResults.getSortField())){
|
||||||
wrapper.orderBy(true, ObjectUtils.isEmpty(forecastResults.getIsAsc()) ? false : forecastResults.getIsAsc(), forecastResults.getSortField());
|
wrapper.orderBy(true, ObjectUtils.isEmpty(forecastResults.getIsAsc()) ? false : forecastResults.getIsAsc(), forecastResults.getSortField());
|
||||||
}
|
}
|
||||||
|
|
@ -93,37 +82,17 @@ public class ForecastResultsController {
|
||||||
|
|
||||||
@Operation(summary = "获取人工交互洪水预报结果")
|
@Operation(summary = "获取人工交互洪水预报结果")
|
||||||
@PostMapping("/getHumanForecastResult")
|
@PostMapping("/getHumanForecastResult")
|
||||||
public R<List<ForecastResultVo>> getHumanForecastResult(@RequestBody ForecastTask forecastTask) throws Exception {
|
public R<ForecastProject> getHumanForecastResult(@RequestBody ForecastTask forecastTask) throws Exception {
|
||||||
|
ForecastProject forecastProject = new ForecastProject();
|
||||||
List<ForecastResultVo> voList = service.getHumanForecastResult(forecastTask);
|
List<ForecastResultVo> voList = service.getHumanForecastResult(forecastTask);
|
||||||
return R.ok(voList);
|
forecastProject.setType("2");
|
||||||
|
forecastProject.setForecastTm(forecastTask.getForecastTime());
|
||||||
|
forecastProject.setProjectTm(forecastTask.getNowTime());
|
||||||
|
forecastProject.setStartTm(forecastTask.getStartTime());
|
||||||
|
forecastProject.setEndTm(forecastTask.getEndTime());
|
||||||
|
forecastProject.setForecastPeriod(forecastTask.getForecastPeriod());
|
||||||
|
forecastProject.setForecastWarm(forecastTask.getForecastWarm());
|
||||||
|
forecastProject.setVoList(voList);
|
||||||
|
return R.ok(forecastProject);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Operation(summary = "查看方案洪水预报结果")
|
|
||||||
// @PostMapping("/getForecastTaskResult")
|
|
||||||
// public R<List<ForecastResultVo>> getForecastTaskResult(@Schema(name = "taskId", description = "预测方案id") @RequestParam("taskId") String taskId) throws Exception {
|
|
||||||
// ForecastTask forecastTask = forecastTaskService.getById(taskId);
|
|
||||||
// List<ForecastResultVo> voList = service.getForecastTaskResult(forecastTask);
|
|
||||||
// return R.ok(voList);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// @Operation(summary = "洪水预报测试")
|
|
||||||
// @PostMapping("/forecastTest")
|
|
||||||
// public R<List<FloodAlgorithemVo>> forecastTest() throws Exception {
|
|
||||||
// double[] PList = new double[] {6.5, 6.75, 7, 5.25, 3.5, 4, 4.5, 4, 3.5, 4.25, 5, 4, 3, 3, 3, 2.75, 2.5, 1.25, 0, 0.25, 0.5};
|
|
||||||
// double[] u = new double[]{1.27, 0.75, 0.45, 0.27, 0.16, 0.09, 0.07, 0.03, 0.02, 0.01, 0.01};
|
|
||||||
// return R.ok(RrainfallForecast.getData("2024-06-28 08:00:00", 0.93, 1.0, 120, 0.0, 675.94, 0.5, 100.0, PList, u, "", "716153201"));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Operation(summary = "洪水预报测试2")
|
|
||||||
// @PostMapping("/forecastTest2")
|
|
||||||
// public R<List<ForecastResultVo>> forecastTest2() throws Exception {
|
|
||||||
// DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
// ForecastTask forecastTask = new ForecastTask();
|
|
||||||
// forecastTask.setForecastTm(dateFormat.parse("2024-07-01 22:00:00"));
|
|
||||||
// forecastTask.setStartTime(dateFormat.parse("2024-07-01 16:00:00"));
|
|
||||||
// forecastTask.setEndTime(dateFormat.parse("2024-07-02 03:00:00"));
|
|
||||||
// List<ForecastResultVo> forecastResultVos = service.humanFloodForecast(forecastTask);
|
|
||||||
// return R.ok(forecastResultVos);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*@description 预测结果VO
|
*@description 预测结果VO
|
||||||
|
|
@ -20,7 +21,7 @@ public class ForecastResultVo {
|
||||||
* 时间
|
* 时间
|
||||||
*/
|
*/
|
||||||
@Schema(description="时间")
|
@Schema(description="时间")
|
||||||
private String tm;
|
private Date tm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预测入库流量
|
* 预测入库流量
|
||||||
|
|
@ -64,6 +65,12 @@ public class ForecastResultVo {
|
||||||
@Schema(description="降雨")
|
@Schema(description="降雨")
|
||||||
private BigDecimal drp;
|
private BigDecimal drp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是预测雨量(0:真实 1:预测)
|
||||||
|
*/
|
||||||
|
@Schema(description="是否是预测雨量(0:真实 1:预测)")
|
||||||
|
private String ispreDrp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 径流深
|
* 径流深
|
||||||
*/
|
*/
|
||||||
|
|
@ -75,4 +82,10 @@ public class ForecastResultVo {
|
||||||
*/
|
*/
|
||||||
@Schema(description="主汛期防洪限制水位")
|
@Schema(description="主汛期防洪限制水位")
|
||||||
private BigDecimal flLowLimLev;
|
private BigDecimal flLowLimLev;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 土壤含水量
|
||||||
|
*/
|
||||||
|
@Schema(description="土壤含水量")
|
||||||
|
private BigDecimal pa;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -423,7 +423,7 @@ public class AttResBase implements Serializable {
|
||||||
private String stcd;
|
private String stcd;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否病险 1:病
|
* 是否病险 1:病
|
||||||
*/
|
*/
|
||||||
@TableField(value="is_danger")
|
@TableField(value="is_danger")
|
||||||
@Schema(description="是否病险 1:病 ")
|
@Schema(description="是否病险 1:病 ")
|
||||||
|
|
@ -486,8 +486,15 @@ public class AttResBase implements Serializable {
|
||||||
@Size(max = 255,message = "adcd最大长度要小于 255")
|
@Size(max = 255,message = "adcd最大长度要小于 255")
|
||||||
private String adcd;
|
private String adcd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 堰顶高程,m
|
||||||
|
*/
|
||||||
|
@TableField(value="wcrstel")
|
||||||
|
@Schema(description="堰顶高程,m")
|
||||||
|
private BigDecimal wcrstel;
|
||||||
|
|
||||||
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
@Schema(description = "文件集合")
|
@Schema(description = "文件集合")
|
||||||
private List<FileAssociations> files;
|
private List<FileAssociations> files;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
import com.gunshi.core.dateformat.DateFormatString;
|
import com.gunshi.core.dateformat.DateFormatString;
|
||||||
import com.gunshi.project.xyt.entity.page.GenericPageParams;
|
import com.gunshi.project.xyt.entity.page.GenericPageParams;
|
||||||
|
import com.gunshi.project.xyt.entity.vo.ForecastResultVo;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
@ -17,7 +18,9 @@ import jakarta.validation.constraints.Size;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 描述: 预报_预测方案管理表
|
* 描述: 预报_预测方案管理表
|
||||||
|
|
@ -98,7 +101,7 @@ public class ForecastProject extends GenericPageParams implements Serializable {
|
||||||
*/
|
*/
|
||||||
@TableField(value="user_id")
|
@TableField(value="user_id")
|
||||||
@Schema(description="操作人id")
|
@Schema(description="操作人id")
|
||||||
private Integer userId;
|
private Long userId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预见期(小时)
|
* 预见期(小时)
|
||||||
|
|
@ -131,21 +134,11 @@ public class ForecastProject extends GenericPageParams implements Serializable {
|
||||||
private Date updateTm;
|
private Date updateTm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务状态(0:正常 1:暂停 2:删除)
|
* 任务时间间隔(小时)
|
||||||
*/
|
|
||||||
@TableField(value="status")
|
|
||||||
@Schema(description="任务状态(0:正常 1:暂停 2:删除)")
|
|
||||||
@Size(max = 1,message = "任务状态(0:正常 1:暂停 2:删除)最大长度要小于 1")
|
|
||||||
@NotBlank(message = "任务状态(0:正常 1:暂停 2:删除)不能为空")
|
|
||||||
@NotNull(message = "任务状态(0:正常 1:暂停 2:删除)不能为空")
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务时间间隔(分钟)
|
|
||||||
*/
|
*/
|
||||||
@TableField(value="time_interval")
|
@TableField(value="time_interval")
|
||||||
@Schema(description="任务时间间隔(分钟)")
|
@Schema(description="任务时间间隔(小时)")
|
||||||
private Integer timeInterval;
|
private BigDecimal timeInterval;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自动任务id(type为1时有值)
|
* 自动任务id(type为1时有值)
|
||||||
|
|
@ -154,4 +147,11 @@ public class ForecastProject extends GenericPageParams implements Serializable {
|
||||||
@Schema(description="自动任务id(type为1时有值)")
|
@Schema(description="自动任务id(type为1时有值)")
|
||||||
private Long taskId;
|
private Long taskId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预报结果voList
|
||||||
|
*/
|
||||||
|
@Schema(description = "预报结果voList")
|
||||||
|
@TableField(exist = false)
|
||||||
|
private List<ForecastResultVo> voList;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,13 @@ public class ForecastResults extends GenericPageParams implements Serializable {
|
||||||
@Schema(description="降雨")
|
@Schema(description="降雨")
|
||||||
private BigDecimal drp;
|
private BigDecimal drp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是预测雨量(0:真实 1:预测)
|
||||||
|
*/
|
||||||
|
@TableField(value="ispre_drp")
|
||||||
|
@Schema(description="是否是预测雨量(0:真实 1:预测)")
|
||||||
|
private String ispreDrp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 径流深
|
* 径流深
|
||||||
*/
|
*/
|
||||||
|
|
@ -132,4 +139,11 @@ public class ForecastResults extends GenericPageParams implements Serializable {
|
||||||
@Schema(description="主汛期防洪限制水位")
|
@Schema(description="主汛期防洪限制水位")
|
||||||
private BigDecimal flLowLimLev;
|
private BigDecimal flLowLimLev;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 土壤含水量
|
||||||
|
*/
|
||||||
|
@TableField(value="pa")
|
||||||
|
@Schema(description="土壤含水量")
|
||||||
|
private BigDecimal pa;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,10 +95,10 @@ public class ForecastTask extends GenericPageParams implements Serializable {
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务时间间隔(分钟)
|
* 任务时间间隔(小时)
|
||||||
*/
|
*/
|
||||||
@TableField(value="time_interval")
|
@TableField(value="time_interval")
|
||||||
@Schema(description="任务时间间隔(分钟)")
|
@Schema(description="任务时间间隔(小时)")
|
||||||
private BigDecimal timeInterval;
|
private BigDecimal timeInterval;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -109,6 +109,14 @@ public class ForecastTask extends GenericPageParams implements Serializable {
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private Date forecastTime;
|
private Date forecastTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择的执行当前时间
|
||||||
|
*/
|
||||||
|
@Schema(description = "选择的执行当前时间")
|
||||||
|
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
|
||||||
|
@TableField(exist = false)
|
||||||
|
private Date nowTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 选择的起始时间
|
* 选择的起始时间
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,19 @@
|
||||||
package com.gunshi.project.xyt.schedule;
|
package com.gunshi.project.xyt.schedule;
|
||||||
|
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
||||||
import com.gunshi.project.xyt.entity.vo.ForecastResultVo;
|
import com.gunshi.project.xyt.entity.vo.ForecastResultVo;
|
||||||
|
import com.gunshi.project.xyt.model.AttResBase;
|
||||||
|
import com.gunshi.project.xyt.model.ForecastProject;
|
||||||
import com.gunshi.project.xyt.model.ForecastTask;
|
import com.gunshi.project.xyt.model.ForecastTask;
|
||||||
|
import com.gunshi.project.xyt.model.ForecastUseparam;
|
||||||
|
import com.gunshi.project.xyt.service.AttResBaseService;
|
||||||
|
import com.gunshi.project.xyt.service.ForecastProjectService;
|
||||||
import com.gunshi.project.xyt.service.ForecastResultsService;
|
import com.gunshi.project.xyt.service.ForecastResultsService;
|
||||||
|
import com.gunshi.project.xyt.service.ForecastUseparamService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.quartz.Job;
|
import org.quartz.Job;
|
||||||
import org.quartz.JobDataMap;
|
import org.quartz.JobDataMap;
|
||||||
|
|
@ -11,9 +22,13 @@ import org.quartz.JobExecutionException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author cxw
|
* @author cxw
|
||||||
|
|
@ -25,24 +40,90 @@ import java.util.List;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TaskGroupJob implements Job {
|
public class TaskGroupJob implements Job {
|
||||||
|
|
||||||
private static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
private static SimpleDateFormat sdfMinute = new SimpleDateFormat("yyyy-MM-dd HH:mm:00");
|
||||||
|
|
||||||
|
private static SimpleDateFormat sdfTime = new SimpleDateFormat("yyyyMMddHHmm");
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ForecastResultsService forecastResultsService;
|
private ForecastResultsService forecastResultsService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ForecastUseparamService forecastUseparamService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AttResBaseService attResBaseService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ForecastProjectService forecastProjectService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(JobExecutionContext context) throws JobExecutionException {
|
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||||
JobDataMap jdMap = context.getJobDetail().getJobDataMap();
|
JobDataMap jdMap = context.getJobDetail().getJobDataMap();
|
||||||
String jobId = (String) jdMap.get("jobId");
|
String jobId = (String) jdMap.get("jobId");
|
||||||
ForecastTask forecastTask = (ForecastTask) jdMap.get("forecastTask");
|
ForecastTask forecastTask = (ForecastTask) jdMap.get("forecastTask");
|
||||||
log.info("{}----TaskGroupJob-计划执行开始===>jobId:{}", dtf.format(LocalDateTime.now()), jobId);
|
log.info("{}----TaskGroupJob-计划执行开始===>jobId:{}", sdf.format(LocalDateTime.now()), jobId);
|
||||||
// 根据执行时间、预热期、预见期获取对应的预报、开始、结束时间
|
|
||||||
// todo
|
|
||||||
try {
|
try {
|
||||||
List<ForecastResultVo> forecastResultVo = forecastResultsService.autoFloodForecast(forecastTask);
|
// 根据执行时间、预热期、预见期获取对应的预报、开始、结束时间
|
||||||
|
Date nowTime = sdfMinute.parse(sdf.format(new Date()));
|
||||||
|
Date forecastTime = nowTime;
|
||||||
|
Date startTime;
|
||||||
|
Date endTime;
|
||||||
|
Integer forecastPeriod = forecastTask.getForecastPeriod();// 预见期:小时
|
||||||
|
Integer forecastWarm = forecastTask.getForecastWarm();// 预热期:天
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTime(nowTime);
|
||||||
|
// 预报时间就是当前时间
|
||||||
|
forecastTask.setNowTime(nowTime);
|
||||||
|
forecastTask.setForecastTime(nowTime);
|
||||||
|
// 预热期:往前推 天
|
||||||
|
calendar.add(calendar.DATE, - forecastWarm);
|
||||||
|
startTime = calendar.getTime();
|
||||||
|
forecastTask.setStartTime(startTime);
|
||||||
|
// 预见期:先恢复,再往后推 小时
|
||||||
|
calendar.setTime(nowTime);
|
||||||
|
calendar.add(calendar.HOUR_OF_DAY, forecastPeriod);
|
||||||
|
endTime = calendar.getTime();
|
||||||
|
forecastTask.setEndTime(endTime);
|
||||||
|
List<ForecastResultVo> voList = forecastResultsService.autoFloodForecast(forecastTask);
|
||||||
|
// 符合条件就保存到数据库
|
||||||
|
if (CollectionUtils.isNotEmpty(voList)) {
|
||||||
|
Map<String, Object> map = forecastUseparamService.getMap(new QueryWrapper<ForecastUseparam>().eq("param_code", "ydgdyjz"));// 获取安全值
|
||||||
|
AttResBase attResBase = attResBaseService.getOne(new QueryWrapper<>());// 获取堰顶高程
|
||||||
|
if (MapUtil.isNotEmpty(map) && ObjectUtils.isNotEmpty(attResBase) && ObjectUtils.isNotEmpty(attResBase.getWcrstel())) {
|
||||||
|
BigDecimal ydgdyjz = new BigDecimal(map.get("ydgdyjz").toString());
|
||||||
|
BigDecimal wcrstel = attResBase.getWcrstel();
|
||||||
|
Boolean isSave = false;
|
||||||
|
for (ForecastResultVo vo : voList) {
|
||||||
|
// 当计算的预报最高水位离堰顶高程小于此安全值,或者超过堰顶高度的值时,发送系统内消息提示。同时自动滚动预报保存方案结果
|
||||||
|
if ((vo.getYcSwHValue().add(ydgdyjz)).compareTo(wcrstel) > 0) {
|
||||||
|
isSave = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isSave) {
|
||||||
|
ForecastProject forecastProject = new ForecastProject();
|
||||||
|
forecastProject.setId(IdWorker.getId());
|
||||||
|
forecastProject.setName("未来" + forecastPeriod + "小时洪水预报-".concat(sdfTime.format(nowTime)));
|
||||||
|
forecastProject.setType("1");
|
||||||
|
forecastProject.setForecastTm(forecastTime);
|
||||||
|
forecastProject.setProjectTm(nowTime);
|
||||||
|
forecastProject.setStartTm(startTime);
|
||||||
|
forecastProject.setEndTm(endTime);
|
||||||
|
// forecastProject.setUserId();
|
||||||
|
forecastProject.setForecastPeriod(forecastPeriod);
|
||||||
|
forecastProject.setForecastWarm(forecastWarm);
|
||||||
|
forecastProject.setTimeInterval(forecastTask.getTimeInterval());
|
||||||
|
forecastProject.setTaskId(forecastTask.getId());
|
||||||
|
forecastProject.setVoList(voList);
|
||||||
|
forecastProjectService.saveForecastResults(forecastProject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
log.info("{}----TaskGroupJob-计划执行结束===>jobId:{}", dtf.format(LocalDateTime.now()), jobId);
|
log.info("{}----TaskGroupJob-计划执行结束===>jobId:{}", sdf.format(LocalDateTime.now()), jobId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,18 @@
|
||||||
package com.gunshi.project.xyt.service;
|
package com.gunshi.project.xyt.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.gunshi.project.xyt.entity.vo.ForecastResultVo;
|
||||||
import com.gunshi.project.xyt.mapper.ForecastProjectMapper;
|
import com.gunshi.project.xyt.mapper.ForecastProjectMapper;
|
||||||
import com.gunshi.project.xyt.model.ForecastProject;
|
import com.gunshi.project.xyt.model.ForecastProject;
|
||||||
|
import com.gunshi.project.xyt.model.ForecastResults;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 描述: 预报_预测方案管理表
|
* 描述: 预报_预测方案管理表
|
||||||
|
|
@ -20,6 +25,38 @@ import java.util.Date;
|
||||||
public class ForecastProjectService extends ServiceImpl<ForecastProjectMapper, ForecastProject>
|
public class ForecastProjectService extends ServiceImpl<ForecastProjectMapper, ForecastProject>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ForecastResultsService forecastResultsService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 保存预报结果
|
||||||
|
* @param forecastProject
|
||||||
|
* @return: void
|
||||||
|
* @auther: cxw
|
||||||
|
* @date: 2024-08-06, 周二, 10:06:40
|
||||||
|
*/
|
||||||
|
public Boolean saveForecastResults(ForecastProject forecastProject) {
|
||||||
|
List<ForecastResults> retList = new ArrayList<>();
|
||||||
|
List<ForecastResultVo> voList = forecastProject.getVoList();
|
||||||
|
for (ForecastResultVo vo : voList) {
|
||||||
|
ForecastResults forecastResults = new ForecastResults();
|
||||||
|
forecastResults.setId(IdWorker.getId());
|
||||||
|
forecastResults.setTm(vo.getTm());
|
||||||
|
forecastResults.setYcRkQValue(vo.getYcRkQValue());
|
||||||
|
forecastResults.setRealRkQValue(vo.getRealRkQValue());
|
||||||
|
forecastResults.setYcCkQValue(vo.getYcCkQValue());
|
||||||
|
forecastResults.setRealCkQValue(vo.getRealCkQValue());
|
||||||
|
forecastResults.setYcSwHValue(vo.getYcSwHValue());
|
||||||
|
forecastResults.setRealSwHValue(vo.getRealSwHValue());
|
||||||
|
forecastResults.setDrp(vo.getDrp());
|
||||||
|
forecastResults.setIspreDrp(vo.getIspreDrp());
|
||||||
|
forecastResults.setR(vo.getR());
|
||||||
|
forecastResults.setProjectId(forecastProject.getId());
|
||||||
|
forecastResults.setFlLowLimLev(vo.getFlLowLimLev());
|
||||||
|
forecastResults.setPa(vo.getPa());
|
||||||
|
}
|
||||||
|
return forecastResultsService.saveBatch(retList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,11 @@ public class ForecastResultsService extends ServiceImpl<ForecastResultsMapper, F
|
||||||
{
|
{
|
||||||
|
|
||||||
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
private static SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");
|
private static SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
|
||||||
private static SimpleDateFormat eightSdf = new SimpleDateFormat("yyyy-MM-dd 08");
|
private static SimpleDateFormat eightSdf = new SimpleDateFormat("yyyy-MM-dd 08");
|
||||||
|
|
||||||
private static SimpleDateFormat sixteenSdf = new SimpleDateFormat("yyyy-MM-dd 16");
|
private static SimpleDateFormat sixteenSdf = new SimpleDateFormat("yyyy-MM-dd 16");
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
@ -92,7 +95,167 @@ public class ForecastResultsService extends ServiceImpl<ForecastResultsMapper, F
|
||||||
*/
|
*/
|
||||||
public List<ForecastResultVo> autoFloodForecast(ForecastTask forecastTask) throws Exception {
|
public List<ForecastResultVo> autoFloodForecast(ForecastTask forecastTask) throws Exception {
|
||||||
// 获取预测数据
|
// 获取预测数据
|
||||||
|
List<ForecastResultVo> voList = excuteForecast(forecastTask);
|
||||||
|
return voList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 获取人工交互洪水预报结果
|
||||||
|
* @param forecastTask
|
||||||
|
* @return: java.util.List<com.gunshi.project.xyt.entity.vo.ForecastResultVo>
|
||||||
|
* @auther: cxw
|
||||||
|
* @date: 2024-07-31, 周三, 11:09:24
|
||||||
|
*/
|
||||||
|
public List<ForecastResultVo> getHumanForecastResult(ForecastTask forecastTask) throws Exception {
|
||||||
|
// 当前时间整点,作为获取雨量数据历史、预测分隔点
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.set(Calendar.MINUTE, 0);
|
||||||
|
calendar.set(Calendar.SECOND, 0);
|
||||||
|
calendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
Date nowHourTime = calendar.getTime();
|
||||||
|
forecastTask.setNowTime(nowHourTime);
|
||||||
|
List<ForecastResultVo> voList = excuteForecast(forecastTask);
|
||||||
|
return voList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 组装洪水预报ForecastResultVo
|
||||||
|
* @param forecastTask
|
||||||
|
* @return: java.util.List<com.gunshi.project.xyt.entity.vo.ForecastResultVo>
|
||||||
|
* @auther: cxw
|
||||||
|
* @date: 2024-08-05, 周一, 17:14:52
|
||||||
|
*/
|
||||||
|
private List<ForecastResultVo> excuteForecast(ForecastTask forecastTask) throws Exception {
|
||||||
List<ForecastResultVo> voList = new ArrayList<>();
|
List<ForecastResultVo> voList = new ArrayList<>();
|
||||||
|
Date nowHourTime = forecastTask.getNowTime();
|
||||||
|
Date startTime = forecastTask.getStartTime();
|
||||||
|
Date endTime = forecastTask.getEndTime();
|
||||||
|
// 获取整个时间线的降雨数据
|
||||||
|
List<StPptnR> pptnRAllList = new ArrayList<>();
|
||||||
|
List<StPptnR> pptnRFutureList = new ArrayList<>();
|
||||||
|
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");
|
||||||
|
} else {
|
||||||
|
qwExisted = new QueryWrapper<StPptnR>().eq("stcd", "716153201").ge("tm", startTime).le("tm", nowHourTime).orderBy(true, true, "tm");
|
||||||
|
pptnRFutureList = getForecastDrpData(nowHourTime, "716153201");
|
||||||
|
}
|
||||||
|
List<StPptnR> pptnRExistedList = stPptnRService.list(qwExisted);
|
||||||
|
pptnRAllList.addAll(pptnRExistedList);
|
||||||
|
pptnRAllList.addAll(pptnRFutureList);
|
||||||
|
// 获取配置参数
|
||||||
|
List<ForecastUseparam> paramList = forecastUseparamService.list();
|
||||||
|
List<ForecastU> uList = forecastUService.list();
|
||||||
|
if (CollectionUtils.isEmpty(paramList) || CollectionUtils.isEmpty(uList) || CollectionUtils.isEmpty(pptnRAllList)) {
|
||||||
|
return voList;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
dt = Double.parseDouble(paramMap.get("dt"));
|
||||||
|
Wm = Double.parseDouble(paramMap.get("Im"));
|
||||||
|
// 根据开始结束时间查询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)));
|
||||||
|
if (CollectionUtils.isEmpty(paList)) {
|
||||||
|
return voList;
|
||||||
|
}
|
||||||
|
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"));
|
||||||
|
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<Date[]> periods = splitByDay8To8(startTime, endTime);
|
||||||
|
for (Date[] period : periods) {
|
||||||
|
// 根据每段时间的开始时间,如果在08点前,则采用前一天的pa值计算
|
||||||
|
if (isBeforeEightAM(period[0])) {
|
||||||
|
cal.setTime(period[0]);
|
||||||
|
// 将日期往前推一天
|
||||||
|
cal.add(Calendar.DATE, -1);
|
||||||
|
}
|
||||||
|
ForecastPa forecastPa = paMap.get(sdfDay.format(cal.getTime()));
|
||||||
|
// 根据降雨数据,按照△t的颗粒度,均分
|
||||||
|
List<String> pResultList = new ArrayList<>();
|
||||||
|
// 筛选时间段内的降雨数据。第一个条件:时间大于等于开始时间;第二个条件:时间小于等于结束时间(包前不包后,但是需要使用最后的tm计算间隔值)
|
||||||
|
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 = 0; i < filterList.size(); i++) {
|
||||||
|
// 到第二天早八,包前不包后,最后一条的第二天早八剔除
|
||||||
|
if (i + 1 == filterList.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
StPptnR stPptnR = filterList.get(i);
|
||||||
|
String drp = stPptnR.getDrp();
|
||||||
|
StPptnR stPptnRNext = filterList.get(i + 1);
|
||||||
|
// 两条数据的小时差
|
||||||
|
double diffHours = dateHourDifference(stPptnR.getTm(), stPptnRNext.getTm());
|
||||||
|
// 两条数据间需要增补几条
|
||||||
|
int floorNum = (int) Math.floor(diffHours / dt);
|
||||||
|
for (int j = 0; j < floorNum; j++) {
|
||||||
|
BigDecimal add = new BigDecimal(drp).divide(BigDecimal.valueOf(floorNum)).setScale(2, BigDecimal.ROUND_HALF_UP);
|
||||||
|
pResultList.add(add.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double[] PList = pResultList.stream().mapToDouble(Double::parseDouble).toArray();
|
||||||
|
// 水位历史数据
|
||||||
|
List<StRsvrR> rsvrRRealList = stRsvrRService.list(new QueryWrapper<StRsvrR>().eq("stcd", "716153201").ge("tm", period[0]).le("tm", period[1]));
|
||||||
|
rsvrRRealList = reorganizeRsvrRData(rsvrRRealList, dt);
|
||||||
|
// 预测执行
|
||||||
|
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");
|
||||||
|
if (CollectionUtils.isNotEmpty(forecastVoList)) {
|
||||||
|
forecastVoList = forecastVoList.subList(0, PList.length);
|
||||||
|
for (int j = 0; j < forecastVoList.size(); j++) {
|
||||||
|
FloodAlgorithemVo floodAlgorithemVo = forecastVoList.get(j);
|
||||||
|
ForecastResultVo resultVo = new ForecastResultVo();
|
||||||
|
Date dateTm = sdf.parse(floodAlgorithemVo.getDateStr());
|
||||||
|
resultVo.setTm(dateTm);
|
||||||
|
resultVo.setYcRkQValue(floodAlgorithemVo.getRq());// 预测入库流量
|
||||||
|
// resultVo.setRealRkQValue();// 暂无真实入库流量
|
||||||
|
resultVo.setYcCkQValue(floodAlgorithemVo.getCq());// 预测出库流量
|
||||||
|
resultVo.setYcSwHValue(floodAlgorithemVo.getKh());// 预测水库水位
|
||||||
|
H1 = resultVo.getYcSwHValue().doubleValue();// 先以预测水位作为下一次预测段起始值
|
||||||
|
if (j < rsvrRRealList.size()) {
|
||||||
|
BigDecimal realSwHValue = new BigDecimal(rsvrRRealList.get(j).getRz());
|
||||||
|
resultVo.setRealSwHValue(realSwHValue);// 真实水库水位
|
||||||
|
H1 = realSwHValue.doubleValue();// 如果有真实水位,将最后一条的真实水位作为下一次预测段的初始水位
|
||||||
|
// 真实出库流量=真实水库水位与泄流量曲线差值法
|
||||||
|
if (realSwHValue != null && CollectionUtils.isNotEmpty(stZqrlBList)) {
|
||||||
|
BigDecimal maxZ = stZqrlBList.stream().max(Comparator.comparing(StZqrlB::getZ)).get().getZ();
|
||||||
|
BigDecimal minZ = stZqrlBList.stream().min(Comparator.comparing(StZqrlB::getZ)).get().getZ();
|
||||||
|
if (realSwHValue.compareTo(minZ) < 0 || realSwHValue.compareTo(maxZ) > 0) {
|
||||||
|
resultVo.setRealCkQValue(BigDecimal.ZERO);// 真实出库流量
|
||||||
|
} else {
|
||||||
|
Map<BigDecimal, BigDecimal> stZvalMap = stZqrlBList.stream().collect(Collectors.toMap(StZqrlB::getZ, StZqrlB::getQ));
|
||||||
|
List<BigDecimal> list = stZqrlBList.stream().map(StZqrlB::getZ).collect(Collectors.toList());
|
||||||
|
resultVo.setRealCkQValue(DataHandleUtil.calcData(realSwHValue, stZvalMap, list));// 真实出库流量
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultVo.setDrp(floodAlgorithemVo.getDrp());
|
||||||
|
resultVo.setIspreDrp(dateTm.compareTo(nowHourTime) <= 0 ? "0" : "1");// 0:真实 1:预测
|
||||||
|
resultVo.setR(floodAlgorithemVo.getR());
|
||||||
|
resultVo.setFlLowLimLev(attResBase.getFlLowLimLev());
|
||||||
|
resultVo.setPa(floodAlgorithemVo.getPa());
|
||||||
|
voList.add(resultVo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return voList;
|
return voList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,152 +310,6 @@ public class ForecastResultsService extends ServiceImpl<ForecastResultsMapper, F
|
||||||
return pptnRFutureList;
|
return pptnRFutureList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: 获取人工交互洪水预报结果
|
|
||||||
* @param forecastTask
|
|
||||||
* @return: java.util.List<com.gunshi.project.xyt.entity.vo.ForecastResultVo>
|
|
||||||
* @auther: cxw
|
|
||||||
* @date: 2024-07-31, 周三, 11:09:24
|
|
||||||
*/
|
|
||||||
public List<ForecastResultVo> getHumanForecastResult(ForecastTask forecastTask) throws Exception {
|
|
||||||
// 获取预测数据
|
|
||||||
List<ForecastResultVo> voList = new ArrayList<>();
|
|
||||||
// 当前时间整点,作为获取雨量数据历史、预测分隔点
|
|
||||||
Calendar calendar = Calendar.getInstance();
|
|
||||||
calendar.set(Calendar.MINUTE, 0);
|
|
||||||
calendar.set(Calendar.SECOND, 0);
|
|
||||||
calendar.set(Calendar.MILLISECOND, 0);
|
|
||||||
Date nowHourTime = calendar.getTime();
|
|
||||||
Date forecastTm = forecastTask.getForecastTime();
|
|
||||||
Date startTm = forecastTask.getStartTime();
|
|
||||||
Date endTm = forecastTask.getEndTime();
|
|
||||||
// 获取整个时间线的降雨数据
|
|
||||||
List<StPptnR> pptnRAllList = new ArrayList<>();
|
|
||||||
List<StPptnR> pptnRFutureList = new ArrayList<>();
|
|
||||||
QueryWrapper<StPptnR> qwExisted = new QueryWrapper<>();
|
|
||||||
// 如果结束时间在当前时间之前,降雨序列从历史降雨表获取
|
|
||||||
if (endTm.compareTo(nowHourTime) <= 0) {
|
|
||||||
qwExisted = new QueryWrapper<StPptnR>().eq("stcd", "716153201").ge("tm", startTm).le("tm", endTm).orderBy(true, true, "tm");
|
|
||||||
} else {
|
|
||||||
qwExisted = new QueryWrapper<StPptnR>().eq("stcd", "716153201").ge("tm", startTm).le("tm", nowHourTime).orderBy(true, true, "tm");
|
|
||||||
pptnRFutureList = getForecastDrpData(nowHourTime, "716153201");
|
|
||||||
}
|
|
||||||
List<StPptnR> pptnRExistedList = stPptnRService.list(qwExisted);
|
|
||||||
pptnRAllList.addAll(pptnRExistedList);
|
|
||||||
pptnRAllList.addAll(pptnRFutureList);
|
|
||||||
// 获取配置参数
|
|
||||||
List<ForecastUseparam> paramList = forecastUseparamService.list();
|
|
||||||
List<ForecastU> uList = forecastUService.list();
|
|
||||||
double dt = 0.0;
|
|
||||||
double Wm = 0.0;
|
|
||||||
// 泄流量
|
|
||||||
List<StZqrlB> stZqrlBList = stZqrlBService.list(new QueryWrapper<StZqrlB>().eq("stcd", "716153201"));
|
|
||||||
if (CollectionUtils.isEmpty(paramList) || CollectionUtils.isEmpty(uList) || CollectionUtils.isEmpty(pptnRAllList) || CollectionUtils.isEmpty(stZqrlBList)) {
|
|
||||||
return voList;
|
|
||||||
}
|
|
||||||
// 每小时的单位径流量,单位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;
|
|
||||||
}
|
|
||||||
dt = Double.parseDouble(paramMap.get("dt"));
|
|
||||||
Wm = Double.parseDouble(paramMap.get("Im"));
|
|
||||||
// 根据开始结束时间查询pa
|
|
||||||
Calendar cal = Calendar.getInstance();
|
|
||||||
cal.setTime(startTm);
|
|
||||||
// 将日期往前推一天
|
|
||||||
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(endTm)));
|
|
||||||
if (CollectionUtils.isEmpty(paList)) {
|
|
||||||
return voList;
|
|
||||||
}
|
|
||||||
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", startTm).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<Date[]> periods = splitByDay8To8(startTm, endTm);
|
|
||||||
for (Date[] period : periods) {
|
|
||||||
// 根据每段时间的开始时间,如果在08点前,则采用前一天的pa值计算
|
|
||||||
if (isBeforeEightAM(period[0])) {
|
|
||||||
cal.setTime(period[0]);
|
|
||||||
// 将日期往前推一天
|
|
||||||
cal.add(Calendar.DATE, -1);
|
|
||||||
}
|
|
||||||
ForecastPa forecastPa = paMap.get(sdfDay.format(cal.getTime()));
|
|
||||||
// 根据降雨数据,按照△t的颗粒度,均分
|
|
||||||
List<String> pResultList = new ArrayList<>();
|
|
||||||
// 筛选时间段内的降雨数据。第一个条件:时间大于等于开始时间;第二个条件:时间小于等于结束时间(包前不包后,但是需要使用最后的tm计算间隔值)
|
|
||||||
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 = 0; i < filterList.size(); i++) {
|
|
||||||
// 到第二天早八,包前不包后,最后一条的第二天早八剔除
|
|
||||||
if (i + 1 == filterList.size()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
StPptnR stPptnR = filterList.get(i);
|
|
||||||
String drp = stPptnR.getDrp();
|
|
||||||
StPptnR stPptnRNext = filterList.get(i + 1);
|
|
||||||
// 两条数据的小时差
|
|
||||||
double diffHours = dateHourDifference(stPptnR.getTm(), stPptnRNext.getTm());
|
|
||||||
// 两条数据间需要增补几条
|
|
||||||
int floorNum = (int) Math.floor(diffHours / dt);
|
|
||||||
for (int j = 0; j < floorNum; j++) {
|
|
||||||
BigDecimal add = new BigDecimal(drp).divide(BigDecimal.valueOf(floorNum)).setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
||||||
pResultList.add(add.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
double[] PList = pResultList.stream().mapToDouble(Double::parseDouble).toArray();
|
|
||||||
List<StRsvrR> rsvrRRealList = stRsvrRService.list(new QueryWrapper<StRsvrR>().eq("stcd", "716153201").ge("tm", period[0]).le("tm", period[1]));
|
|
||||||
rsvrRRealList = reorganizeRsvrRData(rsvrRRealList, dt);
|
|
||||||
// 预测执行
|
|
||||||
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");
|
|
||||||
if (CollectionUtils.isNotEmpty(forecastVoList)) {
|
|
||||||
forecastVoList = forecastVoList.subList(0, PList.length);
|
|
||||||
for (int j = 0; j < forecastVoList.size(); j++) {
|
|
||||||
FloodAlgorithemVo floodAlgorithemVo = forecastVoList.get(j);
|
|
||||||
ForecastResultVo resultVo = new ForecastResultVo();
|
|
||||||
resultVo.setTm(floodAlgorithemVo.getDateStr());
|
|
||||||
resultVo.setYcRkQValue(floodAlgorithemVo.getRq());// 预测入库流量
|
|
||||||
// resultVo.setRealRkQValue();// 暂无真实入库流量
|
|
||||||
resultVo.setYcCkQValue(floodAlgorithemVo.getCq());// 预测出库流量
|
|
||||||
resultVo.setYcSwHValue(floodAlgorithemVo.getKh());// 预测水库水位
|
|
||||||
H1 = resultVo.getYcSwHValue().doubleValue();// 先以预测水位作为下一次预测段起始值
|
|
||||||
if (j < rsvrRRealList.size()) {
|
|
||||||
BigDecimal realSwHValue = new BigDecimal(rsvrRRealList.get(j).getRz());
|
|
||||||
resultVo.setRealSwHValue(realSwHValue);// 真实水库水位
|
|
||||||
H1 = realSwHValue.doubleValue();// 如果有真实水位,将最后一条的真实水位作为下一次预测段的初始水位
|
|
||||||
// 真实出库流量=真实水库水位与泄流量曲线差值法
|
|
||||||
if (realSwHValue != null && CollectionUtils.isNotEmpty(stZqrlBList)) {
|
|
||||||
BigDecimal maxZ = stZqrlBList.stream().max(Comparator.comparing(StZqrlB::getZ)).get().getZ();
|
|
||||||
BigDecimal minZ = stZqrlBList.stream().min(Comparator.comparing(StZqrlB::getZ)).get().getZ();
|
|
||||||
if (realSwHValue.compareTo(minZ) < 0 || realSwHValue.compareTo(maxZ) > 0) {
|
|
||||||
resultVo.setRealCkQValue(BigDecimal.ZERO);// 真实出库流量
|
|
||||||
} else {
|
|
||||||
Map<BigDecimal, BigDecimal> stZvalMap = stZqrlBList.stream().collect(Collectors.toMap(StZqrlB::getZ, StZqrlB::getQ));
|
|
||||||
List<BigDecimal> list = stZqrlBList.stream().map(StZqrlB::getZ).collect(Collectors.toList());
|
|
||||||
resultVo.setRealCkQValue(DataHandleUtil.calcData(realSwHValue, stZvalMap, list));// 真实出库流量
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resultVo.setDrp(floodAlgorithemVo.getDrp());
|
|
||||||
resultVo.setR(floodAlgorithemVo.getR());
|
|
||||||
resultVo.setFlLowLimLev(attResBase.getFlLowLimLev());
|
|
||||||
voList.add(resultVo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return voList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: 根据△T来整编实际水位数据
|
* @description: 根据△T来整编实际水位数据
|
||||||
* @param rsvrRRealList
|
* @param rsvrRRealList
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue