Merge remote-tracking branch 'origin/test' into ci-restruct
This commit is contained in:
commit
b68db75959
@ -121,6 +121,14 @@ public class DraftMapController {
|
||||
return this.draftMapCiDataGenerator.generate(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成车辆段联锁数据
|
||||
*/
|
||||
@PostMapping(path = "/{id}/ci/generateAndSaveDepot")
|
||||
public int generateAndSaveDepot(@PathVariable Long id, String stationCode) {
|
||||
return this.draftMapCiDataGenerator.generateDepot(id, stationCode);
|
||||
}
|
||||
|
||||
/**
|
||||
*草稿地图导出
|
||||
*/
|
||||
|
@ -14,4 +14,10 @@ public interface DraftMapCiDataGenerator {
|
||||
*/
|
||||
CiGenerateResultVO generate(Long mapId);
|
||||
|
||||
/**
|
||||
* 生成车辆段联锁
|
||||
* @param mapId
|
||||
* @return
|
||||
*/
|
||||
int generateDepot(Long mapId, String stationCode);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package club.joylink.rtss.services.draftData;
|
||||
|
||||
import club.joylink.rtss.entity.DraftMapRoute;
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.build.SimulationBuilder;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
||||
@ -34,6 +35,10 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
|
||||
|
||||
@Autowired
|
||||
private DraftMapService draftMapService;
|
||||
|
||||
@Autowired
|
||||
private DraftMapRouteService draftMapRouteService;
|
||||
|
||||
@Autowired
|
||||
private RoutingGenerator routingGenerator;
|
||||
|
||||
@ -97,6 +102,60 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
|
||||
return result.convert2VO();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public int generateDepot(Long mapId, String stationCode) {
|
||||
// 先校验地图基础数据
|
||||
MapVO mapVO = this.draftMapService.getDraftMapData(mapId);
|
||||
SimulationBuilder.SimulationDeviceBuildResult buildResult = SimulationBuilder.checkAndBuildBasicMapData(mapVO);
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertCollectionEmpty(buildResult.getErrMsgList(),
|
||||
String.format("地图基础数据有错误: %s", JsonUtils.writeValueAsString(buildResult.getErrMsgList())));
|
||||
MapCiGenerateConfig generateConfig = mapVO.getGraphDataNew().getGenerateConfig();
|
||||
Map<String, MapElement> deviceMap = buildResult.getDeviceMap();
|
||||
// 处理旧数据
|
||||
List<MapRouteNewVO> routeList = this.draftMapRouteService.queryAllRoutes(mapId);
|
||||
List<Long> deletingList = new ArrayList<>();
|
||||
Integer routeCodeIndex = routeList.stream().peek(mapRouteNewVO -> {
|
||||
if (mapRouteNewVO.getStationCode().equals(stationCode)) {
|
||||
deletingList.add(mapRouteNewVO.getId());
|
||||
}
|
||||
}).map(MapRouteNewVO::getCode)
|
||||
.map(c -> Integer.parseInt(c.substring(CodeGenerator.Prefix_Route.length())))
|
||||
.max(Integer::compareTo).orElse(0);
|
||||
// 联锁关系数据生成
|
||||
List<String> errorList = new ArrayList<>();
|
||||
List<Route> generatedRouteList = new ArrayList<>();
|
||||
CodeGenerator routeCodeGenerator = CodeGenerator.getRouteCodeGenerator(routeCodeIndex);
|
||||
// 获取所有信号机
|
||||
List<Signal> signalList = deviceMap.values().stream()
|
||||
.filter(mapElement -> mapElement.getDeviceType().equals(MapElement.DeviceType.SIGNAL))
|
||||
.map(mapElement -> ((Signal) mapElement))
|
||||
.filter(signal -> signal.getInterlockStation().getCode().equals(stationCode))
|
||||
.collect(Collectors.toList());
|
||||
log.info(String.format("共有信号机[%s]个", signalList.size()));
|
||||
for (Signal signal : signalList) {
|
||||
// 信号机接近区段构建
|
||||
// this.generateApproachSection(signal, generateConfig);
|
||||
generatedRouteList.addAll(this.generateRouteDepot(signal, routeCodeGenerator, generateConfig, errorList));
|
||||
}
|
||||
log.info(String.format("生成一般进路[%s]条", generatedRouteList.size()));
|
||||
// 进路敌对关系构建
|
||||
// this.buildRouteConflict(generatedRouteList);
|
||||
|
||||
if (!CollectionUtils.isEmpty(errorList)) {
|
||||
for (String errMsg : errorList) {
|
||||
log.warn(String.format("联锁数据生成警告信息:[%s]", errMsg));
|
||||
}
|
||||
}
|
||||
// // 清除不需要的基本进路
|
||||
// this.deleteBaseRoute(signalList, generatedRouteList);
|
||||
// 删除旧数据,保存新数据
|
||||
this.draftMapRouteService.deleteRoutes(deletingList);
|
||||
this.draftMapRouteService.createRoutes(mapId, generatedRouteList.stream()
|
||||
.map(MapRouteNewVO::fromBO).collect(Collectors.toList()));
|
||||
return generatedRouteList.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 唯一编码生成器
|
||||
*/
|
||||
@ -650,6 +709,47 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
|
||||
return routeList;
|
||||
}
|
||||
|
||||
private List<Route> generateRouteDepot(Signal start, CodeGenerator routeCodeGenerator,
|
||||
MapCiGenerateConfig config, List<String> errorList) {
|
||||
boolean right = start.isRight();
|
||||
Section startSection = start.getSection().getSectionOf(right);
|
||||
if (Objects.isNull(startSection)) {
|
||||
System.out.println(start.getShowName());
|
||||
}
|
||||
List<SectionPath> routePathList = new ArrayList<>();
|
||||
getRoutePathOfDepot(start, startSection, new SectionPath(right), routePathList, config, errorList);
|
||||
return buildRouteFromPathDepot(start, routeCodeGenerator, routePathList, config, errorList);
|
||||
}
|
||||
|
||||
private List<Route> buildRouteFromPathDepot(Signal start, CodeGenerator routeCodeGenerator, List<SectionPath> routePathList,
|
||||
MapCiGenerateConfig config, List<String> errorList) {
|
||||
boolean right = start.isRight();
|
||||
List<Route> routeList = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(routePathList)) {
|
||||
for (SectionPath sectionPath : routePathList) {
|
||||
Section lastSection = sectionPath.getLastSection();
|
||||
Signal end = lastSection.getSignalOf(right);
|
||||
// 根据配置取进路终端信号机名称
|
||||
String endName = Objects.nonNull(end) ? end.getShowName() : lastSection.getName();
|
||||
Signal clickEnd = null;
|
||||
if (config.isRouteButton() && config.isGetNearlySignal()) {
|
||||
// 进路按钮取最近的信号机
|
||||
clickEnd = this.queryNearlySignalOf(start, sectionPath);
|
||||
}
|
||||
// 构建进路
|
||||
String code = routeCodeGenerator.next();
|
||||
String name = String.format("%s-%s", start.getShowName(), endName);
|
||||
Route route = this.buildRoute(code, name, start, end, clickEnd, sectionPath,
|
||||
null, config.isRouteSignalAlwaysGreen(), config.isRouteInterlockDoNotIncludeStandHoldTrain());
|
||||
routeList.add(route);
|
||||
|
||||
}
|
||||
} else {
|
||||
errorList.add(String.format("以[%s(%s)]为始端信号的进路未搜索到", start.getName(), start.getCode()));
|
||||
}
|
||||
return routeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询距给给定信号机最近的信号机
|
||||
*
|
||||
@ -1768,6 +1868,92 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private void getRoutePathOfDepot(Signal startSignal, Section section,
|
||||
SectionPath tempPath, List<SectionPath> routePathList,
|
||||
MapCiGenerateConfig config, List<String> errorList) {
|
||||
boolean right = startSignal.isRight();
|
||||
if (!CollectionUtils.isEmpty(tempPath.getSectionList())) {
|
||||
if (Objects.isNull(section)) {
|
||||
// if (routePathList.size() > 1) {
|
||||
routePathList.add(tempPath);
|
||||
// }
|
||||
return;
|
||||
}
|
||||
// 兼容在道岔区段的信号机
|
||||
Signal signal = tempPath.getLastSection().getSignalOf(right);
|
||||
if (Objects.nonNull(signal)) { // 找到,添加路径,返回
|
||||
if (signal.isDepotSameSignal(startSignal)) {
|
||||
routePathList.add(tempPath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
tempPath.addSection(section);
|
||||
if (section.isSwitchTrack()) {
|
||||
Switch relSwitch = section.getRelSwitch();
|
||||
Switch linkedSwitch = relSwitch.queryLinkedSwitch();
|
||||
if (relSwitch.isA(section)) {
|
||||
// 路径存在两种情况,道岔定位从A->B和道岔反位从A->C
|
||||
// 产生分化递归
|
||||
SectionPath npPath = tempPath.cloneNew();// 定位路径
|
||||
npPath.addSection(relSwitch.getB());
|
||||
npPath.addSwitchElement(new SwitchElement(relSwitch, true));
|
||||
// 没有侧防,且联动道岔存在
|
||||
if (!config.isGenerateFls() && Objects.nonNull(linkedSwitch)) {
|
||||
npPath.addSwitchElement(new SwitchElement(linkedSwitch, true));
|
||||
}
|
||||
getRoutePathOfDepot(startSignal, relSwitch.getB().getSectionOf(right), npPath, routePathList, config, errorList);
|
||||
SectionPath rpPath = tempPath.cloneNew();// 反位路径
|
||||
rpPath.addSection(relSwitch.getC());
|
||||
rpPath.addSwitchElement(new SwitchElement(relSwitch, false));
|
||||
// 如果是同一道岔计轴,添加另一道岔定位
|
||||
Switch otherSwitch = relSwitch.queryAxleRelatedOtherSwitch();
|
||||
if (!config.isGenerateFls() && Objects.nonNull(otherSwitch) && relSwitch.isBConnectTo(otherSwitch)) {
|
||||
rpPath.addSwitchElement(new SwitchElement(otherSwitch, true));
|
||||
// 另一道岔联动道岔也需要
|
||||
Switch otherLinkSwitch = otherSwitch.queryLinkedSwitch();
|
||||
if (otherLinkSwitch != null) {
|
||||
rpPath.addSwitchElement(new SwitchElement(otherLinkSwitch, true));
|
||||
}
|
||||
}
|
||||
getRoutePathOfDepot(startSignal, relSwitch.getC().getSectionOf(right), rpPath, routePathList, config, errorList);
|
||||
} else if (relSwitch.isB(section)) {
|
||||
// 只有一条路径,从B->A,道岔定位
|
||||
tempPath.addSection(relSwitch.getA());
|
||||
tempPath.addSwitchElement(new SwitchElement(relSwitch, true));
|
||||
// 没有侧防,且联动道岔存在
|
||||
if (!config.isGenerateFls() && Objects.nonNull(linkedSwitch)) {
|
||||
tempPath.addSwitchElement(new SwitchElement(linkedSwitch, true));
|
||||
}
|
||||
getRoutePathOfDepot(startSignal, relSwitch.getA().getSectionOf(right), tempPath, routePathList, config, errorList);
|
||||
} else if (relSwitch.isC(section)) {
|
||||
// 只有一条路径,从C->A,道岔反位
|
||||
tempPath.addSection(relSwitch.getA());
|
||||
tempPath.addSwitchElement(new SwitchElement(relSwitch, false));
|
||||
// 如果是同一道岔计轴,添加另一道岔定位
|
||||
Switch otherSwitch = relSwitch.queryAxleRelatedOtherSwitch();
|
||||
if (!config.isGenerateFls() && Objects.nonNull(otherSwitch)) {
|
||||
tempPath.addSwitchElement(new SwitchElement(otherSwitch, true));
|
||||
// 另一道岔联动道岔也需要
|
||||
Switch otherLinkSwitch = otherSwitch.queryLinkedSwitch();
|
||||
if (otherLinkSwitch != null) {
|
||||
tempPath.addSwitchElement(new SwitchElement(otherLinkSwitch, true));
|
||||
}
|
||||
}
|
||||
getRoutePathOfDepot(startSignal, relSwitch.getA().getSectionOf(right), tempPath, routePathList, config, errorList);
|
||||
} else {
|
||||
errorList.add(String.format("地图基础数据有错误:区段[%s(%s)]关联了道岔[%s(%s)],却不是此道岔的关联区段",
|
||||
section.getName(), section.getCode(),
|
||||
relSwitch.getName(), relSwitch.getCode()));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// 非道岔区段
|
||||
Section next = section.getSectionOf(right);
|
||||
getRoutePathOfDepot(startSignal, next, tempPath, routePathList, config, errorList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成接近区段
|
||||
*
|
||||
|
@ -17,9 +17,13 @@ public interface DraftMapRouteService {
|
||||
|
||||
void deleteRoute(Long id, String code);
|
||||
|
||||
void deleteRoutes(List<Long> ids);
|
||||
|
||||
void deleteStandHoldList(Long mapId);
|
||||
|
||||
void setSetOverlapInCtcFalse(Long mapId);
|
||||
|
||||
void createRoute(long draftMapId, MapRouteNewVO routeNewVO);
|
||||
|
||||
void createRoutes(Long draftMapId, List<MapRouteNewVO> routeList);
|
||||
}
|
||||
|
@ -154,6 +154,16 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRoutes(List<Long> ids) {
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
DraftMapRouteExample example = new DraftMapRouteExample();
|
||||
example.createCriteria().andIdIn(ids);
|
||||
this.draftMapRouteDAO.deleteByExample(example);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteStandHoldList(Long mapId) {
|
||||
List<MapRouteNewVO> mapRouteNewVOS = queryAllRoutes(mapId);
|
||||
@ -190,4 +200,12 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
routeNewVO.setCode(code);
|
||||
draftMapRouteDAO.insert(routeNewVO.convert2Draft());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createRoutes(Long draftMapId, List<MapRouteNewVO> routeList) {
|
||||
routeList.forEach(mapRouteNewVO -> {
|
||||
mapRouteNewVO.setMapId(draftMapId);
|
||||
draftMapRouteDAO.insert(mapRouteNewVO.convert2Draft());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -450,6 +450,14 @@ public class Signal extends DelayUnlockDevice {
|
||||
return SignalType.TRANSMISSION.equals(this.type);
|
||||
}
|
||||
|
||||
public boolean isDepotSameSignal(Signal signal) {
|
||||
return this.type.equals(signal.getType())
|
||||
|| (this.type.equals(SignalType.PROTECTION) && signal.getType().equals(SignalType.SHUNTING2))
|
||||
|| (this.type.equals(SignalType.SHUNTING) && signal.getType().equals(SignalType.SHUNTING2))
|
||||
|| (this.type.equals(SignalType.SHUNTING2) && signal.getType().equals(SignalType.PROTECTION))
|
||||
|| (this.type.equals(SignalType.SHUNTING2) && signal.getType().equals(SignalType.SHUNTING));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否与轨道常规运行方向相反
|
||||
*
|
||||
@ -637,6 +645,10 @@ public class Signal extends DelayUnlockDevice {
|
||||
* 出站信号机
|
||||
*/
|
||||
EXIT,
|
||||
/**
|
||||
* 列车兼调车信号机
|
||||
*/
|
||||
SHUNTING2,
|
||||
}
|
||||
|
||||
public enum SignalFault implements DeviceFault {
|
||||
|
@ -219,7 +219,7 @@ public class MapRouteNewVO {
|
||||
vo.setCode(route.getCode());
|
||||
vo.setName(route.getName());
|
||||
vo.setStartSignalCode(route.getStart().getCode());
|
||||
vo.setEndSignalCode(route.getDestination().getCode());
|
||||
vo.setEndSignalCode(Objects.nonNull(route.getDestination()) ? route.getDestination().getCode() : null);
|
||||
vo.setEndButtonSignalCode(Objects.nonNull(route.getDestinationButtonSignal()) ? route.getDestinationButtonSignal().getCode() : null);
|
||||
vo.setAspect(route.getAspect());
|
||||
vo.setTurnBack(route.isTurnBack());
|
||||
|
Loading…
Reference in New Issue
Block a user