diff --git a/src/main/java/club/joylink/rtss/services/draftData/DraftMapCiDataGeneratorImpl.java b/src/main/java/club/joylink/rtss/services/draftData/DraftMapCiDataGeneratorImpl.java index e2dbf3736..a8fbe12bd 100644 --- a/src/main/java/club/joylink/rtss/services/draftData/DraftMapCiDataGeneratorImpl.java +++ b/src/main/java/club/joylink/rtss/services/draftData/DraftMapCiDataGeneratorImpl.java @@ -175,10 +175,7 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator { .filter(mapElement -> MapElement.DeviceType.SECTION.equals(mapElement.getDeviceType())) .map(mapElement -> (Section) mapElement) .collect(Collectors.toList()); - // 生成侧防 - if (config.isGenerateFls()) { - this.generateFls(switchList); - } + Map> overlapMap = new HashMap<>(); List approachList = new ArrayList<>(); log.info(String.format("共有信号机[%s]个", signalList.size())); @@ -214,6 +211,42 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator { generatedRouteList.stream().filter(route -> route.isGround()).count(), generatedRouteList.stream().filter(route -> route.isGuide()).count())); } + // 生成侧防,构建进路侧防关系 + if (config.isGenerateFls()) { + Map flsMap = this.generateFls(switchList); + for (Route route : generatedRouteList) { + // 进路道岔侧防 + List routeFlsList = new ArrayList<>(); + if (route.getSwitchList() != null) { + for (SwitchElement switchElement : route.getSwitchList()) { + String name = RouteFls.buildName(switchElement); + RouteFls routeFls = flsMap.get(name); + if (routeFls != null) { + routeFlsList.add(routeFls); + } + } + route.setFlsList(routeFlsList); + } + // 进路延续保护道岔侧防 + RouteOverlap overlap = route.getOverlap(); + if (overlap != null) { + List pathList = overlap.getPathList(); + for (SectionPath sectionPath : pathList) { + List overlapFlsList = new ArrayList<>(); + List overlapSwitchList = sectionPath.getSwitchList(); + if (overlapSwitchList != null) { + for (SwitchElement switchElement : overlapSwitchList) { + RouteFls routeFls = flsMap.get(RouteFls.buildName(switchElement)); + if (routeFls != null) { + overlapFlsList.add(routeFls); + } + } + } + sectionPath.setFlsList(overlapFlsList); + } + } + } + } // 根据配置生成折返进路 if (config.isGenerateTbRoute()) { List tbRouteList = this.generateTurnBackRoute(generatedRouteList, routeCodeGenerator, config); @@ -1058,23 +1091,30 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator { generatedRouteList.removeAll(removeList); } - private void generateFls(List switchList) { + private Map generateFls(List switchList) { CodeGenerator fpCodeGenerator = new CodeGenerator("Fls"); // 侧防 - List list = new ArrayList<>(); + Map map = new HashMap<>(); for (Switch aSwitch : switchList) { - RouteFls npFls = this.buildNpFls(aSwitch); + RouteFls npFls = this.buildNpFls(aSwitch, fpCodeGenerator); if (Objects.nonNull(npFls)) { - list.add(npFls); + map.put(npFls.getName(), npFls); } - RouteFls rpFls = this.buildRpFls(aSwitch); + RouteFls rpFls = this.buildRpFls(aSwitch, fpCodeGenerator); if (Objects.nonNull(rpFls)) { - list.add(rpFls); + map.put(rpFls.getName(), rpFls); } } + return map; } - private RouteFls buildNpFls(Switch aSwitch) { - RouteFls fls = new RouteFls(new SwitchElement(aSwitch, true)); + /** + * 构建道岔定位侧防 + * @param aSwitch + * @param fpCodeGenerator + * @return + */ + private RouteFls buildNpFls(Switch aSwitch, CodeGenerator fpCodeGenerator) { + RouteFls fls = new RouteFls(fpCodeGenerator.next(), new SwitchElement(aSwitch, true)); // 暂时只生成一级侧防 Switch linkedSwitch = aSwitch.queryLinkedSwitch(); if (Objects.nonNull(linkedSwitch)) { @@ -1082,7 +1122,7 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator { RouteFls.FlsElement flsElement = new RouteFls.FlsElement(new SwitchElement(linkedSwitch, true)); fls.addLevel1(flsElement); } else { - // 无联动道岔,则从道岔B区段向外查询,第一个反向信号机和经过的路径道岔位置构成一级侧防 + // 无联动道岔,则从道岔C区段向外查询,第一个反向信号机和经过的路径道岔位置构成一级侧防 Section c = aSwitch.getC(); if (c.getLeftSection() == null && c.getRightSection() == null) { // 尽头区段,不需构成侧防 @@ -1091,30 +1131,112 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator { BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(c.getLeftSection() != null && c.getRightSection() != null, String.format("道岔区段[%s]关联区段关系异常,只能最多一边关联,实际两边都关联了区段", c.debugStr())); boolean right = true; - Section section = c.getRightSection(); + Section startSection = c.getRightSection(); if (c.getLeftSection() != null) { // 左向区段存在,方向向左 right = false; - section = c.getLeftSection(); + startSection = c.getLeftSection(); } - while (Objects.nonNull(section)) { + Stack
sectionStack = new Stack<>(); + sectionStack.push(startSection); + int i = 0; + while (!sectionStack.isEmpty() && i < 100) { + ++i; + Section section = sectionStack.pop(); Signal oppositeSignal = section.getSignalOf(!right); - if (Objects.nonNull(oppositeSignal)) { + if (Objects.nonNull(oppositeSignal)) { // 找到反向信号机 Section firstSection = oppositeSignal.getSection().getSectionOf(oppositeSignal.isRight()); RouteFls.FlsElement flsElement; - if (firstSection.isSwitchTrack()) { + if (firstSection.isSwitchTrack() && !Objects.equals(aSwitch, firstSection.getRelSwitch())) { flsElement = new RouteFls.FlsElement(oppositeSignal, new SwitchElement(firstSection.getRelSwitch(), true)); } else { flsElement = new RouteFls.FlsElement(oppositeSignal); } fls.addLevel1(flsElement); + } else { // 未找到,取下一区段,入栈 + Section next = section.getSectionOf(right); + if (next != null) { + sectionStack.push(next); + } else { + if (section.isSwitchTrack() && section.getSectionOf(!right) != null) { + // 非尽头道岔区段 + Switch relSwitch = section.getRelSwitch(); + if (relSwitch.isA(section)) { + sectionStack.push(relSwitch.getC()); + sectionStack.push(relSwitch.getB()); + } else { + sectionStack.push(relSwitch.getA()); + } + } + } } } } - return null; + if (!fls.hasElement()) { + return null; + } + return fls; } - private RouteFls buildRpFls(Switch aSwitch) { - return null; + /** + * 构建道岔反位侧防 + * @param aSwitch + * @param fpCodeGenerator + * @return + */ + private RouteFls buildRpFls(Switch aSwitch, CodeGenerator fpCodeGenerator) { + RouteFls fls = new RouteFls(fpCodeGenerator.next(), new SwitchElement(aSwitch, false)); + // 暂只生成一级侧防 + Section b = aSwitch.getB(); + if (b.getLeftSection() == null && b.getRightSection() == null) { + // 尽头区段,不需构成侧防 + return null; + } + BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(b.getLeftSection() != null && b.getRightSection() != null, + String.format("道岔区段[%s]关联区段关系异常,只能最多一边关联,实际两边都关联了区段", b.debugStr())); + boolean right = true; + Section startSection = b.getRightSection(); + if (b.getLeftSection() != null) { // 左向区段存在,方向向左 + right = false; + startSection = b.getLeftSection(); + } + Stack
sectionStack = new Stack<>(); + sectionStack.push(startSection); + int i = 0; + while (!sectionStack.isEmpty() && i < 100) { + ++i; + Section section = sectionStack.pop(); + Signal oppositeSignal = section.getSignalOf(!right); + if (Objects.nonNull(oppositeSignal)) { // 找到反向信号机 + Section firstSection = oppositeSignal.getSection().getSectionOf(oppositeSignal.isRight()); + RouteFls.FlsElement flsElement; + if (firstSection.isSwitchTrack() && !Objects.equals(aSwitch, firstSection.getRelSwitch())) { + flsElement = new RouteFls.FlsElement(oppositeSignal, new SwitchElement(firstSection.getRelSwitch(), true)); + } else { + flsElement = new RouteFls.FlsElement(oppositeSignal); + } + fls.addLevel1(flsElement); + } else { // 未找到,取下一区段,入栈 + Section next = section.getSectionOf(right); + if (next != null) { + sectionStack.push(next); + } else { + if (section.isSwitchTrack() && section.getSectionOf(!right) != null) { + // 非尽头道岔区段 + Switch relSwitch = section.getRelSwitch(); + if (relSwitch.isA(section)) { + sectionStack.push(relSwitch.getC()); + sectionStack.push(relSwitch.getB()); + } else { + sectionStack.push(relSwitch.getA()); + } + } + } + } + } + if (!fls.hasElement()) { + return null; + } + return fls; } private void generateRunLevel(Map deviceMap, List errorList, diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapElement.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapElement.java index 4c1381c43..a90f4c95f 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapElement.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapElement.java @@ -39,6 +39,8 @@ public abstract class MapElement { ROUTE, /** 进路延续保护 */ OVERLAP, + /** 侧防 */ + FLANK_PROTECTION, /** 自动信号 */ AUTO_SIGNAL, /** 自动折返 */ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/RouteFls.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/RouteFls.java index 55bb4a7b2..34d73b5e9 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/RouteFls.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/RouteFls.java @@ -11,9 +11,8 @@ import java.util.List; */ @Getter @Setter -public class RouteFls { +public class RouteFls extends MapNamedElement { - private String name; /** * 所防护的道岔位置 */ @@ -23,10 +22,15 @@ public class RouteFls { private List level2List; - public RouteFls(SwitchElement base) { + public RouteFls(String code, SwitchElement base) { + super(code, buildName(base), DeviceType.FLANK_PROTECTION); this.base = base; } + public static String buildName(SwitchElement element) { + return String.format("Fls_%s_%s", element.getASwitch().getName(), element.isNormal() ? "N" : "R"); + } + public void addLevel1(FlsElement flsElement) { if (level1List == null) { level1List = new ArrayList<>(); @@ -34,6 +38,15 @@ public class RouteFls { level1List.add(flsElement); } + public boolean hasElement() { + return this.level1List != null && !this.level1List.isEmpty(); + } + + @Override + public void reset() { + + } + /** * 侧防元件 */ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/SectionPath.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/SectionPath.java index 6fa2ab87a..ea42ae4ab 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/SectionPath.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/SectionPath.java @@ -26,6 +26,9 @@ public class SectionPath { /** 道岔位置(如果有道岔的话) */ private List switchList; + /** 侧防 */ + private List flsList; + private List
sectionList; public SectionPath(boolean right) {