Browse Source

路段交通指标分析。 交通指标时间分布,交通指标排名,交通指标雷达图

develop
王兴琳 6 months ago
parent
commit
078cf73791
  1. 43
      zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java
  2. 5
      zc-business/src/main/java/com/zc/business/domain/DcEvent.java
  3. 5
      zc-business/src/main/java/com/zc/business/mapper/DcGantryMetricsStatisticsDataMapper.java
  4. 2
      zc-business/src/main/java/com/zc/business/mapper/DcGantryStatisticsDataMapper.java
  5. 7
      zc-business/src/main/java/com/zc/business/service/IDcGantryMetricsStatisticsDataService.java
  6. 6
      zc-business/src/main/java/com/zc/business/service/IDcGantryStatisticsDataService.java
  7. 11
      zc-business/src/main/java/com/zc/business/service/impl/DcEventServiceImpl.java
  8. 42
      zc-business/src/main/java/com/zc/business/service/impl/DcGantryStatisticsDataImpl.java
  9. 52
      zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java
  10. 270
      zc-business/src/main/java/com/zc/business/service/impl/IDcGantryMetricsStatisticsDataServiceImpl.java
  11. 31
      zc-business/src/main/resources/mapper/business/DcGantryMetricsStatisticsDataMapper.xml
  12. 38
      zc-business/src/main/resources/mapper/business/DcGantryStatisticsDataMapper.xml

43
zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java

@ -175,6 +175,49 @@ public AjaxResult realTimeTrafficFlow(String startDate, String direction,String
// 将查询结果封装为成功响应并返回 // 将查询结果封装为成功响应并返回
return AjaxResult.success(mapList); return AjaxResult.success(mapList);
} }
/**
* 车流量时段分析
* @param startDate 时间
* @param direction 方向
* @param periodType 时间粒子
*/
@ApiOperation("车流量时段分析")
@GetMapping("/history/trafficPeriodAnalysis")
public AjaxResult trafficPeriodAnalysis(String startDate, String direction,String periodType ){
List<Map<String,String>> mapList = dcGantryStatisticsDataService.trafficPeriodAnalysis(startDate,direction,periodType);
// 将查询结果封装为成功响应并返回
return AjaxResult.success(mapList);
}
/**
* sectionTrafficIndexAnalysis
* @param startDate 时间
* @param direction 方向
* @param periodType 时间粒子
* @param ranking 排名 1 饱和度 2拥挤度 3交通特征指数
*
*/
@ApiOperation("路段交通指标分析")
@GetMapping("/history/sectionTrafficIndexAnalysis")
public AjaxResult sectionTrafficIndexAnalysis(String startDate, String direction,String periodType,int ranking ){
List<Map<String, Object>> mapList = dcGantryMetricsStatisticsDataService.sectionTrafficIndexAnalysis(startDate,direction,periodType,ranking);
// 将查询结果封装为成功响应并返回
return AjaxResult.success(mapList);
}
@ApiOperation("通指标时间分布")
@GetMapping("/history/passIndicatorTimeDistribution")
public AjaxResult passIndicatorTimeDistribution(String startDate, String direction,String periodType ){
List<Map<String, Object>> mapList = dcGantryMetricsStatisticsDataService.passIndicatorTimeDistribution(startDate,direction,periodType);
// 将查询结果封装为成功响应并返回
return AjaxResult.success(mapList);
}
@ApiOperation("交通指标雷达图")
@GetMapping("/history/radarMapOfTrafficIndicators")
public AjaxResult radarMapOfTrafficIndicators(String startDate, String direction,String periodType ){
Map<String, Object> map = dcGantryMetricsStatisticsDataService.radarMapOfTrafficIndicators(startDate,direction,periodType);
// 将查询结果封装为成功响应并返回
return AjaxResult.success(map);
}
/** /**

5
zc-business/src/main/java/com/zc/business/domain/DcEvent.java

@ -58,7 +58,7 @@ public class DcEvent {
* 2- * 2-
* 3- * 3-
*/ */
@Excel(name = "方向", readConverterExp = "1=菏泽方向,3=济南方向") @Excel(name = "方向")
//@Excel(name = "方向") //@Excel(name = "方向")
@ApiModelProperty("方向") @ApiModelProperty("方向")
private String direction; private String direction;
@ -69,6 +69,7 @@ public class DcEvent {
@ApiModelProperty("处理人员") @ApiModelProperty("处理人员")
private Long userId; private Long userId;
@Excel(name = "事件子类")
@ApiModelProperty("事件子类") @ApiModelProperty("事件子类")
private String eventSubclassName; private String eventSubclassName;
@ -136,7 +137,7 @@ public class DcEvent {
* 3-3 立交封闭和限行 * 3-3 立交封闭和限行
* 3-4 服务区封闭和限行 * 3-4 服务区封闭和限行
*/ */
@Excel(name = "事件类型字符串")
@ApiModelProperty("事件子类 例:事件子类:* 1-1 追尾* 1-2 侧翻* 1-3 撞护栏* 1-4 自然* 1-5 其他事故* 2-1 车辆故障") @ApiModelProperty("事件子类 例:事件子类:* 1-1 追尾* 1-2 侧翻* 1-3 撞护栏* 1-4 自然* 1-5 其他事故* 2-1 车辆故障")
private String eventSubclass; private String eventSubclass;

5
zc-business/src/main/java/com/zc/business/mapper/DcGantryMetricsStatisticsDataMapper.java

@ -3,8 +3,10 @@ package com.zc.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zc.business.domain.DcGantryMetricsStatisticsData; import com.zc.business.domain.DcGantryMetricsStatisticsData;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 门架指标数据统计Mapper接口 * 门架指标数据统计Mapper接口
@ -29,4 +31,7 @@ public interface DcGantryMetricsStatisticsDataMapper extends BaseMapper<DcGantry
* @return 影响的记录数通常对于批量操作这个值可能不准确因为每个 INSERT/UPDATE 可能影响不同的记录数 * @return 影响的记录数通常对于批量操作这个值可能不准确因为每个 INSERT/UPDATE 可能影响不同的记录数
*/ */
int insertOrUpdateBatch(List<DcGantryMetricsStatisticsData> gantryTrafficMetricsDataList); int insertOrUpdateBatch(List<DcGantryMetricsStatisticsData> gantryTrafficMetricsDataList);
List<Map<String, Object>> sectionTrafficIndexAnalysis(@Param("startDate") String startDate, @Param("direction") String direction,@Param("periodType") String periodType);
} }

2
zc-business/src/main/java/com/zc/business/mapper/DcGantryStatisticsDataMapper.java

@ -45,5 +45,7 @@ public interface DcGantryStatisticsDataMapper extends BaseMapper<DcGantryStatist
* 全路段双向实时车流量 * 全路段双向实时车流量
*/ */
List<Map<String, String>> realTimeTrafficFlow(@Param("startDate") String startDate, @Param("direction")String direction, @Param("periodType")String periodType ); List<Map<String, String>> realTimeTrafficFlow(@Param("startDate") String startDate, @Param("direction")String direction, @Param("periodType")String periodType );
List<Map<String, Object>> trafficPeriodAnalysis(@Param("startDate") String startDate, @Param("direction")String direction, @Param("periodType")String periodType);
} }

7
zc-business/src/main/java/com/zc/business/service/IDcGantryMetricsStatisticsDataService.java

@ -6,6 +6,7 @@ import com.zc.business.domain.DcGantryMetricsStatisticsData;
import com.zc.business.domain.DcGantryMetricsStatisticsData; import com.zc.business.domain.DcGantryMetricsStatisticsData;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 门架指标统计服务接口提供处理交通数据的相关方法 * 门架指标统计服务接口提供处理交通数据的相关方法
@ -39,4 +40,10 @@ public interface IDcGantryMetricsStatisticsDataService extends IService<DcGantry
* @return 门架指标统计数据列表 * @return 门架指标统计数据列表
*/ */
List<DcGantryMetricsStatisticsData> gantryMetricsData(DcGantryMetricsStatisticsData request); List<DcGantryMetricsStatisticsData> gantryMetricsData(DcGantryMetricsStatisticsData request);
List<Map<String, Object>> sectionTrafficIndexAnalysis(String startDate, String direction, String periodType,int ranking);
List<Map<String, Object>> passIndicatorTimeDistribution(String startDate, String direction, String periodType);
Map<String, Object> radarMapOfTrafficIndicators(String startDate, String direction, String periodType);
} }

6
zc-business/src/main/java/com/zc/business/service/IDcGantryStatisticsDataService.java

@ -47,5 +47,11 @@ public interface IDcGantryStatisticsDataService extends IService<DcGantryStatist
* 全路段双向实时车流量 * 全路段双向实时车流量
*/ */
List<Map<String, String>> realTimeTrafficFlow(String startDate, String direction,String periodType ); List<Map<String, String>> realTimeTrafficFlow(String startDate, String direction,String periodType );
/**
* 车流量时段分析
*/
List<Map<String, String>> trafficPeriodAnalysis(String startDate, String direction, String periodType);
} }

11
zc-business/src/main/java/com/zc/business/service/impl/DcEventServiceImpl.java

@ -229,9 +229,7 @@ public class DcEventServiceImpl extends ServiceImpl<DcEventMapper, DcEvent> impl
dcEvent.getDcEventAccident().setId(uuid); dcEvent.getDcEventAccident().setId(uuid);
int i1 = dcEventAccidentMapper.insertDcEventAccident(dcEvent.getDcEventAccident()); int i1 = dcEventAccidentMapper.insertDcEventAccident(dcEvent.getDcEventAccident());
if (dcEvent.getEventState() ==1){
updateDcEventState(uuid,1);//直接确认
}
} }
break; break;
//车辆事故 //车辆事故
@ -239,9 +237,6 @@ public class DcEventServiceImpl extends ServiceImpl<DcEventMapper, DcEvent> impl
if (dcEvent.getDcEventVehicleAccident() != null) { if (dcEvent.getDcEventVehicleAccident() != null) {
dcEvent.getDcEventVehicleAccident().setId(uuid); dcEvent.getDcEventVehicleAccident().setId(uuid);
int i5 = dcEventVehicleAccidentMapper.insertDcEventVehicleAccident(dcEvent.getDcEventVehicleAccident()); int i5 = dcEventVehicleAccidentMapper.insertDcEventVehicleAccident(dcEvent.getDcEventVehicleAccident());
if (dcEvent.getEventState() ==1){
updateDcEventState(uuid,1);//直接确认
}
} }
break; break;
//交通管制 //交通管制
@ -1224,10 +1219,10 @@ public class DcEventServiceImpl extends ServiceImpl<DcEventMapper, DcEvent> impl
return 1; return 1;
} }
//事件状态已被修改 返回成功 /* //事件状态已被修改 返回成功
if (dcEvent1.getEventState() == 1) { if (dcEvent1.getEventState() == 1) {
return 1; return 1;
} }*/
int i = dcEventMapper.updateDcEventState(id, state); int i = dcEventMapper.updateDcEventState(id, state);

42
zc-business/src/main/java/com/zc/business/service/impl/DcGantryStatisticsDataImpl.java

@ -21,9 +21,9 @@ import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Date; import java.time.LocalDateTime;
import java.util.List; import java.util.*;
import java.util.Map; import java.util.stream.Collectors;
/** /**
* 门架数据统计服务实现类 * 门架数据统计服务实现类
@ -206,4 +206,40 @@ public class DcGantryStatisticsDataImpl extends ServiceImpl<DcGantryStatisticsDa
public List<Map<String, String>> realTimeTrafficFlow(String startDate, String direction, String periodType ) { public List<Map<String, String>> realTimeTrafficFlow(String startDate, String direction, String periodType ) {
return dcGantryStatisticsDataMapper.realTimeTrafficFlow(startDate,direction,periodType); return dcGantryStatisticsDataMapper.realTimeTrafficFlow(startDate,direction,periodType);
} }
/**
* 车流量时段分析
*/
@Override
public List<Map<String, String>> trafficPeriodAnalysis(String startDate, String direction, String periodType) {
List<Map<String, Object>> mapList = dcGantryStatisticsDataMapper.trafficPeriodAnalysis(startDate, direction, periodType);
List<Map<String, String>> aggregatedList = aggregateTrafficVolume(mapList);
return aggregatedList;
}
public List<Map<String, String>> aggregateTrafficVolume(List<Map<String, Object>> dataList) {
// 创建一个Map,用于存储整点时间的流量数据
Map<Integer, Integer> aggregatedData = new HashMap<>();
// 遍历接口返回的数据列表
for (Map<String, Object> data : dataList) {
LocalDateTime statisticalDate = (LocalDateTime) data.get("statisticalDate");
int hour = statisticalDate.getHour();
// 获取该整点时间的流量数据并累加
int trafficVolume = (int) data.get("trafficVolume");
aggregatedData.put(hour,
aggregatedData.getOrDefault(hour, 0) + trafficVolume);
}
// 将整点时间的流量数据重新构建为列表
List<Map<String, String>> aggregatedList = new ArrayList<>();
for (Map.Entry<Integer, Integer> entry : aggregatedData.entrySet()) {
Map<String, String> aggregatedItem = new HashMap<>();
aggregatedItem.put("statisticalHour", String.valueOf(entry.getKey())); // 整点时间
aggregatedItem.put("trafficVolume", String.valueOf(entry.getValue())); // 流量数据
aggregatedList.add(aggregatedItem);
}
return aggregatedList;
}
} }

52
zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java

@ -778,14 +778,28 @@ public class DcTrafficStatisticsServiceImpl implements IDcTrafficStatisticsServi
return null; return null;
} }
/**
* private static String extract(String input) {
* @param startDate Pattern pattern = Pattern.compile("K(\\d{3})\\+(\\d{3})");
* @param direction Matcher matcher = pattern.matcher(input);
* @return
* @throws HttpException if (matcher.find()) {
* @throws IOException String part1 = matcher.group(1);
*/ String part2 = matcher.group(2);
// 直接拼接两部分数字,无需格式化,这样得到的字符串自然没有前导零
return part1 + part2;
} else {
return "N/A";
}
}
public static String getDescriptionByIdentification(int identification) {
for (StakeMarkRange range : StakeMarkRange.values()) {
if (range.getIdentification() == identification) {
return range.getDescription();
}
}
return "";
}
public List<Map<String, Object>> realTimeTrafficFlowHour2(String startDate,Long direction) throws HttpException, IOException { public List<Map<String, Object>> realTimeTrafficFlowHour2(String startDate,Long direction) throws HttpException, IOException {
OkHttp okHttp = new OkHttp(); OkHttp okHttp = new OkHttp();
@ -851,26 +865,4 @@ public class DcTrafficStatisticsServiceImpl implements IDcTrafficStatisticsServi
return new ArrayList(); return new ArrayList();
} }
private static String extract(String input) {
Pattern pattern = Pattern.compile("K(\\d{3})\\+(\\d{3})");
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
String part1 = matcher.group(1);
String part2 = matcher.group(2);
// 直接拼接两部分数字,无需格式化,这样得到的字符串自然没有前导零
return part1 + part2;
} else {
return "N/A";
}
}
public static String getDescriptionByIdentification(int identification) {
for (StakeMarkRange range : StakeMarkRange.values()) {
if (range.getIdentification() == identification) {
return range.getDescription();
}
}
return "";
}
} }

270
zc-business/src/main/java/com/zc/business/service/impl/IDcGantryMetricsStatisticsDataServiceImpl.java

@ -8,8 +8,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.zc.business.domain.DcGantryMetricsStatisticsData; import com.zc.business.domain.DcGantryMetricsStatisticsData;
import com.zc.business.domain.DcGantryStatisticsData;
import com.zc.business.enums.ChannelCongestionLevelEnum; import com.zc.business.enums.ChannelCongestionLevelEnum;
import com.zc.business.enums.StakeMarkRange;
import com.zc.business.enums.TrafficCompositionRateEnum; import com.zc.business.enums.TrafficCompositionRateEnum;
import com.zc.business.enums.TrafficDataPeriodTypeEnum; import com.zc.business.enums.TrafficDataPeriodTypeEnum;
import com.zc.business.mapper.DcGantryMetricsStatisticsDataMapper; import com.zc.business.mapper.DcGantryMetricsStatisticsDataMapper;
@ -28,9 +28,11 @@ import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.time.LocalDateTime;
import java.util.Date; import java.util.*;
import java.util.List; import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/** /**
* 门架指标统计服务实现类负责处理实时设备消息缓存数据定时任务以及数据保存等功能 * 门架指标统计服务实现类负责处理实时设备消息缓存数据定时任务以及数据保存等功能
@ -162,6 +164,226 @@ public class IDcGantryMetricsStatisticsDataServiceImpl
return list(queryWrapper); return list(queryWrapper);
} }
/**
* 路段交通指标分析
*
* @param startDate
* @param direction
* @param periodType
* @return
*/
@Override
public List<Map<String, Object>> sectionTrafficIndexAnalysis(String startDate, String direction, String periodType, int ranking) {
List<Map<String, Object>> mapListOne = gantryMetricsStatisticsDataMapper.sectionTrafficIndexAnalysis(startDate, direction, periodType);
List<Map<String, Object>> mapList = new ArrayList<>();
Map<Integer, List<Map<String, Object>>> result = mapListOne.stream()
.collect(Collectors.groupingBy(map -> {
String stakeMark = map.get("stakeMark").toString();
int extractedNumber = Integer.parseInt(extract(stakeMark));
return Arrays.stream(StakeMarkRange.values())
.filter(smRange -> extractedNumber >= smRange.getStakeMark() && extractedNumber <= smRange.getEndMark())
.mapToInt(StakeMarkRange::getIdentification)
.findFirst()
.orElse(0);
}));
// 处理每个组
for (Map.Entry<Integer, List<Map<String, Object>>> entry : result.entrySet()) {
Integer groupId = entry.getKey();
List<Map<String, Object>> groupData = entry.getValue();
// 计算crowdingRate和trafficCompositionRate的众数,以及saturationRate的平均值
int[] rates = {0, 0}; // 用于存储众数,第一个元素为crowdingRate众数,第二个为trafficCompositionRate众数
float sumSaturationRate = 0;
int count = groupData.size();
String id = "";
Map<Integer, Integer> crowdingRateCounts = new HashMap<>();
Map<Integer, Integer> trafficCompositionRateCounts = new HashMap<>();
for (Map<String, Object> item : groupData) {
Integer crowdingRate = (Integer) item.get("crowdingRate");
Integer trafficCompositionRate = (Integer) item.get("trafficCompositionRate");
Float saturationRate = (Float) item.get("saturationRate");
id = (String) item.get("id");
// Double saturationRate = (Double) item.get("saturationRate");
sumSaturationRate += saturationRate;
crowdingRateCounts.put(crowdingRate, crowdingRateCounts.getOrDefault(crowdingRate, 0) + 1);
trafficCompositionRateCounts.put(trafficCompositionRate, trafficCompositionRateCounts.getOrDefault(trafficCompositionRate, 0) + 1);
}
// 找到众数
rates[0] = findMaxCountKey(crowdingRateCounts);
rates[1] = findMaxCountKey(trafficCompositionRateCounts);
// 计算平均saturationRate
double avgSaturationRate = count > 0 ? sumSaturationRate / count : 0;
// 格式化保留4位小数
String formattedAvgSaturationRate = String.format("%.4f", avgSaturationRate);
Map<String, Object> map = new HashMap<>();
String description = getDescriptionByIdentification(groupId);
map.put("groupId", groupId);
map.put("Id", id);
map.put("groupName", description);
map.put("crowdingRate", rates[0]);
map.put("trafficCompositionRate", rates[1]);
map.put("saturationRate", formattedAvgSaturationRate);
mapList.add(map);
// System.out.println("集团: " + groupId);
// System.out.println("拥堵度" + rates[0]);
// System.out.println("交通组成特征指数" + rates[1]);
// System.out.println("平均饱和度:" + formattedAvgSaturationRate);
}
if (ranking == 1) {
mapList.sort(Comparator.comparingInt(map -> (Integer) ((Map<String, Object>) map).get("saturationRate")).reversed());
}
if (ranking == 2) {
mapList.sort(Comparator.comparingInt(map -> (Integer) ((Map<String, Object>) map).get("crowdingRate")).reversed());
}
if (ranking == 3) {
mapList.sort(Comparator.comparingInt(map -> (Integer) ((Map<String, Object>) map).get("trafficCompositionRate")).reversed());
}
return mapList;
}
/**
* 交通指标时间分布
*
* @param startDate
* @param direction
* @param periodType
* @return
*/
@Override
public List<Map<String, Object>> passIndicatorTimeDistribution(String startDate, String direction, String periodType) {
List<Map<String, Object>> mapList = gantryMetricsStatisticsDataMapper.sectionTrafficIndexAnalysis(startDate, direction, periodType);
List<Map<String, Object>> mapTime = new ArrayList<>();
// 使用 Java流按照相同时间分组
Map<LocalDateTime, List<Map<String, Object>>> result = mapList.stream()
.collect(Collectors.groupingBy(
map -> (LocalDateTime) map.get("statisticalDate"),
Collectors.toList()
));
// 处理每个组
for (Map.Entry<LocalDateTime, List<Map<String, Object>>> entry : result.entrySet()) {
LocalDateTime groupId = entry.getKey();
List<Map<String, Object>> groupData = entry.getValue();
// 计算crowdingRate和trafficCompositionRate的众数,以及saturationRate的平均值
int[] rates = {0, 0}; // 用于存储众数,第一个元素为crowdingRate众数,第二个为trafficCompositionRate众数
float sumSaturationRate = 0;
int count = groupData.size();
String id = "";
Map<Integer, Integer> crowdingRateCounts = new HashMap<>();
Map<Integer, Integer> trafficCompositionRateCounts = new HashMap<>();
for (Map<String, Object> item : groupData) {
Integer crowdingRate = (Integer) item.get("crowdingRate");
Integer trafficCompositionRate = (Integer) item.get("trafficCompositionRate");
Float saturationRate = (Float) item.get("saturationRate");
id = (String) item.get("id");
// Double saturationRate = (Double) item.get("saturationRate");
sumSaturationRate += saturationRate;
crowdingRateCounts.put(crowdingRate, crowdingRateCounts.getOrDefault(crowdingRate, 0) + 1);
trafficCompositionRateCounts.put(trafficCompositionRate, trafficCompositionRateCounts.getOrDefault(trafficCompositionRate, 0) + 1);
}
// 找到众数
rates[0] = findMaxCountKey(crowdingRateCounts);
rates[1] = findMaxCountKey(trafficCompositionRateCounts);
// 计算平均saturationRate
double avgSaturationRate = count > 0 ? sumSaturationRate / count : 0;
// 格式化保留4位小数
String formattedAvgSaturationRate = String.format("%.4f", avgSaturationRate);
Map<String, Object> map = new HashMap<>();
map.put("groupTime", groupId);
map.put("Id", id);
map.put("crowdingRate", rates[0]);
map.put("trafficCompositionRate", rates[1]);
map.put("saturationRate", formattedAvgSaturationRate);
mapTime.add(map);
}
// 输出结果
result.forEach((date, data) -> {
System.out.println("统计日期:" + date);
data.forEach(entry -> {
entry.forEach((key, value) -> {
System.out.println(key + ": " + value);
});
});
});
return mapTime;
}
/**
* 交通指标雷达图
* @param startDate
* @param direction
* @param periodType
* @return
*/
@Override
public Map<String, Object> radarMapOfTrafficIndicators(String startDate, String direction, String periodType) {
List<Map<String, Object>> mapOne = gantryMetricsStatisticsDataMapper.sectionTrafficIndexAnalysis(startDate, direction, periodType);
// 计算crowdingRate和trafficCompositionRate的众数,以及saturationRate的平均值
int[] rates = {0, 0}; // 用于存储众数,第一个元素为crowdingRate众数,第二个为trafficCompositionRate众数
float sumSaturationRate = 0;
int count = mapOne.size();
Map<Integer, Integer> crowdingRateCounts = new HashMap<>();
Map<Integer, Integer> trafficCompositionRateCounts = new HashMap<>();
for (Map<String, Object> item : mapOne) {
Integer crowdingRate = (Integer) item.get("crowdingRate");
Integer trafficCompositionRate = (Integer) item.get("trafficCompositionRate");
Float saturationRate = (Float) item.get("saturationRate");
// Double saturationRate = (Double) item.get("saturationRate");
sumSaturationRate += saturationRate;
crowdingRateCounts.put(crowdingRate, crowdingRateCounts.getOrDefault(crowdingRate, 0) + 1);
trafficCompositionRateCounts.put(trafficCompositionRate, trafficCompositionRateCounts.getOrDefault(trafficCompositionRate, 0) + 1);
}
// 找到众数
rates[0] = findMaxCountKey(crowdingRateCounts);
rates[1] = findMaxCountKey(trafficCompositionRateCounts);
// 计算平均saturationRate
double avgSaturationRate = count > 0 ? sumSaturationRate / count : 0;
// 格式化保留4位小数
String formattedAvgSaturationRate = String.format("%.4f", avgSaturationRate);
Map<String, Object> map = new HashMap<>();
map.put("crowdingRate", rates[0]);
map.put("trafficCompositionRate", rates[1]);
map.put("saturationRate", formattedAvgSaturationRate);
return map;
}
private static int findMaxCountKey(Map<Integer, Integer> counts) {
// 初始化一个 Pair 类型来存储当前的最大计数及对应的键
Pair<Integer, Integer> maxPair = null;
for (Map.Entry<Integer, Integer> entry : counts.entrySet()) {
if (maxPair == null || entry.getValue() > maxPair.getValue() ||
(entry.getValue().equals(maxPair.getValue()) && entry.getKey() > maxPair.getKey())) {
maxPair = new Pair<>(entry.getKey(), entry.getValue());
}
}
// 确保maxPair不为null,这里假设输入的counts非空且至少有一个元素
return maxPair.getKey();
}
/** /**
* 恢复小时缓存数据的方法 * 恢复小时缓存数据的方法
* 该方法首先会获取当前月份的门架入口数据 * 该方法首先会获取当前月份的门架入口数据
@ -272,4 +494,44 @@ public class IDcGantryMetricsStatisticsDataServiceImpl
} }
private static String extract(String input) {
Pattern pattern = Pattern.compile("K(\\d{3})\\+(\\d{3})");
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
String part1 = matcher.group(1);
String part2 = matcher.group(2);
// 直接拼接两部分数字,无需格式化,这样得到的字符串自然没有前导零
return part1 + part2;
} else {
return "N/A";
}
}
public static String getDescriptionByIdentification(int identification) {
for (StakeMarkRange range : StakeMarkRange.values()) {
if (range.getIdentification() == identification) {
return range.getDescription();
}
}
return "";
}
public static class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
} }

31
zc-business/src/main/resources/mapper/business/DcGantryMetricsStatisticsDataMapper.xml

@ -3,7 +3,17 @@
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zc.business.mapper.DcGantryMetricsStatisticsDataMapper"> <mapper namespace="com.zc.business.mapper.DcGantryMetricsStatisticsDataMapper">
<resultMap type="map" id="countMap">
<result property="id" column="id"/>
<result property="facilityName" column="facility_name"/>
<result property="stakeMark" column="stake_mark"/>
<result property="direction" column="direction"/>
<result property="gantryCode" column="gantry_code"/>
<result property="trafficCompositionRate" column="traffic_composition_rate"/>
<result property="crowdingRate" column="crowding_rate"/>
<result property="saturationRate" column="saturation_rate"/>
<result property="statisticalDate" column="statistical_date"/>
</resultMap>
<!-- 插入或更新门架指标数据 --> <!-- 插入或更新门架指标数据 -->
<insert id="insertOrUpdate" parameterType="com.zc.business.domain.DcGantryMetricsStatisticsData"> <insert id="insertOrUpdate" parameterType="com.zc.business.domain.DcGantryMetricsStatisticsData">
INSERT INTO INSERT INTO
@ -74,4 +84,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
update_time = NOW() update_time = NOW()
</insert> </insert>
<select id="sectionTrafficIndexAnalysis" resultMap="countMap" resultType="map" >
SELECT fa.facility_name,
fa.stake_mark,
fa.direction,
dg.statistical_date,
dg.gantry_code,
dg.id,
dg.traffic_composition_rate,
dg.crowding_rate,
dg.saturation_rate
FROM dc_gantry_metrics_statistics_data as dg
LEFT JOIN dc_facility as fa on fa.facility_code = dg.gantry_code
WHERE DATE(dg.statistical_date) = #{startDate}
AND fa.direction = #{direction}
AND dg.period_type = #{periodType}
</select>
</mapper> </mapper>

38
zc-business/src/main/resources/mapper/business/DcGantryStatisticsDataMapper.xml

@ -7,6 +7,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="volume" column="total_traffic_volume"/> <result property="volume" column="total_traffic_volume"/>
<result property="name" column="interval_name"/> <result property="name" column="interval_name"/>
</resultMap> </resultMap>
<resultMap type="map" id="trafficPeriodAnalysisMap">
<result property="gantryCode" column="gantry_code"/>
<result property="trafficVolume" column="traffic_volume"/>
<result property="facilityName" column="facility_name"/>
<result property="stakeMark" column="stake_mark"/>
<result property="direction" column="direction"/>
<result property="statisticalDate" column="statistical_date"/>
</resultMap>
<!-- 插入或更新交通路段数据 --> <!-- 插入或更新交通路段数据 -->
<insert id="insertOrUpdate" parameterType="com.zc.business.domain.DcGantryStatisticsData"> <insert id="insertOrUpdate" parameterType="com.zc.business.domain.DcGantryStatisticsData">
INSERT INTO INSERT INTO
@ -213,4 +221,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select> </select>
<select id="trafficPeriodAnalysis" resultMap="trafficPeriodAnalysisMap" resultType="map" >
SELECT
dg.gantry_code,
dg.traffic_volume,
fa.facility_name,
fa.stake_mark,
fa.direction,
dg.statistical_date
FROM
dc_gantry_statistics_data AS dg
LEFT JOIN
dc_facility AS fa
ON
fa.facility_code = dg.gantry_code
WHERE
<if test="periodType == 1">
YEAR(dg.statistical_date) = #{startDate}
</if>
<if test="periodType == 2">
DATE_FORMAT(dg.statistical_date, '%Y-%m') = #{startDate}
</if>
<if test="periodType == 4">
DATE(dg.statistical_date) = DATE(#{startDate})
</if>
AND fa.direction = #{direction}
AND dg.period_type = '5'
</select>
</mapper> </mapper>

Loading…
Cancel
Save