Browse Source

Merge remote-tracking branch 'origin/develop' into develop

develop
wangsixiang 6 months ago
parent
commit
17302d0464
  1. 6
      zc-business/src/main/java/com/zc/business/controller/DcEventProcessController.java
  2. 62
      zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java
  3. 5
      zc-business/src/main/java/com/zc/business/domain/DcEvent.java
  4. 4
      zc-business/src/main/java/com/zc/business/domain/DcEventProcess.java
  5. 5
      zc-business/src/main/java/com/zc/business/mapper/DcGantryMetricsStatisticsDataMapper.java
  6. 12
      zc-business/src/main/java/com/zc/business/mapper/DcGantryStatisticsDataMapper.java
  7. 7
      zc-business/src/main/java/com/zc/business/service/IDcGantryMetricsStatisticsDataService.java
  8. 6
      zc-business/src/main/java/com/zc/business/service/IDcGantryStatisticsDataService.java
  9. 20
      zc-business/src/main/java/com/zc/business/service/impl/DcEventServiceImpl.java
  10. 47
      zc-business/src/main/java/com/zc/business/service/impl/DcGantryStatisticsDataImpl.java
  11. 52
      zc-business/src/main/java/com/zc/business/service/impl/DcTrafficStatisticsServiceImpl.java
  12. 273
      zc-business/src/main/java/com/zc/business/service/impl/IDcGantryMetricsStatisticsDataServiceImpl.java
  13. 31
      zc-business/src/main/resources/mapper/business/DcGantryMetricsStatisticsDataMapper.xml
  14. 93
      zc-business/src/main/resources/mapper/business/DcGantryStatisticsDataMapper.xml
  15. 2
      zc-business/src/main/resources/mapper/business/DcTrafficIncidentsMapper.xml

6
zc-business/src/main/java/com/zc/business/controller/DcEventProcessController.java

@ -4,6 +4,7 @@ import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.exception.file.InvalidExtensionException;
@ -104,8 +105,11 @@ public class DcEventProcessController extends BaseController
// @PreAuthorize("@ss.hasPermi('system:process:add')")
@Log(title = "事件处理流程", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody DcEventProcess dcEventProcess){
public AjaxResult add(@RequestBody @Valid DcEventProcess dcEventProcess){
DcEvent dcEvent = dcEventService.selectDcEventById(dcEventProcess.getEventId());
if (dcEvent == null){
return AjaxResult.error("事件信息有误!");
}
if (dcEvent.getEventState() == 2){
return AjaxResult.error("事件已结束,无法进行操作!");
}

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

@ -162,6 +162,25 @@ public class DcTrafficStatisticsController {
// 将查询结果封装为成功响应并返回
return AjaxResult.success(dcStatisticsData);
}
/**
* 交通流统计 列表
* @param startDate
* @param endDate
* @param direction
* @param periodType
* @return
*/
@ApiOperation("交通流统计")
@GetMapping("/history/trafficFlowStatistics")
public AjaxResult trafficFlowStatistics(String startDate, String endDate,String direction,String periodType){
List<Map<String,String>> mapList = dcGantryStatisticsDataService.trafficFlowStatistics(startDate,endDate,direction,periodType);
// 将查询结果封装为成功响应并返回
return AjaxResult.success(mapList);
}
/**
* 全路段双向实时车流量
* @param startDate 时间
@ -175,6 +194,49 @@ public AjaxResult realTimeTrafficFlow(String startDate, String direction,String
// 将查询结果封装为成功响应并返回
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,Long 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-
* 3-
*/
@Excel(name = "方向", readConverterExp = "1=菏泽方向,3=济南方向")
@Excel(name = "方向")
//@Excel(name = "方向")
@ApiModelProperty("方向")
private String direction;
@ -69,6 +69,7 @@ public class DcEvent {
@ApiModelProperty("处理人员")
private Long userId;
@Excel(name = "事件子类")
@ApiModelProperty("事件子类")
private String eventSubclassName;
@ -136,7 +137,7 @@ public class DcEvent {
* 3-3 立交封闭和限行
* 3-4 服务区封闭和限行
*/
@Excel(name = "事件类型字符串")
@ApiModelProperty("事件子类 例:事件子类:* 1-1 追尾* 1-2 侧翻* 1-3 撞护栏* 1-4 自然* 1-5 其他事故* 2-1 车辆故障")
private String eventSubclass;

4
zc-business/src/main/java/com/zc/business/domain/DcEventProcess.java

@ -9,7 +9,9 @@ import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
/**
* 事件处理流程对象 dc_event_process
@ -28,6 +30,7 @@ public class DcEventProcess
/** $column.columnComment */
@ApiModelProperty(value="事件ID")
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
@NotBlank(message = "事件ID不能为空")
private String eventId;
/** $column.columnComment */
@ -73,6 +76,7 @@ public class DcEventProcess
/** $column.columnComment */
@ApiModelProperty("内容")
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
@Size(max = 500, message = "内容不能超过500个字符")
private String context;
/** $column.type */

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

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

@ -45,5 +45,17 @@ 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, Object>> trafficPeriodAnalysis(@Param("startDate") String startDate, @Param("direction")String direction, @Param("periodType")String periodType);
/**
* 交通流统计 列表
* @param startDate
* @param endDate
* @param direction
* @param periodType
* @return
*/
List<Map<String, String>> trafficFlowStatistics(@Param("startDate")String startDate, @Param("endDate")String endDate, @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 java.util.List;
import java.util.Map;
/**
* 门架指标统计服务接口提供处理交通数据的相关方法
@ -39,4 +40,10 @@ public interface IDcGantryMetricsStatisticsDataService extends IService<DcGantry
* @return 门架指标统计数据列表
*/
List<DcGantryMetricsStatisticsData> gantryMetricsData(DcGantryMetricsStatisticsData request);
List<Map<String, Object>> sectionTrafficIndexAnalysis(String startDate, String direction, String periodType,Long 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>> trafficPeriodAnalysis(String startDate, String direction, String periodType);
List<Map<String, String>> trafficFlowStatistics(String startDate, String endDate, String direction, String periodType);
}

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

@ -102,9 +102,11 @@ public class DcEventServiceImpl extends ServiceImpl<DcEventMapper, DcEvent> impl
@Override
public DcEvent selectDcEventById(String id) {
DcEvent dcEvent = dcEventMapper.selectDcEventById(id);
if (dcEvent != null){
List<DcProcessConfig> processConfigList = dcProcessConfigMapper.selectDcProcessConfigByEventType(Math.toIntExact(dcEvent.getEventType()));
dcEvent.setProcessConfigList(processConfigList);
}
return dcEvent;
}
@ -229,9 +231,7 @@ public class DcEventServiceImpl extends ServiceImpl<DcEventMapper, DcEvent> impl
dcEvent.getDcEventAccident().setId(uuid);
int i1 = dcEventAccidentMapper.insertDcEventAccident(dcEvent.getDcEventAccident());
if (dcEvent.getEventState() ==1){
updateDcEventState(uuid,1);//直接确认
}
}
break;
//车辆事故
@ -239,9 +239,6 @@ public class DcEventServiceImpl extends ServiceImpl<DcEventMapper, DcEvent> impl
if (dcEvent.getDcEventVehicleAccident() != null) {
dcEvent.getDcEventVehicleAccident().setId(uuid);
int i5 = dcEventVehicleAccidentMapper.insertDcEventVehicleAccident(dcEvent.getDcEventVehicleAccident());
if (dcEvent.getEventState() ==1){
updateDcEventState(uuid,1);//直接确认
}
}
break;
//交通管制
@ -870,7 +867,10 @@ public class DcEventServiceImpl extends ServiceImpl<DcEventMapper, DcEvent> impl
}
}
*/
//桩号校验
if (!com.ruoyi.common.utils.StakeMarkUtils.checkStakeMark(dcEvent.getStakeMark())) {
return -1;
}
// 事件子类校验
for (EventSubclass value : EventSubclass.values()) {
if (value.getDescription().equals(dcEvent.getEventSubclass())) {
@ -1224,10 +1224,10 @@ public class DcEventServiceImpl extends ServiceImpl<DcEventMapper, DcEvent> impl
return 1;
}
//事件状态已被修改 返回成功
/* //事件状态已被修改 返回成功
if (dcEvent1.getEventState() == 1) {
return 1;
}
}*/
int i = dcEventMapper.updateDcEventState(id, state);

47
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.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
/**
* 门架数据统计服务实现类
@ -206,4 +206,45 @@ public class DcGantryStatisticsDataImpl extends ServiceImpl<DcGantryStatisticsDa
public List<Map<String, String>> realTimeTrafficFlow(String startDate, String direction, String 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;
}
@Override
public List<Map<String, String>> trafficFlowStatistics(String startDate, String endDate, String direction, String periodType) {
return dcGantryStatisticsDataMapper.trafficFlowStatistics(startDate,endDate,direction,periodType);
}
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;
}
/**
*
* @param startDate
* @param direction
* @return
* @throws HttpException
* @throws IOException
*/
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 List<Map<String, Object>> realTimeTrafficFlowHour2(String startDate,Long direction) throws HttpException, IOException {
OkHttp okHttp = new OkHttp();
@ -851,26 +865,4 @@ public class DcTrafficStatisticsServiceImpl implements IDcTrafficStatisticsServi
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 "";
}
}

273
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.ruoyi.common.exception.ServiceException;
import com.zc.business.domain.DcGantryMetricsStatisticsData;
import com.zc.business.domain.DcGantryStatisticsData;
import com.zc.business.enums.ChannelCongestionLevelEnum;
import com.zc.business.enums.StakeMarkRange;
import com.zc.business.enums.TrafficCompositionRateEnum;
import com.zc.business.enums.TrafficDataPeriodTypeEnum;
import com.zc.business.mapper.DcGantryMetricsStatisticsDataMapper;
@ -28,9 +28,11 @@ import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 门架指标统计服务实现类负责处理实时设备消息缓存数据定时任务以及数据保存等功能
@ -162,6 +164,229 @@ public class IDcGantryMetricsStatisticsDataServiceImpl
return list(queryWrapper);
}
/**
* 路段交通指标分析
*
* @param startDate
* @param direction
* @param periodType
* @return
*/
@Override
public List<Map<String, Object>> sectionTrafficIndexAnalysis(String startDate, String direction, String periodType, Long 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位小数
Double formattedAvgSaturationRate = Double.valueOf(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 !=null){
if (ranking == 1) {
mapList.sort(Comparator.comparingDouble(map -> Double.parseDouble(((Map<String, Object>) map).get("saturationRate").toString())).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 +497,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"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<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 INTO
@ -74,4 +84,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
update_time = NOW()
</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>

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

@ -7,6 +7,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="volume" column="total_traffic_volume"/>
<result property="name" column="interval_name"/>
</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>
<resultMap type="map" id="trafficFlowStatisticsMap">
<result property="intervalName" column="interval_name"/>
<result property="stakeMake" column="stake_make"/>
<result property="endMake" column="end_make"/>
<result property="facilityCode" column="facility_code"/>
<result property="direction" column="direction"/>
<result property="statisticalDate" column="statistical_date"/>
<result property="facilityName" column="facility_name"/>
<result property="trafficVolume" column="traffic_volume"/>
<result property="periodType" column="period_type"/>
</resultMap>
<!-- 插入或更新交通路段数据 -->
<insert id="insertOrUpdate" parameterType="com.zc.business.domain.DcGantryStatisticsData">
INSERT INTO
@ -213,4 +232,78 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</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>
<select id="trafficFlowStatistics" resultMap="trafficFlowStatisticsMap" resultType="map" >
SELECT
i.interval_name,
i.stake_make ,
i.end_make,
ps.facility_code ,
ps.facility_name ,
ps.direction ,
dgsd.traffic_volume ,
dgsd.statistical_date,
dgsd.period_type
FROM
(
SELECT 'K054+394' AS stake_make, 'K059+289' AS end_make, '殷家林枢纽-大学城立交' AS interval_name UNION ALL
SELECT 'K059+289', 'K072+847', '大学城立交-长清立交' UNION ALL
SELECT 'K072+847', 'K083+835', '长清立交-松竹枢纽' UNION ALL
SELECT 'K083+835', 'K086+499', '松竹枢纽-孝里立交' UNION ALL
SELECT 'K086+499', 'K099+750', '孝里立交-平阴北立交' UNION ALL
SELECT 'K099+750', 'K105+904', '平阴北立交-平阴立交' UNION ALL
SELECT 'K105+904', 'K117+878', '平阴立交-孔村枢纽' UNION ALL
SELECT 'K117+878', 'K126+233', '孔村枢纽-平阴南立交' UNION ALL
SELECT 'K126+233', 'K145+933', '平阴南立交-东平立交' UNION ALL
SELECT 'K145+933', 'K155+652', '东平立交-东平湖枢纽' UNION ALL
SELECT 'K155+652', 'K173+950', '东平湖枢纽-梁山东立交' UNION ALL
SELECT 'K173+950', 'K179+396', '梁山东立交-梁山立交' UNION ALL
SELECT 'K179+396', 'K190+495', '梁山立交-嘉祥西立交' UNION ALL
SELECT 'K190+495', 'K202+979', '嘉祥西立交'
) AS i
JOIN dc_facility AS ps
ON ps.stake_mark BETWEEN CONCAT(i.stake_make, '+0') AND CONCAT(i.end_make, '+0')
<if test="direction != null">
AND ps.direction = #{direction}
</if>
JOIN dc_gantry_statistics_data AS dgsd
ON ps.facility_code = dgsd.gantry_code
AND DATE(dgsd.statistical_date) BETWEEN #{startDate} AND #{endDate}
<if test="periodType != null">
AND dgsd.period_type = #{periodType}
</if>
ORDER BY
dgsd.statistical_date DESC;
</select>
</mapper>

2
zc-business/src/main/resources/mapper/business/DcTrafficIncidentsMapper.xml

@ -57,7 +57,7 @@
<select id="selectTrafficIncidentsAllProcessing" resultType="java.lang.Long">
select count(*) from dc_event
where event_state != '2'
where event_state = '1'
</select>
<select id="selectEventTypeList" resultType="java.util.Map">

Loading…
Cancel
Save