泰国沙盘禁用列车自动上线逻辑
This commit is contained in:
parent
5cc2c02ccc
commit
b41ea03502
@ -1,8 +1,17 @@
|
|||||||
package club.joylink.rtss.simulation.cbtc.CTC;
|
package club.joylink.rtss.simulation.cbtc.CTC;
|
||||||
|
|
||||||
|
import club.joylink.rtss.constants.ProjectCode;
|
||||||
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainLoadService;
|
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainLoadService;
|
||||||
import club.joylink.rtss.simulation.cbtc.CTC.data.*;
|
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcEffectRepository;
|
||||||
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.*;
|
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.CTC.data.TrackView;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.BusyBoardVO;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.CtcStationRunPlanLogVO;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.RailDispatchCommandVO;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.RouteSequenceVO;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.TrackViewVO;
|
||||||
import club.joylink.rtss.simulation.cbtc.CTC.rail.dcmd.service.DisCmdSendService;
|
import club.joylink.rtss.simulation.cbtc.CTC.rail.dcmd.service.DisCmdSendService;
|
||||||
import club.joylink.rtss.simulation.cbtc.CTC.service.CTCService;
|
import club.joylink.rtss.simulation.cbtc.CTC.service.CTCService;
|
||||||
import club.joylink.rtss.simulation.cbtc.CTC.service.CtcDispatchCommandService;
|
import club.joylink.rtss.simulation.cbtc.CTC.service.CtcDispatchCommandService;
|
||||||
@ -21,426 +30,464 @@ import club.joylink.rtss.vo.client.WebSocketMessageType;
|
|||||||
import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
|
import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
|
||||||
import club.joylink.rtss.websocket.StompMessageService;
|
import club.joylink.rtss.websocket.StompMessageService;
|
||||||
import club.joylink.rtss.websocket.WebSocketMessage;
|
import club.joylink.rtss.websocket.WebSocketMessage;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class CTCLogicLoop {
|
public class CTCLogicLoop {
|
||||||
public static final String LOGIC_NAME = "CTC"; //逻辑循环任务名称
|
|
||||||
public static final int LOGIC_RATE = 1000; //逻辑循环频率
|
|
||||||
public static final String MESSAGE_NAME = "CTC_MESSAGE"; //消息发送任务名称
|
|
||||||
public static final int MESSAGE_RATE = 1000; //消息发送频率
|
|
||||||
|
|
||||||
@Autowired
|
public static final String LOGIC_NAME = "CTC"; //逻辑循环任务名称
|
||||||
private StompMessageService stompMessageService;
|
public static final int LOGIC_RATE = 1000; //逻辑循环频率
|
||||||
@Autowired
|
public static final String MESSAGE_NAME = "CTC_MESSAGE"; //消息发送任务名称
|
||||||
private CTCService ctcService;
|
public static final int MESSAGE_RATE = 1000; //消息发送频率
|
||||||
@Autowired
|
|
||||||
private CtcDispatchCommandService ctcDispatchCommandService;
|
|
||||||
@Autowired
|
|
||||||
private DisCmdSendService disCmdService;
|
|
||||||
@Autowired
|
|
||||||
private AtsTrainLoadService atsTrainLoadService;
|
|
||||||
|
|
||||||
public void run(Simulation simulation) {
|
@Autowired
|
||||||
updateRunPlanLog(simulation);
|
private StompMessageService stompMessageService;
|
||||||
routeSequenceUpdate(simulation);
|
@Autowired
|
||||||
trackViewUpdate(simulation);
|
private CTCService ctcService;
|
||||||
// 加载已签收行车日志,
|
@Autowired
|
||||||
loadSignRunPlanTrain(simulation);
|
private CtcDispatchCommandService ctcDispatchCommandService;
|
||||||
|
@Autowired
|
||||||
|
private DisCmdSendService disCmdService;
|
||||||
|
@Autowired
|
||||||
|
private AtsTrainLoadService atsTrainLoadService;
|
||||||
|
|
||||||
|
public void run(Simulation simulation) {
|
||||||
|
updateRunPlanLog(simulation);
|
||||||
|
routeSequenceUpdate(simulation);
|
||||||
|
trackViewUpdate(simulation);
|
||||||
|
// 加载已签收行车日志,
|
||||||
|
loadSignRunPlanTrain(simulation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMessage(Simulation simulation) {
|
||||||
|
sendTrackViewMessage(simulation);
|
||||||
|
sendRouteSequenceMessage(simulation);
|
||||||
|
// 发送运行计划变化消息
|
||||||
|
sendRunPlanChangeMessage(simulation);
|
||||||
|
sendRunPlanRemoveMessage(simulation);
|
||||||
|
// 下发计划
|
||||||
|
sendZoneRunPlanSend(simulation);
|
||||||
|
// 发送计划按钮是否闪烁
|
||||||
|
sendRunPlanConfirmActiveMessage(simulation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMessageWhenSubscribeCtc(Simulation simulation, String userId) {
|
||||||
|
sendAllBusyBoardMessage(simulation, userId);
|
||||||
|
//dis cmd v1
|
||||||
|
sendUnreadDispatchCommand(simulation, userId);
|
||||||
|
//dis cmd v2
|
||||||
|
disCmdService.autoSendUnread(simulation, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendAllBusyBoardMessage(Simulation simulation, String userId) {
|
||||||
|
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||||
|
List<BusyBoardVO> list = new ArrayList<>();
|
||||||
|
Map<String, TrackViewVO> trackViewVOMap = ctcRepository.getTrackViewVOMap();
|
||||||
|
Map<String, RouteSequenceVO> routeSequenceVOMap = ctcRepository.getRouteSequenceVOMap();
|
||||||
|
HashSet<String> stationCodes = new HashSet<>(trackViewVOMap.keySet());
|
||||||
|
stationCodes.addAll(routeSequenceVOMap.keySet());
|
||||||
|
for (String stationCode : stationCodes) {
|
||||||
|
TrackViewVO trackViewVO = trackViewVOMap.get(stationCode);
|
||||||
|
RouteSequenceVO routeSequenceVO = routeSequenceVOMap.get(stationCode);
|
||||||
|
BusyBoardVO busyBoardVO = new BusyBoardVO(stationCode, routeSequenceVO, trackViewVO);
|
||||||
|
list.add(busyBoardVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(Simulation simulation) {
|
SocketMessageVO<List<BusyBoardVO>> message
|
||||||
sendTrackViewMessage(simulation);
|
= SocketMessageFactory.buildCtcBusyBoardMessage(simulation.getId(), list);
|
||||||
sendRouteSequenceMessage(simulation);
|
stompMessageService.sendToUser(userId, message);
|
||||||
// 发送运行计划变化消息
|
}
|
||||||
sendRunPlanChangeMessage(simulation);
|
|
||||||
sendRunPlanRemoveMessage(simulation);
|
|
||||||
// 下发计划
|
|
||||||
sendZoneRunPlanSend(simulation);
|
|
||||||
// 发送计划按钮是否闪烁
|
|
||||||
sendRunPlanConfirmActiveMessage(simulation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendMessageWhenSubscribeCtc(Simulation simulation, String userId) {
|
/**
|
||||||
sendAllBusyBoardMessage(simulation, userId);
|
* 发送该成员所属受令方的未读的调度命令
|
||||||
//dis cmd v1
|
*/
|
||||||
sendUnreadDispatchCommand(simulation, userId);
|
private void sendUnreadDispatchCommand(Simulation simulation, String userId) {
|
||||||
//dis cmd v2
|
SimulationMember member = simulation.querySimulationMemberByUserId(userId);
|
||||||
disCmdService.autoSendUnread(simulation,userId);
|
if (member != null) {
|
||||||
}
|
List<RailDispatchCommandVO> unreadCommands = ctcDispatchCommandService.queryUnreadDispatchCommand(
|
||||||
|
simulation, member);
|
||||||
private void sendAllBusyBoardMessage(Simulation simulation, String userId) {
|
for (RailDispatchCommandVO unreadCommand : unreadCommands) {
|
||||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
WebSocketMessage<RailDispatchCommandVO.WsMsgType, RailDispatchCommandVO> messageBody
|
||||||
List<BusyBoardVO> list = new ArrayList<>();
|
= new WebSocketMessage<>(RailDispatchCommandVO.WsMsgType.ADD, unreadCommand);
|
||||||
Map<String, TrackViewVO> trackViewVOMap = ctcRepository.getTrackViewVOMap();
|
SocketMessageVO<WebSocketMessage<RailDispatchCommandVO.WsMsgType, RailDispatchCommandVO>> message
|
||||||
Map<String, RouteSequenceVO> routeSequenceVOMap = ctcRepository.getRouteSequenceVOMap();
|
= SocketMessageFactory.buildDispatchCommandMessage(simulation.getId(), messageBody);
|
||||||
HashSet<String> stationCodes = new HashSet<>(trackViewVOMap.keySet());
|
|
||||||
stationCodes.addAll(routeSequenceVOMap.keySet());
|
|
||||||
for (String stationCode : stationCodes) {
|
|
||||||
TrackViewVO trackViewVO = trackViewVOMap.get(stationCode);
|
|
||||||
RouteSequenceVO routeSequenceVO = routeSequenceVOMap.get(stationCode);
|
|
||||||
BusyBoardVO busyBoardVO = new BusyBoardVO(stationCode, routeSequenceVO, trackViewVO);
|
|
||||||
list.add(busyBoardVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
SocketMessageVO<List<BusyBoardVO>> message
|
|
||||||
= SocketMessageFactory.buildCtcBusyBoardMessage(simulation.getId(), list);
|
|
||||||
stompMessageService.sendToUser(userId, message);
|
stompMessageService.sendToUser(userId, message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
private void trackViewUpdate(Simulation simulation) {
|
||||||
* 发送该成员所属受令方的未读的调度命令
|
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||||
*/
|
for (TrackView trackView : ctcRepository.getTrackViewMap().values()) {
|
||||||
private void sendUnreadDispatchCommand(Simulation simulation, String userId) {
|
for (Map<String, TrackView.Line> lineMap : trackView.getTrackLineMap().values()) {
|
||||||
SimulationMember member = simulation.querySimulationMemberByUserId(userId);
|
Iterator<TrackView.Line> lineIterator = lineMap.values().iterator();
|
||||||
if (member != null) {
|
while (lineIterator.hasNext()) {
|
||||||
List<RailDispatchCommandVO> unreadCommands = ctcDispatchCommandService.queryUnreadDispatchCommand(simulation, member);
|
TrackView.Line line = lineIterator.next();
|
||||||
for (RailDispatchCommandVO unreadCommand : unreadCommands) {
|
int remain = line.getRemain2Delete();
|
||||||
WebSocketMessage<RailDispatchCommandVO.WsMsgType, RailDispatchCommandVO> messageBody
|
if (remain == -1) {
|
||||||
= new WebSocketMessage<>(RailDispatchCommandVO.WsMsgType.ADD, unreadCommand);
|
TrackView.Process process = line.getProcess();
|
||||||
SocketMessageVO<WebSocketMessage<RailDispatchCommandVO.WsMsgType, RailDispatchCommandVO>> message
|
if (TrackView.Process.FINISH.equals(process)) {
|
||||||
= SocketMessageFactory.buildDispatchCommandMessage(simulation.getId(), messageBody);
|
line.startDelayDelete();
|
||||||
stompMessageService.sendToUser(userId, message);
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
remain -= LOGIC_RATE;
|
||||||
|
if (remain <= 0) {
|
||||||
private void trackViewUpdate(Simulation simulation) {
|
lineIterator.remove();
|
||||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
|
||||||
for (TrackView trackView : ctcRepository.getTrackViewMap().values()) {
|
|
||||||
for (Map<String, TrackView.Line> lineMap : trackView.getTrackLineMap().values()) {
|
|
||||||
Iterator<TrackView.Line> lineIterator = lineMap.values().iterator();
|
|
||||||
while (lineIterator.hasNext()) {
|
|
||||||
TrackView.Line line = lineIterator.next();
|
|
||||||
int remain = line.getRemain2Delete();
|
|
||||||
if (remain == -1) {
|
|
||||||
TrackView.Process process = line.getProcess();
|
|
||||||
if (TrackView.Process.FINISH.equals(process)) {
|
|
||||||
line.startDelayDelete();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
remain -= LOGIC_RATE;
|
|
||||||
if (remain <= 0) {
|
|
||||||
lineIterator.remove();
|
|
||||||
} else {
|
|
||||||
line.setRemain2Delete(remain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进路序列更新与自触
|
|
||||||
*/
|
|
||||||
private void routeSequenceUpdate(Simulation simulation) {
|
|
||||||
LocalDateTime correctSystemTime = simulation.getCorrectSystemTime();
|
|
||||||
SimulationDataRepository repository = simulation.getRepository();
|
|
||||||
for (Map.Entry<String, RouteSequence> entry : simulation.getCtcRepository().getRouteSequenceMap().entrySet()) {
|
|
||||||
String stationCode = entry.getKey();
|
|
||||||
Station station = repository.getByCode(stationCode, Station.class);
|
|
||||||
RouteSequence routeSequence = entry.getValue();
|
|
||||||
for (RouteSequence.Line line : routeSequence.getLines()) {
|
|
||||||
//更新触发/正在触发状态
|
|
||||||
if (line.isTriggered())
|
|
||||||
continue;
|
|
||||||
Route route = line.getRoute();
|
|
||||||
if (route == null)
|
|
||||||
continue;
|
|
||||||
if (Objects.equals(line.getTripNumber(), route.getTripNumber())) {
|
|
||||||
if (route.isLock()) {
|
|
||||||
line.setTriggered(true);
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
line.setSetting(route.isSetting());
|
|
||||||
if (line.isSetting())
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//自动触发
|
|
||||||
if (station.isInterlockControl() || !line.isAutoTrigger()) //非常站控或者没有设置自触
|
|
||||||
continue;
|
|
||||||
TrainInfo trainInfo = repository.findSupervisedTrainByTrip("", line.getTripNumber());
|
|
||||||
if (line.isDeparture()) { //发车进路需列车停稳并到达计划时间
|
|
||||||
if (correctSystemTime.isBefore(line.getPlanDateTime()))
|
|
||||||
continue;
|
|
||||||
if (trainInfo != null && trainInfo.isStop() && Objects.equals(trainInfo.getPhysicalSection(), line.getTrackCode()))
|
|
||||||
ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null);
|
|
||||||
} else {
|
|
||||||
if (!correctSystemTime.isBefore(line.getPlanDateTime()))
|
|
||||||
ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null);
|
|
||||||
else if (trainInfo != null && line.isTriggerSection(trainInfo.getPhysicalSection()))
|
|
||||||
ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新行车日志状态
|
|
||||||
*/
|
|
||||||
private void updateRunPlanLog(Simulation simulation) {
|
|
||||||
SimulationDataRepository repository = simulation.getRepository();
|
|
||||||
String actualTime = simulation.getCorrectSystemTime().toLocalTime().toString();
|
|
||||||
int index = actualTime.indexOf(".");
|
|
||||||
if (index != -1) {
|
|
||||||
actualTime = actualTime.substring(0, index);
|
|
||||||
}
|
|
||||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
|
||||||
for (TrainInfo trainInfo : repository.getSuperviseTrainList()) {
|
|
||||||
VirtualRealityTrain train = repository.getOnlineTrainBy(trainInfo.getGroupNumber());
|
|
||||||
SectionPosition headPosition = train.getHeadPosition();
|
|
||||||
Section headSection = headPosition.getSection();
|
|
||||||
Station station = headSection.getDeviceStation();
|
|
||||||
String tripNumber = trainInfo.getTripNumber();
|
|
||||||
CtcStationRunPlanLog runPlan = ctcRepository.findRunPlan(station.getCode(), tripNumber);
|
|
||||||
if (runPlan == null)
|
|
||||||
continue;
|
|
||||||
// 接车计划到点:列车占压区段与接车计划股道一致,且列车是停站状态
|
|
||||||
CtcStationRunPlanLog.RunPlanItem arriveRunPlan = runPlan.getArriveRunPlan();
|
|
||||||
if (arriveRunPlan != null) {
|
|
||||||
if (!arriveRunPlan.isFinish()) {
|
|
||||||
if (headSection.equals(arriveRunPlan.getTrackSection()) && train.isParkingAt()) {
|
|
||||||
arriveRunPlan.setActualTime(actualTime);
|
|
||||||
arriveRunPlan.setFinish(true);
|
|
||||||
//设置上一站的<邻站到达>
|
|
||||||
Station previousStation = runPlan.findPreviousStation();
|
|
||||||
if (previousStation != null) {
|
|
||||||
CtcStationRunPlanLog previousRunPlan = ctcRepository.findRunPlan(previousStation.getCode(), tripNumber);
|
|
||||||
if (previousRunPlan != null) {
|
|
||||||
CtcStationRunPlanLog.RunPlanItem previousDeparturePlan = previousRunPlan.getDepartRunPlan();
|
|
||||||
if (previousDeparturePlan != null) {
|
|
||||||
previousDeparturePlan.setAdjacentDepart(actualTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 发车计划发点:列车位置越过出站信号机
|
|
||||||
CtcStationRunPlanLog.RunPlanItem departRunPlan = runPlan.getDepartRunPlan();
|
|
||||||
if (departRunPlan != null) {
|
|
||||||
if (!departRunPlan.isFinish()) { //实际发车时间没填
|
|
||||||
Section trackSection = departRunPlan.getTrackSection();
|
|
||||||
Signal signal = trackSection.getSignalOf(departRunPlan.isRight());
|
|
||||||
if (headPosition.isAheadOf(signal.getPosition(), departRunPlan.isRight())) { //车头越过出站信号机
|
|
||||||
departRunPlan.setActualTime(actualTime);
|
|
||||||
departRunPlan.setFinish(true);
|
|
||||||
//设置下一站的<邻站出发>
|
|
||||||
Station nextStation = runPlan.findNextStation();
|
|
||||||
if (nextStation != null) {
|
|
||||||
CtcStationRunPlanLog nextRunPlan = ctcRepository.findRunPlan(nextStation.getCode(), tripNumber);
|
|
||||||
if (nextRunPlan != null) {
|
|
||||||
CtcStationRunPlanLog.RunPlanItem nextArriveRunPlan = nextRunPlan.getArriveRunPlan();
|
|
||||||
if (nextArriveRunPlan != null) {
|
|
||||||
nextArriveRunPlan.setAdjacentDepart(actualTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendTrackViewMessage(Simulation simulation) {
|
|
||||||
List<BusyBoardVO> list = new ArrayList<>();
|
|
||||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
|
||||||
Map<String, TrackView> trackViewMap = ctcRepository.getTrackViewMap();
|
|
||||||
Map<String, TrackViewVO> trackViewVOMap = ctcRepository.getTrackViewVOMap();
|
|
||||||
for (Map.Entry<String, TrackView> trackViewEntry : trackViewMap.entrySet()) {
|
|
||||||
String stationCode = trackViewEntry.getKey();
|
|
||||||
TrackView trackView = trackViewEntry.getValue();
|
|
||||||
TrackViewVO trackViewVO = trackViewVOMap.get(stationCode);
|
|
||||||
TrackViewVO changedViewVO;
|
|
||||||
if (trackViewVO == null) {
|
|
||||||
trackViewVO = new TrackViewVO(trackView);
|
|
||||||
trackViewVOMap.put(stationCode, trackViewVO);
|
|
||||||
changedViewVO = trackViewVO;
|
|
||||||
} else {
|
} else {
|
||||||
changedViewVO = trackViewVO.updateAndReturnChanged(trackView);
|
line.setRemain2Delete(remain);
|
||||||
}
|
|
||||||
if (changedViewVO != null) {
|
|
||||||
BusyBoardVO busyBoardVO = new BusyBoardVO(stationCode, null, changedViewVO);
|
|
||||||
list.add(busyBoardVO);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!CollectionUtils.isEmpty(list)) {
|
}
|
||||||
SocketMessageVO<List<BusyBoardVO>> message
|
|
||||||
= SocketMessageFactory.buildCtcBusyBoardMessage(simulation.getId(), list);
|
|
||||||
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送进路序列消息
|
* 进路序列更新与自触
|
||||||
*/
|
*/
|
||||||
private void sendRouteSequenceMessage(Simulation simulation) {
|
private void routeSequenceUpdate(Simulation simulation) {
|
||||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
LocalDateTime correctSystemTime = simulation.getCorrectSystemTime();
|
||||||
Map<String, RouteSequence> routeSequenceMap = ctcRepository.getRouteSequenceMap();
|
SimulationDataRepository repository = simulation.getRepository();
|
||||||
Map<String, RouteSequenceVO> routeSequenceVOMap = ctcRepository.getRouteSequenceVOMap();
|
for (Map.Entry<String, RouteSequence> entry : simulation.getCtcRepository()
|
||||||
List<BusyBoardVO> list = new ArrayList<>();
|
.getRouteSequenceMap().entrySet()) {
|
||||||
if (CollectionUtils.isEmpty(routeSequenceVOMap)) {
|
String stationCode = entry.getKey();
|
||||||
for (RouteSequence routeSequence : routeSequenceMap.values()) {
|
Station station = repository.getByCode(stationCode, Station.class);
|
||||||
RouteSequenceVO routeSequenceVO = new RouteSequenceVO(routeSequence);
|
RouteSequence routeSequence = entry.getValue();
|
||||||
routeSequenceVOMap.put(routeSequenceVO.getStationCode(), routeSequenceVO);
|
for (RouteSequence.Line line : routeSequence.getLines()) {
|
||||||
BusyBoardVO busyBoardVO = new BusyBoardVO(routeSequenceVO.getStationCode(), routeSequenceVO, null);
|
//更新触发/正在触发状态
|
||||||
list.add(busyBoardVO);
|
if (line.isTriggered()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Route route = line.getRoute();
|
||||||
|
if (route == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (Objects.equals(line.getTripNumber(), route.getTripNumber())) {
|
||||||
|
if (route.isLock()) {
|
||||||
|
line.setTriggered(true);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
line.setSetting(route.isSetting());
|
||||||
|
if (line.isSetting()) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//自动触发
|
||||||
|
if (station.isInterlockControl() || !line.isAutoTrigger()) //非常站控或者没有设置自触
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TrainInfo trainInfo = repository.findSupervisedTrainByTrip("", line.getTripNumber());
|
||||||
|
if (line.isDeparture()) { //发车进路需列车停稳并到达计划时间
|
||||||
|
if (correctSystemTime.isBefore(line.getPlanDateTime())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (trainInfo != null && trainInfo.isStop() && Objects.equals(
|
||||||
|
trainInfo.getPhysicalSection(), line.getTrackCode())) {
|
||||||
|
ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (RouteSequence routeSequence : routeSequenceMap.values()) {
|
if (!correctSystemTime.isBefore(line.getPlanDateTime())) {
|
||||||
RouteSequenceVO vo = routeSequenceVOMap.get(routeSequence.getStationCode());
|
ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null);
|
||||||
RouteSequenceVO changed = vo.updateAndReturnChanged(routeSequence);
|
} else if (trainInfo != null && line.isTriggerSection(trainInfo.getPhysicalSection())) {
|
||||||
if (changed != null) {
|
ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null);
|
||||||
BusyBoardVO busyBoardVO = new BusyBoardVO(vo.getStationCode(), changed, null);
|
}
|
||||||
list.add(busyBoardVO);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新行车日志状态
|
||||||
|
*/
|
||||||
|
private void updateRunPlanLog(Simulation simulation) {
|
||||||
|
SimulationDataRepository repository = simulation.getRepository();
|
||||||
|
String actualTime = simulation.getCorrectSystemTime().toLocalTime().toString();
|
||||||
|
int index = actualTime.indexOf(".");
|
||||||
|
if (index != -1) {
|
||||||
|
actualTime = actualTime.substring(0, index);
|
||||||
|
}
|
||||||
|
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||||
|
for (TrainInfo trainInfo : repository.getSuperviseTrainList()) {
|
||||||
|
VirtualRealityTrain train = repository.getOnlineTrainBy(trainInfo.getGroupNumber());
|
||||||
|
SectionPosition headPosition = train.getHeadPosition();
|
||||||
|
Section headSection = headPosition.getSection();
|
||||||
|
Station station = headSection.getDeviceStation();
|
||||||
|
String tripNumber = trainInfo.getTripNumber();
|
||||||
|
CtcStationRunPlanLog runPlan = ctcRepository.findRunPlan(station.getCode(), tripNumber);
|
||||||
|
if (runPlan == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 接车计划到点:列车占压区段与接车计划股道一致,且列车是停站状态
|
||||||
|
CtcStationRunPlanLog.RunPlanItem arriveRunPlan = runPlan.getArriveRunPlan();
|
||||||
|
if (arriveRunPlan != null) {
|
||||||
|
if (!arriveRunPlan.isFinish()) {
|
||||||
|
if (headSection.equals(arriveRunPlan.getTrackSection()) && train.isParkingAt()) {
|
||||||
|
arriveRunPlan.setActualTime(actualTime);
|
||||||
|
arriveRunPlan.setFinish(true);
|
||||||
|
//设置上一站的<邻站到达>
|
||||||
|
Station previousStation = runPlan.findPreviousStation();
|
||||||
|
if (previousStation != null) {
|
||||||
|
CtcStationRunPlanLog previousRunPlan = ctcRepository.findRunPlan(
|
||||||
|
previousStation.getCode(), tripNumber);
|
||||||
|
if (previousRunPlan != null) {
|
||||||
|
CtcStationRunPlanLog.RunPlanItem previousDeparturePlan = previousRunPlan.getDepartRunPlan();
|
||||||
|
if (previousDeparturePlan != null) {
|
||||||
|
previousDeparturePlan.setAdjacentDepart(actualTime);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!CollectionUtils.isEmpty(list)) {
|
}
|
||||||
SocketMessageVO<List<BusyBoardVO>> message
|
// 发车计划发点:列车位置越过出站信号机
|
||||||
= SocketMessageFactory.buildCtcBusyBoardMessage(simulation.getId(), list);
|
CtcStationRunPlanLog.RunPlanItem departRunPlan = runPlan.getDepartRunPlan();
|
||||||
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
if (departRunPlan != null) {
|
||||||
}
|
if (!departRunPlan.isFinish()) { //实际发车时间没填
|
||||||
}
|
Section trackSection = departRunPlan.getTrackSection();
|
||||||
|
Signal signal = trackSection.getSignalOf(departRunPlan.isRight());
|
||||||
public void addJobs(Simulation simulation) {
|
if (headPosition.isAheadOf(signal.getPosition(), departRunPlan.isRight())) { //车头越过出站信号机
|
||||||
simulation.addJob(LOGIC_NAME, () -> this.run(simulation), LOGIC_RATE);
|
departRunPlan.setActualTime(actualTime);
|
||||||
simulation.addFixedRateJob(MESSAGE_NAME, () -> this.sendMessage(simulation), MESSAGE_RATE);
|
departRunPlan.setFinish(true);
|
||||||
}
|
//设置下一站的<邻站出发>
|
||||||
|
Station nextStation = runPlan.findNextStation();
|
||||||
/**
|
if (nextStation != null) {
|
||||||
* 行车区段运行计划下发
|
CtcStationRunPlanLog nextRunPlan = ctcRepository.findRunPlan(nextStation.getCode(),
|
||||||
*/
|
tripNumber);
|
||||||
public void sendZoneRunPlanSend(Simulation simulation) {
|
if (nextRunPlan != null) {
|
||||||
List<CtcEffectRepository.CtcStageRunPlanRepository.CtcStageRunPlanVO> allList = simulation.getCtcRepository().getCtcEffectRepository().getChangeStageRunPlan();
|
CtcStationRunPlanLog.RunPlanItem nextArriveRunPlan = nextRunPlan.getArriveRunPlan();
|
||||||
if (!CollectionUtils.isEmpty(allList)) {
|
if (nextArriveRunPlan != null) {
|
||||||
sendCtcMessage(simulation.getId(), allList, WebSocketMessageType.SIMULATION_RAILWAY_RUN_PLAN_SEND, simulation.getSimulationUserIds());
|
nextArriveRunPlan.setAdjacentDepart(actualTime);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 运行计划发送变化事件
|
|
||||||
*/
|
|
||||||
private void sendRunPlanChangeMessage(Simulation simulation) {
|
|
||||||
Map<String, CtcStationRunPlanLogVO> ctcRunPlanVOMap = simulation.getCtcRepository().getRunPlanStatusVOMap();
|
|
||||||
List<CtcStationRunPlanLog> allRunPlanList = simulation.getCtcRepository().getAllRunPlanList();
|
|
||||||
List<CtcStationRunPlanLogVO> messageList = new ArrayList<>();
|
|
||||||
allRunPlanList.forEach(runPlan -> {
|
|
||||||
String mapKey = runPlan.getStation().getCode() + "_" + runPlan.getCode();
|
|
||||||
CtcStationRunPlanLogVO runPlanVO = ctcRunPlanVOMap.get(mapKey);
|
|
||||||
if (runPlanVO == null) {
|
|
||||||
ctcRunPlanVOMap.put(mapKey, new CtcStationRunPlanLogVO(runPlan));
|
|
||||||
messageList.add(ctcRunPlanVOMap.get(mapKey));
|
|
||||||
} else {
|
|
||||||
CtcStationRunPlanLogVO changeCtcStationRunPlanLogVo = runPlanVO.compareAndChange(runPlan);
|
|
||||||
if (changeCtcStationRunPlanLogVo != null) {
|
|
||||||
messageList.add(changeCtcStationRunPlanLogVo);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
if (!CollectionUtils.isEmpty(messageList)) {
|
|
||||||
sendCtcMessage(simulation.getId(), messageList
|
|
||||||
, WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_CHANGE, simulation.getSimulationUserIds());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
private void sendTrackViewMessage(Simulation simulation) {
|
||||||
* 运行计划移除时清除垃圾数据
|
List<BusyBoardVO> list = new ArrayList<>();
|
||||||
*
|
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||||
* @param simulation 仿真实体
|
Map<String, TrackView> trackViewMap = ctcRepository.getTrackViewMap();
|
||||||
*/
|
Map<String, TrackViewVO> trackViewVOMap = ctcRepository.getTrackViewVOMap();
|
||||||
public void sendRunPlanRemoveMessage(Simulation simulation) {
|
for (Map.Entry<String, TrackView> trackViewEntry : trackViewMap.entrySet()) {
|
||||||
Map<String, CtcStationRunPlanLogVO> ctcRunPlanVOMap = simulation.getCtcRepository().getRunPlanStatusVOMap();
|
String stationCode = trackViewEntry.getKey();
|
||||||
List<CtcStationRunPlanLogVO> ctcStationRunPlanLogVOList = ctcRunPlanVOMap.values().stream()
|
TrackView trackView = trackViewEntry.getValue();
|
||||||
.filter(vo -> simulation.getCtcRepository().getRunPlanByRunPlanCodeAndStationCode(vo.getStationCode(), vo.getCode()) == null)
|
TrackViewVO trackViewVO = trackViewVOMap.get(stationCode);
|
||||||
.map(vo -> new CtcStationRunPlanLogVO(vo.getStationCode(), vo.getCode()))
|
TrackViewVO changedViewVO;
|
||||||
.collect(Collectors.toList());
|
if (trackViewVO == null) {
|
||||||
if (!CollectionUtils.isEmpty(ctcStationRunPlanLogVOList)) {
|
trackViewVO = new TrackViewVO(trackView);
|
||||||
// 移除已删除的数据
|
trackViewVOMap.put(stationCode, trackViewVO);
|
||||||
ctcStationRunPlanLogVOList.forEach(vo -> ctcRunPlanVOMap.remove(vo.getStationCode() + "_" + vo.getCode()));
|
changedViewVO = trackViewVO;
|
||||||
sendCtcMessage(simulation.getId(), ctcStationRunPlanLogVOList
|
} else {
|
||||||
, WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_REMOVE, simulation.getSimulationUserIds());
|
changedViewVO = trackViewVO.updateAndReturnChanged(trackView);
|
||||||
|
}
|
||||||
|
if (changedViewVO != null) {
|
||||||
|
BusyBoardVO busyBoardVO = new BusyBoardVO(stationCode, null, changedViewVO);
|
||||||
|
list.add(busyBoardVO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!CollectionUtils.isEmpty(list)) {
|
||||||
|
SocketMessageVO<List<BusyBoardVO>> message
|
||||||
|
= SocketMessageFactory.buildCtcBusyBoardMessage(simulation.getId(), list);
|
||||||
|
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送进路序列消息
|
||||||
|
*/
|
||||||
|
private void sendRouteSequenceMessage(Simulation simulation) {
|
||||||
|
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||||
|
Map<String, RouteSequence> routeSequenceMap = ctcRepository.getRouteSequenceMap();
|
||||||
|
Map<String, RouteSequenceVO> routeSequenceVOMap = ctcRepository.getRouteSequenceVOMap();
|
||||||
|
List<BusyBoardVO> list = new ArrayList<>();
|
||||||
|
if (CollectionUtils.isEmpty(routeSequenceVOMap)) {
|
||||||
|
for (RouteSequence routeSequence : routeSequenceMap.values()) {
|
||||||
|
RouteSequenceVO routeSequenceVO = new RouteSequenceVO(routeSequence);
|
||||||
|
routeSequenceVOMap.put(routeSequenceVO.getStationCode(), routeSequenceVO);
|
||||||
|
BusyBoardVO busyBoardVO = new BusyBoardVO(routeSequenceVO.getStationCode(), routeSequenceVO,
|
||||||
|
null);
|
||||||
|
list.add(busyBoardVO);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (RouteSequence routeSequence : routeSequenceMap.values()) {
|
||||||
|
RouteSequenceVO vo = routeSequenceVOMap.get(routeSequence.getStationCode());
|
||||||
|
RouteSequenceVO changed = vo.updateAndReturnChanged(routeSequence);
|
||||||
|
if (changed != null) {
|
||||||
|
BusyBoardVO busyBoardVO = new BusyBoardVO(vo.getStationCode(), changed, null);
|
||||||
|
list.add(busyBoardVO);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (!CollectionUtils.isEmpty(list)) {
|
||||||
|
SocketMessageVO<List<BusyBoardVO>> message
|
||||||
|
= SocketMessageFactory.buildCtcBusyBoardMessage(simulation.getId(), list);
|
||||||
|
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
public void addJobs(Simulation simulation) {
|
||||||
* 运行计划发送计划
|
simulation.addJob(LOGIC_NAME, () -> this.run(simulation), LOGIC_RATE);
|
||||||
*/
|
simulation.addFixedRateJob(MESSAGE_NAME, () -> this.sendMessage(simulation), MESSAGE_RATE);
|
||||||
public void sendRunPlanConfirmActiveMessage(Simulation simulation) {
|
}
|
||||||
Map<String, Boolean> changeMap = new HashMap<>();
|
|
||||||
simulation.getCtcRepository().getSimulationRunPlanMap().forEach((k, v) -> {
|
/**
|
||||||
boolean isChange = v.values().stream().anyMatch(CtcStationRunPlanLog::isChange);
|
* 行车区段运行计划下发
|
||||||
if (isChange) {
|
*/
|
||||||
changeMap.put(k, Boolean.TRUE);
|
public void sendZoneRunPlanSend(Simulation simulation) {
|
||||||
|
List<CtcEffectRepository.CtcStageRunPlanRepository.CtcStageRunPlanVO> allList = simulation.getCtcRepository()
|
||||||
|
.getCtcEffectRepository().getChangeStageRunPlan();
|
||||||
|
if (!CollectionUtils.isEmpty(allList)) {
|
||||||
|
sendCtcMessage(simulation.getId(), allList,
|
||||||
|
WebSocketMessageType.SIMULATION_RAILWAY_RUN_PLAN_SEND, simulation.getSimulationUserIds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 运行计划发送变化事件
|
||||||
|
*/
|
||||||
|
private void sendRunPlanChangeMessage(Simulation simulation) {
|
||||||
|
Map<String, CtcStationRunPlanLogVO> ctcRunPlanVOMap = simulation.getCtcRepository()
|
||||||
|
.getRunPlanStatusVOMap();
|
||||||
|
List<CtcStationRunPlanLog> allRunPlanList = simulation.getCtcRepository().getAllRunPlanList();
|
||||||
|
List<CtcStationRunPlanLogVO> messageList = new ArrayList<>();
|
||||||
|
allRunPlanList.forEach(runPlan -> {
|
||||||
|
String mapKey = runPlan.getStation().getCode() + "_" + runPlan.getCode();
|
||||||
|
CtcStationRunPlanLogVO runPlanVO = ctcRunPlanVOMap.get(mapKey);
|
||||||
|
if (runPlanVO == null) {
|
||||||
|
ctcRunPlanVOMap.put(mapKey, new CtcStationRunPlanLogVO(runPlan));
|
||||||
|
messageList.add(ctcRunPlanVOMap.get(mapKey));
|
||||||
|
} else {
|
||||||
|
CtcStationRunPlanLogVO changeCtcStationRunPlanLogVo = runPlanVO.compareAndChange(runPlan);
|
||||||
|
if (changeCtcStationRunPlanLogVo != null) {
|
||||||
|
messageList.add(changeCtcStationRunPlanLogVo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!CollectionUtils.isEmpty(messageList)) {
|
||||||
|
sendCtcMessage(simulation.getId(), messageList
|
||||||
|
, WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_CHANGE, simulation.getSimulationUserIds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 运行计划移除时清除垃圾数据
|
||||||
|
*
|
||||||
|
* @param simulation 仿真实体
|
||||||
|
*/
|
||||||
|
public void sendRunPlanRemoveMessage(Simulation simulation) {
|
||||||
|
Map<String, CtcStationRunPlanLogVO> ctcRunPlanVOMap = simulation.getCtcRepository()
|
||||||
|
.getRunPlanStatusVOMap();
|
||||||
|
List<CtcStationRunPlanLogVO> ctcStationRunPlanLogVOList = ctcRunPlanVOMap.values().stream()
|
||||||
|
.filter(vo -> simulation.getCtcRepository()
|
||||||
|
.getRunPlanByRunPlanCodeAndStationCode(vo.getStationCode(), vo.getCode()) == null)
|
||||||
|
.map(vo -> new CtcStationRunPlanLogVO(vo.getStationCode(), vo.getCode()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (!CollectionUtils.isEmpty(ctcStationRunPlanLogVOList)) {
|
||||||
|
// 移除已删除的数据
|
||||||
|
ctcStationRunPlanLogVOList.forEach(
|
||||||
|
vo -> ctcRunPlanVOMap.remove(vo.getStationCode() + "_" + vo.getCode()));
|
||||||
|
sendCtcMessage(simulation.getId(), ctcStationRunPlanLogVOList
|
||||||
|
, WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_REMOVE, simulation.getSimulationUserIds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 运行计划发送计划
|
||||||
|
*/
|
||||||
|
public void sendRunPlanConfirmActiveMessage(Simulation simulation) {
|
||||||
|
Map<String, Boolean> changeMap = new HashMap<>();
|
||||||
|
simulation.getCtcRepository().getSimulationRunPlanMap().forEach((k, v) -> {
|
||||||
|
boolean isChange = v.values().stream().anyMatch(CtcStationRunPlanLog::isChange);
|
||||||
|
if (isChange) {
|
||||||
|
changeMap.put(k, Boolean.TRUE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 为空时
|
||||||
|
if (!Objects.equals(simulation.getCtcRepository().getRunPlanSendOut(), changeMap.isEmpty())
|
||||||
|
|| !changeMap.isEmpty()) {
|
||||||
|
simulation.getCtcRepository().setRunPlanSendOut(changeMap.isEmpty());
|
||||||
|
sendCtcMessage(simulation.getId(), changeMap,
|
||||||
|
WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_CONFIRM_SEND
|
||||||
|
, simulation.getSimulationUserIds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送CTC运行计划消息
|
||||||
|
*
|
||||||
|
* @param simulationId 仿真ID
|
||||||
|
* @param messageInfo 运行计划列表
|
||||||
|
* @param type 消息类型
|
||||||
|
* @param userIds 用户ID
|
||||||
|
*/
|
||||||
|
public <T> void sendCtcMessage(String simulationId, T messageInfo, WebSocketMessageType type,
|
||||||
|
Set<String> userIds) {
|
||||||
|
if (messageInfo != null) {
|
||||||
|
SocketMessageVO<T> messageVO = SocketMessageFactory.build(type, simulationId, messageInfo);
|
||||||
|
stompMessageService.sendToUser(userIds, messageVO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载已签收至占线板上的列车
|
||||||
|
*
|
||||||
|
* @param simulation 仿真信息
|
||||||
|
*/
|
||||||
|
private void loadSignRunPlanTrain(Simulation simulation) {
|
||||||
|
if (!simulation.isPlanRunning() || ProjectCode.THAILAND_SANDBOX.equals(
|
||||||
|
simulation.getProject())) { //泰国沙盘项目不能随意指定列车上线,所以禁用此逻辑,后续考虑用地图配置
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 没有加载过计划、始发计划、已发送至占线板、当前时间晚于计划时间提前5分钟
|
||||||
|
simulation.getCtcRepository().getAllRunPlanList().stream()
|
||||||
|
.filter(r -> r.getDepartRunPlan() != null && (r.isStartRunPlan() || (
|
||||||
|
r.getArriveRunPlan() == null && r.getDepartRunPlan() != null)))
|
||||||
|
.filter(r -> {
|
||||||
|
boolean valid = !r.isLoad() && r.isSign() && r.getStatus() != -1
|
||||||
|
&& simulation.getCorrectSystemTime()
|
||||||
|
.isAfter(r.getDepartRunPlan().getPlanTime().minusMinutes(5));
|
||||||
|
if (valid) {
|
||||||
|
valid = !simulation.getRepository().getTrainInfoMap().values().stream()
|
||||||
|
.anyMatch(trainInfo -> r.getDepartRunPlan().getTripNumber()
|
||||||
|
.equals(trainInfo.getTripNumber()));
|
||||||
|
if (!valid) { // 如果列车已经上线,则直接修改状态
|
||||||
|
r.setLoad(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
})
|
||||||
|
.sorted((r1, r2) ->
|
||||||
|
r1.getDepartRunPlan().getPlanTime().isBefore(r2.getDepartRunPlan().getPlanTime()) ? -1
|
||||||
|
: 1)
|
||||||
|
.forEach(r -> {
|
||||||
|
Section section = r.getDepartRunPlan().getTrackSection();
|
||||||
|
if (section.isFree()) {
|
||||||
|
String tripNumber = r.getDepartRunPlan().getTripNumber();
|
||||||
|
int lastNum = tripNumber.charAt(tripNumber.length() - 1) - 48;
|
||||||
|
atsTrainLoadService.loadTripNumberTrain(simulation, tripNumber, section.getCode(),
|
||||||
|
lastNum % 2 == 0);
|
||||||
|
r.setLoad(true); // 已上线
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// 为空时
|
}
|
||||||
if (!Objects.equals(simulation.getCtcRepository().getRunPlanSendOut(), changeMap.isEmpty()) || !changeMap.isEmpty()) {
|
|
||||||
simulation.getCtcRepository().setRunPlanSendOut(changeMap.isEmpty());
|
|
||||||
sendCtcMessage(simulation.getId(), changeMap, WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_CONFIRM_SEND
|
|
||||||
, simulation.getSimulationUserIds());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送CTC运行计划消息
|
|
||||||
*
|
|
||||||
* @param simulationId 仿真ID
|
|
||||||
* @param messageInfo 运行计划列表
|
|
||||||
* @param type 消息类型
|
|
||||||
* @param userIds 用户ID
|
|
||||||
*/
|
|
||||||
public <T> void sendCtcMessage(String simulationId, T messageInfo, WebSocketMessageType type, Set<String> userIds) {
|
|
||||||
if (messageInfo != null) {
|
|
||||||
SocketMessageVO<T> messageVO = SocketMessageFactory.build(type, simulationId, messageInfo);
|
|
||||||
stompMessageService.sendToUser(userIds, messageVO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 加载已签收至占线板上的列车
|
|
||||||
*
|
|
||||||
* @param simulation 仿真信息
|
|
||||||
*/
|
|
||||||
private void loadSignRunPlanTrain(Simulation simulation) {
|
|
||||||
if (!simulation.isPlanRunning()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 没有加载过计划、始发计划、已发送至占线板、当前时间晚于计划时间提前5分钟
|
|
||||||
simulation.getCtcRepository().getAllRunPlanList().stream()
|
|
||||||
.filter(r -> r.getDepartRunPlan() != null && (r.isStartRunPlan() || (r.getArriveRunPlan() == null && r.getDepartRunPlan() != null)))
|
|
||||||
.filter(r -> {
|
|
||||||
boolean valid = !r.isLoad() && r.isSign() && r.getStatus() != -1
|
|
||||||
&& simulation.getCorrectSystemTime().isAfter(r.getDepartRunPlan().getPlanTime().minusMinutes(5));
|
|
||||||
if (valid) {
|
|
||||||
valid = !simulation.getRepository().getTrainInfoMap().values().stream()
|
|
||||||
.anyMatch(trainInfo -> r.getDepartRunPlan().getTripNumber().equals(trainInfo.getTripNumber()));
|
|
||||||
if (!valid) { // 如果列车已经上线,则直接修改状态
|
|
||||||
r.setLoad(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return valid;
|
|
||||||
})
|
|
||||||
.sorted((r1, r2) -> r1.getDepartRunPlan().getPlanTime().isBefore(r2.getDepartRunPlan().getPlanTime()) ? -1 : 1)
|
|
||||||
.forEach(r -> {
|
|
||||||
Section section = r.getDepartRunPlan().getTrackSection();
|
|
||||||
if (section.isFree()) {
|
|
||||||
String tripNumber = r.getDepartRunPlan().getTripNumber();
|
|
||||||
int lastNum = tripNumber.charAt(tripNumber.length() - 1) - 48;
|
|
||||||
atsTrainLoadService.loadTripNumberTrain(simulation, tripNumber, section.getCode(), lastNum % 2 == 0);
|
|
||||||
r.setLoad(true); // 已上线
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,261 +2,264 @@ package club.joylink.rtss.simulation.cbtc.CTC.service;
|
|||||||
|
|
||||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
|
import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
|
||||||
import club.joylink.rtss.simulation.cbtc.CTC.data.*;
|
import club.joylink.rtss.simulation.cbtc.CTC.data.CascoControl;
|
||||||
|
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.Simulation;
|
||||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.map.SwitchElement;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.annotation.Resource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.time.LocalTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class CTCService {
|
public class CTCService {
|
||||||
@Autowired
|
|
||||||
private CiApiService ciApiService;
|
|
||||||
@Resource
|
|
||||||
private CascoControlService cascoControlService;
|
|
||||||
/**
|
|
||||||
* 创建了新的运行计划item
|
|
||||||
*/
|
|
||||||
public void runPlanItemCreate(Simulation simulation, Station station, CtcStationRunPlanLog.RunPlanItem item, boolean departure) {
|
|
||||||
regenerateRouteSequenceAndTrackView(simulation, station);
|
|
||||||
// CtcRepository ctcRepository = simulation.getCtcRepository();
|
|
||||||
// //进路序列
|
|
||||||
// RouteSequence routeSequence = ctcRepository.getRouteSequence(station.getCode());
|
|
||||||
// AtomicInteger idGenerator = ctcRepository.getRouteSequenceIdGenerator();
|
|
||||||
// RouteSequence.Line line = RouteSequence.buildLine(item, departure, idGenerator);
|
|
||||||
// routeSequence.addLine(line);
|
|
||||||
// //股道视图
|
|
||||||
// TrackView trackView = ctcRepository.getTrackView(station.getCode());
|
|
||||||
// if (departure) {
|
|
||||||
// trackView.addDepartureLine(line);
|
|
||||||
// } else {
|
|
||||||
// trackView.addReceivingLine(line);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
@Autowired
|
||||||
* 运行计划item更新了
|
private CiApiService ciApiService;
|
||||||
*/
|
@Resource
|
||||||
public void runPlanItemUpdate(Simulation simulation, Station station, CtcStationRunPlanLog.RunPlanItem item, boolean departure) {
|
private CascoControlService cascoControlService;
|
||||||
regenerateRouteSequenceAndTrackView(simulation, station);
|
|
||||||
// CtcRepository ctcRepository = simulation.getCtcRepository();
|
|
||||||
// RouteSequence.Line routeSequenceLine = ctcRepository.getRouteSequenceLine(station.getCode(), item.getTripNumber(), departure);
|
|
||||||
//
|
|
||||||
// String oldTc = routeSequenceLine.getTrackCode();
|
|
||||||
// String oldTn = routeSequenceLine.getTripNumber();
|
|
||||||
//
|
|
||||||
// routeSequenceLine.update();
|
|
||||||
//
|
|
||||||
// ctcRepository.updateTrackView(station.getCode(), oldTc, oldTn, routeSequenceLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重新生成进路序列和股道视图
|
* 重新生成进路序列和股道视图 该方法应该在车务终端发送阶段计划之后调用
|
||||||
* 该方法应该在车务终端发送阶段计划之后调用
|
*/
|
||||||
*/
|
public void regenerateRouteSequenceAndTrackView(Simulation simulation, Station station) {
|
||||||
public void regenerateRouteSequenceAndTrackView(Simulation simulation, Station station) {
|
if (simulation.getRepository().getConfig().isHasCTC()) {
|
||||||
if (simulation.getRepository().getConfig().isHasCTC()) {
|
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
ctcRepository.buildRouteSequence(station);
|
||||||
ctcRepository.buildRouteSequence(station);
|
ctcRepository.buildTrackViewData(station);
|
||||||
ctcRepository.buildTrackViewData(station);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 完成接预
|
||||||
|
*/
|
||||||
|
public void finishReceivingNotice(Simulation simulation, String stationCode, String tripNumber) {
|
||||||
|
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
|
||||||
|
plan.finishReceivingNotice();
|
||||||
|
String systemTime = simulation.getCorrectSystemTime()
|
||||||
|
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd"));
|
||||||
|
plan.getArriveRunPlan().setAdjacentMessageTime(systemTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消接预
|
||||||
|
*/
|
||||||
|
public void cancelReceivingNotice(Simulation simulation, String stationCode, String tripNumber) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 完成发预
|
||||||
|
*/
|
||||||
|
public void finishDepartureNotice(Simulation simulation, String stationCode, String tripNumber) {
|
||||||
|
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
|
||||||
|
plan.finishDepartureNotice();
|
||||||
|
String systemTime = simulation.getCorrectSystemTime()
|
||||||
|
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd"));
|
||||||
|
plan.getDepartRunPlan().setAdjacentMessageTime(systemTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelDepartureNotice(Simulation simulation, String stationCode, String tripNumber) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finishArrive(Simulation simulation, String stationCode, String tripNumber,
|
||||||
|
LocalTime time) {
|
||||||
|
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
|
||||||
|
if (time == null) {
|
||||||
|
time = simulation.getCorrectSystemTime().toLocalTime();
|
||||||
|
}
|
||||||
|
plan.finishArrive(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelArrive(Simulation simulation, String stationCode, String tripNumber) {
|
||||||
|
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
|
||||||
|
plan.cancelArrive();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finishDeparture(Simulation simulation, String stationCode, String tripNumber,
|
||||||
|
LocalTime time) {
|
||||||
|
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
|
||||||
|
if (time == null) {
|
||||||
|
time = simulation.getCorrectSystemTime().toLocalTime();
|
||||||
|
}
|
||||||
|
plan.finishDeparture(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelDeparture(Simulation simulation, String stationCode, String tripNumber) {
|
||||||
|
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
|
||||||
|
plan.cancelDeparture();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送发车预告
|
||||||
|
*/
|
||||||
|
public void sendDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) {
|
||||||
|
CtcStationRunPlanLog currentStationPlan = getCtcStationRunPlanByRunPlanCode(simulation,
|
||||||
|
stationCode, runPlanCode);
|
||||||
|
Station nextStation = currentStationPlan.getNextStation();
|
||||||
|
CtcStationRunPlanLog nextStationPlan = getCtcStationRunPlanByRunPlanCode(simulation,
|
||||||
|
nextStation.getCode(), runPlanCode);
|
||||||
|
currentStationPlan.sendDepartureNotice();
|
||||||
|
nextStationPlan.receiveDepartureNotice();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同意发车预告
|
||||||
|
*/
|
||||||
|
public void agreeDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) {
|
||||||
|
CtcStationRunPlanLog currentStationPlan = getCtcStationRunPlanByRunPlanCode(simulation,
|
||||||
|
stationCode, runPlanCode);
|
||||||
|
Station previousStation = currentStationPlan.getPreviousStation();
|
||||||
|
CtcStationRunPlanLog previousStationPlan = getCtcStationRunPlanByRunPlanCode(simulation,
|
||||||
|
previousStation.getCode(), runPlanCode);
|
||||||
|
currentStationPlan.finishReceivingNotice();
|
||||||
|
previousStationPlan.finishDepartureNotice();
|
||||||
|
String systemTime = simulation.getCorrectSystemTime()
|
||||||
|
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd"));
|
||||||
|
currentStationPlan.getArriveRunPlan().setAdjacentMessageTime(systemTime);
|
||||||
|
previousStationPlan.getDepartRunPlan().setAdjacentMessageTime(systemTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进路自触
|
||||||
|
*/
|
||||||
|
public void routeAutoTrigger(Simulation simulation, String stationCode, String tripNumber,
|
||||||
|
String routeCode, boolean trigger) {
|
||||||
|
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||||
|
RouteSequence.Line line = ctcRepository.getRouteSequenceLine(stationCode, tripNumber,
|
||||||
|
routeCode);
|
||||||
|
line.setAutoTrigger(trigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> cascoControl(CascoControl cc, boolean force) {
|
||||||
|
if (Objects.equals(true, force)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return this.cascoControlService.checkCascoControlRoute(cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param simulation
|
||||||
|
* @param routeCode
|
||||||
|
* @param tripNumber
|
||||||
|
* @param force
|
||||||
|
* @param duration
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<String> setRoute(Simulation simulation, String routeCode, String tripNumber,
|
||||||
|
Boolean force, Integer duration) {
|
||||||
|
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||||
|
if (force == null || !force) { // 非强制办理
|
||||||
|
// 存在分路不良的区段
|
||||||
|
boolean isBadShut = route.getSectionList().stream().anyMatch(Section::isBadShunt);
|
||||||
|
if (isBadShut) {
|
||||||
|
throw BusinessExceptionAssertEnum.OPERATION_FAIL.exception("进路不能办理,存在分路不良区段");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Station station = route.getStart().getStation();
|
||||||
|
if (station == null) {
|
||||||
|
station = route.getStart().getDeviceStation();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> conflictInfo = new ArrayList<>();
|
||||||
|
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||||
|
CascoControl cc = new CascoControl(simulation, station, route, tripNumber);
|
||||||
|
List<String> errCCMsg = this.cascoControl(cc,
|
||||||
|
Objects.isNull(force) ? false : force.booleanValue());//站细卡控
|
||||||
|
if (Objects.equals(false, CollectionUtils.isEmpty(errCCMsg))) {
|
||||||
|
//站细检测错误的信息
|
||||||
|
return errCCMsg;
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(tripNumber) && !Objects.equals(true, force)) { //列车进路防错办
|
||||||
|
List<RouteSequence.Line> lines = ctcRepository.findRouteSequenceLines(station.getCode(),
|
||||||
|
tripNumber);
|
||||||
|
if (!CollectionUtils.isEmpty(lines)) {
|
||||||
|
boolean b = lines.stream()
|
||||||
|
.noneMatch(line -> Objects.equals(line.getRouteCode(), routeCode));
|
||||||
|
if (b) {
|
||||||
|
conflictInfo.add(
|
||||||
|
String.format("车次[%s]的进路序列中不包含进路[name:%s]", tripNumber, route.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (duration != null && !Objects.equals(true, force)) { //调车进路防错办
|
||||||
|
Set<Section> sections = new HashSet<>(route.getSectionList());
|
||||||
|
Map<Switch, SwitchElement> switchMap = new HashMap<>();
|
||||||
|
List<SwitchElement> switchList = route.getSwitchList();
|
||||||
|
if (!CollectionUtils.isEmpty(switchList)) {
|
||||||
|
switchMap = switchList.stream()
|
||||||
|
.collect(Collectors.toMap(SwitchElement::getASwitch, Function.identity()));
|
||||||
|
}
|
||||||
|
LocalTime endTime = simulation.getCorrectSystemTime().plusSeconds(duration).toLocalTime();
|
||||||
|
List<RouteSequence.Line> lines = ctcRepository.findRouteSequenceLineThatLessThan(
|
||||||
|
station.getCode(), endTime);
|
||||||
|
out:
|
||||||
|
for (RouteSequence.Line line : lines) {
|
||||||
|
Route lineRoute = line.getRoute();
|
||||||
|
if (lineRoute == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (Section section : lineRoute.getSectionList()) {
|
||||||
|
if (sections.contains(section)) {
|
||||||
|
conflictInfo.add(String.format("所选进路[name:%s]与车次[%s]的[name:%s]进路冲突",
|
||||||
|
route.getName(), line.getTripNumber(), lineRoute.getName()));
|
||||||
|
continue out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
List<SwitchElement> sl = lineRoute.getSwitchList();
|
||||||
|
if (!CollectionUtils.isEmpty(sl)) {
|
||||||
/**
|
for (SwitchElement element : sl) {
|
||||||
* 完成接预
|
SwitchElement e = switchMap.get(element.getASwitch());
|
||||||
*/
|
if (e != null && !element.equals(e)) {
|
||||||
public void finishReceivingNotice(Simulation simulation, String stationCode, String tripNumber) {
|
conflictInfo.add(String.format("所选进路[name:%s]与车次[%s]的[name:%s]进路冲突",
|
||||||
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
|
route.getName(), line.getTripNumber(), lineRoute.getName()));
|
||||||
plan.finishReceivingNotice();
|
continue out;
|
||||||
String systemTime = simulation.getCorrectSystemTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd"));
|
|
||||||
plan.getArriveRunPlan().setAdjacentMessageTime(systemTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消接预
|
|
||||||
*/
|
|
||||||
public void cancelReceivingNotice(Simulation simulation, String stationCode, String tripNumber) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 完成发预
|
|
||||||
*/
|
|
||||||
public void finishDepartureNotice(Simulation simulation, String stationCode, String tripNumber) {
|
|
||||||
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
|
|
||||||
plan.finishDepartureNotice();
|
|
||||||
String systemTime = simulation.getCorrectSystemTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd"));
|
|
||||||
plan.getDepartRunPlan().setAdjacentMessageTime(systemTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancelDepartureNotice(Simulation simulation, String stationCode, String tripNumber) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void finishArrive(Simulation simulation, String stationCode, String tripNumber, LocalTime time) {
|
|
||||||
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
|
|
||||||
if (time == null)
|
|
||||||
time = simulation.getCorrectSystemTime().toLocalTime();
|
|
||||||
plan.finishArrive(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancelArrive(Simulation simulation, String stationCode, String tripNumber) {
|
|
||||||
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
|
|
||||||
plan.cancelArrive();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void finishDeparture(Simulation simulation, String stationCode, String tripNumber, LocalTime time) {
|
|
||||||
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
|
|
||||||
if (time == null)
|
|
||||||
time = simulation.getCorrectSystemTime().toLocalTime();
|
|
||||||
plan.finishDeparture(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancelDeparture(Simulation simulation, String stationCode, String tripNumber) {
|
|
||||||
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
|
|
||||||
plan.cancelDeparture();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送发车预告
|
|
||||||
*/
|
|
||||||
public void sendDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) {
|
|
||||||
CtcStationRunPlanLog currentStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, stationCode, runPlanCode);
|
|
||||||
Station nextStation = currentStationPlan.getNextStation();
|
|
||||||
CtcStationRunPlanLog nextStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, nextStation.getCode(), runPlanCode);
|
|
||||||
currentStationPlan.sendDepartureNotice();
|
|
||||||
nextStationPlan.receiveDepartureNotice();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 同意发车预告
|
|
||||||
*/
|
|
||||||
public void agreeDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) {
|
|
||||||
CtcStationRunPlanLog currentStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, stationCode, runPlanCode);
|
|
||||||
Station previousStation = currentStationPlan.getPreviousStation();
|
|
||||||
CtcStationRunPlanLog previousStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, previousStation.getCode(), runPlanCode);
|
|
||||||
currentStationPlan.finishReceivingNotice();
|
|
||||||
previousStationPlan.finishDepartureNotice();
|
|
||||||
String systemTime = simulation.getCorrectSystemTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd"));
|
|
||||||
currentStationPlan.getArriveRunPlan().setAdjacentMessageTime(systemTime);
|
|
||||||
previousStationPlan.getDepartRunPlan().setAdjacentMessageTime(systemTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进路自触
|
|
||||||
*/
|
|
||||||
public void routeAutoTrigger(Simulation simulation, String stationCode, String tripNumber, String routeCode, boolean trigger) {
|
|
||||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
|
||||||
RouteSequence.Line line = ctcRepository.getRouteSequenceLine(stationCode, tripNumber, routeCode);
|
|
||||||
line.setAutoTrigger(trigger);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> cascoControl(CascoControl cc,boolean force){
|
|
||||||
if(Objects.equals(true,force)){
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return this.cascoControlService.checkCascoControlRoute(cc);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param simulation
|
|
||||||
* @param routeCode
|
|
||||||
* @param tripNumber
|
|
||||||
* @param force
|
|
||||||
* @param duration
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public List<String> setRoute(Simulation simulation, String routeCode, String tripNumber, Boolean force, Integer duration) {
|
|
||||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
|
||||||
if (force == null || !force) { // 非强制办理
|
|
||||||
// 存在分路不良的区段
|
|
||||||
boolean isBadShut = route.getSectionList().stream().anyMatch(Section::isBadShunt);
|
|
||||||
if (isBadShut) {
|
|
||||||
throw BusinessExceptionAssertEnum.OPERATION_FAIL.exception("进路不能办理,存在分路不良区段");
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Station station = route.getStart().getStation();
|
}
|
||||||
if (station == null)
|
|
||||||
station = route.getStart().getDeviceStation();
|
|
||||||
|
|
||||||
List<String> conflictInfo = new ArrayList<>();
|
|
||||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
|
||||||
CascoControl cc = new CascoControl(simulation,station,route,tripNumber);
|
|
||||||
List<String> errCCMsg = this.cascoControl(cc,Objects.isNull(force) ? false:force.booleanValue());//站细卡控
|
|
||||||
if(Objects.equals(false,CollectionUtils.isEmpty(errCCMsg))){
|
|
||||||
//站细检测错误的信息
|
|
||||||
return errCCMsg;
|
|
||||||
}
|
|
||||||
if (StringUtils.hasText(tripNumber) && !Objects.equals(true, force)) { //列车进路防错办
|
|
||||||
List<RouteSequence.Line> lines = ctcRepository.findRouteSequenceLines(station.getCode(), tripNumber);
|
|
||||||
if (!CollectionUtils.isEmpty(lines)) {
|
|
||||||
boolean b = lines.stream().noneMatch(line -> Objects.equals(line.getRouteCode(), routeCode));
|
|
||||||
if (b)
|
|
||||||
conflictInfo.add(String.format("车次[%s]的进路序列中不包含进路[name:%s]", tripNumber, route.getName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (duration != null && !Objects.equals(true, force)) { //调车进路防错办
|
|
||||||
Set<Section> sections = new HashSet<>(route.getSectionList());
|
|
||||||
Map<Switch, SwitchElement> switchMap = new HashMap<>();
|
|
||||||
List<SwitchElement> switchList = route.getSwitchList();
|
|
||||||
if (!CollectionUtils.isEmpty(switchList)) {
|
|
||||||
switchMap = switchList.stream().collect(Collectors.toMap(SwitchElement::getASwitch, Function.identity()));
|
|
||||||
}
|
|
||||||
LocalTime endTime = simulation.getCorrectSystemTime().plusSeconds(duration).toLocalTime();
|
|
||||||
List<RouteSequence.Line> lines = ctcRepository.findRouteSequenceLineThatLessThan(station.getCode(), endTime);
|
|
||||||
out:
|
|
||||||
for (RouteSequence.Line line : lines) {
|
|
||||||
Route lineRoute = line.getRoute();
|
|
||||||
if (lineRoute == null)
|
|
||||||
continue;
|
|
||||||
for (Section section : lineRoute.getSectionList()) {
|
|
||||||
if (sections.contains(section)) {
|
|
||||||
conflictInfo.add(String.format("所选进路[name:%s]与车次[%s]的[name:%s]进路冲突",
|
|
||||||
route.getName(), line.getTripNumber(), lineRoute.getName()));
|
|
||||||
continue out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<SwitchElement> sl = lineRoute.getSwitchList();
|
|
||||||
if (!CollectionUtils.isEmpty(sl)) {
|
|
||||||
for (SwitchElement element : sl) {
|
|
||||||
SwitchElement e = switchMap.get(element.getASwitch());
|
|
||||||
if (e != null && !element.equals(e)) {
|
|
||||||
conflictInfo.add(String.format("所选进路[name:%s]与车次[%s]的[name:%s]进路冲突",
|
|
||||||
route.getName(), line.getTripNumber(), lineRoute.getName()));
|
|
||||||
continue out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!conflictInfo.isEmpty())
|
|
||||||
return conflictInfo;
|
|
||||||
|
|
||||||
Route.CheckFailMessage checkFailMessage = ciApiService.settingRoute(simulation, routeCode);
|
|
||||||
if (checkFailMessage != null)
|
|
||||||
throw BusinessExceptionAssertEnum.OPERATION_FAIL.exception(checkFailMessage.debugStr());
|
|
||||||
route.setTripNumber(tripNumber);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
if (!conflictInfo.isEmpty()) {
|
||||||
|
return conflictInfo;
|
||||||
|
}
|
||||||
|
|
||||||
private CtcStationRunPlanLog getCtcStationRunPlan(Simulation simulation, String stationCode, String tripNumber) {
|
Route.CheckFailMessage checkFailMessage = ciApiService.settingRoute(simulation, routeCode);
|
||||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
if (checkFailMessage != null) {
|
||||||
return ctcRepository.getRunPlan(stationCode, tripNumber);
|
throw BusinessExceptionAssertEnum.OPERATION_FAIL.exception(checkFailMessage.debugStr());
|
||||||
}
|
}
|
||||||
|
route.setTripNumber(tripNumber);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private CtcStationRunPlanLog getCtcStationRunPlanByRunPlanCode(Simulation simulation, String stationCode, String runPlanCode) {
|
private CtcStationRunPlanLog getCtcStationRunPlan(Simulation simulation, String stationCode,
|
||||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
String tripNumber) {
|
||||||
return ctcRepository.getRunPlanByRunPlanCode(stationCode, runPlanCode);
|
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||||
}
|
return ctcRepository.getRunPlan(stationCode, tripNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CtcStationRunPlanLog getCtcStationRunPlanByRunPlanCode(Simulation simulation,
|
||||||
|
String stationCode, String runPlanCode) {
|
||||||
|
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||||
|
return ctcRepository.getRunPlanByRunPlanCode(stationCode, runPlanCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user