package top.haijunit.train.simulation.domain; import lombok.Getter; import lombok.Setter; import top.haijunit.train.domain.constant.DirectionEnum; import top.haijunit.train.domain.constant.RouteStatusEnum; import top.haijunit.train.domain.constant.SwitchStateEnum; import top.haijunit.train.domain.entity.RouteEntity; import top.haijunit.train.domain.entity.SelectionEntity; import top.haijunit.train.domain.entity.SignalEntity; import top.haijunit.train.utils.NumberUtil; import java.io.Serializable; import java.math.BigDecimal; import java.util.LinkedList; import java.util.Map; import java.util.stream.Collectors; /** * @author zhanghaijun * @date 2023/12/3 01:42 * @description 用于进路计算 */ @Getter @Setter public class RouteItem implements Serializable { // 进路Id private Long id; // 进路名称 private String name; // 触发点位置 private BigDecimal trigPosition; // 进路方向 private DirectionEnum direction; // 进路状态 private RouteStatusEnum routeStatus; // 下一条进路Id private Long nextId; // 区段 private LinkedList selectionList; // 信号灯 private LinkedList signalList; // 道岔的预定状态 private Map switchStateMap; public RouteItem(RouteEntity route, LinkedList selectionList, LinkedList signalList) { this.id = route.getId(); this.name = route.getName(); this.trigPosition = route.getTrigPosition(); this.direction = route.getDirection(); this.routeStatus = RouteStatusEnum.IDLE; this.nextId = route.getNextId(); this.switchStateMap = route.getSwitchMap(); this.selectionList = selectionList; this.signalList = signalList; } /** 进路开始公里标 */ public BigDecimal getHeadKilometer() { return this.getSelectionList().getFirst().getStartKilometer(); } /** 进路结束公里标 */ public BigDecimal getTailKilometer() { return this.getSelectionList().getLast().getEndKilometer(); } public LinkedList getSelectionIds() { return this.getSelectionList().stream().map(SelectionEntity::getId).collect(Collectors.toCollection(LinkedList::new)); } public LinkedList getSelectionNames() { return this.getSelectionList().stream().map(SelectionEntity::getName).collect(Collectors.toCollection(LinkedList::new)); } /** * @param kilometer 公里标 * @param direction 方向 * @return 公里标是否在当前进路中 */ public boolean isContain(BigDecimal kilometer, DirectionEnum direction) { if (this.getDirection() != direction) { return false; } return NumberUtil.isContain(kilometer, this.getHeadKilometer(), this.getTailKilometer()); } /** * @param tailKilometer 公里标 * @param direction 方向 * @return 是否已经通过当前进路 */ public boolean isPass(BigDecimal headKilometer, BigDecimal tailKilometer, DirectionEnum direction) { if (!isContain(headKilometer, direction)) { return true; } if (!isContain(tailKilometer, direction)) { return true; } return switch (direction) { // 上行 车尾 < 进路的开始里程 case UP -> NumberUtil.isLess(tailKilometer, this.getHeadKilometer()); // 下行 车位 => 进路的结束里程 case DOWN -> NumberUtil.isGreaterOrEqual(tailKilometer, this.getTailKilometer()); }; } // 是否触发下一个进路 public boolean isTrigger(BigDecimal kilometer, DirectionEnum direction) { if (!isContain(kilometer, direction)) { // 车头不在进路中,直接返回false return false; } return switch (direction) { // 上行 进路开始公里数 <= 车头公里数 <= 触发点公里数 case UP -> NumberUtil.isIn(kilometer, this.getHeadKilometer(), this.getTrigKilometer()); // 下行 触发点公里数 <= 车头公里数 <= 进路结束公里数 case DOWN -> NumberUtil.isIn(kilometer, this.getTrigKilometer(), this.getTailKilometer()); }; } public BigDecimal getTrigKilometer() { return this.getHeadKilometer().add(this.getTrigPosition()); } // 是否包含道岔 public boolean isEmptySwitch() { return this.getSwitchStateMap().isEmpty(); } // 改变状态 public void setStatus(RouteStatusEnum status) { this.routeStatus = status; } }