| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- package top.haijunit.train.simulation.domain;
- import cn.hutool.core.util.StrUtil;
- import liquibase.util.StringUtil;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.RequiredArgsConstructor;
- import top.haijunit.train.domain.constant.DirectionEnum;
- import top.haijunit.train.domain.entity.SignStopEntity;
- import top.haijunit.train.utils.NumberUtil;
- import java.math.BigDecimal;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Optional;
- /**
- * @author zhanghaijun
- * @date 2023/12/17 21:30
- * @description [一句话描述该类的功能]
- * @version 1.0
- */
- @Data
- public class TrainTravel {
- // 可行驶的区段集合
- private final List<SectionItem> sectionList;
- // 停车标的位置
- private final HashMap<Long, SignStopEntity> signStopMap;
- public TrainTravel(List<SectionItem> sectionList, List<SignStopEntity> signStopEntityList) {
- this.sectionList = sectionList;
- this.signStopMap = signStopEntityList.stream().collect(HashMap::new, (map, entity) -> map.put(entity.getSelectionId(), entity), HashMap::putAll);
- }
- public TrainTravel(List<SectionItem> sectionList, HashMap<Long, SignStopEntity> signStopMap) {
- this.sectionList = sectionList;
- this.signStopMap = signStopMap;
- }
- public TravelItem travel(TrainItem train, BigDecimal distance) {
- Optional<SectionItem> sectionOptional = sectionList.stream().filter(item -> {
- return item.getSectionId().equals(train.getBlockId()) && item.getDirection().equals(train.getDirection());
- }).findFirst();
- return sectionOptional.map(sectionItem -> travel(sectionItem.getId(), train.getOffset(), distance)).orElse(null);
- }
- /**
- * 列车行驶
- * @param section 当前区段
- * @param offset 偏移量
- * @param distance 行驶距离
- * @return 行驶后的位置
- */
- public TravelItem travel(String id, BigDecimal offset, BigDecimal distance) {
- Optional<SectionItem> sectionOptional = sectionList.stream().filter(item -> StrUtil.equals(item.getId(), id)).findFirst();
- if (sectionOptional.isEmpty()) {
- return null;
- }
- SectionItem sectionItem = sectionOptional.get();
- if (null == offset) {
- // 偏移量为当前区段长度 上行的开始位置是区段的末端
- offset = sectionItem.getSectionLength();
- }
- BigDecimal travelDistance = NumberUtil.mul(sectionItem.getDirection().getFactor(), distance.abs());
- BigDecimal travelOffset = NumberUtil.add(offset, travelDistance);
- // 计算停车标
- SignStopEntity stopEntity = signStopMap.get(sectionItem.getSectionId());
- if (null != stopEntity) {
- BigDecimal minInclude = NumberUtil.min(offset.abs(), travelOffset);
- BigDecimal maxInclude = NumberUtil.max(offset.abs(), travelOffset);
- Boolean isStop = switch (sectionItem.getDirection()) {
- case UP -> NumberUtil.isGreaterOrEqual(stopEntity.getSelectionOff().abs(), minInclude) && NumberUtil.isLess(stopEntity.getSelectionOff().abs(), maxInclude);
- case DOWN -> NumberUtil.isGreater(stopEntity.getSelectionOff().abs(), minInclude) && NumberUtil.isLessOrEqual(stopEntity.getSelectionOff().abs(), maxInclude);
- };
- if (isStop) {
- return new TravelItem(sectionItem, stopEntity.getSelectionOff().abs(), true);
- }
- }
- if (NumberUtil.isLess(travelOffset, BigDecimal.ZERO)) {
- // <0 上行 行驶到下一个区段
- return travel(sectionItem.getNextId(), null, travelOffset.abs());
- } else if (NumberUtil.isGreaterOrEqual(travelOffset, sectionItem.getSectionLength())) {
- // >= 区段的长度 下行 实行到下一个区段
- return travel(sectionItem.getNextId(), BigDecimal.ZERO, travelOffset.subtract(sectionItem.getSectionLength()));
- } else {
- // 行驶后的位置在当前区段
- return new TravelItem(sectionItem, travelOffset, false);
- }
- }
- @Data
- @AllArgsConstructor
- public static class TravelItem {
- // 区段
- private SectionItem section;
- // 偏移量
- private BigDecimal offset;
- // 是否停车
- private boolean isStop;
- }
- }
|