diff --git a/zc-business/src/main/java/com/zc/business/domain/DcTrafficMetricsData.java b/zc-business/src/main/java/com/zc/business/domain/DcTrafficMetricsData.java index 3fee49b5..09297c7c 100644 --- a/zc-business/src/main/java/com/zc/business/domain/DcTrafficMetricsData.java +++ b/zc-business/src/main/java/com/zc/business/domain/DcTrafficMetricsData.java @@ -1,5 +1,6 @@ package com.zc.business.domain; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import java.util.Date; @@ -39,6 +40,7 @@ public class DcTrafficMetricsData { /** * 统计时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") private Date statisticalDate; /** diff --git a/zc-business/src/main/java/com/zc/business/enums/ChannelCongestionLevelEnum.java b/zc-business/src/main/java/com/zc/business/enums/ChannelCongestionLevelEnum.java index 24922754..770b96ad 100644 --- a/zc-business/src/main/java/com/zc/business/enums/ChannelCongestionLevelEnum.java +++ b/zc-business/src/main/java/com/zc/business/enums/ChannelCongestionLevelEnum.java @@ -69,7 +69,7 @@ public enum ChannelCongestionLevelEnum { */ public static ChannelCongestionLevelEnum fromSpeed(int speed) { for (ChannelCongestionLevelEnum level : values()) { - if (speed > level.speedThreshold) { + if (speed >= level.speedThreshold) { return level; } } diff --git a/zc-business/src/main/java/com/zc/business/request/DcTrafficMetricsDataRequest.java b/zc-business/src/main/java/com/zc/business/request/DcTrafficMetricsDataRequest.java index 0e60621e..d5030b8d 100644 --- a/zc-business/src/main/java/com/zc/business/request/DcTrafficMetricsDataRequest.java +++ b/zc-business/src/main/java/com/zc/business/request/DcTrafficMetricsDataRequest.java @@ -1,6 +1,7 @@ package com.zc.business.request; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; @@ -30,11 +31,13 @@ public class DcTrafficMetricsDataRequest { /** * 开始时间 */ + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date startTime; /** * 结束时间 */ + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date endTime; /** diff --git a/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java b/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java index 5924c2b6..1caca7d6 100644 --- a/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java +++ b/zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java @@ -30,6 +30,8 @@ import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.io.IOException; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; @@ -152,6 +154,9 @@ public class DcTrafficStatisticsServiceImpl // 从Redis缓存中获取指定方向的交通路段数据列表 List dcTrafficSectionDataCaches = getDcTrafficSectionDataRedisCache(request.getDirection()); + // 过滤掉时间错误的交通数据 + processStaleTrafficSectionData(dcTrafficSectionDataCaches); + // 根据请求过滤交通数据 List trafficSectionDataList = filterTrafficDataByRequest(request, dcTrafficSectionDataCaches); @@ -189,7 +194,10 @@ public class DcTrafficStatisticsServiceImpl LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.between(DcTrafficSectionData::getStatisticalDate, request.getStartTime(), request.getEndTime()); queryWrapper.eq(DcTrafficSectionData::getPeriodType, request.getPeriodType()); - queryWrapper.eq(DcTrafficSectionData::getDirection, request.getDirection()); + + if (request.getDirection() != null) { + queryWrapper.eq(DcTrafficSectionData::getDirection, request.getDirection()); + } // 根据请求获取所属路段ID,并进一步筛选路段范围内的数据 Long roadSectionId = request.getRoadSectionId(); @@ -329,6 +337,36 @@ public class DcTrafficStatisticsServiceImpl return new ArrayList<>(dcTrafficSectionDataMap.values()); } + /** + * 过滤掉时间错误的交通路段数据,并更新数据的统计时间为当前时间。 + * 该方法会遍历交通路段数据列表,移除统计时间早于20分钟前的数据,并将其它数据的统计时间更新为当前时间。 + * + * @param dcTrafficSectionDataList 交通路段数据列表,列表中每一项包含一个交通路段的统计数据。 + */ + public void processStaleTrafficSectionData(List dcTrafficSectionDataList) { + // 计算20分钟前的时间戳 + Instant twentyMinutesAgo = Instant.now().minus(20, ChronoUnit.MINUTES); + // 获取当前时间 + Instant currentTime = Instant.now(); + + // 遍历交通路段数据列表 + dcTrafficSectionDataList.removeIf(data -> { + // 获取数据的统计时间 + Instant dataStatisticalTime = data.getStatisticalDate().toInstant(); + + // 如果数据的统计时间早于20分钟前,则移除该数据,并记录日志 + if (dataStatisticalTime.isBefore(twentyMinutesAgo)) { + logger.error("过滤掉时间错误的交通路段数据,已移除:" + data); + return true; // 移除该元素 + } + + // 更新数据的统计时间为当前时间 + data.setStatisticalDate(Date.from(currentTime)); // 直接使用Instant对象 + return false; // 保留该元素 + }); + } + + /** * 根据方向获取交通数据 * diff --git a/zc-business/src/main/java/com/zc/business/statistics/handler/TrafficAnalysis.java b/zc-business/src/main/java/com/zc/business/statistics/handler/TrafficAnalysis.java index 1be1f17c..7ce8ddc1 100644 --- a/zc-business/src/main/java/com/zc/business/statistics/handler/TrafficAnalysis.java +++ b/zc-business/src/main/java/com/zc/business/statistics/handler/TrafficAnalysis.java @@ -303,9 +303,6 @@ public class TrafficAnalysis { return (int) Math.round(averageSaturationDegree); } - - - /** * 计算路段饱和度 * @@ -423,14 +420,16 @@ public class TrafficAnalysis { // 遍历排序后的路段数据,计算每个路段的拥堵里程,并累加到总拥堵里程中 for (DcTrafficSectionData dcTrafficSectionData : sortedList) { + int averageSpeed = dcTrafficSectionData.getAverageSpeed(); int stakeMark = dcTrafficSectionData.getStakeMark(); // 对于不拥堵的路段,累加之前计算的默认拥堵距离 - if (!ChannelCongestionLevelEnum.isMediumOrSevereCongestion(averageSpeed)) { + if (!ChannelCongestionLevelEnum.isMediumOrSevereCongestion(averageSpeed) || dcTrafficSectionData.getTrafficVolume() == 0) { totalCongestionDistance.addAndGet(defaultCongestionDistance); previousStakeMark = stakeMark; defaultCongestionDistance = 0; + previousAverageSpeed = 0; continue; } @@ -447,12 +446,18 @@ public class TrafficAnalysis { // 如果当前路段被计算过,则累加拥堵路段数量 congestedSectionQuantity.addAndGet(1); } + } else { + // 如果之前没有计算过任何路段,则直接累加默认拥堵距离 + totalCongestionDistance.addAndGet(defaultCongestionDistance); + // 累加拥堵路段数量 + congestedSectionQuantity.addAndGet(1); } // 更新辅助变量以备后续计算 previousStakeMark = stakeMark; previousAverageSpeed = averageSpeed; } + }); // 计算并返回路网整体的拥堵指数 @@ -624,7 +629,7 @@ public class TrafficAnalysis { // 如果找到对应的路段,则将交通数据添加到该路段的数据列表中。 if (index > -1) { DcRoadSection dcRoadSection = sortedRoadSections.get(index); - List dcTrafficSectionList = sectionDataMap.putIfAbsent(dcRoadSection.getId(), new ArrayList<>()); + List dcTrafficSectionList = sectionDataMap.computeIfAbsent(dcRoadSection.getId(), k -> new ArrayList<>()); dcTrafficSectionList.add(trafficSectionData); } }