进路路径对象调整

进路路径查询方法重写
按计划行车加载列车逻辑调整
进路延续保护侧防逻辑问题修改
This commit is contained in:
walker-sheng 2021-01-28 16:36:07 +08:00
parent 6531a09c60
commit 05ab248b18
8 changed files with 329 additions and 136 deletions

View File

@ -205,15 +205,10 @@ public class AtsTrainLoadService {
RoutePath routePath = this.selectDefaultRoutePath(repository, stationPlan.getSection(), nextStationPlan.getSection()); RoutePath routePath = this.selectDefaultRoutePath(repository, stationPlan.getSection(), nextStationPlan.getSection());
right = routePath.isRight(); right = routePath.isRight();
int t = current.toSecondOfDay() - stationPlan.getLeaveTime().toSecondOfDay(); int t = current.toSecondOfDay() - stationPlan.getLeaveTime().toSecondOfDay();
float s = routePath.getLenFromSection(stationPlan.getSection()); float totalLen = routePath.getLength();
//-最后区段+后右停车点 + 前区段-前右停车点 -左停车点+前左停车点
s= right?
s-nextStationPlan.getSection().getLen()+nextStationPlan.getSection().getStopPointByDirection(right)+stationPlan.getSection().getLen()-stationPlan.getSection().getStopPointByDirection(right)
:
s-nextStationPlan.getSection().getStopPointByDirection(right)+stationPlan.getSection().getStopPointByDirection(right);
int totalTime = nextStationPlan.getArriveTime().toSecondOfDay() - stationPlan.getLeaveTime().toSecondOfDay(); int totalTime = nextStationPlan.getArriveTime().toSecondOfDay() - stationPlan.getLeaveTime().toSecondOfDay();
float moveDistance = s / totalTime * t; // 移动的距离 float moveDistance = totalLen / totalTime * t; // 移动的距离
headPosition = routePath.getSectionPositionOfLen(moveDistance,stationPlan.getSection()); headPosition = routePath.getSectionPositionOfLen(moveDistance);
SectionPosition nextTargetPosition = new SectionPosition(nextStationPlan.getSection(), SectionPosition nextTargetPosition = new SectionPosition(nextStationPlan.getSection(),
nextStationPlan.getSection().getStopPointByDirection(right)); nextStationPlan.getSection().getStopPointByDirection(right));
if (headPosition.isAheadOf(nextTargetPosition, right)) { if (headPosition.isAheadOf(nextTargetPosition, right)) {
@ -431,8 +426,6 @@ public class AtsTrainLoadService {
trainInfo.updateEstimatedArriveInfo(endStationPlan.getSection(), endStationPlan.getArriveTime()); trainInfo.updateEstimatedArriveInfo(endStationPlan.getSection(), endStationPlan.getArriveTime());
train.updateNextStationPlan(endStationPlan.getStation(), endStationPlan.getSection(), tripPlan.isPlanParking(endStationPlan)); train.updateNextStationPlan(endStationPlan.getStation(), endStationPlan.getSection(), tripPlan.isPlanParking(endStationPlan));
break; break;
} else if (passedSectionStopPoint(headPosition, endStationPlan.getSection(), right)) {
continue;
} else { } else {
RoutePath routePath = this.selectDefaultRoutePath(repository, startStationPlan.getSection(), endStationPlan.getSection()); RoutePath routePath = this.selectDefaultRoutePath(repository, startStationPlan.getSection(), endStationPlan.getSection());
if (routePath.containsSection(headPosition.getSection())) { if (routePath.containsSection(headPosition.getSection())) {
@ -461,16 +454,6 @@ public class AtsTrainLoadService {
return false; return false;
} }
private boolean passedSectionStopPoint(SectionPosition headPosition, Section funSection, boolean right) {
float d = headPosition.getOffset() - funSection.getStopPointByDirection(right);
if (Objects.equals(headPosition.getSection(), funSection)
&& d > SimulationConstants.PARK_POINT_MAX_OFFSET) {
return true;
}
return false;
}
/** /**
* 处理碰撞逻辑 * 处理碰撞逻辑
* @param simulation * @param simulation

View File

@ -478,11 +478,13 @@ public class RouteService {
return; return;
} }
MapConfig config = simulation.getRepository().getConfig(); MapConfig config = simulation.getRepository().getConfig();
if (!config.isRouteSettingNoFail()) {
if (simulation.getSystemTime().isAfter(overlap.getSettingStartTime().plusSeconds(10))) { if (simulation.getSystemTime().isAfter(overlap.getSettingStartTime().plusSeconds(10))) {
overlap.settingFailed(); overlap.settingFailed();
log.info(String.format("进路延续保护[%s]办理失败", overlap.debugStr())); log.info(String.format("进路延续保护[%s]办理失败", overlap.debugStr()));
return; return;
} }
}
boolean right = overlap.isRight(); boolean right = overlap.isRight();
SectionPath sectionPath = overlap.selectPath(); SectionPath sectionPath = overlap.selectPath();
// 延续保护区段预先锁闭 // 延续保护区段预先锁闭
@ -515,10 +517,9 @@ public class RouteService {
} }
} }
List<SwitchElement> switchList = sectionPath.getSwitchList(); List<SwitchElement> switchList = sectionPath.getSwitchList();
if (!overlap.isRequisition()) { // 设备征用 List<RouteFls> flsList = sectionPath.getFlsList();
// 延续保护位置转动 // 延续保护位置转动
this.routeSwitchTurn(simulation, switchList); this.routeSwitchTurn(simulation, switchList);
List<RouteFls> flsList = sectionPath.getFlsList();
this.routeFlsControl(simulation, flsList); this.routeFlsControl(simulation, flsList);
if (config.isLockFirst()) { if (config.isLockFirst()) {
for (SwitchElement switchElement : switchList) { for (SwitchElement switchElement : switchList) {
@ -530,11 +531,8 @@ public class RouteService {
} }
} }
} }
overlap.updateRequisition(true);
return;
}
// 道岔是否转换到位置 // 道岔是否转换到位置
boolean onPosition = this.checkRouteSwitchPosition(switchList); boolean onPosition = this.checkRouteSwitchPosition(switchList) && this.isFlsSwitchOnPosition(flsList);
if (!onPosition) return; // 未到位返回 if (!onPosition) return; // 未到位返回
if (!overlap.getSection().isRouteLock()) { if (!overlap.getSection().isRouteLock()) {
return; return;
@ -544,6 +542,26 @@ public class RouteService {
log.debug(String.format("进路延续保护[%s]办理成功", overlap.debugStr())); log.debug(String.format("进路延续保护[%s]办理成功", overlap.debugStr()));
} }
private boolean isFlsSwitchOnPosition(List<RouteFls> flsList) {
if (!CollectionUtils.isEmpty(flsList)) {
for (RouteFls routeFls : flsList) {
List<RouteFls.FlsElement> level1List = routeFls.getLevel1List();
for (RouteFls.FlsElement flsElement : level1List) {
SwitchElement pSwitch = flsElement.getPSwitch();
if (pSwitch != null && !pSwitch.getASwitch().isOnPosition(pSwitch.isNormal())) {
return false;
} else {
SwitchElement fpae = flsElement.getFpae();
if (fpae != null && !fpae.getASwitch().isOnPosition(fpae.isNormal())) {
return false;
}
}
}
}
}
return true;
}
private boolean checkRouteSwitchPosition(List<SwitchElement> switchList) { private boolean checkRouteSwitchPosition(List<SwitchElement> switchList) {
if (!CollectionUtils.isEmpty(switchList)) { if (!CollectionUtils.isEmpty(switchList)) {
for (SwitchElement switchElement : switchList) { for (SwitchElement switchElement : switchList) {

View File

@ -758,9 +758,6 @@ public class InterlockBuilder2 {
errMsgList.add(String.format("站间运行等级[%s]无法找到路径", errMsgList.add(String.format("站间运行等级[%s]无法找到路径",
runLevel.debugStr(), startSection.debugStr(), endSection.debugStr())); runLevel.debugStr(), startSection.debugStr(), endSection.debugStr()));
} else { } else {
for (RoutePath routePath : routePaths) {
routePath.calculateDistance();
}
routePathMap.put(routePaths.get(0).getKey(), routePaths); routePathMap.put(routePaths.get(0).getKey(), routePaths);
} }
} }

View File

@ -269,7 +269,7 @@ public class RunPlanBuilder {
StationPlan firstStationPlan = tripPlan.getFirstStationPlan(); StationPlan firstStationPlan = tripPlan.getFirstStationPlan();
if (!Objects.equals(startSection.getCode(), firstStationPlan.getSection().getCode()) && if (!Objects.equals(startSection.getCode(), firstStationPlan.getSection().getCode()) &&
!Objects.equals(startSection.getDeviceStation().getCode(), firstStationPlan.getStation().getCode())) { !Objects.equals(startSection.getStation().getCode(), firstStationPlan.getStation().getCode())) {
log.warn(String.format("计划车次[%s|%s|%s]起始区段[%s(%s)]错误:既不是第一个车站[%s(%s)]到发计划的停靠区段[%s(%s)],也不属于第一个到站计划车站", log.warn(String.format("计划车次[%s|%s|%s]起始区段[%s(%s)]错误:既不是第一个车站[%s(%s)]到发计划的停靠区段[%s(%s)],也不属于第一个到站计划车站",
tripPlan.getServiceNumber(), tripPlan.getTripNumber(), tripPlan.getServiceNumber(), tripPlan.getTripNumber(),
tripPlan.getDestinationCode(), startSection.getName(), tripPlan.getDestinationCode(), startSection.getName(),
@ -280,7 +280,7 @@ public class RunPlanBuilder {
} }
StationPlan lastStationPlan = tripPlan.getLastStationPlan(); StationPlan lastStationPlan = tripPlan.getLastStationPlan();
if (!Objects.equals(endSection.getCode(), lastStationPlan.getSection().getCode()) && if (!Objects.equals(endSection.getCode(), lastStationPlan.getSection().getCode()) &&
!Objects.equals(endSection.getDeviceStation().getCode(), lastStationPlan.getStation().getCode())) { !Objects.equals(endSection.getStation().getCode(), lastStationPlan.getStation().getCode())) {
log.warn(String.format("计划车次[%s|%s|%s]结束区段[%s(%s)]错误:既不是最后车站[%s(%s)]到发计划的停靠区段[%s(%s)],也不属于最后到站的计划车站", log.warn(String.format("计划车次[%s|%s|%s]结束区段[%s(%s)]错误:既不是最后车站[%s(%s)]到发计划的停靠区段[%s(%s)],也不属于最后到站的计划车站",
tripPlan.getServiceNumber(), tripPlan.getTripNumber(), tripPlan.getServiceNumber(), tripPlan.getTripNumber(),
tripPlan.getDestinationCode(), endSection.getName(), tripPlan.getDestinationCode(), endSection.getName(),

View File

@ -85,7 +85,6 @@ public class CalculateService {
* 计算从起点到终点距离单方向 * 计算从起点到终点距离单方向
*/ */
public static Float calculateDistance(SectionPosition startPosition, SectionPosition endPosition, boolean right) { public static Float calculateDistance(SectionPosition startPosition, SectionPosition endPosition, boolean right) {
// long start = System.currentTimeMillis();
Section startSection = startPosition.getSection(); Section startSection = startPosition.getSection();
Section endSection = endPosition.getSection(); Section endSection = endPosition.getSection();
float distance = 0; float distance = 0;
@ -119,8 +118,6 @@ public class CalculateService {
distance += baseOffset - endPosition.getOffset(); distance += baseOffset - endPosition.getOffset();
} }
} }
// long end = System.currentTimeMillis();
// System.out.println(String.format("计算距离用时:%s", (end-start)));
return distance; return distance;
} }
@ -640,110 +637,185 @@ public class CalculateService {
public static List<RoutePath> queryRoutePathsOnDirection(Section start, Section end, Boolean right) { public static List<RoutePath> queryRoutePathsOnDirection(Section start, Section end, Boolean right) {
List<RoutePath> list = new ArrayList<>(); List<RoutePath> list = new ArrayList<>();
Signal signal = null; List<String> warnList = new ArrayList<>();
// if (start.isSwitchTrack()) {
// signal = start.querySwitchSectionRelatedSignalByDirection(right);
// } else {
// signal = start.getSignalOf(right);
// }
Section section = start;
int rc = 0;
while (signal == null && rc < 20) {
++rc;
if (section == null) {
break;
}
signal = section.getSignalOf(right);
if (signal != null) {
break;
}
Section sectionOf = section.getSectionOf(!right);
if (sectionOf != null) {
section = sectionOf;
} else if (sectionOf == null && section.isSwitchTrack()) {
Switch relSwitch = section.getRelSwitch();
if (relSwitch.isA(section)) {
section = relSwitch.getB();
} else {
section = relSwitch.getA();
}
}
}
RoutePath routePath = new RoutePath(start, end, right); RoutePath routePath = new RoutePath(start, end, right);
getRoutePaths(signal, right, end, 1, routePath, list); queryRoutePaths(0, start, routePath, list, warnList);
if (!CollectionUtils.isEmpty(list)) {
for (RoutePath path : list) {
path.calculateDistance();
log.debug(path.debugStr2());
}
} else {
log.warn(String.format("进路路径[%s]未找到:[%s]",
routePath.debugStr(),
String.join(",", warnList)));
}
return list; return list;
} }
private static void getRoutePaths(Signal signal, Boolean right, Section end, int iter, private static void queryRoutePaths(int iter, Section section, RoutePath routePath,
RoutePath routePath, List<RoutePath> list) { List<RoutePath> list, List<String> warnList) {
if (Objects.isNull(signal)) { if (section == null) {
warnList.add(String.format("进路路径[%s]未找到,找到的最后区段为[%s],下一区段为null",
routePath.debugStr(), routePath.getLastSection().debugStr()));
return; return;
} }
if (iter > 20) { if (iter > 10) {
warnList.add(String.format("进路路径[%s]未找到迭代10次,最后区段为[%s]",
routePath.debugStr(), routePath.getLastSection().debugStr()));
return; return;
} }
Section end = routePath.getEnd();
boolean right = routePath.isRight();
Signal signal = section.getSignalOf(right);
if (signal == null) {
// 区段没有信号机
Section next = section.getSectionOf(right);
if (next != null) {
// 下一区段存在
if (Objects.equals(next, end)) {
// 找到结束
list.add(routePath);
} else {
// 添加并进行迭代
routePath.addSection(next);
queryRoutePaths(iter + 1, next, routePath, list, warnList);
}
} else if (section.isSwitchTrack()) { // 道岔区段
Switch relSwitch = section.getRelSwitch();
if (relSwitch.isA(section)) {
RoutePath path1 = routePath.cloneNew();
path1.addSection(relSwitch.getB());
queryRoutePaths(iter + 1, relSwitch.getB(), path1, list, warnList);
RoutePath path2 = routePath.cloneNew();
path2.addSection(relSwitch.getC());
queryRoutePaths(iter + 1, relSwitch.getC(), path2, list, warnList);
} else {
routePath.addSection(relSwitch.getA());
queryRoutePaths(iter + 1, relSwitch.getA(), routePath, list, warnList);
}
} else {
warnList.add(String.format("区段[%s]的[%s]区段不存在",
section.debugStr(), right ? "右向" : "左向"));
}
return;
}
// 信号机存在
routePath.addSignal(signal); routePath.addSignal(signal);
List<Route> routeList = signal.getRouteList(); List<Route> routeList = signal.getRouteList();
if (!CollectionUtils.isEmpty(routeList)) { if (!CollectionUtils.isEmpty(routeList)) {
// 根据信号机的进路查询 // 进路
Set<Signal> signals = new HashSet<>(); boolean find = false;
if (signal.isVirtual()) { // 虚拟信号机应该只有一条进路
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(routeList.size() == 1);
Route route = routeList.get(0);
routePath.addRoute(route);
List<Section> sectionList = route.getSectionList();
int i = sectionList.indexOf(end);
if (i >= 0) {
// 找到
routePath.addSections(sectionList.subList(0, i));
list.add(routePath);
} else {
routePath.addSections(sectionList);
queryRoutePaths(iter+1, route.getLastRouteSection(), routePath, list, warnList);
}
return;
}
Map<Section, List<Route>> routeMap = new HashMap<>(); // 进路终端对应进路列表(ATP进路合并进正常进路终端)
routeList.sort(Comparator.comparing(Route::isAtp)); // 将ATP进路排在最后处理
for (Route route : routeList) { for (Route route : routeList) {
if (route.isGround() || route.isGuide()) { // 如果进路是分为ATP信号地面信号引导信号的只处理ATP信号 Section lastRouteSection = route.getLastRouteSection();
continue; List<Route> routes = routeMap.get(lastRouteSection);
if (routes == null) {
routes = new ArrayList<>();
routeMap.put(lastRouteSection, routes);
} }
if (route.isRouteSection(end)) { routes.add(route);
for (Section section : route.getSectionList()) { if (route.isAtp()) { // 哈尔滨一ATP进路
routePath.addSection(section); boolean handled = false;
if (Objects.equals(section, end)) { Set<Section> sections = routeMap.keySet();
break; for (Section last : sections) {
List<Route> tempList = routeMap.get(last);
if (tempList.contains(lastRouteSection)) {
handled = true;
tempList.add(route);
List<Route> nextRouteList = route.getDestination().getRouteList();
if (nextRouteList.size() == 1 &&
Objects.equals(nextRouteList.get(0).getLastRouteSection(), last)) {
tempList.addAll(nextRouteList);
} else {
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception();
} }
} }
}
if (handled) {
routeMap.remove(lastRouteSection);
}
}
}
Set<Section> keys = routeMap.keySet();
List<RoutePath> iterList = new ArrayList<>();
for (Section key : keys) {
List<Route> routeList1 = routeMap.get(key);
List<Section> sectionList = routeList1.get(0).getSectionList();
int i = sectionList.indexOf(end);
if (i >= 0) {
// 找到
routePath.addRoutes(routeList1);
if (!find) {
find = true;
routePath.addSections(sectionList.subList(0, i));
}
} else {
// 不包含
RoutePath clone = routePath.cloneNew();
clone.addRoutes(routeList1);
clone.addSections(sectionList);
iterList.add(clone);
}
}
if (find) {
list.add(routePath); list.add(routePath);
return; return;
} else { } else {
signals.add(route.getDestination()); for (RoutePath clone : iterList) {
} Section next = clone.getLastSection();
} queryRoutePaths(iter + 1, next, clone, list, warnList);
if (!CollectionUtils.isEmpty(signals)) {
for (Signal endSignal : signals) {
RoutePath clone = routePath.cloneNew();
for (Route route : routeList) {
if (Objects.equals(route.getDestination(), endSignal)) {
clone.addSections(route.getSectionList());
break;
}
}
getRoutePaths(endSignal, right, end, iter + 1, clone, list);
} }
} }
} else { } else {
// 循着自动信号后面的区段查询 // 自动信号
AutoSignal autoSignal = signal.getAutoSignal(); AutoSignal autoSignal = signal.getAutoSignal();
if (Objects.nonNull(autoSignal)) { if (autoSignal == null) {
warnList.add(String.format("信号机[%s]既没有进路也不是自动信号", signal.debugStr()));
return;
}
List<Section> sectionList = autoSignal.getSectionList(); List<Section> sectionList = autoSignal.getSectionList();
for (Section section : sectionList) { int i = sectionList.indexOf(end);
routePath.addSection(section); if (i >= 0) {
if (Objects.equals(section, end)) { // 找到
routePath.addSections(sectionList.subList(0, i));
list.add(routePath); list.add(routePath);
return; return;
} else { } else {
Signal signalOf = section.getSignalOf(right); // 顺着区段找下一个有信号机的区段为止
if (Objects.nonNull(signalOf)) { for (Section next : sectionList) {
RoutePath clone = routePath.cloneNew(); routePath.addSection(next);
getRoutePaths(signalOf, right, end, iter + 1, clone, list); if (next.getSignalOf(right) != null) {
queryRoutePaths(iter + 1, next, routePath, list, warnList);
break; break;
} }
} }
} }
} }
} }
}
/** /**
* 查找从startSection到destination的途径区段路径 * 查找从startSection到destination的途径区段路径
*/ */
public static Set<List<Section>> querySectionPaths2Destination(@NonNull Section startSection, @NonNull Section destination, public static Set<List<Section>> querySectionPaths2Destination(Section startSection, Section destination,
@NonNull Boolean right, @NonNull boolean stop) { Boolean right, boolean stop) {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
//从startSection开始寻找第一个同向信号机如果是折返轨两边的信号机都算并记录途径区段 //从startSection开始寻找第一个同向信号机如果是折返轨两边的信号机都算并记录途径区段
List<Signal> signals = new ArrayList<>(); List<Signal> signals = new ArrayList<>();

View File

@ -35,7 +35,7 @@ public class Route extends MapNamedElement {
/** 是否折返进路 */ /** 是否折返进路 */
private boolean turnBack; private boolean turnBack;
/** 是否引导进路 */ /** 是否ATP进路 */
private boolean atp; private boolean atp;
/** 是否地面信号进路 */ /** 是否地面信号进路 */

View File

@ -64,11 +64,11 @@ public class RouteFls {
public void lock() { public void lock() {
for (FlsElement flsElement : this.getLevel1List()) { for (FlsElement flsElement : this.getLevel1List()) {
SwitchElement pSwitch = flsElement.getPSwitch(); SwitchElement pSwitch = flsElement.getPSwitch();
if (pSwitch != null) { if (pSwitch != null && !pSwitch.getASwitch().isSectionOccupied()) {
pSwitch.getASwitch().fpLock(); pSwitch.getASwitch().fpLock();
} else { } else {
SwitchElement fpae = flsElement.getFpae(); SwitchElement fpae = flsElement.getFpae();
if (fpae != null) { if (fpae != null && !fpae.getASwitch().isSectionOccupied()) {
fpae.getASwitch().fpLock(); fpae.getASwitch().fpLock();
} }
} }

View File

@ -1,5 +1,6 @@
package club.joylink.rtss.simulation.cbtc.data.support; package club.joylink.rtss.simulation.cbtc.data.support;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.constant.RunLevel; import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
import club.joylink.rtss.simulation.cbtc.data.map.*; import club.joylink.rtss.simulation.cbtc.data.map.*;
import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
@ -10,6 +11,7 @@ import org.springframework.util.CollectionUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors;
@Getter @Getter
public class RoutePath { public class RoutePath {
@ -26,7 +28,10 @@ public class RoutePath {
/** 信号机列表 */ /** 信号机列表 */
private List<Signal> signalList = new ArrayList<>(); private List<Signal> signalList = new ArrayList<>();
/** 区段列表 */ /** 进路列表 */
private List<Route> routeList = new ArrayList<>();
/** 区段列表(不包含start和end) */
private List<Section> sectionList = new ArrayList<>(); private List<Section> sectionList = new ArrayList<>();
/** 方向 */ /** 方向 */
@ -48,15 +53,40 @@ public class RoutePath {
} }
public void addSignal(Signal signal) { public void addSignal(Signal signal) {
if (this.signalList.contains(signal)) {
return;
}
this.signalList.add(signal); this.signalList.add(signal);
} }
public void addSection(Section section) { public void addSection(Section section) {
if (this.sectionList.contains(section)) {
return;
}
this.sectionList.add(section); this.sectionList.add(section);
} }
public void addSections(List<Section> sections) { public void addSections(List<Section> sections) {
this.sectionList.addAll(sections); if (!CollectionUtils.isEmpty(sections)) {
for (Section section : sections) {
this.addSection(section);
}
}
}
public void addRoute(Route route) {
if (this.routeList.contains(route)) {
return;
}
this.routeList.add(route);
}
public void addRoutes(List<Route> routeList) {
if (!CollectionUtils.isEmpty(routeList)) {
for (Route route : routeList) {
this.addRoute(route);
}
}
} }
public RoutePath cloneNew() { public RoutePath cloneNew() {
@ -73,9 +103,25 @@ public class RoutePath {
return length; return length;
} }
float len = 0; float len = 0;
if (start.isFunctionTrack()) {
if (this.isRight()) {
len += start.getLen() - start.getStopPointRight();
} else {
len += start.getStopPointLeft();
}
}
for (Section section : this.sectionList) { for (Section section : this.sectionList) {
len += section.getLen(); len += section.getLen();
} }
if (end.isFunctionTrack()) {
if (this.isRight()) {
len += end.getStopPointRight();
} else {
len += end.getLen() - end.getStopPointLeft();
}
} else {
len += end.getLen();
}
this.length = len; this.length = len;
return len; return len;
} }
@ -85,7 +131,9 @@ public class RoutePath {
} }
public boolean containsSection(Section section) { public boolean containsSection(Section section) {
return this.sectionList.contains(section) || Objects.equals(section, this.start); return this.start.isSamePhysical(section.getCode()) ||
this.end.isSamePhysical(section.getCode()) ||
this.sectionList.contains(section);
} }
public boolean isPathSection(Section section) { public boolean isPathSection(Section section) {
@ -103,13 +151,6 @@ public class RoutePath {
} }
return true; return true;
} }
public String debugStr() {
return String.format("%s(%s)->%s(%s)",
this.start.getStation().getName(), this.start.getName(),
this.end.getStation().getName(), this.end.getName());
}
public float getLenFromSection(Section fromSection){ public float getLenFromSection(Section fromSection){
List<Section> list = new ArrayList<>(); List<Section> list = new ArrayList<>();
if(sectionList.contains(fromSection)){ if(sectionList.contains(fromSection)){
@ -128,6 +169,56 @@ public class RoutePath {
} }
return len; return len;
} }
public SectionPosition getSectionPositionOfLen(float len) {
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(len <= this.length);
float l = len;
Section section = null;
float offset = 0;
if (this.start.isFunctionTrack()) {
float s = 0;
if (this.isRight()) {
s = this.start.getLen() - this.start.getStopPointRight();
} else {
s = this.start.getStopPointLeft();
}
if (l < s) {
offset = this.start.getStopPointRight() + l;
section = this.start;
} else {
l -= s;
}
}
if (section == null) {
for (Section next : this.sectionList) {
if (l <= next.getLen()) {
section = next;
if (this.isRight()) {
offset = l;
} else {
offset = next.getLen() - l;
}
break;
} else {
l -= next.getLen();
}
}
}
if (section == null) {
// end区段
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(l <= this.end.getLen());
section = this.end;
if (this.isRight()) {
offset = l;
} else {
offset = this.end.getLen() - l;
}
}
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(section);
return new SectionPosition(section, offset);
}
public SectionPosition getSectionPositionOfLen(float runLen,Section fromSection) { public SectionPosition getSectionPositionOfLen(float runLen,Section fromSection) {
float remain = runLen; float remain = runLen;
Section target = null; Section target = null;
@ -242,4 +333,36 @@ public class RoutePath {
} }
return false; return false;
} }
public Section getLastSection() {
return this.sectionList.get(this.sectionList.size() - 1);
}
public String debugStr() {
return String.format("%s(%s)->%s(%s)",
this.start.getStation().getName(), this.start.getName(),
this.end.getStation().getName(), this.end.getName());
}
public String debugStr2() {
String sections = String.join(",", this.sectionList.stream()
.map(Section::debugStr)
.collect(Collectors.toList()));
String signals = String.join(",", this.signalList.stream()
.map(Signal::debugStr)
.collect(Collectors.toList()));
String routes = String.join(",", this.routeList.stream()
.map(Route::debugStr)
.collect(Collectors.toList()));
return String.format("进路路径[%s]:{方向:%s," +
"距离:%s" +
"途经区段:[%s]," +
"途经信号机:[%s]," +
"途经进路(多种方式):[%s]}",
this.debugStr(), this.isRight()?"":"",
this.length,
sections,
signals,
routes);
}
} }