This commit is contained in:
DU 2021-01-13 10:41:49 +08:00
commit 13f5dd8142
7 changed files with 175 additions and 27 deletions

View File

@ -5,6 +5,7 @@ import club.joylink.rtss.dao.*;
import club.joylink.rtss.entity.*; import club.joylink.rtss.entity.*;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.services.training.ITrainingV1Service; import club.joylink.rtss.services.training.ITrainingV1Service;
import club.joylink.rtss.simulation.cbtc.GroupSimulationService;
import club.joylink.rtss.vo.UserVO; import club.joylink.rtss.vo.UserVO;
import club.joylink.rtss.vo.client.*; import club.joylink.rtss.vo.client.*;
import club.joylink.rtss.vo.client.training.TrainingResultVO; import club.joylink.rtss.vo.client.training.TrainingResultVO;
@ -50,6 +51,9 @@ public class UserExamService implements IUserExamService {
@Autowired @Autowired
private LsLessonDAO lessonDAO; private LsLessonDAO lessonDAO;
@Autowired
private GroupSimulationService groupSimulationService;
@Override @Override
@Transactional @Transactional
public UserExamVO generateExamInstance(long examId, UserVO userVO) { public UserExamVO generateExamInstance(long examId, UserVO userVO) {
@ -63,8 +67,9 @@ public class UserExamService implements IUserExamService {
calendar.setTime(new Date()); calendar.setTime(new Date());
calendar.add(Calendar.SECOND, examDef.getDuration()); calendar.add(Calendar.SECOND, examDef.getDuration());
LsLesson lesson = this.lessonDAO.selectByPrimaryKey(examDef.getLessonId()); LsLesson lesson = this.lessonDAO.selectByPrimaryKey(examDef.getLessonId());
List<UserPermissionVO> examPermission = iUserPermissionService.getExamUserPermission(userVO, lesson.getMapId(), lesson.getPrdType(), lesson.getId()); groupSimulationService.confirmHasPermission(userVO, lesson.getMapId(), lesson.getPrdType());
BusinessExceptionAssertEnum.SIMULATION_PERMISSION_NOT_AVAILABLE.assertCollectionNotEmpty(examPermission); // List<UserPermissionVO> examPermission = iUserPermissionService.getExamUserPermission(userVO, lesson.getMapId(), lesson.getPrdType(), lesson.getId());
// BusinessExceptionAssertEnum.SIMULATION_PERMISSION_NOT_AVAILABLE.assertCollectionNotEmpty(examPermission);
} }
// 判断是否在考试时间之内 // 判断是否在考试时间之内
if (examDef.getStartTime() != null) { if (examDef.getStartTime() != null) {

View File

@ -175,10 +175,7 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
.filter(mapElement -> MapElement.DeviceType.SECTION.equals(mapElement.getDeviceType())) .filter(mapElement -> MapElement.DeviceType.SECTION.equals(mapElement.getDeviceType()))
.map(mapElement -> (Section) mapElement) .map(mapElement -> (Section) mapElement)
.collect(Collectors.toList()); .collect(Collectors.toList());
// 生成侧防
if (config.isGenerateFls()) {
this.generateFls(switchList);
}
Map<String, List<RouteOverlap>> overlapMap = new HashMap<>(); Map<String, List<RouteOverlap>> overlapMap = new HashMap<>();
List<Signal> approachList = new ArrayList<>(); List<Signal> approachList = new ArrayList<>();
log.info(String.format("共有信号机[%s]个", signalList.size())); log.info(String.format("共有信号机[%s]个", signalList.size()));
@ -214,6 +211,42 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
generatedRouteList.stream().filter(route -> route.isGround()).count(), generatedRouteList.stream().filter(route -> route.isGround()).count(),
generatedRouteList.stream().filter(route -> route.isGuide()).count())); generatedRouteList.stream().filter(route -> route.isGuide()).count()));
} }
// 生成侧防,构建进路侧防关系
if (config.isGenerateFls()) {
Map<String, RouteFls> flsMap = this.generateFls(switchList);
for (Route route : generatedRouteList) {
// 进路道岔侧防
List<RouteFls> routeFlsList = new ArrayList<>();
if (route.getSwitchList() != null) {
for (SwitchElement switchElement : route.getSwitchList()) {
String name = RouteFls.buildName(switchElement);
RouteFls routeFls = flsMap.get(name);
if (routeFls != null) {
routeFlsList.add(routeFls);
}
}
route.setFlsList(routeFlsList);
}
// 进路延续保护道岔侧防
RouteOverlap overlap = route.getOverlap();
if (overlap != null) {
List<SectionPath> pathList = overlap.getPathList();
for (SectionPath sectionPath : pathList) {
List<RouteFls> overlapFlsList = new ArrayList<>();
List<SwitchElement> overlapSwitchList = sectionPath.getSwitchList();
if (overlapSwitchList != null) {
for (SwitchElement switchElement : overlapSwitchList) {
RouteFls routeFls = flsMap.get(RouteFls.buildName(switchElement));
if (routeFls != null) {
overlapFlsList.add(routeFls);
}
}
}
sectionPath.setFlsList(overlapFlsList);
}
}
}
}
// 根据配置生成折返进路 // 根据配置生成折返进路
if (config.isGenerateTbRoute()) { if (config.isGenerateTbRoute()) {
List<Route> tbRouteList = this.generateTurnBackRoute(generatedRouteList, routeCodeGenerator, config); List<Route> tbRouteList = this.generateTurnBackRoute(generatedRouteList, routeCodeGenerator, config);
@ -1058,23 +1091,30 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
generatedRouteList.removeAll(removeList); generatedRouteList.removeAll(removeList);
} }
private void generateFls(List<Switch> switchList) { private Map<String, RouteFls> generateFls(List<Switch> switchList) {
CodeGenerator fpCodeGenerator = new CodeGenerator("Fls"); // 侧防 CodeGenerator fpCodeGenerator = new CodeGenerator("Fls"); // 侧防
List<RouteFls> list = new ArrayList<>(); Map<String, RouteFls> map = new HashMap<>();
for (Switch aSwitch : switchList) { for (Switch aSwitch : switchList) {
RouteFls npFls = this.buildNpFls(aSwitch); RouteFls npFls = this.buildNpFls(aSwitch, fpCodeGenerator);
if (Objects.nonNull(npFls)) { if (Objects.nonNull(npFls)) {
list.add(npFls); map.put(npFls.getName(), npFls);
} }
RouteFls rpFls = this.buildRpFls(aSwitch); RouteFls rpFls = this.buildRpFls(aSwitch, fpCodeGenerator);
if (Objects.nonNull(rpFls)) { if (Objects.nonNull(rpFls)) {
list.add(rpFls); map.put(rpFls.getName(), rpFls);
} }
} }
return map;
} }
private RouteFls buildNpFls(Switch aSwitch) { /**
RouteFls fls = new RouteFls(new SwitchElement(aSwitch, true)); * 构建道岔定位侧防
* @param aSwitch
* @param fpCodeGenerator
* @return
*/
private RouteFls buildNpFls(Switch aSwitch, CodeGenerator fpCodeGenerator) {
RouteFls fls = new RouteFls(fpCodeGenerator.next(), new SwitchElement(aSwitch, true));
// 暂时只生成一级侧防 // 暂时只生成一级侧防
Switch linkedSwitch = aSwitch.queryLinkedSwitch(); Switch linkedSwitch = aSwitch.queryLinkedSwitch();
if (Objects.nonNull(linkedSwitch)) { if (Objects.nonNull(linkedSwitch)) {
@ -1082,7 +1122,7 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
RouteFls.FlsElement flsElement = new RouteFls.FlsElement(new SwitchElement(linkedSwitch, true)); RouteFls.FlsElement flsElement = new RouteFls.FlsElement(new SwitchElement(linkedSwitch, true));
fls.addLevel1(flsElement); fls.addLevel1(flsElement);
} else { } else {
// 无联动道岔则从道岔B区段向外查询第一个反向信号机和经过的路径道岔位置构成一级侧防 // 无联动道岔则从道岔C区段向外查询第一个反向信号机和经过的路径道岔位置构成一级侧防
Section c = aSwitch.getC(); Section c = aSwitch.getC();
if (c.getLeftSection() == null && c.getRightSection() == null) { if (c.getLeftSection() == null && c.getRightSection() == null) {
// 尽头区段不需构成侧防 // 尽头区段不需构成侧防
@ -1091,30 +1131,112 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(c.getLeftSection() != null && c.getRightSection() != null, BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(c.getLeftSection() != null && c.getRightSection() != null,
String.format("道岔区段[%s]关联区段关系异常,只能最多一边关联,实际两边都关联了区段", c.debugStr())); String.format("道岔区段[%s]关联区段关系异常,只能最多一边关联,实际两边都关联了区段", c.debugStr()));
boolean right = true; boolean right = true;
Section section = c.getRightSection(); Section startSection = c.getRightSection();
if (c.getLeftSection() != null) { // 左向区段存在方向向左 if (c.getLeftSection() != null) { // 左向区段存在方向向左
right = false; right = false;
section = c.getLeftSection(); startSection = c.getLeftSection();
} }
while (Objects.nonNull(section)) { Stack<Section> sectionStack = new Stack<>();
sectionStack.push(startSection);
int i = 0;
while (!sectionStack.isEmpty() && i < 100) {
++i;
Section section = sectionStack.pop();
Signal oppositeSignal = section.getSignalOf(!right); Signal oppositeSignal = section.getSignalOf(!right);
if (Objects.nonNull(oppositeSignal)) { if (Objects.nonNull(oppositeSignal)) { // 找到反向信号机
Section firstSection = oppositeSignal.getSection().getSectionOf(oppositeSignal.isRight()); Section firstSection = oppositeSignal.getSection().getSectionOf(oppositeSignal.isRight());
RouteFls.FlsElement flsElement; RouteFls.FlsElement flsElement;
if (firstSection.isSwitchTrack()) { if (firstSection.isSwitchTrack() && !Objects.equals(aSwitch, firstSection.getRelSwitch())) {
flsElement = new RouteFls.FlsElement(oppositeSignal, new SwitchElement(firstSection.getRelSwitch(), true)); flsElement = new RouteFls.FlsElement(oppositeSignal, new SwitchElement(firstSection.getRelSwitch(), true));
} else { } else {
flsElement = new RouteFls.FlsElement(oppositeSignal); flsElement = new RouteFls.FlsElement(oppositeSignal);
} }
fls.addLevel1(flsElement); fls.addLevel1(flsElement);
} else { // 未找到取下一区段入栈
Section next = section.getSectionOf(right);
if (next != null) {
sectionStack.push(next);
} else {
if (section.isSwitchTrack() && section.getSectionOf(!right) != null) {
// 非尽头道岔区段
Switch relSwitch = section.getRelSwitch();
if (relSwitch.isA(section)) {
sectionStack.push(relSwitch.getC());
sectionStack.push(relSwitch.getB());
} else {
sectionStack.push(relSwitch.getA());
}
}
}
} }
} }
} }
return null; if (!fls.hasElement()) {
return null;
}
return fls;
} }
private RouteFls buildRpFls(Switch aSwitch) { /**
return null; * 构建道岔反位侧防
* @param aSwitch
* @param fpCodeGenerator
* @return
*/
private RouteFls buildRpFls(Switch aSwitch, CodeGenerator fpCodeGenerator) {
RouteFls fls = new RouteFls(fpCodeGenerator.next(), new SwitchElement(aSwitch, false));
// 暂只生成一级侧防
Section b = aSwitch.getB();
if (b.getLeftSection() == null && b.getRightSection() == null) {
// 尽头区段不需构成侧防
return null;
}
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(b.getLeftSection() != null && b.getRightSection() != null,
String.format("道岔区段[%s]关联区段关系异常,只能最多一边关联,实际两边都关联了区段", b.debugStr()));
boolean right = true;
Section startSection = b.getRightSection();
if (b.getLeftSection() != null) { // 左向区段存在方向向左
right = false;
startSection = b.getLeftSection();
}
Stack<Section> sectionStack = new Stack<>();
sectionStack.push(startSection);
int i = 0;
while (!sectionStack.isEmpty() && i < 100) {
++i;
Section section = sectionStack.pop();
Signal oppositeSignal = section.getSignalOf(!right);
if (Objects.nonNull(oppositeSignal)) { // 找到反向信号机
Section firstSection = oppositeSignal.getSection().getSectionOf(oppositeSignal.isRight());
RouteFls.FlsElement flsElement;
if (firstSection.isSwitchTrack() && !Objects.equals(aSwitch, firstSection.getRelSwitch())) {
flsElement = new RouteFls.FlsElement(oppositeSignal, new SwitchElement(firstSection.getRelSwitch(), true));
} else {
flsElement = new RouteFls.FlsElement(oppositeSignal);
}
fls.addLevel1(flsElement);
} else { // 未找到取下一区段入栈
Section next = section.getSectionOf(right);
if (next != null) {
sectionStack.push(next);
} else {
if (section.isSwitchTrack() && section.getSectionOf(!right) != null) {
// 非尽头道岔区段
Switch relSwitch = section.getRelSwitch();
if (relSwitch.isA(section)) {
sectionStack.push(relSwitch.getC());
sectionStack.push(relSwitch.getB());
} else {
sectionStack.push(relSwitch.getA());
}
}
}
}
}
if (!fls.hasElement()) {
return null;
}
return fls;
} }
private void generateRunLevel(Map<String, MapElement> deviceMap, List<String> errorList, private void generateRunLevel(Map<String, MapElement> deviceMap, List<String> errorList,

View File

@ -276,5 +276,7 @@ public interface GroupSimulationService {
void changePassengerFlow(String group, Long passengerFlowId); void changePassengerFlow(String group, Long passengerFlowId);
void confirmHasPermission(UserVO userVO, Long mapId, String prdType);
boolean hasPermission(UserVO userVO, Long mapId, String prdType); boolean hasPermission(UserVO userVO, Long mapId, String prdType);
} }

View File

@ -952,7 +952,8 @@ public class GroupSimulationServiceImpl implements GroupSimulationService {
/** /**
* 确认该用户有权限进入该仿真 * 确认该用户有权限进入该仿真
*/ */
private void confirmHasPermission(UserVO userVO, Long mapId, String prdType) { @Override
public void confirmHasPermission(UserVO userVO, Long mapId, String prdType) {
BusinessExceptionAssertEnum.INSUFFICIENT_PERMISSIONS.assertTrue(hasPermission(userVO, mapId, prdType)); BusinessExceptionAssertEnum.INSUFFICIENT_PERMISSIONS.assertTrue(hasPermission(userVO, mapId, prdType));
} }

View File

@ -39,6 +39,8 @@ public abstract class MapElement {
ROUTE, ROUTE,
/** 进路延续保护 */ /** 进路延续保护 */
OVERLAP, OVERLAP,
/** 侧防 */
FLANK_PROTECTION,
/** 自动信号 */ /** 自动信号 */
AUTO_SIGNAL, AUTO_SIGNAL,
/** 自动折返 */ /** 自动折返 */

View File

@ -11,9 +11,8 @@ import java.util.List;
*/ */
@Getter @Getter
@Setter @Setter
public class RouteFls { public class RouteFls extends MapNamedElement {
private String name;
/** /**
* 所防护的道岔位置 * 所防护的道岔位置
*/ */
@ -23,10 +22,15 @@ public class RouteFls {
private List<FlsElement> level2List; private List<FlsElement> level2List;
public RouteFls(SwitchElement base) { public RouteFls(String code, SwitchElement base) {
super(code, buildName(base), DeviceType.FLANK_PROTECTION);
this.base = base; this.base = base;
} }
public static String buildName(SwitchElement element) {
return String.format("Fls_%s_%s", element.getASwitch().getName(), element.isNormal() ? "N" : "R");
}
public void addLevel1(FlsElement flsElement) { public void addLevel1(FlsElement flsElement) {
if (level1List == null) { if (level1List == null) {
level1List = new ArrayList<>(); level1List = new ArrayList<>();
@ -34,6 +38,15 @@ public class RouteFls {
level1List.add(flsElement); level1List.add(flsElement);
} }
public boolean hasElement() {
return this.level1List != null && !this.level1List.isEmpty();
}
@Override
public void reset() {
}
/** /**
* 侧防元件 * 侧防元件
*/ */

View File

@ -26,6 +26,9 @@ public class SectionPath {
/** 道岔位置(如果有道岔的话) */ /** 道岔位置(如果有道岔的话) */
private List<SwitchElement> switchList; private List<SwitchElement> switchList;
/** 侧防 */
private List<RouteFls> flsList;
private List<Section> sectionList; private List<Section> sectionList;
public SectionPath(boolean right) { public SectionPath(boolean right) {