diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcStationRunPlanLogService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcStationRunPlanLogService.java index 14b2e0cb2..6eff5d15c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcStationRunPlanLogService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcStationRunPlanLogService.java @@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.cbtc.ATS.service.runplan; import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; import club.joylink.rtss.simulation.cbtc.CTC.CTCLogicLoop; +import club.joylink.rtss.simulation.cbtc.CTC.CTCService; import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog; import club.joylink.rtss.simulation.cbtc.CTC.data.RouteSequence; import club.joylink.rtss.simulation.cbtc.Simulation; @@ -36,6 +37,9 @@ public class CtcStationRunPlanLogService { @Autowired private CTCLogicLoop ctcLogicLoop; + @Autowired + private CTCService ctcService; + /** * 批量修改运行计划 * @@ -232,6 +236,7 @@ public class CtcStationRunPlanLogService { ctcStationRunPlanLog.getArriveRunPlan().setTrackSection(arriveSection); changeRunPlanLog.setArriveRunPlan(new CtcStationRunPlanLog.RunPlanItem()); changeRunPlanLog.getArriveRunPlan().setTrackSection(arriveSection); + ctcService.runPlanItemUpdate(simulation, ctcStationRunPlanLog.getStation(), changeRunPlanLog.getArriveRunPlan(), false); } } if (!StringUtils.isEmpty(departSectionCode)) { @@ -241,6 +246,7 @@ public class CtcStationRunPlanLogService { ctcStationRunPlanLog.getDepartRunPlan().setTrackSection(departSection); changeRunPlanLog.setDepartRunPlan(new CtcStationRunPlanLog.RunPlanItem()); changeRunPlanLog.getDepartRunPlan().setTrackSection(departSection); + ctcService.runPlanItemUpdate(simulation, ctcStationRunPlanLog.getStation(), changeRunPlanLog.getArriveRunPlan(), true); } } if (changeRunPlanLog.getArriveRunPlan() != null || changeRunPlanLog.getDepartRunPlan() != null) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCLogicLoop.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCLogicLoop.java index 9022d9349..25467e479 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCLogicLoop.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCLogicLoop.java @@ -18,10 +18,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; @Component @@ -55,12 +52,14 @@ public class CTCLogicLoop { private void sendAllRouteSequenceMessage(Simulation simulation) { CtcRepository ctcRepository = simulation.getCtcRepository(); - Map map = new HashMap<>(); + List> list = new ArrayList<>(); for (RouteSequenceVO vo : ctcRepository.getRouteSequenceVOMap().values()) { + Map map = new HashMap<>(); map.put("stationCode", vo.getStationCode()); map.put("routeSequence", vo); + list.add(map); } - SocketMessageVO message = SocketMessageFactory.buildCtcRouteSequenceMessage(simulation.getId(), map); + SocketMessageVO message = SocketMessageFactory.buildCtcRouteSequenceMessage(simulation.getId(), list); stompMessageService.sendToUser(simulation.getSimulationUserIds(), message); } @@ -71,23 +70,29 @@ public class CTCLogicLoop { CtcRepository ctcRepository = simulation.getCtcRepository(); Map routeSequenceMap = ctcRepository.getRouteSequenceMap(); Map routeSequenceVOMap = ctcRepository.getRouteSequenceVOMap(); - Map map = new HashMap<>(); + List> list = new ArrayList<>(); if (CollectionUtils.isEmpty(routeSequenceVOMap)) { for (RouteSequence routeSequence : routeSequenceMap.values()) { RouteSequenceVO routeSequenceVO = new RouteSequenceVO(routeSequence); routeSequenceVOMap.put(routeSequenceVO.getStationCode(), routeSequenceVO); + Map map = new HashMap<>(); map.put("stationCode", routeSequenceVO.getStationCode()); map.put("routeSequence", routeSequenceVO); + list.add(map); } } else { - for (RouteSequenceVO vo : routeSequenceVOMap.values()) { - RouteSequence routeSequence = routeSequenceMap.get(vo.getStationCode()); + for (RouteSequence routeSequence : routeSequenceMap.values()) { + RouteSequenceVO vo = routeSequenceVOMap.get(routeSequence.getStationCode()); Map changed = vo.updateAndReturnChanged(routeSequence); - map.put("stationCode", vo.getStationCode()); - map.put("routeSequence", changed); + if (changed != null) { + Map map = new HashMap<>(); + map.put("stationCode", vo.getStationCode()); + map.put("routeSequence", changed); + list.add(map); + } } } - SocketMessageVO message = SocketMessageFactory.buildCtcRouteSequenceMessage(simulation.getId(), map); + SocketMessageVO message = SocketMessageFactory.buildCtcRouteSequenceMessage(simulation.getId(), list); stompMessageService.sendToUser(simulation.getSimulationUserIds(), message); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCService.java index 26821a24b..51791418d 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCService.java @@ -16,31 +16,11 @@ import java.util.Map; @Component public class CTCService { - public void generateRouteSequence(Simulation simulation) { - SimulationDataRepository repository = simulation.getRepository(); + public void runPlanItemUpdate(Simulation simulation, Station station, CtcStationRunPlanLog.RunPlanItem item, boolean departure) { CtcRepository ctcRepository = simulation.getCtcRepository(); - Map> stationLineMap = new HashMap<>(); - for (Station station : repository.getStationList()) { - stationLineMap.put(station.getCode(), new ArrayList<>()); - } - for (CtcStationRunPlanLog plan : ctcRepository.getAllRunPlanList()) { - List lines = stationLineMap.get(plan.getStation().getCode()); - CtcStationRunPlanLog.RunPlanItem arriveRunPlan = plan.getArriveRunPlan(); - if (arriveRunPlan != null) { - RouteSequence.Line line = RouteSequence.buildLine(arriveRunPlan, false); - lines.add(line); - } - CtcStationRunPlanLog.RunPlanItem departRunPlan = plan.getDepartRunPlan(); - if (departRunPlan != null) { - RouteSequence.Line line = RouteSequence.buildLine(departRunPlan, true); - lines.add(line); - } - } - Map routeSequenceMap = ctcRepository.getRouteSequenceMap(); - for (Station station : repository.getStationList()) { - RouteSequence routeSequence = new RouteSequence(station, stationLineMap.get(station.getCode())); - routeSequenceMap.put(station.getCode(), routeSequence); - } + ctcRepository.deleteRouteSequenceLine(station.getCode(), item); + RouteSequence.Line line = RouteSequence.buildLine(item, departure); + ctcRepository.addRouteSequenceLine(station.getCode(), line); } /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcRepository.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcRepository.java index 1c27d7f61..cfff14a4a 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcRepository.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcRepository.java @@ -15,7 +15,7 @@ import java.util.stream.Collectors; @Getter public class CtcRepository { /** - * 进路序列 + * 车站-进路序列。每个车站都应该有 * k - stationCode */ private final Map routeSequenceMap = new HashMap<>(); @@ -65,6 +65,20 @@ public class CtcRepository { */ private final Map> simulationRunPlanEffectAreaMap = new ConcurrentHashMap<>(); + + public void reset() { + // 编辑区清空 + this.simulationRunPlanEditAreaMap.clear(); + // 仿真运行数据直接清空 + this.simulationRunPlanMap.clear(); + this.allRunPlanList.clear(); + // 重置原始数据 + this.originRunPlanMap.values().forEach(runPlanMap -> runPlanMap.values().forEach(runPlan -> { + runPlan.reset(); + this.allRunPlanList.add(runPlan); + })); + } + /** * 添加至仿真中的行车计划 * @@ -168,17 +182,15 @@ public class CtcRepository { return routeSequence.getLine(tripNumber, routeCode); } - public void reset() { - // 编辑区清空 - this.simulationRunPlanEditAreaMap.clear(); - // 仿真运行数据直接清空 - this.simulationRunPlanMap.clear(); - this.allRunPlanList.clear(); - // 重置原始数据 - this.originRunPlanMap.values().forEach(runPlanMap -> runPlanMap.values().forEach(runPlan -> { - runPlan.reset(); - this.allRunPlanList.add(runPlan); - })); - // generateRouteSequence(); + public void deleteRouteSequenceLine(String stationCode, CtcStationRunPlanLog.RunPlanItem item) { + RouteSequence routeSequence = routeSequenceMap.get(stationCode); + if (routeSequence == null) + return; + routeSequence.deleteLines(item); + } + + public void addRouteSequenceLine(String stationCode, RouteSequence.Line line) { + RouteSequence routeSequence = routeSequenceMap.get(stationCode); + routeSequence.addLine(line); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequence.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequence.java index b0646abb7..dc4e82e9d 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequence.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequence.java @@ -8,11 +8,10 @@ import club.joylink.rtss.simulation.cbtc.data.map.Station; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; +import org.springframework.util.CollectionUtils; import java.time.LocalTime; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.stream.Collectors; @@ -60,8 +59,13 @@ public class RouteSequence { return 1; }); this.lines = lines; - this.tripLineMap = lines.stream().collect(Collectors.groupingBy(Line::getTripNumber)); - this.idLineMap = lines.stream().collect(Collectors.toMap(Line::getId, Function.identity())); + if (!CollectionUtils.isEmpty(lines)) { + this.tripLineMap = lines.stream().collect(Collectors.groupingBy(Line::getTripNumber)); + this.idLineMap = lines.stream().collect(Collectors.toMap(Line::getId, Function.identity())); + } else { + this.tripLineMap = new HashMap<>(); + this.idLineMap = new HashMap<>(); + } } public static Line buildLine(CtcStationRunPlanLog.RunPlanItem item, boolean departure) { @@ -130,6 +134,37 @@ public class RouteSequence { return station == null ? null : station.getCode(); } + public void deleteLines(CtcStationRunPlanLog.RunPlanItem item) { + Iterator iterator = lines.iterator(); + while (iterator.hasNext()) { + Line line = iterator.next(); + if (Objects.equals(line.getItem(), item)) { + iterator.remove(); + tripLineMap.remove(line.getTripNumber()); + idLineMap.remove(line.getId()); + } + } + } + + public void addLine(Line line) { + idLineMap.put(line.getId(), line); + List list = tripLineMap.computeIfAbsent(line.getTripNumber(), k -> new ArrayList<>()); + for (int i = 0, listSize = list.size(); i < listSize; i++) { + Line l = list.get(i); + if (l.getPlanTime().isAfter(line.getPlanTime())) { + list.add(i, line); + break; + } + } + for (int i = 0, linesSize = lines.size(); i < linesSize; i++) { + Line l = lines.get(i); + if (l.getPlanTime().isAfter(line.getPlanTime())) { + list.add(i, line); + break; + } + } + } + @Getter @AllArgsConstructor public static class Line { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequenceVO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequenceVO.java index 238eef32b..792c58c62 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequenceVO.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequenceVO.java @@ -22,10 +22,10 @@ public class RouteSequenceVO { */ private boolean readOnly; - private List lines; + private final List lines; @JsonIgnore - private Map idLineMap; + private final Map idLineMap; public RouteSequenceVO(RouteSequence routeSequence) { this.stationCode = routeSequence.getStationCode(); @@ -34,17 +34,35 @@ public class RouteSequenceVO { this.idLineMap = lines.stream().collect(Collectors.toMap(LineVO::getId, Function.identity())); } + private LineVO findLine(String id) { + return idLineMap.get(id); + } + + private void addLine(LineVO line) { + this.lines.add(line); + this.idLineMap.put(line.getId(), line); + } + public Map updateAndReturnChanged(RouteSequence routeSequence) { Map map = new HashMap<>(); if (!Objects.equals(readOnly, routeSequence.isReadOnly())) { readOnly = routeSequence.isReadOnly(); map.put("readOnly", readOnly); } - List> lines = this.lines.stream() - .map(vo -> vo.updateAndReturnChanged(routeSequence.getLine(vo.getId()))) - .collect(Collectors.toList()); - if (!CollectionUtils.isEmpty(lines)) { - map.put("lines", lines); + List properties = new ArrayList<>(); + for (RouteSequence.Line line : routeSequence.getLines()) { + LineVO vo = findLine(line.getId()); + if (vo == null) { + vo = new LineVO(line); + addLine(vo); + properties.add(vo); + } else { + Map changed = vo.updateAndReturnChanged(line); + properties.add(changed); + } + } + if (!CollectionUtils.isEmpty(properties)) { + map.put("lines", properties); } if (!CollectionUtils.isEmpty(map)) { return map; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java b/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java index bc5f76c8f..a8c8ceb89 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java @@ -2,7 +2,9 @@ package club.joylink.rtss.simulation.cbtc.build; import club.joylink.rtss.entity.Ibp; import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; +import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository; import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog; +import club.joylink.rtss.simulation.cbtc.CTC.data.RouteSequence; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; @@ -97,10 +99,40 @@ public class SimulationBuilder { // CTC行车日志数据结构构建 if (simulation.getRepository().getConfig().isHasCTC()) { buildCtcStationRunPlanLog(simulation, simulation.getRepository().getServiceTripsMap()); + generateRouteSequence(simulation); } return simulation; } + private static void generateRouteSequence(Simulation simulation) { + SimulationDataRepository repository = simulation.getRepository(); + CtcRepository ctcRepository = simulation.getCtcRepository(); + Map> stationLineMap = new HashMap<>(); + for (Station station : repository.getStationList()) { + stationLineMap.put(station.getCode(), new ArrayList<>()); + } + for (CtcStationRunPlanLog plan : ctcRepository.getAllRunPlanList()) { + List lines = stationLineMap.get(plan.getStation().getCode()); + CtcStationRunPlanLog.RunPlanItem arriveRunPlan = plan.getArriveRunPlan(); + if (arriveRunPlan != null) { + RouteSequence.Line line = RouteSequence.buildLine(arriveRunPlan, false); + if (line != null) + lines.add(line); + } + CtcStationRunPlanLog.RunPlanItem departRunPlan = plan.getDepartRunPlan(); + if (departRunPlan != null) { + RouteSequence.Line line = RouteSequence.buildLine(departRunPlan, true); + if (line != null) + lines.add(line); + } + } + Map routeSequenceMap = ctcRepository.getRouteSequenceMap(); + for (Station station : repository.getStationList()) { + RouteSequence routeSequence = new RouteSequence(station, stationLineMap.get(station.getCode())); + routeSequenceMap.put(station.getCode(), routeSequence); + } + } + private static void loadIscsResources(Simulation simulation, List iscsSystemResourceList) { SimulationIscsDataRepository iscsRepository = simulation.getIscsRepository(); iscsRepository.addSystemResources(iscsSystemResourceList);