由于水位和雨量有5分钟左右的时间差,所以选择时间间隔最接近的数据进行结合展示
parent
56da4f7282
commit
f5e3755e38
|
|
@ -146,10 +146,10 @@ public class StZqrlBController {
|
||||||
@PostMapping("/list")
|
@PostMapping("/list")
|
||||||
public R<List<StZqrlB>> list(@RequestBody StZqrlB dto) {
|
public R<List<StZqrlB>> list(@RequestBody StZqrlB dto) {
|
||||||
LambdaQueryChainWrapper<StZqrlB> q = service.lambdaQuery().orderByAsc(StZqrlB::getZ);
|
LambdaQueryChainWrapper<StZqrlB> q = service.lambdaQuery().orderByAsc(StZqrlB::getZ);
|
||||||
String stcd = dto.getStcd();
|
// String stcd = dto.getStcd();
|
||||||
if (StringUtils.isNotBlank(stcd)){
|
// if (StringUtils.isNotBlank(stcd)){
|
||||||
q.eq(StZqrlB::getStcd, stcd);
|
// q.eq(StZqrlB::getStcd, stcd);
|
||||||
}
|
// }
|
||||||
return R.ok(q.list());
|
return R.ok(q.list());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.gunshi.project.hsz.entity.vo;
|
package com.gunshi.project.hsz.entity.vo;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
import com.gunshi.project.hsz.model.FileAssociations;
|
import com.gunshi.project.hsz.model.FileAssociations;
|
||||||
import com.gunshi.project.hsz.model.HiddenInfo;
|
import com.gunshi.project.hsz.model.HiddenInfo;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
@ -15,10 +17,19 @@ public class MentenceInfoCountVo extends HiddenInfo {
|
||||||
@Schema(description = "维护对象名称")
|
@Schema(description = "维护对象名称")
|
||||||
private String mentenceStName;
|
private String mentenceStName;
|
||||||
|
|
||||||
|
@Schema(description = "维护项目Id")
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long mentenceStId;
|
||||||
|
|
||||||
@Schema(description = "维护项目名称")
|
@Schema(description = "维护项目名称")
|
||||||
private String mentenceStDetailName;
|
private String mentenceStDetailName;
|
||||||
|
|
||||||
|
@Schema(description = "维护对象Id")
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long mentenceStDetailId;
|
||||||
|
|
||||||
@Schema(description = "维护人Id")
|
@Schema(description = "维护人Id")
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
private String mentencePersonId;
|
private String mentencePersonId;
|
||||||
|
|
||||||
@Schema(description = "维护人名称")
|
@Schema(description = "维护人名称")
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ public interface AttResBaseMapper extends BaseMapper<AttResBase> {
|
||||||
|
|
||||||
@Select("""
|
@Select("""
|
||||||
<script>
|
<script>
|
||||||
select t.stcd,(t.tm - INTERVAL '5 minutes') as tm,
|
select t.stcd,t.tm,
|
||||||
t.rz from public.st_rsvr_r t
|
t.rz from public.st_rsvr_r t
|
||||||
where t.stcd = #{obj.stcd}
|
where t.stcd = #{obj.stcd}
|
||||||
<if test="obj.stm != null ">
|
<if test="obj.stm != null ">
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ public interface MentenceFarmerRecordMapper extends BaseMapper<MentenceFarmerRec
|
||||||
@Select("""
|
@Select("""
|
||||||
<script>
|
<script>
|
||||||
select t1.*,t2.mentence_person_id as mentencePersonId,t2.mentence_person_name as mentencePersonName,
|
select t1.*,t2.mentence_person_id as mentencePersonId,t2.mentence_person_name as mentencePersonName,
|
||||||
t3.name as mentenceStDetailName,t4.st_name as mentenceStName
|
t3.name as mentenceStDetailName,t4.st_name as mentenceStName,t4.id as mentenceStId,t3.id as mentenceStDetailId
|
||||||
from hidden_info t1
|
from hidden_info t1
|
||||||
join mentence_farmer_record t2 on t1.mentence_farmer_record_id = t2.id
|
join mentence_farmer_record t2 on t1.mentence_farmer_record_id = t2.id
|
||||||
join mentence_st_detail t3 on t2.mentence_st_detail_id = t3.id
|
join mentence_st_detail t3 on t2.mentence_st_detail_id = t3.id
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ public class ReservoirWaterService {
|
||||||
private StRiverRRealService stRiverRRealServices;
|
private StRiverRRealService stRiverRRealServices;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//实时供水
|
//实时供水
|
||||||
@Autowired
|
@Autowired
|
||||||
private StWaterRRealService stWaterRRealService;
|
private StWaterRRealService stWaterRRealService;
|
||||||
|
|
@ -178,7 +179,8 @@ public class ReservoirWaterService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<StZvarlB> zvarl(String stcd) {
|
public List<StZvarlB> zvarl(String stcd) {
|
||||||
LambdaQueryWrapper<StZvarlB> queryWrapper = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<StZvarlB> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.orderByAsc(StZvarlB::getRz);
|
||||||
return stZvarlBMapper.selectList(queryWrapper);
|
return stZvarlBMapper.selectList(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,7 +193,11 @@ public class ReservoirWaterService {
|
||||||
//获取库容曲线关系,算出库容
|
//获取库容曲线关系,算出库容
|
||||||
List<StZvarlB> zvarl = zvarl(stcd);
|
List<StZvarlB> zvarl = zvarl(stcd);
|
||||||
if(CollectionUtils.isNotEmpty(zvarl)){
|
if(CollectionUtils.isNotEmpty(zvarl)){
|
||||||
calcTqData(rzData,zvarl);
|
//calcTqData(rzData,zvarl);
|
||||||
|
rzData.stream().forEach(o -> {
|
||||||
|
BigDecimal w = stZvarlBService.getWByZvarl(zvarl, o.getRz());
|
||||||
|
o.setW(w);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
//根据监测时间合并雨量和水位数据
|
//根据监测时间合并雨量和水位数据
|
||||||
return bindData(stcd,drpData,rzData);
|
return bindData(stcd,drpData,rzData);
|
||||||
|
|
@ -228,26 +234,30 @@ public class ReservoirWaterService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AttResMonitorVo> bindData(String stcd,List<AttResMonitorVo> drpData, List<AttResMonitorVo> rzData) {
|
private List<AttResMonitorVo> bindData(String stcd, List<AttResMonitorVo> drpData, List<AttResMonitorVo> rzData) {
|
||||||
HashSet<Date> strings = new HashSet<>();
|
// 以水位数据的时间为基准(过五分钟的数据)
|
||||||
drpData.stream().forEach(v1 -> strings.add(v1.getTm()));
|
return rzData.stream().map(rzVo -> {
|
||||||
rzData.stream().forEach(v1 -> strings.add(v1.getTm()));
|
AttResMonitorVo resultVo = AttResMonitorVo.builder()
|
||||||
|
.stcd(stcd)
|
||||||
|
.tm(rzVo.getTm()) // 使用水位数据的时间
|
||||||
|
.rz(rzVo.getRz())
|
||||||
|
.w(rzVo.getW())
|
||||||
|
.build();
|
||||||
|
|
||||||
ArrayList<AttResMonitorVo> result = new ArrayList<>();
|
// 为这个水位时间点查找最接近的降水数据
|
||||||
strings.stream().forEach(v1 -> result.add(AttResMonitorVo.builder().stcd(stcd).tm(v1).build()));
|
drpData.stream()
|
||||||
|
.min(Comparator.comparing(drpVo -> Math.abs(rzVo.getTm().getTime() - drpVo.getTm().getTime())))
|
||||||
List<AttResMonitorVo> list = result.stream().map(v1 -> {
|
.ifPresent(closestDrp -> {
|
||||||
drpData.stream().filter(v2 -> v1.getTm().equals(v2.getTm())).forEach(v2 -> {
|
long timeDiff = Math.abs(rzVo.getTm().getTime() - closestDrp.getTm().getTime());
|
||||||
v1.setDrp(v2.getDrp());
|
if (timeDiff <= 30 * 60 * 1000) { // 30分钟容差
|
||||||
|
resultVo.setDrp(closestDrp.getDrp());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
rzData.stream().filter(v2 -> v1.getTm().equals(v2.getTm())).forEach(v2 -> {
|
return resultVo;
|
||||||
v1.setRz(v2.getRz());
|
})
|
||||||
v1.setW(v2.getW());
|
.sorted(Comparator.comparing(AttResMonitorVo::getTm).reversed())
|
||||||
});
|
.collect(Collectors.toList());
|
||||||
return v1;
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
return list.stream().sorted(Comparator.comparing(AttResMonitorVo::getTm).reversed()).collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public StRsvrVo rz(ReservoirWaterCommonSo reservoirWaterCommonSo) {
|
public StRsvrVo rz(ReservoirWaterCommonSo reservoirWaterCommonSo) {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
@ -76,6 +77,94 @@ public class RiverWaterService {
|
||||||
return stZqrlBMapper.selectList(queryWrapper);
|
return stZqrlBMapper.selectList(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BigDecimal getQByRz(List<StZqR> zqr,BigDecimal rz){
|
||||||
|
// 1. 参数校验
|
||||||
|
if (zqr == null || zqr.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("水位-流量关系列表不能为空");
|
||||||
|
}
|
||||||
|
if (rz == null) {
|
||||||
|
throw new IllegalArgumentException("水位值不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 检查边界情况:如果目标水位低于最低水位或高于最高水位
|
||||||
|
BigDecimal minRz = zqr.get(0).getZ();
|
||||||
|
BigDecimal maxRz = zqr.get(zqr.size() - 1).getZ();
|
||||||
|
if (rz.compareTo(minRz) < 0) {
|
||||||
|
// 低于最低水位,返回0流量
|
||||||
|
return BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
if (rz.compareTo(maxRz) > 0) {
|
||||||
|
// 高于最高水位,返回0流量
|
||||||
|
return BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 二分查找水位区间
|
||||||
|
int l = 0;
|
||||||
|
int r = zqr.size() - 1;
|
||||||
|
|
||||||
|
while (l <= r) {
|
||||||
|
int mid = l + (r - l) / 2;
|
||||||
|
BigDecimal midRz = zqr.get(mid).getZ();
|
||||||
|
int compareResult = midRz.compareTo(rz);
|
||||||
|
|
||||||
|
if (compareResult == 0) {
|
||||||
|
// 找到完全匹配的水位,直接返回对应的流量
|
||||||
|
return zqr.get(mid).getQ();
|
||||||
|
} else if (compareResult < 0) {
|
||||||
|
l = mid + 1;
|
||||||
|
} else {
|
||||||
|
r = mid - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 此时:
|
||||||
|
* l 指向第一个大于rz的位置
|
||||||
|
* r 指向最后一个小于rz的位置
|
||||||
|
* 即:r为 (x1, y1) - 下限水位和流量
|
||||||
|
* l为 (x2, y2) - 上限水位和流量
|
||||||
|
*/
|
||||||
|
if (l >= zqr.size() || r < 0) {
|
||||||
|
return BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取前后相邻的两个点
|
||||||
|
StZqR lowerPoint = zqr.get(r);
|
||||||
|
StZqR upperPoint = zqr.get(l);
|
||||||
|
|
||||||
|
// 使用线性插值计算流量
|
||||||
|
return linearInterpolation(
|
||||||
|
lowerPoint.getZ(), lowerPoint.getQ(),
|
||||||
|
upperPoint.getZ(), upperPoint.getQ(),
|
||||||
|
rz
|
||||||
|
).setScale(3, RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线性插值辅助方法(可以复用之前的)
|
||||||
|
* @param x1 已知点1的水位
|
||||||
|
* @param y1 已知点1的流量
|
||||||
|
* @param x2 已知点2的水位
|
||||||
|
* @param y2 已知点2的流量
|
||||||
|
* @param x 目标水位
|
||||||
|
* @return 目标水位对应的流量
|
||||||
|
*/
|
||||||
|
private BigDecimal linearInterpolation(BigDecimal x1, BigDecimal y1,
|
||||||
|
BigDecimal x2, BigDecimal y2,
|
||||||
|
BigDecimal x) {
|
||||||
|
// 使用公式: y = y1 + ( (y2 - y1) / (x2 - x1) ) * (x - x1)
|
||||||
|
|
||||||
|
// 计算斜率: (y2 - y1) / (x2 - x1)
|
||||||
|
BigDecimal slope = y2.subtract(y1)
|
||||||
|
.divide(x2.subtract(x1), 10, RoundingMode.HALF_UP);
|
||||||
|
|
||||||
|
// 计算: slope * (x - x1)
|
||||||
|
BigDecimal xDiff = x.subtract(x1);
|
||||||
|
BigDecimal product = slope.multiply(xDiff);
|
||||||
|
|
||||||
|
// 计算最终结果: y1 + product
|
||||||
|
return y1.add(product);
|
||||||
|
}
|
||||||
|
|
||||||
public List<AttRvMonitorVo> monitorData(DataQueryCommonSo dataQueryCommonSo) {
|
public List<AttRvMonitorVo> monitorData(DataQueryCommonSo dataQueryCommonSo) {
|
||||||
String stcd = dataQueryCommonSo.getStcd();
|
String stcd = dataQueryCommonSo.getStcd();
|
||||||
|
|
@ -84,9 +173,12 @@ public class RiverWaterService {
|
||||||
//水位数据
|
//水位数据
|
||||||
List<AttRvMonitorVo> rzData = attRvBaseMapper.rz(dataQueryCommonSo);
|
List<AttRvMonitorVo> rzData = attRvBaseMapper.rz(dataQueryCommonSo);
|
||||||
//获取水位流量关系,算出转换流量
|
//获取水位流量关系,算出转换流量
|
||||||
List<StZqrlB> zqrl = zqrl(stcd);
|
//List<StZqrlB> zqrl = zqrl(stcd);
|
||||||
if(CollectionUtils.isNotEmpty(zqrl)){
|
List<StZqR> zqr = zqr(stcd);
|
||||||
calcTqData(rzData,zqrl);
|
if(CollectionUtils.isNotEmpty(zqr)){
|
||||||
|
rzData.stream().forEach(o->{
|
||||||
|
o.setQ(getQByRz(zqr,o.getZ()));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
//根据监测时间合并雨量和水位数据
|
//根据监测时间合并雨量和水位数据
|
||||||
return bindData(stcd,drpData,rzData);
|
return bindData(stcd,drpData,rzData);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue