Commit 17bbcc50 authored by duwei's avatar duwei

异常事件时空分布(拥堵、失衡、溢出、空放)

parent ab9caec1
......@@ -294,8 +294,8 @@ public class RunningEvaluateServiceImpl implements RunningEvaluateService {
Date startDate = bo.getStartDate();
Date endDate = bo.getEndDate();
endDate = DateUtil.offsetDay(endDate, 1); // 包含最后一天
int startStamp = (int) (startDate.getTime() / 1000); // 10位时间戳
int endStamp = (int) (endDate.getTime() / 1000);
// int startStamp = (int) (startDate.getTime() / 1000); // 10位时间戳
// int endStamp = (int) (endDate.getTime() / 1000);
String startTime = DateUtil.format(startDate, "yyyy-MM-dd HH:mm:ss");
String endTime = DateUtil.format(endDate, "yyyy-MM-dd HH:mm:ss");
......@@ -315,8 +315,9 @@ public class RunningEvaluateServiceImpl implements RunningEvaluateService {
.filter(metricHistDTO -> metricHistDTO.getStatus() != null && metricHistDTO.getStatus().equals(status))
.collect(Collectors.toList());
//5. 整合数据
//5. 整合数据(按状态、时间区间重叠合并,并计算持续时间)
runningEvaluateStatusVO.setProblemStatusList(buildProblemStatusList(filteredList));
//1天时间每5分钟一个时间点列表 ["00:15", "00:30" ... ]
runningEvaluateStatusVO.setTimeList(TimeArrayUtil.getMinuteSectionArray(5));
return runningEvaluateStatusVO;
......@@ -604,14 +605,13 @@ public class RunningEvaluateServiceImpl implements RunningEvaluateService {
}
}
List<RunningEvaluateMetricsDetailVO.ProblemStatus> buildProblemStatusList(
List<MetricHistDTO> metricHistDTOList) {
List<RunningEvaluateMetricsDetailVO.ProblemStatus> buildProblemStatusList(List<MetricHistDTO> metricHistDTOList) {
List<RunningEvaluateMetricsDetailVO.ProblemStatus> res = new ArrayList<>();
// 验证数据是否正确
//1. 验证数据是否正确
if (!isDataValid(metricHistDTOList)) {
return res;
}
// 根据持续时长去重
//2. 分组,并找出最大持续时长,最终获取最大持续时长的数据DTO
List<MetricHistDTO> uniqueList = metricHistDTOList.stream()
.collect(Collectors.groupingBy(
MetricHistDTO::getStartTime, // 按startTime分组
......@@ -623,20 +623,23 @@ public class RunningEvaluateServiceImpl implements RunningEvaluateService {
))
.values().stream().collect(Collectors.toList()); // 从Map中获取值并收集到新的列表中
//3. 循环最大持续时长的数据DTO集合
// 设置状态,开始时间,结束时间,持续时长
for (MetricHistDTO metricHistDTO : uniqueList) {
RunningEvaluateMetricsDetailVO.ProblemStatus problemStatus =
new RunningEvaluateMetricsDetailVO.ProblemStatus();
RunningEvaluateMetricsDetailVO.ProblemStatus problemStatus = new RunningEvaluateMetricsDetailVO.ProblemStatus();
Integer status1 = metricHistDTO.getStatus();
problemStatus.setStatus(status1);
Date startTime1 = metricHistDTO.getStartTime();
problemStatus.setStartTime(startTime1);
Integer duration1 = metricHistDTO.getDuration();
Date startTime1 = metricHistDTO.getStartTime();
DateTime endTime = DateUtil.offsetMinute(startTime1, duration1);
problemStatus.setEndTime(endTime);
problemStatus.setDurationMinutes(duration1);
problemStatus.setStatus(status1);//状态
problemStatus.setStartTime(startTime1);//开始时间
problemStatus.setEndTime(endTime);//结束时间
problemStatus.setDurationMinutes(duration1);//持续时长
res.add(problemStatus);
}
//4. 按状态和开始时间排序
// 合并时间区间
// 先按 status 排序,status 相同再按 startTime 排序
List<RunningEvaluateMetricsDetailVO.ProblemStatus> sortedList = res.stream()
......@@ -647,14 +650,22 @@ public class RunningEvaluateServiceImpl implements RunningEvaluateService {
List<RunningEvaluateMetricsDetailVO.ProblemStatus> mergedList = new ArrayList<>();
RunningEvaluateMetricsDetailVO.ProblemStatus current = sortedList.get(0);
//5. 合并时间区间(同一个状态,时间区间重叠的要合并,并计算新的持续时长)
/*
初始化current为排序后列表的第一个元素。
遍历剩余元素,逐一与current比较:
如果current和next的状态相同且时间区间重叠(即current.getEndTime()不早于next.getStartTime()),则合并两者:
更新current的结束时间为两者结束时间的较大值。
重新计算current的持续时长。
如果不重叠,则将current添加到mergedList中,并将current更新为next。
最后,将最后一个current添加到mergedList中。
*/
for (int i = 1; i < sortedList.size(); i++) {
RunningEvaluateMetricsDetailVO.ProblemStatus next = sortedList.get(i);
if (Objects.equals(current.getStatus(), next.getStatus())
&& !current.getEndTime().before(next.getStartTime())) {
// 如果有交叉,则合并记录
if (Objects.equals(current.getStatus(), next.getStatus()) && !current.getEndTime().before(next.getStartTime())) {
// 如果时间有交叉,则合并记录
current.setEndTime(new Date(Math.max(current.getEndTime().getTime(), next.getEndTime().getTime())));
current.setDurationMinutes(
(int) ((current.getEndTime().getTime() - current.getStartTime().getTime()) / (60 * 1000)));
current.setDurationMinutes((int) ((current.getEndTime().getTime() - current.getStartTime().getTime()) / (60 * 1000)));
} else {
// 否则,将当前记录添加到结果列表中,并更新当前记录
mergedList.add(current);
......
......@@ -76,9 +76,8 @@ public class SceneEvaluateServiceImpl implements SceneEvaluateService {
SceneEvaluateAbnormalDistributeVO vo = new SceneEvaluateAbnormalDistributeVO();
//日期,状态分布(路口状态:0正常;1失衡;2拥堵;3溢出;4死锁;5空放)
List<SceneEvaluateAbnormalDistributeVO.TimeDistribution> timeDistributionList =
buildTimeDistributionList(crossId, startDate, endDate);
//每一天对应的状态列表 (路口状态:0正常;1失衡;2拥堵;3溢出;4死锁;5空放)
List<SceneEvaluateAbnormalDistributeVO.TimeDistribution> timeDistributionList = buildTimeDistributionList(crossId, startDate, endDate);
vo.setTimeDateDistributionList(buildTimeDateDistributionList(timeDistributionList));
......@@ -1336,34 +1335,42 @@ public class SceneEvaluateServiceImpl implements SceneEvaluateService {
vo.setEmptyReleaseDuration(emptyReleaseDuration/60);
}
private List<SceneEvaluateAbnormalDistributeVO.TimeDistribution> buildTimeDistributionList(
String crossId, Date startDate, Date endDate) {
private List<SceneEvaluateAbnormalDistributeVO.TimeDistribution> buildTimeDistributionList(String crossId, Date startDate, Date endDate) {
//返回结果
List<SceneEvaluateAbnormalDistributeVO.TimeDistribution> res = new ArrayList<>();
//1. 参数初始化
Calendar start = Calendar.getInstance();
Calendar end = Calendar.getInstance();
start.setTime(startDate);
end.setTime(endDate);
// 使 endDate 包含在内
// 设置开始和结束日期,并将结束日期加一天以包含整个时间段
end.add(Calendar.DATE, 1);
//2. 遍历从开始日期到结束日期的每一天。
for (Date date = start.getTime(); start.before(end); start.add(Calendar.DATE, 1), date = start.getTime()) {
SceneEvaluateAbnormalDistributeVO.TimeDistribution timeDistribution =
new SceneEvaluateAbnormalDistributeVO.TimeDistribution();
SceneEvaluateAbnormalDistributeVO.TimeDistribution timeDistribution = new SceneEvaluateAbnormalDistributeVO.TimeDistribution();
// 每一天
timeDistribution.setProblemDate(date);
// 获取问题列表
// 路口级别全量数据
Calendar partEnd = (Calendar) start.clone();
partEnd.add(Calendar.DAY_OF_MONTH, 1);
//2.1 查询路口级数据,条件时间范围和路口ID
// int startStamp = (int)(start.getTimeInMillis() / 1000);
// int endStamp = (int)(partEnd.getTimeInMillis() / 1000);
String startTime = DateUtil.format(startDate, "yyyy-MM-dd HH:mm:ss");
String endTime = DateUtil.format(endDate, "yyyy-MM-dd HH:mm:ss");
List<MetricHistDTO> crossDTOList = crossDataHistMapper.selectMetricHistDTO2(crossId, startTime, endTime);
// 过滤有问题的记录
//2.2 过滤有问题的记录
List<MetricHistDTO> filteredList = crossDTOList.stream()
.filter(metricHistDTO -> metricHistDTO.getStatus() != null && !metricHistDTO.getStatus().equals(0))
.collect(Collectors.toList());
//2.3 整合数据 (路口状态(如拥堵、溢出等),开始时间HH:mm,结束时间HH:mm,持续时间)
timeDistribution.setProblemStatusList(runningEvaluateService.buildProblemStatusList(filteredList));
res.add(timeDistribution);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment