增加生成通过进路逻辑(大铁);修改进路办理条件检查及办理流程以兼容通过进路

This commit is contained in:
joylink_zhangsai 2022-05-09 17:01:58 +08:00
parent cd66dc8056
commit d4b8a99f50
7 changed files with 347 additions and 187 deletions

View File

@ -14,6 +14,7 @@ import club.joylink.rtss.vo.client.PageVO;
import club.joylink.rtss.vo.client.map.MapDataVO;
import club.joylink.rtss.vo.client.map.MapRouteQueryVO;
import club.joylink.rtss.vo.map.MapGraphDataNewVO;
import club.joylink.rtss.vo.map.MapRouteAspectVO;
import club.joylink.rtss.vo.map.MapVO;
import club.joylink.rtss.vo.map.graph.MapSignalButtonVO;
import club.joylink.rtss.vo.map.logic.MapRouteNewVO;
@ -237,6 +238,7 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
Map<String, MapRouteNewVO> routeVOMap = new LinkedHashMap<>(); //k - startSignal.code + destinationSignal.code
/* 列车进路 */
long trainStart = System.currentTimeMillis();
List<MapSignalButtonVO> buttonVOS = type_button_map.get(MapSignalButtonVO.Type.PICK);
if (!CollectionUtils.isEmpty(buttonVOS)) {
for (MapSignalButtonVO vo : buttonVOS) {
@ -247,23 +249,28 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
routeCodeGenerator, signalCode_button_map, routeVOMap, 0);
}
}
// /* 通过进路 */
// List<MapSignalButtonVO> passButtonVOS = type_button_map.get(MapSignalButtonVO.Type.PASS);
// if (!CollectionUtils.isEmpty(passButtonVOS)) {
// for (MapSignalButtonVO vo : passButtonVOS) {
// Signal signal = signalMap.get(vo.getSignalCode());
// BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(signal,
// String.format("按钮[%s]关联的信号机[%s]不存在", vo.getCode(), vo.getSignalCode()));
// generatePassRoute(signal, vo, routeMap,
// routeCodeGenerator, signalCode_button_map, routeVOMap, 0);
// }
// }
long dioStart = System.currentTimeMillis();
System.out.println("生成列车进路耗时:" + (dioStart - trainStart));
/* 调车进路(逻辑中不考虑调车终端按钮,因为暂时没遇到) */
signalMap.values().stream()
.filter(Signal::hasShuntingFunction)
.forEach(signal -> {
generateShuntingRoute(signal, new ArrayList<>(), new ArrayList<>(), routeMap, routeCodeGenerator, routeVOMap, 0);
});
long passStart = System.currentTimeMillis();
System.out.println("生成调车进路耗时:" + (passStart - dioStart));
/* 通过进路 */
List<MapSignalButtonVO> passButtonVOS = type_button_map.get(MapSignalButtonVO.Type.PASS);
if (!CollectionUtils.isEmpty(passButtonVOS)) {
for (MapSignalButtonVO vo : passButtonVOS) {
Signal signal = signalMap.get(vo.getSignalCode());
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(signal,
String.format("按钮[%s]关联的信号机[%s]不存在", vo.getCode(), vo.getSignalCode()));
generatePassRoute(signal, vo, routeMap,
routeCodeGenerator, signalCode_button_map, routeVOMap, 0);
}
}
System.out.println("生成通过进路耗时:" + (System.currentTimeMillis() - passStart));
routeVOMap.values().stream().map(MapRouteNewVO::convert2Draft).forEach(draftMapRoute -> {
draftMapRoute.setMapId(mapId);
@ -428,13 +435,68 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
}
}
private void generatePassRoute(Signal signal, MapSignalButtonVO vo, Map<String, Route> routeMap,
private void generatePassRoute(Signal signal, MapSignalButtonVO buttonVO, Map<String, Route> routeMap,
DraftMapCiDataGeneratorImpl.CodeGenerator routeCodeGenerator,
Map<String, List<MapSignalButtonVO>> signalCode_button_map,
Map<String, MapRouteNewVO> routeVOMap, int iter) {
MapRouteNewVO routeVO = new MapRouteNewVO();
routeVO.setMultiRoute(true);
routeVO.setStartSignalCode(signal.getCode());
List<MapRouteAspectVO> routeAspectVOS = new ArrayList<>();
routeVO.setRouteAspectList(routeAspectVOS);
Signal outboundSignal = null; //出站信号机
boolean right = signal.isRight();
Section section = signal.getSection();
section = section.getNextSection(right);
while (section != null) {
Signal destination = section.getSignalOf(!right);
if (destination != null) {
if (destination.isReceivingDepartureSignal()) {
routeVO.setCode(routeCodeGenerator.next());
routeVO.setName("T_" + signal.getShowName() + "-" + destination.getShowName());
String startEndSignalCode = outboundSignal.getCode() + destination.getCode();
MapRouteNewVO departureRoute = routeVOMap.get(startEndSignalCode); //发车进路
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(departureRoute.getName().startsWith("L"),
String.format("信号机[%s]的通过进路的发车进路[%s]不是列车进路", signal.getCode(), departureRoute.getCode()));
routeAspectVOS.add(new MapRouteAspectVO(departureRoute.getCode(), departureRoute.getSignalAspect()));
routeVO.setEndSectionCode(departureRoute.getEndSectionCode());
List<MapSignalButtonVO> buttons = signalCode_button_map.get(destination.getCode());
MapSignalButtonVO endButton = buttons.stream().filter(vo -> MapSignalButtonVO.Type.PICK.equals(vo.getType()))
.limit(1).findAny().orElse(null);
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(endButton,
String.format("以信号机[%s]、[%s]为始终端的通过进路,终端信号机无列车信号按钮", signal.getCode(), destination.getCode()));
routeVO.setBtnCodeList(Arrays.asList(buttonVO.getCode(), endButton.getCode()));
routeVOMap.put(signal.getCode() + destination.getCode(), routeVO);
break;
} else if (destination.isShunting2()) {
String startEndSignalCode = signal.getCode() + destination.getCode();
MapRouteNewVO receivingRoute = routeVOMap.get(startEndSignalCode);
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(receivingRoute,
String.format("[%s]接车进路不存在", startEndSignalCode));
routeVO.setStartSectionCode(receivingRoute.getStartSectionCode());
routeAspectVOS.add(new MapRouteAspectVO(receivingRoute.getCode(), receivingRoute.getSignalAspect()));
outboundSignal = section.getSignalOf(right);
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(outboundSignal,
String.format("股道[%s]无出站信号机", section.getCode()));
}
}
Section next = section.getNextSection(right);
if (next == null) {
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(section.isSwitchTrack() && section.getNextSection(!right) != null,
String.format("信号机[%s]未找到终端信号机", signal.getCode()));
Switch relSwitch = section.getRelSwitch();
if (relSwitch.isA(section)) {
next = relSwitch.getB();
} else if (relSwitch.isB(section)) {
next = relSwitch.getA();
} else {
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception(String.format("信号机[%s]路径上的区段[%s]是道岔的C区段",
signal.getCode(), section.getCode()));
}
}
section = next;
}
}
/**
@ -446,6 +508,7 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
* 3.1.接车进路经过反位道岔的是黄黄否则是
* 3.2.发车进路绿
* 4.如果始终端信号机有多条进路反位道岔少的优先其次反位道岔更靠后的优先西贺村联锁表
* 5.锁闭区段接车进路锁闭到终端信号机所在区段发车进路锁闭到终端信号机前一个区段
*/
private void generateTrainRoute(Signal startSignal, MapSignalButtonVO startButton, List<Section> sections,
List<SwitchElement> switches, Map<String, Route> routeMap,
@ -478,6 +541,9 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
route.setInterlockStation(startSignal.getInterlockStation());
route.setStart(startSignal);
route.setDestination(endSignal);
if (endSignal.isReceivingDepartureSignal()) {
sections.remove(sections.size() - 1);
}
route.setSectionList(sections);
// switches = switches.stream().distinct().collect(Collectors.toList());
route.setSwitchList(switches);

View File

@ -35,6 +35,14 @@ public class CiRouteService {
* @return
*/
public static Route.CheckFailMessage routeSetCheck(Simulation simulation, Route route) {
if (!CollectionUtils.isEmpty(route.getMultiRouteAspects())) {
for (Route.MultiRouteAspect multiRouteAspect : route.getMultiRouteAspects()) {
Route.CheckFailMessage checkFailMessage = routeSetCheck(simulation, multiRouteAspect.getRoute());
if (checkFailMessage != null) {
return checkFailMessage;
}
}
} else {
MapConfig config = simulation.getRepository().getConfig();
Signal start = route.getStart();
if (!config.isSignalBlockRouteSettable()) {
@ -115,6 +123,8 @@ public class CiRouteService {
}
return failMessage;
}
return null;
}
private static Route.CheckFailMessage monitorRouteOverlapConflictCheck(Simulation simulation, Route route) {
SimulationDataRepository repository = simulation.getRepository();
@ -220,6 +230,8 @@ public class CiRouteService {
return;
}
}
List<Route.MultiRouteAspect> multiRouteAspects = route.getMultiRouteAspects();
if (CollectionUtils.isEmpty(multiRouteAspects)) {
// 道岔位置转换
boolean mainRouteSwitchOnPos = this.switchControlService.batchTurnRouteSwitch(simulation, route.getSwitchList());
// 预先锁闭
@ -242,6 +254,21 @@ public class CiRouteService {
log.debug("进路[{}]信号开放,办理结束", route.debugStr());
route.settingOver();
}
} else {
//由远及近办理进路
for (int i = multiRouteAspects.size() - 1; i >= 0; i--) {
Route.MultiRouteAspect routeAspect = multiRouteAspects.get(i);
Route subRoute = routeAspect.getRoute();
if (!subRoute.isLock()) {
setRoute(simulation, subRoute);
break;
}
}
//最近的一条进路已经锁闭
if (multiRouteAspects.get(0).getRoute().isLock()) { //
route.settingOver();
}
}
}
}

View File

@ -262,12 +262,26 @@ public class InterlockBuilder2 {
List<MapRouteNewVO> routeList = logicData.getRouteList();
Map<String, Route> routeMap = new HashMap<>();
for (MapRouteNewVO routeVO : routeList) {
Route route;
if (routeVO.isMultiRoute()) {
continue;
}
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(routeMap.containsKey(routeVO.getCode()),
String.format("存在code重复的进路[%s]", routeVO.getCode()));
Route route = new Route(routeVO.getCode(), routeVO.getName());
route = new Route(routeVO.getCode(), routeVO.getName());
elementMap.put(route.getCode(), route);
List<Route.MultiRouteAspect> multiRouteAspects = new ArrayList<>();
route.setMultiRouteAspects(multiRouteAspects);
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertCollectionNotEmpty(routeVO.getRouteAspectList(),
String.format("组合进路[%s]中进路列表不能为null", routeVO.getCode()));
for (MapRouteAspectVO mapRouteAspectVO : routeVO.getRouteAspectList()) {
Route subRoute = (Route) elementMap.get(mapRouteAspectVO.getRouteCode());
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(subRoute,
String.format("组合进路[%s]的子进路[%s]不存在", route.getCode(), mapRouteAspectVO.getRouteCode()));
multiRouteAspects.add(new Route.MultiRouteAspect(subRoute, getAspect(errMsgList, mapRouteAspectVO.getSignalAspect())));
}
} else {
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(routeMap.containsKey(routeVO.getCode()),
String.format("存在code重复的进路[%s]", routeVO.getCode()));
route = new Route(routeVO.getCode(), routeVO.getName());
elementMap.put(route.getCode(), route);
routeMap.put(route.getCode(), route);
route.setTurnBack(routeVO.isTurnBack());
@ -276,10 +290,32 @@ public class InterlockBuilder2 {
route.setGuide(routeVO.isGuide());
route.setArs(routeVO.isArc());
route.setFlt(routeVO.isFlt());
SignalAspect aspect = getAspect(errMsgList, routeVO.getSignalAspect());
route.setAspect(aspect);
List<Section> sections = routeVO.getRouteSectionList().stream()
.map(sectionCode -> (Section) elementMap.get(sectionCode))
.collect(Collectors.toList());
route.setSectionList(sections);
List<SwitchElement> routeSwitchList = routeVO.getRouteSwitchList().stream().map(switchEle -> {
Switch aSwitch = (Switch) elementMap.get(switchEle.getSwitchCode());
return new SwitchElement(aSwitch, switchEle.isNormal());
}).collect(Collectors.toList());
route.setSwitchList(routeSwitchList);
List<String> flsListVO = routeVO.getFlsList();
if (!CollectionUtils.isEmpty(flsListVO)) {
List<RouteFls> flsList = flsListVO.stream().map(flsMap::get).collect(Collectors.toList());
route.setFlsList(flsList);
}
}
Signal start = (Signal) elementMap.get(routeVO.getStartSignalCode());
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(start,
String.format("进路[%s]的始端信号机[%s]不存在", routeVO.getId(), routeVO.getStartSignalCode()));
Signal destination = null;
if (start == null) {
errMsgList.add(String.format("进路[%s]的始端信号机[%s]不存在", routeVO.getCode(), routeVO.getStartSignalCode()));
} else {
route.setStart(start);
if (StringUtils.hasText(routeVO.getEndSignalCode())) {
destination = (Signal) elementMap.get(routeVO.getEndSignalCode());
} else {
start.getRouteList().add(route);
for (String bntCode : routeVO.getBtnCodeList()) {
Signal end;
@ -291,12 +327,35 @@ public class InterlockBuilder2 {
end = (Signal) elementMap.get(bntCode);
}
if (!end.equals(start)) {
route.setDestination(end);
destination = end;
break;
}
}
}
}
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(destination,
String.format("进路[%s]终端信号机不存在", route.getCode()));
route.setDestination(destination);
}
for (MapRouteNewVO routeVO : routeList) {
Route route = routeMap.get(routeVO.getCode());
if (!CollectionUtils.isEmpty(routeVO.getConflictRouteList())) {
List<Route> conflictRoutes = routeVO.getConflictRouteList().stream()
.map(o -> {
Route conflictRoute = routeMap.get(o);
if (conflictRoute == null) {
errMsgList.add(String.format("冲突进路[%s]不存在", o));
}
return conflictRoute;
}).collect(Collectors.toList());
route.setConflictingRouteList(conflictRoutes);
}
}
}
private static SignalAspect getAspect(List<String> errMsgList, Integer signalAspect) {
SignalAspect aspect = null;
switch (routeVO.getSignalAspect()) {
switch (signalAspect) {
case 1:
aspect = SignalAspect.R;
break;
@ -331,38 +390,9 @@ public class InterlockBuilder2 {
aspect = SignalAspect.RF;
break;
default:
errMsgList.add(String.format("未知的信号显示[%s]", routeVO.getSignalAspect()));
}
route.setAspect(aspect);
List<Section> sections = routeVO.getRouteSectionList().stream()
.map(sectionCode -> (Section) elementMap.get(sectionCode))
.collect(Collectors.toList());
route.setSectionList(sections);
List<SwitchElement> routeSwitchList = routeVO.getRouteSwitchList().stream().map(switchEle -> {
Switch aSwitch = (Switch) elementMap.get(switchEle.getSwitchCode());
return new SwitchElement(aSwitch, switchEle.isNormal());
}).collect(Collectors.toList());
route.setSwitchList(routeSwitchList);
List<String> flsListVO = routeVO.getFlsList();
if (!CollectionUtils.isEmpty(flsListVO)) {
List<RouteFls> flsList = flsListVO.stream().map(flsMap::get).collect(Collectors.toList());
route.setFlsList(flsList);
}
}
for (MapRouteNewVO routeVO : routeList) {
Route route = routeMap.get(routeVO.getCode());
if (!CollectionUtils.isEmpty(routeVO.getConflictRouteList())) {
List<Route> conflictRoutes = routeVO.getConflictRouteList().stream()
.map(o -> {
Route conflictRoute = routeMap.get(o);
if (conflictRoute == null) {
errMsgList.add(String.format("冲突进路[%s]不存在", o));
}
return conflictRoute;
}).collect(Collectors.toList());
route.setConflictingRouteList(conflictRoutes);
}
errMsgList.add(String.format("未知的信号显示[%s]", signalAspect));
}
return aspect;
}
private static void buildParkTimes(MapLogicDataNewVO logicData, Map<String, MapElement> elementMap, Map<String, StationParkTime> parkTimeMap,
@ -1531,6 +1561,8 @@ public class InterlockBuilder2 {
.map(mapElement -> ((Route) mapElement))
.collect(Collectors.toList());
for (Route route : routeList) {
if (!CollectionUtils.isEmpty(route.getMultiRouteAspects()))
continue;
List<Section> sectionList = route.getSectionList();
for (Section section : sectionList) {
if (Objects.equals(route.getLastRouteSection(), section)) { // 最后区段

View File

@ -811,6 +811,8 @@ public class CalculateService {
Map<Section, List<Route>> routeMap = new HashMap<>(); // 进路终端对应进路列表(ATP进路合并进正常进路终端)
routeList.sort(Comparator.comparing(Route::isAtp)); // 将ATP进路排在最后处理
for (Route route : routeList) {
if (!CollectionUtils.isEmpty(route.getMultiRouteAspects()))
continue;
Section lastRouteSection = route.getLastRouteSection();
List<Route> routes = routeMap.get(lastRouteSection);
if (routes == null) {

View File

@ -26,6 +26,7 @@ public class Route extends MapNamedElement {
this.psdList = new ArrayList<>();
this.espList = new ArrayList<>();
this.conflictingRouteList = new ArrayList<>();
this.sectionList = new ArrayList<>();
this.switchList = new ArrayList<>();
}
@ -97,6 +98,11 @@ public class Route extends MapNamedElement {
/**进路终端按钮信号机*/
private Signal destinationButtonSignal;
/**
* 组合进路中的所有单进路
*/
private List<MultiRouteAspect> multiRouteAspects;
// ------------------状态属性---------------------
/** ats自动控制 */
private boolean atsControl;
@ -718,4 +724,19 @@ public class Route extends MapNamedElement {
}
}
@Getter
public static class MultiRouteAspect {
private Route route;
/**
* route在该组合进路中的信号显示暂时没用
*/
private SignalAspect aspect;
public MultiRouteAspect(Route route, SignalAspect aspect) {
this.route = route;
this.aspect = aspect;
}
}
}

View File

@ -650,6 +650,13 @@ public class Signal extends DelayUnlockDevice {
return SignalType.RECEIVING.equals(type) || SignalType.DEPARTURE.equals(type);
}
/**
* 是列车兼调车信号机
*/
public boolean isShunting2() {
return SignalType.SHUNTING2.equals(type);
}
/**
* 引导信号延时关闭开始计时
*/

View File

@ -14,4 +14,9 @@ public class MapRouteAspectVO {
* 1-2-绿3-4-黄红5-绿绿6-绿黄7-黄黄8-黄闪黄9-白红10-11-12-红闪
*/
private Integer signalAspect;
public MapRouteAspectVO(String routeCode, Integer signalAspect) {
this.routeCode = routeCode;
this.signalAspect = signalAspect;
}
}