Browse Source

解决交通特征指标接口存储的问题

develop
xiepufeng 8 months ago
parent
commit
fd7e87457d
  1. 2
      zc-business/src/main/java/com/zc/business/domain/DcTrafficMetricsData.java
  2. 2
      zc-business/src/main/java/com/zc/business/enums/ChannelCongestionLevelEnum.java
  3. 3
      zc-business/src/main/java/com/zc/business/request/DcTrafficMetricsDataRequest.java
  4. 38
      zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java
  5. 15
      zc-business/src/main/java/com/zc/business/statistics/handler/TrafficAnalysis.java

2
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;
/**

2
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;
}
}

3
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;
/**

38
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<DcTrafficSectionData> dcTrafficSectionDataCaches = getDcTrafficSectionDataRedisCache(request.getDirection());
// 过滤掉时间错误的交通数据
processStaleTrafficSectionData(dcTrafficSectionDataCaches);
// 根据请求过滤交通数据
List<DcTrafficSectionData> trafficSectionDataList = filterTrafficDataByRequest(request, dcTrafficSectionDataCaches);
@ -189,7 +194,10 @@ public class DcTrafficStatisticsServiceImpl
LambdaQueryWrapper<DcTrafficSectionData> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.between(DcTrafficSectionData::getStatisticalDate, request.getStartTime(), request.getEndTime());
queryWrapper.eq(DcTrafficSectionData::getPeriodType, request.getPeriodType());
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<DcTrafficSectionData> 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; // 保留该元素
});
}
/**
* 根据方向获取交通数据
*

15
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<DcTrafficSectionData> dcTrafficSectionList = sectionDataMap.putIfAbsent(dcRoadSection.getId(), new ArrayList<>());
List<DcTrafficSectionData> dcTrafficSectionList = sectionDataMap.computeIfAbsent(dcRoadSection.getId(), k -> new ArrayList<>());
dcTrafficSectionList.add(trafficSectionData);
}
}

Loading…
Cancel
Save