Commit d1cee43b authored by hanbing's avatar hanbing

[add] 新信号评价-干线评价-底部曲线图

parent 7fea895d
package net.wanji.opt.bo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* @author Kent HAN
* @date 2023/6/9 13:52
*/
@Data
@ApiModel(value = "BottomCurveBO", description = "底部曲线图")
public class BottomCurveBO {
@ApiModelProperty(value = "路口ID")
private String crossId;
@ApiModelProperty(value = "范围 0路口 1进口道 2方向 3车道")
private Integer scope;
@ApiModelProperty(value = "范围列表")
List<String> scopeList;
@ApiModelProperty(value = "时间粒度(分钟)")
private Integer minutes;
@ApiModelProperty(value = "指标编号")
private String metricCode;
@ApiModelProperty(value = "开始时间 格式 yyyy-MM-dd HH:mm")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
private Date startTime;
@ApiModelProperty(value = "结束时间 格式 yyyy-MM-dd HH:mm")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
private Date endTime;
}
...@@ -5,14 +5,17 @@ import io.swagger.annotations.ApiOperation; ...@@ -5,14 +5,17 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses; import io.swagger.annotations.ApiResponses;
import net.wanji.common.framework.rest.JsonViewObject; import net.wanji.common.framework.rest.JsonViewObject;
import net.wanji.opt.bo.BottomCurveBO;
import net.wanji.opt.bo.BottomMenuBO; import net.wanji.opt.bo.BottomMenuBO;
import net.wanji.opt.service.impl.MainlineEvaluateServiceImpl; import net.wanji.opt.service.impl.MainlineEvaluateServiceImpl;
import net.wanji.opt.vo.MainlineEvaluateBottomCurveVO;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import java.text.ParseException;
import java.util.List; import java.util.List;
@Api(value = "MainlineEvaluateController", description = "干线评价") @Api(value = "MainlineEvaluateController", description = "干线评价")
...@@ -38,4 +41,15 @@ public class MainlineEvaluateController { ...@@ -38,4 +41,15 @@ public class MainlineEvaluateController {
return JsonViewObject.newInstance().success(res); return JsonViewObject.newInstance().success(res);
} }
@ApiOperation(value = "底部曲线图", notes = "底部曲线图", response = JsonViewObject.class,
produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
@PostMapping(value = "/bottomCurve",
produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
@ApiResponses({
@ApiResponse(code = 200, message = "OK", response = MainlineEvaluateBottomCurveVO.class),
})
public JsonViewObject bottomCurve(@RequestBody BottomCurveBO bo) throws ParseException {
List<MainlineEvaluateBottomCurveVO> res = mainlineEvaluateService.bottomCurve(bo);
return JsonViewObject.newInstance().success(res);
}
} }
\ No newline at end of file
package net.wanji.opt.service; package net.wanji.opt.service;
import net.wanji.opt.bo.BottomCurveBO;
import net.wanji.opt.bo.BottomMenuBO; import net.wanji.opt.bo.BottomMenuBO;
import net.wanji.opt.vo.MainlineEvaluateBottomCurveVO;
import java.text.ParseException;
import java.util.List; import java.util.List;
public interface MainlineEvaluateService { public interface MainlineEvaluateService {
List<String> bottomMenu(BottomMenuBO bo); List<String> bottomMenu(BottomMenuBO bo);
List<MainlineEvaluateBottomCurveVO> bottomCurve(BottomCurveBO bo) throws ParseException;
} }
...@@ -2,21 +2,21 @@ package net.wanji.opt.service.impl; ...@@ -2,21 +2,21 @@ package net.wanji.opt.service.impl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.wanji.common.enums.BaseEnum; import net.wanji.common.enums.BaseEnum;
import net.wanji.common.enums.StrategyAndMetricsEnum;
import net.wanji.common.enums.TurnConvertEnum; import net.wanji.common.enums.TurnConvertEnum;
import net.wanji.databus.dao.entity.BaseCrossDirInfoPO; import net.wanji.databus.dao.entity.BaseCrossDirInfoPO;
import net.wanji.databus.dao.mapper.BaseCrossDirInfoMapper; import net.wanji.databus.dao.mapper.*;
import net.wanji.databus.dao.mapper.BaseCrossTurnInfoMapper; import net.wanji.databus.po.*;
import net.wanji.databus.dao.mapper.CrossBaseLaneInfoMapper; import net.wanji.opt.bo.BottomCurveBO;
import net.wanji.databus.dao.mapper.LaneInfoMapper;
import net.wanji.databus.po.CrossTurnInfoPO;
import net.wanji.databus.po.LaneInfoPO;
import net.wanji.opt.bo.BottomMenuBO; import net.wanji.opt.bo.BottomMenuBO;
import net.wanji.opt.service.MainlineEvaluateService; import net.wanji.opt.service.MainlineEvaluateService;
import net.wanji.opt.vo.MainlineEvaluateBottomCurveVO;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.text.ParseException;
import java.util.List; import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -29,13 +29,26 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -29,13 +29,26 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
private final BaseCrossDirInfoMapper baseCrossDirInfoMapper; private final BaseCrossDirInfoMapper baseCrossDirInfoMapper;
private final BaseCrossTurnInfoMapper baseCrossTurnInfoMapper; private final BaseCrossTurnInfoMapper baseCrossTurnInfoMapper;
private final LaneInfoMapper laneInfoMapper; private final LaneInfoMapper laneInfoMapper;
private final CrossDirDataHistMapper crossDirDataHistMapper;
private final CrossDataHistMapper crossDataHistMapper;
private final CrossTurnDataHistMapper crossTurnDataHistMapper;
private final CrossLaneDataHistMapper crossLaneDataHistMapper;
SimpleDateFormat hourMinuteFormat = new SimpleDateFormat("HH:mm");
SimpleDateFormat dateHourMinuteFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
public MainlineEvaluateServiceImpl(@Qualifier("baseCrossDirInfoMapper") BaseCrossDirInfoMapper baseCrossDirInfoMapper, public MainlineEvaluateServiceImpl(@Qualifier("baseCrossDirInfoMapper") BaseCrossDirInfoMapper baseCrossDirInfoMapper,
@Qualifier("baseCrossTurnInfoMapper") BaseCrossTurnInfoMapper baseCrossTurnInfoMapper, @Qualifier("baseCrossTurnInfoMapper") BaseCrossTurnInfoMapper baseCrossTurnInfoMapper,
CrossBaseLaneInfoMapper crossBaseLaneInfoMapper, @Qualifier("laneInfoMapper") LaneInfoMapper laneInfoMapper) { CrossBaseLaneInfoMapper crossBaseLaneInfoMapper,
@Qualifier("laneInfoMapper") LaneInfoMapper laneInfoMapper,
CrossDirDataHistMapper crossDirDataHistMapper, CrossDataHistMapper crossDataHistMapper, CrossTurnDataHistMapper crossTurnDataHistMapper, CrossLaneDataHistMapper crossLaneDataHistMapper) {
this.baseCrossDirInfoMapper = baseCrossDirInfoMapper; this.baseCrossDirInfoMapper = baseCrossDirInfoMapper;
this.baseCrossTurnInfoMapper = baseCrossTurnInfoMapper; this.baseCrossTurnInfoMapper = baseCrossTurnInfoMapper;
this.laneInfoMapper = laneInfoMapper; this.laneInfoMapper = laneInfoMapper;
this.crossDirDataHistMapper = crossDirDataHistMapper;
this.crossDataHistMapper = crossDataHistMapper;
this.crossTurnDataHistMapper = crossTurnDataHistMapper;
this.crossLaneDataHistMapper = crossLaneDataHistMapper;
} }
@Override @Override
...@@ -54,6 +67,449 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -54,6 +67,449 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
return null; return null;
} }
@Override
public List<MainlineEvaluateBottomCurveVO> bottomCurve(BottomCurveBO bo) throws ParseException {
String crossId = bo.getCrossId();
Integer scope = bo.getScope();
List<String> scopeList = bo.getScopeList();
Integer minutes = bo.getMinutes();
String metricCode = bo.getMetricCode();
Date startTime = bo.getStartTime();
Date endTime = bo.getEndTime();
if (scope != 1 && Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.LOAD_BALANCE.getCode())) {
throw new RuntimeException("只有路口级别可选择负载均衡度");
}
List<String> timeList = buildTimeList(startTime, endTime, minutes);
List<MainlineEvaluateBottomCurveVO> res = new ArrayList<>();
int startTimeStamp = (int)(startTime.getTime() / 1000);
int endTimeStamp = (int)(endTime.getTime() / 1000);
if (scope == 0) { // 路口
// 查询路口该时段内的所有数据
List<CrossDataHistPO> crossPOList = crossDataHistMapper.selectByCrossIdAndStartEnd(
crossId, startTimeStamp, endTimeStamp);
for (String timeStr : timeList) {
Date startDatetime = calcDate(timeStr, startTime);
MainlineEvaluateBottomCurveVO vo = new MainlineEvaluateBottomCurveVO();
vo.setMetricTime(timeStr);
// 计算 endDatetime
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDatetime);
calendar.add(Calendar.MINUTE, minutes);
Date endDatetime = calendar.getTime();
// 转换为 10 位时间戳
int startTimeStampPart = (int)(startDatetime.getTime() / 1000);
int endTimeStampPart = (int)(endDatetime.getTime() / 1000);
// 使用流式编程进行筛选
List<CrossDataHistPO> filteredList = crossPOList.stream()
.filter(po -> po.getBatchTime() >= startTimeStampPart && po.getBatchTime() <= endTimeStampPart)
.collect(Collectors.toList());
if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.NO_STOP_RATE.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDataHistPO::getNoStopRate)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.STOP_RATE.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDataHistPO::getOneStopRate)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.AVERAGE_DELAY.getCode())) {
double v = filteredList.stream()
.mapToInt(CrossDataHistPO::getDelayTime)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.MAX_QUEUE_LENGTH.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDataHistPO::getQueueLength)
.max()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.STOP_TIMES.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDataHistPO::getStopTimes)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.AVERAGE_SPEED.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDataHistPO::getSpeed)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.GREEN_LIGHT_EFFICIENCY.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDataHistPO::getGreenLightEfficiency)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.SATURATION.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDataHistPO::getSturation)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.LOAD_BALANCE.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDataHistPO::getLoadBalance)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
}
res.add(vo);
}
} else if (scope == 1) { // 进口道
// 查询各进口道该时段内的所有数据
List<CrossDirDataHistPO> dirPOList = crossDirDataHistMapper.selectByCrossIdAndStartEnd(
crossId, startTimeStamp, endTimeStamp);
for (String timeStr : timeList) {
Date startDatetime = calcDate(timeStr, startTime);
for (String dirStr : scopeList) {
int index = dirStr.indexOf("进口");
String dirName = dirStr.substring(0, index);
Integer dirCode = BaseEnum.SignalDirectionEnum.getCodeByName(dirName);
MainlineEvaluateBottomCurveVO vo = new MainlineEvaluateBottomCurveVO();
vo.setMetricTime(timeStr);
vo.setScopeName(dirStr);
// 计算 endDatetime
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDatetime);
calendar.add(Calendar.MINUTE, minutes);
Date endDatetime = calendar.getTime();
// 转换为 10 位时间戳
int startTimeStampPart = (int)(startDatetime.getTime() / 1000);
int endTimeStampPart = (int)(endDatetime.getTime() / 1000);
// 使用流式编程进行筛选
List<CrossDirDataHistPO> filteredList = dirPOList.stream()
.filter(po -> po.getDirType().equals(dirCode))
.filter(po -> po.getInOutType().equals(1))
.filter(po -> po.getBatchTime() >= startTimeStampPart
&& po.getBatchTime() <= endTimeStampPart)
.collect(Collectors.toList());
if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.NO_STOP_RATE.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDirDataHistPO::getNoStopRate)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.STOP_RATE.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDirDataHistPO::getOneStopRate)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.AVERAGE_DELAY.getCode())) {
double v = filteredList.stream()
.mapToInt(CrossDirDataHistPO::getDelayTime)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.MAX_QUEUE_LENGTH.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDirDataHistPO::getQueueLength)
.max()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.STOP_TIMES.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDirDataHistPO::getStopTimes)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.AVERAGE_SPEED.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDirDataHistPO::getSpeed)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.GREEN_LIGHT_EFFICIENCY.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDirDataHistPO::getGreenLightEfficiency)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.SATURATION.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossDirDataHistPO::getSturation)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
}
res.add(vo);
}
}
} else if (scope == 2) { // 方向
// 查询各方向该时段内的所有数据
List<CrossTurnDataHistPO> dirPOList = crossTurnDataHistMapper.selectByCrossId (
crossId, endTimeStamp, startTimeStamp);
for (String timeStr : timeList) {
Date startDatetime = calcDate(timeStr, startTime);
for (String turnStr : scopeList) {
int index = turnStr.indexOf("进口");
String dirName = turnStr.substring(0, index);
Integer dirCode = BaseEnum.SignalDirectionEnum.getCodeByName(dirName);
String turnName = turnStr.substring(index + 2);
String turnCode = TurnConvertEnum.getCodeByDesc(turnName);
MainlineEvaluateBottomCurveVO vo = new MainlineEvaluateBottomCurveVO();
vo.setMetricTime(timeStr);
vo.setScopeName(turnStr);
// 计算 endDatetime
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDatetime);
calendar.add(Calendar.MINUTE, minutes);
Date endDatetime = calendar.getTime();
// 转换为 10 位时间戳
int startTimeStampPart = (int)(startDatetime.getTime() / 1000);
int endTimeStampPart = (int)(endDatetime.getTime() / 1000);
// 使用流式编程进行筛选
List<CrossTurnDataHistPO> filteredList = dirPOList.stream()
.filter(po -> po.getInDir().equals(dirCode))
.filter(po -> po.getTurnType().equals(turnCode))
.filter(po -> po.getBatchTime() >= startTimeStampPart
&& po.getBatchTime() <= endTimeStampPart)
.collect(Collectors.toList());
if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.NO_STOP_RATE.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossTurnDataHistPO::getNoStopRate)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.STOP_RATE.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossTurnDataHistPO::getOneStopRate)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.AVERAGE_DELAY.getCode())) {
double v = filteredList.stream()
.mapToInt(CrossTurnDataHistPO::getDelayTime)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.MAX_QUEUE_LENGTH.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossTurnDataHistPO::getQueueLength)
.max()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.STOP_TIMES.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossTurnDataHistPO::getStopTimes)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.AVERAGE_SPEED.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossTurnDataHistPO::getSpeed)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.GREEN_LIGHT_EFFICIENCY.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossTurnDataHistPO::getGreenLightEfficiency)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.SATURATION.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossTurnDataHistPO::getSturation)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
}
res.add(vo);
}
}
} else if (scope == 3) { // 车道
// 查询各车道该时段内的所有数据
List<CrossLaneDataHistPOExt> lanePOList = crossLaneDataHistMapper.selectByCrossId(
crossId, endTimeStamp, startTimeStamp);
for (String timeStr : timeList) {
Date startDatetime = calcDate(timeStr, startTime);
for (String laneStr : scopeList) {
int indexOfJinKou = laneStr.indexOf("进口");
int indexOfCheDao = laneStr.indexOf("车道");
// 截取"进口"之前的部分
String dirName = laneStr.substring(0, indexOfJinKou);
// 截取"车道"之前的数字部分
String laneSortStr = laneStr.substring(indexOfCheDao - 2, indexOfCheDao);
Integer dirCode = BaseEnum.SignalDirectionEnum.getCodeByName(dirName);
Integer laneSort = Integer.parseInt(laneSortStr);
MainlineEvaluateBottomCurveVO vo = new MainlineEvaluateBottomCurveVO();
vo.setMetricTime(timeStr);
vo.setScopeName(laneStr);
// 计算 endDatetime
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDatetime);
calendar.add(Calendar.MINUTE, minutes);
Date endDatetime = calendar.getTime();
// 转换为 10 位时间戳
int startTimeStampPart = (int)(startDatetime.getTime() / 1000);
int endTimeStampPart = (int)(endDatetime.getTime() / 1000);
// 筛选方向、车道序号
List<CrossLaneDataHistPOExt> filteredList = lanePOList.stream()
.filter(po -> po.getDir().equals(dirCode))
.filter(po -> po.getSort().equals(laneSort))
.filter(po -> po.getBatchTime() >= startTimeStampPart
&& po.getBatchTime() <= endTimeStampPart)
.collect(Collectors.toList());
if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.NO_STOP_RATE.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossLaneDataHistPOExt::getNoStopRate)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.STOP_RATE.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossLaneDataHistPOExt::getOneStopRate)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.AVERAGE_DELAY.getCode())) {
double v = filteredList.stream()
.mapToInt(CrossLaneDataHistPOExt::getDelayTime)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.MAX_QUEUE_LENGTH.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossLaneDataHistPOExt::getQueueLength)
.max()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.STOP_TIMES.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossLaneDataHistPOExt::getStopTimes)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.AVERAGE_SPEED.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossLaneDataHistPOExt::getSpeed)
.average()
.orElse(0.0);
int round = (int) (Math.round(v));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.GREEN_LIGHT_EFFICIENCY.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossLaneDataHistPOExt::getGreenLightEfficiency)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
} else if (Objects.equals(metricCode, StrategyAndMetricsEnum.Metrics.SATURATION.getCode())) {
double v = filteredList.stream()
.mapToDouble(CrossLaneDataHistPOExt::getSturation)
.average()
.orElse(0.0);
int round = (int) (Math.round(v * 100));
vo.setValue(round);
}
res.add(vo);
}
}
}
return res;
}
private Date calcDate(String timeStr, Date startTime) throws ParseException {
// 使用 Calendar 来获取年、月、日信息
Calendar calendar = Calendar.getInstance();
calendar.setTime(startTime);
// 使用 SimpleDateFormat 来获取时和分
Date time = hourMinuteFormat.parse(timeStr);
Calendar timeCal = Calendar.getInstance();
timeCal.setTime(time);
// 组合两者
calendar.set(Calendar.HOUR_OF_DAY, timeCal.get(Calendar.HOUR_OF_DAY));
calendar.set(Calendar.MINUTE, timeCal.get(Calendar.MINUTE));
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// 转换回 Date 对象
Date startDatetime = calendar.getTime();
return startDatetime;
}
private List<String> buildTimeList(Date startTime, Date endTime, Integer minutes) {
// 用于存储时间区间的列表
List<String> timeList = new ArrayList<>();
Calendar cal = Calendar.getInstance();
cal.setTime(startTime);
while (cal.getTime().before(endTime) || cal.getTime().equals(endTime)) {
String formattedTime = hourMinuteFormat.format(cal.getTime());
timeList.add(formattedTime);
// 增加指定分钟数
cal.add(Calendar.MINUTE, minutes);
}
return timeList;
}
public static String formatTime(int totalMinutes) {
int hours = totalMinutes / 60;
int minutes = totalMinutes % 60;
return String.format("%02d:%02d", hours, minutes);
}
private List<String> buildLaneMenu(String crossId) { private List<String> buildLaneMenu(String crossId) {
List<BaseCrossDirInfoPO> poList = baseCrossDirInfoMapper.selectByCrossId(crossId); List<BaseCrossDirInfoPO> poList = baseCrossDirInfoMapper.selectByCrossId(crossId);
List<BaseCrossDirInfoPO> dirList = poList.stream() List<BaseCrossDirInfoPO> dirList = poList.stream()
......
package net.wanji.opt.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author Kent HAN
* @date 2023/2/9 8:38
*/
@Data
@NoArgsConstructor
@ApiModel(value = "MainlineEvaluateBottomCurveVO", description = "底部曲线图")
public class MainlineEvaluateBottomCurveVO {
@ApiModelProperty(value = "时间")
private String metricTime;
@ApiModelProperty(value = "范围名称")
private String scopeName;
@ApiModelProperty(value = "数值")
private Integer value;
}
...@@ -152,6 +152,16 @@ public class BaseEnum { ...@@ -152,6 +152,16 @@ public class BaseEnum {
} }
return null; return null;
} }
public static Integer getCodeByName(String name) {
for (SignalDirectionEnum signalDirectionEnum : SignalDirectionEnum.values()) {
if (Objects.equals(signalDirectionEnum.getName(), name)) {
return signalDirectionEnum.getCode();
}
}
return null;
}
} }
@Getter @Getter
......
...@@ -76,6 +76,15 @@ public class StrategyAndMetricsEnum { ...@@ -76,6 +76,15 @@ public class StrategyAndMetricsEnum {
} }
return null; return null;
} }
public static Metrics getEnumByCode(String code) {
for (Metrics value : Metrics.values()) {
if (value.code.equals(code)) {
return value;
}
}
return null;
}
} }
public static final Map<Strategy, List<Metrics>> STRATEGY_METRICS_MAP; public static final Map<Strategy, List<Metrics>> STRATEGY_METRICS_MAP;
......
...@@ -100,4 +100,13 @@ public enum TurnConvertEnum { ...@@ -100,4 +100,13 @@ public enum TurnConvertEnum {
return res; return res;
} }
public static String getCodeByDesc(String desc){
for (TurnConvertEnum e : TurnConvertEnum.values()) {
if(e.desc.equals(desc)){
return e.code;
}
}
return null;
}
} }
...@@ -20,4 +20,6 @@ public interface CrossLaneDataHistMapper extends BaseMapper<CrossLaneDataHistPO> ...@@ -20,4 +20,6 @@ public interface CrossLaneDataHistMapper extends BaseMapper<CrossLaneDataHistPO>
void deleteBatch(@Param("list") Collection<String> crossIds); void deleteBatch(@Param("list") Collection<String> crossIds);
List<MetricHistDTO> selectMetricHistDTO(String crossId, int startStamp, int endStamp); List<MetricHistDTO> selectMetricHistDTO(String crossId, int startStamp, int endStamp);
List<CrossLaneDataHistPOExt> selectByCrossIdAndDir(String crossId, Integer dir, int endTimeStamp, int startTimeStamp); List<CrossLaneDataHistPOExt> selectByCrossIdAndDir(String crossId, Integer dir, int endTimeStamp, int startTimeStamp);
List<CrossLaneDataHistPOExt> selectByCrossId(String crossId, int endTimeStamp, int startTimeStamp);
} }
...@@ -74,4 +74,14 @@ ...@@ -74,4 +74,14 @@
AND batch_time <![CDATA[ >= ]]> #{startTimeStamp} AND batch_time <![CDATA[ >= ]]> #{startTimeStamp}
AND batch_time <![CDATA[ <= ]]> #{endTimeStamp}; AND batch_time <![CDATA[ <= ]]> #{endTimeStamp};
</select> </select>
<select id="selectByCrossId" resultType="net.wanji.databus.po.CrossLaneDataHistPOExt">
SELECT *
FROM t_base_lane_info
JOIN t_lane_data_hist ON t_base_lane_info.id = t_lane_data_hist.id
WHERE t_base_lane_info.cross_id = #{crossId}
AND t_base_lane_info.type = 2
AND batch_time <![CDATA[ >= ]]> #{startTimeStamp}
AND batch_time <![CDATA[ <= ]]> #{endTimeStamp};
</select>
</mapper> </mapper>
\ No newline at end of file
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