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

This commit is contained in:
joylink_zhangsai 2021-03-25 15:03:53 +08:00
commit 7e425787d9
8 changed files with 246 additions and 149 deletions

View File

@ -358,7 +358,7 @@ public class RunPlanDraftService implements IRunPlanDraftService {
RunPlanUserConfigVO config = runPlanUserConfigService.getConfig(userVO.getId(), mapVO.getId()); RunPlanUserConfigVO config = runPlanUserConfigService.getConfig(userVO.getId(), mapVO.getId());
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertTrue(Objects.nonNull(config) && config.hasReentryData(), "运行图-用户缺少配置或没有配置车站折返数据"); BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertTrue(Objects.nonNull(config) && config.hasReentryData(), "运行图-用户缺少配置或没有配置车站折返数据");
List<RunPlanRoutingVO> userRoutings = runPlanRoutingService.getUserRoutingBy(userVO.getId(), mapVO.getId()); List<RunPlanRoutingVO> userRoutings = runPlanRoutingService.getUserRoutingBy(userVO.getId(), mapVO.getId());
Map<String, RunPlanRoutingVO> userRoutingMap = userRoutings.stream().collect(Collectors.toMap(RunPlanRoutingVO::getCode, Function.identity(), (o, n) -> o)); Map<Long, RunPlanRoutingVO> userRoutingMap = userRoutings.stream().collect(Collectors.toMap(RunPlanRoutingVO::getId, Function.identity(), (o, n) -> o));
for (RunPlanTripConfigVO tripConfigVO : serviceConfig.getTripConfigList()) { for (RunPlanTripConfigVO tripConfigVO : serviceConfig.getTripConfigList()) {
// 查询交路 // 查询交路
RunPlanRoutingVO routingData = userRoutingMap.get(tripConfigVO.getRoutingCode()); RunPlanRoutingVO routingData = userRoutingMap.get(tripConfigVO.getRoutingCode());
@ -616,7 +616,7 @@ public class RunPlanDraftService implements IRunPlanDraftService {
MapVO mapVO = this.iMapService.getMapDetail(runPlanVO.getMapId()); MapVO mapVO = this.iMapService.getMapDetail(runPlanVO.getMapId());
RunPlanUserConfigVO config = runPlanUserConfigService.getConfig(userVO.getId(), mapVO.getId()); RunPlanUserConfigVO config = runPlanUserConfigService.getConfig(userVO.getId(), mapVO.getId());
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertTrue(Objects.nonNull(config) && config.hasReentryData(), "运行图-用户缺少配置或没有配置车站折返数据"); BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertTrue(Objects.nonNull(config) && config.hasReentryData(), "运行图-用户缺少配置或没有配置车站折返数据");
RunPlanRoutingVO routingData = runPlanRoutingService.queryUserRoutingByCode(userVO.getId(), mapVO.getId(), tripConfig.getRoutingCode()); RunPlanRoutingVO routingData = runPlanRoutingService.queryUserRoutingById(userVO.getId(), mapVO.getId(), tripConfig.getRoutingCode());
String tripNumber = "000"; String tripNumber = "000";
// 查询交路 // 查询交路
@ -786,17 +786,17 @@ public class RunPlanDraftService implements IRunPlanDraftService {
//运行图验证内容 //运行图验证内容
// 验证是否有时刻数据 // 验证是否有时刻数据
RunPlanVO planVO = getRunPlanById(planId);
if (CollectionUtils.isEmpty(planVO.getTripList())) {
errorList.add("运行图数据为空!");
return errorList;
}
// 找到每个服务发车时间查找发车时间不能过早 结束时间不能过晚 // 找到每个服务发车时间查找发车时间不能过早 结束时间不能过晚
// 同一服务 根据发车排序每个车次往后每个时刻应该晚于上个且时刻之间时间应该根据站间运行等级距离计算最小值 // 同一服务 根据发车排序每个车次往后每个时刻应该晚于上个且时刻之间时间应该根据站间运行等级距离计算最小值
// 不同服务发车间隔>=1分45秒 // 不同服务发车间隔>=1分45秒
// 同站车次间隔时间不能过小 根据最大最小速度计算 站间距离 // 同站车次间隔时间不能过小 根据最大最小速度计算 站间距离
// 折返时间 // 折返时间
RunPlanVO planVO = getRunPlanById(planId);
if (CollectionUtils.isEmpty(planVO.getTripList())) {
errorList.add("运行图数据为空!");
return errorList;
}
MapVO map = this.iMapService.getMapDetail(planVO.getMapId()); MapVO map = this.iMapService.getMapDetail(planVO.getMapId());
SimulationBuilder.SimulationDeviceBuildResult buildResult = SimulationBuilder.checkAndBuildMapData(map); SimulationBuilder.SimulationDeviceBuildResult buildResult = SimulationBuilder.checkAndBuildMapData(map);
BusinessExceptionAssertEnum.DATA_ERROR.assertCollectionEmpty(buildResult.getErrMsgList(), BusinessExceptionAssertEnum.DATA_ERROR.assertCollectionEmpty(buildResult.getErrMsgList(),

View File

@ -1435,6 +1435,7 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
String.format("O_%s_%s", end.getName(), deviceName)); String.format("O_%s_%s", end.getName(), deviceName));
routeOverlap.setPathList(Arrays.asList(sectionPath)); routeOverlap.setPathList(Arrays.asList(sectionPath));
routeOverlap.setSection(signalSection); routeOverlap.setSection(signalSection);
routeOverlap.setSignal(end);
routeOverlap.setRight(right); routeOverlap.setRight(right);
routeOverlap.setDelayReleaseTime(config.getOverlapReleaseTime()); // 默认延时解锁时间 routeOverlap.setDelayReleaseTime(config.getOverlapReleaseTime()); // 默认延时解锁时间
@ -1481,6 +1482,7 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
routeOverlap.setPathList(overlapPathList); routeOverlap.setPathList(overlapPathList);
routeOverlap.setSection(signalSection); routeOverlap.setSection(signalSection);
routeOverlap.setDelayReleaseTime(config.getOverlapReleaseTime()); // 默认延时解锁时间 routeOverlap.setDelayReleaseTime(config.getOverlapReleaseTime()); // 默认延时解锁时间
routeOverlap.setSignal(end);
routeOverlap.setRight(right); routeOverlap.setRight(right);
// 是否触发式延续保护 // 是否触发式延续保护
if (config.isOverlapSettingByTrigger()) { if (config.isOverlapSettingByTrigger()) {

View File

@ -30,7 +30,7 @@ public interface IRunPlanRoutingService {
RunPlanRoutingVO queryUserRoutingBySDTNumber(Long userId, Long planId, String SDTNumber); RunPlanRoutingVO queryUserRoutingBySDTNumber(Long userId, Long planId, String SDTNumber);
RunPlanRoutingVO queryUserRoutingByCode(Long userId, Long mapId, String routingCode); RunPlanRoutingVO queryUserRoutingById(Long userId, Long mapId, Long routingId);
List<RunPlanRoutingSection> getRoutingSectionDataBy(Long userId, Long planId, String routingCode); List<RunPlanRoutingSection> getRoutingSectionDataBy(Long userId, Long planId, String routingCode);

View File

@ -8,11 +8,14 @@ import club.joylink.rtss.vo.client.runplan.RunPlanTripTimeVO;
import club.joylink.rtss.vo.client.runplan.RunPlanTripVO; import club.joylink.rtss.vo.client.runplan.RunPlanTripVO;
import club.joylink.rtss.vo.client.runplan.user.*; import club.joylink.rtss.vo.client.runplan.user.*;
import club.joylink.rtss.vo.runplan.RunPlanInputData; import club.joylink.rtss.vo.runplan.RunPlanInputData;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.time.LocalTime; import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -35,16 +38,10 @@ public class RunPlanGenerator {
public List<RunPlanTripVO> generatorTrips(Long userId, RunPlanInputData inputData, MapVO mapVO) { public List<RunPlanTripVO> generatorTrips(Long userId, RunPlanInputData inputData, MapVO mapVO) {
//校验时间 //校验时间
BusinessExceptionAssertEnum.DATA_ERROR.assertTrue(inputData.getOverTime().isAfter(inputData.getBeginTime()), "输入参数错误:发车时间应早于结束时间"); checkInputTime(inputData);
LocalTime beginTimeOffset = inputData.getBeginTime().minusHours(OFFSET_TIME_HOURS);
//向前推两小时如果到前一天则时间不合理
BusinessExceptionAssertEnum.DATA_ERROR.assertTrue(inputData.getBeginTime().isAfter(beginTimeOffset), "发车时间过早,建议晚于上午两点");
inputData.setBeginTime(beginTimeOffset);
inputData.setOverTime(inputData.getOverTime().minusHours(OFFSET_TIME_HOURS));
RunPlanRoutingVO running1Routing = runPlanRoutingService.queryUserRoutingById(userId, mapVO.getId(), inputData.getRunningRouting1());
RunPlanRoutingVO running1Routing = runPlanRoutingService.queryUserRoutingByCode(userId, mapVO.getId(), inputData.getRunningRouting1()); RunPlanRoutingVO running2Routing = runPlanRoutingService.queryUserRoutingById(userId, mapVO.getId(), inputData.getRunningRouting2());
RunPlanRoutingVO running2Routing = runPlanRoutingService.queryUserRoutingByCode(userId, mapVO.getId(), inputData.getRunningRouting2());
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(running1Routing.isLoopRoute() && running2Routing.isLoopRoute(), "交路类型错误"); BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(running1Routing.isLoopRoute() && running2Routing.isLoopRoute(), "交路类型错误");
//验证环路是否闭环 //验证环路是否闭环
boolean isLoop = running1Routing.getParkSectionCodeList().get(0).getSectionCode().equals(running2Routing.getParkSectionCodeList().get(running2Routing.getParkSectionCodeList().size() - 1).getSectionCode()) boolean isLoop = running1Routing.getParkSectionCodeList().get(0).getSectionCode().equals(running2Routing.getParkSectionCodeList().get(running2Routing.getParkSectionCodeList().size() - 1).getSectionCode())
@ -54,7 +51,7 @@ public class RunPlanGenerator {
List<RunPlanRoutingVO> inboundRoutings = new ArrayList<>(); List<RunPlanRoutingVO> inboundRoutings = new ArrayList<>();
RunPlanRoutingVO outboundRouting1 = null; RunPlanRoutingVO outboundRouting1 = null;
RunPlanRoutingVO outboundRouting2 = null; RunPlanRoutingVO outboundRouting2 = null;
if (inputData.isOutAndIn()) { if (inputData.hasOutAndInBound()) {
//确定出库 //确定出库
List<RunPlanRoutingVO> outboundRoutings = runPlanRoutingService.getUserRoutingByType(userId, mapVO.getId(), RunPlanRoutingVO.UserRoutingType.OUTBOUND); List<RunPlanRoutingVO> outboundRoutings = runPlanRoutingService.getUserRoutingByType(userId, mapVO.getId(), RunPlanRoutingVO.UserRoutingType.OUTBOUND);
inboundRoutings = runPlanRoutingService.getUserRoutingByType(userId, mapVO.getId(), RunPlanRoutingVO.UserRoutingType.INBOUND); inboundRoutings = runPlanRoutingService.getUserRoutingByType(userId, mapVO.getId(), RunPlanRoutingVO.UserRoutingType.INBOUND);
@ -64,12 +61,12 @@ public class RunPlanGenerator {
.findFirst().orElse(null); .findFirst().orElse(null);
outboundRouting2 = outboundRoutings.stream().filter(outRouting -> outboundRouting2 = outboundRoutings.stream().filter(outRouting ->
Objects.equals(outRouting.getEndSectionCode(), running2Routing.getStartSectionCode())&& !Objects.equals(outRouting.getRight(), running2Routing.getRight()) ) Objects.equals(outRouting.getEndSectionCode(), running2Routing.getStartSectionCode()) && !Objects.equals(outRouting.getRight(), running2Routing.getRight()))
.sorted(Comparator.comparingInt(o -> o.getParkSectionCodeList().indexOf(running2Routing.getParkSectionCodeList().get(0)))) .sorted(Comparator.comparingInt(o -> o.getParkSectionCodeList().indexOf(running2Routing.getParkSectionCodeList().get(0))))
.findFirst().orElse(null); .findFirst().orElse(null);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotTrue(Objects.isNull(outboundRouting1) && Objects.isNull(outboundRouting2), "没有找到对应的出库交路"); BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotTrue(Objects.isNull(outboundRouting1) && Objects.isNull(outboundRouting2), "没有找到对应的出库交路");
if((Objects.nonNull(outboundRouting1) && Objects.nonNull(outboundRouting2)) && Objects.equals(outboundRouting1.getRight(),outboundRouting2.getRight()) && Objects.equals(outboundRouting1.getStartStationCode(),outboundRouting2.getStartStationCode()) ){ if ((Objects.nonNull(outboundRouting1) && Objects.nonNull(outboundRouting2)) && Objects.equals(outboundRouting1.getRight(), outboundRouting2.getRight()) && Objects.equals(outboundRouting1.getStartStationCode(), outboundRouting2.getStartStationCode())) {
outboundRouting2 =null; outboundRouting2 = null;
} }
} }
@ -80,31 +77,24 @@ public class RunPlanGenerator {
RunPlanUserConfigVO config = runPlanUserConfigService.getConfig(userId, mapVO.getId()); RunPlanUserConfigVO config = runPlanUserConfigService.getConfig(userId, mapVO.getId());
Map<String, RunPlanUserConfigVO.ReentryTime> reentryData = checkStationReentry(mapVO, running1Routing, config); Map<String, RunPlanUserConfigVO.ReentryTime> reentryData = checkStationReentry(mapVO, running1Routing, config);
List<RunPlanTripVO> tripList = new ArrayList<>(100); List<RunPlanTripVO> tripList = new ArrayList<>(100);
//单个服务号还是多服务铺画 if (inputData.multiService() && (!inputData.hasOutAndInBound() || (Objects.nonNull(outboundRouting1) && Objects.nonNull(outboundRouting2)))) {
if (Objects.nonNull(inputData.getDepartureInterval())) {
if (!inputData.isOutAndIn() || (Objects.nonNull(outboundRouting1) && Objects.nonNull(outboundRouting2))) {
//相向发车 //相向发车
LinkedList<RunPlanTripVO> serviceTripList = generateService(inputData, mapVO, outboundRouting1, inboundRoutings, running1Routing, running2Routing, runLevelMap, parkTimeMap, reentryData); LinkedList<RunPlanTripVO> serviceTripList1 = generateService(inputData, mapVO, outboundRouting1, inboundRoutings, running1Routing, running2Routing, runLevelMap, parkTimeMap, reentryData);
tripList.addAll(serviceTripList); tripList.addAll(serviceTripList1);
int startServiceNumber = Integer.parseInt(inputData.getServiceNumber()); int startServiceNumber = Integer.parseInt(inputData.getServiceNumber());
LocalTime beginTime = inputData.getBeginTime(); LocalTime initBeginTime = inputData.getBeginTime();
LocalTime firstRoundTripTime1 = getLastDepartTime(inputData, mapVO, runLevelMap, parkTimeMap, reentryData, outboundRouting1, outboundRouting2, running1Routing, running2Routing, serviceTripList, true);
inputData.setServiceNumber(String.format("%03d", startServiceNumber + 1)); inputData.setServiceNumber(String.format("%03d", startServiceNumber + 1));
serviceTripList = generateService(inputData, mapVO, outboundRouting2, inboundRoutings, running2Routing, running1Routing, runLevelMap, parkTimeMap, reentryData); LinkedList<RunPlanTripVO> serviceTripList2 = generateService(inputData, mapVO, outboundRouting2, inboundRoutings, running2Routing, running1Routing, runLevelMap, parkTimeMap, reentryData);
tripList.addAll(serviceTripList); tripList.addAll(serviceTripList2);
LocalTime firstRoundTripTime2 = getLastDepartTime(inputData, mapVO, runLevelMap, parkTimeMap, reentryData, outboundRouting2, outboundRouting1, running2Routing, running1Routing, serviceTripList, true); DepartEndTime departEndTime = getDepartEndTime(inputData, serviceTripList1, serviceTripList2);
inputData.setServiceNumber(String.format("%03d", startServiceNumber + 2)); inputData.setServiceNumber(String.format("%03d", startServiceNumber + 2));
generateServices(inputData, mapVO, running1Routing, running2Routing, inboundRoutings, outboundRouting1, runLevelMap, parkTimeMap, reentryData, tripList, beginTime, firstRoundTripTime2); generateServices(inputData, mapVO, running1Routing, running2Routing, inboundRoutings, outboundRouting1, runLevelMap, parkTimeMap, reentryData, tripList, initBeginTime, departEndTime.departEndTime1);
inputData.setServiceNumber(String.format("%03d", startServiceNumber + 3)); inputData.setServiceNumber(String.format("%03d", startServiceNumber + 3));
generateServices(inputData, mapVO, running2Routing, running1Routing, inboundRoutings, outboundRouting2, runLevelMap, parkTimeMap, reentryData, tripList, beginTime, firstRoundTripTime1); generateServices(inputData, mapVO, running2Routing, running1Routing, inboundRoutings, outboundRouting2, runLevelMap, parkTimeMap, reentryData, tripList, initBeginTime, departEndTime.departEndTime2);
} else { } else {
LocalTime firstRoundTripTime = null;
LocalTime preServiceDepartTime;
RunPlanRoutingVO outboundRouting; RunPlanRoutingVO outboundRouting;
//出库的衔接环路 //出库的衔接环路
@ -121,93 +111,189 @@ public class RunPlanGenerator {
otherLoop = running1Routing; otherLoop = running1Routing;
} }
if (inputData.multiService()) {
LocalTime departEndTime = null;
LocalTime preServiceDepartTime;
do { do {
LinkedList<RunPlanTripVO> serviceTripList = generateService(inputData, mapVO, outboundRouting, inboundRoutings, outRefLoop, otherLoop, runLevelMap, parkTimeMap, reentryData); LinkedList<RunPlanTripVO> serviceTripList = generateService(inputData, mapVO, outboundRouting, inboundRoutings, outRefLoop, otherLoop, runLevelMap, parkTimeMap, reentryData);
inputData.setServiceNumber(String.format("%03d", Integer.parseInt(inputData.getServiceNumber()) + 2)); if (Objects.isNull(departEndTime)) {
inputData.setBeginTime(inputData.getBeginTime().plusSeconds(inputData.getDepartureInterval())); departEndTime = getDepartEndTime(inputData, serviceTripList);
if (Objects.isNull(firstRoundTripTime)) {
firstRoundTripTime = getLastDepartTime(inputData, mapVO, runLevelMap, parkTimeMap, reentryData, outboundRouting, null, outRefLoop, otherLoop, serviceTripList, false);
} }
preServiceDepartTime = serviceTripList.getFirst().getStartTime(); preServiceDepartTime = serviceTripList.getFirst().getStartTime();
tripList.addAll(serviceTripList); tripList.addAll(serviceTripList);
} while (preServiceDepartTime.plusSeconds(inputData.getDepartureInterval() * 2).compareTo(firstRoundTripTime) <= 0); inputData.setServiceNumber(String.format("%03d", Integer.parseInt(inputData.getServiceNumber()) + 2));
} inputData.setBeginTime(inputData.getBeginTime().plusSeconds(inputData.getDepartureInterval()));
} while (preServiceDepartTime.plusSeconds(inputData.getDepartureInterval() * 2).compareTo(departEndTime) <= 0);
} else { } else {
RunPlanRoutingVO outboundRouting;
//出库的衔接环路
RunPlanRoutingVO outRefLoop;
//另一个交路
RunPlanRoutingVO otherLoop;
if (Objects.nonNull(outboundRouting1)) {
outboundRouting = outboundRouting1;
outRefLoop = running1Routing;
otherLoop = running2Routing;
} else {
outboundRouting = outboundRouting2;
outRefLoop = running2Routing;
otherLoop = running1Routing;
}
tripList.addAll(generateService(inputData, mapVO, outboundRouting, inboundRoutings, outRefLoop, otherLoop, runLevelMap, parkTimeMap, reentryData)); tripList.addAll(generateService(inputData, mapVO, outboundRouting, inboundRoutings, outRefLoop, otherLoop, runLevelMap, parkTimeMap, reentryData));
} }
}
return tripList; return tripList;
} }
private void generateServices(RunPlanInputData inputData, MapVO mapVO, RunPlanRoutingVO running1Routing, RunPlanRoutingVO running2Routing, List<RunPlanRoutingVO> inboundRoutings, RunPlanRoutingVO outboundRouting1, Map<String, Integer> runLevelMap, Map<String, Integer> parkTimeMap, Map<String, RunPlanUserConfigVO.ReentryTime> reentryData, List<RunPlanTripVO> tripList, LocalTime beginTime, LocalTime firstRoundTripTime2) { private LocalTime getDepartEndTime(RunPlanInputData inputData, LinkedList<RunPlanTripVO> serviceTripList) {
LinkedList<RunPlanTripVO> serviceTripList; LocalTime departEndTime;
inputData.setBeginTime(beginTime.plusSeconds(inputData.getDepartureInterval())); List<RunPlanTripTimeVO> outBoundTimeList = serviceTripList.getFirst().getTimeList();
LocalTime preServiceDepartTime1; RunPlanTripTimeVO tripTime = null;
do { LocalTime overTime = null;
serviceTripList = generateService(inputData, mapVO, outboundRouting1, inboundRoutings, running1Routing, running2Routing, runLevelMap, parkTimeMap, reentryData); k:
inputData.setServiceNumber(String.format("%03d", Integer.parseInt(inputData.getServiceNumber()) + 2)); for (int f = 1; f < outBoundTimeList.size(); f++) {
inputData.setBeginTime(inputData.getBeginTime().plusSeconds(inputData.getDepartureInterval())); tripTime = outBoundTimeList.get(f);
preServiceDepartTime1 = serviceTripList.getFirst().getStartTime(); for (int i = 0; i < serviceTripList.size(); i += 2) {
tripList.addAll(serviceTripList); List<RunPlanTripTimeVO> secondTimeList = serviceTripList.get(i).getTimeList();
} while (preServiceDepartTime1.plusSeconds(inputData.getDepartureInterval() * 2).compareTo(firstRoundTripTime2) <= 0); for (RunPlanTripTimeVO runPlanTripTimeVO : secondTimeList) {
if (Objects.equals(runPlanTripTimeVO.getStationCode(), tripTime.getStationCode())) {
if (runPlanTripTimeVO.getArrivalTime().isAfter(tripTime.getArrivalTime())) {
overTime = runPlanTripTimeVO.getArrivalTime();
break k;
}
break;
}
}
}
}
departEndTime = Objects.nonNull(overTime) ? overTime.minusSeconds(ChronoUnit.SECONDS.between(inputData.getBeginTime(), tripTime.getArrivalTime())) : LocalTime.of(12, 0);
return departEndTime;
} }
private LocalTime getLastDepartTime(RunPlanInputData inputData, MapVO mapVO, private void checkInputTime(RunPlanInputData inputData) {
Map<String, Integer> runLevelMap, Map<String, Integer> parkTimeMap, Map<String, RunPlanUserConfigVO.ReentryTime> reentryData, BusinessExceptionAssertEnum.DATA_ERROR.assertTrue(inputData.getOverTime().isAfter(inputData.getBeginTime()), "输入参数错误:发车时间应早于结束时间");
RunPlanRoutingVO outboundRouting, RunPlanRoutingVO otherOutboundRouting, RunPlanRoutingVO outRefLoop, RunPlanRoutingVO otherLoop, LocalTime beginTimeOffset = inputData.getBeginTime().minusHours(OFFSET_TIME_HOURS);
LinkedList<RunPlanTripVO> serviceTripList, boolean opposite) { BusinessExceptionAssertEnum.DATA_ERROR.assertTrue(inputData.getBeginTime().isAfter(beginTimeOffset), "发车时间过早,建议晚于上午两点");
if (inputData.isOutAndIn()) { inputData.setBeginTime(beginTimeOffset);
if (Objects.equals(outboundRouting.getRight(), outRefLoop.getRight())) { inputData.setOverTime(inputData.getOverTime().minusHours(OFFSET_TIME_HOURS));
LocalTime firstRoundTripTime; }
if (serviceTripList.size() == 2) {
firstRoundTripTime = serviceTripList.get(1).getEndTime(); private void generateServices(RunPlanInputData inputData, MapVO mapVO, RunPlanRoutingVO running1Routing, RunPlanRoutingVO running2Routing, List<RunPlanRoutingVO> inboundRoutings, RunPlanRoutingVO outboundRouting1, Map<String, Integer> runLevelMap, Map<String, Integer> parkTimeMap, Map<String, RunPlanUserConfigVO.ReentryTime> reentryData, List<RunPlanTripVO> tripList, LocalTime initBeginTime, LocalTime departEndTime) {
} else if (Objects.equals(outboundRouting.getParkSectionCodeList().get(1).getStationCode(), outRefLoop.getStartStationCode())) { LinkedList<RunPlanTripVO> serviceTripList;
firstRoundTripTime = serviceTripList.get(opposite ? 1 : 2).getEndTime(); inputData.setBeginTime(initBeginTime);
LocalTime preServiceDepartTime = inputData.getBeginTime();
while (preServiceDepartTime.plusSeconds(inputData.getDepartureInterval() * 2).compareTo(Objects.nonNull(departEndTime) ? departEndTime : LocalTime.of(12, 0)) <= 0) {
inputData.setBeginTime(inputData.getBeginTime().plusSeconds(inputData.getDepartureInterval()));
serviceTripList = generateService(inputData, mapVO, outboundRouting1, inboundRoutings, running1Routing, running2Routing, runLevelMap, parkTimeMap, reentryData);
inputData.setServiceNumber(String.format("%03d", Integer.parseInt(inputData.getServiceNumber()) + 2));
preServiceDepartTime = serviceTripList.getFirst().getStartTime();
tripList.addAll(serviceTripList);
}
}
private DepartEndTime getDepartEndTime(RunPlanInputData inputData, LinkedList<RunPlanTripVO> serviceTripList1, LinkedList<RunPlanTripVO> serviceTripList2) {
Long interval1 = null;
LocalTime time11 = null;
LocalTime time12 = null;
RunPlanTripTimeVO collisionTripTime1 = null;
List<RunPlanTripTimeVO> firstTimeListOf1 = serviceTripList1.getFirst().getTimeList();
List<RunPlanTripTimeVO> secondTimeListOf2 = serviceTripList2.get(1).getTimeList();
k:
for (int i = 1; i < firstTimeListOf1.size(); i++) {
for (int y = 0; y < secondTimeListOf2.size(); y++) {
if (Objects.equals(firstTimeListOf1.get(i).getStationCode(), secondTimeListOf2.get(y).getStationCode())) {
time11 = firstTimeListOf1.get(i).getArrivalTime();
time12 = secondTimeListOf2.get(y).getArrivalTime();
interval1 = ChronoUnit.SECONDS.between(time11, time12);
collisionTripTime1 = firstTimeListOf1.get(i);
break k;
}
}
}
Long interval2 = null;
LocalTime time22 = null;
LocalTime time21 = null;
RunPlanTripTimeVO collisionTripTime2 = null;
List<RunPlanTripTimeVO> firstTimeListOf2 = serviceTripList2.getFirst().getTimeList();
List<RunPlanTripTimeVO> secondTimeListOf1 = serviceTripList1.get(1).getTimeList();
k:
for (int i = 1; i < firstTimeListOf2.size(); i++) {
for (int y = 0; y < secondTimeListOf1.size(); y++) {
if (Objects.equals(firstTimeListOf2.get(i).getStationCode(), secondTimeListOf1.get(y).getStationCode())) {
time22 = firstTimeListOf2.get(i).getArrivalTime();
time21 = secondTimeListOf1.get(y).getArrivalTime();
interval2 = ChronoUnit.SECONDS.between(time22, time21);
collisionTripTime2 = firstTimeListOf2.get(i);
break k;
}
}
}
if ((Objects.isNull(interval1) && Objects.isNull(interval2))) {
return new DepartEndTime(null, null);
}
LocalTime departEndTime1 = null;
LocalTime departEndTime2 = null;
LocalTime overTime = null;
if (Objects.isNull(interval2) || (Objects.nonNull(interval1) && Math.abs(interval1) <= Math.abs(interval2))) {
if (time11.isBefore(time12)) {
if(Objects.nonNull(interval2) && time22.isBefore(time21)){
departEndTime1 = time12.minusSeconds(ChronoUnit.SECONDS.between(inputData.getBeginTime(), time11));
departEndTime2 = time21.minusSeconds(ChronoUnit.SECONDS.between(inputData.getBeginTime(), time22));
}else{
departEndTime1 = time12.minusSeconds(ChronoUnit.SECONDS.between(inputData.getBeginTime(), time11));
departEndTime2 = inputData.getBeginTime().plusSeconds(Math.abs(interval1));
}
} else { } else {
int outTripRunTime = getOutTripRunTime(mapVO, opposite ? otherOutboundRouting : outboundRouting, runLevelMap, parkTimeMap, reentryData); departEndTime2 = inputData.getBeginTime().plusSeconds(Math.abs(interval1));
if (serviceTripList.size() == 3) { k:
int inTripRunTime = getInTripRunTime(mapVO, inputData.getInboundRouting(), runLevelMap, parkTimeMap, reentryData); for (int i = 1; i < serviceTripList2.size(); i += 2) {
int outRefTripRunTime = getLoopTripRunTime(mapVO, outRefLoop, runLevelMap, parkTimeMap, reentryData); List<RunPlanTripTimeVO> secondTimeList = serviceTripList2.get(i).getTimeList();
firstRoundTripTime = serviceTripList.get(2).getEndTime().minusSeconds(inTripRunTime - outRefTripRunTime + outTripRunTime); for (RunPlanTripTimeVO runPlanTripTimeVO : secondTimeList) {
if (Objects.equals(runPlanTripTimeVO.getStationCode(), collisionTripTime1.getStationCode())) {
if (runPlanTripTimeVO.getArrivalTime().isAfter(collisionTripTime1.getArrivalTime())) {
overTime = runPlanTripTimeVO.getArrivalTime();
break k;
}
break;
}
}
}
if (Objects.nonNull(overTime)) {
departEndTime1 = overTime.minusSeconds(ChronoUnit.SECONDS.between(inputData.getBeginTime(), time11));
}
}
} else { } else {
firstRoundTripTime = serviceTripList.get(opposite ? 2 : 3).getEndTime().minusSeconds(outTripRunTime); if (time22.isBefore(time21)) {
if(Objects.nonNull(interval1) && time11.isBefore(time12)){
departEndTime2 = time21.minusSeconds(ChronoUnit.SECONDS.between(inputData.getBeginTime(), time22));
departEndTime1 = time12.minusSeconds(ChronoUnit.SECONDS.between(inputData.getBeginTime(), time11));
}else{
departEndTime2 = time21.minusSeconds(ChronoUnit.SECONDS.between(inputData.getBeginTime(), time22));
departEndTime1 = inputData.getBeginTime().plusSeconds(Math.abs(interval2));
} }
}
return firstRoundTripTime;
}
if (Objects.equals(outboundRouting.getRight(), otherLoop.getRight())) {
LocalTime firstRoundTripTime;
if (Objects.equals(outboundRouting.getParkSectionCodeList().get(1).getStationCode(), otherLoop.getStartStationCode()) || serviceTripList.size() == 2) {
firstRoundTripTime = serviceTripList.get(opposite ? 0 : 1).getEndTime();
} else { } else {
int outTripRunTime = getOutTripRunTime(mapVO, opposite ? otherOutboundRouting : outboundRouting, runLevelMap, parkTimeMap, reentryData); departEndTime1 = inputData.getBeginTime().plusSeconds(Math.abs(interval2));
if (serviceTripList.size() == 3) {
int inTripRunTime = getInTripRunTime(mapVO, inputData.getInboundRouting(), runLevelMap, parkTimeMap, reentryData); k:
int outRefTripRunTime = getLoopTripRunTime(mapVO, otherLoop, runLevelMap, parkTimeMap, reentryData); for (int i = 1; i < serviceTripList1.size(); i += 2) {
firstRoundTripTime = serviceTripList.get(opposite ? 1 : 2).getEndTime().minusSeconds(inTripRunTime - outRefTripRunTime + outTripRunTime); List<RunPlanTripTimeVO> secondTimeList = serviceTripList1.get(i).getTimeList();
} else { for (RunPlanTripTimeVO runPlanTripTimeVO : secondTimeList) {
firstRoundTripTime = serviceTripList.get(opposite ? 1 : 2).getEndTime().minusSeconds(outTripRunTime); if (Objects.equals(runPlanTripTimeVO.getStationCode(), collisionTripTime2.getStationCode())) {
if (runPlanTripTimeVO.getArrivalTime().isAfter(collisionTripTime2.getArrivalTime())) {
overTime = runPlanTripTimeVO.getArrivalTime();
break k;
}
break;
} }
} }
return firstRoundTripTime;
} }
return null; if (Objects.nonNull(overTime)) {
departEndTime2 = overTime.minusSeconds(ChronoUnit.SECONDS.between(inputData.getBeginTime(), time22));
} }
return serviceTripList.get(0).getEndTime(); }
}
return new DepartEndTime(departEndTime1, departEndTime2);
}
@AllArgsConstructor
@Getter
class DepartEndTime {
LocalTime departEndTime1;
LocalTime departEndTime2;
} }
private Map<String, RunPlanUserConfigVO.ReentryTime> checkStationReentry(MapVO mapVO, RunPlanRoutingVO running1Routing, RunPlanUserConfigVO config) { private Map<String, RunPlanUserConfigVO.ReentryTime> checkStationReentry(MapVO mapVO, RunPlanRoutingVO running1Routing, RunPlanUserConfigVO config) {
@ -247,7 +333,7 @@ public class RunPlanGenerator {
LinkedList<RunPlanTripVO> serviceTripList = new LinkedList<>(); LinkedList<RunPlanTripVO> serviceTripList = new LinkedList<>();
int nextTripNumber = 1; int nextTripNumber = 1;
if (inputData.isOutAndIn()) { if (inputData.hasOutAndInBound()) {
//构建出库车次 //构建出库车次
nextTripNumber = buildServiceTrip(inputData, mapVO, outboundRouting, runLevelMap, parkTimeMap, reentryData, serviceTripList, nextTripNumber); nextTripNumber = buildServiceTrip(inputData, mapVO, outboundRouting, runLevelMap, parkTimeMap, reentryData, serviceTripList, nextTripNumber);
} }
@ -271,17 +357,17 @@ public class RunPlanGenerator {
} }
} }
if (inputData.isOutAndIn()) { if (inputData.hasOutAndInBound()) {
//找最快回库交路 //找最快回库交路
RunPlanRoutingVO inboundRouting; RunPlanRoutingVO inboundRouting;
if (loop) { if (loop) {
inboundRouting = inboundRoutings.stream().filter(inRouting -> inboundRouting = inboundRoutings.stream().filter(inRouting ->
Objects.equals(inRouting.getStartSectionCode(), otherLoop.getStartSectionCode())&& Objects.equals(inRouting.getRight(), otherLoop.getRight())) Objects.equals(inRouting.getStartStationCode(), otherLoop.getStartStationCode())/*&& Objects.equals(inRouting.getRight(), otherLoop.getRight())*/)
.sorted(Comparator.comparingInt(o -> o.getParkSectionCodeList().size())) .sorted(Comparator.comparingInt(o -> o.getParkSectionCodeList().size()))
.findFirst().orElse(null); .findFirst().orElse(null);
} else { } else {
inboundRouting = inboundRoutings.stream().filter(inRouting -> inboundRouting = inboundRoutings.stream().filter(inRouting ->
Objects.equals(inRouting.getStartSectionCode(), outRefLoop.getStartSectionCode())&& Objects.equals(inRouting.getRight(), outRefLoop.getRight())) Objects.equals(inRouting.getStartStationCode(), outRefLoop.getStartStationCode())/*&& Objects.equals(inRouting.getRight(), outRefLoop.getRight())*/)
.sorted(Comparator.comparingInt(o -> o.getParkSectionCodeList().size())) .sorted(Comparator.comparingInt(o -> o.getParkSectionCodeList().size()))
.findFirst().orElse(null); .findFirst().orElse(null);
} }

View File

@ -394,13 +394,9 @@ public class RunPlanRoutingService implements IRunPlanRoutingService {
} }
@Override @Override
public RunPlanRoutingVO queryUserRoutingByCode(Long userId, Long mapId, String routingCode) { public RunPlanRoutingVO queryUserRoutingById(Long userId, Long mapId, Long routingId) {
RunPlanRoutingExample example = new RunPlanRoutingExample(); RunPlanRouting runPlanRouting = getRunPlanRoutingData(routingId);
example.createCriteria().andMapIdEqualTo(mapId).andUserIdEqualTo(userId).andCodeEqualTo(routingCode); return RunPlanRoutingVO.convert2VO(runPlanRouting,this.iMapService.getMapDetail(mapId));
example.or().andMapIdEqualTo(mapId).andUserIdIsNull().andCodeEqualTo(routingCode);
List<RunPlanRouting> runPlanRoutings = runPlanRoutingDAO.selectByExampleWithBLOBs(example);
if (CollectionUtils.isEmpty(runPlanRoutings)) return null;
return RunPlanRoutingVO.convert2VO(runPlanRoutings.get(0),this.iMapService.getMapDetail(mapId));
} }
@Override @Override

View File

@ -1,11 +1,11 @@
package club.joylink.rtss.vo.client.map.newmap; package club.joylink.rtss.vo.client.map.newmap;
import club.joylink.rtss.entity.DraftMapOverlap;
import club.joylink.rtss.simulation.cbtc.data.map.RouteOverlap;
import club.joylink.rtss.util.JsonUtils;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import club.joylink.rtss.simulation.cbtc.data.map.RouteOverlap;
import club.joylink.rtss.entity.DraftMapOverlap;
import club.joylink.rtss.util.JsonUtils;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Getter; import lombok.Getter;
@ -56,6 +56,8 @@ public class MapOverlapVO {
@NotBlank(message = "解锁区段code不能为空") @NotBlank(message = "解锁区段code不能为空")
private String unlockSectionCode; private String unlockSectionCode;
private String signalCode;
@ApiModelProperty(value = "是否右向", required = true) @ApiModelProperty(value = "是否右向", required = true)
private boolean right; private boolean right;
@ -103,6 +105,7 @@ public class MapOverlapVO {
vo.setName(overlap.getName()); vo.setName(overlap.getName());
vo.setUnlockTime(overlap.getDelayReleaseTime()); vo.setUnlockTime(overlap.getDelayReleaseTime());
vo.setUnlockSectionCode(overlap.getSection().getCode()); vo.setUnlockSectionCode(overlap.getSection().getCode());
vo.setSignalCode(overlap.getSignal().getCode());
vo.setRight(overlap.isRight()); vo.setRight(overlap.isRight());
vo.setPathList(MapSectionPathVO.convertBO2VOList(overlap.getPathList())); vo.setPathList(MapSectionPathVO.convertBO2VOList(overlap.getPathList()));
if (!CollectionUtils.isEmpty(overlap.getTriggerPathList())) { if (!CollectionUtils.isEmpty(overlap.getTriggerPathList())) {

View File

@ -26,8 +26,7 @@ public class RunPlanTripConfigVO {
private LocalTime endTime; private LocalTime endTime;
@ApiModelProperty(value = "交路编号") @ApiModelProperty(value = "交路编号")
@NotBlank(message = "交路编号不能为空") private Long routingCode;
private String routingCode;
@Valid @Valid
@NotEmpty @NotEmpty

View File

@ -11,6 +11,7 @@ import lombok.Setter;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.time.LocalTime; import java.time.LocalTime;
import java.util.Objects;
@ApiModel(value = "运行图生成输入参数") @ApiModel(value = "运行图生成输入参数")
@Getter @Getter
@ -20,15 +21,15 @@ public class RunPlanInputData {
@ApiModelProperty(value = "表号") @ApiModelProperty(value = "表号")
private String serviceNumber; private String serviceNumber;
/**环路1-运行交路code*/ /**环路1-运行交路id*/
@ApiModelProperty(value = "运行交路code") @ApiModelProperty(value = "运行交路id")
@NotBlank(message= "环路不能为空") @NotNull(message= "环路不能为空")
private String runningRouting1; private Long runningRouting1;
/**环路2-运行交路code*/ /**环路2-运行交路id*/
@ApiModelProperty(value = "运行交路code") @ApiModelProperty(value = "运行交路id")
@NotBlank(message= "环路不能为空") @NotNull(message= "环路不能为空")
private String runningRouting2; private Long runningRouting2;
/**运营开始时间*/ /**运营开始时间*/
@ApiModelProperty(value = "开始时间") @ApiModelProperty(value = "开始时间")
@ -41,7 +42,7 @@ public class RunPlanInputData {
/**发车间隔,s*/ /**发车间隔,s*/
@ApiModelProperty(value = "发车间隔,s") @ApiModelProperty(value = "发车间隔,s")
private Integer departureInterval ; private Integer departureInterval;
/**运行等级默认-站间运行时间*/ /**运行等级默认-站间运行时间*/
private int runLevel = 3; private int runLevel = 3;
@ -52,4 +53,14 @@ public class RunPlanInputData {
/**回库交路*/ /**回库交路*/
@JsonIgnore @JsonIgnore
private RunPlanRoutingVO inboundRouting; private RunPlanRoutingVO inboundRouting;
@JsonIgnore
public boolean multiService() {
return Objects.nonNull(departureInterval);
}
@JsonIgnore
public boolean hasOutAndInBound() {
return outAndIn;
}
} }