Commit 53a9d564 authored by hanbing's avatar hanbing

[add] 绿波评价-干线方案评价、干线路口评价

parent 238e1068
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 = "MainlineCrossEvaluateBO", description = "干线路口评价")
public class MainlineCrossEvaluateBO {
@ApiModelProperty(value = "方案名称")
private String greenwaveName;
@ApiModelProperty(value = "指标名称")
private String metricName;
@ApiModelProperty(value = "路口ID列表")
private List<String> crossIdList;
@ApiModelProperty(value = "分析时段开始时间 格式 yyyy-MM-dd HH:mm:ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date startTime;
@ApiModelProperty(value = "分析时段结束时间 格式 yyyy-MM-dd HH:mm:ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date endTime;
@ApiModelProperty(value = "干线方案时段开始时间 格式 HH:mm")
private String startHourMinute;
@ApiModelProperty(value = "干线方案时段结束时间 格式 HH:mm")
private String endHourMinute;
}
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;
/**
* @author Kent HAN
* @date 2023/6/9 13:52
*/
@Data
@ApiModel(value = "MainlineSchemeEvaluateBO", description = "干线方案评价")
public class MainlineSchemeEvaluateBO {
@ApiModelProperty(value = "绿波ID")
private Integer greenwaveId;
@ApiModelProperty(value = "方向名称")
private String dirName;
@ApiModelProperty(value = "指标名称")
private String metricName;
@ApiModelProperty(value = "分析时段开始时间 格式 yyyy-MM-dd HH:mm:ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date startTime;
@ApiModelProperty(value = "分析时段结束时间 格式 yyyy-MM-dd HH:mm:ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date endTime;
}
...@@ -7,13 +7,9 @@ import io.swagger.annotations.ApiResponses; ...@@ -7,13 +7,9 @@ import io.swagger.annotations.ApiResponses;
import net.wanji.common.annotation.aspect.AspectLog; import net.wanji.common.annotation.aspect.AspectLog;
import net.wanji.common.enums.BaseEnum; import net.wanji.common.enums.BaseEnum;
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.*;
import net.wanji.opt.bo.BottomMenuBO;
import net.wanji.opt.bo.MainlineSchemeAnalysisBO;
import net.wanji.opt.service.impl.MainlineEvaluateServiceImpl; import net.wanji.opt.service.impl.MainlineEvaluateServiceImpl;
import net.wanji.opt.vo.MainlineEvaluateBottomCurveVO; import net.wanji.opt.vo.*;
import net.wanji.opt.vo.MainlineListVO;
import net.wanji.opt.vo.MainlineSchemeAnalysisVO;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
...@@ -74,4 +70,28 @@ public class MainlineEvaluateController { ...@@ -74,4 +70,28 @@ public class MainlineEvaluateController {
MainlineSchemeAnalysisVO res = mainlineEvaluateService.mainlineSchemeAnalysis(bo); MainlineSchemeAnalysisVO res = mainlineEvaluateService.mainlineSchemeAnalysis(bo);
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 = "/mainlineSchemeEvaluate",
produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
@ApiResponses({
@ApiResponse(code = 200, message = "OK", response = MainlineSchemeEvaluateVO.class),
})
public JsonViewObject mainlineSchemeEvaluate(@RequestBody MainlineSchemeEvaluateBO bo) {
MainlineSchemeEvaluateVO res = mainlineEvaluateService.mainlineSchemeEvaluate(bo);
return JsonViewObject.newInstance().success(res);
}
@ApiOperation(value = "干线路口评价", notes = "干线路口评价", response = JsonViewObject.class,
produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
@PostMapping(value = "/mainlineCrossEvaluate",
produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
@ApiResponses({
@ApiResponse(code = 200, message = "OK", response = MainlineCrossEvaluateVO.class),
})
public JsonViewObject mainlineCrossEvaluate(@RequestBody MainlineCrossEvaluateBO bo) {
List<MainlineCrossEvaluateVO> res = mainlineEvaluateService.mainlineCrossEvaluate(bo);
return JsonViewObject.newInstance().success(res);
}
} }
\ No newline at end of file
...@@ -21,4 +21,6 @@ public interface GreenwaveInfoMapper { ...@@ -21,4 +21,6 @@ public interface GreenwaveInfoMapper {
GreenwaveInfoPO selectById(Integer id); GreenwaveInfoPO selectById(Integer id);
List<GreenwaveInfoPO> selectAll(); List<GreenwaveInfoPO> selectAll();
GreenwaveInfoPO selectByName(String greenwaveName);
} }
package net.wanji.opt.service; package net.wanji.opt.service;
import net.wanji.opt.bo.BottomCurveBO; import net.wanji.opt.bo.*;
import net.wanji.opt.bo.BottomMenuBO; import net.wanji.opt.vo.*;
import net.wanji.opt.bo.MainlineSchemeAnalysisBO;
import net.wanji.opt.vo.MainlineEvaluateBottomCurveVO;
import net.wanji.opt.vo.MainlineListVO;
import net.wanji.opt.vo.MainlineSchemeAnalysisVO;
import java.text.ParseException; import java.text.ParseException;
import java.util.List; import java.util.List;
...@@ -19,4 +15,8 @@ public interface MainlineEvaluateService { ...@@ -19,4 +15,8 @@ public interface MainlineEvaluateService {
List<MainlineListVO> mainlineList(); List<MainlineListVO> mainlineList();
MainlineSchemeAnalysisVO mainlineSchemeAnalysis(MainlineSchemeAnalysisBO bo); MainlineSchemeAnalysisVO mainlineSchemeAnalysis(MainlineSchemeAnalysisBO bo);
MainlineSchemeEvaluateVO mainlineSchemeEvaluate(MainlineSchemeEvaluateBO bo);
List<MainlineCrossEvaluateVO> mainlineCrossEvaluate(MainlineCrossEvaluateBO bo);
} }
package net.wanji.opt.service.impl; package net.wanji.opt.service.impl;
import cn.hutool.core.collection.CollectionUtil;
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.CrossInOutEnum;
import net.wanji.common.enums.StrategyAndMetricsEnum; import net.wanji.common.enums.StrategyAndMetricsEnum;
import net.wanji.common.enums.TurnConvertEnum; import net.wanji.common.enums.TurnConvertEnum;
import net.wanji.common.utils.tool.CrossUtil;
import net.wanji.common.utils.tool.TimeArrayUtil;
import net.wanji.databus.dao.entity.*; import net.wanji.databus.dao.entity.*;
import net.wanji.databus.dao.mapper.*; import net.wanji.databus.dao.mapper.*;
import net.wanji.databus.po.*; import net.wanji.databus.po.*;
import net.wanji.databus.vo.CrossIdAndNameVO; import net.wanji.databus.vo.CrossIdAndNameVO;
import net.wanji.opt.bo.BottomCurveBO; import net.wanji.opt.bo.*;
import net.wanji.opt.bo.BottomMenuBO;
import net.wanji.opt.bo.MainlineSchemeAnalysisBO;
import net.wanji.opt.dao.mapper.strategy.SceneStrategyMapper; import net.wanji.opt.dao.mapper.strategy.SceneStrategyMapper;
import net.wanji.opt.dao.mapper.strategy.StrategyMapper; import net.wanji.opt.dao.mapper.strategy.StrategyMapper;
import net.wanji.opt.dao.mapper.trend.GreenwaveInfoMapper; import net.wanji.opt.dao.mapper.trend.GreenwaveInfoMapper;
import net.wanji.opt.po.strategy.SceneStrategyPO; import net.wanji.opt.po.strategy.SceneStrategyPO;
import net.wanji.opt.po.strategy.StrategyPO; import net.wanji.opt.po.strategy.StrategyPO;
import net.wanji.opt.service.MainlineEvaluateService; import net.wanji.opt.service.MainlineEvaluateService;
import net.wanji.opt.vo.MainlineEvaluateBottomCurveVO; import net.wanji.opt.vo.*;
import net.wanji.opt.vo.MainlineListVO; import org.jetbrains.annotations.NotNull;
import net.wanji.opt.vo.MainlineSchemeAnalysisVO;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -29,6 +30,7 @@ import java.util.*; ...@@ -29,6 +30,7 @@ import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.ToDoubleFunction;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -56,6 +58,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -56,6 +58,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
private final RidInfoMapper ridInfoMapper; private final RidInfoMapper ridInfoMapper;
SimpleDateFormat hourMinuteFormat = new SimpleDateFormat("HH:mm"); SimpleDateFormat hourMinuteFormat = new SimpleDateFormat("HH:mm");
SimpleDateFormat dayFormat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat dateHourMinuteFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); SimpleDateFormat dateHourMinuteFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
...@@ -116,8 +119,8 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -116,8 +119,8 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
List<MainlineEvaluateBottomCurveVO> res = new ArrayList<>(); List<MainlineEvaluateBottomCurveVO> res = new ArrayList<>();
int startTimeStamp = (int)(startTime.getTime() / 1000); int startTimeStamp = (int) (startTime.getTime() / 1000);
int endTimeStamp = (int)(endTime.getTime() / 1000); int endTimeStamp = (int) (endTime.getTime() / 1000);
if (scope == 0) { // 路口 if (scope == 0) { // 路口
// 查询路口该时段内的所有数据 // 查询路口该时段内的所有数据
...@@ -134,8 +137,8 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -134,8 +137,8 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
calendar.add(Calendar.MINUTE, minutes); calendar.add(Calendar.MINUTE, minutes);
Date endDatetime = calendar.getTime(); Date endDatetime = calendar.getTime();
// 转换为 10 位时间戳 // 转换为 10 位时间戳
int startTimeStampPart = (int)(startDatetime.getTime() / 1000); int startTimeStampPart = (int) (startDatetime.getTime() / 1000);
int endTimeStampPart = (int)(endDatetime.getTime() / 1000); int endTimeStampPart = (int) (endDatetime.getTime() / 1000);
// 使用流式编程进行筛选 // 使用流式编程进行筛选
List<CrossDataHistPO> filteredList = crossPOList.stream() List<CrossDataHistPO> filteredList = crossPOList.stream()
.filter(po -> po.getBatchTime() >= startTimeStampPart && po.getBatchTime() <= endTimeStampPart) .filter(po -> po.getBatchTime() >= startTimeStampPart && po.getBatchTime() <= endTimeStampPart)
...@@ -230,8 +233,8 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -230,8 +233,8 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
calendar.add(Calendar.MINUTE, minutes); calendar.add(Calendar.MINUTE, minutes);
Date endDatetime = calendar.getTime(); Date endDatetime = calendar.getTime();
// 转换为 10 位时间戳 // 转换为 10 位时间戳
int startTimeStampPart = (int)(startDatetime.getTime() / 1000); int startTimeStampPart = (int) (startDatetime.getTime() / 1000);
int endTimeStampPart = (int)(endDatetime.getTime() / 1000); int endTimeStampPart = (int) (endDatetime.getTime() / 1000);
// 使用流式编程进行筛选 // 使用流式编程进行筛选
List<CrossDirDataHistPO> filteredList = dirPOList.stream() List<CrossDirDataHistPO> filteredList = dirPOList.stream()
.filter(po -> po.getDirType().equals(dirCode)) .filter(po -> po.getDirType().equals(dirCode))
...@@ -302,7 +305,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -302,7 +305,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
} }
} else if (scope == 2) { // 方向 } else if (scope == 2) { // 方向
// 查询各方向该时段内的所有数据 // 查询各方向该时段内的所有数据
List<CrossTurnDataHistPO> dirPOList = crossTurnDataHistMapper.selectByCrossId ( List<CrossTurnDataHistPO> dirPOList = crossTurnDataHistMapper.selectByCrossId(
crossId, endTimeStamp, startTimeStamp); crossId, endTimeStamp, startTimeStamp);
for (String timeStr : timeList) { for (String timeStr : timeList) {
...@@ -325,8 +328,8 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -325,8 +328,8 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
calendar.add(Calendar.MINUTE, minutes); calendar.add(Calendar.MINUTE, minutes);
Date endDatetime = calendar.getTime(); Date endDatetime = calendar.getTime();
// 转换为 10 位时间戳 // 转换为 10 位时间戳
int startTimeStampPart = (int)(startDatetime.getTime() / 1000); int startTimeStampPart = (int) (startDatetime.getTime() / 1000);
int endTimeStampPart = (int)(endDatetime.getTime() / 1000); int endTimeStampPart = (int) (endDatetime.getTime() / 1000);
// 使用流式编程进行筛选 // 使用流式编程进行筛选
List<CrossTurnDataHistPO> filteredList = dirPOList.stream() List<CrossTurnDataHistPO> filteredList = dirPOList.stream()
.filter(po -> po.getInDir().equals(dirCode)) .filter(po -> po.getInDir().equals(dirCode))
...@@ -424,8 +427,8 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -424,8 +427,8 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
calendar.add(Calendar.MINUTE, minutes); calendar.add(Calendar.MINUTE, minutes);
Date endDatetime = calendar.getTime(); Date endDatetime = calendar.getTime();
// 转换为 10 位时间戳 // 转换为 10 位时间戳
int startTimeStampPart = (int)(startDatetime.getTime() / 1000); int startTimeStampPart = (int) (startDatetime.getTime() / 1000);
int endTimeStampPart = (int)(endDatetime.getTime() / 1000); int endTimeStampPart = (int) (endDatetime.getTime() / 1000);
// 筛选方向、车道序号 // 筛选方向、车道序号
List<CrossLaneDataHistPOExt> filteredList = lanePOList.stream() List<CrossLaneDataHistPOExt> filteredList = lanePOList.stream()
.filter(po -> po.getDir().equals(dirCode)) .filter(po -> po.getDir().equals(dirCode))
...@@ -511,7 +514,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -511,7 +514,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
.collect(Collectors.groupingBy(po -> getPrefix(po.getName()))) .collect(Collectors.groupingBy(po -> getPrefix(po.getName())))
.values() .values()
.stream() .stream()
.filter(list -> list.size() > 1) .filter(list -> !list.isEmpty())
.map(list -> list.get(0)) .map(list -> list.get(0))
.collect(Collectors.toList()); .collect(Collectors.toList());
...@@ -606,6 +609,640 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -606,6 +609,640 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
return res; return res;
} }
@Override
public MainlineSchemeEvaluateVO mainlineSchemeEvaluate(MainlineSchemeEvaluateBO bo) {
Integer greenwaveId = bo.getGreenwaveId();
String dirName = bo.getDirName();
String metricName = bo.getMetricName();
Date boStartTime = bo.getStartTime();
Date boEndTime = bo.getEndTime();
MainlineSchemeEvaluateVO res = new MainlineSchemeEvaluateVO();
GreenwaveInfoPO greenwaveInfoPO = greenwaveInfoMapper.selectById(greenwaveId);
Integer sectionId = greenwaveInfoPO.getSectionId();
CrossSectionPO crossSectionPO = baseCrossSectionMapper.selectById(sectionId);
String startHourMinuteStr = crossSectionPO.getStartTime();
String endHourMinuteStr = crossSectionPO.getEndTime();
res.setTimeSection(startHourMinuteStr + "-" + endHourMinuteStr);
// 确定控制策略
StrategyPO strategyPO = getStrategyPO(greenwaveId);
String strategyName = strategyPO.getStrategyName();
res.setStrategyName(strategyName);
res.setGreenwaveCrossList(buildGreenwaveCrossList(greenwaveId));
String strategyCode = strategyPO.getStrategyCode();
setCurveElementListAndEvaluateList(dirName, metricName, greenwaveId, boStartTime, boEndTime, startHourMinuteStr,
endHourMinuteStr, res, strategyCode);
return res;
}
@Override
public List<MainlineCrossEvaluateVO> mainlineCrossEvaluate(MainlineCrossEvaluateBO bo) {
String greenwaveName = bo.getGreenwaveName();
String metricName = bo.getMetricName();
List<String> crossIdList = bo.getCrossIdList();
Date startDate = bo.getStartTime();
Date endDate = bo.getEndTime();
String startHourMinute = bo.getStartHourMinute();
String endHourMinute = bo.getEndHourMinute();
List<MainlineCrossEvaluateVO> res = new ArrayList<>();
for (String crossId : crossIdList) {
MainlineCrossEvaluateVO mainlineCrossEvaluateVO = new MainlineCrossEvaluateVO();
BaseCrossInfoPO baseCrossInfoPO = baseCrossInfoMapper.selectById(crossId);
String crossName = baseCrossInfoPO.getName();
mainlineCrossEvaluateVO.setCrossName(crossName);
// 确定协调方向
String[] split = greenwaveName.split(" ");
String dirStr = split[1];
String[] split1 = dirStr.split("向");
GreenwaveInfoPO greenwaveInfoPO = greenwaveInfoMapper.selectByName(greenwaveName);
Integer dir = greenwaveInfoPO.getDir();
List<Integer> coordDirCodeList = new ArrayList<>();
if (dir == 0) { // 正向
String dirStr1 = split1[0];
Integer dirCode = BaseEnum.SignalDirectionEnum.getCodeByName(dirStr1);
dirCode = convertDirCode(dirStr1, crossId, dirCode);
coordDirCodeList.add(dirCode);
} else if (dir == 1) { // 反向
String dirStr1 = split1[1];
Integer dirCode = BaseEnum.SignalDirectionEnum.getCodeByName(dirStr1);
dirCode = convertDirCode(dirStr1, crossId, dirCode);
coordDirCodeList.add(dirCode);
} else { // 双向
String dirStr1 = split1[0];
Integer dirCode1 = BaseEnum.SignalDirectionEnum.getCodeByName(dirStr1);
dirCode1 = convertDirCode(dirStr1, crossId, dirCode1);
coordDirCodeList.add(dirCode1);
String dirStr2 = split1[1];
Integer dirCode2 = BaseEnum.SignalDirectionEnum.getCodeByName(dirStr2);
dirCode2 = convertDirCode(dirStr2, crossId, dirCode2);
coordDirCodeList.add(dirCode2);
}
mainlineCrossEvaluateVO.setCoordValue(calcCoordValue(
coordDirCodeList, crossId, startDate, endDate, startHourMinute, endHourMinute));
mainlineCrossEvaluateVO.setNonCoordValue(calcNonCoordValue(
coordDirCodeList, crossId, startDate, endDate, startHourMinute, endHourMinute));
mainlineCrossEvaluateVO.setDirElementList(buildDirElementList(
crossId, metricName, startDate, endDate, startHourMinute, endHourMinute));
mainlineCrossEvaluateVO.setCrossEvaluateList(buildCrossEvaluateList(
crossId, startDate, endDate, startHourMinute, endHourMinute));
res.add(mainlineCrossEvaluateVO);
}
return res;
}
private List<String> buildCrossEvaluateList(
String crossId, Date startDate, Date endDate, String startHourMinute, String endHourMinute) {
List<String> res = new ArrayList<>();
// 获取路口所有方向
List<BaseCrossDirInfoPO> baseCrossDirInfoPOList =
baseCrossDirInfoMapper.selectByCrossIdAndInOutType(crossId, CrossInOutEnum.IN.getCode());
List<Integer> dirCodeList = baseCrossDirInfoPOList.stream()
.map(BaseCrossDirInfoPO::getDirType)
.collect(Collectors.toList());
for (Integer dirCode : dirCodeList) {
String boStartDayStr = dayFormat.format(startDate);
String boEndDayStr = dayFormat.format(endDate);
List<CrossDirDataHistPO> crossDirDataHistPOList = crossDirDataHistMapper.selectByCrossDirAndTimeSection(
crossId, dirCode, boStartDayStr, boEndDayStr, startHourMinute, endHourMinute);
Integer maxDelayTime = crossDirDataHistPOList.stream()
.map(CrossDirDataHistPO::getDelayTime)
.max(Integer::compareTo)
.orElse(0);
Double maxQueueLength = crossDirDataHistPOList.stream()
.mapToDouble(CrossDirDataHistPO::getQueueLength)
.max()
.orElse(0.0);
int level = CrossUtil.calcEfficiencyLevel(maxDelayTime, maxQueueLength);
if (level == 3) {
res.add(BaseEnum.SignalDirectionEnum.getNameByCode(dirCode) + "进口延误较高效率较低");
} else if (level == 4) {
res.add(BaseEnum.SignalDirectionEnum.getNameByCode(dirCode) + "进口延误高效率低");
}
}
if (CollectionUtil.isEmpty(res)) {
res.add("该路口运行效率良好");
}
return res;
}
private List<MainlineCrossEvaluateVO.DirElement> buildDirElementList(
String crossId, String metricName, Date startDate, Date endDate, String startHourMinute,
String endHourMinute) {
// 获取路口所有方向
List<BaseCrossDirInfoPO> baseCrossDirInfoPOList =
baseCrossDirInfoMapper.selectByCrossIdAndInOutType(crossId, CrossInOutEnum.IN.getCode());
List<Integer> dirCodeList = baseCrossDirInfoPOList.stream()
.map(BaseCrossDirInfoPO::getDirType)
.collect(Collectors.toList());
List<MainlineCrossEvaluateVO.DirElement> res = new ArrayList<>();
for (Integer dirCode : dirCodeList) {
MainlineCrossEvaluateVO.DirElement dirElement = new MainlineCrossEvaluateVO.DirElement();
dirElement.setDir(dirCode);
String boStartDayStr = dayFormat.format(startDate);
String boEndDayStr = dayFormat.format(endDate);
List<CrossDirDataHistPO> crossDirDataHistPOList = crossDirDataHistMapper.selectByCrossDirAndTimeSection(
crossId, dirCode, boStartDayStr, boEndDayStr, startHourMinute, endHourMinute);
dirElement.setValue(calcDirValue(metricName, crossDirDataHistPOList));
res.add(dirElement);
}
return res;
}
private Integer calcDirValue(String metricName, List<CrossDirDataHistPO> crossDirDataHistPOList) {
int dirValue = 0;
if (Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.GREEN_LIGHT_EFFICIENCY.getDescription())) {
double average = crossDirDataHistPOList.stream()
.mapToDouble(CrossDirDataHistPO::getGreenLightEfficiency)
.average()
.orElse(0.0);
dirValue = (int) Math.round(average * 100);
} else if (Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.STOP_TIMES.getDescription())) {
double average = crossDirDataHistPOList.stream()
.mapToDouble(CrossDirDataHistPO::getStopTimes)
.average()
.orElse(0.0);
dirValue = (int) Math.round(average);
} else if (Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.AVERAGE_DELAY.getDescription())) {
double average = crossDirDataHistPOList.stream()
.mapToDouble(CrossDirDataHistPO::getDelayTime)
.average()
.orElse(0.0);
dirValue = (int) Math.round(average);
} else if (Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.AVERAGE_SPEED.getDescription())) {
double average = crossDirDataHistPOList.stream()
.mapToDouble(CrossDirDataHistPO::getSpeed)
.average()
.orElse(0.0);
dirValue = (int) Math.round(average);
}
return dirValue;
}
private Integer calcNonCoordValue(List<Integer> coordDirCodeList, String crossId, Date startDate, Date endDate,
String startHourMinute, String endHourMinute) {
// 筛选非协调方向
List<BaseCrossDirInfoPO> baseCrossDirInfoPOList =
baseCrossDirInfoMapper.selectByCrossIdAndInOutType(crossId, CrossInOutEnum.IN.getCode());
List<Integer> nonCoordDirCodeList = baseCrossDirInfoPOList.stream()
.map(BaseCrossDirInfoPO::getDirType)
.collect(Collectors.toList());
nonCoordDirCodeList.removeAll(coordDirCodeList);
// 查询时段内路口非协调方向数据
String boStartDayStr = dayFormat.format(startDate);
String boEndDayStr = dayFormat.format(endDate);
List<CrossDirDataHistPO> crossDirDataHistPOList = crossDirDataHistMapper.selectByCrossDirsAndTimeSection(
crossId, nonCoordDirCodeList, boStartDayStr, boEndDayStr, startHourMinute, endHourMinute);
// 计算非协调方向指标(排队长度)
int nonCoordValue = (int) (crossDirDataHistPOList.stream()
.mapToDouble(CrossDirDataHistPO::getQueueLength)
.average()
.orElse(0.0));
return nonCoordValue;
}
private Integer calcCoordValue(List<Integer> coordDirCodeList, String crossId, Date startDate, Date endDate,
String startHourMinute, String endHourMinute) {
// 查询时段内路口协调方向数据
String boStartDayStr = dayFormat.format(startDate);
String boEndDayStr = dayFormat.format(endDate);
List<CrossDirDataHistPO> crossDirDataHistPOList = crossDirDataHistMapper.selectByCrossDirsAndTimeSection(
crossId, coordDirCodeList, boStartDayStr, boEndDayStr, startHourMinute, endHourMinute);
// 计算协调方向指标(不停车通过率)
int coordValue = (int) (crossDirDataHistPOList.stream()
.mapToDouble(CrossDirDataHistPO::getNoStopRate)
.average()
.orElse(0.0) * 100);
return coordValue;
}
private void setCurveElementListAndEvaluateList(
String dirName, String metricName, Integer greenwaveId, Date boStartTime, Date boEndTime,
String startHourMinuteStr, String endHourMinuteStr, MainlineSchemeEvaluateVO res, String strategyCode) {
String boStartTimeStr = sdf.format(boStartTime);
String boEndTimeStr = sdf.format(boEndTime);
// 获取绿波历史数据
List<GreenwaveHistPO> greenwaveHistPOList = greenwaveHistMapper
.selectByIdAndTimeSection(greenwaveId, boStartTimeStr, boEndTimeStr);
// 过滤时段内的数据
List<GreenwaveHistPO> filteredGreenwaveList = greenwaveHistPOList.stream()
.filter(po -> {
try {
return isTimeInRange(po.getGmtModified(), startHourMinuteStr, endHourMinuteStr);
} catch (ParseException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
// 获取绿波指标
double noparkPassRate = filteredGreenwaveList.stream()
.mapToDouble(GreenwaveHistPO::getNoparkPassRate)
.average()
.orElse(0.0);
double cordReliability = filteredGreenwaveList.stream()
.mapToDouble(GreenwaveHistPO::getCordReliability)
.average()
.orElse(0.0);
double uncoordinatePhaseQueue = filteredGreenwaveList.stream()
.mapToDouble(GreenwaveHistPO::getUncoordinatePhaseQueue)
.average()
.orElse(0.0);
double cordQueueRatio = filteredGreenwaveList.stream()
.mapToDouble(GreenwaveHistPO::getCordQueueRatio)
.average()
.orElse(0.0);
List<GreenwaveCrossPO> greenwaveCrossPOList = greenwaveCrossMapper.selectByGreenwaveId(greenwaveId);
// 获取各路口方向历史数据
// 提取方向
String[] split = dirName.split("向");
String dirStr = split[0];
Integer dir = BaseEnum.SignalDirectionEnum.getCodeByName(dirStr);
List<CrossDirDataHistPO> totalCrossDirDataHistPOList = new ArrayList<>();
for (GreenwaveCrossPO greenwaveCrossPO : greenwaveCrossPOList) {
buildTotalCrossDirHistList(boStartTime, boEndTime, startHourMinuteStr, endHourMinuteStr, dirStr, dir,
totalCrossDirDataHistPOList, greenwaveCrossPO);
}
// 获取协调方向评价指标
int coordSpeed = 0;
int cordDelay = 0;
if (dirName.contains("非协调")) {
String dirStr1 = split[1];
String[] split1 = dirStr1.split("(");
String s = split1[0];
Integer dir1 = BaseEnum.SignalDirectionEnum.getCodeByName(s);
List<CrossDirDataHistPO> totalCrossDirDataHistPOList1 = new ArrayList<>();
for (GreenwaveCrossPO greenwaveCrossPO : greenwaveCrossPOList) {
buildTotalCrossDirHistList(boStartTime, boEndTime, startHourMinuteStr, endHourMinuteStr, dirStr1, dir1,
totalCrossDirDataHistPOList1, greenwaveCrossPO);
coordSpeed = (int) (totalCrossDirDataHistPOList1.stream()
.mapToDouble(CrossDirDataHistPO::getSpeed)
.average()
.orElse(0.0));
cordDelay = (int) (totalCrossDirDataHistPOList1.stream()
.mapToDouble(CrossDirDataHistPO::getDelayTime)
.average()
.orElse(0.0));
}
} else {
coordSpeed = (int) (totalCrossDirDataHistPOList.stream()
.mapToDouble(CrossDirDataHistPO::getSpeed)
.average()
.orElse(0.0));
cordDelay = (int) (totalCrossDirDataHistPOList.stream()
.mapToDouble(CrossDirDataHistPO::getDelayTime)
.average()
.orElse(0.0));
}
// 生成评价结果
List<String> evaluateList = new ArrayList<>();
// 获取饱和度
double saturation = totalCrossDirDataHistPOList.stream()
.mapToDouble(CrossDirDataHistPO::getSturation)
.average()
.orElse(0.0);
GreenwaveInfoPO greenwaveInfoPO = greenwaveInfoMapper.selectById(greenwaveId);
Integer greenwaveDir = greenwaveInfoPO.getDir();
if (greenwaveDir == 0 || greenwaveDir == 1) { // 单向绿波
if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_EFFICIENCY.getCode())) {
if (saturation < 0.8) {
if (noparkPassRate > 0.8 && cordReliability > 0.7) {
// 协调不停车通过率需大于80%,并且协调方案可靠性需大于70%
evaluateList.add("该方案符合控制策略");
} else if (uncoordinatePhaseQueue < 0.5) {
// 如果以上不满足,则非协调相位二次排队需小于50%
evaluateList.add("该方案符合控制策略");
} else {
evaluateList.add("该方案不符合控制策略");
}
} else {
// 协调方案可靠性需大于70%
if (cordReliability > 0.7) {
evaluateList.add("该方案符合控制策略");
} else {
evaluateList.add("该方案不符合控制策略");
}
}
} else if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_BALANCE.getCode())) {
if (cordQueueRatio < 0.6) {
// 协调路段排队空间占比需小于60%
evaluateList.add("该方案符合控制策略");
} else if (uncoordinatePhaseQueue < 1.0) {
// 如果以上不满足,则非协调相位二次排队需小于100%
evaluateList.add("该方案符合控制策略");
} else {
evaluateList.add("该方案不符合控制策略");
}
}
} else { // 双向绿波
if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_EFFICIENCY.getCode())) {
// 协调不停车通过率需大于50%,并且协调方案可靠性需大于70%
if (noparkPassRate > 0.5 && cordReliability > 0.7) {
evaluateList.add("该方案符合控制策略");
} else {
evaluateList.add("该方案不符合控制策略");
}
} else if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_BALANCE.getCode())) {
if (cordQueueRatio < 0.6) {
// 协调路段排队空间占比需小于60%
evaluateList.add("该方案符合控制策略");
} else if (uncoordinatePhaseQueue < 1.0) {
// 如果以上不满足,则非协调相位二次排队需小于100%
evaluateList.add("该方案符合控制策略");
} else {
evaluateList.add("该方案不符合控制策略");
}
}
}
evaluateList.add("协调方向平均速度" + coordSpeed + "km/h");
evaluateList.add("协调方向平均延误" + cordDelay + "s");
String s = evaluateList.get(0);
if (s.contains("不符合")) {
evaluateList.add("协调效果差");
} else {
evaluateList.add("协调效果良好");
}
res.setEvaluateList(evaluateList);
// 生成曲线图
List<String> timeArray = TimeArrayUtil.getCustomTimeIntervals(startHourMinuteStr, endHourMinuteStr, 5);
if (Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.NO_PARK_PASS_RATE.getDescription())
|| Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.TRVAL_TIME.getDescription())
|| Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.CORD_RELIABILITY.getDescription())
|| Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.UNCOORDINATE_PHASE_QUEUE.getDescription())
|| Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.CORD_QUEUE_RATIO.getDescription())) {
// 按时间粒度聚合绿波历史数据
Map<String, List<GreenwaveHistPO>> groupedByTime = greenwaveHistPOList.stream()
.collect(Collectors.groupingBy(po -> {
Calendar calendar = Calendar.getInstance();
calendar.setTime(po.getGmtModified());
return getHourMinuteString(calendar);
}));
String enumName = StrategyAndMetricsEnum.Metrics.getEnumNameByDescription(metricName);
evaluateMetrics(enumName, timeArray, groupedByTime, res);
} else {
List<MainlineSchemeEvaluateVO.CurveElement> curveElementList = new ArrayList<>();
// 按时间粒度聚合路口方向历史数据
Map<String, List<CrossDirDataHistPO>> groupedByTime = totalCrossDirDataHistPOList.stream()
.collect(Collectors.groupingBy(po -> {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis((long) po.getBatchTime() * 1000);
return getHourMinuteString(calendar);
}));
if (Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.GREEN_LIGHT_EFFICIENCY.getDescription())) {
for (String hourMinute : timeArray) {
MainlineSchemeEvaluateVO.CurveElement curveElement = new MainlineSchemeEvaluateVO.CurveElement();
curveElement.setMetricTime(hourMinute);
List<CrossDirDataHistPO> crossDirDataHistPOList = groupedByTime.get(hourMinute);
OptionalDouble minAverage = crossDirDataHistPOList.stream()
.collect(Collectors.groupingBy(CrossDirDataHistPO::getCrossId))
.entrySet().stream()
.mapToDouble(entry -> entry.getValue().stream()
.mapToDouble(CrossDirDataHistPO::getGreenLightEfficiency)
.average()
.orElse(0.0))
.min();
int value = (int) (minAverage.orElse(0.0) * 100);
curveElement.setValue(value);
curveElementList.add(curveElement);
}
} else if (Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.STOP_TIMES.getDescription())) {
for (String hourMinute : timeArray) {
MainlineSchemeEvaluateVO.CurveElement curveElement = new MainlineSchemeEvaluateVO.CurveElement();
curveElement.setMetricTime(hourMinute);
List<CrossDirDataHistPO> crossDirDataHistPOList = groupedByTime.get(hourMinute);
double sumOfAverages = crossDirDataHistPOList.stream()
.collect(Collectors.groupingBy(CrossDirDataHistPO::getCrossId))
.entrySet().stream()
.mapToDouble(entry -> entry.getValue().stream()
.mapToDouble(CrossDirDataHistPO::getStopTimes)
.average()
.orElse(0.0))
.sum();
int value = (int) sumOfAverages;
curveElement.setValue(value);
curveElementList.add(curveElement);
}
} else if (Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.AVERAGE_DELAY.getDescription())) {
for (String hourMinute : timeArray) {
MainlineSchemeEvaluateVO.CurveElement curveElement = new MainlineSchemeEvaluateVO.CurveElement();
curveElement.setMetricTime(hourMinute);
List<CrossDirDataHistPO> crossDirDataHistPOList = groupedByTime.get(hourMinute);
double sumOfAverages = crossDirDataHistPOList.stream()
.collect(Collectors.groupingBy(CrossDirDataHistPO::getCrossId))
.entrySet().stream()
.mapToDouble(entry -> entry.getValue().stream()
.mapToDouble(CrossDirDataHistPO::getDelayTime)
.average()
.orElse(0.0))
.sum();
int value = (int) sumOfAverages;
curveElement.setValue(value);
curveElementList.add(curveElement);
}
} else if (Objects.equals(metricName, StrategyAndMetricsEnum.Metrics.AVERAGE_SPEED.getDescription())) {
for (String hourMinute : timeArray) {
MainlineSchemeEvaluateVO.CurveElement curveElement = new MainlineSchemeEvaluateVO.CurveElement();
curveElement.setMetricTime(hourMinute);
List<CrossDirDataHistPO> crossDirDataHistPOList = groupedByTime.get(hourMinute);
double sumOfAverages = crossDirDataHistPOList.stream()
.collect(Collectors.groupingBy(CrossDirDataHistPO::getCrossId))
.entrySet().stream()
.mapToDouble(entry -> entry.getValue().stream()
.mapToDouble(CrossDirDataHistPO::getSpeed)
.average()
.orElse(0.0))
.average().orElse(0.0);
int value = (int) sumOfAverages;
curveElement.setValue(value);
curveElementList.add(curveElement);
}
}
res.setCurveElementList(curveElementList);
}
}
@NotNull
private String getHourMinuteString(Calendar calendar) {
int minute = calendar.get(Calendar.MINUTE);
minute = (minute / 5) * 5; // Round down to nearest 5 minutes
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return hourMinuteFormat.format(calendar.getTime());
}
private void evaluateMetrics(String metricName, List<String> timeArray,
Map<String, List<GreenwaveHistPO>> groupedByTime, MainlineSchemeEvaluateVO res) {
List<MainlineSchemeEvaluateVO.CurveElement> curveElementList = new ArrayList<>();
for (String hourMinute : timeArray) {
MainlineSchemeEvaluateVO.CurveElement curveElement = new MainlineSchemeEvaluateVO.CurveElement();
curveElement.setMetricTime(hourMinute);
List<GreenwaveHistPO> greenwaveHistPOListHourMinute = groupedByTime.get(hourMinute);
ToDoubleFunction<GreenwaveHistPO> function;
switch (metricName) {
case "NO_PARK_PASS_RATE":
function = GreenwaveHistPO::getNoparkPassRate;
break;
case "TRVAL_TIME":
function = GreenwaveHistPO::getTrvalTime;
break;
case "CORD_RELIABILITY":
function = GreenwaveHistPO::getCordReliability;
break;
case "UNCOORDINATE_PHASE_QUEUE":
function = GreenwaveHistPO::getUncoordinatePhaseQueue;
break;
case "CORD_QUEUE_RATIO":
function = GreenwaveHistPO::getCordQueueRatio;
break;
default:
throw new IllegalArgumentException("Unknown metric: " + metricName);
}
if (CollectionUtil.isNotEmpty(greenwaveHistPOListHourMinute)) {
int value = calculateAverage(greenwaveHistPOListHourMinute, function);
curveElement.setValue(value);
} else {
curveElement.setValue(0);
}
curveElementList.add(curveElement);
}
res.setCurveElementList(curveElementList);
}
private int calculateAverage(List<GreenwaveHistPO> list, ToDoubleFunction<GreenwaveHistPO> function) {
return (int) (list.stream().mapToDouble(function).average().orElse(0.0) * 100);
}
private void buildTotalCrossDirHistList(
Date boStartTime, Date boEndTime, String startHourMinuteStr, String endHourMinuteStr, String dirStr,
Integer dir, List<CrossDirDataHistPO> totalCrossDirDataHistPOList, GreenwaveCrossPO greenwaveCrossPO) {
String crossId = greenwaveCrossPO.getCrossId();
Integer dirCode = dir;
dirCode = convertDirCode(dirStr, crossId, dirCode);
String boStartDayStr = dayFormat.format(boStartTime);
String boEndDayStr = dayFormat.format(boEndTime);
List<CrossDirDataHistPO> crossDirDataHistPOList = crossDirDataHistMapper.selectByCrossDirAndTimeSection(
crossId, dirCode, boStartDayStr, boEndDayStr, startHourMinuteStr, endHourMinuteStr);
totalCrossDirDataHistPOList.addAll(crossDirDataHistPOList);
}
private Integer convertDirCode(String dirStr, String crossId, Integer dirCode) {
if (Objects.equals(crossId, "13NF80B5QN0")) {
// 霞景路方向转换
if (Objects.equals(dirStr, "东")) {
dirCode = 2; // 东北
} else if (Objects.equals(dirStr, "西")) {
dirCode = 6; // 西南
}
} else if (Objects.equals(crossId, "13NGH0B5RC0")) {
// 洪山路方向转换
if (Objects.equals(dirStr, "西")) {
dirCode = 6; // 西南
}
}
return dirCode;
}
private boolean isTimeInRange(Date date, String startStr, String endStr) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
Date startDate = sdf.parse(startStr);
Date endDate = sdf.parse(endStr);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
cal.setTime(startDate);
int startHour = cal.get(Calendar.HOUR_OF_DAY);
int startMinute = cal.get(Calendar.MINUTE);
cal.setTime(endDate);
int endHour = cal.get(Calendar.HOUR_OF_DAY);
int endMinute = cal.get(Calendar.MINUTE);
return (hour > startHour || (hour == startHour && minute >= startMinute))
&& (hour < endHour || (hour == endHour && minute <= endMinute));
}
private List<GreenwaveDetailVO.GreenwaveCross> buildGreenwaveCrossList(Integer greenwaveId) {
List<GreenwaveDetailVO.GreenwaveCross> res = new ArrayList<>();
List<GreenwaveCrossPO> greenwaveCrossList = greenwaveCrossMapper.selectByGreenwaveId(greenwaveId);
int size = greenwaveCrossList.size();
for (int i = 0; i < size; i++) {
GreenwaveCrossPO greenwaveCrossPO = greenwaveCrossList.get(i);
GreenwaveDetailVO.GreenwaveCross greenwaveCross = new GreenwaveDetailVO.GreenwaveCross();
String crossId = greenwaveCrossPO.getCrossId();
greenwaveCross.setCrossId(crossId);
BaseCrossInfoPO baseCrossInfoPO = baseCrossInfoMapper.selectById(crossId);
if (baseCrossInfoPO == null) {
throw new RuntimeException("无此路口基础信息");
}
greenwaveCross.setCrossName(baseCrossInfoPO.getName());
greenwaveCross.setIsKeyRoute(greenwaveCrossPO.getIsKeyRoute());
greenwaveCross.setSort(greenwaveCrossPO.getSort());
// 到下一个路口距离
Integer distanceToNextCross = null;
if (i < size - 1) { // 不是最后一个路口
double nextCrossLen = greenwaveCrossPO.getNextCrossLen();
distanceToNextCross = (int) nextCrossLen;
}
greenwaveCross.setDistanceToNextCross(distanceToNextCross);
res.add(greenwaveCross);
}
return res;
}
private List<MainlineSchemeAnalysisVO.GreenwaveData> buildGreenwaveData(List<GreenwaveHistPO> filteredList) { private List<MainlineSchemeAnalysisVO.GreenwaveData> buildGreenwaveData(List<GreenwaveHistPO> filteredList) {
List<MainlineSchemeAnalysisVO.GreenwaveData> res = new ArrayList<>(); List<MainlineSchemeAnalysisVO.GreenwaveData> res = new ArrayList<>();
List<GreenwaveHistPO> distinctList = filteredList.stream() List<GreenwaveHistPO> distinctList = filteredList.stream()
...@@ -615,6 +1252,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -615,6 +1252,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
for (GreenwaveHistPO greenwaveHistPO : distinctList) { for (GreenwaveHistPO greenwaveHistPO : distinctList) {
MainlineSchemeAnalysisVO.GreenwaveData greenwaveData = new MainlineSchemeAnalysisVO.GreenwaveData(); MainlineSchemeAnalysisVO.GreenwaveData greenwaveData = new MainlineSchemeAnalysisVO.GreenwaveData();
greenwaveData.setName(greenwaveHistPO.getGreenwaveName()); greenwaveData.setName(greenwaveHistPO.getGreenwaveName());
greenwaveData.setGreenwaveId(greenwaveHistPO.getId());
Integer greenwaveId = greenwaveHistPO.getId(); Integer greenwaveId = greenwaveHistPO.getId();
greenwaveData.setDirList(buildDirList(greenwaveId)); greenwaveData.setDirList(buildDirList(greenwaveId));
...@@ -669,47 +1307,80 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -669,47 +1307,80 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
return res; return res;
} }
private List<String> buildMetricList(Integer greenwaveId, Integer coordinateDir) { private List<MainlineSchemeAnalysisVO.Metric> buildMetricList(Integer greenwaveId, Integer coordinateDir) {
List<String> res = new ArrayList<>(); List<MainlineSchemeAnalysisVO.Metric> res = new ArrayList<>();
// 确定控制策略 // 确定控制策略
GreenwaveScenePO greenwaveScenePO = greenwaveSceneMapper.selectByGreenwaveId(greenwaveId); StrategyPO strategyPO = getStrategyPO(greenwaveId);
Integer sceneId = greenwaveScenePO.getSceneId();
List<SceneStrategyPO> sceneStrategyPOList = sceneStrategyMapper.selectBySceneId(sceneId);
Optional<SceneStrategyPO> maxPriorityPO = sceneStrategyPOList.stream()
.max(Comparator.comparingInt(SceneStrategyPO::getSceneStrategyPriority));
SceneStrategyPO sceneStrategyPO = maxPriorityPO.get();
Integer strategyId = sceneStrategyPO.getStrategyId();
StrategyPO strategyPO = strategyMapper.selectById(strategyId);
String strategyCode = strategyPO.getStrategyCode(); String strategyCode = strategyPO.getStrategyCode();
if (coordinateDir == 0 || coordinateDir == 1) { // 单向绿波 if (coordinateDir == 0 || coordinateDir == 1) { // 单向绿波
if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_EFFICIENCY.getCode())) { if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_EFFICIENCY.getCode())) {
addMetrics(res); addMetrics(res);
res.add(StrategyAndMetricsEnum.Metrics.UNCOORDINATE_PHASE_QUEUE.getDescription()); MainlineSchemeAnalysisVO.Metric metric = new MainlineSchemeAnalysisVO.Metric();
} else if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.BALANCE.getCode())) { metric.setMetricName(StrategyAndMetricsEnum.Metrics.UNCOORDINATE_PHASE_QUEUE.getDescription());
res.add(StrategyAndMetricsEnum.Metrics.CORD_QUEUE_RATIO.getDescription()); metric.setIsShown(0);
res.add(StrategyAndMetricsEnum.Metrics.UNCOORDINATE_PHASE_QUEUE.getDescription()); res.add(metric);
} else {
fillBalanceMetrics(res, strategyCode);
} }
} else { // 双向绿波 } else { // 双向绿波
if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_EFFICIENCY.getCode())) { if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_EFFICIENCY.getCode())) {
addMetrics(res); addMetrics(res);
} else if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.BALANCE.getCode())) { } else fillBalanceMetrics(res, strategyCode);
res.add(StrategyAndMetricsEnum.Metrics.CORD_QUEUE_RATIO.getDescription());
res.add(StrategyAndMetricsEnum.Metrics.UNCOORDINATE_PHASE_QUEUE.getDescription());
}
} }
return res; return res;
} }
private void addMetrics(List<String> res) { private void fillBalanceMetrics(List<MainlineSchemeAnalysisVO.Metric> res, String strategyCode) {
res.add(StrategyAndMetricsEnum.Metrics.NO_PARK_PASS_RATE.getDescription()); if (Objects.equals(strategyCode, StrategyAndMetricsEnum.Strategy.LINE_BALANCE.getCode())) {
res.add(StrategyAndMetricsEnum.Metrics.TRVAL_TIME.getDescription()); MainlineSchemeAnalysisVO.Metric metric = new MainlineSchemeAnalysisVO.Metric();
res.add(StrategyAndMetricsEnum.Metrics.GREEN_LIGHT_EFFICIENCY.getDescription()); metric.setMetricName(StrategyAndMetricsEnum.Metrics.CORD_QUEUE_RATIO.getDescription());
res.add(StrategyAndMetricsEnum.Metrics.STOP_TIMES.getDescription()); metric.setIsShown(0);
res.add(StrategyAndMetricsEnum.Metrics.AVERAGE_DELAY.getDescription()); res.add(metric);
res.add(StrategyAndMetricsEnum.Metrics.AVERAGE_SPEED.getDescription());
res.add(StrategyAndMetricsEnum.Metrics.CORD_RELIABILITY.getDescription()); MainlineSchemeAnalysisVO.Metric metric1 = new MainlineSchemeAnalysisVO.Metric();
metric1.setMetricName(StrategyAndMetricsEnum.Metrics.UNCOORDINATE_PHASE_QUEUE.getDescription());
metric1.setIsShown(0);
res.add(metric1);
}
}
private void addMetrics(List<MainlineSchemeAnalysisVO.Metric> res) {
MainlineSchemeAnalysisVO.Metric metric = new MainlineSchemeAnalysisVO.Metric();
metric.setMetricName(StrategyAndMetricsEnum.Metrics.NO_PARK_PASS_RATE.getDescription());
metric.setIsShown(0);
res.add(metric);
MainlineSchemeAnalysisVO.Metric metric2 = new MainlineSchemeAnalysisVO.Metric();
metric2.setMetricName(StrategyAndMetricsEnum.Metrics.TRVAL_TIME.getDescription());
metric2.setIsShown(0);
res.add(metric2);
MainlineSchemeAnalysisVO.Metric metric3 = new MainlineSchemeAnalysisVO.Metric();
metric3.setMetricName(StrategyAndMetricsEnum.Metrics.GREEN_LIGHT_EFFICIENCY.getDescription());
metric3.setIsShown(1);
res.add(metric3);
MainlineSchemeAnalysisVO.Metric metric4 = new MainlineSchemeAnalysisVO.Metric();
metric4.setMetricName(StrategyAndMetricsEnum.Metrics.STOP_TIMES.getDescription());
metric4.setIsShown(1);
res.add(metric4);
MainlineSchemeAnalysisVO.Metric metric5 = new MainlineSchemeAnalysisVO.Metric();
metric5.setMetricName(StrategyAndMetricsEnum.Metrics.AVERAGE_DELAY.getDescription());
metric5.setIsShown(1);
res.add(metric5);
MainlineSchemeAnalysisVO.Metric metric6 = new MainlineSchemeAnalysisVO.Metric();
metric6.setMetricName(StrategyAndMetricsEnum.Metrics.AVERAGE_SPEED.getDescription());
metric6.setIsShown(1);
res.add(metric6);
MainlineSchemeAnalysisVO.Metric metric7 = new MainlineSchemeAnalysisVO.Metric();
metric7.setMetricName(StrategyAndMetricsEnum.Metrics.CORD_RELIABILITY.getDescription());
metric7.setIsShown(0);
res.add(metric7);
} }
private String reverseDirName(String input, String character) { private String reverseDirName(String input, String character) {
...@@ -737,14 +1408,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -737,14 +1408,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
Double cordQueueRatio = greenwaveHistPO.getCordQueueRatio(); Double cordQueueRatio = greenwaveHistPO.getCordQueueRatio();
Integer greenwaveId = greenwaveHistPO.getId(); Integer greenwaveId = greenwaveHistPO.getId();
// 确定控制策略 // 确定控制策略
GreenwaveScenePO greenwaveScenePO = greenwaveSceneMapper.selectByGreenwaveId(greenwaveId); StrategyPO strategyPO = getStrategyPO(greenwaveId);
Integer sceneId = greenwaveScenePO.getSceneId();
List<SceneStrategyPO> sceneStrategyPOList = sceneStrategyMapper.selectBySceneId(sceneId);
Optional<SceneStrategyPO> maxPriorityPO = sceneStrategyPOList.stream()
.max(Comparator.comparingInt(SceneStrategyPO::getSceneStrategyPriority));
SceneStrategyPO sceneStrategyPO = maxPriorityPO.get();
Integer strategyId = sceneStrategyPO.getStrategyId();
StrategyPO strategyPO = strategyMapper.selectById(strategyId);
String strategyCode = strategyPO.getStrategyCode(); String strategyCode = strategyPO.getStrategyCode();
// 确定评价 // 确定评价
...@@ -801,7 +1465,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -801,7 +1465,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
qualified++; qualified++;
} else if (uncoordinatePhaseQueue < 1.0) { } else if (uncoordinatePhaseQueue < 1.0) {
// 如果以上不满足,则非协调相位二次排队需小于100% // 如果以上不满足,则非协调相位二次排队需小于100%
qualified ++; qualified++;
} else { } else {
notQualified++; notQualified++;
} }
...@@ -820,7 +1484,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -820,7 +1484,7 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
qualified++; qualified++;
} else if (uncoordinatePhaseQueue < 1.0) { } else if (uncoordinatePhaseQueue < 1.0) {
// 如果以上不满足,则非协调相位二次排队需小于100% // 如果以上不满足,则非协调相位二次排队需小于100%
qualified ++; qualified++;
} else { } else {
notQualified++; notQualified++;
} }
...@@ -833,6 +1497,18 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -833,6 +1497,18 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
return res; return res;
} }
private StrategyPO getStrategyPO(Integer greenwaveId) {
GreenwaveScenePO greenwaveScenePO = greenwaveSceneMapper.selectByGreenwaveId(greenwaveId);
Integer sceneId = greenwaveScenePO.getSceneId();
List<SceneStrategyPO> sceneStrategyPOList = sceneStrategyMapper.selectBySceneId(sceneId);
Optional<SceneStrategyPO> maxPriorityPO = sceneStrategyPOList.stream()
.min(Comparator.comparingInt(SceneStrategyPO::getSceneStrategyPriority));
SceneStrategyPO sceneStrategyPO = maxPriorityPO.get();
Integer strategyId = sceneStrategyPO.getStrategyId();
StrategyPO strategyPO = strategyMapper.selectById(strategyId);
return strategyPO;
}
private List<BaseCrossInfoPO> getGreenwaveCross(Integer greenwaveId) { private List<BaseCrossInfoPO> getGreenwaveCross(Integer greenwaveId) {
List<BaseCrossInfoPO> res = new ArrayList<>(); List<BaseCrossInfoPO> res = new ArrayList<>();
List<GreenwaveCrossPO> greenwaveCrosses = greenwaveCrossMapper.selectByGreenwaveId(greenwaveId); List<GreenwaveCrossPO> greenwaveCrosses = greenwaveCrossMapper.selectByGreenwaveId(greenwaveId);
...@@ -1014,5 +1690,4 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService { ...@@ -1014,5 +1690,4 @@ public class MainlineEvaluateServiceImpl implements MainlineEvaluateService {
return res; return res;
} }
} }
...@@ -925,7 +925,7 @@ public class SchemeEvaluateServiceImpl implements SchemeEvaluateService { ...@@ -925,7 +925,7 @@ public class SchemeEvaluateServiceImpl implements SchemeEvaluateService {
stopTimesLong + StrategyAndMetricsEnum.Metrics.STOP_TIMES.getUnit()); stopTimesLong + StrategyAndMetricsEnum.Metrics.STOP_TIMES.getUnit());
// 计算指标是否合格 // 计算指标是否合格
int level = calcEfficiencyLevel(maxDelayTime, maxQueueLength); int level = CrossUtil.calcEfficiencyLevel(maxDelayTime, maxQueueLength);
if (level == 3) { if (level == 3) {
tableContent.setHasProblem(1); tableContent.setHasProblem(1);
problemList.add(BaseEnum.SignalDirectionEnum.getNameByCode(dirCode) + "进口" problemList.add(BaseEnum.SignalDirectionEnum.getNameByCode(dirCode) + "进口"
...@@ -1243,7 +1243,7 @@ public class SchemeEvaluateServiceImpl implements SchemeEvaluateService { ...@@ -1243,7 +1243,7 @@ public class SchemeEvaluateServiceImpl implements SchemeEvaluateService {
crossId, dirCode, CrossInOutEnum.IN.getCode(), startTimeStamp, endTimeStamp); crossId, dirCode, CrossInOutEnum.IN.getCode(), startTimeStamp, endTimeStamp);
Double maxQueueLength = crossDirDataHistMapper.selectMaxQueueLength( Double maxQueueLength = crossDirDataHistMapper.selectMaxQueueLength(
crossId, dirCode, CrossInOutEnum.IN.getCode(), startTimeStamp, endTimeStamp); crossId, dirCode, CrossInOutEnum.IN.getCode(), startTimeStamp, endTimeStamp);
int level = calcEfficiencyLevel(maxDelayTime, maxQueueLength); int level = CrossUtil.calcEfficiencyLevel(maxDelayTime, maxQueueLength);
if (level == 3) { if (level == 3) {
strategyEvaluateList.add(BaseEnum.SignalDirectionEnum.getNameByCode(dirCode) + "进口延误较高效率较低"); strategyEvaluateList.add(BaseEnum.SignalDirectionEnum.getNameByCode(dirCode) + "进口延误较高效率较低");
} else if (level == 4) { } else if (level == 4) {
...@@ -1256,26 +1256,6 @@ public class SchemeEvaluateServiceImpl implements SchemeEvaluateService { ...@@ -1256,26 +1256,6 @@ public class SchemeEvaluateServiceImpl implements SchemeEvaluateService {
vo.setStrategyEvaluateList(strategyEvaluateList); vo.setStrategyEvaluateList(strategyEvaluateList);
} }
private int calcEfficiencyLevel(Integer delayTime, Double queueLength) {
int level = 0;
if (delayTime != null) {
if (delayTime >=40 && delayTime <= 49) {
level = 3;
} else if (delayTime >= 50) {
level = 4;
}
}
if (queueLength != null) {
int intQueueLength = (int) Math.round(queueLength);
if (intQueueLength >= 60 && intQueueLength <=79 && level < 3) {
level = 3;
} else if (intQueueLength >= 80) {
level = 4;
}
}
return level;
}
private SchemeEvaluateSchemeDetailOverallVO.OverallMetrics buildNoStopRateOverallMetrics( private SchemeEvaluateSchemeDetailOverallVO.OverallMetrics buildNoStopRateOverallMetrics(
int intStopTimesAverage) { int intStopTimesAverage) {
SchemeEvaluateSchemeDetailOverallVO.OverallMetrics overallMetrics = SchemeEvaluateSchemeDetailOverallVO.OverallMetrics overallMetrics =
......
package net.wanji.opt.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author Kent HAN
* @date 2023/2/9 8:38
*/
@Data
@NoArgsConstructor
@ApiModel(value = "MainlineCrossEvaluateVO", description = "干线路口评价")
public class MainlineCrossEvaluateVO {
@ApiModelProperty(value = "路口名称")
private String crossName;
@ApiModelProperty(value = "协调方向指标(不停车通过率)")
private Integer coordValue;
@ApiModelProperty(value = "非协调方向指标(排队长度)")
private Integer nonCoordValue;
@ApiModelProperty(value = "方向指标列表")
private List<DirElement> dirElementList;
@ApiModelProperty(value = "评价")
private List<String> crossEvaluateList;
@NoArgsConstructor
@Data
public static class DirElement {
@ApiModelProperty(value = "方向:1北;2东北;3东;4东南;5南;6西南;7西;8西北")
private Integer dir;
@ApiModelProperty(value = "指标数值")
private Integer value;
}
}
...@@ -50,6 +50,9 @@ public class MainlineSchemeAnalysisVO { ...@@ -50,6 +50,9 @@ public class MainlineSchemeAnalysisVO {
@ApiModelProperty(value = "方案名称") @ApiModelProperty(value = "方案名称")
private String name; private String name;
@ApiModelProperty(value = "绿波ID")
private Integer greenwaveId;
@ApiModelProperty(value = "方向下拉列表") @ApiModelProperty(value = "方向下拉列表")
private List<DirectionList> dirList; private List<DirectionList> dirList;
} }
...@@ -60,6 +63,15 @@ public class MainlineSchemeAnalysisVO { ...@@ -60,6 +63,15 @@ public class MainlineSchemeAnalysisVO {
private String name; private String name;
@ApiModelProperty(value = "指标列表") @ApiModelProperty(value = "指标列表")
private List<String> metricList; private List<Metric> metricList;
}
@Data
public static class Metric {
@ApiModelProperty(value = "指标名称")
private String metricName;
@ApiModelProperty(value = "是否在干线路口评价下拉列表和底部曲线图下拉列表展示,0否 1是")
private Integer isShown;
} }
} }
package net.wanji.opt.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author Kent HAN
* @date 2023/2/9 8:38
*/
@Data
@NoArgsConstructor
@ApiModel(value = "MainlineSchemeEvaluateVO", description = "干线方案评价")
public class MainlineSchemeEvaluateVO {
@ApiModelProperty(value = "时段")
private String timeSection;
@ApiModelProperty(value = "控制策略")
private String strategyName;
@ApiModelProperty(value = "路口线路图")
private List<GreenwaveDetailVO.GreenwaveCross> greenwaveCrossList;
@ApiModelProperty(value = "曲线图")
private List<CurveElement> curveElementList;
@ApiModelProperty(value = "评价")
private List<String> evaluateList;
@NoArgsConstructor
@Data
public static class CurveElement {
@ApiModelProperty(value = "时间")
private String metricTime;
@ApiModelProperty(value = "数值")
private Integer value;
}
}
...@@ -42,4 +42,10 @@ ...@@ -42,4 +42,10 @@
from t_greenwave_info from t_greenwave_info
</select> </select>
<select id="selectByName" resultType="net.wanji.databus.dao.entity.GreenwaveInfoPO">
select <include refid="baseColumnList"></include>
from t_greenwave_info
where name = #{greenwaveName}
</select>
</mapper> </mapper>
...@@ -92,6 +92,15 @@ public class StrategyAndMetricsEnum { ...@@ -92,6 +92,15 @@ public class StrategyAndMetricsEnum {
} }
return null; return null;
} }
public static String getEnumNameByDescription(String description) {
for (Metrics metric : Metrics.values()) {
if (metric.description.equals(description)) {
return metric.name();
}
}
throw new IllegalArgumentException("No enum found with description: " + description);
}
} }
public static final Map<Strategy, List<Metrics>> STRATEGY_METRICS_MAP; public static final Map<Strategy, List<Metrics>> STRATEGY_METRICS_MAP;
......
...@@ -36,4 +36,24 @@ public class CrossUtil { ...@@ -36,4 +36,24 @@ public class CrossUtil {
} }
return res; return res;
} }
public static int calcEfficiencyLevel(Integer delayTime, Double queueLength) {
int level = 0;
if (delayTime != null) {
if (delayTime >=40 && delayTime <= 49) {
level = 3;
} else if (delayTime >= 50) {
level = 4;
}
}
if (queueLength != null) {
int intQueueLength = (int) Math.round(queueLength);
if (intQueueLength >= 60 && intQueueLength <=79 && level < 3) {
level = 3;
} else if (intQueueLength >= 80) {
level = 4;
}
}
return level;
}
} }
...@@ -47,4 +47,47 @@ public class TimeArrayUtil { ...@@ -47,4 +47,47 @@ public class TimeArrayUtil {
} }
return timeSegments; return timeSegments;
} }
/**
* 按分钟段返回指定区间的时间数组。如 ["00:15", "00:30" ... ]
* minutes,分钟段。如按每15分钟生成,则 minute 传15。
* @author Kent HAN
* @date 2022/11/3 16:30
*/
public static List<String> getCustomTimeIntervals(String startHourMinuteStr, String endHourMinuteStr, Integer minutes) {
int startMinutes = convertToMinutes(startHourMinuteStr);
int endMinutes = convertToMinutes(endHourMinuteStr);
List<String> res = new ArrayList<>();
for (int currentMinutes = startMinutes; currentMinutes < endMinutes; currentMinutes += minutes) {
res.add(convertToHourMinuteStr(currentMinutes));
}
return res;
}
private static int convertToMinutes(String hourMinuteStr) {
String[] parts = hourMinuteStr.split(":");
int hours = Integer.parseInt(parts[0]);
int minutes = Integer.parseInt(parts[1]);
return hours * 60 + minutes;
}
private static String convertToHourMinuteStr(int minutes) {
int hours = minutes / 60;
minutes %= 60;
return String.format("%02d:%02d", hours, minutes);
}
public static void main(String[] args) {
String startHourMinuteStr = "07:00";
String endHourMinuteStr = "9:10";
Integer intervalMinutes = 5;
List<String> intervals = getCustomTimeIntervals(startHourMinuteStr, endHourMinuteStr, intervalMinutes);
for (String interval : intervals) {
System.out.println(interval);
}
}
} }
...@@ -50,4 +50,26 @@ public interface CrossDirDataHistMapper extends BaseMapper<CrossDirDataHistPO> { ...@@ -50,4 +50,26 @@ public interface CrossDirDataHistMapper extends BaseMapper<CrossDirDataHistPO> {
List<CrossDirDataHistPOExt> selectByMetrics(String crossId, int dirInt, int startTimeStamp, int endTimeStamp, List<String> laneIds); List<CrossDirDataHistPOExt> selectByMetrics(String crossId, int dirInt, int startTimeStamp, int endTimeStamp, List<String> laneIds);
List<CrossDirDataHistPO> selectByCrossIdsDirsAndTimestamp(List<String> crossIdList, List<Integer> dirCodeList, int startTimeStamp, int endTimeStamp);
List<CrossDirDataHistPO> selectByCrossIdDirsAndTimestamp(String crossId, List<Integer> dirCodeList, int startTimeStamp, int endTimeStamp);
List<CrossDirDataHistPO> selectByCrossDirAndTimeSection(
@Param("crossId") String crossId,
@Param("dirCode") Integer dirCode,
@Param("boStartDayStr") String boStartDayStr,
@Param("boEndDayStr") String boEndDayStr,
@Param("startHourMinuteStr") String startHourMinuteStr,
@Param("endHourMinuteStr") String endHourMinuteStr
);
List<CrossDirDataHistPO> selectByCrossDirsAndTimeSection(
@Param("crossId") String crossId,
@Param("dirCodeList") List<Integer> dirCodeList,
@Param("boStartDayStr") String boStartDayStr,
@Param("boEndDayStr") String boEndDayStr,
@Param("startHourMinuteStr") String startHourMinuteStr,
@Param("endHourMinuteStr") String endHourMinuteStr
);
} }
...@@ -16,4 +16,6 @@ public interface GreenwaveHistMapper { ...@@ -16,4 +16,6 @@ public interface GreenwaveHistMapper {
List<GreenwaveHistPOExt> selectRunMonitor(Date nowTime); List<GreenwaveHistPOExt> selectRunMonitor(Date nowTime);
List<GreenwaveHistPO> selectByTimeSection(String startTimeStr, String endTimeStr); List<GreenwaveHistPO> selectByTimeSection(String startTimeStr, String endTimeStr);
List<GreenwaveHistPO> selectByIdAndTimeSection(Integer greenwaveId, String startTimeStr, String endTimeStr);
} }
...@@ -39,7 +39,7 @@ public class CrossDirDataRealtimePO { ...@@ -39,7 +39,7 @@ public class CrossDirDataRealtimePO {
public Integer flow; public Integer flow;
@ApiModelProperty(name = "平均速度(km/h)",notes = "") @ApiModelProperty(name = "平均速度(km/h)",notes = "")
public Double speed; public Double speed;
@ApiModelProperty(name = "排队长(米)",notes = "") @ApiModelProperty(name = "排队长(米)",notes = "")
public Double queueLength; public Double queueLength;
@ApiModelProperty(name = "停车次数",notes = "") @ApiModelProperty(name = "停车次数",notes = "")
public Double stopTimes; public Double stopTimes;
......
...@@ -191,4 +191,58 @@ ...@@ -191,4 +191,58 @@
AND batch_time <![CDATA[ >= ]]> #{startTimeStamp} AND batch_time <![CDATA[ >= ]]> #{startTimeStamp}
</select> </select>
<select id="selectByCrossIdsDirsAndTimestamp" resultType="net.wanji.databus.po.CrossDirDataHistPO">
select <include refid="Base_Column_List"></include>
from t_cross_dir_data_hist
where cross_id in
<foreach collection="crossIdList" item="crossId" separator="," open="(" close=")">
#{crossId}
</foreach>
and dir_type in
<foreach collection="dirCodeList" item="dirCode" separator="," open="(" close=")">
#{dirCode}
</foreach>
and in_out_type = 1
and batch_time <![CDATA[ >= ]]> #{startTimeStamp}
and batch_time <![CDATA[ <= ]]> #{endTimeStamp}
order by batch_time
</select>
<select id="selectByCrossDirAndTimeSection" resultType="net.wanji.databus.po.CrossDirDataHistPO">
SELECT <include refid="Base_Column_List"></include>
FROM t_cross_dir_data_hist
WHERE cross_id = #{crossId}
AND dir_type = #{dirCode}
AND in_out_type = 1
AND DATE_FORMAT(FROM_UNIXTIME(batch_time), '%Y-%m-%d') BETWEEN #{boStartDayStr} AND #{boEndDayStr}
AND DATE_FORMAT(FROM_UNIXTIME(batch_time), '%H:%i') BETWEEN #{startHourMinuteStr} AND #{endHourMinuteStr}
</select>
<select id="selectByCrossIdDirsAndTimestamp" resultType="net.wanji.databus.po.CrossDirDataHistPO">
select <include refid="Base_Column_List"></include>
from t_cross_dir_data_hist
where cross_id = #{crossId}
and dir_type in
<foreach collection="dirCodeList" item="dirCode" separator="," open="(" close=")">
#{dirCode}
</foreach>
and in_out_type = 1
and batch_time <![CDATA[ >= ]]> #{startTimeStamp}
and batch_time <![CDATA[ <= ]]> #{endTimeStamp}
order by batch_time
</select>
<select id="selectByCrossDirsAndTimeSection" resultType="net.wanji.databus.po.CrossDirDataHistPO">
SELECT <include refid="Base_Column_List"></include>
FROM t_cross_dir_data_hist
WHERE cross_id = #{crossId}
AND dir_type in
<foreach collection="dirCodeList" item="dirCode" separator="," open="(" close=")">
#{dirCode}
</foreach>
AND in_out_type = 1
AND DATE_FORMAT(FROM_UNIXTIME(batch_time), '%Y-%m-%d') BETWEEN #{boStartDayStr} AND #{boEndDayStr}
AND DATE_FORMAT(FROM_UNIXTIME(batch_time), '%H:%i') BETWEEN #{startHourMinuteStr} AND #{endHourMinuteStr}
</select>
</mapper> </mapper>
\ No newline at end of file
...@@ -33,4 +33,12 @@ ...@@ -33,4 +33,12 @@
and t1.gmt_modified <![CDATA[ >= ]]> #{startTimeStr} and t1.gmt_modified <![CDATA[ >= ]]> #{startTimeStr}
</select> </select>
<select id="selectByIdAndTimeSection" resultType="net.wanji.databus.dao.entity.GreenwaveHistPO">
select <include refid="Base_Column_List"/>
from t_greenwave_hist
where id = #{greenwaveId}
and gmt_modified <![CDATA[ <= ]]> #{endTimeStr}
and gmt_modified <![CDATA[ >= ]]> #{startTimeStr}
</select>
</mapper> </mapper>
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