gunshi-project-ss/src/main/java/com/gunshi/project/hsz/service/RainBasinDivisionService.java

497 lines
17 KiB
Java

package com.gunshi.project.hsz.service;
import cn.hutool.core.bean.BeanUtil;
import com.gunshi.project.hsz.entity.so.StPptnSo;
import com.gunshi.project.hsz.entity.vo.CartogramVo;
import com.gunshi.project.hsz.entity.vo.StPptnDetailsVo;
import com.gunshi.project.hsz.entity.vo.StPptnVo;
import com.gunshi.project.hsz.mapper.RealRainMapper;
import com.gunshi.project.hsz.mapper.StPptnRMapper;
import com.gunshi.project.hsz.model.StPptnRD;
import com.gunshi.project.hsz.model.StPptnRReal;
import com.gunshi.project.hsz.model.StStbprpBAutoDao;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* Description:
* Created by wanyan on 2024/7/8
*
* @author wanyan
* @version 1.0
*/
@Service
@Slf4j
public class RainBasinDivisionService {
@Autowired
private RealRainMapper realRainMapper;
@Autowired
private StPptnRMapper stPptnRMapper;
@Resource
private StStbprpBAutoDao stStbprpBAutoDao;
/**
* 根据测站编码查询时间段内每小时的雨量
*
* @param stPptnSo 雨量站降雨量查询参数
* @return
*/
public List<StPptnVo> queryStPptnPerHourByStcdAndStartTimeAndEndTime(StPptnSo stPptnSo) {
String stcd = stPptnSo.getStcd();
List<StPptnVo> stPptnVos = realRainMapper.queryStPptnPerHourByStcdAndStartTimeAndEndTime(stcd, stPptnSo.getStartTime(), stPptnSo.getEndTime());
SimpleDateFormat df = new SimpleDateFormat("MM-dd HH:mm");
for (StPptnVo stPptnVo : stPptnVos) {
Date time = stPptnVo.getTime();
stPptnVo.setTimeStr(df.format(time));
}
return stPptnVos;
}
/**
* 根据测站编码查询时间段内每小时的雨量统计
*
* @param stPptnSo 雨量站降雨量查询参数
* @return
*/
public CartogramVo queryStPptnPerHourChartByStcdAndStartTimeAndEndTime(StPptnSo stPptnSo) {
//实测
List<StPptnVo> stPptnVos1 = queryStPptnPerHourNowByStcdAndStartTimeAndEndTime(stPptnSo);
//累计
List<StPptnVo> stPptnVos2 = queryStPptnPerHourSumByStcdAndStartTimeAndEndTime(stPptnSo);
CartogramVo cartogramVo = new CartogramVo();
List<String> time = new ArrayList<>();
List<BigDecimal> actual = new ArrayList<>();
List<BigDecimal> total = new ArrayList<>();
for (StPptnVo stPptnVo : stPptnVos1) {
time.add(stPptnVo.getTimeStr());
actual.add(stPptnVo.getSumDrp());
}
for (StPptnVo stPptnVo : stPptnVos2) {
total.add(stPptnVo.getSumDrp());
}
cartogramVo.setTime(time);
cartogramVo.setActual(actual);
cartogramVo.setTotal(total);
return cartogramVo;
}
/**
* 根据测站编码查询时间段内每小时的实测雨量
*
* @param stPptnSo 雨量站降雨量查询参数
* @return
*/
public List<StPptnVo> queryStPptnPerHourNowByStcdAndStartTimeAndEndTime(StPptnSo stPptnSo) {
List<StPptnVo> stPptnVos = queryStPptnPerHourByStcdAndStartTimeAndEndTime(stPptnSo);
Collections.reverse(stPptnVos);
return stPptnVos;
}
/**
* 根据测站编码查询时间段内每小时的累计雨量
*
* @param stPptnSo 雨量站降雨量查询参数
* @return
*/
public List<StPptnVo> queryStPptnPerHourSumByStcdAndStartTimeAndEndTime(StPptnSo stPptnSo) {
List<StPptnVo> stPptnVos = queryStPptnPerHourNowByStcdAndStartTimeAndEndTime(stPptnSo);
BigDecimal sumdrp = BigDecimal.valueOf(0);
for (StPptnVo stPptnVo : stPptnVos) {
sumdrp = sumdrp.add(stPptnVo.getSumDrp());
stPptnVo.setSumDrp(sumdrp);
}
return stPptnVos;
}
/**
* 根据测站编码查询时间段内每天的雨量
*
* @param stPptnSo 雨量站降雨量查询参数
* @return
*/
@SneakyThrows
public List<StPptnVo> queryStPptnPerDayByStcdAndStartTimeAndEndTime(StPptnSo stPptnSo) {
String stcd = stPptnSo.getStcd();
Date stm = stPptnSo.getStartTime();
Date etm = stPptnSo.getEndTime();
Date now = new Date();
if (etm.getTime() > now.getTime()) etm = now;
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
stm = df.parse(df.format(stm));
etm = df.parse(df.format(etm));
Calendar cal = Calendar.getInstance();
List<StPptnVo> stPptnVos = new ArrayList<>();
while (etm.getTime() >= stm.getTime()) {
cal.setTime(stm);
StPptnVo stPptnVo = new StPptnVo();
stPptnVo.setTime(stm);
stPptnVo.setTimeStr(df.format(stm));
int year = cal.get(Calendar.YEAR);
StPptnRD pptnrd = realRainMapper.getStPptnRD(
stcd, stm, year
);
if (pptnrd != null) {
stPptnVo.setSumDrp(pptnrd.getDrp());
}
stPptnVos.add(stPptnVo);
cal.add(Calendar.DAY_OF_MONTH, 1);
stm = cal.getTime();
}
return stPptnVos;
}
/**
* 根据测站编码查询时间段内每天的雨量统计
*
* @param stPptnSo 雨量站降雨量查询参数
* @return
*/
public CartogramVo queryStPptnPerDayChartChartByStcdAndStartTimeAndEndTime(StPptnSo stPptnSo) {
//实测
List<StPptnVo> stPptnVos1 = queryStPptnPerDayByStcdAndStartTimeAndEndTime(stPptnSo);
//累计
List<StPptnVo> stPptnVos2 = queryStPptnPerDaySumByStcdAndStartTimeAndEndTime(stPptnSo);
CartogramVo cartogramVo = new CartogramVo();
List<String> time = new ArrayList<>();
List<BigDecimal> actual = new ArrayList<>();
List<BigDecimal> total = new ArrayList<>();
for (StPptnVo stPptnVo : stPptnVos1) {
time.add(stPptnVo.getTimeStr());
actual.add(stPptnVo.getSumDrp());
}
for (StPptnVo stPptnVo : stPptnVos2) {
total.add(stPptnVo.getSumDrp());
}
cartogramVo.setTime(time);
cartogramVo.setActual(actual);
cartogramVo.setTotal(total);
return cartogramVo;
}
/**
* 根据测站编码查询时间段内每天的累计雨量
*
* @param stPptnSo 雨量站降雨量查询参数
* @return
*/
public List<StPptnVo> queryStPptnPerDaySumByStcdAndStartTimeAndEndTime(StPptnSo stPptnSo) {
List<StPptnVo> stPptnVos = queryStPptnPerDayByStcdAndStartTimeAndEndTime(stPptnSo);
BigDecimal sumdrp = BigDecimal.valueOf(0);
for (StPptnVo stPptnVo : stPptnVos) {
if (stPptnVo.getSumDrp() != null){
sumdrp = sumdrp.add(stPptnVo.getSumDrp());
}
stPptnVo.setSumDrp(sumdrp);
}
return stPptnVos;
}
/**
* 根据测站编码查询详细雨量情况
*
* @param stcd 测站编码
* @return
*/
public StPptnDetailsVo queryStPptnDetailsByStcd(String stcd) {
// StPptnRStat stPptnRStat = stPptnRStatMapper.queryStPptnRStatByStcd(stcd);
StPptnRReal stPptnRReal = realRainMapper.queryPptnByStcd(stcd);
StPptnDetailsVo stPptnDetailsVo = new StPptnDetailsVo();
if (stPptnRReal != null){
BeanUtil.copyProperties(stPptnRReal, stPptnDetailsVo);
}else {
stPptnDetailsVo.setStcd(stcd);
}
BigDecimal value0 = new BigDecimal(0);
Date date = new Date();
// //48小时降雨量
// BigDecimal h48 = stStbprpBMapper.queryStPptn48HByStcd(stcd);
// if (h48 == null) {
// stPptnDetailsVo.setH48(value0);
// } else {
// stPptnDetailsVo.setH48(h48);
// }
//
// //今日雨量
// BigDecimal todayDrp = queryTodayDrpByStcdAndTime(stcd, date);
// if (todayDrp == null) {
// stPptnDetailsVo.setTodayDrp(value0);
// } else {
// stPptnDetailsVo.setTodayDrp(todayDrp);
// }
//昨日雨量
BigDecimal yesterdayDrp = queryYesterdayDrpByStcdAndTime(stcd, date);
if (yesterdayDrp == null) {
stPptnDetailsVo.setYesterdayDrp(value0);
} else {
stPptnDetailsVo.setYesterdayDrp(yesterdayDrp);
}
//本月降雨量
BigDecimal monthDay = queryMonthDrpByStcdAndTime(stcd, date);
if (monthDay == null) {
stPptnDetailsVo.setMonthDrp(value0);
} else {
stPptnDetailsVo.setMonthDrp(monthDay);
}
//本年降雨量
BigDecimal yearDrp = queryYearDrpByStcdAndTime(stcd, date);
if (yearDrp == null) {
stPptnDetailsVo.setYearDrp(value0);
} else {
stPptnDetailsVo.setYearDrp(yearDrp);
}
//本年天数
Long yearDay = countYearDay(date);
stPptnDetailsVo.setYearDay(yearDay);
Map<String, Object> map = queryYearDrpDayAndMaxDrpAndMaxDrpTimeByStcdAndTime(stcd, date);
//本年降雨天数
Long yearDrpDay = (Long) map.get("count");
stPptnDetailsVo.setYearDrpDay(yearDrpDay);
//本年最大日雨量
BigDecimal maxDrp = (BigDecimal) map.get("maxDrp");
stPptnDetailsVo.setMaxDrp(maxDrp);
//本年最大日雨量时间
Date maxDrpTime =(Date) map.get("maxDrpTime");
stPptnDetailsVo.setMaxDrpTime(maxDrpTime);
return stPptnDetailsVo;
}
/**
* 根据测站编码和时间查看昨日降雨量
*
* @param stcd 测站编码
* @param time 当前时间
* @return 昨日降雨量
*/
public BigDecimal queryYesterdayDrpByStcdAndTime(String stcd, Date time) {
LocalDateTime now = LocalDateTime.ofInstant(time.toInstant(), ZoneId.systemDefault());
LocalDateTime startTime;
LocalDateTime endTime;
LocalDateTime yesterday = now.minusDays(1);
if (now.getHour() >= 8) {
startTime = LocalDateTime.of(
yesterday.getYear(),
yesterday.getMonthValue(),
yesterday.getDayOfMonth(),
8,
0,
0
);
endTime = LocalDateTime.of(
now.getYear(),
now.getMonthValue(),
now.getDayOfMonth(),
8,
0,
0
);
} else {
endTime = endTime = LocalDateTime.of(
yesterday.getYear(),
yesterday.getMonthValue(),
yesterday.getDayOfMonth(),
8,
0,
0
);
yesterday = yesterday.minusDays(1);
startTime = LocalDateTime.of(
yesterday.getYear(),
yesterday.getMonthValue(),
yesterday.getDayOfMonth(),
8,
0,
0
);
}
return stPptnRMapper.queryStPptnTimeQuantumByStcdAndTime(
stcd,
Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant())
);
}
/**
* 根据测站编码和时间查看本月降雨量
*
* @param stcd 测站编码
* @param time 当前时间
* @return 本月降雨量
*/
public BigDecimal queryMonthDrpByStcdAndTime(String stcd, Date time) {
LocalDateTime now = LocalDateTime.ofInstant(time.toInstant(), ZoneId.systemDefault());
LocalDateTime startTime;
LocalDateTime endTime;
if (now.getHour() >= 8 || (now.getHour() < 8 && now.getDayOfMonth() > 1)) {
startTime = LocalDateTime.of(
now.getYear(),
now.getMonthValue(),
1,
8,
0,
0
);
endTime = now;
return stPptnRMapper.queryStPptnTimeQuantumByStcdAndTime(
stcd,
Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant())
);
}
BigDecimal monthdrp = BigDecimal.valueOf(0);
return monthdrp;
}
/**
* 根据测站编码和时间查看本年降雨量
*
* @param stcd 测站编码
* @param time 当前时间
* @return 本年降雨量
*/
public BigDecimal queryYearDrpByStcdAndTime(String stcd, Date time) {
LocalDateTime now = LocalDateTime.ofInstant(time.toInstant(), ZoneId.systemDefault());
LocalDateTime startTime;
LocalDateTime endTime;
if (now.getHour() >= 8 || (now.getHour() < 8 && now.getMonthValue() > 1) || (now.getHour() < 8 && now.getMonthValue() == 1 && now.getDayOfMonth() >= 1)) {
startTime = LocalDateTime.of(
now.getYear(),
1,
1,
8,
0,
0
);
endTime = now;
return stPptnRMapper.queryStPptnTimeQuantumByStcdAndTime(
stcd,
Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant())
);
}
BigDecimal monthDrp = BigDecimal.valueOf(0);
return monthDrp;
}
/**
* 根据测站编码和时间查询本年降雨天数、本年最大日雨量、本年最大日雨量时间
*
* @param stcd 测站编码
* @param time 当前时间
* @return 本年降雨天数、本年最大日雨量、本年最大日雨量时间
*/
public Map<String, Object> queryYearDrpDayAndMaxDrpAndMaxDrpTimeByStcdAndTime(String stcd, Date time) {
Date now = new Date();
Date startTime = new Date(now.getYear(), 0, 1, 8, 0, 0);
BigDecimal maxDrp = BigDecimal.valueOf(0);
Date maxDrpTime = startTime;
Long count = 0L;
Map<String, Object> map = new HashMap<>();
map.put("count", count);
map.put("maxDrp", maxDrp);
map.put("maxDrpTime", maxDrpTime);
// QueryWrapper<StStbprpB> queryWrapper = new QueryWrapper<>();
// queryWrapper.eq(StStbprpB.COL_STCD,stcd);
// StStbprpB stStbprpB = stStbprpBAutoDao.getOne(queryWrapper);
StPptnRD stPptnRD = realRainMapper.getMaxOfYear(stcd,now.getYear() + 1900);
if (stPptnRD == null){
return map;
}
count = realRainMapper.getRainOfDayInYear(stcd, now.getYear()+1900);
map.put("count", count);
map.put("maxDrp", stPptnRD.getDrp());
map.put("maxDrpTime", stPptnRD.getTm());
return map;
}
/**
* 计算本年天数
*
* @param time 当前时间
* @return 本年天数
*/
public Long countYearDay(Date time) {
LocalDateTime now = LocalDateTime.ofInstant(time.toInstant(), ZoneId.systemDefault());
LocalDateTime startTime = LocalDateTime.of(now.getYear(), 1, 1, 8, 0, 0);
long count = ChronoUnit.DAYS.between(startTime, now);
return count + 1;
}
public StPptnRReal maxRain(StPptnSo stPptnSo) {
StPptnRReal stPptnRReal = new StPptnRReal();
List<StPptnVo> stPptnVos = realRainMapper.queryStPptnPerHourByStcdAndStartTimeAndEndTime(stPptnSo.getStcd(), stPptnSo.getStartTime(), stPptnSo.getEndTime());
if (stPptnVos == null || stPptnVos.isEmpty()) {
return null;
}
stPptnRReal.setH1(stPptnVos.stream().max(Comparator.comparing(StPptnVo::getSumDrp)).get().getSumDrp());
Collections.reverse(stPptnVos);
List<Integer> list = Arrays.asList(3, 6, 12);
for(Integer num : list){
BigDecimal data = calcMaxData(num,stPptnVos);
if(num == 3){
stPptnRReal.setH3(data);
}
if(num == 6){
stPptnRReal.setH6(data);
}
if(num == 12){
stPptnRReal.setH12(data);
}
}
return stPptnRReal;
}
private BigDecimal calcMaxData(Integer num, List<StPptnVo> stPptnVos) {
List<BigDecimal> list = stPptnVos.stream().map(StPptnVo::getSumDrp).collect(Collectors.toList());
return IntStream.range(0, list.size() - num -1)
.mapToObj(i -> list.subList(i, Math.min(i + num, list.size()))) // 获取每几个数的子列表
.map(sublist -> sublist.stream().reduce(BigDecimal.ZERO, BigDecimal::add))
.max(BigDecimal::compareTo)
.orElse(BigDecimal.ZERO);
}
public StPptnRReal queryStPptnRealByStcd(String stcd) {
return realRainMapper.queryPptnByStcd(stcd);
}
}