From 618c8dc33c9688410290ab69d27fac23ca6a1de2 Mon Sep 17 00:00:00 2001 From: joylink_zhangsai <1021828630@qq.com> Date: Thu, 16 Nov 2023 15:16:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AE=BE=E7=BD=AE=E8=AE=A1?= =?UTF-8?q?=E5=88=92=E8=BD=A6=E6=97=B6=EF=BC=8C=E4=B8=8B=E4=B8=80=E8=BD=A6?= =?UTF-8?q?=E7=AB=99=E8=AE=A1=E5=88=92=E7=9A=84=E7=AD=9B=E9=80=89=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cbtc/ATS/service/AtsTrainService.java | 1261 +++++++++-------- 1 file changed, 660 insertions(+), 601 deletions(-) diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java index f6c33c81b..167186aec 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java @@ -11,7 +11,14 @@ import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.constant.TrainType; import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; -import club.joylink.rtss.simulation.cbtc.data.map.*; +import club.joylink.rtss.simulation.cbtc.data.map.DestinationCodeDefinition; +import club.joylink.rtss.simulation.cbtc.data.map.MapElement; +import club.joylink.rtss.simulation.cbtc.data.map.Route; +import club.joylink.rtss.simulation.cbtc.data.map.Routing; +import club.joylink.rtss.simulation.cbtc.data.map.Section; +import club.joylink.rtss.simulation.cbtc.data.map.SectionRunPath; +import club.joylink.rtss.simulation.cbtc.data.map.Signal; +import club.joylink.rtss.simulation.cbtc.data.map.Station; import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan; import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; @@ -24,16 +31,20 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService; import club.joylink.rtss.simulation.cbtc.onboard.ATP.OnboardAtpApiService; import club.joylink.rtss.vo.client.operation.DriveParamVO; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import java.time.LocalTime; -import java.util.*; -import java.util.stream.Collectors; - /** * ATS列车服务 */ @@ -41,570 +52,610 @@ import java.util.stream.Collectors; @Component public class AtsTrainService { - @Autowired - private AtsStandService atsStandService; + @Autowired + private AtsStandService atsStandService; - @Autowired - private CiApiService ciApiService; + @Autowired + private CiApiService ciApiService; - @Autowired - private OnboardAtpApiService onboardAtpApiService; + @Autowired + private OnboardAtpApiService onboardAtpApiService; - @Autowired - private ATPService atpService; + @Autowired + private ATPService atpService; - @Autowired - private AtsRouteService atsRouteService; + @Autowired + private AtsRouteService atsRouteService; - @Autowired - private AtsPlanTrainStageService atsPlanTrainStageService; + @Autowired + private AtsPlanTrainStageService atsPlanTrainStageService; - @Autowired - private AtsHeadTrainStageService atsHeadTrainStageService; + @Autowired + private AtsHeadTrainStageService atsHeadTrainStageService; - @Autowired - private AtsTrainService atsTrainService; + @Autowired + private AtsTrainService atsTrainService; - /** - * 添加列车追踪 - * - * @param simulation - * @param sectionCode - * @param groupNumber - * @param dn 目的地码 - * @param sn 服务号/表号 - * @param tn 行程号/序号/车次号 - * @param cn - */ - public void addTrainTrace(Simulation simulation, String sectionCode, String groupNumber, - String dn, String sn, String tn, String cn, boolean autoTrigger) { - SimulationDataRepository repository = simulation.getRepository(); - //车组号检查 - TrainInfo trainInfo = repository.findSupervisedTrainByGroup(groupNumber); - if (Objects.nonNull(trainInfo)) { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - String.format("[%s]已经存在", groupNumber)); - } - //区段车辆数检查 - Section section = repository.getByCode(sectionCode, Section.class); - List existList = repository.queryTrainInfosBySection(section); - if (existList.size() >= 10) { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - String.format("区段超过10辆")); - } - //添加监控列车 - TripPlan tripPlan = repository.findTripPlan(sn, tn); - TrainInfo ti; - if (tripPlan != null) { - //车次计划检查 - boolean tripRepeat = repository.getTrainInfoMap().values().stream() - .anyMatch(info -> Objects.equals(info.getServiceNumber(), sn) && Objects.equals(info.getTripNumber(), tn)); - BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(tripRepeat, "车次计划已在运行"); - ti = new TrainInfo(groupNumber, TrainType.PLAN); - ti.init(section, tripPlan, dn, cn); - } else if (StringUtils.hasText(dn)) { - ti = new TrainInfo(groupNumber, TrainType.HEAD); - } else { - ti = new TrainInfo(groupNumber, TrainType.MANUAL); - } - ti.init(section, dn, sn, tn, cn); - ti.setAtsAutoTrigger(autoTrigger); - repository.addTrainInfo(ti); + /** + * 添加列车追踪 + * + * @param simulation + * @param sectionCode + * @param groupNumber + * @param dn 目的地码 + * @param sn 服务号/表号 + * @param tn 行程号/序号/车次号 + * @param cn + */ + public void addTrainTrace(Simulation simulation, String sectionCode, String groupNumber, + String dn, String sn, String tn, String cn, boolean autoTrigger) { + SimulationDataRepository repository = simulation.getRepository(); + //车组号检查 + TrainInfo trainInfo = repository.findSupervisedTrainByGroup(groupNumber); + if (Objects.nonNull(trainInfo)) { + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, + String.format("[%s]已经存在", groupNumber)); } + //区段车辆数检查 + Section section = repository.getByCode(sectionCode, Section.class); + List existList = repository.queryTrainInfosBySection(section); + if (existList.size() >= 10) { + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, + String.format("区段超过10辆")); + } + //添加监控列车 + TripPlan tripPlan = repository.findTripPlan(sn, tn); + TrainInfo ti; + if (tripPlan != null) { + //车次计划检查 + boolean tripRepeat = repository.getTrainInfoMap().values().stream() + .anyMatch(info -> Objects.equals(info.getServiceNumber(), sn) && Objects.equals( + info.getTripNumber(), tn)); + BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(tripRepeat, "车次计划已在运行"); + ti = new TrainInfo(groupNumber, TrainType.PLAN); + ti.init(section, tripPlan, dn, cn); + } else if (StringUtils.hasText(dn)) { + ti = new TrainInfo(groupNumber, TrainType.HEAD); + } else { + ti = new TrainInfo(groupNumber, TrainType.MANUAL); + } + ti.init(section, dn, sn, tn, cn); + ti.setAtsAutoTrigger(autoTrigger); + repository.addTrainInfo(ti); + } - /** - * 删除列车追踪 - * - * @param simulation - * @param groupNumber - */ - public void removeTrainTrace(Simulation simulation, String groupNumber) { - SimulationDataRepository repository = simulation.getRepository(); - TrainInfo trainInfo = repository.findSupervisedTrainByGroup(groupNumber); - if (Objects.isNull(trainInfo)) { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - String.format("不存在车组号为[%s]的车次", groupNumber)); - } - if (repository.getConfig().isRailway()) {// 大铁、删除列车 + /** + * 删除列车追踪 + * + * @param simulation + * @param groupNumber + */ + public void removeTrainTrace(Simulation simulation, String groupNumber) { + SimulationDataRepository repository = simulation.getRepository(); + TrainInfo trainInfo = repository.findSupervisedTrainByGroup(groupNumber); + if (Objects.isNull(trainInfo)) { + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, + String.format("不存在车组号为[%s]的车次", groupNumber)); + } + if (repository.getConfig().isRailway()) {// 大铁、删除列车 // if (!trainInfo.isStop()) { // throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, String.format("列车[%s]未停稳的车次", groupNumber)); // } - repository.deleteOnlineTrain(trainInfo.getGroupNumber()); - repository.deleteSuperviseTrain(trainInfo.getGroupNumber()); - } else if (!trainInfo.isCtcLevel()) { // 原始 - repository.deleteSuperviseTrain(groupNumber); - } + repository.deleteOnlineTrain(trainInfo.getGroupNumber()); + repository.deleteSuperviseTrain(trainInfo.getGroupNumber()); + } else if (!trainInfo.isCtcLevel()) { // 原始 + repository.deleteSuperviseTrain(groupNumber); } + } - /** - * 移动车组号 - * - * @param simulation - * @param groupNumber - * @param sectionCode - */ - public void moveTrainTrace(Simulation simulation, String groupNumber, String sectionCode) { - SimulationDataRepository repository = simulation.getRepository(); - TrainInfo trainInfo = repository.findSupervisedTrainByGroup(groupNumber); - if (Objects.isNull(trainInfo)) { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - String.format("不存在车组号为[%s]的车次", groupNumber)); - } - Section target = repository.getByCode(sectionCode, Section.class); - if (!trainInfo.isCtcLevel()) { - trainInfo.init(target, trainInfo.getDestinationCode(), trainInfo.getServiceNumber(), trainInfo.getTripNumber(), trainInfo.getCrewNumber()); - } + /** + * 移动车组号 + * + * @param simulation + * @param groupNumber + * @param sectionCode + */ + public void moveTrainTrace(Simulation simulation, String groupNumber, String sectionCode) { + SimulationDataRepository repository = simulation.getRepository(); + TrainInfo trainInfo = repository.findSupervisedTrainByGroup(groupNumber); + if (Objects.isNull(trainInfo)) { + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, + String.format("不存在车组号为[%s]的车次", groupNumber)); } - - /** - * 设置计划车 - */ - public void setPlanTrain(Simulation simulation, String groupNumber, String serviceNumber, String tripNumber) { - Objects.requireNonNull(groupNumber); - SimulationDataRepository repository = simulation.getRepository(); - TrainInfo supervisedTrain = repository.findSupervisedTrainByGroup(groupNumber); - if (Objects.isNull(supervisedTrain)) { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - String.format("不存在追踪的列车[%s]", groupNumber)); - } - TrainInfo trainInfo = repository.findSupervisedTrainByTrip(serviceNumber, tripNumber); - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNull(trainInfo, - String.format("服务号[%s]车次号[%s]的列车已经上线", serviceNumber, tripNumber)); - TripPlan tripPlan = repository.getTripPlan(serviceNumber, tripNumber); - setPlanTrain(simulation, repository, supervisedTrain, tripPlan); + Section target = repository.getByCode(sectionCode, Section.class); + if (!trainInfo.isCtcLevel()) { + trainInfo.init(target, trainInfo.getDestinationCode(), trainInfo.getServiceNumber(), + trainInfo.getTripNumber(), trainInfo.getCrewNumber()); } + } - private void setPlanTrain(Simulation simulation, SimulationDataRepository repository, TrainInfo supervisedTrain, TripPlan tripPlan) { - if (supervisedTrain.hasPositionAndDirection()) { - Section phySection = repository.getByCode(supervisedTrain.getPhysicalSection(), Section.class); - StationPlan nextPlan = null; - List planList = tripPlan.getPlanList(); - for (int i = planList.size() - 1; i >= 0; i--) { - StationPlan stationPlan = planList.get(i); - List routePaths = repository.queryRoutePathsByEndAndContainsSection(stationPlan.getSection(), phySection); - if (!CollectionUtils.isEmpty(routePaths)) { - nextPlan = stationPlan; - if (routePaths.get(0).isRight() != tripPlan.isRight()) { - break; - } - } else { - break; - } - } - if (Objects.isNull(nextPlan)) { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - String.format("无法更新计划,列车[%s]位置[%s(%s)]无法到达计划[%s|%s|%s]中的任何站台", - supervisedTrain.getServiceNumber(), - phySection.getName(), phySection.getCode(), - tripPlan.getServiceNumber(), tripPlan.getTripNumber(), - tripPlan.getDestinationCode())); - } - // 更新列车计划和下一站 - supervisedTrain.initPlan(tripPlan, nextPlan, repository.getConfig()); - this.onboardAtpApiService.updateTripPlan(simulation, supervisedTrain.getGroupNumber(), tripPlan); - atsPlanTrainStageService.updateNextPlan(simulation, supervisedTrain, tripPlan, nextPlan); + /** + * 设置计划车 + */ + public void setPlanTrain(Simulation simulation, String groupNumber, String serviceNumber, + String tripNumber) { + Objects.requireNonNull(groupNumber); + SimulationDataRepository repository = simulation.getRepository(); + TrainInfo supervisedTrain = repository.findSupervisedTrainByGroup(groupNumber); + if (Objects.isNull(supervisedTrain)) { + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, + String.format("不存在追踪的列车[%s]", groupNumber)); + } + TrainInfo trainInfo = repository.findSupervisedTrainByTrip(serviceNumber, tripNumber); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNull(trainInfo, + String.format("服务号[%s]车次号[%s]的列车已经上线", serviceNumber, tripNumber)); + TripPlan tripPlan = repository.getTripPlan(serviceNumber, tripNumber); + setPlanTrain(simulation, repository, supervisedTrain, tripPlan); + } + + private void setPlanTrain(Simulation simulation, SimulationDataRepository repository, + TrainInfo supervisedTrain, TripPlan tripPlan) { + if (supervisedTrain.hasPositionAndDirection()) { + Section phySection = repository.getByCode(supervisedTrain.getPhysicalSection(), + Section.class); + StationPlan nextPlan = null; + List planList = tripPlan.getPlanList(); + for (int i = planList.size() - 1; i >= 0; i--) { + StationPlan stationPlan = planList.get(i); + List routePaths = repository.queryRoutePathsByEndAndContainsSection( + stationPlan.getSection(), phySection); + if (!CollectionUtils.isEmpty(routePaths)) { + if (routePaths.get(0).isRight() != tripPlan.isRight()) { + break; + } + nextPlan = stationPlan; + } + } + if (Objects.isNull(nextPlan)) { + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, + String.format("无法更新计划,列车[%s]位置[%s(%s)]无法到达计划[%s|%s|%s]中的任何站台", + supervisedTrain.getServiceNumber(), + phySection.getName(), phySection.getCode(), + tripPlan.getServiceNumber(), tripPlan.getTripNumber(), + tripPlan.getDestinationCode())); + } + // 更新列车计划和下一站 + supervisedTrain.initPlan(tripPlan, nextPlan, repository.getConfig()); + this.onboardAtpApiService.updateTripPlan(simulation, supervisedTrain.getGroupNumber(), + tripPlan); + atsPlanTrainStageService.updateNextPlan(simulation, supervisedTrain, tripPlan, nextPlan); // long runningTime = ChronoUnit.SECONDS.between(tripPlan.getStartTime(), nextPlan.getArriveTime()); // this.onboardAtpApiService.updateNextStation(simulation, supervisedTrain.getGroupNumber(), // nextPlan.getStation().getCode(), nextPlan.getSection().getCode(), runningTime, nextPlan.isPark()); - } } + } - public void setHeadTrain(Simulation simulation, String groupNumber, String serviceNumber, String tripNumber, String destinationCode) { - Objects.requireNonNull(groupNumber); - Objects.requireNonNull(destinationCode); - SimulationDataRepository repository = simulation.getRepository(); - TrainInfo supervisedTrain = repository.findSupervisedTrainByGroup(groupNumber); - if (Objects.isNull(supervisedTrain)) { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - String.format("不存在追踪的列车[%s]", groupNumber)); - } - if (StringUtils.hasText(tripNumber) && repository.getConfig().isCheckDirectionWhenSetHead()) { - boolean tripRight; - char c = tripNumber.charAt(0); - switch (c) { - case '2': - tripRight = repository.getConfig().isRight(true); - break; - case '1': - tripRight = repository.getConfig().isRight(false); - break; - default: - throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("车次号不正确"); - } - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertEquals(tripRight, supervisedTrain.getRight(), "方向不正确"); - } - setDestinationCode(simulation, groupNumber, serviceNumber, tripNumber, destinationCode, repository, supervisedTrain); + public void setHeadTrain(Simulation simulation, String groupNumber, String serviceNumber, + String tripNumber, String destinationCode) { + Objects.requireNonNull(groupNumber); + Objects.requireNonNull(destinationCode); + SimulationDataRepository repository = simulation.getRepository(); + TrainInfo supervisedTrain = repository.findSupervisedTrainByGroup(groupNumber); + if (Objects.isNull(supervisedTrain)) { + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, + String.format("不存在追踪的列车[%s]", groupNumber)); } + if (StringUtils.hasText(tripNumber) && repository.getConfig().isCheckDirectionWhenSetHead()) { + boolean tripRight; + char c = tripNumber.charAt(0); + switch (c) { + case '2': + tripRight = repository.getConfig().isRight(true); + break; + case '1': + tripRight = repository.getConfig().isRight(false); + break; + default: + throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("车次号不正确"); + } + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertEquals(tripRight, + supervisedTrain.getRight(), "方向不正确"); + } + setDestinationCode(simulation, groupNumber, serviceNumber, tripNumber, destinationCode, + repository, supervisedTrain); + } - /** - * 设置目的地码 - */ - private void setDestinationCode(Simulation simulation, String groupNumber, String serviceNumber, String tripNumber, - String destinationCode, SimulationDataRepository repository, TrainInfo supervisedTrain) { - Boolean right = supervisedTrain.getRight(); - Section headSection = repository.getByCode(supervisedTrain.getNotNullPhysicalSection(), Section.class); - Map destinationMap = repository.getDestinationMap(); + /** + * 设置目的地码 + */ + private void setDestinationCode(Simulation simulation, String groupNumber, String serviceNumber, + String tripNumber, + String destinationCode, SimulationDataRepository repository, TrainInfo supervisedTrain) { + Boolean right = supervisedTrain.getRight(); + Section headSection = repository.getByCode(supervisedTrain.getNotNullPhysicalSection(), + Section.class); + Map destinationMap = repository.getDestinationMap(); - if (!CollectionUtils.isEmpty(destinationMap)) { //有新版目的地码数据 - DestinationCodeDefinition destinationCodeDefinition = destinationMap.get(destinationCode); - if (destinationCodeDefinition == null) { - throw new SimulationException(SimulationExceptionType.Illegal_Argument, String.format("目的地码[%s]不存在", destinationCode)); - } - Section destinationSection = destinationCodeDefinition.getSection(); - Section targetSection = null; - Station targetStation = null; - String estimatedArriveStandTrack = supervisedTrain.getEstimatedArriveStandTrack(); - if (estimatedArriveStandTrack != null) { - targetSection = repository.getByCode(estimatedArriveStandTrack, Section.class); - targetStation = targetSection.getStation(); - } - boolean stop = supervisedTrain.isStop(); - switch (destinationCodeDefinition.getType()) { - case NORMAL_OPERATION: - case LAST_OPERATION: - case NON_OPERATION: - case LAST_NON_OPERATION: { - Section startSection = targetSection; - if (startSection == null) { - startSection = headSection; - } - if (right == null) { - throw new SimulationException(SimulationExceptionType.Illegal_Argument, - String.format("列车[%s]方向未知", groupNumber)); - } - BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(destinationCodeDefinition.containsSection(startSection, right), - String.format("%s超出%s范围", String.format("列车[%s]", groupNumber), destinationCodeDefinition.logStr())); - break; + if (!CollectionUtils.isEmpty(destinationMap)) { //有新版目的地码数据 + DestinationCodeDefinition destinationCodeDefinition = destinationMap.get(destinationCode); + if (destinationCodeDefinition == null) { + throw new SimulationException(SimulationExceptionType.Illegal_Argument, + String.format("目的地码[%s]不存在", destinationCode)); + } + Section destinationSection = destinationCodeDefinition.getSection(); + Section targetSection = null; + Station targetStation = null; + String estimatedArriveStandTrack = supervisedTrain.getEstimatedArriveStandTrack(); + if (estimatedArriveStandTrack != null) { + targetSection = repository.getByCode(estimatedArriveStandTrack, Section.class); + targetStation = targetSection.getStation(); + } + boolean stop = supervisedTrain.isStop(); + switch (destinationCodeDefinition.getType()) { + case NORMAL_OPERATION: + case LAST_OPERATION: + case NON_OPERATION: + case LAST_NON_OPERATION: { + Section startSection = targetSection; + if (startSection == null) { + startSection = headSection; + } + if (right == null) { + throw new SimulationException(SimulationExceptionType.Illegal_Argument, + String.format("列车[%s]方向未知", groupNumber)); + } + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue( + destinationCodeDefinition.containsSection(startSection, right), + String.format("%s超出%s范围", String.format("列车[%s]", groupNumber), + destinationCodeDefinition.logStr())); + break; + } + case OTHER: + Routing selectRouting = null; + Section fromSection = headSection; + List routings = repository.queryRoutingByDestCode(destinationCode); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertCollectionNotEmpty(routings, + String.format("列车[%s]无法到达目的地码[%s]对应区段[%s]", groupNumber, + destinationCode, destinationSection.getCode())); + for (Routing routing : routings) { + if (headSection.isTurnBackTrack()) { //是折返轨,不限制方向 + if (routing.containsSection(headSection)) { + selectRouting = routing; + } + for (Section section : routing.getAllSections()) { + List routePaths = repository.queryRoutePathsByEndAndContainsSection( + section, headSection); + if (!CollectionUtils.isEmpty(routePaths)) { + if (routePaths.stream() + .anyMatch(routePath -> routePath.isRight() == routing.isRight())) { + fromSection = section; + selectRouting = routing; + } } - case OTHER: - Routing selectRouting = null; - Section fromSection = headSection; - List routings = repository.queryRoutingByDestCode(destinationCode); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertCollectionNotEmpty(routings, - String.format("列车[%s]无法到达目的地码[%s]对应区段[%s]", groupNumber, destinationCode, destinationSection.getCode())); - for (Routing routing : routings) { - if (headSection.isTurnBackTrack()) { //是折返轨,不限制方向 - if (routing.containsSection(headSection)) { - selectRouting = routing; - } - for (Section section : routing.getAllSections()) { - List routePaths = repository.queryRoutePathsByEndAndContainsSection(section, headSection); - if (!CollectionUtils.isEmpty(routePaths)) { - if (routePaths.stream().anyMatch(routePath -> routePath.isRight() == routing.isRight())) { - fromSection = section; - selectRouting = routing; - } - } - } - } else { //不是折返轨,必须和列车同向 - if (routing.isRight() == right) { - if (routing.containsSection(headSection)) { - selectRouting = routing; - } else { - for (Section section : routing.getAllSections()) { - List routePaths = repository.queryRoutePathsByEndAndContainsSection(section, headSection); - if (routePaths.stream().anyMatch(routePath -> routePath.isRight() == right)) { - fromSection = section; - selectRouting = routing; - } - } - } - } - } - if (selectRouting != null) { - break; - } + } + } else { //不是折返轨,必须和列车同向 + if (routing.isRight() == right) { + if (routing.containsSection(headSection)) { + selectRouting = routing; + } else { + for (Section section : routing.getAllSections()) { + List routePaths = repository.queryRoutePathsByEndAndContainsSection( + section, headSection); + if (routePaths.stream().anyMatch(routePath -> routePath.isRight() == right)) { + fromSection = section; + selectRouting = routing; } - if (selectRouting != null) { - List
sections = selectRouting.getSectionsFrom(fromSection); - if (!sections.get(0).equals(headSection)) { - sections.add(0, headSection); - } - supervisedTrain.setHctPath(new SectionRunPath(sections, selectRouting.isRight())); - } else { - List routePaths = repository.queryRoutePathsByEndAndContainsSection(destinationSection, headSection); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertCollectionNotEmpty(routePaths, - String.format("列车[%s]无法到达目的地码[%s]对应区段[%s]", groupNumber, destinationCode, destinationSection.getCode())); - RoutePath routePath = routePaths.stream() - .min(Comparator.comparingDouble(RoutePath::getReverseSwitchQuantity)) - .get(); - List
sections = new ArrayList<>(); - sections.add(routePath.getStart()); - sections.add(routePath.getEnd()); - supervisedTrain.setHctPath(new SectionRunPath(sections, routePath.isRight())); - } - break; - default: - throw new SimulationException(SimulationExceptionType.System_Fault, String.format("无法识别的目的地码类型[%s]", destinationCodeDefinition.getType())); + } + } + } } - //默认 - } else { //没有新版目的地码数据 + if (selectRouting != null) { + break; + } + } + if (selectRouting != null) { + List
sections = selectRouting.getSectionsFrom(fromSection); + if (!sections.get(0).equals(headSection)) { + sections.add(0, headSection); + } + supervisedTrain.setHctPath(new SectionRunPath(sections, selectRouting.isRight())); + } else { + List routePaths = repository.queryRoutePathsByEndAndContainsSection( + destinationSection, headSection); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertCollectionNotEmpty(routePaths, + String.format("列车[%s]无法到达目的地码[%s]对应区段[%s]", groupNumber, + destinationCode, destinationSection.getCode())); + RoutePath routePath = routePaths.stream() + .min(Comparator.comparingDouble(RoutePath::getReverseSwitchQuantity)) + .get(); + List
sections = new ArrayList<>(); + sections.add(routePath.getStart()); + sections.add(routePath.getEnd()); + supervisedTrain.setHctPath(new SectionRunPath(sections, routePath.isRight())); + } + break; + default: + throw new SimulationException(SimulationExceptionType.System_Fault, + String.format("无法识别的目的地码类型[%s]", destinationCodeDefinition.getType())); + } + //默认 + } else { //没有新版目的地码数据 // List routingList = repository.queryRoutingByDestCode(destinationCode); // if (CollectionUtils.isEmpty(routingList)) { // throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, // String.format("不存在目的地号为[%s]的交路", destinationCode)); // } - throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("目的地码数据过期"); - } - - boolean needParking = true; - if (repository.getConfig().isNoParkingServiceNumber(serviceNumber)) { - needParking = false; - } - supervisedTrain.change2HeadCode(destinationCode, serviceNumber, tripNumber); - atsHeadTrainStageService.updatePlanSection(simulation, supervisedTrain); - this.onboardAtpApiService.update2HeadTrainServiceNumber(simulation, groupNumber, serviceNumber, tripNumber, destinationCode, needParking); - supervisedTrain.updateEstimatedArriveInfo(null, null); + throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("目的地码数据过期"); } - /** - * 设置人工车 - */ - public void setManualTrain(Simulation simulation, String groupNumber) { - Objects.requireNonNull(groupNumber); - SimulationDataRepository repository = simulation.getRepository(); - TrainInfo supervisedTrain = repository.findSupervisedTrainByGroup(groupNumber); - if (Objects.isNull(supervisedTrain)) { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - String.format("不存在追踪的列车[%s]", groupNumber)); - } - // 取消列车计划/目的地 + boolean needParking = true; + if (repository.getConfig().isNoParkingServiceNumber(serviceNumber)) { + needParking = false; + } + supervisedTrain.change2HeadCode(destinationCode, serviceNumber, tripNumber); + atsHeadTrainStageService.updatePlanSection(simulation, supervisedTrain); + this.onboardAtpApiService.update2HeadTrainServiceNumber(simulation, groupNumber, serviceNumber, + tripNumber, destinationCode, needParking); + supervisedTrain.updateEstimatedArriveInfo(null, null); + } + + /** + * 设置人工车 + */ + public void setManualTrain(Simulation simulation, String groupNumber) { + Objects.requireNonNull(groupNumber); + SimulationDataRepository repository = simulation.getRepository(); + TrainInfo supervisedTrain = repository.findSupervisedTrainByGroup(groupNumber); + if (Objects.isNull(supervisedTrain)) { + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, + String.format("不存在追踪的列车[%s]", groupNumber)); + } + // 取消列车计划/目的地 // this.onboardAtpApiService.change2Manual(simulation, groupNumber); - supervisedTrain.change2Manual(); - onboardAtpApiService.resetAtoSpeedMax(simulation, groupNumber); - } + supervisedTrain.change2Manual(); + onboardAtpApiService.resetAtoSpeedMax(simulation, groupNumber); + } - /** - * 扣车 - */ - public void hold(Simulation simulation, String groupNumber) { - simulation.getRepository().getOnlineTrainList().forEach(train -> { - train.setTrainHold(true); - train.setHold(true); - }); - } + /** + * 扣车 + */ + public void hold(Simulation simulation, String groupNumber) { + simulation.getRepository().getOnlineTrainList().forEach(train -> { + train.setTrainHold(true); + train.setHold(true); + }); + } - /** - * 取消扣车 - */ - public void cancelHold(Simulation simulation, String groupNumber) { - simulation.getRepository().getOnlineTrainList().forEach(train -> { - train.setTrainHold(false); - train.setHold(false); - }); - } + /** + * 取消扣车 + */ + public void cancelHold(Simulation simulation, String groupNumber) { + simulation.getRepository().getOnlineTrainList().forEach(train -> { + train.setTrainHold(false); + train.setHold(false); + }); + } - /** - * 修改车次号 - */ - public void changeTripNumber(Simulation simulation, String groupNumber, String serviceNumber) { - TrainInfo trainInfo = simulation.getRepository().getSupervisedTrainByGroup(groupNumber); - TripPlan tripPlan = simulation.getRepository().findTripPlan(serviceNumber, trainInfo.getTripNumber()); - if (tripPlan == null) { - throw new SimulationException(SimulationExceptionType.Illegal_Argument, String.format("[%s : %s]车次计划未找到", serviceNumber, trainInfo.getTripNumber())); + /** + * 修改车次号 + */ + public void changeTripNumber(Simulation simulation, String groupNumber, String serviceNumber) { + TrainInfo trainInfo = simulation.getRepository().getSupervisedTrainByGroup(groupNumber); + TripPlan tripPlan = simulation.getRepository() + .findTripPlan(serviceNumber, trainInfo.getTripNumber()); + if (tripPlan == null) { + throw new SimulationException(SimulationExceptionType.Illegal_Argument, + String.format("[%s : %s]车次计划未找到", serviceNumber, trainInfo.getTripNumber())); + } + onboardAtpApiService.updateTripPlan(simulation, groupNumber, tripPlan); + trainInfo.applyNewTripPlan(tripPlan); + } + + /** + * 列车派接功能(派groupNumber1接groupNumber2) + */ + public void dispatch(Simulation simulation, String groupNumber1, String groupNumber2) { + //没有逻辑,只是用于剧本动作记录 + } + + /** + * 托管 + */ + public void trust(Simulation simulation, String groupNumber, DriveParamVO param) { + SimulationDataRepository repository = simulation.getRepository(); + VirtualRealityTrain train = repository.getOnlineTrainBy(groupNumber); + //计算目标位置 + SectionPosition targetPosition = null; + String targetDeviceCode = param.getTargetDeviceCode(); + boolean right = train.isRight(); + SectionPosition headPosition = train.getHeadPosition(); + if (StringUtils.hasText(targetDeviceCode)) { + SectionPosition tempTargetPosition; + MapElement element = repository.findByCode(targetDeviceCode); + if (element != null) { + if (!(element instanceof Section)) { + throw new SimulationException(SimulationExceptionType.System_Fault, "只能选列车或区段"); } - onboardAtpApiService.updateTripPlan(simulation, groupNumber, tripPlan); - trainInfo.applyNewTripPlan(tripPlan); - } - - /** - * 列车派接功能(派groupNumber1接groupNumber2) - */ - public void dispatch(Simulation simulation, String groupNumber1, String groupNumber2) { - //没有逻辑,只是用于剧本动作记录 - } - - /** - * 托管 - */ - public void trust(Simulation simulation, String groupNumber, DriveParamVO param) { - SimulationDataRepository repository = simulation.getRepository(); - VirtualRealityTrain train = repository.getOnlineTrainBy(groupNumber); - //计算目标位置 - SectionPosition targetPosition = null; - String targetDeviceCode = param.getTargetDeviceCode(); - boolean right = train.isRight(); - SectionPosition headPosition = train.getHeadPosition(); - if (StringUtils.hasText(targetDeviceCode)) { - SectionPosition tempTargetPosition; - MapElement element = repository.findByCode(targetDeviceCode); - if (element != null) { - if (!(element instanceof Section)) { - throw new SimulationException(SimulationExceptionType.System_Fault, "只能选列车或区段"); - } - Section section = (Section) element; - Section targetSection = section.getNextRunningSectionOf(right); - SectionPosition trainTargetPosition = new SectionPosition(targetSection, targetSection.getStopPointByDirection(right)); - Float distance = CalculateService.calculateDistance(train.getHeadPosition(), trainTargetPosition, right, false); - if (distance == null) { - throw new SimulationException(SimulationExceptionType.Illegal_Argument, "无法到达的位置"); - } - tempTargetPosition = new SectionPosition(section, section.getStopPointByDirection(right)); - } else { - VirtualRealityTrain targetTrain = repository.getVRByCode(targetDeviceCode, VirtualRealityTrain.class); - SectionPosition targetTrainTailPosition = targetTrain.calculateTailPosition(); - boolean targetIsRight = targetTrain.isRight(); - tempTargetPosition = CalculateService.calculateNextPositionByStartAndLen(targetTrainTailPosition, !targetIsRight, 2, false); - } - targetPosition = tempTargetPosition.convert2PhysicalSectionPosition(); - BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotNull(targetPosition, "无法抵达所选位置"); + Section section = (Section) element; + Section targetSection = section.getNextRunningSectionOf(right); + SectionPosition trainTargetPosition = new SectionPosition(targetSection, + targetSection.getStopPointByDirection(right)); + Float distance = CalculateService.calculateDistance(train.getHeadPosition(), + trainTargetPosition, right, false); + if (distance == null) { + throw new SimulationException(SimulationExceptionType.Illegal_Argument, "无法到达的位置"); } - //找要越过的信号机 - Section section = headPosition.getSection(); - if (param.isThroughRedSignal()) { // 越红灯行驶 - Signal signal = section.getSignalOf(right); - boolean b = false; - if (signal != null && signal.getPosition().isAheadOf(headPosition, right)) { - VirtualRealitySignal vrSignal = signal.getVirtualSignal(); - b = vrSignal != null && vrSignal.getModel().getDefaultAspect().equals(vrSignal.getAspect()); - } - BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(b, "需要车头所在区段前方有同向信号机,且为禁止信号"); - param.setThroughSignal(signal); - param.setThroughSignalAspect(signal.getDefaultAspect()); - } else if (param.isThroughGuideSignal()) { // 越引导行驶 - Signal signal = section.getSignalOf(right); - boolean b = false; - if (signal != null && signal.getPosition().isAheadOf(headPosition, right)) { - VirtualRealitySignal vrSignal = signal.getVirtualSignal(); - b = vrSignal != null && vrSignal.getModel().getGuideAspect().equals(vrSignal.getAspect()); - } - BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(b, "需要车头所在区段前方有同向信号机,且为引导信号"); - param.setThroughSignal(signal); - param.setThroughSignalAspect(signal.getGuideAspect()); - } else if (param.isDriverNextStand()){ // 行驶至前方车站 - // 停车目的区段 - if (section.isStandTrack()) { - targetPosition = new SectionPosition(section, section.getStopPointByDirection(train.isRight())); - } else { - targetPosition = train.calculateNextStandStopPosition(); - if (targetPosition == null && train.getTarget() != null) { - targetPosition = new SectionPosition(train.getTarget(), train.getTarget().getStopPointByDirection(train.isRight())); - } - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(targetPosition, train.debugStr() + "找不到下一个停车点"); - param.setThroughSignal(section.getSignalOf(right)); - } - } else { - param.setThroughSignal(null); - param.setThroughSignalAspect(null); + tempTargetPosition = new SectionPosition(section, section.getStopPointByDirection(right)); + } else { + VirtualRealityTrain targetTrain = repository.getVRByCode(targetDeviceCode, + VirtualRealityTrain.class); + SectionPosition targetTrainTailPosition = targetTrain.calculateTailPosition(); + boolean targetIsRight = targetTrain.isRight(); + tempTargetPosition = CalculateService.calculateNextPositionByStartAndLen( + targetTrainTailPosition, !targetIsRight, 2, false); + } + targetPosition = tempTargetPosition.convert2PhysicalSectionPosition(); + BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotNull(targetPosition, "无法抵达所选位置"); + } + //找要越过的信号机 + Section section = headPosition.getSection(); + if (param.isThroughRedSignal()) { // 越红灯行驶 + Signal signal = section.getSignalOf(right); + boolean b = false; + if (signal != null && signal.getPosition().isAheadOf(headPosition, right)) { + VirtualRealitySignal vrSignal = signal.getVirtualSignal(); + b = vrSignal != null && vrSignal.getModel().getDefaultAspect().equals(vrSignal.getAspect()); + } + BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(b, + "需要车头所在区段前方有同向信号机,且为禁止信号"); + param.setThroughSignal(signal); + param.setThroughSignalAspect(signal.getDefaultAspect()); + } else if (param.isThroughGuideSignal()) { // 越引导行驶 + Signal signal = section.getSignalOf(right); + boolean b = false; + if (signal != null && signal.getPosition().isAheadOf(headPosition, right)) { + VirtualRealitySignal vrSignal = signal.getVirtualSignal(); + b = vrSignal != null && vrSignal.getModel().getGuideAspect().equals(vrSignal.getAspect()); + } + BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(b, + "需要车头所在区段前方有同向信号机,且为引导信号"); + param.setThroughSignal(signal); + param.setThroughSignalAspect(signal.getGuideAspect()); + } else if (param.isDriverNextStand()) { // 行驶至前方车站 + // 停车目的区段 + if (section.isStandTrack()) { + targetPosition = new SectionPosition(section, + section.getStopPointByDirection(train.isRight())); + } else { + targetPosition = train.calculateNextStandStopPosition(); + if (targetPosition == null && train.getTarget() != null) { + targetPosition = new SectionPosition(train.getTarget(), + train.getTarget().getStopPointByDirection(train.isRight())); } - VirtualRealityTrain linkTrain = train.getLinkTrain(); - if (linkTrain != null) { - DriveParamVO linkParamVO = param.cloneParamVO(); - if (targetPosition != null) { - Section targetSection = targetPosition.getSection(); - float offset = targetSection.getStopPointByDirection(train.isRight()); - SectionPosition linkTargetSectionPosition = new SectionPosition(targetSection, offset); - linkParamVO.setTargetPosition(linkTargetSectionPosition); - Float distance = CalculateService.calculateDistance(headPosition, linkTrain.calculateTailPosition(), right, false); - float len = linkTrain.getLen() + (distance == null ? 0 : distance); - targetPosition = new SectionPosition(targetSection, offset + (len * (right ? -1 : 1))); - } - linkTrain.updateDriveParam(linkParamVO); - } - param.setTargetPosition(targetPosition); - train.updateDriveParam(param); - + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(targetPosition, + train.debugStr() + "找不到下一个停车点"); + param.setThroughSignal(section.getSignalOf(right)); + } + } else { + param.setThroughSignal(null); + param.setThroughSignalAspect(null); } - - /** - * 连挂(groupNumber1连挂groupNumber2 - */ - public void link(Simulation simulation, String groupNumber, String groupNumber2) { - SimulationDataRepository repository = simulation.getRepository(); - VirtualRealityTrain activeTrain = repository.getOnlineTrainBy(groupNumber); - VirtualRealityTrain passiveTrain = repository.getOnlineTrainBy(groupNumber2); - if (activeTrain.isRight() != passiveTrain.isRight()) { - throw new SimulationException(SimulationExceptionType.Invalid_Operation, String.format("列车[%s][%s]方向不同", groupNumber, groupNumber2)); - } - SectionPosition headPosition = activeTrain.getHeadPosition(); - SectionPosition tailPosition = passiveTrain.calculateTailPosition(); - Float distance = CalculateService.calculateDistance(headPosition, tailPosition, activeTrain.isRight(), false); - if (distance == null || distance > 3) { - throw new SimulationException(SimulationExceptionType.Invalid_Operation, String.format("列车[%s][%s]距离过远", groupNumber, groupNumber2)); - } - activeTrain.setLinkTrain(passiveTrain); + VirtualRealityTrain linkTrain = train.getLinkTrain(); + if (linkTrain != null) { + DriveParamVO linkParamVO = param.cloneParamVO(); + if (targetPosition != null) { + Section targetSection = targetPosition.getSection(); + float offset = targetSection.getStopPointByDirection(train.isRight()); + SectionPosition linkTargetSectionPosition = new SectionPosition(targetSection, offset); + linkParamVO.setTargetPosition(linkTargetSectionPosition); + Float distance = CalculateService.calculateDistance(headPosition, + linkTrain.calculateTailPosition(), right, false); + float len = linkTrain.getLen() + (distance == null ? 0 : distance); + targetPosition = new SectionPosition(targetSection, offset + (len * (right ? -1 : 1))); + } + linkTrain.updateDriveParam(linkParamVO); } + param.setTargetPosition(targetPosition); + train.updateDriveParam(param); - /** - * 排列进路到(站台/信号机) - */ - public void setRouteTo(Simulation simulation, String groupNumber, List routeCodes) { - BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(routeCodes, "所选进路不能为空"); - SimulationDataRepository repository = simulation.getRepository(); - TrainInfo trainInfo = repository.getSupervisedTrainByGroup(groupNumber); - routeCodes.forEach(code -> { - ciApiService.settingRoute(simulation, code); - Route route = repository.getByCode(code, Route.class); - route.setTrain(trainInfo); - }); + } + + /** + * 连挂(groupNumber1连挂groupNumber2 + */ + public void link(Simulation simulation, String groupNumber, String groupNumber2) { + SimulationDataRepository repository = simulation.getRepository(); + VirtualRealityTrain activeTrain = repository.getOnlineTrainBy(groupNumber); + VirtualRealityTrain passiveTrain = repository.getOnlineTrainBy(groupNumber2); + if (activeTrain.isRight() != passiveTrain.isRight()) { + throw new SimulationException(SimulationExceptionType.Invalid_Operation, + String.format("列车[%s][%s]方向不同", groupNumber, groupNumber2)); } - - /** - * 设置列车运行类型 - */ - public void setRunType(Simulation simulation, String groupNumber, VirtualRealityTrain.RunType runType) { - VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); - train.setRunType(runType); + SectionPosition headPosition = activeTrain.getHeadPosition(); + SectionPosition tailPosition = passiveTrain.calculateTailPosition(); + Float distance = CalculateService.calculateDistance(headPosition, tailPosition, + activeTrain.isRight(), false); + if (distance == null || distance > 3) { + throw new SimulationException(SimulationExceptionType.Invalid_Operation, + String.format("列车[%s][%s]距离过远", groupNumber, groupNumber2)); } + activeTrain.setLinkTrain(passiveTrain); + } - /** - * 设置全线列车扣车 - */ - public void setAllHold(Simulation simulation) { - simulation.getRepository().getOnlineTrainList().forEach(train -> { - train.setTrainHold(true); - train.setHold(true); - }); + /** + * 排列进路到(站台/信号机) + */ + public void setRouteTo(Simulation simulation, String groupNumber, List routeCodes) { + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(routeCodes, + "所选进路不能为空"); + SimulationDataRepository repository = simulation.getRepository(); + TrainInfo trainInfo = repository.getSupervisedTrainByGroup(groupNumber); + routeCodes.forEach(code -> { + ciApiService.settingRoute(simulation, code); + Route route = repository.getByCode(code, Route.class); + route.setTrain(trainInfo); + }); + } + + /** + * 设置列车运行类型 + */ + public void setRunType(Simulation simulation, String groupNumber, + VirtualRealityTrain.RunType runType) { + VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); + train.setRunType(runType); + } + + /** + * 设置全线列车扣车 + */ + public void setAllHold(Simulation simulation) { + simulation.getRepository().getOnlineTrainList().forEach(train -> { + train.setTrainHold(true); + train.setHold(true); + }); + } + + /** + * 取消全线列车扣车 + */ + public void cancelAllHold(Simulation simulation) { + simulation.getRepository().getOnlineTrainList().forEach(train -> { + if (train.isTrainHold()) { + train.setTrainHold(false); + train.setHold(false); + } + }); + } + + /** + * 下令停车 + */ + public void orderStop(Simulation simulation, String groupNumber) { + VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); + train.setOrderStop(true); + } + + /** + * 取消停车命令 + */ + public void cancelOrderStop(Simulation simulation, String groupNumber) { + VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); + train.setOrderStop(false); + } + + /** + * 列车发车【泰雷兹】 + */ + public void departure(Simulation simulation, String groupNumber) { + TrainInfo trainInfo = simulation.getRepository().getSupervisedTrainByGroup(groupNumber); + if (trainInfo.isParking() || trainInfo.isHold()) { + onboardAtpApiService.departure(simulation, groupNumber); + VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); + train.setNeedDepartureCommand(false); } + } - /** - * 取消全线列车扣车 - */ - public void cancelAllHold(Simulation simulation) { - simulation.getRepository().getOnlineTrainList().forEach(train -> { - if (train.isTrainHold()) { - train.setTrainHold(false); - train.setHold(false); - } - }); - } - - /** - * 下令停车 - */ - public void orderStop(Simulation simulation, String groupNumber) { - VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); - train.setOrderStop(true); - } - - /** - * 取消停车命令 - */ - public void cancelOrderStop(Simulation simulation, String groupNumber) { - VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); - train.setOrderStop(false); - } - - /** - * 列车发车【泰雷兹】 - */ - public void departure(Simulation simulation, String groupNumber) { - TrainInfo trainInfo = simulation.getRepository().getSupervisedTrainByGroup(groupNumber); - if (trainInfo.isParking() || trainInfo.isHold()) { - onboardAtpApiService.departure(simulation, groupNumber); - VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); - train.setNeedDepartureCommand(false); - } - } - - /** - * 列车跳停 - */ - public void skipStop(Simulation simulation, String groupNumber, String destinationCode, List standCodes) { - // TODO: 2021/4/6 目前计划车没有运行线,所以运行线的跳停在计划车上不生效。并且<查询列车经过的站台>接口,计划车的站台是根据车次计划而不是运行线筛选的。 - BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(standCodes, "所选站台列表不能为空"); - //2021-04-09 16:26:21 为了简化逻辑,对运行线的跳停先改为对站台设置所有列车跳停。所以可以直接调用站台的跳停方法 - standCodes.forEach(code -> atsStandService.setJumpStop(simulation, code, groupNumber)); + /** + * 列车跳停 + */ + public void skipStop(Simulation simulation, String groupNumber, String destinationCode, + List standCodes) { + // TODO: 2021/4/6 目前计划车没有运行线,所以运行线的跳停在计划车上不生效。并且<查询列车经过的站台>接口,计划车的站台是根据车次计划而不是运行线筛选的。 + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(standCodes, + "所选站台列表不能为空"); + //2021-04-09 16:26:21 为了简化逻辑,对运行线的跳停先改为对站台设置所有列车跳停。所以可以直接调用站台的跳停方法 + standCodes.forEach(code -> atsStandService.setJumpStop(simulation, code, groupNumber)); // SimulationDataRepository repository = simulation.getRepository(); // if (StringUtils.hasText(groupNumber)) { @@ -622,96 +673,104 @@ public class AtsTrainService { // trains.forEach(train -> atsStandService.setJumpStop(simulation, standCode, train.getGroupNumber())); // }); // } - } + } - public void distribute(Simulation simulation, String groupNumber, String serviceNumber) { - // TODO: 2021/4/7 如果给某列车分配一个已经有列车在跑的班次,该列车在停车点会分配上班次,该班次原来那辆车会被分配一条和班次相关的运行线。(就类似脱离班次操作) - BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(simulation.getRepository().isVrTrainOnline(groupNumber)); - LocalTime now = LocalTime.now(); - Optional tripPlanOptional = simulation.getRepository().getTripPlanList(serviceNumber).stream() - .filter(tripPlan -> tripPlan.getStartTime().isBefore(now) && tripPlan.getEndTime().isAfter(now)) - .findAny(); - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(tripPlanOptional.isPresent(), - String.format("当前时间不能分配该服务号[%s]", serviceNumber)); - setPlanTrain(simulation, groupNumber, serviceNumber, tripPlanOptional.get().getTripNumber()); - } + public void distribute(Simulation simulation, String groupNumber, String serviceNumber) { + // TODO: 2021/4/7 如果给某列车分配一个已经有列车在跑的班次,该列车在停车点会分配上班次,该班次原来那辆车会被分配一条和班次相关的运行线。(就类似脱离班次操作) + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue( + simulation.getRepository().isVrTrainOnline(groupNumber)); + LocalTime now = LocalTime.now(); + Optional tripPlanOptional = simulation.getRepository().getTripPlanList(serviceNumber) + .stream() + .filter( + tripPlan -> tripPlan.getStartTime().isBefore(now) && tripPlan.getEndTime().isAfter(now)) + .findAny(); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(tripPlanOptional.isPresent(), + String.format("当前时间不能分配该服务号[%s]", serviceNumber)); + setPlanTrain(simulation, groupNumber, serviceNumber, tripPlanOptional.get().getTripNumber()); + } - /** - * 取消CBTC进路【泰雷兹】 - */ - public void cancelCBTCRoute(Simulation simulation, List routeCodes) { - SimulationDataRepository repository = simulation.getRepository(); - Map settingRouteMap = repository.getSettingRouteMap(); - List collect = routeCodes.stream().map(settingRouteMap::get).filter(Objects::nonNull).collect(Collectors.toList()); - if (!CollectionUtils.isEmpty(collect)) { - TrainInfo trainInfo = collect.get(0).getTrain(); - if (trainInfo != null) { - VirtualRealityTrain train = repository.getOnlineTrainBy(trainInfo.getGroupNumber()); - atpService.triggerSignalEB(train); - train.setNeedDepartureCommand(true); - } - collect.forEach(route -> atsRouteService.cancelRoute(simulation, route.getStart().getCode())); - } + /** + * 取消CBTC进路【泰雷兹】 + */ + public void cancelCBTCRoute(Simulation simulation, List routeCodes) { + SimulationDataRepository repository = simulation.getRepository(); + Map settingRouteMap = repository.getSettingRouteMap(); + List collect = routeCodes.stream().map(settingRouteMap::get).filter(Objects::nonNull) + .collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(collect)) { + TrainInfo trainInfo = collect.get(0).getTrain(); + if (trainInfo != null) { + VirtualRealityTrain train = repository.getOnlineTrainBy(trainInfo.getGroupNumber()); + atpService.triggerSignalEB(train); + train.setNeedDepartureCommand(true); + } + collect.forEach(route -> atsRouteService.cancelRoute(simulation, route.getStart().getCode())); } + } - /** - * 取消跳停【泰雷兹】 - */ - public void cancelSkipStop(Simulation simulation, String groupNumber, String destinationCode, List standCodes) { - BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(standCodes, "所选站台列表不能为空"); - standCodes.forEach(code -> atsStandService.cancelJumpStop(simulation, code, groupNumber)); - } + /** + * 取消跳停【泰雷兹】 + */ + public void cancelSkipStop(Simulation simulation, String groupNumber, String destinationCode, + List standCodes) { + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(standCodes, + "所选站台列表不能为空"); + standCodes.forEach(code -> atsStandService.cancelJumpStop(simulation, code, groupNumber)); + } - public void autoTrigger(Simulation simulation, String groupNumber, boolean autoTrigger) { - TrainInfo trainInfo = simulation.getRepository().getSupervisedTrainByGroup(groupNumber); - trainInfo.setAtsAutoTrigger(autoTrigger); - } + public void autoTrigger(Simulation simulation, String groupNumber, boolean autoTrigger) { + TrainInfo trainInfo = simulation.getRepository().getSupervisedTrainByGroup(groupNumber); + trainInfo.setAtsAutoTrigger(autoTrigger); + } - public void regulation(Simulation simulation, String groupNumber, BusinessConsts.Regulation regulation, RegulationParam regulationParam) { - SimulationDataRepository repository = simulation.getRepository(); - switch (regulation) { - case TIME_TABLE_REGULATION: - break; - case HEADWAY_REGULATION_FRONT: - case HEADWAY_REGULATION_FRONT_AND_BACK: - BusinessExceptionAssertEnum.INVALID_OPERATION - .assertNotNull(regulationParam.getIntervalTime(), "间隔时间不能为空"); - repository.setIntervalTime(regulationParam.getIntervalTime()); - return; - case REGULATION_OFF: - break; - default: - throw new IllegalStateException("Unexpected value: " + regulation); - } - if (StringUtils.hasText(groupNumber)) { - TrainInfo trainInfo = repository.getSupervisedTrainByGroup(groupNumber); - trainInfo.updateRegulation(regulation, regulationParam); - } else { - repository.getSuperviseTrainList().forEach(trainInfo -> - trainInfo.updateRegulation(regulation, regulationParam)); - } - repository.setIntervalTime(null); + public void regulation(Simulation simulation, String groupNumber, + BusinessConsts.Regulation regulation, RegulationParam regulationParam) { + SimulationDataRepository repository = simulation.getRepository(); + switch (regulation) { + case TIME_TABLE_REGULATION: + break; + case HEADWAY_REGULATION_FRONT: + case HEADWAY_REGULATION_FRONT_AND_BACK: + BusinessExceptionAssertEnum.INVALID_OPERATION + .assertNotNull(regulationParam.getIntervalTime(), "间隔时间不能为空"); + repository.setIntervalTime(regulationParam.getIntervalTime()); + return; + case REGULATION_OFF: + break; + default: + throw new IllegalStateException("Unexpected value: " + regulation); } + if (StringUtils.hasText(groupNumber)) { + TrainInfo trainInfo = repository.getSupervisedTrainByGroup(groupNumber); + trainInfo.updateRegulation(regulation, regulationParam); + } else { + repository.getSuperviseTrainList().forEach(trainInfo -> + trainInfo.updateRegulation(regulation, regulationParam)); + } + repository.setIntervalTime(null); + } - public IntervalCalculateResult calculateInterval(Simulation simulation, Integer trainNumber, Integer interval) { - IntervalCalculateResult result = new IntervalCalculateResult(); - if (trainNumber != null) { - result.setTrainNumber(trainNumber); - int avgIntervalTime = 360 / trainNumber; - result.setAvg(avgIntervalTime); - result.setMin((int) (avgIntervalTime * 0.66)); - result.setMax((int) (avgIntervalTime * 1.33)); - result.setIntervalTime(avgIntervalTime); - } else if (interval != null) { - result.setIntervalTime(interval); - int avgTrainNumber = 360 / interval; - result.setAvg(avgTrainNumber); - result.setMin(Math.max(0, avgTrainNumber - 1)); - result.setMax(avgTrainNumber + 1); - result.setTrainNumber(avgTrainNumber); - } else { - throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("参数异常"); - } - return result; + public IntervalCalculateResult calculateInterval(Simulation simulation, Integer trainNumber, + Integer interval) { + IntervalCalculateResult result = new IntervalCalculateResult(); + if (trainNumber != null) { + result.setTrainNumber(trainNumber); + int avgIntervalTime = 360 / trainNumber; + result.setAvg(avgIntervalTime); + result.setMin((int) (avgIntervalTime * 0.66)); + result.setMax((int) (avgIntervalTime * 1.33)); + result.setIntervalTime(avgIntervalTime); + } else if (interval != null) { + result.setIntervalTime(interval); + int avgTrainNumber = 360 / interval; + result.setAvg(avgTrainNumber); + result.setMin(Math.max(0, avgTrainNumber - 1)); + result.setMax(avgTrainNumber + 1); + result.setTrainNumber(avgTrainNumber); + } else { + throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("参数异常"); } + return result; + } }