【增加行车区间实体类】

【行车计划增加“班别(车组)”字段,同车次问题】
【增加车务管理端版本等信息,修改方法信息,需要前端协助修改】
【增加调度台操作区间段行车计划方法、下发阶段计划后端功能】
This commit is contained in:
weizhihong 2022-06-23 11:40:31 +08:00
parent 49b6899df3
commit f0cd5023dd
20 changed files with 1102 additions and 480 deletions

View File

@ -0,0 +1,87 @@
package club.joylink.rtss.simulation.cbtc.ATS.operation.handler;
import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation;
import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandler;
import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandlerMapping;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam;
import club.joylink.rtss.simulation.cbtc.ATS.service.runplan.CtcManageService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* 车务管理终端操作
*/
@OperateHandler
@Slf4j
public class CtcManageOperateHandler {
@Autowired
private CtcManageService ctcManageService;
/**
* 保存行车日志到编辑区
*
* @param simulation 仿真实体
* @param zoneCode 区间编码
* @param stationCode 车站编码
* @param runPlanParamList 运行计划
*/
@OperateHandlerMapping(type = Operation.Type.CTC_ADD_RUN_PLAN_LIST_TO_EDIT_AREA)
public void saveRunPlanListToEditArea(Simulation simulation, String zoneCode, String stationCode, List<CtcRunPlanParam> runPlanParamList) {
ctcManageService.saveRunPlanListToEditArea(simulation, zoneCode, stationCode, runPlanParamList);
}
/**
* 将车站编辑区的行车日志发布至生效区
*
* @param simulation 仿真实体
* @param zoneCode 区间编码
* @param stationCode 车站编码
*/
@OperateHandlerMapping(type = Operation.Type.CTC_RELEASE_RUN_PLAN_TO_SIMULATION)
public void releaseRunPlanToSimulation(Simulation simulation, String zoneCode, String stationCode) {
ctcManageService.releaseRunPlanToEffectAreaMap(simulation, zoneCode, stationCode);
}
/**
* 导入覆盖车站编辑区行车日志
*
* @param simulation 仿真实体
* @param zoneCode 区间编码
* @param stationCode 车站编码
* @param runPlanParamList 运行计划
*/
@OperateHandlerMapping(type = Operation.Type.CTC_COVER_RUN_PLAN_LIST_TO_EDIT_AREA)
public void coverRunPlanToEditArea(Simulation simulation, String zoneCode, String stationCode, List<CtcRunPlanParam> runPlanParamList) {
ctcManageService.coverRunPlanToEditArea(simulation, zoneCode, stationCode, runPlanParamList);
}
/**
* 将车站编辑区中删除车次内容
*
* @param simulation 仿真实体
* @param zoneCode 区间编码
* @param stationCode 车站编码
* @param runPlanCode 车次
*/
@OperateHandlerMapping(type = Operation.Type.CTC_REMOVE_RUN_PLAN_FROM_EDIT_AREA)
public void removeRunPlanFromEditArea(Simulation simulation, String zoneCode, String stationCode, String runPlanCode) {
ctcManageService.removeRunPlanFromEditArea(simulation, zoneCode, stationCode, runPlanCode);
}
/**
* 清空车站编辑区内容
*
* @param simulation 仿真实体
* @param zoneCode 区间编码
* @param stationCode 车站编码
*/
@OperateHandlerMapping(type = Operation.Type.CTC_CLEAR_RUN_PLAN_FROM_EDIT_AREA)
public void clearRunPlanFromEditArea(Simulation simulation, String zoneCode, String stationCode) {
ctcManageService.clearRunPlanFromEditArea(simulation, zoneCode, stationCode);
}
}

View File

@ -92,63 +92,6 @@ public class CtcStationRunPlanOperateHandler {
ctcStationRunPlanLogService.removeRunPlan(simulation, stationCode, runPlanCode);
}
/**
* 添加行车日志到编辑区
*
* @param simulation 仿真实体
* @param runPlanParamList 运行计划
*/
@OperateHandlerMapping(type = Operation.Type.CTC_ADD_RUN_PLAN_LIST_TO_EDIT_AREA)
public void addRunPlanToEditArea(Simulation simulation, String stationCode, List<CtcRunPlanParam> runPlanParamList) {
ctcStationRunPlanLogService.addRunPlanListToEditArea(simulation, stationCode, runPlanParamList);
}
/**
* 将车站编辑区的行车日志发布至生效区
*
* @param simulation 仿真实体
* @param stationCode 车站编码
*/
@OperateHandlerMapping(type = Operation.Type.CTC_RELEASE_RUN_PLAN_TO_SIMULATION)
public void releaseRunPlanToSimulation(Simulation simulation, String stationCode) {
ctcStationRunPlanLogService.releaseRunPlanToSimulation(simulation, stationCode);
}
/**
* 导入覆盖车站编辑区行车日志
*
* @param simulation 仿真实体
* @param stationCode 车站编码
* @param runPlanParamList 运行计划列表
*/
@OperateHandlerMapping(type = Operation.Type.CTC_COVER_RUN_PLAN_LIST_TO_EDIT_AREA)
public void coverRunPlanToEditArea(Simulation simulation, String stationCode, List<CtcRunPlanParam> runPlanParamList) {
ctcStationRunPlanLogService.coverRunPlanToEditArea(simulation, stationCode, runPlanParamList);
}
/**
* 将车站编辑区中删除车次内容
*
* @param simulation 仿真实体
* @param stationCode 车站编码
* @param runPlanCode 车次
*/
@OperateHandlerMapping(type = Operation.Type.CTC_REMOVE_RUN_PLAN_FROM_EDIT_AREA)
public void removeRunPlanFromEditArea(Simulation simulation, String stationCode, String runPlanCode) {
ctcStationRunPlanLogService.removeRunPlanFromEditArea(simulation, stationCode, runPlanCode);
}
/**
* 清空车站编辑区内容
*
* @param simulation 仿真实体
* @param stationCode 车站编码
*/
@OperateHandlerMapping(type = Operation.Type.CTC_CLEAR_RUN_PLAN_FROM_EDIT_AREA)
public void clearRunPlanFromEditArea(Simulation simulation, String stationCode) {
ctcStationRunPlanLogService.clearRunPlanFromEditArea(simulation, stationCode);
}
/**
* CTC行车日志发送发车预告
*/
@ -164,16 +107,4 @@ public class CtcStationRunPlanOperateHandler {
public void agreeDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) {
ctcService.agreeDepartureNotice(simulation, stationCode, runPlanCode);
}
/**
* 将CTC生效区发布至车站
*
* @param simulation 仿真实体
* @param stationCode 车站编码
*/
@OperateHandlerMapping(type = Operation.Type.CTC_RELEASE_EFFECT_AREA_TO_STATION)
public void effectAreaToStation(Simulation simulation, String stationCode) {
ctcStationRunPlanLogService.effectAreaToStation(simulation, stationCode);
}
}

View File

@ -0,0 +1,70 @@
package club.joylink.rtss.simulation.cbtc.ATS.operation.handler;
import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandler;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam;
import club.joylink.rtss.simulation.cbtc.ATS.service.runplan.CtcZoneService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
/**
* 区段行驶计划集中调度
*/
@OperateHandler
@Slf4j
public class CtcZoneOperateHandler {
@Autowired
private CtcZoneService ctcZoneService;
/**
* 行车线保存行车计划
*
* @param simulation 仿真
* @param zoneCode 区间编码
* @param planParam 行车计划
*/
public void saveRunPlan(Simulation simulation, String zoneCode, CtcRunPlanParam planParam) {
ctcZoneService.saveRunPlan(simulation, zoneCode, planParam);
}
/**
* 删除行车线中的行车计划状态删除
*
* @param simulation 仿真
* @param zoneCode 区间编码
* @param runPlanCode 行车计划编码
*/
public void deleteRunPlan(Simulation simulation, String zoneCode, String runPlanCode) {
ctcZoneService.delRunPlan(simulation, zoneCode, runPlanCode);
}
/**
* 行车线发送行车计划
*
* @param simulation 仿真
* @param zoneCode 区间编码
*/
public void releaseRunPlan(Simulation simulation, String zoneCode) {
ctcZoneService.releaseRunPlan(simulation, zoneCode);
}
/**
* 发布车站的行车计划
*
* @param simulation 仿真
* @param stationCode 车站编码
*/
public void releaseStationRunPlan(Simulation simulation, String stationCode) {
ctcZoneService.releaseStationRunPlan(simulation, stationCode);
}
/**
* 发布所有的行车计划
*
* @param simulation 仿真
*/
public void releaseAllRunPlan(Simulation simulation) {
ctcZoneService.releaseAllRunPlan(simulation);
}
}

View File

@ -26,6 +26,11 @@ public class CtcRunPlanParam implements Cloneable {
*/
private String stationCode;
/**
* 班别
*/
private String groupNumber;
/**
* 运行计划车次信息
*/
@ -152,13 +157,11 @@ public class CtcRunPlanParam implements Cloneable {
/**
* 生成主键
*
* @return 主键
*/
public String generateId() {
return this.getTripNumber()
+ (StringUtils.isEmpty(this.arriveDirectionCode) ? "_" : this.arriveDirectionCode)
+ (StringUtils.isEmpty(this.departDirectionCode) ? "_" : this.departDirectionCode);
public void generateRunPlanCodeAndTripNumber() {
this.tripNumber = StringUtils.isEmpty(this.tripNumber) ?
(StringUtils.isEmpty(this.arriveTripNumber) ? this.departTripNumber : this.arriveTripNumber) : this.tripNumber;
this.runPlanCode = StringUtils.isEmpty(this.runPlanCode) ? (this.groupNumber + this.tripNumber) : this.runPlanCode;
}
public CtcRunPlanParam compareAndChange(CtcRunPlanParam modify) {
@ -175,6 +178,11 @@ public class CtcRunPlanParam implements Cloneable {
runPlanParam.setTripNumber(modify.getTripNumber());
change = true;
}
if (!Objects.equals(this.groupNumber, modify.getGroupNumber())) {
this.groupNumber = modify.getGroupNumber();
runPlanParam.setGroupNumber(this.getGroupNumber());
change = true;
}
if (!Objects.equals(this.trackSectionCode, modify.getTrackSectionCode())) {
this.trackSectionCode = modify.getTrackSectionCode();
runPlanParam.setTrackSectionCode(modify.getTrackSectionCode());

View File

@ -0,0 +1,127 @@
package club.joylink.rtss.simulation.cbtc.ATS.service.runplan;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcManageRepository;
import club.joylink.rtss.simulation.cbtc.Simulation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Component
@Slf4j
public class CtcManageService {
/**
* 往行车线保存行车计划
*
* @param simulation 仿真
* @param railwayCode 铁路局(调度台区段)
* @param stationCode 车站
* @param runPlanParamList 行车计划
*/
public void saveRunPlanListToEditArea(Simulation simulation, String railwayCode, String stationCode, List<CtcRunPlanParam> runPlanParamList) {
CtcManageRepository manageRepository = simulation.getCtcRepository().getManageRepositoryMap().get(railwayCode);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(manageRepository);
for (CtcRunPlanParam p : runPlanParamList) {
p.generateRunPlanCodeAndTripNumber();
if (StringUtils.isEmpty(p.getDepartSectionCode())) {
p.setDepartSectionCode(p.getTrackSectionCode());
}
if (StringUtils.isEmpty(p.getArriveSectionCode())) {
p.setArriveSectionCode(p.getTrackSectionCode());
}
manageRepository.saveRunPlanToEditArea(stationCode, p);
}
}
/**
* 将车站编辑区的行车日志发布至生效区
*
* @param simulation 仿真实体
* @param railwayCode 铁路局(调度台区段)
* @param stationCode 车站编码
*/
public void releaseRunPlanToEffectAreaMap(Simulation simulation, String railwayCode, String stationCode) {
CtcManageRepository manageRepository = simulation.getCtcRepository().getManageRepositoryMap().get(railwayCode);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(manageRepository);
// 获取编辑区的固定路径数据
CtcManageRepository.StationRunPlanRepository editRepository = manageRepository.getStationRunPlanRepository(stationCode, true);
// 编辑区版本 + 1
int version = editRepository.getVersion().incrementAndGet();
// 生成新的计划数据
Map<String, CtcRunPlanParam> runPlanParamMap = editRepository.getRunPlanParamMap().values().stream()
.map(CtcRunPlanParam::clone).collect(Collectors.toMap(CtcRunPlanParam::getRunPlanCode, p -> p));
// 获取生效区实体
CtcManageRepository.StationRunPlanRepository effectRepository = manageRepository.getStationRunPlanRepository(stationCode, false);
effectRepository.getVersion().set(version); // 版本覆盖
effectRepository.getRunPlanParamMap().clear(); // 计划清空
effectRepository.getRunPlanParamMap().putAll(runPlanParamMap); // 导入计划
}
/**
* 覆盖编辑区行车计划
*
* @param simulation 仿真实体
* @param railwayCode 铁路局(调度台区段)
* @param stationCode 车站编码
* @param runPlanParamList 行车计划
*/
public void coverRunPlanToEditArea(Simulation simulation, String railwayCode, String stationCode, List<CtcRunPlanParam> runPlanParamList) {
CtcManageRepository manageRepository = simulation.getCtcRepository().getManageRepositoryMap().get(railwayCode);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(manageRepository);
// 获取固定路径数据
CtcManageRepository.StationRunPlanRepository runPlanRepository = manageRepository.getStationRunPlanRepository(stationCode, true);
Map<String, CtcRunPlanParam> runPlanParamMap = runPlanParamList.stream().map(p -> {
p.generateRunPlanCodeAndTripNumber();
if (StringUtils.isEmpty(p.getDepartSectionCode())) {
p.setDepartSectionCode(p.getTrackSectionCode());
}
if (StringUtils.isEmpty(p.getArriveSectionCode())) {
p.setArriveSectionCode(p.getTrackSectionCode());
}
return p;
}).collect(Collectors.toMap(CtcRunPlanParam::getRunPlanCode, p -> p));
// 清空
runPlanRepository.getRunPlanParamMap().clear();
// 覆盖
runPlanRepository.getRunPlanParamMap().putAll(runPlanParamMap);
}
/**
* 将车站编辑区中删除车次内容
*
* @param simulation 仿真实体
* @param stationCode 车站编码
* @param railwayCode 铁路局(调度台区段)
* @param runPlanCode 车次
*/
public void removeRunPlanFromEditArea(Simulation simulation, String railwayCode, String stationCode, String runPlanCode) {
CtcManageRepository manageRepository = simulation.getCtcRepository().getManageRepositoryMap().get(railwayCode);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(manageRepository);
// 获取编辑区的固定路径数据
CtcManageRepository.StationRunPlanRepository runPlanRepository = manageRepository.getStationRunPlanRepository(stationCode, true);
runPlanRepository.getRunPlanParamMap().remove(runPlanCode);
}
/**
* 全部清空
*
* @param simulation 仿真修改
* @param railwayCode 铁路局(调度台区段)
* @param stationCode 车站编码
*/
public void clearRunPlanFromEditArea(Simulation simulation, String railwayCode, String stationCode) {
CtcManageRepository manageRepository = simulation.getCtcRepository().getManageRepositoryMap().get(railwayCode);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(manageRepository);
// 获取固定路径数据
CtcManageRepository.StationRunPlanRepository runPlanRepository = manageRepository.getStationRunPlanRepository(stationCode, true);
// 清空
runPlanRepository.getRunPlanParamMap().clear();
}
}

View File

@ -1,7 +1,6 @@
package club.joylink.rtss.simulation.cbtc.ATS.service.runplan;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam;
import club.joylink.rtss.simulation.cbtc.CTC.CTCLogicLoop;
import club.joylink.rtss.simulation.cbtc.CTC.CTCService;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog;
import club.joylink.rtss.simulation.cbtc.CTC.data.RouteSequence;
@ -10,33 +9,20 @@ import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
import club.joylink.rtss.websocket.StompMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
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.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Component
@Slf4j
public class CtcStationRunPlanLogService {
@Autowired
private StompMessageService stompMessageService;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private CTCLogicLoop ctcLogicLoop;
@Autowired
private CTCService ctcService;
@ -97,116 +83,6 @@ public class CtcStationRunPlanLogService {
});
}
/**
* 批量往编辑区添加运行计划
*
* @param simulation 仿真实体
* @param stationCode 车站编码
* @param runPlanParamList 运行计划列表
*/
public void addRunPlanListToEditArea(Simulation simulation, String stationCode, List<CtcRunPlanParam> runPlanParamList) {
Map<String, CtcRunPlanParam> stationRunPlanMap = simulation.getCtcRepository().getSimulationRunPlanEditAreaMap()
.getOrDefault(stationCode, new ConcurrentHashMap<>(64));
boolean isEmpty = CollectionUtils.isEmpty(stationRunPlanMap);
runPlanParamList.forEach(p -> {
String tripNumber = StringUtils.isEmpty(p.getArriveTripNumber()) ? p.getDepartTripNumber() : p.getArriveTripNumber();
p.setTripNumber(tripNumber);
p.setRunPlanCode(tripNumber);
if (StringUtils.isEmpty(p.getDepartSectionCode())) {
p.setDepartSectionCode(p.getTrackSectionCode());
}
if (StringUtils.isEmpty(p.getArriveSectionCode())) {
p.setArriveSectionCode(p.getTrackSectionCode());
}
if (stationRunPlanMap.containsKey(tripNumber)) {
modifyRunPlanParam(stationRunPlanMap.get(tripNumber), p);
} else {
stationRunPlanMap.put(tripNumber, p);
}
});
if (isEmpty) {
simulation.getCtcRepository().getSimulationRunPlanEditAreaMap().put(stationCode, stationRunPlanMap);
}
}
/**
* 将车站编辑区中删除车次内容
*
* @param simulation 仿真实体
* @param stationCode 车站编码
* @param runPlanCode 车次
*/
public void removeRunPlanFromEditArea(Simulation simulation, String stationCode, String runPlanCode) {
Map<String, CtcRunPlanParam> stationRunLogTripNumberMap = simulation.getCtcRepository().getSimulationRunPlanEditAreaMap().get(stationCode);
if (!CollectionUtils.isEmpty(stationRunLogTripNumberMap)) {
stationRunLogTripNumberMap.remove(runPlanCode);
}
}
/**
* 全部清空
*
* @param simulation 仿真修改
* @param stationCode 车站编码
*/
public void clearRunPlanFromEditArea(Simulation simulation, String stationCode) {
simulation.getCtcRepository().getSimulationRunPlanEditAreaMap().remove(stationCode);
}
/**
* 覆盖编辑区中的运行计划
*
* @param simulation 仿真实体
* @param stationCode 车站编码
* @param runPlanParamList 运行计划列表
*/
public void coverRunPlanToEditArea(Simulation simulation, String stationCode, List<CtcRunPlanParam> runPlanParamList) {
// 运行计划
runPlanParamList.forEach(p -> {
String tripNumber = StringUtils.isEmpty(p.getArriveTripNumber())
? p.getDepartTripNumber() : p.getArriveTripNumber();
p.setTripNumber(tripNumber);
p.setRunPlanCode(tripNumber);
});
Map<String, CtcRunPlanParam> planParamMap
= runPlanParamList.stream().collect(Collectors.toMap(CtcRunPlanParam::getRunPlanCode, (p) -> p));
simulation.getCtcRepository().getSimulationRunPlanEditAreaMap().put(stationCode, planParamMap);
}
/**
* 将车站编辑区的行车日志发布至生效区
*
* @param simulation 仿真实体
* @param stationCode 车站编码
*/
public void releaseRunPlanToSimulation(Simulation simulation, String stationCode) {
// 编辑区信息
Map<String, CtcRunPlanParam> planParamMap = simulation.getCtcRepository().getSimulationRunPlanEditAreaMap()
.getOrDefault(stationCode, new ConcurrentHashMap<>());
// 编辑区版本 + 1
AtomicInteger editVersion = simulation.getCtcRepository().getStationEditAreaVersion()
.getOrDefault(stationCode, new AtomicInteger(0));
editVersion.decrementAndGet();
simulation.getCtcRepository().getStationEditAreaVersion().put(stationCode, editVersion);
// 发布至生效区中
simulation.getCtcRepository().getSimulationRunPlanEffectAreaMap().put(stationCode, planParamMap);
AtomicInteger effectVersion = new AtomicInteger(editVersion.get()); // 覆盖生效区版本
simulation.getCtcRepository().getStationEffectAreaVersion().put(stationCode, effectVersion);
}
/**
* 生效至车站操作中
*
* @param simulation 仿真实体
* @param stationCode 车站编码
*/
public void effectAreaToStation(Simulation simulation, String stationCode) {
Map<String, CtcRunPlanParam> runPlanParamMap = simulation.getCtcRepository().getSimulationRunPlanEffectAreaMap()
.get(stationCode);
if (!CollectionUtils.isEmpty(runPlanParamMap)) {
modifyBatchRunPlan(simulation, stationCode, new ArrayList<>(runPlanParamMap.values()), 1);
}
}
/**
* 人工上报行车日志的到点时间
@ -404,11 +280,8 @@ public class CtcStationRunPlanLogService {
* @return 行车日志
*/
private CtcStationRunPlanLog createRunPlanLog(Simulation simulation, String stationCode, CtcRunPlanParam paramInfo) {
paramInfo.generateRunPlanCodeAndTripNumber();
String tripNumber = paramInfo.getTripNumber();
if (StringUtils.isEmpty(tripNumber)) {
tripNumber = StringUtils.isEmpty(paramInfo.getArriveTripNumber()) ? paramInfo.getDepartTripNumber() : paramInfo.getArriveTripNumber();
}
paramInfo.setTripNumber(tripNumber);
CtcStationRunPlanLog ctcStationRunPlanLog = new CtcStationRunPlanLog(paramInfo);
ctcStationRunPlanLog.setCode(tripNumber);
Station station = simulation.getRepository().getByCode(stationCode, Station.class);
@ -417,79 +290,4 @@ public class CtcStationRunPlanLogService {
ctcStationRunPlanLog.setDepartRunPlan(CtcStationRunPlanLog.createRunPlanItem(simulation, paramInfo, false));
return ctcStationRunPlanLog;
}
/**
* 编辑运行计划参数
*
* @param original 原始参数
* @param modify 修改参数
*/
private void modifyRunPlanParam(CtcRunPlanParam original, CtcRunPlanParam modify) {
if (modify.getStationCode() != null
&& !Objects.equals(original.getStationCode(), modify.getStationCode())) {
original.setStationCode(modify.getStationCode());
}
if (modify.getTripNumber() != null
&& !Objects.equals(original.getTripNumber(), modify.getTripNumber())) {
original.setTripNumber(modify.getTripNumber());
}
if (modify.getTrackSectionCode() != null
&& !Objects.equals(original.getTrackSectionCode(), modify.getTrackSectionCode())) {
original.setTrackSectionCode(modify.getTrackSectionCode());
}
if (modify.getArriveSectionCode() != null
&& !Objects.equals(original.getArriveSectionCode(), modify.getArriveSectionCode())) {
original.setArriveSectionCode(modify.getArriveSectionCode());
}
if (modify.getDepartSectionCode() != null
&& !Objects.equals(original.getDepartSectionCode(), modify.getDepartSectionCode())) {
original.setDepartSectionCode(modify.getDepartSectionCode());
}
if (modify.getArriveTime() != null
&& !Objects.equals(original.getArriveTime(), modify.getArriveTime())) {
original.setArriveTime(modify.getArriveTime());
}
if (modify.getDepartTime() != null
&& !Objects.equals(original.getDepartTime(), modify.getDepartTime())) {
original.setDepartTime(modify.getDepartTime());
}
if (modify.getArriveTripNumber() != null
&& !Objects.equals(original.getArriveTripNumber(), modify.getArriveTripNumber())) {
original.setArriveTripNumber(modify.getArriveTripNumber());
}
if (modify.getDepartTripNumber() != null
&& !Objects.equals(original.getDepartTripNumber(), modify.getDepartTripNumber())) {
original.setDepartTripNumber(modify.getDepartTripNumber());
}
if (modify.getArriveStationCode() != null
&& !Objects.equals(original.getArriveStationCode(), modify.getArriveStationCode())) {
original.setArriveStationCode(modify.getArriveStationCode());
}
if (modify.getDepartStationCode() != null
&& !Objects.equals(original.getDepartStationCode(), modify.getDepartStationCode())) {
original.setDepartStationCode(modify.getDepartStationCode());
}
if (modify.getArriveDirectionCode() != null
&& !Objects.equals(original.getArriveDirectionCode(), modify.getArriveDirectionCode())) {
original.setArriveDirectionCode(modify.getArriveDirectionCode());
}
if (modify.getDepartDirectionCode() != null
&& !Objects.equals(original.getDepartDirectionCode(), modify.getDepartDirectionCode())) {
original.setDepartDirectionCode(modify.getDepartDirectionCode());
}
// 存在不一样的选项
Map<CtcStationRunPlanLog.RunPlanTask, Integer> modifyMap = new HashMap<>();
modify.getRunPlanTaskMap().forEach((k, v) -> {
if (!original.getRunPlanTaskMap().containsKey(k) && !Objects.equals(original.getRunPlanTaskMap().get(k), v)) {
modifyMap.put(k, v);
}
});
if (original.getRunPlanTaskMap().size() != modify.getRunPlanTaskMap().size() || !CollectionUtils.isEmpty(modifyMap)) {
original.getRunPlanTaskMap().putAll(modify.getRunPlanTaskMap());
}
if (!Objects.equals(original.getStatus(), modify.getStatus())) {
original.setStatus(modify.getStatus());
}
}
}

View File

@ -0,0 +1,97 @@
package club.joylink.rtss.simulation.cbtc.ATS.service.runplan;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationStagePlan;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcZoneRepository;
import club.joylink.rtss.simulation.cbtc.Simulation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Component
@Slf4j
public class CtcZoneService {
/**
* 往行车线保存行车计划
*
* @param simulation 仿真
* @param zoneCode 区间编码
* @param planParam 行车计划
*/
public void saveRunPlan(Simulation simulation, String zoneCode, CtcRunPlanParam planParam) {
CtcZoneRepository railwayRepository = simulation.getCtcRepository().getZoneRepository().get(zoneCode);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(railwayRepository);
railwayRepository.saveRunPlan(planParam);
}
/**
* 删除行车线中的行车计划状态删除
*
* @param simulation 仿真
* @param zoneCode 区间编码
* @param runPlanCode 行车计划编码
*/
public void delRunPlan(Simulation simulation, String zoneCode, String runPlanCode) {
CtcZoneRepository railwayRepository = simulation.getCtcRepository().getZoneRepository().get(zoneCode);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(railwayRepository);
railwayRepository.delRunPlan(runPlanCode);
}
/**
* 行车线发送行车计划
*
* @param simulation 仿真
* @param zoneCode 区间编码
*/
public void releaseRunPlan(Simulation simulation, String zoneCode) {
CtcZoneRepository railwayRepository = simulation.getCtcRepository().getZoneRepository().get(zoneCode);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(railwayRepository);
Map<String, List<CtcRunPlanParam>> stationRunPlanMap = railwayRepository.getZoneRunPlanMap().values().stream()
.collect(Collectors.groupingBy(CtcRunPlanParam::getStationCode));
simulation.getCtcRepository().getStationStagePlan().forEach((k, v) -> {
if (stationRunPlanMap.containsKey(k)) {
v.updateStageRunPlanList(simulation.getCorrectSystemTime(), stationRunPlanMap.get(k));
}
});
}
/**
* 发布车站的行车计划
*
* @param simulation 仿真
* @param stationCode 车站编码
*/
public void releaseStationRunPlan(Simulation simulation, String stationCode) {
CtcStationStagePlan stagePlan = simulation.getCtcRepository().getStationStagePlan().get(stationCode);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(stagePlan);
CtcZoneRepository railwayRepository = simulation.getCtcRepository().getZoneRepository().values().stream()
.filter(r -> r.getStationMap().containsKey(stationCode)).findFirst().orElse(null);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(railwayRepository);
List<CtcRunPlanParam> ctcRunPlanParamList = railwayRepository.getZoneRunPlanMap().values().stream()
.filter(r -> r.getStationCode().equals(stationCode)).collect(Collectors.toList());
stagePlan.updateStageRunPlanList(simulation.getCorrectSystemTime(), ctcRunPlanParamList);
}
/**
* 全量发布
*
* @param simulation 仿真
*/
public void releaseAllRunPlan(Simulation simulation) {
Map<String, CtcStationStagePlan> stagePlanMap = simulation.getCtcRepository().getStationStagePlan();
simulation.getCtcRepository().getZoneRepository().forEach((zoneCode, railwayRepository) -> {
Map<String, List<CtcRunPlanParam>> stationRunPlanMap = railwayRepository.getZoneRunPlanMap().values().stream()
.collect(Collectors.groupingBy(CtcRunPlanParam::getStationCode));
stationRunPlanMap.forEach((k, v) -> {
if (stagePlanMap.containsKey(k)) {
stagePlanMap.get(k).updateStageRunPlanList(simulation.getCorrectSystemTime(), v);
}
});
});
}
}

View File

@ -46,11 +46,9 @@ public class CTCLogicLoop {
sendRunPlanChangeMessage(simulation);
sendRunPlanRemoveMessage(simulation);
// 发送车务管理端消息(编辑区)
sendCtcManageChangeMessage(simulation);
sendCtcManageRemoveMessage(simulation);
// 车务管理端消息生效区
sendCtcManageEffectChangeMessage(simulation);
sendCtcManageEffectRemoveMessage(simulation);
sendManageChange(simulation);
sendManageRemove(simulation);
}
public void sendAllMessage(Simulation simulation) {
@ -232,8 +230,85 @@ public class CTCLogicLoop {
simulation.addFixedRateJob(MESSAGE_NAME, () -> this.sendMessage(simulation), MESSAGE_RATE);
}
/**
* 发送CTC初始变化
* 发送铁路局行车区段信息列表
*
* @param simulation 仿真
* @param userIds 用户
*/
public void sendAllRailwayInfo(Simulation simulation, Set<String> userIds) {
List<CtcZoneVO> ctcZoneVOList = simulation.getCtcRepository().getZoneRepository().values().stream()
.map(r -> new CtcZoneVO(r.getCtcZone())).collect(Collectors.toList());
sendCtcMessage(simulation.getId(), ctcZoneVOList, WebSocketMessageType.SIMULATION_CTC_ZONE, simulation.getSimulationUserIds());
}
/**
* 初始时发送
*
* @param simulation 仿真
* @param userIds 用户
*/
public void sendAllManageChange(Simulation simulation, Set<String> userIds) {
CtcManageRepositoryVO ctcManageRepositoryVO = simulation.getCtcRepository().getCtcManageRepositoryVO();
synchronized (ctcManageRepositoryVO) {
List<CtcRunPlanParam> allList = new ArrayList<>();
if (ctcManageRepositoryVO.getEditAreaCtcRunPlanParamVOMap().isEmpty()) {
simulation.getCtcRepository().getManageRepositoryMap().forEach((k, v) -> {
v.getEditAreaMap().getStationRunPlanMap().forEach((s, r) -> {
allList.addAll(ctcManageRepositoryVO.compareAndReturnChangeRunPlan(r, true));
});
});
} else {
allList.addAll(ctcManageRepositoryVO.getEditAreaCtcRunPlanParamVOMap().values());
}
if (!CollectionUtils.isEmpty(allList)) {
sendCtcMessage(simulation.getId(), allList, WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EDIT_INIT
, userIds);
}
}
}
/**
* 发送管理端编辑区变更数据
*
* @param simulation 仿真数据
*/
public void sendManageChange(Simulation simulation) {
CtcManageRepositoryVO ctcManageRepositoryVO = simulation.getCtcRepository().getCtcManageRepositoryVO();
List<CtcRunPlanParam> allList = new ArrayList<>();
simulation.getCtcRepository().getManageRepositoryMap().forEach((k, v) -> {
v.getEditAreaMap().getStationRunPlanMap().forEach((s, r) -> {
allList.addAll(ctcManageRepositoryVO.compareAndReturnChangeRunPlan(r, true));
});
});
if (!CollectionUtils.isEmpty(allList)) {
sendCtcMessage(simulation.getId(), allList, WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EDIT_CHANGE
, simulation.getSimulationUserIds());
}
}
/**
* 发送管理端编辑区数据删除数据
*
* @param simulation 仿真数据
*/
public void sendManageRemove(Simulation simulation) {
CtcManageRepositoryVO ctcManageRepositoryVO = simulation.getCtcRepository().getCtcManageRepositoryVO();
List<CtcRunPlanParam> allList = new ArrayList<>();
simulation.getCtcRepository().getManageRepositoryMap().forEach((k, v) -> {
v.getEditAreaMap().getStationRunPlanMap().forEach((s, r) -> {
allList.addAll(ctcManageRepositoryVO.compareAndReturnRemoveRunPlan(r, true));
});
});
if (!CollectionUtils.isEmpty(allList)) {
sendCtcMessage(simulation.getId(), allList
, WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EDIT_REMOVE, simulation.getSimulationUserIds());
}
}
/**
* 发送CTC初始行车日志变化
*
* @param simulation 仿真实体
* @param userIds 用户ID
@ -308,150 +383,6 @@ public class CTCLogicLoop {
}
}
/**
* @param simulation 仿真实体
* @param userIds 用户ID
*/
public void initCtcManageMessage(Simulation simulation, Set<String> userIds) {
synchronized (this) {
Map<String, CtcRunPlanParam> editAreaStatusVOMap = simulation.getCtcRepository().getEditAreaStatusVOMap();
List<CtcRunPlanParam> allList = new ArrayList<>();
if (CollectionUtils.isEmpty(editAreaStatusVOMap)) {
simulation.getCtcRepository().getSimulationRunPlanEditAreaMap().forEach((k, v) -> {
v.values().stream().forEach(p -> {
String mapKey = p.getStationCode() + "_" + p.getRunPlanCode();
editAreaStatusVOMap.put(mapKey, p.clone());
allList.add(p);
});
});
} else {
allList.addAll(editAreaStatusVOMap.values());
}
if (!CollectionUtils.isEmpty(allList)) {
sendCtcMessage(simulation.getId(), allList
, WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EDIT_INIT, userIds);
}
}
}
/**
* 发送管理端信息变更消息
*
* @param simulation 仿真实体
*/
public void sendCtcManageChangeMessage(Simulation simulation) {
Map<String, CtcRunPlanParam> editAreaStatusVOMap = simulation.getCtcRepository().getEditAreaStatusVOMap();
List<CtcRunPlanParam> allList = new ArrayList<>();
simulation.getCtcRepository().getSimulationRunPlanEditAreaMap().forEach((k, v) -> {
v.values().stream().forEach(p -> {
String mapKey = p.getStationCode() + "_" + p.getRunPlanCode();
CtcRunPlanParam param = editAreaStatusVOMap.get(mapKey);
CtcRunPlanParam changeCtcRunPlanVo = null;
if (param == null) {
changeCtcRunPlanVo = p.clone();
editAreaStatusVOMap.put(mapKey, changeCtcRunPlanVo);
allList.add(editAreaStatusVOMap.get(mapKey));
} else {
changeCtcRunPlanVo = param.compareAndChange(p);
if (changeCtcRunPlanVo != null) {
allList.add(changeCtcRunPlanVo);
}
}
});
});
if (!CollectionUtils.isEmpty(allList)) {
sendCtcMessage(simulation.getId(), allList
, WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EDIT_CHANGE, simulation.getSimulationUserIds());
}
}
/**
* 发送管理端信息删除消息
*
* @param simulation 仿真实体
*/
public void sendCtcManageRemoveMessage(Simulation simulation) {
// 状态key车站_车次
Map<String, CtcRunPlanParam> editAreaStatusVOMap = simulation.getCtcRepository().getEditAreaStatusVOMap();
// 编辑区key车站 key车次
Map<String, Map<String, CtcRunPlanParam>> editeAreaMap = simulation.getCtcRepository().getSimulationRunPlanEditAreaMap();
List<CtcRunPlanParam> messageInfo = editAreaStatusVOMap.values().stream().filter(vo -> {
Map<String, CtcRunPlanParam> map = editeAreaMap.get(vo.getStationCode());
if (map == null) {
return true;
}
CtcRunPlanParam p = map.get(vo.getRunPlanCode());
if (p == null) {
return true;
}
return false;
}).map(vo -> vo.buildRemoveParam()).collect(Collectors.toList());
if (messageInfo != null && !messageInfo.isEmpty()) {
// 移除已删除状态
messageInfo.forEach(vo -> editAreaStatusVOMap.remove(vo.getStationCode() + "_" + vo.getRunPlanCode()));
sendCtcMessage(simulation.getId(), messageInfo
, WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EDIT_REMOVE, simulation.getSimulationUserIds());
}
}
/**
* 发送生效区变化消息
*
* @param simulation 仿真实体
*/
public void sendCtcManageEffectChangeMessage(Simulation simulation) {
Map<String, CtcRunPlanParam> editAreaStatusVOMap = simulation.getCtcRepository().getEffectAreaStatusVOMap();
List<CtcRunPlanParam> allList = new ArrayList<>();
simulation.getCtcRepository().getSimulationRunPlanEffectAreaMap().forEach((k, v) -> {
v.values().stream().forEach(p -> {
String mapKey = p.getStationCode() + "_" + p.getRunPlanCode();
CtcRunPlanParam param = editAreaStatusVOMap.get(mapKey);
CtcRunPlanParam changeCtcRunPlanVo = null;
if (param == null) {
changeCtcRunPlanVo = p.clone();
editAreaStatusVOMap.put(mapKey, changeCtcRunPlanVo);
allList.add(editAreaStatusVOMap.get(mapKey));
} else {
changeCtcRunPlanVo = param.compareAndChange(p);
if (changeCtcRunPlanVo != null) {
allList.add(changeCtcRunPlanVo);
}
}
});
});
if (!CollectionUtils.isEmpty(allList)) {
sendCtcMessage(simulation.getId(), allList, WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EFFECT_CHANGE
, simulation.getSimulationUserIds());
}
}
/**
* 发送生效区移除消息
*
* @param simulation 仿真实体
*/
public void sendCtcManageEffectRemoveMessage(Simulation simulation) {
Map<String, CtcRunPlanParam> effectAreaStatusVOMap = simulation.getCtcRepository().getEffectAreaStatusVOMap();
Map<String, Map<String, CtcRunPlanParam>> effectAreaMap = simulation.getCtcRepository().getSimulationRunPlanEffectAreaMap();
List<CtcRunPlanParam> messageInfo = effectAreaStatusVOMap.values().stream().filter(vo -> {
Map<String, CtcRunPlanParam> map = effectAreaMap.get(vo.getStationCode());
if (map == null) {
return true;
}
CtcRunPlanParam p = map.get(vo.getRunPlanCode());
if (p == null) {
return true;
}
return false;
}).map(vo -> vo.buildRemoveParam()).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(messageInfo)) {
// 移除已删除状态
messageInfo.forEach(vo -> effectAreaStatusVOMap.remove(vo.getStationCode() + "_" + vo.getRunPlanCode()));
sendCtcMessage(simulation.getId(), messageInfo
, WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EFFECT_REMOVE, simulation.getSimulationUserIds());
}
}
/**
* 发送调度台消息
*

View File

@ -0,0 +1,195 @@
package club.joylink.rtss.simulation.cbtc.CTC.data;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam;
import club.joylink.rtss.simulation.cbtc.data.map.StationDirection;
import lombok.Getter;
import lombok.Setter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 车务管理端数据(调度台区段)
*/
@Getter
@Setter
public class CtcManageRepository {
/**
* 编码(调度台区段)
*/
private CtcZone ctcZone;
/**
* 编辑区
*/
private ManageDataWorkspace editAreaMap;
/**
* 生效区
*/
private ManageDataWorkspace effectAreaMap;
public CtcManageRepository(CtcZone ctcZone) {
this.ctcZone = ctcZone;
this.editAreaMap = new ManageDataWorkspace();
this.effectAreaMap = new ManageDataWorkspace();
}
/**
* 行车计划保存在编辑区
*
* @param stationCode 车站
* @param runPlanParam 行车计划
*/
public void saveRunPlanToEditArea(String stationCode, CtcRunPlanParam runPlanParam) {
this.editAreaMap.saveRunPlan(stationCode, runPlanParam);
}
/**
* 行车计划保存在生效区
*
* @param stationCode 车站
* @param runPlanParam 行车计划
*/
public void saveRunPlanToEffectArea(String stationCode, CtcRunPlanParam runPlanParam) {
this.effectAreaMap.saveRunPlan(stationCode, runPlanParam);
}
/**
* 获取行车日志实体
*
* @param stationCode 车站编码
* @param isEdit 是否编辑区
* @return 日志实体
*/
public StationRunPlanRepository getStationRunPlanRepository(String stationCode, boolean isEdit) {
Map<String, StationRunPlanRepository> stationRunPlanMap = isEdit ?
this.editAreaMap.getStationRunPlanMap() : this.effectAreaMap.getStationRunPlanMap();
if (!stationRunPlanMap.containsKey(stationCode)) {
stationRunPlanMap.put(stationCode, new StationRunPlanRepository(stationCode));
}
return stationRunPlanMap.get(stationCode);
}
public void rest() {
}
/**
* 管理端工作区
*/
@Setter
@Getter
public class ManageDataWorkspace {
/**
* 股道集合
* 车站key
*/
private final Map<String, StationTrackSectionRepository> stationTrackSectionMap = new HashMap<>();
/**
* 出入口集合
* 车站key
*/
private final Map<String, StationDoorRepository> stationDoorMap = new HashMap<>();
/**
* 固定径路集合
* 车站key
*/
private final Map<String, StationRunPlanRepository> stationRunPlanMap = new HashMap<>();
/**
* 保存运行计划至车站
*
* @param stationCode 车站编码
* @param runPlanParam 保存运行计划
*/
public void saveRunPlan(String stationCode, CtcRunPlanParam runPlanParam) {
if (!stationRunPlanMap.containsKey(stationCode)) {
this.stationRunPlanMap.put(stationCode, new StationRunPlanRepository(stationCode));
}
this.stationRunPlanMap.get(stationCode).saveRunPlan(runPlanParam);
}
public void rest() {
}
}
/**
* 工作区信息公共字段以及公共方法
*/
@Getter
@Setter
public abstract static class AbstractWorkspaceRepository {
protected String stationCode;
protected AtomicInteger version;
}
/**
* 车站股道数据
*/
@Setter
@Getter
public static class StationTrackSectionRepository extends AbstractWorkspaceRepository {
private final Map<String, TrackSection> trackSectionMap = new HashMap<>();
public void rest() {
}
}
/**
* 车站出入口
*/
@Setter
@Getter
public static class StationDoorRepository extends AbstractWorkspaceRepository {
private final Map<String, StationDirection> trackSectionMap = new HashMap<>();
public void rest() {
}
}
/**
* 固定进路信息
*/
@Setter
@Getter
public static class StationRunPlanRepository extends AbstractWorkspaceRepository {
private final Map<String, CtcRunPlanParam> runPlanParamMap = new HashMap<>();
/**
* 保存运行计划
*
* @param runPlanParam 运行计划
*/
public void saveRunPlan(CtcRunPlanParam runPlanParam) {
this.runPlanParamMap.put(runPlanParam.getRunPlanCode(), runPlanParam);
}
/**
* 是否存在
*
* @param code 编码
* @return 存在
*/
public boolean isExit(String code) {
return this.runPlanParamMap.containsKey(code);
}
public StationRunPlanRepository(String stationCode) {
this.stationCode = stationCode;
this.version = new AtomicInteger(0);
}
public void rest() {
}
}
}

View File

@ -0,0 +1,108 @@
package club.joylink.rtss.simulation.cbtc.CTC.data;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 车务管理端数据状态
*/
@Getter
@Setter
public class CtcManageRepositoryVO {
/**
* 编辑区股道版本状态
*/
private final Map<String, Integer> editAreaTrackSectionVersionMap = new HashMap<>();
/**
* 编辑区股道状态
*/
private final Map<String, TrackSectionVO> editAreaTrackSectionVOMap = new HashMap<>();
/**
* 编辑区运行计划版本状态
*/
private final Map<String, Integer> editAreaCtcRunPlanVersionMap = new HashMap<>();
/**
* 编辑区行车计划状态
*/
private final Map<String, CtcRunPlanParam> editAreaCtcRunPlanParamVOMap = new HashMap<>();
/**
* 生效区股道版本状态
*/
private final Map<String, Integer> effectAreaTrackSectionVersionMap = new HashMap<>();
/**
* 生效区股道状态
*/
private final Map<String, TrackSectionVO> effectAreaTrackSectionVOMap = new HashMap<>();
/**
* 生效区运行计划版本状态
*/
private final Map<String, Integer> effectAreaCtcRunPlanVersionMap = new HashMap<>();
/**
* 生效区行车计划状态
*/
private final Map<String, CtcRunPlanParam> effectAreaCtcRunPlanParamVOMap = new HashMap<>();
/**
* 比较并返回变化过的运行计划
*
* @param runPlanRepository 运行计划
* @param isEdit 编辑区
* @return 变化过的
*/
public List<CtcRunPlanParam> compareAndReturnChangeRunPlan(CtcManageRepository.StationRunPlanRepository runPlanRepository, boolean isEdit) {
List<CtcRunPlanParam> allList = new ArrayList<>(runPlanRepository.getRunPlanParamMap().size());
Map<String, CtcRunPlanParam> runPlanMap = isEdit ? this.editAreaCtcRunPlanParamVOMap : this.effectAreaCtcRunPlanParamVOMap;
runPlanRepository.getRunPlanParamMap().forEach((k, p) -> {
String mapKey = p.getStationCode() + "_" + p.getRunPlanCode();
CtcRunPlanParam param = runPlanMap.get(mapKey);
CtcRunPlanParam changeCtcRunPlanVo = null;
if (param == null) {
changeCtcRunPlanVo = p.clone();
runPlanMap.put(mapKey, changeCtcRunPlanVo);
allList.add(changeCtcRunPlanVo);
} else {
changeCtcRunPlanVo = param.compareAndChange(p);
if (changeCtcRunPlanVo != null) {
allList.add(changeCtcRunPlanVo);
}
}
});
return allList;
}
/**
* 比较并返回删除的运行计划
*
* @param runPlanRepository 运行计划
* @param isEdit 编辑区
* @return 删除的
*/
public List<CtcRunPlanParam> compareAndReturnRemoveRunPlan(CtcManageRepository.StationRunPlanRepository runPlanRepository, boolean isEdit) {
Map<String, CtcRunPlanParam> runPlanMap = isEdit ? this.editAreaCtcRunPlanParamVOMap : this.effectAreaCtcRunPlanParamVOMap;
List<CtcRunPlanParam> messageInfo = runPlanMap.values().stream().filter(vo -> {
return runPlanRepository.getStationCode().equals(vo.getStationCode()) && !runPlanRepository.isExit(vo.getRunPlanCode());
}).map(vo -> vo.buildRemoveParam()).collect(Collectors.toList());
// 移除数据
if (!CollectionUtils.isEmpty(messageInfo)) {
messageInfo.forEach(vo -> runPlanMap.remove(vo.getStationCode() + "_" + vo.getRunPlanCode()));
}
return messageInfo;
}
}

View File

@ -1,7 +1,6 @@
package club.joylink.rtss.simulation.cbtc.CTC.data;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam;
import lombok.Getter;
import java.util.HashMap;
@ -9,11 +8,42 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* 铁路局CTC 车务管理终端
* |
* |下发计划至更新区
* |
* 更新区
* |
* | 拉取计划至车站终端
* |
* 车站终端更新计划
*/
@Getter
public class CtcRepository {
/**
* 铁路局(调度台区段)数据
*/
private final Map<String, CtcZoneRepository> zoneRepository = new HashMap<>();
/**
* 车务管理终端数据
*/
private final Map<String, CtcManageRepository> manageRepositoryMap = new HashMap<>();
/**
* 管理终端数据状态
*/
private final CtcManageRepositoryVO ctcManageRepositoryVO = new CtcManageRepositoryVO();
/**
* 各车站的阶段计划
*/
private final Map<String, CtcStationStagePlan> stationStagePlan = new HashMap<>();
/************************************************* 以下为车站终端数据 ************************************************/
/**
* 车站-进路序列每个车站都应该有
* k - stationCode
@ -41,6 +71,12 @@ public class CtcRepository {
*/
private List<CtcStationRunPlanLog> allRunPlanList = new LinkedList<>();
/**
* 车站的阶段计划
* 车站key
*/
private Map<String, CtcStationStagePlan> stationStagePlanMap = new HashMap<>();
/**
* 原始数据中行车计划原始行驶计划数据
* 编码为key
@ -53,42 +89,12 @@ public class CtcRepository {
*/
private final Map<String, Map<String, CtcStationRunPlanLog>> simulationRunPlanMap = new ConcurrentHashMap<>();
/**
* 编辑区版本
*/
private final Map<String, AtomicInteger> stationEditAreaVersion = new HashMap<>();
/**
* 管理区编辑区
* 车次为KEY
*/
private final Map<String, Map<String, CtcRunPlanParam>> simulationRunPlanEditAreaMap = new ConcurrentHashMap<>();
/**
* 生效区版本
*/
private final Map<String, AtomicInteger> stationEffectAreaVersion = new HashMap<>();
/**
* 管理区生效区
* 车次为KEY
*/
private final Map<String, Map<String, CtcRunPlanParam>> simulationRunPlanEffectAreaMap = new ConcurrentHashMap<>();
/**
* 运行日志消息状态
*/
private final Map<String, CtcStationRunPlanLogVO> runPlanStatusVOMap = new HashMap<>();
/**
* 车务管理端运行计划状态
*/
private final Map<String, CtcRunPlanParam> editAreaStatusVOMap = new HashMap<>();
/**
* 车务管理端生效区运行计划状态
*/
private final Map<String, CtcRunPlanParam> effectAreaStatusVOMap = new HashMap<>();
/************************************************* 以上为车站终端数据 ************************************************/
public void reset() {
@ -96,10 +102,6 @@ public class CtcRepository {
routeSequenceVOMap.clear();
trackViewMap.clear();
trackViewVOMap.clear();
// 编辑区清空
this.simulationRunPlanEditAreaMap.clear();
// 生效区清空
this.simulationRunPlanEffectAreaMap.clear();
// 仿真运行数据直接清空
this.simulationRunPlanMap.clear();
this.allRunPlanList.clear();
@ -110,8 +112,6 @@ public class CtcRepository {
}));
// 运行计划状态清除
this.runPlanStatusVOMap.clear();
this.editAreaStatusVOMap.clear();
this.effectAreaStatusVOMap.clear();
}
/**

View File

@ -38,6 +38,11 @@ public class CtcStationRunPlanLog {
*/
private Station station;
/**
* 列车班别存在同车次情况
*/
private String groupNumber;
/**
* 车次号
*/

View File

@ -0,0 +1,58 @@
package club.joylink.rtss.simulation.cbtc.CTC.data;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 阶段计划
*/
@Setter
@Getter
public class CtcStationStagePlan {
/**
* 车站编码
*/
private Station station;
/**
* 最近接受时间
*/
private LocalDateTime updateTime;
/**
* 运行计划列表
*/
private List<CtcRunPlanParam> ctcRunPlanParamList;
public CtcStationStagePlan(Station station) {
this.station = station;
this.ctcRunPlanParamList = new ArrayList<>();
}
/**
* 更新运行计划列表
*
* @param updateTime 更新时间
* @param runPlanParamList 运行计划列表
*/
public void updateStageRunPlanList(LocalDateTime updateTime, List<CtcRunPlanParam> runPlanParamList) {
this.updateTime = updateTime;
this.ctcRunPlanParamList = runPlanParamList.stream().map(CtcRunPlanParam::clone).collect(Collectors.toList());
}
/**
* 车站编码
*
* @return 车站编码
*/
public String getStationCode() {
return this.station.getCode();
}
}

View File

@ -0,0 +1,29 @@
package club.joylink.rtss.simulation.cbtc.CTC.data;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* 行驶区间行驶线路
*/
@Setter
@Getter
public class CtcZone {
/**
* 编码
*/
private String code;
/**
* 名称
*/
private String name;
/**
* 车站列表
*/
private List<Station> stationList;
}

View File

@ -0,0 +1,58 @@
package club.joylink.rtss.simulation.cbtc.CTC.data;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import lombok.Getter;
import lombok.Setter;
import java.util.HashMap;
import java.util.Map;
/**
* CTC行车区间关联数据信息
*/
@Setter
@Getter
public class CtcZoneRepository {
/**
* 行车区间编码
*/
private CtcZone ctcZone;
/**
* 包含车站
*/
private Map<String, Station> stationMap = new HashMap<>();
/**
* 运行计划
*/
private final Map<String, CtcRunPlanParam> zoneRunPlanMap = new HashMap<>();
public CtcZoneRepository(CtcZone ctcZone) {
this.ctcZone = ctcZone;
}
/**
* 保存运行计划信息
*
* @param runPlanParam 运行计划
*/
public void saveRunPlan(CtcRunPlanParam runPlanParam) {
// 初始化运行计划编码车次信息
runPlanParam.generateRunPlanCodeAndTripNumber();
this.zoneRunPlanMap.put(runPlanParam.getRunPlanCode(), runPlanParam);
}
/**
* 删除运行计划状态删除
*
* @param runPlanCode
*/
public void delRunPlan(String runPlanCode) {
CtcRunPlanParam runPlanParam = this.zoneRunPlanMap.get(runPlanCode);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(runPlanParam);
runPlanParam.setStatus(-1);
}
}

View File

@ -0,0 +1,64 @@
package club.joylink.rtss.simulation.cbtc.CTC.data;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 行车区间状态
*/
@Setter
@Getter
public class CtcZoneVO {
/**
* 编码
*/
private String code;
/**
* 名称
*/
private String name;
/**
* 车站列表
*/
private List<String> stationCodeList;
public CtcZoneVO(String code) {
this.code = code;
}
public CtcZoneVO(CtcZone ctcZone) {
this.code = ctcZone.getCode();
this.name = ctcZone.getName();
this.stationCodeList = ctcZone.getStationList().stream().map(Station::getCode).collect(Collectors.toList());
}
/**
* 比较并返回变化字段
*
* @param ctcZone 铁路局详细信息
* @return 变化对象
*/
public CtcZoneVO compareAndReturnChange(CtcZone ctcZone) {
CtcZoneVO ctcZoneVO = new CtcZoneVO(ctcZone.getCode());
boolean change = false;
if (!Objects.equals(this.name, ctcZone.getName())) {
this.name = ctcZone.getName();
ctcZoneVO.setName(ctcZone.getName());
change = true;
}
List<String> stationList = ctcZone.getStationList().stream().map(Station::getCode).collect(Collectors.toList());
if (!Objects.equals(this.stationCodeList, stationList)) {
this.stationCodeList = stationList;
ctcZoneVO.setStationCodeList(stationList);
change = true;
}
return change ? ctcZoneVO : null;
}
}

View File

@ -2,9 +2,7 @@ package club.joylink.rtss.simulation.cbtc.build;
import club.joylink.rtss.entity.Ibp;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog;
import club.joylink.rtss.simulation.cbtc.CTC.data.RouteSequence;
import club.joylink.rtss.simulation.cbtc.CTC.data.*;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
@ -100,8 +98,9 @@ public class SimulationBuilder {
loadDepotInOutRoutePath(simulation);
// CTC行车日志数据结构构建
if (simulation.getRepository().getConfig().isHasCTC()) {
buildCtcRailwayInfo(simulation);
buildCtcStationRunPlanLog(simulation);
LocalDateTime now = LocalDateTime.now();
buildCtcStationRunPlanLog(simulation, simulation.getRepository().getServiceTripsMap());
System.out.println("CTC行车日志耗时" + Duration.between(now, LocalDateTime.now()).getSeconds());
now = LocalDateTime.now();
generateRouteSequence(simulation);
@ -357,13 +356,38 @@ public class SimulationBuilder {
}
}
/**
* 构建铁路局(调度台区段)等数据
*
* @param simulation 仿真
*/
public static void buildCtcRailwayInfo(Simulation simulation) {
String code = "Station32295_Station58852_Station47980"; // 后期数据录入
// 铁路局(调度台区段)
CtcZone ctcZone = new CtcZone();
ctcZone.setCode(code);
ctcZone.setName("标准线");
ctcZone.setStationList(simulation.getRepository().getStationList());
// 铁路局(调度台区段)数据
CtcZoneRepository ctcZoneRepository = new CtcZoneRepository(ctcZone);
ctcZone.getStationList().forEach(s -> {
ctcZoneRepository.getStationMap().put(s.getCode(), s);
// 各车站的阶段计划
simulation.getCtcRepository().getStationStagePlan().put(s.getCode(), new CtcStationStagePlan(s));
});
// 集中中心各数据
simulation.getCtcRepository().getZoneRepository().put(code, ctcZoneRepository);
// 车务管理终端数据
simulation.getCtcRepository().getManageRepositoryMap().put(code, new CtcManageRepository(ctcZone));
}
/**
* 根据行车计划构建行车日志
*
* @param simulation 仿真实体
* @param serverTripMap 行车计划
*/
public static void buildCtcStationRunPlanLog(Simulation simulation, Map<String, List<TripPlan>> serverTripMap) {
public static void buildCtcStationRunPlanLog(Simulation simulation) {
Map<String, List<TripPlan>> serverTripMap = simulation.getRepository().getServiceTripsMap();
if (CollectionUtils.isEmpty(serverTripMap)) {
return;
}
@ -381,6 +405,7 @@ public class SimulationBuilder {
ctcRunPlanParam.setRunPlanCode(codePrefix);
// 目前将到达出发车次一直
ctcRunPlanParam.setTripNumber(tripPlan.getTripNumber());
ctcRunPlanParam.setGroupNumber(tripPlan.getServiceNumber());
ctcRunPlanParam.setArriveTripNumber(tripPlan.getTripNumber());
ctcRunPlanParam.setDepartTripNumber(tripPlan.getTripNumber());
ctcRunPlanParam.setStationCode(stationPlan.getStation().getCode());
@ -400,7 +425,22 @@ public class SimulationBuilder {
}
});
});
String code = "Station32295_Station58852_Station47980"; // 后期数据录入
// 集中中心一份
CtcZoneRepository ctcZoneRepository = simulation.getCtcRepository().getZoneRepository().get(code);
// 车务管理终端一份
CtcManageRepository ctcManageRepository = simulation.getCtcRepository().getManageRepositoryMap().get(code);
ctcRunPlanParamList.forEach(param -> {
// 集中中心增加
ctcZoneRepository.saveRunPlan(param.clone());
// 车务管理终端一份
ctcManageRepository.saveRunPlanToEditArea(param.getStationCode(), param.clone());
ctcManageRepository.saveRunPlanToEffectArea(param.getStationCode(), param.clone());
// 各站阶段计划一份
CtcStationStagePlan ctcStationStagePlan = simulation.getCtcRepository().getStationStagePlan().get(param.getStationCode());
if (ctcStationStagePlan != null) {
ctcStationStagePlan.getCtcRunPlanParamList().add(param.clone());
}
CtcStationRunPlanLog runPlanLog = new CtcStationRunPlanLog(param);
runPlanLog.setCode(param.getRunPlanCode());
runPlanLog.setTripNumber(param.getTripNumber());

View File

@ -26,6 +26,7 @@ import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -108,14 +109,18 @@ public class SimulationUserWsListener {
break;
}
case Ctc: {
Set<String> userIds = Stream.of(userId).collect(Collectors.toSet());
// CTC运行日志发消息
ctcLogicLoop.sendAllRunPlanChangeMessage(simulation, Stream.of(userId).collect(Collectors.toSet()));
ctcLogicLoop.sendAllRunPlanChangeMessage(simulation, userIds);
ctcLogicLoop.sendAllRailwayInfo(simulation, userIds);
ctcLogicLoop.sendAllMessage(simulation);
break;
}
case Ctc_Manager: { // CTC运行管理端
// CTC管理端编辑区发送消息
ctcLogicLoop.initCtcManageMessage(simulation, Stream.of(userId).collect(Collectors.toSet()));
Set<String> userIds = Stream.of(userId).collect(Collectors.toSet());
// CTC运行日志发消息
ctcLogicLoop.sendAllRailwayInfo(simulation, userIds);
ctcLogicLoop.sendAllManageChange(simulation, userIds);
break;
}
}

View File

@ -353,6 +353,12 @@ public enum WebSocketMessageType {
* 大铁CTC系统的状态消息
*/
Simulation_RailCtcStatus,
/**
* CTC 铁路局行车区段消息
*/
SIMULATION_CTC_ZONE,
/**
* 仿真CTC运行计划初始化
**/

View File

@ -105,6 +105,11 @@ public class SocketMessageFactory {
topicList.add(String.format(WebSocketSubscribeTopic.Simulation, group));
break;
}
case SIMULATION_CTC_ZONE: {
topicList.add(SimulationSubscribeTopic.Ctc.buildDestination(group));
topicList.add(SimulationSubscribeTopic.Ctc_Manager.buildDestination(group));
break;
}
case SIMULATION_CTC_RUN_PLAN_INIT:
case SIMULATION_CTC_RUN_PLAN_CHANGE:
case SIMULATION_CTC_RUN_PLAN_REMOVE: