Commit 44545b62 authored by duanruiming's avatar duanruiming

[update] 实时监控优化

parent 00af15a2
......@@ -19,6 +19,6 @@ public interface CrossSchemeMapper {
* @param crossId
* @return
*/
List<CrossSchemePO> listCrossSchemeInfo(@Param("crossId") String crossId, @Param("schemeNo")String schemeNo);
List<CrossSchemePO> listCrossSchemeInfo(@Param("crossId") String crossId, @Param("schemeNo")String schemeNo, @Param("id")Integer id);
}
package net.wanji.opt.dao.mapper;
import net.wanji.opt.po.base.CrossPlanOptLogPO;
import net.wanji.opt.po.base.CrossSchemeOptLogPO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
......@@ -10,9 +11,11 @@ import java.util.List;
* @date 2023/01/31 18:32
*/
@Repository
public interface CrossPlanOptLogMapper {
public interface CrossSchemeOptLogMapper {
List<CrossPlanOptLogPO> selectByCrossId();
List<CrossSchemeOptLogPO> selectByCrossId();
int insertOne(CrossPlanOptLogPO entity);
int insertOne(CrossSchemeOptLogPO entity);
int insertBatch(@Param("list") List<CrossSchemeOptLogPO> list);
}
......@@ -17,7 +17,7 @@ public class CrossTurnDataRealtimeDTO {
private String turnId;
@ApiModelProperty(name = "转向类型:u掉头;l左转;s直行;r右转;", notes = "")
private Integer turnType;
private String turnType;
@ApiModelProperty(name = "驶入方向:1北;2东北;3东;4东南;5南;6西南;7西;8西北", notes = "")
private Integer inDir;
......
......@@ -15,7 +15,7 @@ public class CrossTurnInfoDTO {
private String turnId;
@ApiModelProperty(name = "转向类型:u掉头;l左转;s直行;r右转;",notes = "")
private Integer turnType;
private String turnType;
@ApiModelProperty(name = "驶入方向:1北;2东北;3东;4东南;5南;6西南;7西;8西北",notes = "")
private Integer inDir;
......
......@@ -9,13 +9,13 @@ import java.util.Date;
* @date 2023/01/31 18:20
*/
@Data
public class CrossPlanOptLogPO {
public class CrossSchemeOptLogPO {
private int id;
private String crossId;
private String planNo;
private String schemeNo;
private int dirType;
private int turnType;
private String turnType;
private int offset;
private int ringNo;
private String phaseNo;
......
......@@ -11,23 +11,30 @@ import net.wanji.common.utils.tool.DateUtil;
import net.wanji.common.utils.tool.StringUtils;
import net.wanji.databus.dao.entity.RidInfoEntity;
import net.wanji.databus.dao.mapper.RidInfoMapper;
import net.wanji.databus.entity.develop.servicedevelop.develop.StatusCodeEnum;
import net.wanji.feign.pojo.result.JsonViewObject;
import net.wanji.feign.pojo.vo.SchemeSendVO;
import net.wanji.feign.pojo.vo.SignalStatusVO;
import net.wanji.feign.service.UtcFeignClients;
import net.wanji.opt.dao.mapper.CrossPhaseMapper;
import net.wanji.opt.dao.mapper.CrossSchemeMapper;
import net.wanji.opt.dao.mapper.CrossSchemeOptLogMapper;
import net.wanji.opt.dto.*;
import net.wanji.opt.po.base.CrossPhasePO;
import net.wanji.opt.po.base.CrossSchemeOptLogPO;
import net.wanji.opt.po.base.CrossSchemePO;
import net.wanji.opt.service.CrossOptimizeService;
import net.wanji.opt.service.CrossSchedulesService;
import net.wanji.opt.service.CrossSchemeService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;
......@@ -42,25 +49,23 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
@Resource
CrossSchemeService crossSchemeService;
@Resource
CrossSchedulesService crossSchedulesService;
@Resource
CrossPhaseMapper crossPhaseMapper;
@Resource
CrossSchemeMapper crossSchemeMapper;
@Resource
RidInfoMapper ridInfoMapper;
@Resource
CrossSchemeOptLogMapper crossSchemeOptLogMapper;
@Resource
UtcFeignClients utcFeignClients;
static Set<String> CROSS_OPT = new HashSet<>(); // 记录已优化的路口
@Override
@Transactional
public String realtimeOptimize(List<CrossDataRealtimeDTO> abnormalCrossList) {
try {
......@@ -71,13 +76,13 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
// 获取所有信控路口转向实时数据
Map<String, List<CrossTurnDataRealtimeDTO>> turnDataRealtime = listTurnDataRealtime(abnormalCrossList);
// 恢复优化路口原始方案
// 恢复优化路口原始方案:上一批次优化后,路口正常需要恢复原始方案
restoreOptCrossOriSchema(abnormalCrossList, phaseMap);
Map<Integer, List<CrossDataRealtimeDTO>> crossDataMap = abnormalCrossList.stream().collect(Collectors.groupingBy(CrossDataRealtimeDTO::getStatus));
abnormalCrossList = crossDataMap.get(CrossStatusEnum.SPILLOVER.getCode()); // 溢出
if (abnormalCrossList != null && !abnormalCrossList.isEmpty()) {
// spilloverOpt();
spilloverOpt(abnormalCrossList, turnDataRealtime, phaseMap);
}
abnormalCrossList = crossDataMap.get(CrossStatusEnum.CONGESTION.getCode()); // 拥堵
if (abnormalCrossList != null && !abnormalCrossList.isEmpty()) {
......@@ -94,6 +99,78 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
return null;
}
/**
* 路口溢出优化
*
* @param abnormalCrossList
* @param turnDataRealtimeMap
* @param phaseMap
*/
private void spilloverOpt(List<CrossDataRealtimeDTO> abnormalCrossList, Map<String, List<CrossTurnDataRealtimeDTO>> turnDataRealtimeMap,
Map<String, CrossPhaseDTO> phaseMap) throws Exception {
Map<String, List<CrossDataRealtimeDTO>> congestCrossMap = abnormalCrossList.stream().collect(Collectors.groupingBy(CrossDataRealtimeDTO::getCrossId));
String crossId;
for (CrossDataRealtimeDTO cross : abnormalCrossList) {
crossId = cross.getCrossId();
// 判断信号机是否在线 todo 是否某些故障也不需要优化
// 判断当前路口是否存在特殊控制操作
if (isOffLineOrSpecialControlMode(crossId)) {
continue;
}
// 判断当前路口是否已优化
if (CROSS_OPT.contains(crossId)) {
continue;
}
// 判断路口是否是绿波
// 路口拥堵方向转向,dir_turn
List<String> optCrossDirTurnList = getOptCrossDirTurnList(cross);
// 溢出当前路口方向转向减少时间 10s
// 计算路口各转向所需的通行时长(秒)
List<CrossTurnDataRealtimeDTO> crossTurnDataRealtimeDTOS = turnDataRealtimeMap.get(crossId);
for (String dirTurn : optCrossDirTurnList) {
for (CrossTurnDataRealtimeDTO crossTurnDataRealtimeDTO : crossTurnDataRealtimeDTOS) {
Integer inDir = crossTurnDataRealtimeDTO.getInDir();
String turnType = crossTurnDataRealtimeDTO.getTurnType();
if (Objects.equals(dirTurn, String.join("_", String.valueOf(inDir), turnType))) {
crossTurnDataRealtimeDTO.setPassTime(-10.0);
}
}
}
// 溢出优化当前路口 直行
doExecuteCrossOpt(crossTurnDataRealtimeDTOS, phaseMap, crossId, "3");
// 下游路口通过可排队长度计算可加可减时间优化
// 获取下游路口
List<RidInfoEntity> ridInfoEntities = ridInfoMapper.selectOne(crossId, "");
// 不存在下游路口,不做处理
if (CollectionUtils.isEmpty(ridInfoEntities)) {
continue;
}
for (String dirTurn : optCrossDirTurnList) {
Integer dir = Integer.valueOf(dirTurn.substring(0, 1));
for (RidInfoEntity ridInfoEntity : ridInfoEntities) {
Integer inDir = ridInfoEntity.getInDir();
if (!congestCrossMap.containsKey(ridInfoEntity.getEndCrossId()) && Objects.equals(inDir, dir)) {
String endCrossId = ridInfoEntity.getEndCrossId();
List<CrossTurnDataRealtimeDTO> endcrossTurnDataRealtimeDTOS = turnDataRealtimeMap.get(endCrossId);
endcrossTurnDataRealtimeDTOS.forEach(item -> item.setPassTime(item.calPassTime(item)));
// 进行优化下发
doExecuteCrossOpt(crossTurnDataRealtimeDTOS, phaseMap, endCrossId, "3");
// 记录已优化的路口
CROSS_OPT.add(endCrossId);
}
}
}
// 记录已优化的路口
CROSS_OPT.add(crossId);
}
}
/**
* 路口拥堵优化
*
......@@ -116,31 +193,79 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
continue;
}
// 路口拥堵方向转向,dir_turn
List<String> optCrossDirTurnList = getOptCrossDirTurnList(cross);
// 判断当前路口是否已优化
if (CROSS_OPT.contains(crossId)) {
continue;
}
// 判断路口是否是绿波
// 获取上游路口
List<RidInfoEntity> ridInfoEntities = ridInfoMapper.selectOne("", crossId);
// 不存在上游路口,不做处理
if (CollectionUtils.isEmpty(ridInfoEntities)) {
continue;
}
// 判断当前路口是否已优化
if (CROSS_OPT.contains(crossId)) {
continue;
for (String dirTurn : optCrossDirTurnList) {
Integer dir = Integer.valueOf(dirTurn.substring(0, 1));
String turn = dirTurn.substring(2, 1);
// 拥堵路口对上游路口进行优化
for (RidInfoEntity ridInfoEntity : ridInfoEntities) {
Integer inDir = ridInfoEntity.getInDir();
// 拥堵列表包含上游路口,不需要操作, 否则当前路口进行优化,并且路口拥堵方向和驶入方向相同
// 优化当前开始路口的此方向直行,和逆时针方向左转
if (!congestCrossMap.containsKey(ridInfoEntity.getEndCrossId()) && Objects.equals(inDir, dir)) {
String startCrossId = ridInfoEntity.getStartCrossId();
// 计算上游路口各转向所需的通行时长(秒) 此方向和逆时针左转可可减时间 10s
List<CrossTurnDataRealtimeDTO> crossTurnDataRealtimeDTOS = turnDataRealtimeMap.get(startCrossId);
for (CrossTurnDataRealtimeDTO crossTurnDataRealtimeDTO : crossTurnDataRealtimeDTOS) {
Integer startInDir = crossTurnDataRealtimeDTO.getInDir();
if (Objects.equals(startInDir, dir) && Objects.equals("s", turn)) {
crossTurnDataRealtimeDTO.setPassTime(-10.0);
}
if (Objects.equals(startInDir, (dir + 2) == 9 ? 1 : dir + 2) && Objects.equals("l", turn)) {
crossTurnDataRealtimeDTO.setPassTime(-10.0);
}
}
// 进行优化下发
doExecuteCrossOpt(crossTurnDataRealtimeDTOS, phaseMap, startCrossId, "2");
// 记录已优化的路口
CROSS_OPT.add(crossId);
}
}
}
// 拥堵路口对上游路口进行优化
for (RidInfoEntity ridInfoEntity : ridInfoEntities) {
// 拥堵列表包含上游路口,不需要操作, 否则当前路口进行优化 优化当前开始路口的此方向直行,和逆时针方向左转
if (!congestCrossMap.containsKey(ridInfoEntity.getEndCrossId())) {
String startCrossId = ridInfoEntity.getStartCrossId();
doExecuteCrossOpt(turnDataRealtimeMap, phaseMap, startCrossId);
}
}
/**
* 当前路口异常转向列表 element:dir_turn
*
* @param cross
* @return
*/
private static List<String> getOptCrossDirTurnList(CrossDataRealtimeDTO cross) {
List<String> crossIdDirTurnList = new ArrayList<>();
List<CrossDirInfoDTO> dirList = cross.getDirList();
List<CrossTurnInfoDTO> turnList = cross.getTurnList();
if (!CollectionUtils.isEmpty(dirList) && !CollectionUtils.isEmpty(turnList)) {
for (CrossDirInfoDTO crossDirInfoDTO : dirList) {
Integer dirType = crossDirInfoDTO.getDirType();
Integer inOutType = crossDirInfoDTO.getInOutType();
for (CrossTurnInfoDTO crossTurnInfoDTO : turnList) {
Integer inDir = crossTurnInfoDTO.getInDir();
String turnType = crossTurnInfoDTO.getTurnType();
// 路口方向进口=驶入方向
if (Objects.equals(dirType, inDir) && Objects.equals(1, inOutType) && Objects.equals("s", turnType)) {
String str = String.join("_", crossDirInfoDTO.getCrossDirId(), turnType);
crossIdDirTurnList.add(str);
}
}
}
// 判断路口是否是绿波
// 记录已优化的路口
CROSS_OPT.add(crossId);
}
return crossIdDirTurnList;
}
/**
......@@ -152,6 +277,7 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
private static void setTurnList(List<CrossDataRealtimeDTO> abnormalCrossList, Map<String, CrossPhaseDTO> phaseMap) {
for (CrossDataRealtimeDTO crossDataRealtimeDTO : abnormalCrossList) {
List<CrossTurnInfoDTO> turnList = new ArrayList<>();
List<CrossDirInfoDTO> dirList = new ArrayList<>();
for (Map.Entry<String, CrossPhaseDTO> entry : phaseMap.entrySet()) {
String crossDirTurn = entry.getKey();
String[] split = crossDirTurn.split(Constants.SystemParam.SEPARATOR_UNDER_LINE);
......@@ -160,12 +286,20 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
String turn = split[2];
CrossTurnInfoDTO crossTurnInfoDTO = new CrossTurnInfoDTO();
CrossDirInfoDTO crossDirInfoDTO = new CrossDirInfoDTO();
if (StringUtils.equalsIgnoreCase(crossId, crossDataRealtimeDTO.getCrossId())) {
crossTurnInfoDTO.setTurnType(Integer.valueOf(turn));
crossDirInfoDTO.setCrossId(crossId);
crossDirInfoDTO.setInOutType(1);
crossDirInfoDTO.setDirType(Integer.valueOf(dir));
dirList.add(crossDirInfoDTO);
crossTurnInfoDTO.setTurnType(turn);
crossTurnInfoDTO.setInDir(Integer.valueOf(dir));
turnList.add(crossTurnInfoDTO);
}
}
crossDataRealtimeDTO.setDirList(dirList.stream().distinct().collect(Collectors.toList()));
crossDataRealtimeDTO.setTurnList(turnList);
}
}
......@@ -215,8 +349,11 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
}
// 判断路口是否是绿波
// 计算路口各转向所需的通行时长(秒)
List<CrossTurnDataRealtimeDTO> crossTurnDataRealtimeDTOS = turnDataRealtimeMap.get(crossId);
crossTurnDataRealtimeDTOS.forEach(item -> item.setPassTime(item.calPassTime(item)));
// 执行路口优化
doExecuteCrossOpt(turnDataRealtimeMap, phaseMap, crossId);
doExecuteCrossOpt(crossTurnDataRealtimeDTOS, phaseMap, crossId, "1");
// 记录已优化的路口
CROSS_OPT.add(crossId);
......@@ -228,19 +365,15 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
* 执行路口优化逻辑
* 计算路口相位优化时长并下发方案
*
* @param turnDataRealtimeMap
* @param crossTurnDataRealtimeDTOS
* @param phaseMap
* @param crossId
* @throws Exception
*/
private void doExecuteCrossOpt(Map<String, List<CrossTurnDataRealtimeDTO>> turnDataRealtimeMap, Map<String, CrossPhaseDTO> phaseMap, String crossId) throws Exception {
// 计算路口各转向所需的通行时长(秒)
List<CrossTurnDataRealtimeDTO> crossTurnDataRealtimeDTOS = turnDataRealtimeMap.get(crossId);
crossTurnDataRealtimeDTOS.forEach(item -> item.setPassTime(item.calPassTime(item)));
private void doExecuteCrossOpt(List<CrossTurnDataRealtimeDTO> crossTurnDataRealtimeDTOS, Map<String, CrossPhaseDTO> phaseMap, String crossId, String optType) throws Exception {
// 计算路口各相位调整时长(秒)
Map<String, Integer> phaseTimeOptResultMap = new HashMap<>();
Map<Integer, String> timeOffsetPhaseMap = getTimeOffsetPhaseMap(phaseMap, crossTurnDataRealtimeDTOS);
Map<String, Integer> timeOffsetPhaseMap = getTimeOffsetPhaseMap(phaseMap, crossTurnDataRealtimeDTOS);
// 是否需要拆分相位
if (isSplitPhase(timeOffsetPhaseMap)) {
......@@ -250,10 +383,55 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
// 修改原始方案绿灯时间为优化后时间,方案下发
SchemeSendVO schemeSendVO = getSchemeSendVO(crossId, phaseMap, phaseTimeOptResultMap);
JsonViewObject jsonViewObject = utcFeignClients.schemeSend(schemeSendVO);
//todo test下发成功
jsonViewObject.success();
if (Objects.isNull(jsonViewObject) || jsonViewObject.getCode() != 200) {
log.error("实时监控路口优化方案下发远程调用异常!", jsonViewObject);
throw new Exception();
}
// 将优化记录插入方案优化记录表
insertCrossSchemeOptLog(phaseTimeOptResultMap, phaseMap, optType);
}
/**
* 将优化记录数据[按路口相位转向]插入到优化记录表这种
*
* @param phaseTimeOptResultMap
* @param phaseMap
*/
private void insertCrossSchemeOptLog(Map<String, Integer> phaseTimeOptResultMap, Map<String, CrossPhaseDTO> phaseMap, String optType) {
List<CrossSchemeOptLogPO> insertList = new ArrayList<>();
// 数据批次
long dataBatchTimeLong = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
for (Map.Entry<String, CrossPhaseDTO> item : phaseMap.entrySet()) {
CrossSchemeOptLogPO crossSchemeOptLogPO = new CrossSchemeOptLogPO();
CrossPhaseDTO crossPhaseDTO = item.getValue();
BeanUtils.copyProperties(crossPhaseDTO, crossSchemeOptLogPO);
crossSchemeOptLogPO.setSchemeNo(String.valueOf(crossPhaseDTO.getSchemeId()));
crossSchemeOptLogPO.setPhaseOrderId(crossPhaseDTO.getSort());
crossSchemeOptLogPO.setStartTime(new Date());
crossSchemeOptLogPO.setOptType("1");// 自动优化
crossSchemeOptLogPO.setOptType(optType);
crossSchemeOptLogPO.setOptResult(StatusCodeEnum.STATUS_00200.getMessage());
crossSchemeOptLogPO.setOptResultDesc(StatusCodeEnum.STATUS_00200.getDetail());
crossSchemeOptLogPO.setDataBatchTime((int) dataBatchTimeLong);
String phaseNo = crossPhaseDTO.getPhaseNo();
for (Map.Entry<String, Integer> entry : phaseTimeOptResultMap.entrySet()) {
if (Objects.equals(phaseNo, entry.getKey())) {
crossSchemeOptLogPO.setOptTime(entry.getValue());
crossSchemeOptLogPO.setOriGreenTime(crossPhaseDTO.getGreenTime());
}
}
insertList.add(crossSchemeOptLogPO);
}
// crossSchemeOptLogMapper.insertBatch(insertList);
}
/**
......@@ -267,12 +445,12 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
* @return
*/
private SchemeSendVO getSchemeSendVO(String crossId, Map<String, CrossPhaseDTO> phaseMap, Map<String, Integer> phaseTimeOptResultMap) {
String key = String.join(Constants.SystemParam.SEPARATOR_UNDER_LINE, "1", "s");
String key = String.join(Constants.SystemParam.SEPARATOR_UNDER_LINE, crossId, "1", "S");
CrossPhaseDTO crossPhaseDTO = phaseMap.get(key);
String planNo = crossPhaseDTO.getPlanNo();
Integer schemeId = crossPhaseDTO.getSchemeId();
List<CrossSchemePO> crossSchemePOS = crossSchemeMapper.listCrossSchemeInfo(crossId, planNo);
List<CrossPhasePO> crossPhasePOS = crossPhaseMapper.listCrossPhase(crossId, planNo);
List<CrossSchemePO> crossSchemePOS = crossSchemeMapper.listCrossSchemeInfo(crossId, null, schemeId);
List<CrossPhasePO> crossPhasePOS = crossPhaseMapper.listCrossPhase(crossId, String.valueOf(schemeId));
Map<Integer, List<CrossPhasePO>> ringNoPhasePOMap = crossPhasePOS.stream().collect(Collectors.groupingBy(CrossPhasePO::getRingNo));
SchemeSendVO schemeSendVO = new SchemeSendVO();
......@@ -307,17 +485,18 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
/**
* 在最大最小绿范围内,通过转向优化计算相位可优化时间
* key:相位号 value:offsetTime
*
* @param timeOffsetPhaseMap
* @return
*/
private static Map<String, Integer> getPhaseTimeOptMap(Map<Integer, String> timeOffsetPhaseMap) {
private static Map<String, Integer> getPhaseTimeOptMap(Map<String, Integer> timeOffsetPhaseMap) {
HashMap<String, Integer> phaseTimeOptResultMap = new HashMap<>();
// key:相位号 value:最大可加减时间
Map<String, Integer> phaseOffsetTimeSetMap = new HashMap<>();
for (Map.Entry<Integer, String> entry : timeOffsetPhaseMap.entrySet()) {
Integer offsetTime = entry.getKey();
String phaseNo = entry.getValue();
for (Map.Entry<String, Integer> entry : timeOffsetPhaseMap.entrySet()) {
Integer offsetTime = entry.getValue() == null ? 0 : entry.getValue();
String phaseNo = entry.getKey();
if (timeOffsetPhaseMap.containsValue(phaseNo)) {
Integer currentOffsetTime = phaseOffsetTimeSetMap.get(phaseNo);
if (Math.abs(offsetTime) > Math.abs(currentOffsetTime)) {
......@@ -360,11 +539,11 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
* @param timeOffsetPhaseMap
* @return
*/
private boolean isSplitPhase(Map<Integer, String> timeOffsetPhaseMap) {
private boolean isSplitPhase(Map<String, Integer> timeOffsetPhaseMap) {
HashMap<String, Boolean> phaseOffsetMap = new HashMap<>();
for (Map.Entry<Integer, String> entry : timeOffsetPhaseMap.entrySet()) {
Boolean gtZore = entry.getKey() >= 0 ? Boolean.TRUE : Boolean.FALSE;
String phaseNo = entry.getValue();
for (Map.Entry<String, Integer> entry : timeOffsetPhaseMap.entrySet()) {
Boolean gtZore = entry.getValue() >= 0 ? Boolean.TRUE : Boolean.FALSE;
String phaseNo = entry.getKey();
if (phaseOffsetMap.containsKey(phaseNo) && !phaseOffsetMap.containsValue(gtZore)) {
return true;
}
......@@ -382,12 +561,12 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
*
* @param phaseMap
* @param crossTurnDataRealtimeDTOS
* @return key:相位可加减时间 value:相位编号
* @return key:相位编号 value:相位可加减时间
*/
private Map<Integer, String> getTimeOffsetPhaseMap(Map<String, CrossPhaseDTO> phaseMap, List<CrossTurnDataRealtimeDTO> crossTurnDataRealtimeDTOS) {
Map<Integer, String> timeOffsetPhaseMap = new HashMap<>();
private Map<String, Integer> getTimeOffsetPhaseMap(Map<String, CrossPhaseDTO> phaseMap, List<CrossTurnDataRealtimeDTO> crossTurnDataRealtimeDTOS) {
Map<String, Integer> timeOffsetPhaseMap = new HashMap<>();
crossTurnDataRealtimeDTOS.forEach(item -> {
String key = String.join(Constants.SystemParam.SEPARATOR_UNDER_LINE, String.valueOf(item.getInDir()), String.valueOf(item.getTurnType()));
String key = String.join(Constants.SystemParam.SEPARATOR_UNDER_LINE, item.getCrossId(), String.valueOf(item.getInDir()), String.valueOf(item.getTurnType()));
Double passTime = item.getPassTime();
phaseMap.entrySet().forEach(entry -> {
......@@ -398,7 +577,19 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
if (StringUtils.equalsIgnoreCase(key, crossIdDirTurn)) {
Integer realOptGreenTime = getRealOptGreenTime(passTime, crossPhaseDTO);
Integer greenTimeOffset = realOptGreenTime - crossPhaseDTO.getGreenTime() - crossPhaseDTO.getGreenFlashTime();
timeOffsetPhaseMap.put(greenTimeOffset, phaseNo);
Integer realGreenTimeOffset = 0;
if (!timeOffsetPhaseMap.isEmpty() && timeOffsetPhaseMap.get(phaseNo) != null) {
realGreenTimeOffset = timeOffsetPhaseMap.get(phaseNo);
timeOffsetPhaseMap.put(phaseNo, greenTimeOffset);
if (greenTimeOffset < 0 && realGreenTimeOffset > greenTimeOffset) {
timeOffsetPhaseMap.put(phaseNo, realGreenTimeOffset);
}
if (greenTimeOffset >= 0 && realGreenTimeOffset < greenTimeOffset) {
timeOffsetPhaseMap.put(phaseNo, realGreenTimeOffset);
}
} else {
timeOffsetPhaseMap.put(phaseNo, greenTimeOffset);
}
}
});
});
......@@ -406,11 +597,11 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
}
private Integer getRealOptGreenTime(Double passTime, CrossPhaseDTO crossPhaseDTO) {
int passTimeInt = passTime.intValue();
int passTimeInt = passTime == null ? 0 : passTime.intValue();
if (passTimeInt <= crossPhaseDTO.getMinGreenTime()) {
passTimeInt = crossPhaseDTO.getMinGreenTime();
}
if (passTime >= crossPhaseDTO.getMaxGreenTime()) {
if (passTimeInt >= crossPhaseDTO.getMaxGreenTime()) {
passTimeInt = crossPhaseDTO.getMaxGreenTime();
}
return passTimeInt;
......@@ -494,7 +685,7 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
private List<CrossSectionDTO> listSection(List<CrossSchedulesDTO> schedulesDTOList) throws Exception {
List<CrossSectionDTO> sectionInfos = new ArrayList<>();
long currentTime = DateUtil.dateToStamp(DateUtil.getTime(), net.wanji.common.framework.Constants.DATE_FORMAT.E_DATE_FORMAT_TIME.getStrFormat()); // 获取当前时间
LocalTime currentTime = LocalTime.parse(DateUtil.getTime());
int week = DateUtil.getWeek(new Date()) == Constants.SystemParam.ZERO ? WeekEnum.SUNDAY.getCode() : DateUtil.getWeek(new Date()); // 获取当前星期
for (CrossSchedulesDTO schedules : schedulesDTOList) {
......@@ -506,18 +697,21 @@ public class CrossOptimizeServiceImpl implements CrossOptimizeService {
}
// 时段信息列表
for (CrossSectionDTO section : schedules.getSectionInfos()) {
// 过滤非当前时段数据
if (currentTime < DateUtil.dateToStamp(section.getStartTime()) || currentTime > DateUtil.dateToStamp(section.getEndTime())) {
continue;
}
// 过滤控制模式为“非定周期”的数据
if (!ControlModeEnum.FIXED_PERIOD.equals(section.getControlMode())) {
continue;
if (Objects.nonNull(schedules.getSectionInfos())) {
for (CrossSectionDTO section : schedules.getSectionInfos()) {
LocalTime startTime = LocalTime.parse(section.getStartTime());
LocalTime endTime = LocalTime.parse(section.getEndTime());
// 过滤非当前时段数据
if (currentTime.isBefore(startTime) || currentTime.isAfter(endTime)) {
continue;
}
// 过滤控制模式为“非定周期”的数据
if (!ControlModeEnum.FIXED_PERIOD.getCode().equals(section.getControlMode())) {
continue;
}
section.setPlanNo(schedules.getPlanNo());
sectionInfos.add(section);
}
section.setPlanNo(schedules.getPlanNo());
sectionInfos.add(section);
}
}
return sectionInfos;
......
......@@ -34,7 +34,7 @@ public class CrossSchemeServiceImpl implements CrossSchemeService {
@Override
public List<CrossSchemeDTO> listCrossSchemeInfo(String crossId) {
List<CrossSchemePO> schemePOList = crossSchemeMapper.listCrossSchemeInfo(crossId, "");
List<CrossSchemePO> schemePOList = crossSchemeMapper.listCrossSchemeInfo(crossId, "", null);
return BeanListUtils.populateList(schemePOList, new ArrayList<>(), CrossSchemeDTO.class);
}
......
......@@ -3,9 +3,11 @@ package net.wanji.opt.task;
import lombok.extern.slf4j.Slf4j;
import net.wanji.common.enums.CrossStatusEnum;
import net.wanji.common.framework.Constants;
import net.wanji.opt.dao.mapper.trend.CrossDataRealtimeMapper;
import net.wanji.opt.dto.CrossDataRealtimeDTO;
import net.wanji.opt.po.CrossDataRealtimePO;
import net.wanji.opt.po.trend.CrossDataRealtimePO;
import net.wanji.opt.service.CrossOptimizeService;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
......@@ -25,6 +27,8 @@ public class CrossMonitorTask {
@Resource
CrossOptimizeService crossOptimizeService;
@Resource
CrossDataRealtimeMapper crossDataRealtimeMapper;
/**
* 路口实时监测
......@@ -55,6 +59,7 @@ public class CrossMonitorTask {
/**
* 获取异常路口数据
*
* @return
*/
public List<CrossDataRealtimeDTO> listAbnormalCross(List<CrossDataRealtimePO> crossDataRealtimePOList) {
......@@ -62,21 +67,22 @@ public class CrossMonitorTask {
List<CrossDataRealtimeDTO> dtoList = new ArrayList<>();
CrossDataRealtimeDTO dto = null;
int status = 0;
for (CrossDataRealtimePO po: crossDataRealtimePOList) {
for (CrossDataRealtimePO po : crossDataRealtimePOList) {
// 获取失衡、拥堵、溢出路口数据
if(Constants.SystemParam.NO.equals(po.getIsSpillover()) || Constants.SystemParam.NO.equals(po.getIsCongestion()) || Constants.SystemParam.NO.equals(po.getIsUnbalance())) {
if (Constants.SystemParam.NO.equals(po.getIsSpillover()) || Constants.SystemParam.NO.equals(po.getIsCongestion()) || Constants.SystemParam.NO.equals(po.getIsUnbalance())) {
continue;
}
if(Constants.SystemParam.YES.equals(po.getIsSpillover())) { // 溢出
if (Constants.SystemParam.YES.equals(po.getIsSpillover())) { // 溢出
status = CrossStatusEnum.SPILLOVER.getCode();
} else if(Constants.SystemParam.YES.equals(po.getIsCongestion())) { // 拥堵
} else if (Constants.SystemParam.YES.equals(po.getIsCongestion())) { // 拥堵
status = CrossStatusEnum.CONGESTION.getCode();
} else if(Constants.SystemParam.YES.equals(po.getIsUnbalance())) { // 失衡
} else if (Constants.SystemParam.YES.equals(po.getIsUnbalance())) { // 失衡
status = CrossStatusEnum.UNBALANCE.getCode();
}
dto = new CrossDataRealtimeDTO();
BeanUtils.copyProperties(po, dto);
dto.setCrossId(po.getCrossId());
dto.setStatus(status);
dto.setDirList(null);
......@@ -89,13 +95,16 @@ public class CrossMonitorTask {
/**
* 获取路口实时监测数据
* (暂定从数据中心kafka获取)
*
* @return
*/
public List<CrossDataRealtimePO> listCrossDataRealtime() {
return new ArrayList<>();
// todo test数据
List<CrossDataRealtimePO> crossDataRealtimePOList = new ArrayList<>(1);
CrossDataRealtimePO crossDataRealtimePO = crossDataRealtimeMapper.selectById("14Q1409IRF0");
crossDataRealtimePOList.add(crossDataRealtimePO);
return crossDataRealtimePOList;
}
}
\ No newline at end of file
......@@ -13,11 +13,11 @@
<result property="schedulesId" column="schedulesId"/>
<result property="schedulesName" column="schedulesName"/>
<result property="status" column="status"/>
<result property="planId" column="planId"/>
<result property="planNo" column="planNo"/>
<result property="planId" column="plan_id"/>
<result property="planNo" column="plan_no"/>
<result property="crossId" column="cross_id"/>
<result property="week" column="week"/>
<result property="specialDate" column="specialDate"/>
<result property="specialDate" column="special_date"/>
</resultMap>
......@@ -39,8 +39,8 @@
<!-- 查询调度计划信息列表 -->
<select id="listSchedulesPlan" parameterType="String" resultMap="CrossSchedulesPlanPO">
SELECT
s.id schedules_id
,s.`name` schedules_name
s.id schedulesId
,s.`name` schedulesName
,s.`status`
,s.cross_id
,p.id plan_id
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.wanji.opt.dao.mapper.CrossPlanOptLogMapper">
<mapper namespace="net.wanji.opt.dao.mapper.CrossSchemeOptLogMapper">
<!-- 通用查询映射结果 -->
<resultMap type="net.wanji.opt.po.base.CrossPlanOptLogPO" id="BaseResultMap">
<resultMap type="net.wanji.opt.po.base.CrossSchemeOptLogPO" id="BaseResultMap">
<result property="id" column="id"/>
<result property="crossId" column="cross_id"/>
<result property="planNo" column="plan_no"/>
<result property="schemeNo" column="scheme_no"/>
<result property="dirType" column="dir_type"/>
<result property="turnType" column="turn_type"/>
<result property="offset" column="offset"/>
......@@ -28,7 +28,7 @@
</resultMap>
<sql id="Base_Column_List">
id, cross_id, plan_no, dir_type, turn_type, offset, ring_no, phase_no, phase_order_id, ori_green_time,
id, cross_id, scheme_no, dir_type, turn_type, offset, ring_no, phase_no, phase_order_id, ori_green_time,
opt_time, opt_type, opt_reason, start_time, end_time, is_relation, relation_cross_id, opt_result, opt_result_desc,
data_batch_time, restore_result
</sql>
......@@ -36,7 +36,7 @@
<select id="selectByCrossId" parameterType="String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from t_base_cross_plan_opt_log
from t_base_cross_scheme_opt_log
<where>
<if test="crossId != null and crossId != ''">
and cross_id = #{crossId}
......@@ -44,15 +44,29 @@
</where>
</select>
<insert id="insertOne" parameterType="net.wanji.opt.po.base.CrossPlanOptLogPO">
insert into t_base_cross_plan_opt_log (cross_id, plan_no, dir_type, turn_type, offset, ring_no, phase_no,
<insert id="insertOne" parameterType="net.wanji.opt.po.base.CrossSchemeOptLogPO">
insert into t_base_cross_scheme_opt_log (cross_id, scheme_no, dir_type, turn_type, offset, ring_no, phase_no,
phase_order_id, ori_green_time, opt_time, opt_type, opt_reason,
start_time,
end_time, is_relation, relation_cross_id, opt_result, opt_result_desc,
data_batch_time, restore_result)
values (#{crossId}, #{planNo}, #{dirType}, #{turnType}, #{offset}, #{ringNo}, #{phaseNo}, #{phaseOrderId},
values (#{crossId}, #{schemeNo}, #{dirType}, #{turnType}, #{offset}, #{ringNo}, #{phaseNo}, #{phaseOrderId},
#{oriGreenTime}, #{optTime}, #{optType}, #{optReason}, #{startTime}, #{endTime}, #{isRelation},
#{relationCrossId}, #{optResult}, #{optResultDesc}, #{dataBatchTime}, #{restoreResult})
</insert>
<insert id="insertBatch" parameterType="net.wanji.opt.po.base.CrossSchemeOptLogPO">
insert into t_base_cross_scheme_opt_log
(cross_id, scheme_no, dir_type, turn_type, offset, ring_no, phase_no,
phase_order_id, ori_green_time, opt_time, opt_type, opt_reason,
start_time, end_time, is_relation, relation_cross_id, opt_result, opt_result_desc,
data_batch_time, restore_result)
values
<foreach collection="list" item="entity" separator=",">
(#{entity.crossId}, #{entity.schemeNo}, #{entity.dirType}, #{entity.turnType}, #{entity.offset}, #{entity.ringNo}, #{entity.phaseNo}, #{entity.phaseOrderId},
#{entity.oriGreenTime}, #{entity.optTime}, #{entity.optType}, #{entity.optReason}, #{entity.startTime}, #{entity.endTime}, #{entity.isRelation},
#{entity.relationCrossId}, #{entity.optResult}, #{entity.optResultDesc}, #{entity.dataBatchTime}, #{entity.restoreResult})
</foreach>
</insert>
</mapper>
\ No newline at end of file
......@@ -31,6 +31,9 @@
<if test="schemeNo != null and schemeNo != ''">
and scheme_no = #{schemeNo}
</if>
<if test="id != null and id != ''">
and id = #{id}
</if>
</select>
......
......@@ -12,17 +12,17 @@ import java.util.List;
*/
@Repository
public interface RidInfoMapper {
Double selectRoadLength(@Param("startCrossid") String startCrossid,
@Param("endCrossid") String endCrossid);
Double selectRoadLength(@Param("startCrossId") String startCrossId,
@Param("endCrossId") String endCrossId);
String selectStartCrossOutDir(@Param("startCrossid") String startCrossid,
@Param("endCrossid") String endCrossid);
String selectStartCrossOutDir(@Param("startCrossId") String startCrossId,
@Param("endCrossId") String endCrossId);
String selectWkt(@Param("startCrossid") String startCrossid,
@Param("endCrossid") String endCrossid);
String selectWkt(@Param("startCrossId") String startCrossId,
@Param("endCrossId") String endCrossId);
List<RidInfoEntity> selectOne(@Param("startCrossid") String startCrossid,
@Param("endCrossid") String endCrossid);
List<RidInfoEntity> selectOne(@Param("startCrossId") String startCrossId,
@Param("endCrossId") String endCrossId);
RidInfoEntity selectByEndInDir(String endCrossId, int spilloverDirInt);
}
......@@ -40,19 +40,19 @@
<select id="selectRoadLength" resultType="java.lang.Double">
select length
from t_base_rid_info
where start_crossid = #{startCrossid} and end_crossid = #{endCrossid}
where start_crossid = #{startCrossId} and end_crossid = #{endCrossId}
</select>
<select id="selectStartCrossOutDir" resultType="java.lang.String">
select start_crossdirid
from t_base_rid_info
where start_crossid = #{startCrossid} and end_crossid = #{endCrossid}
where start_crossid = #{startCrossId} and end_crossid = #{endCrossId}
</select>
<select id="selectWkt" resultType="java.lang.String">
select wkt
from t_base_rid_info
where start_crossid = #{startCrossid} and end_crossid = #{endCrossid}
where start_crossid = #{startCrossId} and end_crossid = #{endCrossId}
</select>
<select id="selectOne" resultMap="BaseResultMap">
......@@ -61,10 +61,10 @@
from t_base_rid_info
<where>
<if test="startCrossId != null and startCrossId != ''">
and start_cross_id = #{startCrossid}
and start_cross_id = #{startCrossId}
</if>
<if test="endCrossId != null and endCrossId != ''">
and end_cross_id = #{endCrossid}
and end_cross_id = #{endCrossId}
</if>
</where>
</select>
......
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