From eb56128954d55384b16a1ee1f882a25cc15d55a0 Mon Sep 17 00:00:00 2001 From: xiazengbin Date: Mon, 6 Dec 2021 18:06:01 +0800 Subject: [PATCH] =?UTF-8?q?SimulationBuilder.build=E4=B8=AD=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=8A=A0=E8=BD=BD=E8=BD=A6=E8=BE=86=E6=AE=B5route=20p?= =?UTF-8?q?ath?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cbtc/build/SimulationBuilder.java | 893 ++++++++++-------- 1 file changed, 477 insertions(+), 416 deletions(-) diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java b/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java index 8c2664ca8..efd9fa1f6 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java @@ -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 ibpList) { - if (CollectionUtils.isEmpty(ibpList)) - return; - Map deviceMap = mapDataBuildResult.getDeviceMap(); - Map vrDeviceMap = mapDataBuildResult.getVrDeviceMap(); - Map ibpMap = ibpList.stream().collect(Collectors.toMap(Ibp::getStationCode, Function.identity())); - List 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 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 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 checkRunPlanAndBuildLostRoutePaths(Map> serverTripMap, - Map> routePathMap) { - Map errMsgMap = new HashMap<>(); - for (List tripPlanList : serverTripMap.values()) { - for (TripPlan tripPlan : tripPlanList) { - List
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 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 checkRunPlanAndBuildLostRouteUnit(Map> serverTripMap, -// Map routeUnitMap) { -// Map errMsgMap = new HashMap<>(); -// for (List tripPlanList : serverTripMap.values()) { -// for (TripPlan tripPlan : tripPlanList) { -// List
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 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> serverTripMap) { - TerminalPlanBuildResult result = new TerminalPlanBuildResult(); - List errMsgList = result.getErrMsgList(); - Map 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 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 terminalPlanMap; - - private List errMsgList; - - public TerminalPlanBuildResult() { - this.terminalPlanMap = new HashMap<>(); - this.errMsgList = new ArrayList<>(); - } - } - - /** - * 地图数据构建结果 - */ - @Getter - public static class SimulationDeviceBuildResult { - /** - * 地图设备map - * key-设备code - * val-设备对象 - */ - private Map deviceMap; - - /** - * 虚拟真实设备map - * key-设备code - * val-虚拟真实设备对象 - */ - private Map vrDeviceMap; - - /** - * 目的地码定义map - * key-目的地码code - */ - private Map destinationMap = new HashMap<>(); - - /** - * 交路列表 - */ - @Setter - private List routingList; - - /** - * 站间运行等级列表 - */ - @Setter - private List runLevelList; - -// /** -// * 路径单元map -// */ -// private Map routeUnitMap; - - /** - * 路径map - */ - private Map> routePathMap; - - /** - * 接触网map - * key-sectionCode - */ - private Map> catenaryMap = new HashMap<>(); - - private Map> sectionRespondersMap; - - /** 默认停站时间map */ - private Map parkTimeMap = new HashMap<>(); - - @Setter - Map> sectionArriveNearMap; - - Map> parkingTracksMap = new HashMap<>(); - - /** - * 数据错误信息列表 - */ - private List 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> srps = simulation.getRepository().getRoutePathMap(); + // 仿真车辆段站台停车轨列表 + Map> parkingTracksMap = simulation.getRepository().getParkingTracksMap(); + if (CollectionUtils.isEmpty(parkingTracksMap)) { + return; + } + parkingTracksMap.forEach((station, secs) -> { + if (station.isDepot()) {// 车站为车辆段 + List
transferList = station.getTransferList();// 转换轨列表 + if(!CollectionUtils.isEmpty(transferList)) { + transferList.forEach(transSec->{ + //停车轨到转换轨 + secs.forEach(parkSec->{ + final String rpKey=RoutePath.buildKey(parkSec, transSec); + List nrp=tryFindRoutePathByDirection(parkSec, transSec,10); + List srp=srps.get(rpKey); + if(null==srp) { + srp=new ArrayList(); + srps.put(rpKey, srp); + } + if(!CollectionUtils.isEmpty(nrp)) { + srp.addAll(nrp); + } + }); + //转换轨到停车轨 + secs.forEach(parkSec->{ + final String rpKey=RoutePath.buildKey(transSec, parkSec); + List nrp=tryFindRoutePathByDirection(transSec, parkSec,10); + List srp=srps.get(rpKey); + if(null==srp) { + srp=new ArrayList(); + srps.put(rpKey, srp); + } + if(!CollectionUtils.isEmpty(nrp)) { + srp.addAll(nrp); + } + }); + }); + }else { + log.info("仿真数据有问题,车辆段[{}]没有转换轨",station.getName()); + } + } + }); + } + /** + *当方向未知时,起点终点不变,不同方向搜索route path + */ + private static List tryFindRoutePathByDirection(Section start, Section end,int iterTimes) { + List 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 ibpList) { + if (CollectionUtils.isEmpty(ibpList)) + return; + Map deviceMap = mapDataBuildResult.getDeviceMap(); + Map vrDeviceMap = mapDataBuildResult.getVrDeviceMap(); + Map ibpMap = ibpList.stream().collect(Collectors.toMap(Ibp::getStationCode, Function.identity())); + List 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 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 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 checkRunPlanAndBuildLostRoutePaths(Map> serverTripMap, + Map> routePathMap) { + Map errMsgMap = new HashMap<>(); + for (List tripPlanList : serverTripMap.values()) { + for (TripPlan tripPlan : tripPlanList) { + List
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 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 checkRunPlanAndBuildLostRouteUnit(Map> serverTripMap, +// Map routeUnitMap) { +// Map errMsgMap = new HashMap<>(); +// for (List tripPlanList : serverTripMap.values()) { +// for (TripPlan tripPlan : tripPlanList) { +// List
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 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> serverTripMap) { + TerminalPlanBuildResult result = new TerminalPlanBuildResult(); + List errMsgList = result.getErrMsgList(); + Map 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 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 terminalPlanMap; + + private List errMsgList; + + public TerminalPlanBuildResult() { + this.terminalPlanMap = new HashMap<>(); + this.errMsgList = new ArrayList<>(); + } + } + + /** + * 地图数据构建结果 + */ + @Getter + public static class SimulationDeviceBuildResult { + /** + * 地图设备map + * key-设备code + * val-设备对象 + */ + private Map deviceMap; + + /** + * 虚拟真实设备map + * key-设备code + * val-虚拟真实设备对象 + */ + private Map vrDeviceMap; + + /** + * 目的地码定义map + * key-目的地码code + */ + private Map destinationMap = new HashMap<>(); + + /** + * 交路列表 + */ + @Setter + private List routingList; + + /** + * 站间运行等级列表 + */ + @Setter + private List runLevelList; + +// /** +// * 路径单元map +// */ +// private Map routeUnitMap; + + /** + * 路径map + */ + private Map> routePathMap; + + /** + * 接触网map + * key-sectionCode + */ + private Map> catenaryMap = new HashMap<>(); + + private Map> sectionRespondersMap; + + /** 默认停站时间map */ + private Map parkTimeMap = new HashMap<>(); + + @Setter + Map> sectionArriveNearMap; + + Map> parkingTracksMap = new HashMap<>(); + + /** + * 数据错误信息列表 + */ + private List 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<>(); + } + } +}