SimulationBuilder.build中实现加载车辆段route path

This commit is contained in:
xiazengbin 2021-12-06 18:06:01 +08:00
parent 05e0eedb34
commit eb56128954

View File

@ -1,416 +1,477 @@
package club.joylink.rtss.simulation.cbtc.build;
import club.joylink.rtss.entity.Ibp;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.*;
import club.joylink.rtss.simulation.cbtc.data.plan.TerminalDeparturePlan;
import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan;
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityDevice;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityIbp;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.ibp.IbpData;
import club.joylink.rtss.vo.client.runplan.RunPlanVO;
import club.joylink.rtss.vo.client.schedulingNew.SchedulingPlanNewVO;
import club.joylink.rtss.vo.map.logic.MapStationParkingTimeVO;
import club.joylink.rtss.vo.map.MapVO;
import club.joylink.rtss.vo.map.RealLineConfigVO;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import javax.swing.text.Element;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Slf4j
public class SimulationBuilder {
/**
* 构造仿真对象
*/
public static Simulation build(String group, SimulationBuildParams buildParams) {
Simulation simulation = new Simulation(group);
simulation.setBuildParams(buildParams);
if (Objects.nonNull(buildParams.getLoginUserInfo())) {
simulation.setProject(buildParams.getLoginUserInfo().getProject());
}
// 线路配置参数
simulation.getRepository().setConfig(buildConfig(buildParams.getMap().getConfigVO()));
simulation.getRepository().getConfig()
.setRouteLikeHa1(buildParams.getMap().getGraphDataNew().getGenerateConfig().isLikeHa1());
simulation.getRepository().getConfig()
.setOverlapSettingByTrigger(buildParams.getMap().getGraphDataNew().getGenerateConfig().isOverlapSettingByTrigger());
simulation.getRepository().getConfig()
.setSharingECStations(buildParams.getMap().getGraphDataNew().getGenerateConfig().getSharingECStations());
simulation.getRepository().getConfig()
.setHandleDepot(buildParams.getMap().getGraphDataNew().getGenerateConfig().isHandleDepot());
// 地图数据构建
SimulationDeviceBuildResult mapDataBuildResult = checkAndBuildMapData(buildParams.getMap());
// ibp数据构建
buildIbpData(mapDataBuildResult, buildParams.getMap().getIbpList());
simulation.getRepository().setDeviceMap(mapDataBuildResult.getDeviceMap());
simulation.getRepository().setSectionArriveNearMap(mapDataBuildResult.sectionArriveNearMap);
simulation.getRepository().setVrDeviceMap(mapDataBuildResult.getVrDeviceMap());
// simulation.getRepository().setRouteUnitMap(mapDataBuildResult.getRouteUnitMap());
simulation.getRepository().setRoutePathMap(mapDataBuildResult.getRoutePathMap());
simulation.getRepository().setDestinationMap(mapDataBuildResult.getDestinationMap());
simulation.getRepository().setRoutingList(mapDataBuildResult.getRoutingList());
// simulation.getRepository().setRunLevelList(mapDataBuildResult.getRunLevelList());
simulation.getRepository().getCatenaryMap().putAll(mapDataBuildResult.getCatenaryMap());
simulation.getRepository().getSectionRespondersMap().putAll(mapDataBuildResult.getSectionRespondersMap());
simulation.getRepository().setParkingTracksMap(mapDataBuildResult.getParkingTracksMap());
// simulation.getRepository().setParkTimeMap(mapDataBuildResult.getParkTimeMap());
UserConfigDataBuilder.buildRunLevel(simulation.getRepository(), buildParams.getUserRunLevelList(),
buildParams.getMap(), mapDataBuildResult.getErrMsgList());
UserConfigDataBuilder.buildParkTime(simulation.getRepository(), buildParams.getUserParkTimeList(),
buildParams.getMap(), mapDataBuildResult.getErrMsgList());
if (!CollectionUtils.isEmpty(mapDataBuildResult.getErrMsgList())) { // 存在数据异常
mapDataBuildResult.getErrMsgList().forEach(errMsg -> log.warn(String.format("地图数据异常:%s", errMsg)));
simulation.setMapDataError(true);
simulation.addDataErrMsgs(mapDataBuildResult.getErrMsgList());
}
// 加载运行图
checkAndLoadRunPlan(simulation, buildParams.getRunPlan());
// 加载派班计划
checkAndLoadSchedulingPlan(simulation, buildParams.getSchedulingPlan());
return simulation;
}
private static void buildIbpData(SimulationDeviceBuildResult mapDataBuildResult, List<Ibp> ibpList) {
if (CollectionUtils.isEmpty(ibpList))
return;
Map<String, MapElement> deviceMap = mapDataBuildResult.getDeviceMap();
Map<String, VirtualRealityDevice> vrDeviceMap = mapDataBuildResult.getVrDeviceMap();
Map<String, Ibp> ibpMap = ibpList.stream().collect(Collectors.toMap(Ibp::getStationCode, Function.identity()));
List<Station> collect = deviceMap.values().stream()
.filter(element -> MapElement.DeviceType.STATION.equals(element.getDeviceType()))
.map(element -> (Station) element).collect(Collectors.toList());
collect.forEach(station -> {
//构建添加IBP
Ibp ibp = ibpMap.get(station.getCode());
if (ibp == null)
ibp = ibpMap.get(null);
if (ibp != null) {
IbpData ibpData = JsonUtils.read(ibp.getData(), IbpData.class);
VirtualRealityIbp vrIbp = new VirtualRealityIbp(station.getCode() + "_IBP", station.getName() + "_IBP", ibpData, station);
station.setVrIbp(vrIbp);
deviceMap.put(vrIbp.getCode(), vrIbp);
vrDeviceMap.put(vrIbp.getCode(), vrIbp);
}
});
}
private static boolean isOverlapSettingByTrigger(Map<String, MapElement> deviceMap) {
for (MapElement mapElement : deviceMap.values()) {
if (mapElement.getDeviceType().equals(MapElement.DeviceType.OVERLAP)) {
if (!CollectionUtils.isEmpty(((RouteOverlap) mapElement).getTriggerPathList())) {
return true;
} else {
return false;
}
}
}
return false;
}
/**
* 检查并加载派班计划
* @param simulation
* @param schedulingPlan
*/
public static void checkAndLoadSchedulingPlan(Simulation simulation, SchedulingPlanNewVO schedulingPlan) {
if (simulation.isMapDataError() || simulation.isPlanDataError()) {
return;
}
if (Objects.isNull(schedulingPlan)) {
// 如果没有加载计划生成默认的加载计划
if (!simulation.isMapDataError() && simulation.isPlanLoaded() && !simulation.isPlanDataError()) { // 地图数据和运行计划加载成功的情况下
log.info(String.format("地图[%s(%s)]没有派班计划,生成默认派班计划使用",
simulation.getBuildParams().getMap().getName(),
simulation.getBuildParams().getMap().getId()));
SchedulingBuilder.generateSchedulingPlan(simulation);
}
} else {
SchedulingBuilder.loadSchedulingPlan(simulation, schedulingPlan);
}
}
/**
* 检查并加载运行计划
* @param simulation
* @param runPlan
* @return
*/
public static void checkAndLoadRunPlan(Simulation simulation, RunPlanVO runPlan) {
if (simulation.isMapDataError()) {
// 地图逻辑数据有问题不加载
log.info(String.format("仿真地图[%s(%s)]数据有问题,不执行运行计划加载",
simulation.getBuildParams().getMap().getName(),
simulation.getBuildParams().getMap().getId()));
return;
}
if (Objects.nonNull(runPlan)) {
RunPlanBuilder.RunPlanBuildResult runPlanBuildResult =
RunPlanBuilder.buildRunDiagram(simulation.getRepository().getDeviceMap(), runPlan);
simulation.setPlanLoaded(true);
if (!CollectionUtils.isEmpty(runPlanBuildResult.getErrMsgList())) { // 数据异常
runPlanBuildResult.getErrMsgList().forEach(errMsg -> log.warn(String.format("运行图数据异常:%s", errMsg)));
simulation.setPlanDataError(true);
simulation.addDataErrMsgs(runPlanBuildResult.getErrMsgList());
} else {
simulation.getRepository().setServiceTripsMap(runPlanBuildResult.getServerTripMap());
simulation.getRepository().setStandTripMap(runPlanBuildResult.getStandTripMap());
simulation.getRepository().setEndTripMap(runPlanBuildResult.getEndTripMap());
// 校验运行计划和路径单元
List<String> errMsgList = checkRunPlanAndBuildLostRoutePaths(runPlanBuildResult.getServerTripMap(),
simulation.getRepository().getRoutePathMap());
if (!errMsgList.isEmpty()) {
simulation.setMapDataError(true);
simulation.addDataErrMsgs(errMsgList);
}
// // 构建终端发车计划
// TerminalPlanBuildResult terminalPlanBuildResult = buildTerminalPlan(simulation.getRepository(), runPlanBuildResult.getServerTripMap());
// if (!CollectionUtils.isEmpty(terminalPlanBuildResult.getErrMsgList())) {
// simulation.setMapDataError(true);
// simulation.addDataErrMsgs(terminalPlanBuildResult.getErrMsgList());
// } else {
// simulation.getRepository().setTerminalDeparturePlanMap(terminalPlanBuildResult.getTerminalPlanMap());
// }
}
} else {
simulation.addDataErrMsg("运行图为空");
}
}
public static List<String> checkRunPlanAndBuildLostRoutePaths(Map<String, List<TripPlan>> serverTripMap,
Map<String, List<RoutePath>> routePathMap) {
Map<String, String> errMsgMap = new HashMap<>();
for (List<TripPlan> tripPlanList : serverTripMap.values()) {
for (TripPlan tripPlan : tripPlanList) {
List<Section> allViaSectionList = tripPlan.getAllViaStoppedSectionList();
for (int i = 1; i < allViaSectionList.size(); i++) {
Section start = allViaSectionList.get(i - 1);
Section end = allViaSectionList.get(i);
String key = RoutePath.buildKey(start, end);
if (!routePathMap.containsKey(key)) {
// 路径不存在尝试构建
List<RoutePath> routePaths = CalculateService.queryRoutePathsOnDirection(start, end, tripPlan.isRight(), 10);
if (CollectionUtils.isEmpty(routePaths)) {
// 计划方向路径未找到反向尝试
routePaths = CalculateService.queryRoutePathsOnDirection(start, end, !tripPlan.isRight(), 10);
}
if (CollectionUtils.isEmpty(routePaths)) {
// 依然未找到
errMsgMap.put(key, String.format("从[%s]->[%s]无法到达,请检查运行图和联锁数据是否正确",
start.debugStr(), end.debugStr()));
} else {
// 找到保存
log.info(String.format("运行图从[%s]->[%s]没有站间运行数据,根据路径查询找到并生成默认的路径单元",
start.debugStr(), end.debugStr()));
for (RoutePath routePath : routePaths) {
routePath.calculateDistance();
}
routePathMap.put(key, routePaths);
}
}
}
}
}
return new ArrayList<>(errMsgMap.values());
}
// private static List<String> checkRunPlanAndBuildLostRouteUnit(Map<String, List<TripPlan>> serverTripMap,
// Map<String, RouteUnit> routeUnitMap) {
// Map<String, String> errMsgMap = new HashMap<>();
// for (List<TripPlan> tripPlanList : serverTripMap.values()) {
// for (TripPlan tripPlan : tripPlanList) {
// List<Section> allViaSectionList = tripPlan.getAllViaSectionList();
// for (int i = 1; i < allViaSectionList.size(); i++) {
// Section start = allViaSectionList.get(i - 1);
// Section end = allViaSectionList.get(i);
// String key = RouteUnit.buildKey(start, end);
// if (!routeUnitMap.containsKey(key)) {
// // 尝试构建
// List<String> errList = new ArrayList<>();
// RouteUnit routeUnit = InterlockBuilder2.findAndBuildRouteUnit(start, end, tripPlan.isRight(), errList);
// if (Objects.isNull(routeUnit)) {
// // 反向再尝试
// routeUnit = InterlockBuilder2.findAndBuildRouteUnit(start, end, !tripPlan.isRight(), errList);
// }
// if (Objects.nonNull(routeUnit)) {
// log.warn(String.format("运行图从[%s(%s)]到[%s(%s)]没有站间运行数据,根据路径查询找到并生成默认的路径单元",
// start.getName(), start.getCode(), end.getName(), end.getCode()));
// routeUnitMap.put(key, routeUnit);
// } else {
// errMsgMap.put(key, String.format("从[%s(%s)]到[%s(%s)]无法到达,请检查运行图和联锁数据是否正确",
// start.getName(), start.getCode(), end.getName(), end.getCode()));
// }
// }
// }
// }
// }
// return new ArrayList<>(errMsgMap.values());
// }
private static TerminalPlanBuildResult buildTerminalPlan(SimulationDataRepository repository, Map<String, List<TripPlan>> serverTripMap) {
TerminalPlanBuildResult result = new TerminalPlanBuildResult();
List<String> errMsgList = result.getErrMsgList();
Map<String, TerminalDeparturePlan> terminalPlanMap = result.getTerminalPlanMap();
serverTripMap.values().forEach(tripPlanList ->
tripPlanList.forEach(tripPlan -> {
Section startSection = tripPlan.getStartSection();
TerminalDeparturePlan terminalPlan = terminalPlanMap.get(startSection.getCode());
if (Objects.isNull(terminalPlan)) {
terminalPlan = new TerminalDeparturePlan(startSection.getCode());
terminalPlanMap.put(startSection.getCode(), terminalPlan);
}
terminalPlan.addTripPlan(tripPlan);
}));
terminalPlanMap.values().forEach(terminalDeparturePlan ->
terminalDeparturePlan.getPlanList().sort((plan1, plan2) -> {
return plan1.getStartTime().compareTo(plan2.getStartTime());
}));
return result;
}
public static MapConfig buildConfig(RealLineConfigVO configVO) {
MapConfig mapConfig = new MapConfig();
if (Objects.nonNull(configVO)) {
mapConfig.copyConfigBy(configVO);
}
return mapConfig;
}
/**
* 地图基础数据检查和构建
* @param map
* @return
*/
public static SimulationDeviceBuildResult checkAndBuildBasicMapData(MapVO map) {
SimulationDeviceBuildResult mapDataBuildResult = new SimulationDeviceBuildResult();
MapDeviceBuilder.checkAndBuildMapDeviceData(map.getGraphDataNew(), mapDataBuildResult);
return mapDataBuildResult;
}
/**
* 地图数据逻辑检查和构建
*
* @param map
* @return
*/
public static SimulationDeviceBuildResult checkAndBuildMapData(MapVO map) {
SimulationDeviceBuildResult mapDataBuildResult = new SimulationDeviceBuildResult();
MapDeviceBuilder.checkAndBuildMapDeviceData(map.getGraphDataNew(), mapDataBuildResult);
if (CollectionUtils.isEmpty(mapDataBuildResult.getErrMsgList())) { // 基础数据没有问题再构建逻辑数据
// InterlockBuilder.checkAndBuildMapCILogicData(map.getLogicDataNew(), mapDataBuildResult);
InterlockBuilder2.checkAndBuildMapCILogicData(map.getLogicDataNew(), mapDataBuildResult);
List<MapStationParkingTimeVO> parkingTimeList = map.getLogicDataNew().getParkingTimeList();
if (CollectionUtils.isEmpty(parkingTimeList)) {
mapDataBuildResult.errMsgList.add("无停站时间数据");
}
}
return mapDataBuildResult;
}
public static SimulationDeviceBuildResult checkAndBuildMapDeviceData(MapVO map) {
SimulationDeviceBuildResult mapDataBuildResult = new SimulationDeviceBuildResult();
MapDeviceBuilder.checkAndBuildMapDeviceData(map.getGraphDataNew(), mapDataBuildResult);
return mapDataBuildResult;
}
@Getter
public static class TerminalPlanBuildResult {
private Map<String, TerminalDeparturePlan> terminalPlanMap;
private List<String> errMsgList;
public TerminalPlanBuildResult() {
this.terminalPlanMap = new HashMap<>();
this.errMsgList = new ArrayList<>();
}
}
/**
* 地图数据构建结果
*/
@Getter
public static class SimulationDeviceBuildResult {
/**
* 地图设备map
* key-设备code
* val-设备对象
*/
private Map<String, MapElement> deviceMap;
/**
* 虚拟真实设备map
* key-设备code
* val-虚拟真实设备对象
*/
private Map<String, VirtualRealityDevice> vrDeviceMap;
/**
* 目的地码定义map
* key-目的地码code
*/
private Map<String, DestinationCodeDefinition> destinationMap = new HashMap<>();
/**
* 交路列表
*/
@Setter
private List<Routing> routingList;
/**
* 站间运行等级列表
*/
@Setter
private List<StationRunLevel> runLevelList;
// /**
// * 路径单元map
// */
// private Map<String, RouteUnit> routeUnitMap;
/**
* 路径map
*/
private Map<String, List<RoutePath>> routePathMap;
/**
* 接触网map
* key-sectionCode
*/
private Map<String, Set<Catenary>> catenaryMap = new HashMap<>();
private Map<Section,List<Responder>> sectionRespondersMap;
/** 默认停站时间map */
private Map<String, StationParkTime> parkTimeMap = new HashMap<>();
@Setter
Map<String, Set<Section>> sectionArriveNearMap;
Map<Station, List<Section>> parkingTracksMap = new HashMap<>();
/**
* 数据错误信息列表
*/
private List<String> errMsgList;
public SimulationDeviceBuildResult() {
this.deviceMap = new HashMap<>();
this.vrDeviceMap = new HashMap<>();
// this.routeUnitMap = new HashMap<>();
this.routePathMap = new HashMap<>();
this.sectionRespondersMap = new HashMap<>();
this.errMsgList = new ArrayList<>();
}
}
}
package club.joylink.rtss.simulation.cbtc.build;
import club.joylink.rtss.entity.Ibp;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.*;
import club.joylink.rtss.simulation.cbtc.data.plan.TerminalDeparturePlan;
import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan;
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityDevice;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityIbp;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.ibp.IbpData;
import club.joylink.rtss.vo.client.runplan.RunPlanVO;
import club.joylink.rtss.vo.client.schedulingNew.SchedulingPlanNewVO;
import club.joylink.rtss.vo.map.logic.MapStationParkingTimeVO;
import club.joylink.rtss.vo.map.MapVO;
import club.joylink.rtss.vo.map.RealLineConfigVO;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import javax.swing.text.Element;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Slf4j
public class SimulationBuilder {
/**
* 构造仿真对象
*/
public static Simulation build(String group, SimulationBuildParams buildParams) {
Simulation simulation = new Simulation(group);
simulation.setBuildParams(buildParams);
if (Objects.nonNull(buildParams.getLoginUserInfo())) {
simulation.setProject(buildParams.getLoginUserInfo().getProject());
}
// 线路配置参数
simulation.getRepository().setConfig(buildConfig(buildParams.getMap().getConfigVO()));
simulation.getRepository().getConfig()
.setRouteLikeHa1(buildParams.getMap().getGraphDataNew().getGenerateConfig().isLikeHa1());
simulation.getRepository().getConfig()
.setOverlapSettingByTrigger(buildParams.getMap().getGraphDataNew().getGenerateConfig().isOverlapSettingByTrigger());
simulation.getRepository().getConfig()
.setSharingECStations(buildParams.getMap().getGraphDataNew().getGenerateConfig().getSharingECStations());
simulation.getRepository().getConfig()
.setHandleDepot(buildParams.getMap().getGraphDataNew().getGenerateConfig().isHandleDepot());
// 地图数据构建
SimulationDeviceBuildResult mapDataBuildResult = checkAndBuildMapData(buildParams.getMap());
// ibp数据构建
buildIbpData(mapDataBuildResult, buildParams.getMap().getIbpList());
simulation.getRepository().setDeviceMap(mapDataBuildResult.getDeviceMap());
simulation.getRepository().setSectionArriveNearMap(mapDataBuildResult.sectionArriveNearMap);
simulation.getRepository().setVrDeviceMap(mapDataBuildResult.getVrDeviceMap());
// simulation.getRepository().setRouteUnitMap(mapDataBuildResult.getRouteUnitMap());
simulation.getRepository().setRoutePathMap(mapDataBuildResult.getRoutePathMap());
simulation.getRepository().setDestinationMap(mapDataBuildResult.getDestinationMap());
simulation.getRepository().setRoutingList(mapDataBuildResult.getRoutingList());
// simulation.getRepository().setRunLevelList(mapDataBuildResult.getRunLevelList());
simulation.getRepository().getCatenaryMap().putAll(mapDataBuildResult.getCatenaryMap());
simulation.getRepository().getSectionRespondersMap().putAll(mapDataBuildResult.getSectionRespondersMap());
simulation.getRepository().setParkingTracksMap(mapDataBuildResult.getParkingTracksMap());
// simulation.getRepository().setParkTimeMap(mapDataBuildResult.getParkTimeMap());
UserConfigDataBuilder.buildRunLevel(simulation.getRepository(), buildParams.getUserRunLevelList(),
buildParams.getMap(), mapDataBuildResult.getErrMsgList());
UserConfigDataBuilder.buildParkTime(simulation.getRepository(), buildParams.getUserParkTimeList(),
buildParams.getMap(), mapDataBuildResult.getErrMsgList());
if (!CollectionUtils.isEmpty(mapDataBuildResult.getErrMsgList())) { // 存在数据异常
mapDataBuildResult.getErrMsgList().forEach(errMsg -> log.warn(String.format("地图数据异常:%s", errMsg)));
simulation.setMapDataError(true);
simulation.addDataErrMsgs(mapDataBuildResult.getErrMsgList());
}
// 加载运行图
checkAndLoadRunPlan(simulation, buildParams.getRunPlan());
// 加载派班计划
checkAndLoadSchedulingPlan(simulation, buildParams.getSchedulingPlan());
// 加载车辆段route path
loadDepotInOutRoutePath(simulation);
return simulation;
}
/**
* 加载进出depot的route path
*/
private static void loadDepotInOutRoutePath(Simulation simulation) {
final Map<String, List<RoutePath>> srps = simulation.getRepository().getRoutePathMap();
// 仿真车辆段站台停车轨列表
Map<Station, List<Section>> parkingTracksMap = simulation.getRepository().getParkingTracksMap();
if (CollectionUtils.isEmpty(parkingTracksMap)) {
return;
}
parkingTracksMap.forEach((station, secs) -> {
if (station.isDepot()) {// 车站为车辆段
List<Section> transferList = station.getTransferList();// 转换轨列表
if(!CollectionUtils.isEmpty(transferList)) {
transferList.forEach(transSec->{
//停车轨到转换轨
secs.forEach(parkSec->{
final String rpKey=RoutePath.buildKey(parkSec, transSec);
List<RoutePath> nrp=tryFindRoutePathByDirection(parkSec, transSec,10);
List<RoutePath> srp=srps.get(rpKey);
if(null==srp) {
srp=new ArrayList<RoutePath>();
srps.put(rpKey, srp);
}
if(!CollectionUtils.isEmpty(nrp)) {
srp.addAll(nrp);
}
});
//转换轨到停车轨
secs.forEach(parkSec->{
final String rpKey=RoutePath.buildKey(transSec, parkSec);
List<RoutePath> nrp=tryFindRoutePathByDirection(transSec, parkSec,10);
List<RoutePath> srp=srps.get(rpKey);
if(null==srp) {
srp=new ArrayList<RoutePath>();
srps.put(rpKey, srp);
}
if(!CollectionUtils.isEmpty(nrp)) {
srp.addAll(nrp);
}
});
});
}else {
log.info("仿真数据有问题,车辆段[{}]没有转换轨",station.getName());
}
}
});
}
/**
*当方向未知时起点终点不变不同方向搜索route path
*/
private static List<RoutePath> tryFindRoutePathByDirection(Section start, Section end,int iterTimes) {
List<RoutePath> r= CalculateService.queryRoutePathsOnDirection(start, end,true, iterTimes);
if(!CollectionUtils.isEmpty(r)) {
return r;
}else {
return CalculateService.queryRoutePathsOnDirection(start, end,false, iterTimes);
}
}
private static void buildIbpData(SimulationDeviceBuildResult mapDataBuildResult, List<Ibp> ibpList) {
if (CollectionUtils.isEmpty(ibpList))
return;
Map<String, MapElement> deviceMap = mapDataBuildResult.getDeviceMap();
Map<String, VirtualRealityDevice> vrDeviceMap = mapDataBuildResult.getVrDeviceMap();
Map<String, Ibp> ibpMap = ibpList.stream().collect(Collectors.toMap(Ibp::getStationCode, Function.identity()));
List<Station> collect = deviceMap.values().stream()
.filter(element -> MapElement.DeviceType.STATION.equals(element.getDeviceType()))
.map(element -> (Station) element).collect(Collectors.toList());
collect.forEach(station -> {
//构建添加IBP
Ibp ibp = ibpMap.get(station.getCode());
if (ibp == null)
ibp = ibpMap.get(null);
if (ibp != null) {
IbpData ibpData = JsonUtils.read(ibp.getData(), IbpData.class);
VirtualRealityIbp vrIbp = new VirtualRealityIbp(station.getCode() + "_IBP", station.getName() + "_IBP", ibpData, station);
station.setVrIbp(vrIbp);
deviceMap.put(vrIbp.getCode(), vrIbp);
vrDeviceMap.put(vrIbp.getCode(), vrIbp);
}
});
}
private static boolean isOverlapSettingByTrigger(Map<String, MapElement> deviceMap) {
for (MapElement mapElement : deviceMap.values()) {
if (mapElement.getDeviceType().equals(MapElement.DeviceType.OVERLAP)) {
if (!CollectionUtils.isEmpty(((RouteOverlap) mapElement).getTriggerPathList())) {
return true;
} else {
return false;
}
}
}
return false;
}
/**
* 检查并加载派班计划
* @param simulation
* @param schedulingPlan
*/
public static void checkAndLoadSchedulingPlan(Simulation simulation, SchedulingPlanNewVO schedulingPlan) {
if (simulation.isMapDataError() || simulation.isPlanDataError()) {
return;
}
if (Objects.isNull(schedulingPlan)) {
// 如果没有加载计划生成默认的加载计划
if (!simulation.isMapDataError() && simulation.isPlanLoaded() && !simulation.isPlanDataError()) { // 地图数据和运行计划加载成功的情况下
log.info(String.format("地图[%s(%s)]没有派班计划,生成默认派班计划使用",
simulation.getBuildParams().getMap().getName(),
simulation.getBuildParams().getMap().getId()));
SchedulingBuilder.generateSchedulingPlan(simulation);
}
} else {
SchedulingBuilder.loadSchedulingPlan(simulation, schedulingPlan);
}
}
/**
* 检查并加载运行计划
* @param simulation
* @param runPlan
* @return
*/
public static void checkAndLoadRunPlan(Simulation simulation, RunPlanVO runPlan) {
if (simulation.isMapDataError()) {
// 地图逻辑数据有问题不加载
log.info(String.format("仿真地图[%s(%s)]数据有问题,不执行运行计划加载",
simulation.getBuildParams().getMap().getName(),
simulation.getBuildParams().getMap().getId()));
return;
}
if (Objects.nonNull(runPlan)) {
RunPlanBuilder.RunPlanBuildResult runPlanBuildResult =
RunPlanBuilder.buildRunDiagram(simulation.getRepository().getDeviceMap(), runPlan);
simulation.setPlanLoaded(true);
if (!CollectionUtils.isEmpty(runPlanBuildResult.getErrMsgList())) { // 数据异常
runPlanBuildResult.getErrMsgList().forEach(errMsg -> log.warn(String.format("运行图数据异常:%s", errMsg)));
simulation.setPlanDataError(true);
simulation.addDataErrMsgs(runPlanBuildResult.getErrMsgList());
} else {
simulation.getRepository().setServiceTripsMap(runPlanBuildResult.getServerTripMap());
simulation.getRepository().setStandTripMap(runPlanBuildResult.getStandTripMap());
simulation.getRepository().setEndTripMap(runPlanBuildResult.getEndTripMap());
// 校验运行计划和路径单元
List<String> errMsgList = checkRunPlanAndBuildLostRoutePaths(runPlanBuildResult.getServerTripMap(),
simulation.getRepository().getRoutePathMap());
if (!errMsgList.isEmpty()) {
simulation.setMapDataError(true);
simulation.addDataErrMsgs(errMsgList);
}
// // 构建终端发车计划
// TerminalPlanBuildResult terminalPlanBuildResult = buildTerminalPlan(simulation.getRepository(), runPlanBuildResult.getServerTripMap());
// if (!CollectionUtils.isEmpty(terminalPlanBuildResult.getErrMsgList())) {
// simulation.setMapDataError(true);
// simulation.addDataErrMsgs(terminalPlanBuildResult.getErrMsgList());
// } else {
// simulation.getRepository().setTerminalDeparturePlanMap(terminalPlanBuildResult.getTerminalPlanMap());
// }
}
} else {
simulation.addDataErrMsg("运行图为空");
}
}
public static List<String> checkRunPlanAndBuildLostRoutePaths(Map<String, List<TripPlan>> serverTripMap,
Map<String, List<RoutePath>> routePathMap) {
Map<String, String> errMsgMap = new HashMap<>();
for (List<TripPlan> tripPlanList : serverTripMap.values()) {
for (TripPlan tripPlan : tripPlanList) {
List<Section> allViaSectionList = tripPlan.getAllViaStoppedSectionList();
for (int i = 1; i < allViaSectionList.size(); i++) {
Section start = allViaSectionList.get(i - 1);
Section end = allViaSectionList.get(i);
String key = RoutePath.buildKey(start, end);
if (!routePathMap.containsKey(key)) {
// 路径不存在尝试构建
List<RoutePath> routePaths = CalculateService.queryRoutePathsOnDirection(start, end, tripPlan.isRight(), 10);
if (CollectionUtils.isEmpty(routePaths)) {
// 计划方向路径未找到反向尝试
routePaths = CalculateService.queryRoutePathsOnDirection(start, end, !tripPlan.isRight(), 10);
}
if (CollectionUtils.isEmpty(routePaths)) {
// 依然未找到
errMsgMap.put(key, String.format("从[%s]->[%s]无法到达,请检查运行图和联锁数据是否正确",
start.debugStr(), end.debugStr()));
} else {
// 找到保存
log.info(String.format("运行图从[%s]->[%s]没有站间运行数据,根据路径查询找到并生成默认的路径单元",
start.debugStr(), end.debugStr()));
for (RoutePath routePath : routePaths) {
routePath.calculateDistance();
}
routePathMap.put(key, routePaths);
}
}
}
}
}
return new ArrayList<>(errMsgMap.values());
}
// private static List<String> checkRunPlanAndBuildLostRouteUnit(Map<String, List<TripPlan>> serverTripMap,
// Map<String, RouteUnit> routeUnitMap) {
// Map<String, String> errMsgMap = new HashMap<>();
// for (List<TripPlan> tripPlanList : serverTripMap.values()) {
// for (TripPlan tripPlan : tripPlanList) {
// List<Section> allViaSectionList = tripPlan.getAllViaSectionList();
// for (int i = 1; i < allViaSectionList.size(); i++) {
// Section start = allViaSectionList.get(i - 1);
// Section end = allViaSectionList.get(i);
// String key = RouteUnit.buildKey(start, end);
// if (!routeUnitMap.containsKey(key)) {
// // 尝试构建
// List<String> errList = new ArrayList<>();
// RouteUnit routeUnit = InterlockBuilder2.findAndBuildRouteUnit(start, end, tripPlan.isRight(), errList);
// if (Objects.isNull(routeUnit)) {
// // 反向再尝试
// routeUnit = InterlockBuilder2.findAndBuildRouteUnit(start, end, !tripPlan.isRight(), errList);
// }
// if (Objects.nonNull(routeUnit)) {
// log.warn(String.format("运行图从[%s(%s)]到[%s(%s)]没有站间运行数据,根据路径查询找到并生成默认的路径单元",
// start.getName(), start.getCode(), end.getName(), end.getCode()));
// routeUnitMap.put(key, routeUnit);
// } else {
// errMsgMap.put(key, String.format("从[%s(%s)]到[%s(%s)]无法到达,请检查运行图和联锁数据是否正确",
// start.getName(), start.getCode(), end.getName(), end.getCode()));
// }
// }
// }
// }
// }
// return new ArrayList<>(errMsgMap.values());
// }
private static TerminalPlanBuildResult buildTerminalPlan(SimulationDataRepository repository, Map<String, List<TripPlan>> serverTripMap) {
TerminalPlanBuildResult result = new TerminalPlanBuildResult();
List<String> errMsgList = result.getErrMsgList();
Map<String, TerminalDeparturePlan> terminalPlanMap = result.getTerminalPlanMap();
serverTripMap.values().forEach(tripPlanList ->
tripPlanList.forEach(tripPlan -> {
Section startSection = tripPlan.getStartSection();
TerminalDeparturePlan terminalPlan = terminalPlanMap.get(startSection.getCode());
if (Objects.isNull(terminalPlan)) {
terminalPlan = new TerminalDeparturePlan(startSection.getCode());
terminalPlanMap.put(startSection.getCode(), terminalPlan);
}
terminalPlan.addTripPlan(tripPlan);
}));
terminalPlanMap.values().forEach(terminalDeparturePlan ->
terminalDeparturePlan.getPlanList().sort((plan1, plan2) -> {
return plan1.getStartTime().compareTo(plan2.getStartTime());
}));
return result;
}
public static MapConfig buildConfig(RealLineConfigVO configVO) {
MapConfig mapConfig = new MapConfig();
if (Objects.nonNull(configVO)) {
mapConfig.copyConfigBy(configVO);
}
return mapConfig;
}
/**
* 地图基础数据检查和构建
* @param map
* @return
*/
public static SimulationDeviceBuildResult checkAndBuildBasicMapData(MapVO map) {
SimulationDeviceBuildResult mapDataBuildResult = new SimulationDeviceBuildResult();
MapDeviceBuilder.checkAndBuildMapDeviceData(map.getGraphDataNew(), mapDataBuildResult);
return mapDataBuildResult;
}
/**
* 地图数据逻辑检查和构建
*
* @param map
* @return
*/
public static SimulationDeviceBuildResult checkAndBuildMapData(MapVO map) {
SimulationDeviceBuildResult mapDataBuildResult = new SimulationDeviceBuildResult();
MapDeviceBuilder.checkAndBuildMapDeviceData(map.getGraphDataNew(), mapDataBuildResult);
if (CollectionUtils.isEmpty(mapDataBuildResult.getErrMsgList())) { // 基础数据没有问题再构建逻辑数据
// InterlockBuilder.checkAndBuildMapCILogicData(map.getLogicDataNew(), mapDataBuildResult);
InterlockBuilder2.checkAndBuildMapCILogicData(map.getLogicDataNew(), mapDataBuildResult);
List<MapStationParkingTimeVO> parkingTimeList = map.getLogicDataNew().getParkingTimeList();
if (CollectionUtils.isEmpty(parkingTimeList)) {
mapDataBuildResult.errMsgList.add("无停站时间数据");
}
}
return mapDataBuildResult;
}
public static SimulationDeviceBuildResult checkAndBuildMapDeviceData(MapVO map) {
SimulationDeviceBuildResult mapDataBuildResult = new SimulationDeviceBuildResult();
MapDeviceBuilder.checkAndBuildMapDeviceData(map.getGraphDataNew(), mapDataBuildResult);
return mapDataBuildResult;
}
@Getter
public static class TerminalPlanBuildResult {
private Map<String, TerminalDeparturePlan> terminalPlanMap;
private List<String> errMsgList;
public TerminalPlanBuildResult() {
this.terminalPlanMap = new HashMap<>();
this.errMsgList = new ArrayList<>();
}
}
/**
* 地图数据构建结果
*/
@Getter
public static class SimulationDeviceBuildResult {
/**
* 地图设备map
* key-设备code
* val-设备对象
*/
private Map<String, MapElement> deviceMap;
/**
* 虚拟真实设备map
* key-设备code
* val-虚拟真实设备对象
*/
private Map<String, VirtualRealityDevice> vrDeviceMap;
/**
* 目的地码定义map
* key-目的地码code
*/
private Map<String, DestinationCodeDefinition> destinationMap = new HashMap<>();
/**
* 交路列表
*/
@Setter
private List<Routing> routingList;
/**
* 站间运行等级列表
*/
@Setter
private List<StationRunLevel> runLevelList;
// /**
// * 路径单元map
// */
// private Map<String, RouteUnit> routeUnitMap;
/**
* 路径map
*/
private Map<String, List<RoutePath>> routePathMap;
/**
* 接触网map
* key-sectionCode
*/
private Map<String, Set<Catenary>> catenaryMap = new HashMap<>();
private Map<Section,List<Responder>> sectionRespondersMap;
/** 默认停站时间map */
private Map<String, StationParkTime> parkTimeMap = new HashMap<>();
@Setter
Map<String, Set<Section>> sectionArriveNearMap;
Map<Station, List<Section>> parkingTracksMap = new HashMap<>();
/**
* 数据错误信息列表
*/
private List<String> errMsgList;
public SimulationDeviceBuildResult() {
this.deviceMap = new HashMap<>();
this.vrDeviceMap = new HashMap<>();
// this.routeUnitMap = new HashMap<>();
this.routePathMap = new HashMap<>();
this.sectionRespondersMap = new HashMap<>();
this.errMsgList = new ArrayList<>();
}
}
}