Merge remote-tracking branch 'origin/test' into ci-restruct

This commit is contained in:
walker-sheng 2021-09-14 10:01:46 +08:00
commit b68db75959
7 changed files with 235 additions and 1 deletions

View File

@ -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);
}
/**
*草稿地图导出
*/

View File

@ -14,4 +14,10 @@ public interface DraftMapCiDataGenerator {
*/
CiGenerateResultVO generate(Long mapId);
/**
* 生成车辆段联锁
* @param mapId
* @return
*/
int generateDepot(Long mapId, String stationCode);
}

View File

@ -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);
}
}
/**
* 生成接近区段
*

View File

@ -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);
}

View File

@ -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());
});
}
}

View File

@ -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 {

View File

@ -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());