Commit 93a8257b07e1965f651722e03e6dbc818ae36fa6

Authored by 娄高锋
2 parents c16fba6e 6fea2a7e

Merge branch 'pudong' of 192.168.168.201:panzhaov5/bsth_control into pudong

src/main/java/com/bsth/data/gpsdata_v2/DataHandleProcess.java
... ... @@ -110,8 +110,6 @@ public class DataHandleProcess {
110 110 logger.error("", e);
111 111 }
112 112 }
113   - } catch (Exception e) {
114   - //logger.error("", e);
115 113 } finally {
116 114 if (count != null)
117 115 count.countDown();
... ...
src/main/java/com/bsth/data/gpsdata_v2/handlers/InStationProcess.java
... ... @@ -61,12 +61,13 @@ public class InStationProcess {
61 61 * @param prev
62 62 */
63 63 private void inStation(GpsEntity gps, GpsEntity prev){
  64 + boolean flow=true;
64 65 //要经过一个中途站才能进
65 66 StationRoute s = GpsCacheData.prevStation(gps);
66 67 List<StationRoute> routes = GeoCacheData.getStationRoute(gps.getLineId(), gps.getUpDown());
67 68 if(routes.size() > 3 && null != s && s.getName().equals(gps.getStation().getName())){
68   - logger.info("没有进中途站,拒绝进场... -" + gps.getNbbm() + " -time:" + gps.getTimestamp());
69   - return;
  69 + logger.info("没有进中途站,拒绝进站... -" + gps.getNbbm() + " -time:" + gps.getTimestamp());
  70 + flow = false;
70 71 }
71 72  
72 73  
... ... @@ -74,7 +75,7 @@ public class InStationProcess {
74 75 boolean isEnd=false;
75 76  
76 77 //进终点
77   - if(null != sch && sch.getZdzCode().equals(gps.getStopNo())){
  78 + if(flow && null != sch && sch.getZdzCode().equals(gps.getStopNo())){
78 79 inEndStation(sch, gps);
79 80 isEnd = true;
80 81 }
... ...
src/main/java/com/bsth/data/gpsdata_v2/handlers/ReverseRouteProcess.java
... ... @@ -48,7 +48,7 @@ public class ReverseRouteProcess {
48 48 int sortNo = gps.getStation().getRouteSort();
49 49 StationRoute prev = GpsCacheData.prevStation(gps);
50 50 //和上一个站点是反向
51   - if(sortNo < prev.getRouteSort()){
  51 + if(null != prev && sortNo < prev.getRouteSort()){
52 52  
53 53 //满足3个进站反向信号
54 54 List<StationRoute> prevs = GpsCacheData.prevMultiStation(gps);
... ...
src/main/resources/application-dev.properties
... ... @@ -8,9 +8,9 @@ spring.jpa.hibernate.naming_strategy= org.hibernate.cfg.ImprovedNamingStrategy
8 8 spring.jpa.database= MYSQL
9 9 spring.jpa.show-sql= false
10 10 spring.datasource.driver-class-name= com.mysql.jdbc.Driver
11   -spring.datasource.url= jdbc:mysql://127.0.0.1/pd_control?useUnicode=true&characterEncoding=utf-8&useSSL=false
  11 +spring.datasource.url= jdbc:mysql://127.0.0.1/control?useUnicode=true&characterEncoding=utf-8&useSSL=false
12 12 spring.datasource.username= root
13   -spring.datasource.password= root
  13 +spring.datasource.password=
14 14  
15 15 #spring.datasource.url= jdbc:mysql://192.168.168.117/pd_control?useUnicode=true&characterEncoding=utf-8&useSSL=false
16 16 #spring.datasource.username= root
... ... @@ -27,8 +27,10 @@ spring.datasource.test-on-return=true
27 27 spring.datasource.test-while-idle=true
28 28 spring.datasource.validation-query=select 1
29 29  
  30 +http.gps.real.cache.url= http://10.10.150.24:12580/realGps/all
30 31 ##
31 32 #222.66.0.204:5555
  33 +http.gps.real.cache.url= http://10.10.150.24:12580/realGps/all
32 34 http.gps.real.url= http://114.80.178.12:18080/transport_server/rtgps/
33 35 ##\u6D88\u606F\u4E0B\u53D1
34 36 #http.send.directive = http://192.168.168.201:9090/transport_server/message/
35 37 \ No newline at end of file
... ...
src/main/resources/logback.xml
... ... @@ -177,11 +177,7 @@
177 177 </pattern>
178 178 </layout>
179 179 </appender>
180   - <logger name="com.bsth.data.gpsdata.thread.GpsDataLoaderThread"
181   - level="INFO" additivity="false">
182   - <appender-ref ref="GPS_COUNT" />
183   - </logger>
184   - <logger name="com.bsth.data.gpsdata.arrival.GpsRealAnalyse"
  180 + <logger name="com.bsth.data.gpsdata_v2"
185 181 level="INFO" additivity="false">
186 182 <appender-ref ref="GPS_COUNT" />
187 183 </logger>
... ...
src/main/resources/static/pages/base/timesmodel/js/v2/ParameterObj.js
... ... @@ -18,7 +18,46 @@ var ParameterObj = function() {
18 18 }
19 19 };
20 20  
  21 + // 计算吃饭时间
  22 + var _fnEatTime = function() {
  23 + var aTime = [];
  24 + // 午饭时间
  25 + aTime.push(
  26 + isNaN(_formMap.workeLunch) || parseInt(_formMap.workeLunch) == 0 ?
  27 + 20 : parseInt(_formMap.workeLunch)
  28 + );
  29 + // 晚饭时间
  30 + aTime.push(
  31 + isNaN(_formMap.workeDinner) || parseInt(_formMap.workeDinner) == 0 ?
  32 + 20 : parseInt(_formMap.workeDinner)
  33 + );
  34 +
  35 + return aTime;
  36 + };
  37 + var _aEatTime;
  38 +
  39 + // 计算吃饭地点
  40 + var _fnEatDir = function() {
  41 + var aEatD = [];
  42 +
  43 + if (_formMap.cfdd != undefined && String(_formMap.cfdd) == "") {
  44 + aEatD = false;
  45 + } else if (parseInt(_formMap.cfdd) == 0) {
  46 + aEatD.push(true);
  47 + } else if (parseInt(_formMap.cfdd) == 1) {
  48 + aEatD.push(false);
  49 + } else if (String(_formMap.cfdd) == "allYes") {
  50 + aEatD.push(true);
  51 + aEatD.push(false);
  52 + }
  53 +
  54 + return aEatD;
  55 + };
  56 + var _aEatDir;
  57 +
  58 +
21 59 // 计算行驶时间对象
  60 + // TODO:暂时获取标准信息,之后改成历史数据,可能需要使用promise封装
22 61 var _travelTimeObj_fun = function() {
23 62 var upMoningPeakTravelTime =
24 63 isNaN(_formMap.earlyUpTime) || parseInt(_formMap.earlyUpTime) == 0 ?
... ... @@ -62,6 +101,34 @@ var ParameterObj = function() {
62 101 };
63 102 var _travelTimeObj;
64 103  
  104 + // 计算上下行进出场时间
  105 + var _inOutTimeObj_fun = function() {
  106 + var upInTime =
  107 + isNaN(_formMap.upInTimer) || parseInt(_formMap.upInTimer) == 0 ?
  108 + 20 : parseInt(_formMap.upInTimer);
  109 + var upOutTime =
  110 + isNaN(_formMap.upOutTimer) || parseInt(_formMap.upOutTimer) == 0 ?
  111 + 20 : parseInt(_formMap.upOutTimer);
  112 + var downInTime =
  113 + isNaN(_formMap.downInTimer) || parseInt(_formMap.downInTimer) == 0 ?
  114 + 20 : parseInt(_formMap.downInTimer);
  115 + var downOutTime =
  116 + isNaN(_formMap.downOutTimer) || parseInt(_formMap.downOutTimer) == 0 ?
  117 + 20 : parseInt(_formMap.downOutTimer);
  118 +
  119 + return [
  120 + { // 上行
  121 + "out": upOutTime,
  122 + "in": upInTime
  123 + },
  124 + { // 下行
  125 + "out": downOutTime,
  126 + "in": downInTime
  127 + }
  128 + ]
  129 + };
  130 + var _inOutTimeObj;
  131 +
65 132 // 计算行驶里程对象
66 133 var _travelLcObj_fun = function() {
67 134 return [
... ... @@ -274,10 +341,16 @@ var ParameterObj = function() {
274 341  
275 342 _validInternal(); // 验证
276 343  
  344 + // 吃饭时间
  345 + _aEatTime = _fnEatTime();
  346 + // 吃饭地点
  347 + _aEatDir = _fnEatDir();
277 348 // 首班车,末班车行驶时间字符串
278 349 _firstLastDepartureTimeStrObj = _firstLastDepartureTimeStrObj_fun();
279 350 // 行驶时间对象
280 351 _travelTimeObj = _travelTimeObj_fun();
  352 + // 上下行进出场时间
  353 + _inOutTimeObj = _inOutTimeObj_fun();
281 354 // 行驶里程对象
282 355 _travelLcObj = _travelLcObj_fun();
283 356 // 时间段划分对象
... ... @@ -342,6 +415,52 @@ var ParameterObj = function() {
342 415 );
343 416 },
344 417  
  418 + //-------------- 获取吃饭时间 ----------------//
  419 + /**
  420 + * 获取午饭时间。
  421 + * @returns int
  422 + */
  423 + fnGetLunchTime: function() {
  424 + _validInternal(); // 验证
  425 + return _aEatTime[0];
  426 + },
  427 + /**
  428 + * 获取晚饭时间。
  429 + * @returns int
  430 + */
  431 + fnGetDinnerTime: function() {
  432 + _validInternal(); // 验证
  433 + return _aEatTime[1];
  434 + },
  435 +
  436 + //-------------- 获取吃饭地点 ----------------//
  437 + /**
  438 + * 是否吃饭。
  439 + * @returns {boolean}
  440 + */
  441 + fnIsEat: function() {
  442 + _validInternal(); // 验证
  443 + return _aEatDir ? true : false;
  444 + },
  445 +
  446 + /**
  447 + * 是否上行吃饭。
  448 + * @returns {boolean}
  449 + */
  450 + fnIsUpEat: function() {
  451 + _validInternal(); // 验证
  452 + return this.fnIsEat() ? _aEatDir[0] : false;
  453 + },
  454 +
  455 + /**
  456 + * 是否上下行都能吃饭。
  457 + * @returns {boolean}
  458 + */
  459 + fnIsBothEat: function() {
  460 + _validInternal(); // 验证
  461 + return (this.fnIsEat() && _aEatDir.length > 1) ? true : false;
  462 + },
  463 +
345 464 //-------------- 获取行驶时间 ----------------//
346 465 /**
347 466 * 获取上行早高峰行驶时间。
... ... @@ -392,6 +511,39 @@ var ParameterObj = function() {
392 511 return _travelTimeObj.trough[1];
393 512 },
394 513  
  514 + /**
  515 + * 获取上行出场时间。
  516 + * @returns int number
  517 + */
  518 + getUpOutTime: function() {
  519 + _validInternal(); // 验证
  520 + return _inOutTimeObj[0].out;
  521 + },
  522 + /**
  523 + * 获取上行进场时间。
  524 + * @returns int number
  525 + */
  526 + getUpInTime: function() {
  527 + _validInternal(); // 验证
  528 + return _inOutTimeObj[0].in;
  529 + },
  530 + /**
  531 + * 获取下行出场时间。
  532 + * @returns int number
  533 + */
  534 + getDownOutTime: function() {
  535 + _validInternal(); // 验证
  536 + return _inOutTimeObj[1].out;
  537 + },
  538 + /**
  539 + * 获取下行进场时间。
  540 + * @returns int number
  541 + */
  542 + getDownInTime: function() {
  543 + _validInternal(); // 验证
  544 + return _inOutTimeObj[1].in;
  545 + },
  546 +
395 547 //---------------- 获取行驶里程 -----------------//
396 548 /**
397 549 * 获取上行normal班次里程。
... ... @@ -578,6 +730,15 @@ var ParameterObj = function() {
578 730 return parseInt(_formMap.jbclcount);
579 731 },
580 732  
  733 + //----------------- 获取保养信息 ------------------//
  734 + /**
  735 + * 获取例保时间。
  736 + */
  737 + getLbTime: function() {
  738 + _validInternal(); // 验证
  739 + return isNaN(_formMap.lb) || parseInt(_formMap.lb) == 0 ? 5 : parseInt(_formMap.lb);
  740 + },
  741 +
581 742 //----------------- 获取关联数据信息 -----------------//
582 743 /**
583 744 * 获取线路id。
... ... @@ -735,163 +896,186 @@ var ParameterObj = function() {
735 896  
736 897 /**
737 898 * 获取固定的停站时间(固定停站时间都是选的最大值)
738   - * @param timeObj 时间对象
739   - * @param isUp 是否上行
740   - * @returns number
  899 + * @param oTimeObj 时间对象
  900 + * @param bIsUp 是否上行
  901 + * @param iXXTime 行驶时间
  902 + * @returns int 停站时间
741 903 */
742   - calcuFixedStopNumber: function(timeObj, isUp) {
  904 + fnCalcuFixedStopNumber: function(oTimeObj, bIsUp, iXXTime) {
743 905 _validInternal(); // 验证
744   - var paramObj = this;
  906 + var oParam = this;
  907 +
  908 + var iPeakStopTime; // 高峰停站时间
  909 + var iTroughStopTime; // 低谷停站时间
  910 + var iSecondaryStopTime; // 副站停站时间
745 911  
746   - var peakStopTime; // 高峰停站时间
747   - var troughStopTime; // 低谷停站时间
748   - var secondaryStopTime; // 副站停站时间
  912 + var iXXTime_temp;
749 913  
750 914 // 双向停站
751   - if (paramObj.isTwoWayStop()) {
752   - if (isUp) { // 上行
753   - if (this.isMPeakBc(timeObj)) { // 早高峰
754   - peakStopTime = Math.floor(paramObj.getUpMPeakTime() * 0.1); // 行驶时间的10%
755   - if (peakStopTime < 3) { // 不少于3分钟
756   - peakStopTime = 3;
  915 + if (oParam.isTwoWayStop()) {
  916 + if (bIsUp) { // 上行
  917 + if (this.isMPeakBc(oTimeObj)) { // 早高峰
  918 + iXXTime_temp = iXXTime == undefined ? oParam.getUpMPeakTime() : iXXTime;
  919 + iPeakStopTime = Math.floor(iXXTime_temp * 0.1); // 行驶时间的10%
  920 + if (iPeakStopTime < 3) { // 不少于3分钟
  921 + iPeakStopTime = 3;
757 922 }
758   - return peakStopTime;
759   - } else if (this.isEPeakBc(timeObj)) { // 晚高峰
760   - peakStopTime = Math.floor(paramObj.getUpEPeakTime() * 0.1); // 行驶时间的10%
761   - if (peakStopTime < 3) { // 不少于3分钟
762   - peakStopTime = 3;
  923 + return iPeakStopTime;
  924 + } else if (this.isEPeakBc(oTimeObj)) { // 晚高峰
  925 + iXXTime_temp = iXXTime == undefined ? oParam.getUpEPeakTime() : iXXTime;
  926 + iPeakStopTime = Math.floor(iXXTime_temp * 0.1); // 行驶时间的10%
  927 + if (iPeakStopTime < 3) { // 不少于3分钟
  928 + iPeakStopTime = 3;
763 929 }
764   - return peakStopTime;
  930 + return iPeakStopTime;
765 931 } else { // 低谷
766   - if (this.isTroughBeforMPeakStartBc(timeObj)) { // 早高峰开始前
767   - troughStopTime = Math.floor(paramObj.getUpTroughTime() * 0.2); // 行驶时间20%
768   - if (troughStopTime < 10) { // 不少于10分钟
769   - troughStopTime = 10;
  932 + if (this.isTroughBeforMPeakStartBc(oTimeObj)) { // 早高峰开始前
  933 + iXXTime_temp = iXXTime == undefined ? oParam.getUpTroughTime() : iXXTime;
  934 + iTroughStopTime = Math.floor(iXXTime_temp * 0.2); // 行驶时间20%
  935 + if (iTroughStopTime < 10) { // 不少于10分钟
  936 + iTroughStopTime = 10;
770 937 }
771   - return troughStopTime;
772   - } else if (this.isTroughAfterEPeakEndBc(timeObj)) { // 晚高峰结束后
773   - troughStopTime = Math.floor(paramObj.getUpTroughTime() * 0.2); // 行驶时间20%
774   - if (troughStopTime < 10) { // 不少于10分钟
775   - troughStopTime = 10;
  938 + return iTroughStopTime;
  939 + } else if (this.isTroughAfterEPeakEndBc(oTimeObj)) { // 晚高峰结束后
  940 + iXXTime_temp = iXXTime == undefined ? oParam.getUpTroughTime() : iXXTime;
  941 + iTroughStopTime = Math.floor(iXXTime_temp * 0.2); // 行驶时间20%
  942 + if (iTroughStopTime < 10) { // 不少于10分钟
  943 + iTroughStopTime = 10;
776 944 }
777   - return troughStopTime;
  945 + return iTroughStopTime;
778 946 } else { // 早高峰,晚高峰之间
779   - troughStopTime = Math.floor(paramObj.getUpTroughTime() * 0.15); // 行驶时间15%
780   - if (troughStopTime < 10) { // 不少于10分钟
781   - troughStopTime = 10;
  947 + iXXTime_temp = iXXTime == undefined ? oParam.getUpTroughTime() : iXXTime;
  948 + iTroughStopTime = Math.floor(iXXTime_temp * 0.15); // 行驶时间15%
  949 + if (iTroughStopTime < 10) { // 不少于10分钟
  950 + iTroughStopTime = 10;
782 951 }
783   - return troughStopTime;
  952 + return iTroughStopTime;
784 953 }
785 954 }
786 955 } else { // 下行
787   - if (this.isMPeakBc(timeObj)) { // 早高峰
788   - peakStopTime = Math.floor(paramObj.getDownMPeakTime() * 0.1); // 行驶时间的10%
789   - if (peakStopTime < 3) { // 不少于3分钟
790   - peakStopTime = 3;
  956 + if (this.isMPeakBc(oTimeObj)) { // 早高峰
  957 + iXXTime_temp = iXXTime == undefined ? oParam.getDownMPeakTime() : iXXTime;
  958 + iPeakStopTime = Math.floor(iXXTime_temp * 0.1); // 行驶时间的10%
  959 + if (iPeakStopTime < 3) { // 不少于3分钟
  960 + iPeakStopTime = 3;
791 961 }
792   - return peakStopTime;
793   - } else if (this.isEPeakBc(timeObj)) { // 晚高峰
794   - peakStopTime = Math.floor(paramObj.getDownEPeakTime() * 0.1); // 行驶时间的10%
795   - if (peakStopTime < 3) { // 不少于3分钟
796   - peakStopTime = 3;
  962 + return iPeakStopTime;
  963 + } else if (this.isEPeakBc(oTimeObj)) { // 晚高峰
  964 + iXXTime_temp = iXXTime == undefined ? oParam.getDownEPeakTime() : iXXTime;
  965 + iPeakStopTime = Math.floor(iXXTime_temp * 0.1); // 行驶时间的10%
  966 + if (iPeakStopTime < 3) { // 不少于3分钟
  967 + iPeakStopTime = 3;
797 968 }
798   - return peakStopTime;
  969 + return iPeakStopTime;
799 970 } else { // 低谷
800   - if (this.isTroughBeforMPeakStartBc(timeObj)) { // 早高峰开始前
801   - troughStopTime = Math.floor(paramObj.getDownTroughTime() * 0.2); // 行驶时间20%
802   - if (troughStopTime < 10) { // 不少于10分钟
803   - troughStopTime = 10;
  971 + if (this.isTroughBeforMPeakStartBc(oTimeObj)) { // 早高峰开始前
  972 + iXXTime_temp = iXXTime == undefined ? oParam.getDownTroughTime() : iXXTime;
  973 + iTroughStopTime = Math.floor(iXXTime_temp * 0.2); // 行驶时间20%
  974 + if (iTroughStopTime < 10) { // 不少于10分钟
  975 + iTroughStopTime = 10;
804 976 }
805   - return troughStopTime;
806   - } else if (this.isTroughAfterEPeakEndBc(timeObj)) { // 晚高峰结束后
807   - troughStopTime = Math.floor(paramObj.getDownTroughTime() * 0.2); // 行驶时间20%
808   - if (troughStopTime < 10) { // 不少于10分钟
809   - troughStopTime = 10;
  977 + return iTroughStopTime;
  978 + } else if (this.isTroughAfterEPeakEndBc(oTimeObj)) { // 晚高峰结束后
  979 + iXXTime_temp = iXXTime == undefined ? oParam.getDownTroughTime() : iXXTime;
  980 + iTroughStopTime = Math.floor(iXXTime_temp * 0.2); // 行驶时间20%
  981 + if (iTroughStopTime < 10) { // 不少于10分钟
  982 + iTroughStopTime = 10;
810 983 }
811   - return troughStopTime;
  984 + return iTroughStopTime;
812 985 } else { // 早高峰,晚高峰之间
813   - troughStopTime = Math.floor(paramObj.getDownTroughTime() * 0.15); // 行驶时间15%
814   - if (troughStopTime < 10) { // 不少于10分钟
815   - troughStopTime = 10;
  986 + iXXTime_temp = iXXTime == undefined ? oParam.getDownTroughTime() : iXXTime;
  987 + iTroughStopTime = Math.floor(iXXTime_temp * 0.15); // 行驶时间15%
  988 + if (iTroughStopTime < 10) { // 不少于10分钟
  989 + iTroughStopTime = 10;
816 990 }
817   - return troughStopTime;
  991 + return iTroughStopTime;
818 992 }
819 993 }
820 994 }
821 995 } else { // 主站停站
822   - if (isUp == paramObj.isUpOneWayStop()) {
823   - if (isUp) { // 上行
824   - if (this.isMPeakBc(timeObj)) { // 早高峰
825   - peakStopTime = Math.floor(paramObj.getUpMPeakTime() * 0.1); // 行驶时间的10%
826   - if (peakStopTime < 3) { // 不少于3分钟
827   - peakStopTime = 3;
  996 + if (bIsUp == oParam.isUpOneWayStop()) {
  997 + if (bIsUp) { // 上行
  998 + if (this.isMPeakBc(oTimeObj)) { // 早高峰
  999 + iXXTime_temp = iXXTime == undefined ? oParam.getUpMPeakTime() : iXXTime;
  1000 + iPeakStopTime = Math.floor(iXXTime_temp * 0.1); // 行驶时间的10%
  1001 + if (iPeakStopTime < 3) { // 不少于3分钟
  1002 + iPeakStopTime = 3;
828 1003 }
829   - return peakStopTime;
830   - } else if (this.isEPeakBc(timeObj)) { // 晚高峰
831   - peakStopTime = Math.floor(paramObj.getUpEPeakTime() * 0.1); // 行驶时间的10%
832   - if (peakStopTime < 3) { // 不少于3分钟
833   - peakStopTime = 3;
  1004 + return iPeakStopTime;
  1005 + } else if (this.isEPeakBc(oTimeObj)) { // 晚高峰
  1006 + iXXTime_temp = iXXTime == undefined ? oParam.getUpEPeakTime() : iXXTime;
  1007 + iPeakStopTime = Math.floor(iXXTime_temp * 0.1); // 行驶时间的10%
  1008 + if (iPeakStopTime < 3) { // 不少于3分钟
  1009 + iPeakStopTime = 3;
834 1010 }
835   - return peakStopTime;
  1011 + return iPeakStopTime;
836 1012 } else { // 低谷
837   - if (this.isTroughBeforMPeakStartBc(timeObj)) { // 早高峰开始前
838   - troughStopTime = Math.floor(paramObj.getUpTroughTime() * 0.2); // 行驶时间20%
839   - if (troughStopTime < 10) { // 不少于10分钟
840   - troughStopTime = 10;
  1013 + if (this.isTroughBeforMPeakStartBc(oTimeObj)) { // 早高峰开始前
  1014 + iXXTime_temp = iXXTime == undefined ? oParam.getUpTroughTime() : iXXTime;
  1015 + iTroughStopTime = Math.floor(iXXTime_temp * 0.2); // 行驶时间20%
  1016 + if (iTroughStopTime < 10) { // 不少于10分钟
  1017 + iTroughStopTime = 10;
841 1018 }
842   - return troughStopTime;
843   - } else if (this.isTroughAfterEPeakEndBc(timeObj)) { // 晚高峰结束后
844   - troughStopTime = Math.floor(paramObj.getUpTroughTime() * 0.2); // 行驶时间20%
845   - if (troughStopTime < 10) { // 不少于10分钟
846   - troughStopTime = 10;
  1019 + return iTroughStopTime;
  1020 + } else if (this.isTroughAfterEPeakEndBc(oTimeObj)) { // 晚高峰结束后
  1021 + iXXTime_temp = iXXTime == undefined ? oParam.getUpTroughTime() : iXXTime;
  1022 + iTroughStopTime = Math.floor(iXXTime_temp * 0.2); // 行驶时间20%
  1023 + if (iTroughStopTime < 10) { // 不少于10分钟
  1024 + iTroughStopTime = 10;
847 1025 }
848   - return troughStopTime;
  1026 + return iTroughStopTime;
849 1027 } else { // 早高峰,晚高峰之间
850   - troughStopTime = Math.floor(paramObj.getUpTroughTime() * 0.15); // 行驶时间15%
851   - if (troughStopTime < 10) { // 不少于10分钟
852   - troughStopTime = 10;
  1028 + iXXTime_temp = iXXTime == undefined ? oParam.getUpTroughTime() : iXXTime;
  1029 + iTroughStopTime = Math.floor(iXXTime_temp * 0.15); // 行驶时间15%
  1030 + if (iTroughStopTime < 10) { // 不少于10分钟
  1031 + iTroughStopTime = 10;
853 1032 }
854   - return troughStopTime;
  1033 + return iTroughStopTime;
855 1034 }
856 1035 }
857 1036 } else { // 下行
858   - if (this.isMPeakBc(timeObj)) { // 早高峰
859   - peakStopTime = Math.floor(paramObj.getDownMPeakTime() * 0.1); // 行驶时间的10%
860   - if (peakStopTime < 3) { // 不少于3分钟
861   - peakStopTime = 3;
  1037 + if (this.isMPeakBc(oTimeObj)) { // 早高峰
  1038 + iXXTime_temp = iXXTime == undefined ? oParam.getDownMPeakTime() : iXXTime;
  1039 + iPeakStopTime = Math.floor(iXXTime_temp * 0.1); // 行驶时间的10%
  1040 + if (iPeakStopTime < 3) { // 不少于3分钟
  1041 + iPeakStopTime = 3;
862 1042 }
863   - return peakStopTime;
864   - } else if (this.isEPeakBc(timeObj)) { // 晚高峰
865   - peakStopTime = Math.floor(paramObj.getDownEPeakTime() * 0.1); // 行驶时间的10%
866   - if (peakStopTime < 3) { // 不少于3分钟
867   - peakStopTime = 3;
  1043 + return iPeakStopTime;
  1044 + } else if (this.isEPeakBc(oTimeObj)) { // 晚高峰
  1045 + iXXTime_temp = iXXTime == undefined ? oParam.getDownEPeakTime() : iXXTime;
  1046 + iPeakStopTime = Math.floor(iXXTime_temp * 0.1); // 行驶时间的10%
  1047 + if (iPeakStopTime < 3) { // 不少于3分钟
  1048 + iPeakStopTime = 3;
868 1049 }
869   - return peakStopTime;
  1050 + return iPeakStopTime;
870 1051 } else { // 低谷
871   - if (this.isTroughBeforMPeakStartBc(timeObj)) { // 早高峰开始前
872   - troughStopTime = Math.floor(paramObj.getDownTroughTime() * 0.2); // 行驶时间20%
873   - if (troughStopTime < 10) { // 不少于10分钟
874   - troughStopTime = 10;
  1052 + if (this.isTroughBeforMPeakStartBc(oTimeObj)) { // 早高峰开始前
  1053 + iXXTime_temp = iXXTime == undefined ? oParam.getDownTroughTime() : iXXTime;
  1054 + iTroughStopTime = Math.floor(iXXTime_temp * 0.2); // 行驶时间20%
  1055 + if (iTroughStopTime < 10) { // 不少于10分钟
  1056 + iTroughStopTime = 10;
875 1057 }
876   - return troughStopTime;
877   - } else if (this.isTroughAfterEPeakEndBc(timeObj)) { // 晚高峰结束后
878   - troughStopTime = Math.floor(paramObj.getDownTroughTime() * 0.2); // 行驶时间20%
879   - if (troughStopTime < 10) { // 不少于10分钟
880   - troughStopTime = 10;
  1058 + return iTroughStopTime;
  1059 + } else if (this.isTroughAfterEPeakEndBc(oTimeObj)) { // 晚高峰结束后
  1060 + iXXTime_temp = iXXTime == undefined ? oParam.getDownTroughTime() : iXXTime;
  1061 + iTroughStopTime = Math.floor(iXXTime_temp * 0.2); // 行驶时间20%
  1062 + if (iTroughStopTime < 10) { // 不少于10分钟
  1063 + iTroughStopTime = 10;
881 1064 }
882   - return troughStopTime;
  1065 + return iTroughStopTime;
883 1066 } else { // 早高峰,晚高峰之间
884   - troughStopTime = Math.floor(paramObj.getDownTroughTime() * 0.15); // 行驶时间15%
885   - if (troughStopTime < 10) { // 不少于10分钟
886   - troughStopTime = 10;
  1067 + iXXTime_temp = iXXTime == undefined ? oParam.getDownTroughTime() : iXXTime;
  1068 + iTroughStopTime = Math.floor(iXXTime_temp * 0.15); // 行驶时间15%
  1069 + if (iTroughStopTime < 10) { // 不少于10分钟
  1070 + iTroughStopTime = 10;
887 1071 }
888   - return troughStopTime;
  1072 + return iTroughStopTime;
889 1073 }
890 1074 }
891 1075 }
892 1076 } else { // 副站停战,2到3分钟
893   - secondaryStopTime = 3;
894   - return secondaryStopTime; // 直接返回3分钟
  1077 + iSecondaryStopTime = 3;
  1078 + return iSecondaryStopTime; // 直接返回3分钟
895 1079 }
896 1080 }
897 1081  
... ... @@ -935,20 +1119,28 @@ var ParameterObj = function() {
935 1119 var paramObj = this;
936 1120  
937 1121 if (isUp) {
938   - if (bcType == "in") {
  1122 + if (bcType == "in_") {
939 1123 return paramObj.getUpInLc();
940 1124 } else if (bcType == "out") {
941 1125 return paramObj.getUpOutLc();
  1126 + } else if (bcType == "bd") {
  1127 + return 0;
  1128 + } else if (bcType == "lc") {
  1129 + return 0;
942 1130 } else {
943 1131 // 基本班次类型,暂时不考虑区间等其他班次类型
944 1132 // 暂时不考虑高峰低谷里程的区分
945 1133 return paramObj.getUpNormalLc();
946 1134 }
947 1135 } else {
948   - if (bcType == "in") {
  1136 + if (bcType == "in_") {
949 1137 return paramObj.getDownInLc();
950 1138 } else if (bcType == "out") {
951 1139 return paramObj.getDownOutLc();
  1140 + } else if (bcType == "bd") {
  1141 + return 0;
  1142 + } else if (bcType == "lc") {
  1143 + return 0;
952 1144 } else {
953 1145 // 基本班次类型,暂时不考虑区间等其他班次类型
954 1146 // 暂时不考虑高峰低谷里程的区分
... ... @@ -969,9 +1161,9 @@ var ParameterObj = function() {
969 1161 var _time = paramObj.getMPeakStartTimeObj();
970 1162 var _zzsj = // 早高峰上行行驶时间+停站时间+早高峰下行行驶时间+停站时间
971 1163 this.calcuTravelTime(_time, true) +
972   - this.calcuFixedStopNumber(_time, true) +
  1164 + this.fnCalcuFixedStopNumber(_time, true) +
973 1165 this.calcuTravelTime(_time, false) +
974   - this.calcuFixedStopNumber(_time, false);
  1166 + this.fnCalcuFixedStopNumber(_time, false);
975 1167 return _zzsj;
976 1168 },
977 1169  
... ... @@ -987,9 +1179,9 @@ var ParameterObj = function() {
987 1179 var _time = this.addMinute(paramObj.getMPeakStartTimeObj(), -1); // 使用任意一个低谷时间
988 1180 var _zzsj = // 低谷上行行驶时间+停站时间+低谷下行行驶时间+停站时间
989 1181 this.calcuTravelTime(_time, true) +
990   - this.calcuFixedStopNumber(_time, true) +
  1182 + this.fnCalcuFixedStopNumber(_time, true) +
991 1183 this.calcuTravelTime(_time, false) +
992   - this.calcuFixedStopNumber(_time, false);
  1184 + this.fnCalcuFixedStopNumber(_time, false);
993 1185  
994 1186 return _zzsj;
995 1187 },
... ...
src/main/resources/static/pages/base/timesmodel/js/v2/core/InternalBcObj.js
... ... @@ -38,10 +38,21 @@ var InternalBcObj = function(
38 38 this._$_qdzid = otherParamObj.qdzid; // 起点站id
39 39 this._$_zdzid = otherParamObj.zdzid; // 终点站id
40 40  
  41 + // 标记参数,这个班次用于计算,最后必须删除
  42 + this._$_bDelFlag = false;
  43 +
41 44 };
42 45  
43 46 //------------------- get/set 方法 -------------------//
44 47  
  48 +InternalBcObj.prototype.fnSetDelFlag = function(bFlag) {
  49 + this._$_bDelFlag = bFlag;
  50 +};
  51 +
  52 +InternalBcObj.prototype.fnIsDelFlag = function() {
  53 + return this._$_bDelFlag;
  54 +};
  55 +
45 56 /**
46 57 * 设置路牌对象。
47 58 * @param lpObj InternalLpObj路牌对象
... ... @@ -72,6 +83,13 @@ InternalBcObj.prototype.getFcTimeObj = function() {
72 83 return this._$_fcsjObj;
73 84 };
74 85 /**
  86 + * 设置发车时间。
  87 + * @param oFcsj
  88 + */
  89 +InternalBcObj.prototype.setFcTimeObj = function(oFcsj) {
  90 + this._$_fcsjObj = oFcsj;
  91 +};
  92 +/**
75 93 * 获取到达时间。
76 94 * @returns {*|moment.Moment}
77 95 */
... ... @@ -79,6 +97,13 @@ InternalBcObj.prototype.getArrTimeObj = function() {
79 97 return this._$_arrtime;
80 98 };
81 99 /**
  100 + * 设置到达时间。
  101 + * @param oTime
  102 + */
  103 +InternalBcObj.prototype.setArrTimeObj = function(oTime) {
  104 + this._$_arrtime = oTime;
  105 +};
  106 +/**
82 107 * 获取班次时间。
83 108 * @returns int
84 109 */
... ... @@ -92,10 +117,43 @@ InternalBcObj.prototype.getBcTime = function() {
92 117 InternalBcObj.prototype.getStopTime = function() {
93 118 return this._$_stoptime;
94 119 };
  120 +/**
  121 + * 设置停站时间。
  122 + * @param t int
  123 + */
  124 +InternalBcObj.prototype.setStopTime = function(t) {
  125 + this._$_stoptime = t;
  126 +};
  127 +
  128 +/**
  129 + * 获取发车顺序号。
  130 + * @returns int
  131 + */
  132 +InternalBcObj.prototype.fnGetFcno = function() {
  133 + return this._$_fcno;
  134 +};
  135 +/**
  136 + * 设置发车顺序号。
  137 + * @param t int
  138 + */
  139 +InternalBcObj.prototype.fnSetFcno = function(t) {
  140 + this._$_fcno = t;
  141 +};
  142 +
  143 +
95 144  
96 145 //---------------------- 其他方法 -------------------------//
97 146  
98 147 /**
  148 + * 给发车时间添加时间。
  149 + * @param num
  150 + */
  151 +InternalBcObj.prototype.addMinuteToFcsj = function(num) {
  152 + this._$_fcsjObj.add(num, "m"); // 发车时间不需要clone
  153 + this._$_arrtime.add(num, "m"); // 到达时间也不需要clone
  154 +};
  155 +
  156 +/**
99 157 * 转换成显示用班次对象。
100 158 * @returns {{}}
101 159 */
... ...
src/main/resources/static/pages/base/timesmodel/js/v2/core/InternalLpObj.js
1   -/**
2   - * 内部路牌对象。
3   - * @constructor
4   - */
5   -var InternalLpObj = function(
6   - orilpObj, // 原始路牌对象
7   - qCount, // 总共多少圈
8   - isUp // 圈是以上行开始还是下行开始
9   -) {
10   - // TODO:原始路牌对象(这个路牌是对接外部gantt图像,以后有机会改了)
11   - this._$$_orign_lp_obj = orilpObj;
12   -
13   - this._$_isUp = isUp;
14   -
15   - // 距离上一个路牌的最小发车间隔时间
16   - // 用于纵向添加班次的时候使用
17   - // 默认第一个路牌为0
18   - this._$_minVerticalIntervalTime = 0;
19   -
20   - // 路牌的圈数,注意每个路牌的圈数都是一致的,
21   - // 但并不是每一圈都有值
22   - // 第1圈从上标线开始
23   - // 第0圈表示中标线的第一个班次组成的半圈
24   - // 有多少圈根据最终迭代的结果来看
25   - this._$_qCount = qCount;
26   - // 保存的是 InternalGroupBcObj 对象
27   - this._$_groupBcArray = new Array(qCount);
28   -
29   - var i;
30   - for (i = 0; i < this._$_qCount; i++) {
31   - this._$_groupBcArray[i] = new InternalGroupObj(
32   - this, this._$_isUp, undefined, undefined);
33   - }
34   -
35   - // 班型的相关变量
36   - this._$_bx_isLb = false; // 是否连班
37   - this._$_bx_isfb = false; // 是否分班
38   - this._$_bx_isfb_5_2 = false; // 是否5休2分班
39   - this._$_bx_desc; // 班型描述(默认为路牌编号)
40   -
41   - // TODO:
42   -
43   -};
44   -
45   -//------------------- get/set 方法 -------------------//
46   -
47   -/**
48   - * 获取圈
49   - * @param qIndex 圈index
50   - */
51   -InternalLpObj.prototype.getGroup = function(qIndex) {
52   - return this._$_groupBcArray[qIndex];
53   -};
54   -
55   -/**
56   - * 获取班次。
57   - * @param qIndex 第几圈
58   - * @param bcIndex 第几个班次
59   - */
60   -InternalLpObj.prototype.getBc = function(qIndex, bcIndex) {
61   - var group = this._$_groupBcArray[qIndex];
62   - var bc;
63   - if (bcIndex == 0) {
64   - bc = group.getBc1();
65   - } else if (bcIndex == 1) {
66   - bc = group.getBc2();
67   - }
68   - return bc;
69   -};
70   -
71   -/**
72   - * 在具体位置设置班次。
73   - * @param qIndex 第几圈
74   - * @param bcIndex 第几个班次
75   - * @param bc 班次对象
76   - */
77   -InternalLpObj.prototype.setBc = function(qIndex, bcIndex, bc) {
78   - var group = this._$_groupBcArray[qIndex];
79   - if (bcIndex == 0) {
80   - group.setBc1(bc);
81   - bc.setGroup(group);
82   - } else if (bcIndex == 1) {
83   - group.setBc2(bc);
84   - bc.setGroup(group);
85   - }
86   -};
87   -
88   -/**
89   - * 设置原始路牌对象。
90   - * @param lpObj 原始路牌对象
91   - */
92   -InternalLpObj.prototype.setLp = function(lpObj) {
93   - this._$$_orign_lp_obj = lpObj;
94   - var i;
95   - var group;
96   - for (i = 0; i < this._$_groupBcArray.length; i++) {
97   - group = this._$_groupBcArray[i];
98   - if (group) {
99   - group.setLp(this); // 圈和班次保存都是 InternalLpObj 对象
100   - }
101   - }
102   -};
103   -
104   -InternalLpObj.prototype.getLpNo = function() {
105   - return this._$$_orign_lp_obj.lpNo;
106   -};
107   -InternalLpObj.prototype.getLpName = function() {
108   - return this._$$_orign_lp_obj.lpName;
109   -};
110   -InternalLpObj.prototype.setBxFb5_2 = function(fb) {
111   - this._$_bx_isfb_5_2 = fb;
112   -};
113   -InternalLpObj.prototype.isBxFb5_2 = function() {
114   - return this._$_bx_isfb_5_2;
115   -};
116   -InternalLpObj.prototype.setBxLb = function(lb) {
117   - this._$_bx_isLb = lb;
118   -};
119   -InternalLpObj.prototype.isBxLb = function() {
120   - return this._$_bx_isLb;
121   -};
122   -
123   -InternalLpObj.prototype.setBxFb = function(fb) {
124   - this._$_bx_isfb = fb;
125   -};
126   -InternalLpObj.prototype.isBxFb = function() {
127   - return this._$_bx_isfb;
128   -};
129   -
130   -/**
131   - * 设置路牌的班型描述(最终是设置班次的路牌名字)。
132   - * @param desc 描述
133   - */
134   -InternalLpObj.prototype.setBxDesc = function(desc) {
135   - // 最终原始路牌的名字
136   - this._$$_orign_lp_obj.lpName = desc + "_" + this._$$_orign_lp_obj.lpNo;
137   - // 内部对象的班型描述
138   - this._$_bx_desc = desc;
139   -};
140   -/**
141   - * 获取版型描述
142   - * @returns string
143   - */
144   -InternalLpObj.prototype.getBxDesc = function() {
145   - return this._$_bx_desc;
146   -};
147   -
148   -/**
149   - * 设置纵向最小发车间隔时间。
150   - * @param v
151   - */
152   -InternalLpObj.prototype.setVerticalMinIntervalTime = function(v) {
153   - // 第一个路牌,都为0
154   - this._$_minVerticalIntervalTime = v;
155   -};
156   -/**
157   - * 获取纵向最小发车间隔时间。
158   - * @returns {number|*}
159   - */
160   -InternalLpObj.prototype.getVerticalMinIntervalTime = function() {
161   - return this._$_minVerticalIntervalTime;
162   -};
163   -
164   -//-------------------- 班次操作方法(查询,统计,删除) -----------------------//
165   -
166   -/**
167   - * 返回总共班次数。
168   - */
169   -InternalLpObj.prototype.getBcCount = function() {
170   - var i;
171   - var group;
172   - var bccount = 0;
173   - for (i = 0; i < this._$_groupBcArray.length; i++) {
174   - group = this._$_groupBcArray[i];
175   - if (group) {
176   - if (group.getBc1()) {
177   - bccount += 1;
178   - }
179   - if (group.getBc2()) {
180   - bccount += 1;
181   - }
182   - }
183   - }
184   -
185   - return bccount;
186   -};
187   -
188   -/**
189   - * 返回班次列表,过滤空的班次,将所有存在的班次连成连续的对象数组返回。
190   - * @returns arrays (InternalBcObj)
191   - */
192   -InternalLpObj.prototype.getBcArray = function() {
193   - var bcArray = [];
194   - var i;
195   - var group;
196   - for (i = 0; i < this._$_groupBcArray.length; i++) {
197   - group = this._$_groupBcArray[i];
198   - if (group) {
199   - group.getBc1() ? bcArray.push(group.getBc1()) : "";
200   - group.getBc2() ? bcArray.push(group.getBc2()) : "";
201   - }
202   - }
203   -
204   - return bcArray;
205   -};
206   -
207   -/**
208   - * 获取最小(最早)班次对象。
209   - * @returns [{圈index},{班次index}]
210   - */
211   -InternalLpObj.prototype.getMinBcObjPosition = function() {
212   - var i;
213   - var bIndex = [];
214   - for (i = 0; i < this._$_groupBcArray.length; i++) {
215   - if (this._$_groupBcArray[i].getBc1()) {
216   - bIndex.push(i);
217   - bIndex.push(0);
218   - break;
219   - }
220   - if (this._$_groupBcArray[i].getBc2()) {
221   - bIndex.push(i);
222   - bIndex.push(1);
223   - break;
224   - }
225   - }
226   - return bIndex;
227   -};
228   -
229   -/**
230   - * 获取最大(最晚)班次对象。
231   - * @returns [{圈index},{班次index}]
232   - */
233   -InternalLpObj.prototype.getMaxBcObjPosition = function() {
234   - var i;
235   - var bIndex = [];
236   - for (i = this._$_groupBcArray.length - 1; i >= 0; i--) {
237   - if (this._$_groupBcArray[i].getBc2()) {
238   - bIndex.push(i);
239   - bIndex.push(1);
240   - break;
241   - }
242   - if (this._$_groupBcArray[i].getBc1()) {
243   - bIndex.push(i);
244   - bIndex.push(0);
245   - break;
246   - }
247   - }
248   - return bIndex;
249   -};
250   -
251   -/**
252   - * 在具体位置移除班次。
253   - * @param qIndex 第几圈
254   - * @param bcIndex 第几个班次
255   - */
256   -InternalLpObj.prototype.removeBc = function(qIndex, bcIndex) {
257   - var group = this._$_groupBcArray[qIndex];
258   - if (bcIndex == 0) {
259   - group.removeBc1();
260   - } else if (bcIndex == 1) {
261   - group.removeBc2();
262   - }
263   -};
264   -
265   -/**
266   - * 使用指定时间匹配返回离之最近的第几圈第几个班次,
267   - * 使用时间差的绝度值,比较,取最小的
268   - * 如果有两个一样的时间差,取比fctime大的时间
269   - * @param fctime 比较用时间
270   - * @param groupArray 圈数组
271   - * @returns [{第几圈},{第几个班次}]
272   - */
273   -InternalLpObj.prototype.getgetQBcIndexWithFcTimeFromGroupArray = function(
274   - fctime, groupArray
275   -) {
276   - var i;
277   - var timediff; // 时间差取绝对值
278   - var qIndex;
279   - var bcIndex;
280   -
281   - var group;
282   - var bc1time;
283   - var bc2time;
284   -
285   - var tempdiff;
286   - for (i = 0; i < this._$_qCount; i++) {
287   - group = groupArray[i];
288   - if (group) {
289   - if (group.getBc1()) {
290   - bc1time = group.getBc1().getFcTimeObj();
291   - tempdiff = Math.abs(bc1time.diff(fctime));
292   -
293   - if (!timediff) {
294   - timediff = Math.abs(tempdiff);
295   - qIndex = i;
296   - bcIndex = 0;
297   - } else {
298   - if (tempdiff < timediff) {
299   - timediff = tempdiff;
300   - qIndex = i;
301   - bcIndex = 0;
302   - } if (Math.abs(tempdiff) == timediff) {
303   - if (bc1time.isBefore(fctime)) {
304   - timediff = tempdiff;
305   - qIndex = i;
306   - bcIndex = 0;
307   - }
308   -
309   - }
310   - }
311   - }
312   -
313   - if (group.getBc2()) {
314   - bc2time = group.getBc2().getFcTimeObj();
315   - tempdiff = Math.abs(bc2time.diff(fctime));
316   -
317   - if (!timediff) {
318   - timediff = Math.abs(tempdiff);
319   - qIndex = i;
320   - bcIndex = 1;
321   - } else {
322   - if (tempdiff < timediff) {
323   - timediff = tempdiff;
324   - qIndex = i;
325   - bcIndex = 1;
326   - } if (Math.abs(tempdiff) == timediff) {
327   - if (bc2time.isBefore(fctime)) {
328   - timediff = tempdiff;
329   - qIndex = i;
330   - bcIndex = 1;
331   - }
332   -
333   - }
334   - }
335   - }
336   - }
337   - }
338   -
339   - var rst = [];
340   - rst.push(qIndex);
341   - rst.push(bcIndex);
342   -
343   - return rst;
344   -};
345   -
346   -/**
347   - * 使用指定时间匹配返回离之最近的第几圈第几个班次,
348   - * 使用时间差的绝度值,比较,取最小的
349   - * 如果有两个一样的时间差,取比fctime大的时间
350   - * @param fctime 比较用时间
351   - * @returns [{第几圈},{第几个班次}]
352   - */
353   -InternalLpObj.prototype.getQBcIndexWithFcTime = function(
354   - fctime
355   -) {
356   - return this.getgetQBcIndexWithFcTimeFromGroupArray(fctime, this._$_groupBcArray);
357   -};
358   -
359   -//---------------------- 内部数据初始化方法(不同于构造函数)---------------------//
360   -
361   -/**
362   - * 从指定开始时间到结束时间创建不间断班次(连班),并初始化路牌
363   - * 注意,之前有班次会删除后再创建。
364   - * @param startTime 开始时间
365   - * @param endTime 结束时间
366   - * @param isUp 第一个班次是上行还是下行
367   - * @param fromQ 从第几圈开始加入
368   - * @param paramObj 参数对象
369   - * @param factory 工厂对象
370   - */
371   -InternalLpObj.prototype.initDataFromTimeToTime = function(
372   - startTime,
373   - endTime,
374   - isUp,
375   - fromQ,
376   - paramObj,
377   - factory) {
378   -
379   - var bcData = []; // 班次数组
380   - var bcObj;
381   - var kssj = startTime;
382   - var fcno = 1; // 发车顺序号
383   - var bcCount = 1; // 班次数
384   - do {
385   - bcObj = factory.createBcObj(
386   - this, "normal", isUp, fcno, kssj, paramObj); // this就是所属路牌对象
387   - bcData.push(bcObj);
388   -
389   - kssj = paramObj.addMinute(kssj, bcObj.getBcTime() + bcObj.getStopTime());
390   - fcno ++;
391   - bcCount ++;
392   - isUp = !isUp;
393   - } while(kssj.isBefore(endTime));
394   - bcCount--;
395   -
396   - if (bcCount > 0 && bcData[bcCount - 1].getArrTimeObj().isAfter(endTime)) {
397   - // 如果最后一个班次的到达时间超过结束时间,也要去除
398   - bcData.splice(bcCount - 1, 1);
399   - }
400   -
401   - this._initDataFromLbBcArray(bcData, fromQ);
402   -
403   -};
404   -
405   -/**
406   - * 使用连班的班次数组初始化路牌(相应的圈会被覆盖)。
407   - * @param bcArray 连班班次数组
408   - * @param fromQ 从第几圈开始加入
409   - */
410   -InternalLpObj.prototype._initDataFromLbBcArray = function(
411   - bcArray,
412   - fromQ
413   -) {
414   - var _bc1Obj;
415   - var _bc2Obj;
416   - var _qObj;
417   -
418   - // 第一班次是上行还是下行
419   - var isUp = bcArray[0].isUp();
420   -
421   - if (bcArray.length > 0 && fromQ < this._$_qCount) {
422   - // 构造圈数
423   - if (isUp != this._$_isUp) {
424   - // 如果方向不一致,意味着第一个班次是半圈
425   - // 加半圈,并加在bc2上
426   - _bc2Obj = bcArray.slice(0, 1)[0];
427   - _qObj = new InternalGroupObj(
428   - this,
429   - this._$_isUp,
430   - undefined,
431   - _bc2Obj
432   - );
433   - _bc2Obj.setGroup(_qObj);
434   - this._$_groupBcArray[fromQ] = _qObj;
435   -
436   - bcArray.splice(0, 1);
437   - fromQ ++;
438   - }
439   -
440   - var qCount1 = Math.floor(bcArray.length / 2); // 需要添加多少圈
441   - var qCount2 = bcArray.length % 2; // 最后是否有半圈
442   -
443   - while (fromQ < this._$_qCount) {
444   - if (qCount1 > 0) {
445   - _bc1Obj = bcArray.slice(0, 1)[0];
446   - _bc2Obj = bcArray.slice(1, 2)[0];
447   - _qObj = new InternalGroupObj(
448   - this,
449   - this._$_isUp,
450   - _bc1Obj,
451   - _bc2Obj
452   - );
453   - _bc1Obj.setGroup(_qObj);
454   - _bc2Obj.setGroup(_qObj);
455   - this._$_groupBcArray[fromQ] = _qObj;
456   -
457   - bcArray.splice(0, 2);
458   - qCount1 --;
459   - } else if (qCount2 > 0) {
460   - // 加半圈,并加在bc1上
461   - _bc1Obj = bcArray.slice(0, 1)[0];
462   - _qObj = new InternalGroupObj(
463   - this,
464   - this._$_isUp,
465   - _bc1Obj,
466   - undefined
467   - );
468   - _bc1Obj.setGroup(_qObj);
469   - this._$_groupBcArray[fromQ] = _qObj;
470   - } else {
471   - break;
472   - }
473   -
474   - fromQ ++;
475   - }
476   - }
477   -};
478   -
479   -//-------------------------- 其他方法 ----------------------------//
480   -
481   -
482   -// TODO
483   -
484   -/**
485   - *
486   - *
487   - */
488   -InternalLpObj.prototype.calcuLpBx = function() {
489   -
490   -};
491   -
492   -
493   -
494   -
495   -
496   -
497   -
  1 +/**
  2 + * 内部路牌对象。
  3 + * @constructor
  4 + */
  5 +var InternalLpObj = function(
  6 + orilpObj, // 原始路牌对象
  7 + qCount, // 总共多少圈
  8 + isUp // 圈是以上行开始还是下行开始
  9 +) {
  10 + // TODO:原始路牌对象(这个路牌是对接外部gantt图像,以后有机会改了)
  11 + this._$$_orign_lp_obj = orilpObj;
  12 +
  13 + this._$_isUp = isUp;
  14 +
  15 + // 路牌的圈数,注意每个路牌的圈数都是一致的,
  16 + // 但并不是每一圈都有值
  17 + // 第1圈从上标线开始
  18 + // 第0圈表示中标线的第一个班次组成的半圈
  19 + // 有多少圈根据最终迭代的结果来看
  20 + this._$_qCount = qCount;
  21 + // 保存的是 InternalGroupBcObj 对象
  22 + this._$_groupBcArray = new Array(qCount);
  23 +
  24 + var i;
  25 + for (i = 0; i < this._$_qCount; i++) {
  26 + this._$_groupBcArray[i] = new InternalGroupObj(
  27 + this, this._$_isUp, undefined, undefined);
  28 + }
  29 +
  30 + // 距离上一个路牌的最小发车间隔时间
  31 + // 用于纵向添加班次的时候使用
  32 + // 默认第一个路牌为0
  33 + this._$_minVerticalIntervalTime = 0;
  34 +
  35 + // 详细记录每圈每个方向上的发车间隔时间
  36 + // 第一维度表示圈数,第二维度表示第一个方向,第二个方向
  37 + // 第一个方向是否上行由 _$_isUp 决定
  38 + // 这里的间隔表示下一个路牌上的班次距离本路牌的班次发车时间间隔
  39 + // 如果当前是最后一个路牌,表示第一个路牌的下一圈同方向班次距离本班次的间隔
  40 + this._$_aVerticalIntervalTime = new Array(this._$_qCount);
  41 + var i;
  42 + for (i = 0; i < this._$_aVerticalIntervalTime.length; i++) {
  43 + this._$_aVerticalIntervalTime[i] = new Array(2);
  44 + }
  45 +
  46 + // 班型的相关变量
  47 + this._$_bx_isLb = false; // 是否连班
  48 + this._$_bx_isfb = false; // 是否分班
  49 + this._$_bx_isfb_5_2 = false; // 是否5休2分班
  50 + this._$_bx_desc; // 班型描述(默认为路牌编号)
  51 +
  52 + // 其他班次(进出场,例包,吃饭等),TODO:以后再拆
  53 + this._$_other_bc_array = [];
  54 +
  55 + // TODO:
  56 +
  57 +};
  58 +
  59 +//------------------- get/set 方法 -------------------//
  60 +
  61 +InternalLpObj.prototype.getOtherBcArray = function() {
  62 + return this._$_other_bc_array;
  63 +};
  64 +InternalLpObj.prototype.addOtherBcArray = function(ba) {
  65 + this._$_other_bc_array = this._$_other_bc_array.concat(ba);
  66 +};
  67 +
  68 +/**
  69 + * 获取圈
  70 + * @param qIndex 圈index
  71 + */
  72 +InternalLpObj.prototype.getGroup = function(qIndex) {
  73 + return this._$_groupBcArray[qIndex];
  74 +};
  75 +
  76 +/**
  77 + * 获取班次。
  78 + * @param qIndex 第几圈
  79 + * @param bcIndex 第几个班次
  80 + */
  81 +InternalLpObj.prototype.getBc = function(qIndex, bcIndex) {
  82 + var group = this._$_groupBcArray[qIndex];
  83 + var bc;
  84 + if (bcIndex == 0) {
  85 + bc = group.getBc1();
  86 + } else if (bcIndex == 1) {
  87 + bc = group.getBc2();
  88 + }
  89 + return bc;
  90 +};
  91 +
  92 +/**
  93 + * 在具体位置设置班次。
  94 + * @param qIndex 第几圈
  95 + * @param bcIndex 第几个班次
  96 + * @param bc 班次对象
  97 + */
  98 +InternalLpObj.prototype.setBc = function(qIndex, bcIndex, bc) {
  99 + var group = this._$_groupBcArray[qIndex];
  100 + if (bcIndex == 0) {
  101 + group.setBc1(bc);
  102 + bc.setGroup(group);
  103 + } else if (bcIndex == 1) {
  104 + group.setBc2(bc);
  105 + bc.setGroup(group);
  106 + }
  107 +};
  108 +
  109 +/**
  110 + * 设置原始路牌对象。
  111 + * @param lpObj 原始路牌对象
  112 + */
  113 +InternalLpObj.prototype.setLp = function(lpObj) {
  114 + this._$$_orign_lp_obj = lpObj;
  115 + var i;
  116 + var group;
  117 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  118 + group = this._$_groupBcArray[i];
  119 + if (group) {
  120 + group.setLp(this); // 圈和班次保存都是 InternalLpObj 对象
  121 + }
  122 + }
  123 +};
  124 +
  125 +InternalLpObj.prototype.getLpNo = function() {
  126 + return this._$$_orign_lp_obj.lpNo;
  127 +};
  128 +InternalLpObj.prototype.getLpName = function() {
  129 + return this._$$_orign_lp_obj.lpName;
  130 +};
  131 +InternalLpObj.prototype.setBxFb5_2 = function(fb) {
  132 + this._$_bx_isfb_5_2 = fb;
  133 +};
  134 +InternalLpObj.prototype.isBxFb5_2 = function() {
  135 + return this._$_bx_isfb_5_2;
  136 +};
  137 +InternalLpObj.prototype.setBxLb = function(lb) {
  138 + this._$_bx_isLb = lb;
  139 +};
  140 +InternalLpObj.prototype.isBxLb = function() {
  141 + return this._$_bx_isLb;
  142 +};
  143 +
  144 +InternalLpObj.prototype.setBxFb = function(fb) {
  145 + this._$_bx_isfb = fb;
  146 +};
  147 +InternalLpObj.prototype.isBxFb = function() {
  148 + return this._$_bx_isfb;
  149 +};
  150 +
  151 +/**
  152 + * 设置路牌的班型描述(最终是设置班次的路牌名字)。
  153 + * @param desc 描述
  154 + */
  155 +InternalLpObj.prototype.setBxDesc = function(desc) {
  156 + // 最终原始路牌的名字
  157 + this._$$_orign_lp_obj.lpName = desc + "_" + this._$$_orign_lp_obj.lpNo;
  158 + // 内部对象的班型描述
  159 + this._$_bx_desc = desc;
  160 +};
  161 +/**
  162 + * 获取版型描述
  163 + * @returns string
  164 + */
  165 +InternalLpObj.prototype.getBxDesc = function() {
  166 + return this._$_bx_desc;
  167 +};
  168 +
  169 +/**
  170 + * 设置纵向最小发车间隔时间。
  171 + * @param v
  172 + */
  173 +InternalLpObj.prototype.setVerticalMinIntervalTime = function(v) {
  174 + // 第一个路牌,都为0
  175 + this._$_minVerticalIntervalTime = v;
  176 +};
  177 +/**
  178 + * 获取纵向最小发车间隔时间。
  179 + * @returns {number|*}
  180 + */
  181 +InternalLpObj.prototype.getVerticalMinIntervalTime = function() {
  182 + return this._$_minVerticalIntervalTime;
  183 +};
  184 +
  185 +/**
  186 + * 设置纵向发车间隔。
  187 + * @param iQindex 圈index
  188 + * @param iBindex 班次index
  189 + * @param iTime 间隔时间
  190 + */
  191 +InternalLpObj.prototype.fnSetVerticalIntervalTime = function(iQindex, iBindex, iTime) {
  192 + this._$_aVerticalIntervalTime[iQindex][iBindex] = iTime;
  193 +};
  194 +
  195 +/**
  196 + * 返回纵向发车间隔。
  197 + * @param iQindex 圈index
  198 + * @param iBindex 班次index
  199 + */
  200 +InternalLpObj.prototype.fnGetVerticalIntervalTime = function(iQindex, iBindex) {
  201 + return this._$_aVerticalIntervalTime[iQindex][iBindex];
  202 +};
  203 +
  204 +//-------------------- 班次操作方法(查询,统计,删除) -----------------------//
  205 +
  206 +/**
  207 + * 返回总共班次数。
  208 + */
  209 +InternalLpObj.prototype.getBcCount = function() {
  210 + var i;
  211 + var group;
  212 + var bccount = 0;
  213 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  214 + group = this._$_groupBcArray[i];
  215 + if (group) {
  216 + if (group.getBc1()) {
  217 + bccount += 1;
  218 + }
  219 + if (group.getBc2()) {
  220 + bccount += 1;
  221 + }
  222 + }
  223 + }
  224 +
  225 + return bccount;
  226 +};
  227 +
  228 +/**
  229 + * 返回班次列表,过滤空的班次,将所有存在的班次连成连续的对象数组返回。
  230 + * @returns arrays (InternalBcObj)
  231 + */
  232 +InternalLpObj.prototype.getBcArray = function() {
  233 + var bcArray = [];
  234 + var i;
  235 + var group;
  236 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  237 + group = this._$_groupBcArray[i];
  238 + if (group) {
  239 + group.getBc1() ? bcArray.push(group.getBc1()) : "";
  240 + group.getBc2() ? bcArray.push(group.getBc2()) : "";
  241 + }
  242 + }
  243 +
  244 + return bcArray;
  245 +};
  246 +
  247 +/**
  248 + * 获取最小(最早)班次对象。
  249 + * @returns [{圈index},{班次index}]
  250 + */
  251 +InternalLpObj.prototype.getMinBcObjPosition = function() {
  252 + var i;
  253 + var bIndex = [];
  254 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  255 + if (this._$_groupBcArray[i].getBc1()) {
  256 + bIndex.push(i);
  257 + bIndex.push(0);
  258 + break;
  259 + }
  260 + if (this._$_groupBcArray[i].getBc2()) {
  261 + bIndex.push(i);
  262 + bIndex.push(1);
  263 + break;
  264 + }
  265 + }
  266 + return bIndex;
  267 +};
  268 +
  269 +/**
  270 + * 获取最大(最晚)班次对象。
  271 + * @returns [{圈index},{班次index}]
  272 + */
  273 +InternalLpObj.prototype.getMaxBcObjPosition = function() {
  274 + var i;
  275 + var bIndex = [];
  276 + for (i = this._$_groupBcArray.length - 1; i >= 0; i--) {
  277 + if (this._$_groupBcArray[i].getBc2()) {
  278 + bIndex.push(i);
  279 + bIndex.push(1);
  280 + break;
  281 + }
  282 + if (this._$_groupBcArray[i].getBc1()) {
  283 + bIndex.push(i);
  284 + bIndex.push(0);
  285 + break;
  286 + }
  287 + }
  288 + return bIndex;
  289 +};
  290 +
  291 +InternalLpObj.prototype.getMinBcObj = function() {
  292 + var i;
  293 + var bcObj;
  294 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  295 + bcObj = this._$_groupBcArray[i].getBc1();
  296 + if (bcObj) {
  297 + break;
  298 + }
  299 + bcObj = this._$_groupBcArray[i].getBc2();
  300 + if (bcObj) {
  301 + break;
  302 + }
  303 + }
  304 + return bcObj;
  305 +};
  306 +InternalLpObj.prototype.getMaxBcObj = function() {
  307 + var i;
  308 + var bcObj;
  309 + for (i = this._$_groupBcArray.length - 1; i >= 0; i--) {
  310 + bcObj = this._$_groupBcArray[i].getBc2();
  311 + if (bcObj) {
  312 + break;
  313 + }
  314 + bcObj = this._$_groupBcArray[i].getBc1();
  315 + if (bcObj) {
  316 + break;
  317 + }
  318 + }
  319 + return bcObj;
  320 +};
  321 +
  322 +/**
  323 + * 获取车次链信息。
  324 + * @param num 第几个车次链
  325 + * @returns object {s_q: {开始圈索引},s_b : {开始班次索引},e_q : {结束圈索引},e_b : {结束班次索引}, bcount : {班次数}}
  326 + */
  327 +InternalLpObj.prototype.fnGetBcChainInfo = function(num) {
  328 + // 计算总的车次链信息
  329 + var aChainInfo = [];
  330 + var oChainInfo;
  331 + var aBcIndex = this.getMinBcObjPosition();
  332 + var oBc;
  333 + var iQIndex;
  334 + var iBcIndex;
  335 + var i;
  336 + var bFlag;
  337 +
  338 + var iBcount = 0;
  339 +
  340 + if (aBcIndex.length == 2) {
  341 + iBcount = 1;
  342 + oChainInfo = {s_q : aBcIndex[0], s_b : aBcIndex[1], e_q : aBcIndex[0], e_b : aBcIndex[1], bcount: 1};
  343 + aChainInfo.push(oChainInfo);
  344 + bFlag = true;
  345 +
  346 + // 下一个班次的索引
  347 + iQIndex = aBcIndex[1] == 0 ? aBcIndex[0] : aBcIndex[0] + 1;
  348 + iBcIndex = aBcIndex[1] == 0 ? 1 : 0;
  349 +
  350 + for (i = iQIndex; i < this._$_qCount; i++) {
  351 + while (iBcIndex <= 1) {
  352 + oBc = this.getBc(i, iBcIndex);
  353 + if (!oBc) {
  354 + if (bFlag) {
  355 + // 车次链结尾是这个班次的前一个班次
  356 + oChainInfo.e_q = iBcIndex == 0 ? i - 1 : i;
  357 + oChainInfo.e_b = iBcIndex == 0 ? 1 : 0;
  358 + oChainInfo.bcount = iBcount;
  359 + }
  360 +
  361 + bFlag = false;
  362 + } else {
  363 + if (bFlag) {
  364 + iBcount ++;
  365 + oChainInfo.bcount = iBcount;
  366 + } else {
  367 + // 下一个车次链开始
  368 + iBcount = 1;
  369 + oChainInfo = {s_q : i, s_b : iBcIndex, e_q : i, e_b : iBcIndex, bcount: 1};
  370 + aChainInfo.push(oChainInfo);
  371 + bFlag = true;
  372 + }
  373 + }
  374 +
  375 +
  376 + iBcIndex ++;
  377 + }
  378 + iBcIndex = 0;
  379 + }
  380 +
  381 + }
  382 +
  383 + return aChainInfo[num];
  384 +};
  385 +
  386 +/**
  387 + * 获取车次链的个数。
  388 + * @returns int
  389 + */
  390 +InternalLpObj.prototype.fnGetBcChainCount = function() {
  391 + var iChainCount = 0;
  392 + var aBcIndex = this.getMinBcObjPosition();
  393 +
  394 + var oBc;
  395 + var iQIndex;
  396 + var iBcIndex;
  397 + var i;
  398 + var bFlag;
  399 +
  400 + if (aBcIndex.length == 2) {
  401 + iChainCount = 1;
  402 + bFlag = true;
  403 +
  404 + // 下一个班次的索引
  405 + iQIndex = aBcIndex[1] == 0 ? aBcIndex[0] : aBcIndex[0] + 1;
  406 + iBcIndex = aBcIndex[1] == 0 ? 1 : 0;
  407 +
  408 + for (i = iQIndex; i < this._$_qCount; i++) {
  409 + while (iBcIndex <= 1) {
  410 + oBc = this.getBc(i, iBcIndex);
  411 + if (!oBc) {
  412 + bFlag = false;
  413 + } else {
  414 + if (bFlag) {
  415 +
  416 + } else {
  417 + iChainCount ++;
  418 + bFlag = true;
  419 + }
  420 + }
  421 +
  422 +
  423 + iBcIndex ++;
  424 + }
  425 + iBcIndex = 0;
  426 + }
  427 +
  428 + }
  429 +
  430 +
  431 + return iChainCount;
  432 +};
  433 +
  434 +/**
  435 + * 在具体位置移除班次。
  436 + * @param qIndex 第几圈
  437 + * @param bcIndex 第几个班次
  438 + */
  439 +InternalLpObj.prototype.removeBc = function(qIndex, bcIndex) {
  440 + var group = this._$_groupBcArray[qIndex];
  441 + if (bcIndex == 0) {
  442 + group.removeBc1();
  443 + } else if (bcIndex == 1) {
  444 + group.removeBc2();
  445 + }
  446 +};
  447 +
  448 +/**
  449 + * 使用指定时间匹配返回离之最近的第几圈第几个班次,
  450 + * 使用时间差的绝度值,比较,取最小的
  451 + * 如果有两个一样的时间差,取比fctime大的时间
  452 + * @param fctime moment 比较用时间
  453 + * @param groupArray 圈数组
  454 + * @param hasUp boolean 计算上行班次
  455 + * @param hasDown boolean 计算下行班次
  456 + * @returns [{第几圈},{第几个班次}]
  457 + */
  458 +InternalLpObj.prototype.getgetQBcIndexWithFcTimeFromGroupArray = function(
  459 + fctime, groupArray, hasUp, hasDown
  460 +) {
  461 + var i;
  462 + var timediff; // 时间差取绝对值
  463 + var qIndex;
  464 + var bcIndex;
  465 +
  466 + var group;
  467 + var bc1time;
  468 + var bc2time;
  469 +
  470 + var tempdiff;
  471 + for (i = 0; i < this._$_qCount; i++) {
  472 + group = groupArray[i];
  473 + if (group) {
  474 + if (group.getBc1() && hasUp) {
  475 + bc1time = group.getBc1().getFcTimeObj();
  476 + tempdiff = Math.abs(bc1time.diff(fctime));
  477 +
  478 + if (!timediff) {
  479 + timediff = Math.abs(tempdiff);
  480 + qIndex = i;
  481 + bcIndex = 0;
  482 + } else {
  483 + if (tempdiff < timediff) {
  484 + timediff = tempdiff;
  485 + qIndex = i;
  486 + bcIndex = 0;
  487 + } if (Math.abs(tempdiff) == timediff) {
  488 + if (bc1time.isBefore(fctime)) {
  489 + timediff = tempdiff;
  490 + qIndex = i;
  491 + bcIndex = 0;
  492 + }
  493 +
  494 + }
  495 + }
  496 + }
  497 +
  498 + if (group.getBc2() && hasDown) {
  499 + bc2time = group.getBc2().getFcTimeObj();
  500 + tempdiff = Math.abs(bc2time.diff(fctime));
  501 +
  502 + if (!timediff) {
  503 + timediff = Math.abs(tempdiff);
  504 + qIndex = i;
  505 + bcIndex = 1;
  506 + } else {
  507 + if (tempdiff < timediff) {
  508 + timediff = tempdiff;
  509 + qIndex = i;
  510 + bcIndex = 1;
  511 + } if (Math.abs(tempdiff) == timediff) {
  512 + if (bc2time.isBefore(fctime)) {
  513 + timediff = tempdiff;
  514 + qIndex = i;
  515 + bcIndex = 1;
  516 + }
  517 +
  518 + }
  519 + }
  520 + }
  521 + }
  522 + }
  523 +
  524 + var rst = [];
  525 + rst.push(qIndex);
  526 + rst.push(bcIndex);
  527 +
  528 + return rst;
  529 +};
  530 +
  531 +/**
  532 + * 使用指定时间匹配返回离之最近的第几圈第几个班次,
  533 + * 使用时间差的绝度值,比较,取最小的
  534 + * 如果有两个一样的时间差,取比fctime大的时间
  535 + * @param fctime moment 比较用时间
  536 + * @param hasUp boolean 计算上行班次
  537 + * @param hasDown boolean 计算下行班次
  538 + * @returns [{第几圈},{第几个班次}]
  539 + */
  540 +InternalLpObj.prototype.getQBcIndexWithFcTime = function(
  541 + fctime, hasUp, hasDown
  542 +) {
  543 + return this.getgetQBcIndexWithFcTimeFromGroupArray(fctime, this._$_groupBcArray, hasUp, hasDown);
  544 +};
  545 +
  546 +//---------------------- 内部数据初始化方法(不同于构造函数)---------------------//
  547 +
  548 +/**
  549 + * 从指定开始时间到结束时间创建不间断班次(连班),并初始化路牌
  550 + * 注意,之前有班次会删除后再创建。
  551 + * @param startTime 开始时间
  552 + * @param endTime 结束时间
  553 + * @param isUp 第一个班次是上行还是下行
  554 + * @param fromQ 从第几圈开始加入
  555 + * @param paramObj 参数对象
  556 + * @param factory 工厂对象
  557 + */
  558 +InternalLpObj.prototype.initDataFromTimeToTime = function(
  559 + startTime,
  560 + endTime,
  561 + isUp,
  562 + fromQ,
  563 + paramObj,
  564 + factory) {
  565 +
  566 + var bcData = []; // 班次数组
  567 + var bcObj;
  568 + var kssj = startTime;
  569 + var fcno = 1; // 发车顺序号
  570 + var bcCount = 1; // 班次数
  571 + do {
  572 + bcObj = factory.createBcObj(
  573 + this, "normal", isUp, fcno, kssj, paramObj); // this就是所属路牌对象
  574 + bcData.push(bcObj);
  575 +
  576 + kssj = paramObj.addMinute(kssj, bcObj.getBcTime() + bcObj.getStopTime());
  577 + fcno ++;
  578 + bcCount ++;
  579 + isUp = !isUp;
  580 + } while(kssj.isBefore(endTime));
  581 + bcCount--;
  582 +
  583 + //console.log("last -1;" + bcData[bcCount -2].getFcTimeObj().format("HH:mm"));
  584 + //console.log("last;" + bcData[bcCount -1].getFcTimeObj().format("HH:mm"));
  585 + //console.log("endtime: " + endTime.format("HH:mm"));
  586 +
  587 + if (bcCount > 0 && bcData[bcCount - 1].getArrTimeObj().isAfter(endTime)) {
  588 + // 如果最后一个班次的到达时间超过结束时间,也要去除
  589 + bcData.splice(bcCount - 1, 1);
  590 + }
  591 +
  592 + this._initDataFromLbBcArray(bcData, fromQ);
  593 +
  594 +};
  595 +
  596 +/**
  597 + * 使用连班的班次数组初始化路牌(相应的圈会被覆盖)。
  598 + * @param bcArray 连班班次数组
  599 + * @param fromQ 从第几圈开始加入
  600 + */
  601 +InternalLpObj.prototype._initDataFromLbBcArray = function(
  602 + bcArray,
  603 + fromQ
  604 +) {
  605 + var _bc1Obj;
  606 + var _bc2Obj;
  607 + var _qObj;
  608 +
  609 + // 第一班次是上行还是下行
  610 + var isUp = bcArray[0].isUp();
  611 +
  612 + if (bcArray.length > 0 && fromQ < this._$_qCount) {
  613 + // 构造圈数
  614 + if (isUp != this._$_isUp) {
  615 + // 如果方向不一致,意味着第一个班次是半圈
  616 + // 加半圈,并加在bc2上
  617 + _bc2Obj = bcArray.slice(0, 1)[0];
  618 + _qObj = new InternalGroupObj(
  619 + this,
  620 + this._$_isUp,
  621 + undefined,
  622 + _bc2Obj
  623 + );
  624 + _bc2Obj.setGroup(_qObj);
  625 + this._$_groupBcArray[fromQ] = _qObj;
  626 +
  627 + bcArray.splice(0, 1);
  628 + fromQ ++;
  629 + }
  630 +
  631 + var qCount1 = Math.floor(bcArray.length / 2); // 需要添加多少圈
  632 + var qCount2 = bcArray.length % 2; // 最后是否有半圈
  633 +
  634 + while (fromQ < this._$_qCount) {
  635 + if (qCount1 > 0) {
  636 + _bc1Obj = bcArray.slice(0, 1)[0];
  637 + _bc2Obj = bcArray.slice(1, 2)[0];
  638 + _qObj = new InternalGroupObj(
  639 + this,
  640 + this._$_isUp,
  641 + _bc1Obj,
  642 + _bc2Obj
  643 + );
  644 + _bc1Obj.setGroup(_qObj);
  645 + _bc2Obj.setGroup(_qObj);
  646 + this._$_groupBcArray[fromQ] = _qObj;
  647 +
  648 + bcArray.splice(0, 2);
  649 + qCount1 --;
  650 + } else if (qCount2 > 0) {
  651 + // 加半圈,并加在bc1上
  652 + _bc1Obj = bcArray.slice(0, 1)[0];
  653 + _qObj = new InternalGroupObj(
  654 + this,
  655 + this._$_isUp,
  656 + _bc1Obj,
  657 + undefined
  658 + );
  659 + _bc1Obj.setGroup(_qObj);
  660 + this._$_groupBcArray[fromQ] = _qObj;
  661 +
  662 + bcArray.splice(0, 1);
  663 + qCount2 --;
  664 + } else {
  665 + break;
  666 + }
  667 +
  668 + fromQ ++;
  669 + }
  670 + }
  671 +};
  672 +
  673 +//-------------------------- 其他方法 ----------------------------//
  674 +
  675 +/**
  676 + * 从指定位置的班次开始,往后所有的班次修正发车时间
  677 + * @param groupIndex
  678 + * @param bcIndex
  679 + * @param time
  680 + */
  681 +InternalLpObj.prototype.fnAddMinuteToBcFcsj = function(groupIndex, bcIndex, time) {
  682 + var i;
  683 + var oCurBc;
  684 +
  685 + // 修正之前班次的停站时间
  686 + //oCurBc = this.getBc(
  687 + // bcIndex == 0 ? groupIndex - 1 : groupIndex,
  688 + // bcIndex == 1 ? 0 : 1
  689 + //);
  690 + //if (oCurBc) {
  691 + // oCurBc.setStopTime(oCurBc.getStopTime() + time);
  692 + //}
  693 +
  694 +
  695 + for (i = groupIndex; i < this._$_qCount; i++) {
  696 + if (bcIndex == 0) {
  697 + oCurBc = this.getBc(i, 0);
  698 + if (oCurBc) {
  699 + oCurBc.addMinuteToFcsj(time);
  700 + }
  701 + oCurBc = this.getBc(i, 1);
  702 + if (oCurBc) {
  703 + oCurBc.addMinuteToFcsj(time);
  704 + }
  705 +
  706 + } else {
  707 + oCurBc = this.getBc(i, 1);
  708 + if (oCurBc) {
  709 + oCurBc.addMinuteToFcsj(time);
  710 + }
  711 +
  712 + }
  713 +
  714 + bcIndex = 0;
  715 + }
  716 +};
  717 +
  718 +/**
  719 + * 在指定位置添加一个吃饭班次。
  720 + * 注1:吃饭班次不是普通班次,不记录进圈,记录进_$_other_bc_array
  721 + * 注2:添加吃饭班次时,会修改之前班次的停战时间,所以导致之后的班次的停战都会发生变化
  722 + * @param groupIndex
  723 + * @param bcIndex
  724 + * @param factory
  725 + * @param paramObj
  726 + * @returns int 相差时间(吃饭时间距离和停站时间相差值)
  727 + */
  728 +InternalLpObj.prototype.fnAddEatBc = function(groupIndex, bcIndex, factory, paramObj) {
  729 + var oPreBc;
  730 + var oEatBc;
  731 + var iBcModifyTime;
  732 + oPreBc = this.getBc( // 前一个邻接班次
  733 + bcIndex == 0 ? groupIndex - 1 : groupIndex,
  734 + bcIndex == 1 ? 0 : 1);
  735 + if (oPreBc) { // 存在前一个班次
  736 + oEatBc = factory.createBcObj(
  737 + this,
  738 + "cf",
  739 + !oPreBc.isUp(), // 和上一个班次方向相反
  740 + 1,
  741 + oPreBc.getArrTimeObj(), // 使用上一个班次的到达时间作为开始时间
  742 + paramObj
  743 + );
  744 +
  745 + //iBcModifyTime = oEatBc.getBcTime() - oPreBc.getStopTime(); // 后续班次要调整的时间
  746 +
  747 + // 修正之后的班次发车时间
  748 + // 注意:之后那个班次发车时间就是吃饭班次的到达时间
  749 + iBcModifyTime = oEatBc.getArrTimeObj().diff(this.getBc(groupIndex, bcIndex).getFcTimeObj(), "m");
  750 + this.fnAddMinuteToBcFcsj(groupIndex, bcIndex, iBcModifyTime);
  751 +
  752 + oPreBc.setStopTime(0);
  753 + this._$_other_bc_array.push(oEatBc);
  754 +
  755 + return iBcModifyTime;
  756 + } else {
  757 + return false;
  758 + }
  759 +
  760 +};
  761 +
  762 +
  763 +// TODO
  764 +
  765 +/**
  766 + *
  767 + *
  768 + */
  769 +InternalLpObj.prototype.calcuLpBx = function() {
  770 +
  771 +};
  772 +
  773 +
... ...
src/main/resources/static/pages/base/timesmodel/js/v2/core/InternalScheduleObj.js
1   -/**
2   - * 内部行车计划对象。
3   - * @constructor
4   - */
5   -var InternalScheduleObj = function(paramObj, lpArray, factory) {
6   - // 参数对象
7   - var _paramObj = paramObj;
8   - // 外部的路牌数组
9   - var _lpArray = lpArray;
10   - // 工厂对象
11   - var _factory = factory;
12   -
13   - //------------------ 初始化方法1,以及计算关联的内部变量 -----------------//
14   - var _qIsUp; // 每一圈是上行开始还是下行开始
15   - var _qCount = 0; // 总的圈数
16   - var _internalLpArray = []; // 内部对象数组
17   -
18   - var _initFun1 = function() { // 初始化方法1
19   -
20   - //----------------------- 1、确定上标线的方向,圈的方向 -------------------//
21   -
22   - // 确定_qIsUp,哪个方向的首班车晚就用哪个
23   - _qIsUp = _paramObj.getUpFirstDTimeObj().isBefore(
24   - _paramObj.getDownFirstDTimeObj()) ? false : true;
25   - // 上标线开始时间,就是方向的首班车时间
26   - var st = _qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();
27   - // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向
28   - var et;
29   - var et_IsUp;
30   - if (_paramObj.getUpLastDtimeObj().isBefore(
31   - _paramObj.getDownLastDTimeObj())) {
32   - et = _paramObj.getDownLastDTimeObj();
33   - et_IsUp = false;
34   - } else {
35   - et = _paramObj.getUpLastDtimeObj();
36   - et_IsUp = true;
37   - }
38   -
39   - //------------------------ 2、计算总共有多少圈 ------------------------//
40   -
41   -
42   -
43   - // 以开始时间,结束时间,构造上标线用连班班次发车时间
44   - var bcFcsjArrays = []; // 班次发车时间对象数组
45   - var bcArsjArrays = []; // 班次到达时间对象数组
46   - var isUp = _qIsUp; // 方向
47   - var bcCount = 1; // 班次数
48   -
49   - var _kssj = st; // 开始时间
50   - var _bcsj = paramObj.calcuTravelTime(_kssj, isUp); // 班次历时
51   - var _arrsj = paramObj.addMinute(_kssj, _bcsj); // 到达时间
52   - var _stoptime = paramObj.calcuFixedStopNumber(_arrsj, !isUp); // 停站时间
53   -
54   - do {
55   - bcFcsjArrays.push(_kssj);
56   - bcArsjArrays.push(_arrsj);
57   - _kssj = paramObj.addMinute(_kssj, _bcsj + _stoptime);
58   - bcCount ++;
59   - isUp = !isUp;
60   - } while(_kssj.isBefore(et));
61   - bcCount--; // 因为先做do,所以总的班次要减1
62   - if (bcCount > 0 && bcArsjArrays[bcCount - 1].isAfter(et)) {
63   - // 如果最后一个班次的到达时间超过结束时间,也要去除
64   - bcFcsjArrays.splice(bcCount - 1, 1);
65   - bcArsjArrays.splice(bcCount - 1, 1);
66   - bcCount--;
67   - }
68   - var _qCount_p1 = Math.floor(bcCount / 2); // 2个班次一圈
69   - var _qCount_p2 = bcCount % 2; // 余下的1个班次也算一圈
70   -
71   - // 利用连班数组计算圈数
72   - _qCount = 1; // 前面加1圈,补中标线的班次
73   - _qCount += _qCount_p1;
74   - _qCount += _qCount_p2;
75   -
76   - // 计算最后是不是还要补一圈
77   - if (_qCount > 1) { // 总的圈数就1圈,没必要加了(其实是不可能的,除非参数里问题)
78   - if (_qCount_p2 == 0) { // 没有余下班次,整数圈数
79   - // 最后一个班次的方向一定和开始的方向相反,如:上-下,上-下,上-下,一共三圈,最后一个班次为下行
80   - // 判定最后一个班次的方向和上标线判定结束时间的班次方向是否一致
81   - if (!_qIsUp == et_IsUp) {
82   - // 一致不用加圈数
83   - } else {
84   - // 不一致需要加圈补最后一个结束时间班次
85   - _qCount ++;
86   - }
87   - } else {
88   - // 有余下的圈数,最后要不补的班次不管上行,下行都在这一圈里
89   - // 不需要在补圈数了
90   - }
91   - }
92   -
93   - //------------------------ 3、根据路牌数,圈数创建路牌对象 ----------------------//
94   -
95   - // 创建内部的路牌数组,并把之前的连班路牌添加进上标线路牌中
96   - var i;
97   - for (i = 0; i < _lpArray.length; i++) {
98   - _internalLpArray.push(new InternalLpObj(_lpArray[i], _qCount, _qIsUp));
99   - }
100   - // 初始化上标线,从第1圈开始
101   - _internalLpArray[0].initDataFromTimeToTime(bcFcsjArrays[0], et, _qIsUp, 1, _paramObj, _factory);
102   -
103   - console.log("//---------------- 行车计划,初始化方法1 start ----------------//");
104   - console.log("上行首班车时间:" + _paramObj.getUpFirstDTimeObj().format("HH:mm") +
105   - "上行末班车时间:" + _paramObj.getUpLastDtimeObj().format("HH:mm"));
106   - console.log("下行首班车时间:" + _paramObj.getDownFirstDTimeObj().format("HH:mm") +
107   - "下行末班车时间:" + _paramObj.getDownLastDTimeObj().format("HH:mm"));
108   - console.log("总共计算的圈数:" + _qCount);
109   - console.log("圈的方向isUP:" + _qIsUp);
110   - console.log("//---------------- 行车计划,初始化方法1 end ----------------//");
111   -
112   - };
113   -
114   - //------------------ 初始化方法2,以及计算关联的内部变量 ----------------//
115   - var _approximate_zgfQIndex; // 预估早高峰车辆从第几圈开始全部发出
116   - var _approximate_zgfBIndex; // 预估早高峰车辆从第几圈第几个班次开始全部发出(上行或下行)
117   - var _approximate_wgfQIndex; // 预估晚高峰车辆从第几圈开始全部发出
118   - var _approximate_wgfBIndex; // 预估晚高峰车辆从第几圈第几个班次开始全部发出(上行或下行)
119   -
120   - // 同一圈同一方向班次发车间隔的最小值
121   - // 注意:这个值就是用来添加班次的时间增加单位,在后面相关的方法里会具体说明
122   - var _qbcMinIntervalValue;
123   -
124   - var _initFun2 = function() { // 初始化方法2
125   - //------------------------ 1、预估早高峰全部出车第几圈第几个班次全部出车,计算路牌之间的发车间隔 ------------------//
126   -
127   - // 以上标线为标准,查找离早高峰开始时间最近的班次作为早高峰开始班次
128   - // 以这个班次为早高峰起点,全部出车策略
129   - var qbcIndexArray = _internalLpArray[0].getQBcIndexWithFcTime(
130   - _paramObj.getMPeakStartTimeObj());
131   - var qIndex = qbcIndexArray[0]; // 第几圈
132   - var bIndex = qbcIndexArray[1]; // 第几个班次
133   - var startbc = _internalLpArray[0].getBc(qIndex, bIndex);
134   -
135   - // 计算早高峰
136   - var _clCount = _paramObj.calcuClzx();
137   - var _c1 = Math.floor(_paramObj.calcuPeakZzsj() / _clCount);
138   - var _c2 = _paramObj.calcuPeakZzsj() % _clCount;
139   - var _kssj = startbc.getFcTimeObj();
140   -
141   - var i;
142   - for (i = 2; i <= _clCount - _c2; i++) {
143   - _kssj = _paramObj.addMinute(_kssj, _c1);
144   - _internalLpArray[i - 1].setBc(
145   - qIndex,
146   - bIndex,
147   - _factory.createBcObj(
148   - _internalLpArray[i - 1],
149   - "normal", startbc.isUp(),
150   - 1, _kssj, paramObj)
151   - );
152   - // 使用早高峰的发车间隔最为路牌纵向最小发车间隔,不能整除的话,小的放在前面的路牌
153   - _internalLpArray[i - 1].setVerticalMinIntervalTime(_c1);
154   - }
155   - for (i = 1; i <= _c2; i++) {
156   - _kssj = _paramObj.addMinute(_kssj, _c1 + 1);
157   - _internalLpArray[_clCount - _c2 + i - 1].setBc(
158   - qIndex,
159   - bIndex,
160   - _factory.createBcObj(
161   - _internalLpArray[_clCount - _c2 + i - 1],
162   - "normal", startbc.isUp(),
163   - 1, _kssj, paramObj)
164   - );
165   - // 使用早高峰的发车间隔最为路牌纵向最小发车间隔,,不能整除的话,大的放在后面的路牌
166   - _internalLpArray[_clCount - _c2 + i - 1].setVerticalMinIntervalTime(_c1);
167   - }
168   -
169   - _approximate_zgfQIndex = qIndex;
170   - _approximate_zgfBIndex = bIndex;
171   -
172   - //------------------------ 2、预估晚高峰全部出车第几圈第几个班次全部出车,计算路牌之间的发车间隔 ------------------//
173   -
174   - // 以上标线为标准,查找离晚高峰开始时间最近的班次作为晚高峰开始班次
175   - // 以这个班次为早高峰起点,全部出车策略
176   - qbcIndexArray = _internalLpArray[0].getQBcIndexWithFcTime(
177   - _paramObj.getEPeakStartTimeObj());
178   - qIndex = qbcIndexArray[0]; // 第几圈
179   - bIndex = qbcIndexArray[1]; // 第几个班次
180   - startbc = _internalLpArray[0].getBc(qIndex, bIndex);
181   -
182   - // 计算晚高峰
183   - _clCount = _paramObj.calcuClzx();
184   - _c1 = Math.floor(_paramObj.calcuPeakZzsj() / _clCount);
185   - _c2 = _paramObj.calcuPeakZzsj() % _clCount;
186   - _kssj = startbc.getFcTimeObj();
187   -
188   - for (i = 2; i <= _clCount - _c2; i++) {
189   - _kssj = _paramObj.addMinute(_kssj, _c1);
190   - _internalLpArray[i - 1].setBc(
191   - qIndex,
192   - bIndex,
193   - _factory.createBcObj(
194   - _internalLpArray[i - 1],
195   - "normal", startbc.isUp(),
196   - 1, _kssj, _paramObj)
197   - );
198   - }
199   - for (i = 1; i <= _c2; i++) {
200   - _kssj = _paramObj.addMinute(_kssj, _c1 + 1);
201   - _internalLpArray[_clCount - _c2 + i - 1].setBc(
202   - qIndex,
203   - bIndex,
204   - _factory.createBcObj(
205   - _internalLpArray[_clCount - _c2 + i - 1],
206   - "normal", startbc.isUp(),
207   - 1, _kssj, _paramObj)
208   - );
209   - }
210   -
211   - _approximate_wgfQIndex = qIndex;
212   - _approximate_wgfBIndex = bIndex;
213   - _qbcMinIntervalValue = _c1;
214   -
215   - console.log("//---------------- 行车计划,初始化方法2 start ----------------//");
216   - console.log("预估早高峰第" + _approximate_zgfQIndex + "(index)圈,第" + _approximate_zgfBIndex + "(index)班次车辆全部发出");
217   - console.log("预估晚高峰第" + _approximate_wgfQIndex + "(index)圈,第" + _approximate_wgfBIndex + "(index)班次车辆全部发出");
218   - console.log("预估同圈同方向班次最小间隔(分钟):" + _qbcMinIntervalValue);
219   - console.log("//---------------- 行车计划,初始化方法2 end ----------------//");
220   - };
221   -
222   - //----------------------- 初始化方法3,以及计算关联的内部变量 ----------------//
223   - var _zbx_lpIndex; // 中标线对应第几个路牌
224   -
225   - var _initFun3 = function() { // 初始化方法3
226   - //---------------------------- 1、模拟一个中标线,使用临时路牌 ----------------------//
227   -
228   - // 构造中标线
229   - // 中标线开始时间,就是方向的首班车时间
230   - var st = !_qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();
231   - // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向
232   - // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向
233   - var et;
234   - if (_paramObj.getUpLastDtimeObj().isBefore(
235   - _paramObj.getDownLastDTimeObj())) {
236   - et = _paramObj.getDownLastDTimeObj();
237   - } else {
238   - et = _paramObj.getUpLastDtimeObj();
239   - }
240   -
241   - var tempLpObj = new InternalLpObj({lpNo: -999, lpName: "-999"}, _qCount, _qIsUp);
242   - tempLpObj.initDataFromTimeToTime(
243   - st,
244   - et,
245   - !_qIsUp,
246   - 0,
247   - _paramObj,
248   - _factory
249   - );
250   -
251   - //------------------------ 2、找出中标线的早高峰班次,计算应该插在当前路牌数组的那个位置 ----------------//
252   - // TODO:中标线的早高峰发车班次,和插入位置的早高分班次的时间会有误差的
253   - // TODO:这里是直接把中标线班次覆盖,没有根据误差调整,以后改
254   -
255   - // 找出中标线对应的早高峰的班次对象
256   - var _zb_bcobj = tempLpObj.getBc(_approximate_zgfQIndex, _approximate_zgfBIndex);
257   -
258   - // 把所有高峰班次重新构造成一个一个的圈数组,计算对应中标线最近的是第几个路牌
259   - var _tempq_array = [];
260   - var _temp_group;
261   - var _temp_bc;
262   - var i;
263   - for (i = 0; i < _internalLpArray.length; i++) {
264   - _temp_bc = _internalLpArray[i].getBc(_approximate_zgfQIndex, _approximate_zgfBIndex);
265   - if (_temp_bc.isUp() == _qIsUp) {
266   - _temp_group = new InternalGroupObj(_internalLpArray[i], _qIsUp, _temp_bc, undefined);
267   - } else {
268   - _temp_group = new InternalGroupObj(_internalLpArray[i], _qIsUp, undefined, _temp_bc);
269   - }
270   - _tempq_array.push(_temp_group);
271   - }
272   -
273   - var _ttindex_ = tempLpObj.getgetQBcIndexWithFcTimeFromGroupArray(
274   - _zb_bcobj.getFcTimeObj(),
275   - _tempq_array
276   - );
277   - _zbx_lpIndex = _ttindex_[0]; // 中标线放在第几个路牌
278   - tempLpObj.setLp(_lpArray[_zbx_lpIndex]); // 设置原始路牌对象
279   - tempLpObj.setVerticalMinIntervalTime( // 设置纵向最小发车间隔
280   - _internalLpArray[_zbx_lpIndex].getVerticalMinIntervalTime()
281   - );
282   -
283   - // 注意:这里直接把中标线数据替换到指定路牌位置
284   - // TODO:由初始化方法1,初始化方法2得到的2个高峰的班次会被中标线对应班次覆盖
285   - // TODO:目前使用中标线的班次覆盖,以后相互动态调整
286   -
287   - _internalLpArray[_zbx_lpIndex] = tempLpObj;
288   -
289   - console.log("//---------------- 行车计划,初始化方法3 start ----------------//");
290   - console.log("中标线对应第" + (_zbx_lpIndex + 1) + "个路牌");
291   - console.log("//---------------- 行车计划,初始化方法3 end ----------------//");
292   -
293   - };
294   -
295   - //----------------------- 初始化方法4,以及计算关联的内部变量 ----------------//
296   - var _bx_lb_lpcount; // 连班路牌数
297   - var _bx_5_2_fb_lpcount; // 5休2分班路牌数
298   - var _bx_other_fb_lpcount; // 其他分班路牌数
299   -
300   - var _initFun4 = function() { // 初始化方法4
301   - // 总共车辆数(高峰最大车辆数)
302   - var cls = _paramObj.calcuClzx();
303   - // 低谷最少配车(连班车数量)
304   - var dgminpc = Math.round(_paramObj.calcuTroughZzsj() / _paramObj.getTroughMaxFcjx());
305   - // 加班车路牌数(做5休2的路牌数)
306   - var _5_2_lpes = _paramObj.getJBLpes();
307   -
308   - // 做些简单的验证
309   - if (cls < dgminpc) {
310   - alert("总配车数小于低谷最小配车");
311   - throw "总配车数小于低谷最小配车";
312   - }
313   - if (dgminpc < 2) {
314   - alert("连班路牌小于2,办不到啊");
315   - throw "连班路牌小于2,办不到啊";
316   - }
317   - if (cls - dgminpc < _5_2_lpes) {
318   - alert("总分班路牌数小于加班路牌数");
319   - throw "总分班路牌数小于加班路牌数";
320   - }
321   -
322   - _bx_lb_lpcount = dgminpc;
323   - _bx_5_2_fb_lpcount = _5_2_lpes;
324   - _bx_other_fb_lpcount = cls - dgminpc - _5_2_lpes;
325   -
326   - console.log("//---------------- 行车计划,初始化方法4 start ----------------//");
327   - console.log("连班路牌数:" + _bx_lb_lpcount);
328   - console.log("5休2分班路牌数:" + _bx_5_2_fb_lpcount);
329   - console.log("其他分班路牌数:" + _bx_other_fb_lpcount);
330   - console.log("//---------------- 行车计划,初始化方法4 end ----------------//");
331   - };
332   -
333   - //-------------------- 重要的内部方法 -----------------------//
334   - /**
335   - * 在指定位置生成班次(内部重要方法)。
336   - * @param lpIndex 第几个路牌
337   - * @param qIndex 第几圈
338   - * @param bcIndex 第几个班次
339   - * @returns InternalBcObj
340   - */
341   - var _generateBc = function(lpIndex, qIndex, bcIndex) {
342   - // 在初始化布局后使用,否则没有参照班次加不了
343   - // 初始化布局后,相当于把时刻表比作一个围棋棋盘,行为路牌数,列为圈数
344   - // 上标线,中标线,早晚高峰已经布局在棋盘上,其余的空格可以创建班次
345   -
346   - // 这个生成班次是以上一班次时间,以发车间隔为基础添加的,纵向加
347   - // 和生成标线时那种一直往后加班次时不一样,那种是以前一个班次为基础,横向加
348   -
349   - // 1、生成的班次以同一圈同一个方向里离它最早的班次的发车时间为基础
350   - // 2、以每个路牌的纵向最小发车间隔时间为计算发车间隔
351   - // 3、如果班次发车时间越界不管,有其余方法排除这种情况
352   -
353   - // 1、查找同圈同方向里最近的班次,找不到报错(因为有标线存在是不可能找不到的)
354   - var _i;
355   - var _bcObj;
356   - for (_i = lpIndex - 1; _i >= 0; _i--) {
357   - _bcObj = _internalLpArray[_i].getBc(qIndex, bcIndex);
358   - if (_bcObj) {
359   - break;
360   - }
361   - }
362   - if (!_bcObj) {
363   - return false;
364   - //alert("无法在指定位置生成班次");
365   - //throw "无法在路牌index=" + lpIndex + ",圈index=" + qIndex + ",班次index=" + bcIndex + "生成班次";
366   - }
367   -
368   - // 2、计算发车间隔
369   - var _intervalTime = 0;
370   - for (_i = _i + 1; _i <= lpIndex; _i++) {
371   - _intervalTime += _internalLpArray[_i].getVerticalMinIntervalTime();
372   - }
373   -
374   - // 3、计算班次并添加班次
375   - var _kssj = _paramObj.addMinute(_bcObj.getFcTimeObj(), _intervalTime);
376   - _bcObj = _factory.createBcObj(
377   - _internalLpArray[lpIndex],
378   - "normal", _bcObj.isUp(),
379   - 1, _kssj, _paramObj);
380   - _bcObj.setGroup(_internalLpArray[lpIndex].getGroup(qIndex));
381   -
382   - return _bcObj;
383   -
384   - // TODO:这种添加班次的方法,可能造成相邻班次的停站时间问题
385   - // TODO:主要是由于中标线的问题,但是误差不会很大,
386   - // TODO:后面有方法直接调整停站时间(所谓的平滑过度时间)
387   - };
388   -
389   - /**
390   - * 在指定位置生成班次并添加到路牌指定位置中。
391   - * @param lpIndex 第几个路牌
392   - * @param qIndex 第几圈
393   - * @param bcIndex 第几个班次
394   - */
395   - var _generateBcAndSetBc = function(lpIndex, qIndex, bcIndex) {
396   - var _bcObj = _generateBc(lpIndex, qIndex, bcIndex);
397   - _internalLpArray[lpIndex].setBc(qIndex, bcIndex, _bcObj);
398   -
399   - };
400   -
401   - /**
402   - * 查找离指定时间最近的前面的班次索引信息
403   - * @param timeObj 查找时间
404   - * @param isUp 是否上行
405   - * @returns [{路牌index},{圈index},{班次index}]
406   - */
407   - var _findUpClosedBcIndexWithTime = function(timeObj, isUp) {
408   - var _lpObj;
409   - var _groupObj;
410   - var _bcObj;
411   - var _i;
412   - var _j;
413   - var timediff; // 时间差取绝对值
414   -
415   - var _lpIndex;
416   - var _up_qIndex;
417   - var _up_bIndex;
418   -
419   - for (_i = 0; _i < _qCount; _i++) {
420   - for (_j = 0; _j < _internalLpArray.length; _j++) {
421   - _lpObj = _internalLpArray[_j];
422   - _groupObj = _lpObj.getGroup(_i);
423   - _bcObj = isUp ? _groupObj.getBc1() : _groupObj.getBc2();
424   - if (!_bcObj) { // 没有班次动态生成一个,可能生成不出的
425   - _bcObj = _generateBc(_j, _i, isUp == _qIsUp ? 0 : 1);
426   - }
427   - if (_bcObj) {
428   - if (timeObj.diff(_bcObj.getFcTimeObj()) >= 0) {
429   - if (!timediff) {
430   - timediff = timeObj.diff(_bcObj.getFcTimeObj());
431   - _lpIndex = _j;
432   - _up_qIndex = _i;
433   - _up_bIndex = isUp == _qIsUp ? 0 : 1;
434   - } else {
435   - if (timeObj.diff(_bcObj.getFcTimeObj()) < timediff) {
436   - timediff = timeObj.diff(_bcObj.getFcTimeObj());
437   - _lpIndex = _j;
438   - _up_qIndex = _i;
439   - _up_bIndex = isUp == _qIsUp ? 0 : 1;
440   - }
441   - }
442   - }
443   - }
444   - }
445   - }
446   -
447   - if (_lpIndex == undefined) {
448   - return false;
449   - }
450   -
451   - var bcindex = [];
452   - bcindex.push(_lpIndex);
453   - bcindex.push(_up_qIndex);
454   - bcindex.push(_up_bIndex);
455   -
456   - return bcindex;
457   - };
458   -
459   - /**
460   - * 查找离指定时间最近的后面的班次索引信息
461   - * @param timeObj 查找时间
462   - * @param isUp 是否上行
463   - * @returns [{路牌index},{圈index},{班次index}]
464   - */
465   - var _findDownClosedBcIndexWithTime = function(timeObj, isUp) {
466   - var _lpObj;
467   - var _groupObj;
468   - var _bcObj;
469   - var _i;
470   - var _j;
471   - var timediff; // 时间差取绝对值
472   -
473   - var _lpIndex;
474   - var _down_qIndex;
475   - var _down_bIndex;
476   -
477   - var flag;
478   -
479   - for (_i = 0; _i < _qCount; _i++) {
480   - for (_j = 0; _j < _internalLpArray.length; _j++) {
481   - _lpObj = _internalLpArray[_j];
482   - _groupObj = _lpObj.getGroup(_i);
483   - _bcObj = isUp ? _groupObj.getBc1() : _groupObj.getBc2();
484   - if (!_bcObj) { // 没有班次动态生成一个,可能生成不出的
485   - _bcObj = _generateBc(_j, _i, isUp == _qIsUp ? 0 : 1);
486   - }
487   - if (_bcObj) {
488   - //console.log("timeobj -> bcobj diff flag " +
489   - // timeObj.format("HH:mm") + "->" +
490   - // _bcObj.getFcTimeObj().format("HH:mm") +
491   - // timeObj.diff(_bcObj.getFcTimeObj()) +
492   - // (timeObj.diff(_bcObj.getFcTimeObj()) <= 0)
493   - //);
494   -
495   - flag = (timeObj.diff(_bcObj.getFcTimeObj())) <= 0;
496   -
497   - if (flag) {
498   - if (!timediff) {
499   - timediff = timeObj.diff(_bcObj.getFcTimeObj());
500   - _lpIndex = _j;
501   - _down_qIndex = _i;
502   - _down_bIndex = isUp == _qIsUp ? 0 : 1;
503   - } else {
504   - if ((timeObj.diff(_bcObj.getFcTimeObj())) > timediff) {
505   - timediff = timeObj.diff(_bcObj.getFcTimeObj());
506   - _lpIndex = _j;
507   - _down_qIndex = _i;
508   - _down_bIndex = isUp == _qIsUp ? 0 : 1;
509   - }
510   - }
511   - }
512   - }
513   - }
514   - }
515   -
516   - if (_lpIndex == undefined) {
517   - return false;
518   - }
519   -
520   - var bcindex = [];
521   - bcindex.push(_lpIndex);
522   - bcindex.push(_down_qIndex);
523   - bcindex.push(_down_bIndex);
524   -
525   - return bcindex;
526   - };
527   -
528   - return {
529   - //------------- 布局初始化方法 ------------//
530   - /**
531   - * 初始化数据,使用标线初始化
532   - */
533   - initDataWithBxLayout: function() {
534   - // 初始化布局1,构造上标线,计算圈数,把上标线数据放入第一个路牌中
535   - _initFun1();
536   - // 初始化布局2,从上标线的某个班次开始,构造所有路牌的早高峰班次,晚高峰班次
537   - _initFun2();
538   - // 初始化布局3,构造中标线,根据高峰班次,将中标线放入合适的路牌中
539   - _initFun3();
540   - // 初始化4,计算连班,分班相关路牌数
541   - _initFun4();
542   -
543   - // 测试添加班次
544   - //this._generateBc(8, 1, 0);
545   - //this._generateBc(10, 1, 0);
546   - //this._generateBc(11, 1, 0);
547   - //this._generateBc(12, 1, 0);
548   - //this._generateBc(13, 1, 0);
549   - //this._generateBc(14, 1, 0);
550   - //this._generateBc(15, 1, 0);
551   - //this._generateBc(16, 1, 0);
552   - //this._generateBc(17, 1, 0);
553   - //this._generateBc(18, 1, 0);
554   - //
555   - //this._generateBc(10, 1, 1);
556   - //this._generateBc(11, 1, 1);
557   - //this._generateBc(12, 1, 1);
558   - //this._generateBc(13, 1, 1);
559   - //this._generateBc(14, 1, 1);
560   - //this._generateBc(15, 1, 1);
561   - //this._generateBc(16, 1, 1);
562   - //this._generateBc(17, 1, 1);
563   - //this._generateBc(18, 1, 1);
564   -
565   - // 6:31 8:30
566   - // 16:01 18:00
567   -
568   - // 测试找上界
569   - console.log("上界:" + _findUpClosedBcIndexWithTime(_paramObj.getMPeakStartTimeObj(), false));
570   - console.log("下界:" + _findDownClosedBcIndexWithTime(_paramObj.getMPeakEndTimeObj(), false));
571   -
572   - // TODO:
573   -
574   - // 测试时间判定
575   - //console.log("班次出车时间:" + _internalLpArray[0].getQBcIndexWithFcTime(
576   - // _paramObj.getMPeakStartTimeObj()
577   - // ));
578   -
579   - //// 测试画中标线,第6个路牌的位置,下行中标
580   - //_internalLpArray[7].initDataFromTimeToTime(
581   - // _paramObj.getDownFirstDTimeObj(),
582   - // _paramObj.getUpLastDtimeObj(),
583   - // false,
584   - // 0,
585   - // _paramObj,
586   - // _factory
587   - //);
588   -
589   - // TODO:问题
590   - // 1、中标线是直接赋值在具体位置的,没有修正班次时间
591   - // 2、路牌间隔时间需要修正的
592   -
593   - },
594   -
595   - // TODO:
596   -
597   - /**
598   - * 调整高峰班次,
599   - * 初始化生成早高峰,晚高峰班次并不准确,因为根据高峰时间段,并不在一个完整圈内,应该是在两个或多个圈之间
600   - * 当初始化定好布局后(上标线,中标线),然后确定每个路牌的班型(连班,分班,5休2分班)后
601   - * 然后重新计算框在高峰时间段内的班次索引,不足的添加,之前多加的删除(只删除分班路牌上的)
602   - * @param isZgf 是否早高峰
603   - * @param isUp 是否上行
604   - */
605   - adjustGfbc : function(isZgf, isUp) {
606   - var startTime; // 开始时间
607   - var endTime; // 结束时间
608   - var startBcIndex; // 开始班次索引
609   - var endBcIndex; // 结束班次索引
610   -
611   - startTime = isZgf ? _paramObj.getMPeakStartTimeObj() : _paramObj.getEPeakStartTimeObj();
612   - endTime = isZgf ? _paramObj.getMPeakEndTimeObj() : _paramObj.getEPeakEndTimeObj();
613   -
614   - startBcIndex = _findUpClosedBcIndexWithTime(startTime, isUp);
615   - endBcIndex = _findDownClosedBcIndexWithTime(endTime, isUp);
616   -
617   - var _lpIndex;
618   - var _qIndex;
619   - var _bcIndex;
620   - var _qInternelCount; // 高峰时间段中间包含的圈数
621   - var i;
622   - var j;
623   -
624   - var _lp;
625   -
626   - if (startBcIndex && endBcIndex) {
627   - _lpIndex = startBcIndex[0];
628   - _qIndex = startBcIndex[1];
629   - _bcIndex = startBcIndex[2];
630   -
631   - // 处理头
632   - // 删除头部多余班次
633   - for (j = 0; j < _lpIndex; j++) {
634   - _lp = _internalLpArray[j];
635   - if (_lp.isBxFb() && _lp.getBc(_qIndex, _bcIndex)) {
636   - _lp.removeBc(_qIndex, _bcIndex);
637   - }
638   - }
639   -
640   - for (j = _lpIndex; j < _internalLpArray.length; j++) {
641   - _lp = _internalLpArray[j];
642   - if (!_lp.getBc(_qIndex, _bcIndex)) {
643   - _generateBcAndSetBc(j, _qIndex, _bcIndex);
644   - }
645   - }
646   -
647   - // 处理中间
648   - _qInternelCount = endBcIndex[1] - startBcIndex[1] - 1;
649   - for (i = 1; i <= _qInternelCount; i++) {
650   - _lp = _internalLpArray[_qIndex + i];
651   - if (!_lp.getBc(_qIndex + i, _bcIndex)) {
652   - _generateBcAndSetBc(i, _qIndex + i, _bcIndex);
653   - }
654   - }
655   -
656   - // 处理尾部
657   - _lpIndex = endBcIndex[0];
658   - _qIndex = endBcIndex[1];
659   - _bcIndex = endBcIndex[2];
660   - for (j = 0; j < _lpIndex; j++) {
661   - _lp = _internalLpArray[j];
662   - if (!_lp.getBc(_qIndex, _bcIndex)) {
663   - _generateBcAndSetBc(j, _qIndex, _bcIndex);
664   - }
665   - }
666   - // 删除尾部多余的班次
667   - for (j = _lpIndex; j < _internalLpArray.length; j++) {
668   - _lp = _internalLpArray[j];
669   - if (_lp.isBxFb() && _lp.getBc(_qIndex, _bcIndex)) {
670   - _lp.removeBc(_qIndex, _bcIndex);
671   - }
672   - }
673   - }
674   -
675   - },
676   -
677   - /**
678   - * 补充做5休2的班型班次。
679   - * 1、做5休2的路牌总工时不能超过7个小时
680   - * 2、5休2的路牌全部从早晚高峰班次开始往前补充1个班次,组成早晚2圈
681   - * 3、再根据余下工时及早晚高峰开始时间,确定向前或者向后加班次
682   - */
683   - calcuLpBx_5_2: function() {
684   - // 1、先在早晚高峰班次前加1个班次压压惊
685   - var i;
686   - var _lp;
687   - var _zgfbcpos; // 早高峰班次位置
688   - var _wgfbcpos; // 晚高峰班次位置
689   - var _qIndex;
690   - var _bIndex;
691   -
692   - //for (i = 0; i < _internalLpArray.length; i++) {
693   - // _lp = _internalLpArray[i];
694   - // if (_lp.isBxFb5_2()) {
695   - // _zgfbcpos = _lp.getMinBcObjPosition();
696   - // _wgfbcpos = _lp.getMaxBcObjPosition();
697   - //
698   - // // TODO:测试向前添加一个班次
699   - // _qIndex = _zgfbcpos[0];
700   - // _bIndex = _zgfbcpos[1];
701   - // _bIndex == 0 ?
702   - // _generateBcAndSetBc(i, _qIndex - 1, 1) :
703   - // _generateBcAndSetBc(i, _qIndex, 0);
704   - //
705   - // _qIndex = _wgfbcpos[0];
706   - // _bIndex = _wgfbcpos[1];
707   - // _bIndex == 0 ?
708   - // _generateBcAndSetBc(i, _qIndex - 1, 1) :
709   - // _generateBcAndSetBc(i, _qIndex, 0);
710   - //
711   - // }
712   - //}
713   -
714   - // 2、
715   - },
716   -
717   - /**
718   - * 补充连班路牌班次。
719   - * 1、上标线,中标线中间的连班路牌班次从早高峰班次一直拉到底,从早高峰班次向上标线起始班次靠拢
720   - * 2、中标线以下的连班路牌班次从早高峰班次一直拉到底,从早高峰班次向中标线起始班次靠拢
721   - */
722   - calcuLpBx_lb: function() {
723   - // 补充连班的班次,参照上标线,中标线补充不足的班次
724   - var _zgffcsj; // 早高峰发车时间
725   - var _etsj = // 结束时间
726   - _paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj()) ?
727   - _paramObj.getDownLastDTimeObj() :
728   - _paramObj.getUpLastDtimeObj();
729   -
730   - var _lp;
731   - var _minbcPos;
732   - var _bcObj;
733   - var i;
734   - for (i = 0; i < _internalLpArray.length; i++) {
735   - _lp = _internalLpArray[i];
736   - if (_lp.isBxLb() && i != 0 && i != _zbx_lpIndex) {
737   - _minbcPos = _lp.getMinBcObjPosition();
738   - _bcObj = _lp.getBc(_minbcPos[0], _minbcPos[1]);
739   - _zgffcsj = _bcObj.getFcTimeObj();
740   - // 重新初始化连班班型班次
741   - _lp.initDataFromTimeToTime(
742   - _zgffcsj,
743   - _etsj,
744   - _bcObj.isUp(),
745   - _minbcPos[0],
746   - _paramObj,
747   - _factory
748   - );
749   - }
750   - }
751   -
752   - // 还要补充缺失的班次,差上标线几个班次要往前补上
753   - var _bccount;
754   - var j;
755   - var _qIndex;
756   - var _bIndex;
757   - // 补上标线到中标线之间的连班路牌的班次
758   - for (i = 0; i < _zbx_lpIndex; i++) {
759   - _lp = _internalLpArray[i];
760   - if (_lp.isBxLb() && i != 0 && i != _zbx_lpIndex) {
761   - _minbcPos = _lp.getMinBcObjPosition();
762   - _qIndex = _minbcPos[0];
763   - _bIndex = _minbcPos[1];
764   - _bccount = (_qIndex - 1) * 2 + _bIndex; // 距离上标线起始站点差几个班次
765   - for (j = 0; j < _bccount; j++) {
766   - if (_bIndex == 0) {
767   - _qIndex --;
768   - _bIndex = 1;
769   - _generateBcAndSetBc(i, _qIndex, _bIndex);
770   - } else if (_bIndex == 1) {
771   - _bIndex --;
772   - _generateBcAndSetBc(i, _qIndex, _bIndex);
773   - }
774   - }
775   - }
776   - }
777   - // 补中标线以下的连班路牌的班次
778   - for (i = _zbx_lpIndex; i < _internalLpArray.length; i++) {
779   - _lp = _internalLpArray[i];
780   - if (_lp.isBxLb() && i != 0 && i != _zbx_lpIndex) {
781   - _minbcPos = _lp.getMinBcObjPosition();
782   - _qIndex = _minbcPos[0];
783   - _bIndex = _minbcPos[1];
784   - _bccount = (_qIndex - 0) * 2 + _bIndex - 1; // 距离上标线起始站点差几个班次
785   - for (j = 0; j < _bccount; j++) {
786   - if (_bIndex == 0) {
787   - _qIndex --;
788   - _bIndex = 1;
789   - _generateBcAndSetBc(i, _qIndex, _bIndex);
790   - } else if (_bIndex == 1) {
791   - _bIndex --;
792   - _generateBcAndSetBc(i, _qIndex, _bIndex);
793   - }
794   - }
795   - }
796   - }
797   -
798   - },
799   -
800   - /**
801   - * 计算每个路牌的班型及工时对应的圈数。
802   - * 1、将连班,分班路牌分配到各个路牌上(分隔法),上标线,中标线上连班路牌
803   - * 2、确定班型的工时,其中连班路牌的工时由上标线,中标线确定好了,5休2路牌工时也确定了,
804   - * 其余分班路牌的工时由高峰低谷最大,最小发车间隔计算
805   - */
806   - calcuLpBx_fg: function() {
807   - // 间隔法
808   -
809   - //--------------------------- 1、间隔法分隔连班路牌 ----------------------//
810   -
811   - // 除去上标线,中标线的连班路牌个数
812   - var _lblbcount = _bx_lb_lpcount - 2;
813   - // 计算由标线隔开的两个区域的路牌数比率
814   - var _p1 = (_zbx_lpIndex + 1) / (_internalLpArray.length + 1);
815   - var _p2 = (_internalLpArray.length - _zbx_lpIndex) / (_internalLpArray.length + 1);
816   - var _p1_lpcount = _lblbcount * _p1;
817   - var _p2_lpcount = _lblbcount * _p2;
818   - if (parseInt(_p1_lpcount) != _p1_lpcount) { // 没有整除
819   - _p1_lpcount = Math.floor(_p1_lpcount);
820   - _p2_lpcount = Math.floor(_p2_lpcount) + 1;
821   - }
822   -
823   - // 设定第一个区域的连班路牌
824   - var i;
825   - var _count = _p1_lpcount + 1;
826   - var _c1 = Math.floor(_zbx_lpIndex / _count);
827   - var _c2 = _zbx_lpIndex % _count;
828   - var _c2_start_index;
829   - for (i = 1; i <= _count - _c2; i++) {
830   - _internalLpArray[(i - 1) * _c1].setBxLb(true);
831   - _internalLpArray[(i - 1) * _c1].setBxDesc("连班");
832   - _c2_start_index = (i - 1) * _c1;
833   - }
834   - for (i = 1; i <= _c2; i++) {
835   - _internalLpArray[_c2_start_index + i * (_c1 + 1)].setBxLb(true);
836   - _internalLpArray[_c2_start_index + i * (_c1 + 1)].setBxDesc("连班");
837   - }
838   -
839   - // 设定第二个区域的连班路牌
840   - _count = _p2_lpcount + 1;
841   - _c1 = Math.floor((_internalLpArray.length - _zbx_lpIndex - 1) / _count);
842   - _c2 = (_internalLpArray.length - _zbx_lpIndex - 1) % _count;
843   - for (i = 1; i <= _count - _c2; i++) {
844   - _internalLpArray[(i - 1) * _c1 + _zbx_lpIndex].setBxLb(true);
845   - _internalLpArray[(i - 1) * _c1 + _zbx_lpIndex].setBxFb(false);
846   - _internalLpArray[(i - 1) * _c1 + _zbx_lpIndex].setBxFb5_2(false);
847   - _internalLpArray[(i - 1) * _c1 + _zbx_lpIndex].setBxDesc("连班");
848   - _c2_start_index = (i - 1) * _c1 + _zbx_lpIndex;
849   - }
850   - for (i = 1; i <= _c2; i++) {
851   - _internalLpArray[_c2_start_index + i * (_c1 + 1)].setBxLb(true);
852   - _internalLpArray[_c2_start_index + i * (_c1 + 1)].setBxFb(false);
853   - _internalLpArray[_c2_start_index + i * (_c1 + 1)].setBxFb5_2(false);
854   - _internalLpArray[_c2_start_index + i * (_c1 + 1)].setBxDesc("连班");
855   - }
856   -
857   - //---------------------------- 2、分隔法,分隔分班路牌 -------------------------//
858   -
859   - // 设定分班路牌
860   - var notlbIndexes = []; // 去除连班的路牌index列表
861   - for (i = 0; i < _internalLpArray.length; i++) {
862   - if (!_internalLpArray[i].isBxLb()) {
863   - notlbIndexes.push(i);
864   - }
865   - }
866   - // 获取离中标线最近的分班路牌索引
867   - var _temp_fg_index;
868   - for (i = 0; i < notlbIndexes.length; i++) {
869   - if (notlbIndexes[i] == _zbx_lpIndex - 1) {
870   - _temp_fg_index = i;
871   - break;
872   - }
873   - }
874   -
875   - // 使用上面的分隔比率,分隔5休2班型
876   - _p1_lpcount = _bx_5_2_fb_lpcount * _p1;
877   - _p2_lpcount = _bx_5_2_fb_lpcount * _p2;
878   - if (parseInt(_p1_lpcount) != _p1_lpcount) { // 没有整除
879   - _p1_lpcount = Math.floor(_p1_lpcount);
880   - _p2_lpcount = Math.floor(_p2_lpcount) + 1;
881   - }
882   - // 第一个区域
883   - _count = _p1_lpcount;
884   - _c1 = Math.floor(_temp_fg_index / _count);
885   - _c2 = _temp_fg_index % _count;
886   - for (i = 1; i <= _count - _c2; i++) {
887   - _internalLpArray[notlbIndexes[(i - 1) * _c1]].setBxLb(false);
888   - _internalLpArray[notlbIndexes[(i - 1) * _c1]].setBxFb(true);
889   - _internalLpArray[notlbIndexes[(i - 1) * _c1]].setBxFb5_2(true);
890   - _internalLpArray[notlbIndexes[(i - 1) * _c1]].setBxDesc("5休2分班");
891   - _c2_start_index = (i - 1) * _c1;
892   - }
893   - for (i = 1; i <= _c2; i++) {
894   - _internalLpArray[notlbIndexes[_c2_start_index + i * (_c1 + 1)]].setBxLb(false);
895   - _internalLpArray[notlbIndexes[_c2_start_index + i * (_c1 + 1)]].setBxLb(true);
896   - _internalLpArray[notlbIndexes[_c2_start_index + i * (_c1 + 1)]].setBxFb5_2(true);
897   - _internalLpArray[notlbIndexes[_c2_start_index + i * (_c1 + 1)]].setBxDesc("5休2分班");
898   - }
899   - // 第二个区域
900   - _count = _p2_lpcount;
901   - _c1 = Math.floor((notlbIndexes.length - _temp_fg_index - 1) / _count);
902   - _c2 = (notlbIndexes.length - _temp_fg_index - 1) % _count;
903   - for (i = 1; i <= _count - _c2; i++) {
904   - _internalLpArray[notlbIndexes[(i - 1) * _c1 + _temp_fg_index + 1]].setBxLb(false);
905   - _internalLpArray[notlbIndexes[(i - 1) * _c1 + _temp_fg_index + 1]].setBxFb(true);
906   - _internalLpArray[notlbIndexes[(i - 1) * _c1 + _temp_fg_index + 1]].setBxFb5_2(true);
907   - _internalLpArray[notlbIndexes[(i - 1) * _c1 + _temp_fg_index + 1]].setBxDesc("5休2分班");
908   - _c2_start_index = (i - 1) * _c1 + _temp_fg_index + 1;
909   - }
910   - for (i = 1; i <= _c2; i++) {
911   - _internalLpArray[notlbIndexes[_c2_start_index + i * (_c1 + 1)]].setBxLb(false);
912   - _internalLpArray[notlbIndexes[_c2_start_index + i * (_c1 + 1)]].setBxFb(true);
913   - _internalLpArray[notlbIndexes[_c2_start_index + i * (_c1 + 1)]].setBxFb5_2(true);
914   - _internalLpArray[notlbIndexes[_c2_start_index + i * (_c1 + 1)]].setBxDesc("5休2分班");
915   - }
916   -
917   - //-------------------------- 3、余下班次就是其他分班类型 ----------------------//
918   -
919   - for (i = 0; i < notlbIndexes.length; i++) {
920   - if (!_internalLpArray[notlbIndexes[i]].isBxFb5_2()) {
921   - _internalLpArray[notlbIndexes[i]].setBxLb(false);
922   - _internalLpArray[notlbIndexes[i]].setBxFb(true);
923   - _internalLpArray[notlbIndexes[i]].setBxFb5_2(false);
924   - _internalLpArray[notlbIndexes[i]].setBxDesc("其他分班");
925   - }
926   - }
927   -
928   - // 测试打印
929   - var lbIndexes = [];
930   - for (i = 0; i < _internalLpArray.length; i++) {
931   - if (_internalLpArray[i].isBxLb()) {
932   - lbIndexes.push(i);
933   - }
934   - }
935   - console.log("连班路牌indexes=" + lbIndexes);
936   -
937   - var _other_fbIndexes = [];
938   - for (i = 0; i < _internalLpArray.length; i++) {
939   - if (_internalLpArray[i].isBxFb() && !_internalLpArray[i].isBxFb5_2()) {
940   - _other_fbIndexes.push(i);
941   - }
942   - }
943   - console.log("其他分班路牌indexes=" + _other_fbIndexes);
944   -
945   - var _5_2_fbIndexes = [];
946   - for (i = 0; i < _internalLpArray.length; i++) {
947   - if (_internalLpArray[i].isBxFb() && _internalLpArray[i].isBxFb5_2()) {
948   - _5_2_fbIndexes.push(i);
949   - }
950   - }
951   - console.log("5休2分班路牌indexes=" + _5_2_fbIndexes);
952   - },
953   -
954   - //------------- 其他方法 -------------//
955   - /**
956   - * 内部数据转化成显示用的班次数组。
957   - */
958   - toGanttBcArray: function() {
959   - var bcData = [];
960   - var lpObj;
961   - for (i = 0; i < _internalLpArray.length; i++) {
962   - lpObj = _internalLpArray[i];
963   - bcData = bcData.concat(lpObj.getBcArray());
964   - }
965   -
966   - var ganttBcData = [];
967   - for (i = 0; i < bcData.length; i++) {
968   - ganttBcData.push(bcData[i].toGanttBcObj());
969   - }
970   -
971   - return ganttBcData;
972   - }
973   -
974   - // TODO:
975   - };
  1 +/**
  2 + * 内部行车计划对象。
  3 + * @constructor
  4 + */
  5 +var InternalScheduleObj = function(paramObj, lpArray, factory) {
  6 + // 参数对象
  7 + var _paramObj = paramObj;
  8 + // 外部的路牌数组
  9 + var _lpArray = lpArray;
  10 + // 工厂对象
  11 + var _factory = factory;
  12 +
  13 + //------------------ 初始化方法1,以及计算关联的内部变量 -----------------//
  14 + var _qIsUp; // 每一圈是上行开始还是下行开始
  15 + var _qCount = 0; // 总的圈数
  16 + var _internalLpArray = []; // 内部对象数组
  17 + var _aBxDesc = [ // 各种班型描述(班型名称,平均工时,平均需要的班次数,平均工时)
  18 + {'sType':'六工一休', 'fHoursV':6.66, 'fBcCount': 0, 'fAverTime': 0},
  19 + {'sType':'五工一休', 'fHoursV':6.85, 'fBcCount': 0, 'fAverTime': 0},
  20 + {'sType':'四工一休', 'fHoursV':7.14, 'fBcCount': 0, 'fAverTime': 0},
  21 + {'sType':'三工一休', 'fHoursV':7.61, 'fBcCount': 0, 'fAverTime': 0},
  22 + {'sType':'二工一休', 'fHoursV':8.57, 'fBcCount': 0, 'fAverTime': 0},
  23 + {'sType':'一工一休', 'fHoursV':11.42, 'fBcCount': 0, 'fAverTime': 0},
  24 + {'sType':'五工二休', 'fHoursV':7.99, 'fBcCount': 0, 'fAverTime': 0},
  25 + {'sType':'无工休', 'fHoursV':5.43, 'fBcCount': 0, 'fAverTime': 0}
  26 + ];
  27 +
  28 + var _fnInitFun1 = function() { // 初始化方法1
  29 + console.log("//---------------- 行车计划,初始化方法1 start ----------------//");
  30 +
  31 + //----------------------- 1、确定上标线的方向,圈的方向 -------------------//
  32 +
  33 + // 确定_qIsUp,哪个方向的首班车晚就用哪个
  34 + _qIsUp = _paramObj.getUpFirstDTimeObj().isBefore(
  35 + _paramObj.getDownFirstDTimeObj()) ? false : true;
  36 + // 上标线开始时间,就是方向的首班车时间
  37 + var st = _qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();
  38 + // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向
  39 + var et;
  40 + var et_IsUp;
  41 + if (_paramObj.getUpLastDtimeObj().isBefore(
  42 + _paramObj.getDownLastDTimeObj())) {
  43 + et = _paramObj.getDownLastDTimeObj();
  44 + et_IsUp = false;
  45 + } else {
  46 + et = _paramObj.getUpLastDtimeObj();
  47 + et_IsUp = true;
  48 + }
  49 +
  50 + //------------------------ 2、计算总共有多少圈 ------------------------//
  51 +
  52 + // 以开始时间,结束时间,构造上标线用连班班次发车时间
  53 + var bcFcsjArrays = []; // 班次发车时间对象数组
  54 + var bcArsjArrays = []; // 班次到达时间对象数组
  55 + var isUp = _qIsUp; // 方向
  56 + var bcCount = 1; // 班次数
  57 +
  58 + var _kssj = st; // 开始时间
  59 + var _bcsj = paramObj.calcuTravelTime(_kssj, isUp); // 班次历时
  60 + var _arrsj = paramObj.addMinute(_kssj, _bcsj); // 到达时间
  61 + var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, _bcsj); // 停站时间
  62 +
  63 + do {
  64 + bcFcsjArrays.push(_kssj);
  65 + bcArsjArrays.push(_arrsj);
  66 +
  67 + _kssj = paramObj.addMinute(_kssj, _bcsj + _stoptime);
  68 + _bcsj = paramObj.calcuTravelTime(_kssj, isUp);
  69 + _arrsj = paramObj.addMinute(_kssj, _bcsj);
  70 + _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, _bcsj);
  71 +
  72 + bcCount ++;
  73 + isUp = !isUp;
  74 + } while(_kssj.isBefore(et));
  75 + bcCount--; // 因为先做do,所以总的班次要减1
  76 + if (bcCount > 0 && bcArsjArrays[bcCount - 1].isAfter(et)) {
  77 + // 如果最后一个班次的到达时间超过结束时间,也要去除
  78 + bcFcsjArrays.splice(bcCount - 1, 1);
  79 + bcArsjArrays.splice(bcCount - 1, 1);
  80 + bcCount--;
  81 + }
  82 + var _qCount_p1 = Math.floor(bcCount / 2); // 2个班次一圈
  83 + var _qCount_p2 = bcCount % 2; // 余下的1个班次也算一圈
  84 +
  85 + // 利用连班数组计算圈数
  86 + _qCount = 1; // 前面加1圈,补中标线的班次
  87 + _qCount += _qCount_p1;
  88 + _qCount += _qCount_p2;
  89 +
  90 + // 计算最后是不是还要补一圈
  91 + if (_qCount > 1) { // 总的圈数就1圈,没必要加了(其实是不可能的,除非参数里问题)
  92 + if (_qCount_p2 == 0) { // 没有余下班次,整数圈数
  93 + // 最后一个班次的方向一定和开始的方向相反,如:上-下,上-下,上-下,一共三圈,最后一个班次为下行
  94 + // 判定最后一个班次的方向和上标线判定结束时间的班次方向是否一致
  95 + if (!_qIsUp == et_IsUp) {
  96 + // 一致不用加圈数
  97 + } else {
  98 + // 不一致需要加圈补最后一个结束时间班次
  99 + _qCount ++;
  100 + }
  101 + } else {
  102 + // 有余下的圈数,最后要不补的班次不管上行,下行都在这一圈里
  103 + // 不需要在补圈数了
  104 + }
  105 + }
  106 +
  107 + //------------------------ 3、根据路牌数,圈数创建路牌对象 ----------------------//
  108 +
  109 + // 创建内部的路牌数组,并把之前的连班路牌添加进上标线路牌中
  110 + var i;
  111 + for (i = 0; i < _lpArray.length; i++) {
  112 + _internalLpArray.push(new InternalLpObj(_lpArray[i], _qCount, _qIsUp));
  113 + }
  114 + // 初始化上标线,从第1圈开始
  115 + _internalLpArray[0].initDataFromTimeToTime(bcFcsjArrays[0], et, _qIsUp, 1, _paramObj, _factory);
  116 +
  117 + // 以上标线为基础,计算各种班型工时对应的圈数、班次数
  118 + var aBcArray = _internalLpArray[0].getBcArray();
  119 + if (aBcArray.length % 2 != 0) { // 不能整除2,去除一个班次计算
  120 + aBcArray.splice(aBcArray.length - 1, 1);
  121 + }
  122 + var sum = 0;
  123 + // 加吃饭时间
  124 + sum += _paramObj.fnGetLunchTime();
  125 + sum += _paramObj.fnGetDinnerTime();
  126 + // 加进出场时间
  127 + sum += _qIsUp ? _paramObj.getUpOutTime() : _paramObj.getDownOutTime();
  128 + sum += _qIsUp ? _paramObj.getDownInTime() : _paramObj.getUpInTime();
  129 + // 例保时间
  130 + //sum += _paramObj.getLbTime() * 2;
  131 + for (i = 0; i < aBcArray.length; i++) {
  132 + sum += aBcArray[i].getBcTime() + aBcArray[i].getStopTime();
  133 + }
  134 + for (i = 0; i < _aBxDesc.length; i++) {
  135 + _aBxDesc[i].fAverTime = sum / (aBcArray.length / 2);
  136 + _aBxDesc[i].fBcCount = ((_aBxDesc[i].fHoursV * 60) / _aBxDesc[i].fAverTime) * 2;
  137 + }
  138 +
  139 + // 在第一个班次之前再添加一个模拟班次,用于中标线的作用
  140 + // 那一圈必定是低谷,而且圈索引0,班次索引1,暂时标记,最后删除
  141 + var iFirstStopTime =
  142 + _paramObj.fnCalcuFixedStopNumber(
  143 + _paramObj.addMinute(aBcArray[0].getFcTimeObj(), -10),
  144 + _qIsUp
  145 + );
  146 + var iXXTime = _qIsUp ? _paramObj.getDownTroughTime() : _paramObj.getUpTroughTime();
  147 + var oFlagBc = _factory.createBcObj( // 标记班次
  148 + _internalLpArray[0],
  149 + "normal",
  150 + !_qIsUp,
  151 + 1,
  152 + _paramObj.addMinute(aBcArray[0].getFcTimeObj(), -(iFirstStopTime + iXXTime)),
  153 + _paramObj
  154 + );
  155 + oFlagBc.fnSetDelFlag(true); // 标记了删除记号
  156 +
  157 + _internalLpArray[0].setBc(0, 1, oFlagBc);
  158 +
  159 + // 在最后一圈也补上一个或者2个模拟班次,暂时标记,最后需要删除
  160 + var aMaxBcIndex = _internalLpArray[0].getMaxBcObjPosition();
  161 + if (aMaxBcIndex[0] == _qCount - 1) { // 可能加半圈
  162 + oFlagBc = _factory.createBcObj( // 标记班次
  163 + _internalLpArray[0],
  164 + "normal",
  165 + !_qIsUp,
  166 + 1,
  167 + _paramObj.addMinute(
  168 + _internalLpArray[0].getBc(_qCount - 1, 0).getArrTimeObj(),
  169 + _internalLpArray[0].getBc(_qCount - 1, 0).getStopTime()),
  170 + _paramObj
  171 + );
  172 + oFlagBc.fnSetDelFlag(true); // 标记了删除记号
  173 + _internalLpArray[0].setBc(_qCount - 1, 1, oFlagBc);
  174 +
  175 + } else { // 加完整的一圈
  176 + oFlagBc = _factory.createBcObj( // 标记班次
  177 + _internalLpArray[0],
  178 + "normal",
  179 + _qIsUp,
  180 + 1,
  181 + _paramObj.addMinute(
  182 + _internalLpArray[0].getBc(_qCount - 2, 1).getArrTimeObj(),
  183 + _internalLpArray[0].getBc(_qCount - 2, 1).getStopTime()),
  184 + _paramObj
  185 + );
  186 + oFlagBc.fnSetDelFlag(true); // 标记了删除记号
  187 + _internalLpArray[0].setBc(_qCount - 1, 0, oFlagBc);
  188 +
  189 + oFlagBc = _factory.createBcObj( // 标记班次
  190 + _internalLpArray[0],
  191 + "normal",
  192 + !_qIsUp,
  193 + 1,
  194 + _paramObj.addMinute(
  195 + _internalLpArray[0].getBc(_qCount - 1, 0).getArrTimeObj(),
  196 + _internalLpArray[0].getBc(_qCount - 1, 0).getStopTime()),
  197 + _paramObj
  198 + );
  199 + oFlagBc.fnSetDelFlag(true); // 标记了删除记号
  200 + _internalLpArray[0].setBc(_qCount - 1, 1, oFlagBc);
  201 +
  202 + }
  203 +
  204 + console.log("上行首班车时间:" + _paramObj.getUpFirstDTimeObj().format("HH:mm") +
  205 + "上行末班车时间:" + _paramObj.getUpLastDtimeObj().format("HH:mm"));
  206 + console.log("下行首班车时间:" + _paramObj.getDownFirstDTimeObj().format("HH:mm") +
  207 + "下行末班车时间:" + _paramObj.getDownLastDTimeObj().format("HH:mm"));
  208 + console.log("总共计算的圈数:" + _qCount);
  209 + console.log("圈的方向isUP:" + _qIsUp);
  210 + console.log("班型描述(以下):");
  211 + console.log(_aBxDesc);
  212 + console.log("所有路牌间隔描述(以下):");
  213 + for (i = 0; i < _internalLpArray.length; i++) {
  214 + console.log(_internalLpArray[i]._$_aVerticalIntervalTime);
  215 + }
  216 + console.log("//---------------- 行车计划,初始化方法1 end ----------------//");
  217 +
  218 + };
  219 +
  220 + //------------------ 初始化方法2,以及计算关联的内部变量 ----------------//
  221 + var _approximate_zgfQIndex; // 预估早高峰车辆从第几圈开始全部发出
  222 + var _approximate_zgfBIndex; // 预估早高峰车辆从第几圈第几个班次开始全部发出(上行或下行)
  223 + var _approximate_wgfQIndex; // 预估晚高峰车辆从第几圈开始全部发出
  224 + var _approximate_wgfBIndex; // 预估晚高峰车辆从第几圈第几个班次开始全部发出(上行或下行)
  225 +
  226 + var _fnInitFun2 = function() { // 初始化方法2
  227 + console.log("//---------------- 行车计划,初始化方法2 start ----------------//");
  228 +
  229 + //------------------------ 1、计算车辆总数 ------------------------//
  230 + // 是用高峰上行周转时间除以高峰平均间隔得到的
  231 + // 这样算还算合理,车辆不多不少,待以后有新的算法再修正
  232 + var iClCount = _paramObj.calcuClzx();
  233 +
  234 + //------------------------ 2、计算所有路牌的发车在各个圈中的间隔 --------------------//
  235 + var i;
  236 + var j;
  237 + var iBindex = 1;
  238 + var iZzsj;
  239 + var oLp;
  240 + var iC1;
  241 + var iC2;
  242 +
  243 + for (i = 0; i < _qCount - 1; i++) {
  244 + while (iBindex <= 1) {
  245 + // 每圈每个方向的周转时间不一致,以上标线为主
  246 + oLp = _internalLpArray[0];
  247 + iZzsj = oLp.getBc(i + 1, iBindex).getFcTimeObj().diff(
  248 + oLp.getBc(i, iBindex).getFcTimeObj(), "m"
  249 + );
  250 +
  251 + iC1 = Math.floor(iZzsj / iClCount);
  252 + iC2 = iZzsj % iClCount;
  253 +
  254 + for (j = 0; j < iClCount - iC2; j++) {
  255 + oLp = _internalLpArray[j];
  256 + oLp.fnSetVerticalIntervalTime(i, iBindex, iC1);
  257 + }
  258 +
  259 + for (j = 0; j < iC2; j++) {
  260 + oLp = _internalLpArray[iClCount - iC2 + j];
  261 + oLp.fnSetVerticalIntervalTime(i, iBindex, iC1 + 1);
  262 + }
  263 +
  264 + iBindex ++;
  265 +
  266 + }
  267 + iBindex = 0;
  268 + }
  269 + // 最后一圈没有下一圈的参照,周转时间没发获取,由于都是低谷,所以使用倒数第二圈的间隔最为最后一圈的间隔
  270 + for (i = 0; i < _internalLpArray.length; i++) {
  271 + oLp = _internalLpArray[i];
  272 + oLp.fnSetVerticalIntervalTime(_qCount - 1, 0, oLp.fnGetVerticalIntervalTime(_qCount - 2, 0));
  273 + oLp.fnSetVerticalIntervalTime(_qCount - 1, 1, oLp.fnGetVerticalIntervalTime(_qCount - 2, 1));
  274 + }
  275 +
  276 + //------------------------ 3、预估早高峰全部出车第几圈第几个班次全部出车,计算路牌之间的发车间隔 ------------------//
  277 +
  278 + // 以上标线为标准,查找离早高峰开始时间最近的班次作为早高峰开始班次
  279 + // 以这个班次为早高峰起点,全部出车策略
  280 + var qbcIndexArray = _internalLpArray[0].getQBcIndexWithFcTime(
  281 + _paramObj.getMPeakStartTimeObj(), true, true);
  282 + var qIndex = qbcIndexArray[0]; // 第几圈
  283 + var bIndex = qbcIndexArray[1]; // 第几个班次
  284 +
  285 + for (i = 1; i < _internalLpArray.length; i++) {
  286 + _fnGenerateBcAndSetBc(i, qIndex, bIndex);
  287 + }
  288 +
  289 + _approximate_zgfQIndex = qIndex;
  290 + _approximate_zgfBIndex = bIndex;
  291 +
  292 + //------------------------ 4、预估晚高峰全部出车第几圈第几个班次全部出车,计算路牌之间的发车间隔 ------------------//
  293 +
  294 + // 以上标线为标准,查找离晚高峰开始时间最近的班次作为晚高峰开始班次
  295 + // 以这个班次为早高峰起点,全部出车策略
  296 + qbcIndexArray = _internalLpArray[0].getQBcIndexWithFcTime(
  297 + _paramObj.getEPeakStartTimeObj(), true, true);
  298 + qIndex = qbcIndexArray[0]; // 第几圈
  299 + bIndex = qbcIndexArray[1]; // 第几个班次
  300 +
  301 + for (i = 1; i < _internalLpArray.length; i++) {
  302 + _fnGenerateBcAndSetBc(i, qIndex, bIndex);
  303 + }
  304 +
  305 + _approximate_wgfQIndex = qIndex;
  306 + _approximate_wgfBIndex = bIndex;
  307 +
  308 + console.log("早高峰周转时间(固定最大停战时间):" + _paramObj.calcuPeakZzsj() + "分钟");
  309 + console.log("早高峰发车时间范围:" + _paramObj.getMPeakMinFcjx() + "分钟 --- " + _paramObj.getMPeakMaxFcjx() + "分钟");
  310 + console.log("预估早高峰第" + _approximate_zgfQIndex + "(index)圈,第" + _approximate_zgfBIndex + "(index)班次车辆全部发出");
  311 + console.log("预估晚高峰第" + _approximate_wgfQIndex + "(index)圈,第" + _approximate_wgfBIndex + "(index)班次车辆全部发出");
  312 + console.log("//---------------- 行车计划,初始化方法2 end ----------------//");
  313 + };
  314 +
  315 + //----------------------- 初始化方法3,计算连班分班的路牌分布 ----------------//
  316 + var _iBx_lb_lpcount; // 连班路牌数
  317 + var _iBx_5_2_fb_lpcount; // 5休2分班路牌数
  318 + var _iBx_other_fb_lpcount; // 其他分班路牌数
  319 +
  320 + var _fnInitFun3 = function() { // 初始化方法3
  321 + console.log("//---------------- 行车计划,初始化方法3 start ----------------//");
  322 +
  323 + //--------------------- 1、计算分班连班班型车辆分布数 --------------------//
  324 + // 总共车辆数(高峰最大车辆数)
  325 + var iCls = _paramObj.calcuClzx();
  326 + // 低谷最少配车(连班车数量)
  327 + var iDgminpc = Math.round(_paramObj.calcuTroughZzsj() / _paramObj.getTroughMaxFcjx());
  328 + // 加班车路牌数(做5休2的路牌数)
  329 + var i_5_2_lpes = _paramObj.getJBLpes();
  330 +
  331 + // 做些简单的验证
  332 + if (iCls < iDgminpc) {
  333 + alert("总配车数小于低谷最小配车");
  334 + throw "总配车数小于低谷最小配车";
  335 + }
  336 + if (iDgminpc < 2) {
  337 + alert("连班路牌小于2,办不到啊");
  338 + throw "连班路牌小于2,办不到啊";
  339 + }
  340 + if (iCls - iDgminpc < i_5_2_lpes) {
  341 + alert("总分班路牌数小于加班路牌数");
  342 + throw "总分班路牌数小于加班路牌数";
  343 + }
  344 +
  345 + _iBx_lb_lpcount = iDgminpc;
  346 + _iBx_5_2_fb_lpcount = i_5_2_lpes;
  347 + _iBx_other_fb_lpcount = iCls - iDgminpc - i_5_2_lpes;
  348 +
  349 + //------------------------ 2、利用间隔法计算连班路牌分布 --------------------//
  350 + var i;
  351 + var j;
  352 + var iC1 = Math.floor(_internalLpArray.length / _iBx_lb_lpcount);
  353 + var iC2 = _internalLpArray.length % _iBx_lb_lpcount;
  354 + var iLpIndex;
  355 +
  356 + for (i = 0; i < _iBx_lb_lpcount - iC2; i++) {
  357 + iLpIndex = i * iC1;
  358 + _internalLpArray[iLpIndex].setBxLb(true);
  359 + _internalLpArray[iLpIndex].setBxDesc("连班");
  360 + }
  361 + for (j = 0; j < iC2; j++) {
  362 + iLpIndex = i * iC1 + j * (iC1 + 1);
  363 + _internalLpArray[iLpIndex].setBxLb(true);
  364 + _internalLpArray[iLpIndex].setBxDesc("连班");
  365 + }
  366 +
  367 + //------------------------ 3、利用间隔法计算分班班型路牌分布 --------------------//
  368 + // 获取分班路牌索引
  369 + var aNotLbIndexes = [];
  370 + for (i = 0; i < _internalLpArray.length; i++) {
  371 + if (!_internalLpArray[i].isBxLb()) {
  372 + aNotLbIndexes.push(i);
  373 + }
  374 + }
  375 + // 先5休2分班
  376 + iC1 = Math.floor(aNotLbIndexes.length / _iBx_5_2_fb_lpcount);
  377 + iC2 = aNotLbIndexes.length % _iBx_5_2_fb_lpcount;
  378 +
  379 + for (i = 0; i < _iBx_5_2_fb_lpcount - iC2; i++) {
  380 + iLpIndex = aNotLbIndexes[i * iC1];
  381 + _internalLpArray[iLpIndex].setBxLb(false);
  382 + _internalLpArray[iLpIndex].setBxFb(true);
  383 + _internalLpArray[iLpIndex].setBxFb5_2(true);
  384 + _internalLpArray[iLpIndex].setBxDesc("5休2分班");
  385 + }
  386 + for (i = 0; i < iC2; i++) {
  387 + iLpIndex = aNotLbIndexes[_iBx_lb_lpcount - iC2 + i * (iC1 + 1)];
  388 + _internalLpArray[iLpIndex].setBxLb(false);
  389 + _internalLpArray[iLpIndex].setBxFb(true);
  390 + _internalLpArray[iLpIndex].setBxFb5_2(true);
  391 + _internalLpArray[iLpIndex].setBxDesc("5休2分班");
  392 + }
  393 + // 其他分班
  394 + for (i = 0; i < aNotLbIndexes.length; i++) {
  395 + iLpIndex = aNotLbIndexes[i];
  396 + if (!_internalLpArray[iLpIndex].isBxFb5_2()) {
  397 + _internalLpArray[iLpIndex].setBxLb(false);
  398 + _internalLpArray[iLpIndex].setBxFb(true);
  399 + _internalLpArray[iLpIndex].setBxFb5_2(false);
  400 + _internalLpArray[iLpIndex].setBxDesc("其他分班");
  401 + }
  402 + }
  403 +
  404 +
  405 + console.log("连班路牌数:" + _iBx_lb_lpcount);
  406 + console.log("5休2分班路牌数:" + _iBx_5_2_fb_lpcount);
  407 + console.log("其他分班路牌数:" + _iBx_other_fb_lpcount);
  408 + var aLbIndexes = [];
  409 + for (i = 0; i < _internalLpArray.length; i++) {
  410 + if (_internalLpArray[i].isBxLb()) {
  411 + aLbIndexes.push(i);
  412 + }
  413 + }
  414 + console.log("连班路牌indexes=" + aLbIndexes);
  415 + var a_5_2_fbIndexes = [];
  416 + for (i = 0; i < _internalLpArray.length; i++) {
  417 + if (_internalLpArray[i].isBxFb() && _internalLpArray[i].isBxFb5_2()) {
  418 + a_5_2_fbIndexes.push(i);
  419 + }
  420 + }
  421 + console.log("5休2分班路牌indexes=" + a_5_2_fbIndexes);
  422 + var a_other_fbIndexes = [];
  423 + for (i = 0; i < _internalLpArray.length; i++) {
  424 + if (_internalLpArray[i].isBxFb() && !_internalLpArray[i].isBxFb5_2()) {
  425 + a_other_fbIndexes.push(i);
  426 + }
  427 + }
  428 + console.log("其他分班路牌indexes=" + a_other_fbIndexes);
  429 +
  430 + console.log("//---------------- 行车计划,初始化方法3 end ----------------//");
  431 + };
  432 +
  433 + //----------------------- 初始化方法4,计算中标线位置 -------------------------//
  434 + var _iZbx_lpIndex; // 中标线对应第几个路牌
  435 +
  436 + var _fnInitFun4 = function() { // 初始化方法4
  437 + console.log("//---------------- 行车计划,初始化方法3 start ----------------//");
  438 +
  439 + //---------------------------- 1、模拟一个中标线,使用临时路牌 ----------------------//
  440 + // 构造中标线
  441 + // 中标线开始时间,就是方向的首班车时间
  442 + var oSt = !_qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();
  443 + // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向
  444 + // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向
  445 + var oEt;
  446 + if (_paramObj.getUpLastDtimeObj().isBefore(
  447 + _paramObj.getDownLastDTimeObj())) {
  448 + oEt = _paramObj.getDownLastDTimeObj();
  449 + } else {
  450 + oEt = _paramObj.getUpLastDtimeObj();
  451 + }
  452 +
  453 + var oTempLp = new InternalLpObj({lpNo: -999, lpName: "-999"}, _qCount, _qIsUp);
  454 + oTempLp.initDataFromTimeToTime(
  455 + oSt,
  456 + oEt,
  457 + !_qIsUp,
  458 + 0,
  459 + _paramObj,
  460 + _factory
  461 + );
  462 +
  463 + //------------------------ 2、找出中标线的早高峰班次,计算应该插在当前路牌数组的那个位置 ----------------//
  464 + // 找出中标线对应的早高峰的班次对象
  465 + var oZb_gf_bc = oTempLp.getBc(_approximate_zgfQIndex, _approximate_zgfBIndex);
  466 +
  467 + // 把所有连班路牌高峰班次重新构造成一个一个的圈数组,计算对应中标线最近的是第几个路牌
  468 + // 中标线和上标线一样在连班路牌上
  469 + var aTempq = [];
  470 + var oTempq;
  471 + var oTempb;
  472 + var i;
  473 + var oLp;
  474 +
  475 + var aLbIndexes = []; // 连班的路牌索引
  476 + for (i = 0; i < _internalLpArray.length; i++) {
  477 + if (_internalLpArray[i].isBxLb()) {
  478 + aLbIndexes.push(i);
  479 + }
  480 + }
  481 +
  482 + for (i = 0; i < aLbIndexes.length; i++) {
  483 + oLp = _internalLpArray[aLbIndexes[i]];
  484 +
  485 + oTempb = oLp.getBc(_approximate_zgfQIndex, _approximate_zgfBIndex);
  486 + if (oTempb.isUp() == _qIsUp) {
  487 + oTempq = new InternalGroupObj(oLp, _qIsUp, oTempb, undefined);
  488 + } else {
  489 + oTempq = new InternalGroupObj(oLp, _qIsUp, undefined, oTempb);
  490 + }
  491 + aTempq.push(oTempq);
  492 +
  493 + }
  494 +
  495 + var aTtindex = oTempLp.getgetQBcIndexWithFcTimeFromGroupArray(
  496 + oZb_gf_bc.getFcTimeObj(),
  497 + aTempq,
  498 + true,
  499 + true
  500 + );
  501 +
  502 + _iZbx_lpIndex = aLbIndexes[aTtindex[0]]; // 中标线放在第几个路牌
  503 + oTempLp.setLp(_lpArray[_iZbx_lpIndex]); // 设置原始路牌对象
  504 + oTempLp._$_aVerticalIntervalTime = _internalLpArray[_iZbx_lpIndex]._$_aVerticalIntervalTime; // 设置纵向最小发车间隔
  505 + oTempLp.setBxLb(_internalLpArray[_iZbx_lpIndex].isBxLb());
  506 + oTempLp.setBxFb(_internalLpArray[_iZbx_lpIndex].isBxFb());
  507 + oTempLp.setBxFb5_2(_internalLpArray[_iZbx_lpIndex].isBxFb5_2());
  508 +
  509 + // 修正除了第一个班次外,其余其他班次
  510 + var iBcindex = 0;
  511 + for (i = 1; i < _qCount; i++) {
  512 + while (iBcindex <= 1) {
  513 + if (oTempLp.getBc(i, iBcindex)) { // 替换存在的班次
  514 + oTempLp.setBc(i, iBcindex, _fnGenerateBc(_iZbx_lpIndex, i, iBcindex));
  515 + }
  516 + iBcindex ++;
  517 + }
  518 + iBcindex = 0;
  519 + }
  520 +
  521 + _internalLpArray[_iZbx_lpIndex] = oTempLp;
  522 +
  523 + console.log("中标线对应第" + (_iZbx_lpIndex + 1) + "个路牌");
  524 +
  525 + console.log("//---------------- 行车计划,初始化方法4 end ----------------//");
  526 + };
  527 +
  528 + //-------------------- 重要的内部方法 -----------------------//
  529 + /**
  530 + * 核心方法,利用路牌间隔纵向生成班次。
  531 + * @param iLpindex 路牌索引
  532 + * @param iQindex 圈索引
  533 + * @param iBcindex 班次索引
  534 + * @returns object InternalBcObj,失败 false
  535 + */
  536 + var _fnGenerateBc = function(iLpindex, iQindex, iBcindex) {
  537 + // 以上标线为起始点,使用路牌在不同圈,班次索引的发车间隔,计算班次
  538 + // 注意,发车间隔是指下一个班次应该距离当前班次间隔,是从下往上的
  539 +
  540 + // 1、参数验证
  541 + if (iLpindex == 0) { // 上标线的班次不需要生成
  542 + return false;
  543 + }
  544 +
  545 + // 2、计算间隔
  546 + var i;
  547 + var oLp;
  548 + var iTime = 0;
  549 + for (i = 0; i < iLpindex; i++) {
  550 + oLp = _internalLpArray[i];
  551 + iTime += oLp.fnGetVerticalIntervalTime(iQindex, iBcindex);
  552 + }
  553 +
  554 + // 3、生成班次
  555 + var _oKsbc = _internalLpArray[0].getBc(iQindex, iBcindex);
  556 + if (!_oKsbc) {
  557 + return false;
  558 + }
  559 + var _oKssj = _paramObj.addMinute(_oKsbc.getFcTimeObj(), iTime);
  560 + var _oBc = _factory.createBcObj(
  561 + _internalLpArray[iLpindex],
  562 + "normal", _oKsbc.isUp(),
  563 + 1, _oKssj, _paramObj);
  564 +
  565 + return _oBc;
  566 +
  567 + };
  568 +
  569 + /**
  570 + * 核心方法,在指定位置生成班次并添加到路牌指定位置中。
  571 + * @param lpIndex 第几个路牌
  572 + * @param qIndex 第几圈
  573 + * @param bcIndex 第几个班次
  574 + */
  575 + var _fnGenerateBcAndSetBc = function(lpIndex, qIndex, bcIndex) {
  576 + var _bcObj = _fnGenerateBc(lpIndex, qIndex, bcIndex);
  577 + if (_bcObj) {
  578 + _internalLpArray[lpIndex].setBc(qIndex, bcIndex, _bcObj);
  579 + }
  580 + };
  581 +
  582 +
  583 + /**
  584 + * 在指定位置生成班次(内部重要方法)。
  585 + * @param lpIndex 第几个路牌
  586 + * @param qIndex 第几圈
  587 + * @param bcIndex 第几个班次
  588 + * @returns InternalBcObj
  589 + */
  590 + var _generateBc = function(lpIndex, qIndex, bcIndex) {
  591 + // 在初始化布局后使用,否则没有参照班次加不了
  592 + // 初始化布局后,相当于把时刻表比作一个围棋棋盘,行为路牌数,列为圈数
  593 + // 上标线,中标线,早晚高峰已经布局在棋盘上,其余的空格可以创建班次
  594 +
  595 + // 这个生成班次是以上一班次时间,以发车间隔为基础添加的,纵向加
  596 + // 和生成标线时那种一直往后加班次时不一样,那种是以前一个班次为基础,横向加
  597 +
  598 + // 1、生成的班次以同一圈同一个方向里离它最早的班次的发车时间为基础
  599 + // 2、以每个路牌的纵向最小发车间隔时间为计算发车间隔
  600 + // 3、如果班次发车时间越界不管,有其余方法排除这种情况
  601 +
  602 + // 1、查找同圈同方向里最近的班次,找不到报错(因为有标线存在是不可能找不到的)
  603 + var _i;
  604 + var _bcObj;
  605 + for (_i = lpIndex - 1; _i >= 0; _i--) {
  606 + _bcObj = _internalLpArray[_i].getBc(qIndex, bcIndex);
  607 + if (_bcObj) {
  608 + break;
  609 + }
  610 + }
  611 + if (!_bcObj) {
  612 + return false;
  613 + //alert("无法在指定位置生成班次");
  614 + //throw "无法在路牌index=" + lpIndex + ",圈index=" + qIndex + ",班次index=" + bcIndex + "生成班次";
  615 + }
  616 +
  617 + // 2、计算发车间隔
  618 + var _intervalTime = 0;
  619 + for (_i = _i + 1; _i <= lpIndex; _i++) {
  620 + _intervalTime += _internalLpArray[_i].getVerticalMinIntervalTime();
  621 + }
  622 +
  623 + // 3、计算班次并添加班次
  624 + var _kssj = _paramObj.addMinute(_bcObj.getFcTimeObj(), _intervalTime);
  625 + _bcObj = _factory.createBcObj(
  626 + _internalLpArray[lpIndex],
  627 + "normal", _bcObj.isUp(),
  628 + 1, _kssj, _paramObj);
  629 + _bcObj.setGroup(_internalLpArray[lpIndex].getGroup(qIndex));
  630 +
  631 + return _bcObj;
  632 +
  633 + // TODO:这种添加班次的方法,可能造成相邻班次的停站时间问题
  634 + // TODO:主要是由于中标线的问题,但是误差不会很大,
  635 + // TODO:后面有方法直接调整停站时间(所谓的平滑过度时间)
  636 + };
  637 +
  638 + /**
  639 + * 在指定位置生成班次并添加到路牌指定位置中。
  640 + * @param lpIndex 第几个路牌
  641 + * @param qIndex 第几圈
  642 + * @param bcIndex 第几个班次
  643 + */
  644 + var _generateBcAndSetBc = function(lpIndex, qIndex, bcIndex) {
  645 + var _bcObj = _generateBc(lpIndex, qIndex, bcIndex);
  646 + _internalLpArray[lpIndex].setBc(qIndex, bcIndex, _bcObj);
  647 +
  648 + };
  649 +
  650 + /**
  651 + * 查找离指定时间最近的前面的班次索引信息
  652 + * @param timeObj 查找时间
  653 + * @param isUp 是否上行
  654 + * @returns [{路牌index},{圈index},{班次index}]
  655 + */
  656 + var _findUpClosedBcIndexWithTime = function(timeObj, isUp) {
  657 +
  658 + // dododo
  659 +
  660 + var _lpObj;
  661 + var _groupObj;
  662 + var _bcObj;
  663 + var _i;
  664 + var _j;
  665 + var timediff; // 时间差取绝对值
  666 +
  667 + var _lpIndex;
  668 + var _up_qIndex;
  669 + var _up_bIndex;
  670 +
  671 + for (_i = 0; _i < _qCount; _i++) {
  672 + for (_j = 0; _j < _internalLpArray.length; _j++) {
  673 + _lpObj = _internalLpArray[_j];
  674 + _groupObj = _lpObj.getGroup(_i);
  675 + _bcObj = isUp ? _groupObj.getBc1() : _groupObj.getBc2();
  676 + if (!_bcObj) { // 没有班次动态生成一个,可能生成不出的
  677 + _bcObj = _generateBc(_j, _i, isUp == _qIsUp ? 0 : 1);
  678 + }
  679 + if (_bcObj) {
  680 + if (timeObj.diff(_bcObj.getFcTimeObj()) >= 0) {
  681 + if (!timediff) {
  682 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  683 + _lpIndex = _j;
  684 + _up_qIndex = _i;
  685 + _up_bIndex = isUp == _qIsUp ? 0 : 1;
  686 + } else {
  687 + if (timeObj.diff(_bcObj.getFcTimeObj()) < timediff) {
  688 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  689 + _lpIndex = _j;
  690 + _up_qIndex = _i;
  691 + _up_bIndex = isUp == _qIsUp ? 0 : 1;
  692 + }
  693 + }
  694 + }
  695 + }
  696 + }
  697 + }
  698 +
  699 + if (_lpIndex == undefined) {
  700 + return false;
  701 + }
  702 +
  703 + var bcindex = [];
  704 + bcindex.push(_lpIndex);
  705 + bcindex.push(_up_qIndex);
  706 + bcindex.push(_up_bIndex);
  707 +
  708 + return bcindex;
  709 + };
  710 +
  711 + /**
  712 + * 查找离指定时间最近的后面的班次索引信息
  713 + * @param timeObj 查找时间
  714 + * @param isUp 是否上行
  715 + * @returns [{路牌index},{圈index},{班次index}]
  716 + */
  717 + var _findDownClosedBcIndexWithTime = function(timeObj, isUp) {
  718 + var _lpObj;
  719 + var _groupObj;
  720 + var _bcObj;
  721 + var _i;
  722 + var _j;
  723 + var timediff; // 时间差取绝对值
  724 +
  725 + var _lpIndex;
  726 + var _down_qIndex;
  727 + var _down_bIndex;
  728 +
  729 + var flag;
  730 +
  731 + for (_i = 0; _i < _qCount; _i++) {
  732 + for (_j = 0; _j < _internalLpArray.length; _j++) {
  733 + _lpObj = _internalLpArray[_j];
  734 + _groupObj = _lpObj.getGroup(_i);
  735 + _bcObj = isUp ? _groupObj.getBc1() : _groupObj.getBc2();
  736 + if (!_bcObj) { // 没有班次动态生成一个,可能生成不出的
  737 + _bcObj = _generateBc(_j, _i, isUp == _qIsUp ? 0 : 1);
  738 + }
  739 + if (_bcObj) {
  740 + //console.log("timeobj -> bcobj diff flag " +
  741 + // timeObj.format("HH:mm") + "->" +
  742 + // _bcObj.getFcTimeObj().format("HH:mm") +
  743 + // timeObj.diff(_bcObj.getFcTimeObj()) +
  744 + // (timeObj.diff(_bcObj.getFcTimeObj()) <= 0)
  745 + //);
  746 +
  747 + flag = (timeObj.diff(_bcObj.getFcTimeObj())) <= 0;
  748 +
  749 + if (flag) {
  750 + if (!timediff) {
  751 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  752 + _lpIndex = _j;
  753 + _down_qIndex = _i;
  754 + _down_bIndex = isUp == _qIsUp ? 0 : 1;
  755 + } else {
  756 + if ((timeObj.diff(_bcObj.getFcTimeObj())) > timediff) {
  757 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  758 + _lpIndex = _j;
  759 + _down_qIndex = _i;
  760 + _down_bIndex = isUp == _qIsUp ? 0 : 1;
  761 + }
  762 + }
  763 + }
  764 + }
  765 + }
  766 + }
  767 +
  768 + if (_lpIndex == undefined) {
  769 + return false;
  770 + }
  771 +
  772 + var bcindex = [];
  773 + bcindex.push(_lpIndex);
  774 + bcindex.push(_down_qIndex);
  775 + bcindex.push(_down_bIndex);
  776 +
  777 + return bcindex;
  778 + };
  779 +
  780 + return {
  781 + //------------- 布局初始化方法 ------------//
  782 + /**
  783 + * 初始化数据,使用标线初始化
  784 + */
  785 + fnInitDataWithBxLayout: function() {
  786 + // 初始化布局1,构造上标线,计算圈数,把上标线数据放入第一个路牌中
  787 + _fnInitFun1();
  788 + // 初始化布局2,从上标线的某个班次开始,构造所有路牌的早高峰班次,晚高峰班次,计算路牌在各个圈中的间隔
  789 + _fnInitFun2();
  790 + // 初始化布局3,计算连班分班路牌分布
  791 + _fnInitFun3();
  792 + // 初始化布局4,计算中标线位置
  793 + _fnInitFun4();
  794 +
  795 + },
  796 +
  797 + /**
  798 + * 调整高峰班次,
  799 + * 初始化生成早高峰,晚高峰班次并不准确,因为根据高峰时间段,并不在一个完整圈内,应该是在两个或多个圈之间
  800 + * 当初始化定好布局后(上标线,中标线),然后确定每个路牌的班型(连班,分班,5休2分班)后
  801 + * 然后重新计算框在高峰时间段内的班次索引,不足的添加,之前多加的删除(只删除分班路牌上的)
  802 + * @param isZgf 是否早高峰
  803 + * @param isUp 是否上行
  804 + */
  805 + fnAdjustGfbc : function(isZgf, isUp) {
  806 + var oStartTime; // 开始时间
  807 + var oEndTime; // 结束时间
  808 + var iStartBcIndex; // 开始班次索引
  809 + var iEndBcIndex; // 结束班次索引
  810 +
  811 + oStartTime = isZgf ? _paramObj.getMPeakStartTimeObj() : _paramObj.getEPeakStartTimeObj();
  812 + oEndTime = isZgf ? _paramObj.getMPeakEndTimeObj() : _paramObj.getEPeakEndTimeObj();
  813 +
  814 + aStartBcIndex = _findUpClosedBcIndexWithTime(oStartTime, isUp);
  815 + aEndBcIndex = _findDownClosedBcIndexWithTime(oEndTime, isUp);
  816 +
  817 + var iLpIndex;
  818 + var iQIndex;
  819 + var iBcIndex;
  820 + var iQInternelCount; // 高峰时间段中间包含的圈数
  821 + var i;
  822 + var j;
  823 +
  824 + var oLp;
  825 +
  826 + if (aStartBcIndex && aEndBcIndex) {
  827 + iLpIndex = aStartBcIndex[0];
  828 + iQIndex = aStartBcIndex[1];
  829 + iBcIndex = aStartBcIndex[2];
  830 +
  831 + // 处理头
  832 + // 删除头部多余班次
  833 + for (j = 0; j < iLpIndex; j++) {
  834 + oLp = _internalLpArray[j];
  835 + if (oLp.isBxFb() && oLp.getBc(iQIndex, iBcIndex)) {
  836 + oLp.removeBc(iQIndex, iBcIndex);
  837 + }
  838 + }
  839 +
  840 + for (j = iLpIndex; j < _internalLpArray.length; j++) {
  841 + oLp = _internalLpArray[j];
  842 + if (!oLp.getBc(iQIndex, iBcIndex)) {
  843 + _fnGenerateBcAndSetBc(j, iQIndex, iBcIndex);
  844 + }
  845 + }
  846 +
  847 + // 处理中间
  848 + iQInternelCount = aEndBcIndex[1] - aStartBcIndex[1] - 1;
  849 + for (i = 1; i <= iQInternelCount; i++) {
  850 + oLp = _internalLpArray[iQIndex + i];
  851 + if (!oLp.getBc(iQIndex + i, iBcIndex)) {
  852 + _fnGenerateBcAndSetBc(i, iQIndex + i, iBcIndex);
  853 + }
  854 + }
  855 +
  856 + // 处理尾部
  857 + iLpIndex = aEndBcIndex[0];
  858 + iQIndex = aEndBcIndex[1];
  859 + iBcIndex = aEndBcIndex[2];
  860 +
  861 + // 删除尾部多余的班次
  862 + for (j = iLpIndex; j < _internalLpArray.length; j++) {
  863 + oLp = _internalLpArray[j];
  864 + if (oLp.isBxFb() && oLp.getBc(iQIndex, iBcIndex)) {
  865 + oLp.removeBc(iQIndex, iBcIndex);
  866 + }
  867 + }
  868 +
  869 + if (aStartBcIndex[1] != aEndBcIndex[1]) { // 指定时间范围跨圈
  870 + for (j = 0; j < iLpIndex; j++) {
  871 + oLp = _internalLpArray[j];
  872 + if (!oLp.getBc(iQIndex, iBcIndex)) {
  873 + _fnGenerateBcAndSetBc(j, iQIndex, iBcIndex);
  874 + }
  875 + }
  876 + } else {
  877 + // 不跨圈,不用处理,处理头的时候已经加了
  878 + }
  879 +
  880 + }
  881 +
  882 + },
  883 +
  884 + /**
  885 + * 按照营运时间要求补充班次,
  886 + * 早高峰7:45分以前出场运营,
  887 + * 晚高峰16:10分以前出场运营
  888 + */
  889 + fnCalcuLpBc_yy: function() {
  890 + // 补班次的时候,针对的是分班班型
  891 + var i;
  892 + var _oLp;
  893 + var _oBc;
  894 + var _aMinBcIndex;
  895 + var _aMaxBcIndex;
  896 +
  897 + var _qIndex;
  898 + var _bIndex;
  899 +
  900 + var _zgfCDate = _paramObj.toTimeObj("7:45");
  901 + var _wgfCDate = _paramObj.toTimeObj("16:10");
  902 + var _ccsj;
  903 +
  904 + for (i = 0; i < _internalLpArray.length; i++) {
  905 + _oLp = _internalLpArray[i];
  906 + if (_oLp.isBxFb()) { // 分班路牌
  907 + // 早高峰部分
  908 + _aMinBcIndex = _oLp.getMinBcObjPosition();
  909 + _qIndex = _aMinBcIndex[0];
  910 + _bIndex = _aMinBcIndex[1];
  911 + _oBc = _oLp.getBc(_qIndex, _bIndex);
  912 + if (_qIsUp) {
  913 + _ccsj = _bIndex == 0 ?
  914 + _paramObj.getUpOutTime() :
  915 + _paramObj.getDownOutTime();
  916 + } else {
  917 + _ccsj = _bIndex == 0 ?
  918 + _paramObj.getDownOutTime() :
  919 + _paramObj.getUpOutTime();
  920 + }
  921 + if (_zgfCDate.isBefore(_paramObj.addMinute(_oBc.getFcTimeObj(), -_ccsj))) {
  922 + _fnGenerateBcAndSetBc(
  923 + i,
  924 + _bIndex == 0 ? _qIndex - 1 : _qIndex,
  925 + _bIndex == 0 ? 1 : 0
  926 + )
  927 + }
  928 +
  929 + // 晚高峰部分
  930 + _aMaxBcIndex = _oLp.getMaxBcObjPosition();
  931 + _qIndex = _aMaxBcIndex[0];
  932 + _bIndex = _aMaxBcIndex[1];
  933 + _oBc = _oLp.getBc(
  934 + _bIndex == 0 ? _qIndex - 1 : _qIndex,
  935 + _bIndex == 0 ? 1 : 0
  936 + );
  937 + if (!_oBc) { // 前一个班次不存在,再判定加不加
  938 + _oBc = _oLp.getBc(_qIndex, _bIndex);
  939 + if (_qIsUp) {
  940 + _ccsj = _bIndex == 0 ?
  941 + _paramObj.getUpOutTime() :
  942 + _paramObj.getDownOutTime();
  943 + } else {
  944 + _ccsj = _bIndex == 0 ?
  945 + _paramObj.getDownOutTime() :
  946 + _paramObj.getUpOutTime();
  947 + }
  948 + if (_wgfCDate.isBefore(_paramObj.addMinute(_oBc.getFcTimeObj(), -_ccsj))) {
  949 + _fnGenerateBcAndSetBc(
  950 + i,
  951 + _bIndex == 0 ? _qIndex - 1 : _qIndex,
  952 + _bIndex == 0 ? 1 : 0
  953 + )
  954 + }
  955 + }
  956 + }
  957 + }
  958 + },
  959 +
  960 + /**
  961 + * 补充做5休2的班型班次。
  962 + * 1、确认5_2班型大致多少圈(小数点过.7进位)
  963 + * 2、获取当前5_2两端车次链的信息,每段的班次数目,还差几个班次没加
  964 + * 3、如果前面的车次链班次少,则从前面的车次链开始加
  965 + * 4、如果车次链班次数一样,从从后面的车次链开始加
  966 + * 5、加班次时都是往车次链前方加
  967 + * 6、如果前面车次链不能再加班次了,从后面车次链加
  968 + */
  969 + fnCalcuLpBx_5_2: function() {
  970 + // 计算做5休2班型所需的班次数
  971 + var iBxBcount = _aBxDesc[6].fBcCount;
  972 + if (iBxBcount - Math.floor(iBxBcount) > 0.7) {
  973 + iBxBcount = Math.floor(iBxBcount) + 1;
  974 + } else {
  975 + iBxBcount = Math.floor(iBxBcount);
  976 + }
  977 +
  978 + var i;
  979 + var j;
  980 + var oLp;
  981 + var iAddBcCount;
  982 + var oBcChain1;
  983 + var oBcChain2;
  984 + var iQindex;
  985 + var iBindex;
  986 +
  987 + for (i = 0; i < _internalLpArray.length; i++) {
  988 + oLp = _internalLpArray[i];
  989 + if (oLp.isBxFb5_2()) {
  990 + iAddBcCount = iBxBcount - oLp.getBcArray().length; // 需要添加的班次数
  991 + for (j = 1; j <= iAddBcCount; j++) {
  992 + oBcChain1 = oLp.fnGetBcChainInfo(0);
  993 + oBcChain2 = oLp.fnGetBcChainInfo(1);
  994 +
  995 + if (oBcChain1.bcount < oBcChain2.bcount) {
  996 + iQindex = oBcChain1.s_b == 0 ? oBcChain1.s_q - 1 : oBcChain1.s_q;
  997 + iBindex = oBcChain1.s_b == 0 ? 1 : 0;
  998 + // 往车次链往前不能加,就往后加
  999 + if (_fnGenerateBc(i, iQindex, iBindex)) {
  1000 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1001 + } else {
  1002 + iQindex = oBcChain1.e_b == 0 ? oBcChain1.e_q : oBcChain1.e_q + 1;
  1003 + iBindex = oBcChain1.e_b == 0 ? 1 : 0;
  1004 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1005 + }
  1006 +
  1007 + } else if (oBcChain1.bcount > oBcChain2.bcount) {
  1008 + iQindex = oBcChain2.s_b == 0 ? oBcChain2.s_q - 1 : oBcChain2.s_q;
  1009 + iBindex = oBcChain2.s_b == 0 ? 1 : 0;
  1010 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1011 + } else {
  1012 + iQindex = oBcChain2.s_b == 0 ? oBcChain2.s_q - 1 : oBcChain2.s_q;
  1013 + iBindex = oBcChain2.s_b == 0 ? 1 : 0;
  1014 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1015 + }
  1016 + }
  1017 + }
  1018 + }
  1019 +
  1020 + },
  1021 +
  1022 + /**
  1023 + * 补其他分班班型班次。
  1024 + * 从车次链的后面开始加
  1025 + */
  1026 + fnCalcuLpBx_other: function() {
  1027 + // TODO:暂时使用做2休1的班型
  1028 + // 计算做5休2班型所需的班次数
  1029 + var iBxBcount = _aBxDesc[4].fBcCount;
  1030 + if (iBxBcount - Math.floor(iBxBcount) > 0.7) {
  1031 + iBxBcount = Math.floor(iBxBcount) + 1;
  1032 + } else {
  1033 + iBxBcount = Math.floor(iBxBcount);
  1034 + }
  1035 +
  1036 + var i;
  1037 + var j;
  1038 + var oLp;
  1039 + var iAddBcCount;
  1040 + var oBcChain1;
  1041 + var oBcChain2;
  1042 + var iQindex;
  1043 + var iBindex;
  1044 +
  1045 + for (i = 0; i < _internalLpArray.length; i++) {
  1046 + oLp = _internalLpArray[i];
  1047 + if (oLp.isBxFb() && !oLp.isBxFb5_2()) {
  1048 + iAddBcCount = iBxBcount - oLp.getBcArray().length; // 需要添加的班次数
  1049 + for (j = 1; j <= iAddBcCount; j++) {
  1050 + oBcChain1 = oLp.fnGetBcChainInfo(0);
  1051 + oBcChain2 = oLp.fnGetBcChainInfo(1);
  1052 +
  1053 + if (oBcChain1.bcount < oBcChain2.bcount) {
  1054 + iQindex = oBcChain1.e_b == 0 ? oBcChain1.e_q : oBcChain1.e_q + 1;
  1055 + iBindex = oBcChain1.e_b == 0 ? 1 : 0;
  1056 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1057 + } else if (oBcChain1.bcount > oBcChain2.bcount) {
  1058 + iQindex = oBcChain2.e_b == 0 ? oBcChain2.e_q : oBcChain2.e_q + 1;
  1059 + iBindex = oBcChain2.e_b == 0 ? 1 : 0;
  1060 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1061 + } else {
  1062 + iQindex = oBcChain2.e_b == 0 ? oBcChain2.e_q : oBcChain2.e_q + 1;
  1063 + iBindex = oBcChain2.e_b == 0 ? 1 : 0;
  1064 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1065 + }
  1066 + }
  1067 + }
  1068 + }
  1069 +
  1070 + },
  1071 +
  1072 + /**
  1073 + * 补充连班路牌班次。
  1074 + * 1、上标线,中标线中间的连班路牌班次从早高峰班次一直拉到底,从早高峰班次向上标线起始班次靠拢
  1075 + * 2、中标线以下的连班路牌班次从早高峰班次一直拉到底,从早高峰班次向中标线起始班次靠拢
  1076 + */
  1077 + fnCalcuLpBx_lb: function() {
  1078 + // 补充连班的班次,参照上标线,中标线补充不足的班次
  1079 +
  1080 + var aLbLpindexes = []; // 除上标线,中标线的连班路牌索引
  1081 + var i;
  1082 + for (i = 0; i < _internalLpArray.length; i++) {
  1083 + if (_internalLpArray[i].isBxLb() && i != 0 && i != _iZbx_lpIndex) {
  1084 + aLbLpindexes.push(i);
  1085 + }
  1086 + }
  1087 +
  1088 + var oEndsj = // 结束时间
  1089 + _paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj()) ?
  1090 + _paramObj.getDownLastDTimeObj() :
  1091 + _paramObj.getUpLastDtimeObj();
  1092 +
  1093 + var oLp;
  1094 + var aMinbcPos;
  1095 + var oBc;
  1096 + var j;
  1097 + var iTempBcIndex;
  1098 +
  1099 + // 1、从最小班次开始,往后补充班次
  1100 + for (i = 0; i < aLbLpindexes.length; i++) {
  1101 + oLp = _internalLpArray[aLbLpindexes[i]];
  1102 +
  1103 + // 最小班次索引
  1104 + aMinbcPos = oLp.getMinBcObjPosition();
  1105 + // 使用纵向分隔补充班次,从最小班次向后补
  1106 + iTempBcIndex = aMinbcPos[1] == 0 ? 1 : 0;
  1107 + j = iTempBcIndex == 0 ? aMinbcPos[0] + 1 : aMinbcPos[0];
  1108 +
  1109 + while (j < _qCount) {
  1110 + while (iTempBcIndex <= 1) {
  1111 + oBc = _fnGenerateBc(aLbLpindexes[i], j, iTempBcIndex);
  1112 + if (oBc &&
  1113 + oBc.getFcTimeObj().isBefore(oEndsj) &&
  1114 + oBc.getArrTimeObj().isBefore(oEndsj)) {
  1115 + oLp.setBc(j, iTempBcIndex, oBc);
  1116 + }
  1117 + iTempBcIndex++;
  1118 + }
  1119 + iTempBcIndex = 0;
  1120 + j++;
  1121 + }
  1122 +
  1123 + }
  1124 +
  1125 + // 2、上标线中标线之间的路牌,从最小的班次往前补充班次
  1126 +
  1127 + // 还要补充缺失的班次,差上标线几个班次要往前补上
  1128 + var iBccount;
  1129 + var iQindex;
  1130 + var iBindex;
  1131 + // 补上标线到中标线之间的连班路牌的班次
  1132 + for (i = 0; i < aLbLpindexes.length; i++) {
  1133 + if (aLbLpindexes[i] > 0 && aLbLpindexes[i] < _iZbx_lpIndex) {
  1134 + oLp = _internalLpArray[aLbLpindexes[i]];
  1135 + aMinbcPos = oLp.getMinBcObjPosition();
  1136 + iQindex = aMinbcPos[0];
  1137 + iBindex = aMinbcPos[1];
  1138 + iBccount = (iQindex - 1) * 2 + iBindex; // 距离上标线起始站点差几个班次
  1139 + for (j = 0; j < iBccount; j++) {
  1140 + if (iBindex == 0) {
  1141 + iQindex --;
  1142 + iBindex = 1;
  1143 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1144 + } else if (iBindex == 1) {
  1145 + iBindex --;
  1146 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1147 + }
  1148 + }
  1149 +
  1150 + }
  1151 +
  1152 + }
  1153 +
  1154 + // 3、中标线之后的路牌,从最小的班次往前补充班次
  1155 +
  1156 + // 补中标线以下的连班路牌的班次
  1157 + for (i = 0; i < aLbLpindexes.length; i++) {
  1158 + if (aLbLpindexes[i] > _iZbx_lpIndex) {
  1159 + oLp = _internalLpArray[aLbLpindexes[i]];
  1160 + aMinbcPos = oLp.getMinBcObjPosition();
  1161 + iQindex = aMinbcPos[0];
  1162 + iBindex = aMinbcPos[1];
  1163 + iBccount = (iQindex - 0) * 2 + iBindex - 1; // 距离上标线起始站点差几个班次
  1164 + for (j = 0; j < iBccount; j++) {
  1165 + if (iBindex == 0) {
  1166 + iQindex --;
  1167 + iBindex = 1;
  1168 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1169 + } else if (iBindex == 1) {
  1170 + iBindex --;
  1171 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1172 + }
  1173 + }
  1174 + }
  1175 + }
  1176 +
  1177 + },
  1178 +
  1179 + /**
  1180 + * 计算末班车(一般都落在连班班型上,因为按照现在的布局方法,分班路牌不会一直连到最后)。
  1181 + * 1、确定末班车早的班次
  1182 + * 2、从后往前找到与这个班次最匹配的班次的位置(第几个路牌,第几圈,第几个班次),然后覆盖
  1183 + * 3、从第2步找的位置,往上找与另一个末班车匹配的班次位置,然后覆盖
  1184 + */
  1185 + fnCalcuLastBc: function() {
  1186 + //-------------------- 1、确定末班车早的方向,时间 -----------------------//
  1187 + var _oLastTime;
  1188 + var _bLastIsUp;
  1189 + if (_paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj())) {
  1190 + _oLastTime = _paramObj.getUpLastDtimeObj();
  1191 + _bLastIsUp = true;
  1192 + } else {
  1193 + _oLastTime = _paramObj.getDownLastDTimeObj();
  1194 + _bLastIsUp = false;
  1195 + }
  1196 +
  1197 + //-------------------- 2、确定比 _oLastTime 小或者等于的班次位置,并修改班次时间到末班车时间 -----------------//
  1198 + var i;
  1199 + var j;
  1200 + var _oBc;
  1201 + var _oLp;
  1202 + var _aBcIndex;
  1203 +
  1204 + for (i = _qCount - 1; i >= 0; i--) {
  1205 + if (_aBcIndex) {
  1206 + break;
  1207 + }
  1208 + // 从大到小找到第一个合适的班次索引
  1209 + for (j = _internalLpArray.length - 1; j >= 0; j--) {
  1210 + _oLp = _internalLpArray[j];
  1211 + if (_oLp.isBxLb()) {
  1212 + _oBc = _oLp.getBc(i, _qIsUp == _bLastIsUp ? 0 : 1);
  1213 + }
  1214 + if (_oBc != undefined && _oBc.getFcTimeObj().isBefore(_oLastTime)) {
  1215 + _aBcIndex = [];
  1216 + _aBcIndex.push(j); // 路牌索引
  1217 + _aBcIndex.push(i); // 圈索引
  1218 + _aBcIndex.push(_qIsUp == _bLastIsUp ? 0 : 1); // 班次索引
  1219 + break;
  1220 + }
  1221 + }
  1222 + }
  1223 +
  1224 + //-------------------- 3、预估哪个个班次离末班最近,用末班替换,并删除后面的多余班次 -----------------//
  1225 + // 第2步找到的班次不一定是最适合的,需要把之后的班次模拟出来再比较一下
  1226 + var _aBcIndexes = []; // 里面放对象 {lpIndex,qIndex,bcIndex,fcsjTime}
  1227 + _oBc = undefined;
  1228 + for (i = _aBcIndex[0]; i < _internalLpArray.length; i++) {
  1229 + _oLp = _internalLpArray[i];
  1230 + if (_oLp.isBxLb()) {
  1231 + _oBc = _oLp.getBc(_aBcIndex[1], _aBcIndex[2]);
  1232 + if (_oBc == undefined) {
  1233 + _oBc = _fnGenerateBc(i, _aBcIndex[1], _aBcIndex[2]);
  1234 + }
  1235 + _aBcIndexes.push({
  1236 + lpIndex: i,
  1237 + qIndex: _aBcIndex[1],
  1238 + bcIndex: _aBcIndex[2],
  1239 + bcObj: _oBc
  1240 + })
  1241 + }
  1242 + }
  1243 + var _oBcIndex_find; // 第几个路牌离末班车最近
  1244 + for (i = _aBcIndexes.length - 1; i >= 0; i--) {
  1245 + if (_aBcIndexes[i].bcObj.getFcTimeObj().isBefore(_oLastTime)) {
  1246 + _oBcIndex_find = _aBcIndexes[i];
  1247 + break;
  1248 + }
  1249 + }
  1250 + // 替换成末班车
  1251 + _oBc = _oBcIndex_find.bcObj;
  1252 + _oBc.addMinuteToFcsj(_oLastTime.diff(_oBc.getFcTimeObj(), "m"));
  1253 + _internalLpArray[_oBcIndex_find.lpIndex].setBc(
  1254 + _oBcIndex_find.qIndex, _oBcIndex_find.bcIndex, _oBc
  1255 + );
  1256 +
  1257 + // 删除多余班次呢
  1258 + for (i = _oBcIndex_find.lpIndex + 1; i < _internalLpArray.length; i++) {
  1259 + _internalLpArray[i].removeBc(_oBcIndex_find.qIndex, _oBcIndex_find.bcIndex);
  1260 + }
  1261 +
  1262 + //---------------------- 4、从第3步找到的位置,开始往上找,确定另一个末班车,并删除后面多余的班次 -------------//
  1263 + // 因为另一个末班车时间晚,肯定在后面,并且必须在之前的路牌
  1264 + // 如果在之后的路牌,则意味着之前那个末班车位置不对,连班连起来会有两个之前的末班车
  1265 + // 计算大的末班车时间
  1266 + if (_paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj())) {
  1267 + _oLastTime = _paramObj.getDownLastDTimeObj();
  1268 + _bLastIsUp = false;
  1269 + } else {
  1270 + _oLastTime = _paramObj.getUpLastDtimeObj();
  1271 + _bLastIsUp = true;
  1272 + }
  1273 + _aBcIndexes = [];
  1274 + for (i = _oBcIndex_find.lpIndex; i >=0; i--) {
  1275 + _oLp = _internalLpArray[i];
  1276 + if (_oLp.isBxLb()) {
  1277 + _oBc = _oLp.getBc(
  1278 + _oBcIndex_find.bcIndex == 0 ? _oBcIndex_find.qIndex : _oBcIndex_find.qIndex + 1,
  1279 + _oBcIndex_find.bcIndex == 0 ? 1 : 0
  1280 + );
  1281 + if (_oBc == undefined) {
  1282 + _oBc = _fnGenerateBc(
  1283 + i,
  1284 + _oBcIndex_find.bcIndex == 0 ? _oBcIndex_find.qIndex : _oBcIndex_find.qIndex + 1,
  1285 + _oBcIndex_find.bcIndex == 0 ? 1 : 0
  1286 + );
  1287 + }
  1288 + if (!_oBc) { // 纵向生成班次失败,用横向生成班次,发车时间取前一班次的到达时间加停战时间
  1289 + _oBc = _factory.createBcObj(
  1290 + _oLp,
  1291 + "normal",
  1292 + _bLastIsUp,
  1293 + 3,
  1294 + _oLp.getBc(_oBcIndex_find.qIndex, _oBcIndex_find.bcIndex).getArrTimeObj(),
  1295 + _paramObj
  1296 + );
  1297 +
  1298 + }
  1299 + _aBcIndexes.push({
  1300 + lpIndex: i,
  1301 + qIndex: _oBcIndex_find.bcIndex == 0 ? _oBcIndex_find.qIndex : _oBcIndex_find.qIndex + 1,
  1302 + bcIndex: _oBcIndex_find.bcIndex == 0 ? 1 : 0,
  1303 + bcObj: _oBc
  1304 + })
  1305 + }
  1306 + }
  1307 +
  1308 + console.log(_aBcIndexes);
  1309 +
  1310 + _oBcIndex_find = _aBcIndexes[0];
  1311 +
  1312 + for (i = 0; i < _aBcIndexes.length; i++) {
  1313 + if (_aBcIndexes[i].bcObj.getFcTimeObj().isBefore(_oLastTime)) {
  1314 + _oBcIndex_find = _aBcIndexes[i];
  1315 + break;
  1316 + }
  1317 + }
  1318 + // 替换成末班车
  1319 + _oBc = _oBcIndex_find.bcObj;
  1320 + _oBc.addMinuteToFcsj(_oLastTime.diff(_oBc.getFcTimeObj(), "m"));
  1321 + _internalLpArray[_oBcIndex_find.lpIndex].setBc(
  1322 + _oBcIndex_find.qIndex, _oBcIndex_find.bcIndex, _oBc
  1323 + );
  1324 +
  1325 + // 删除多余班次呢
  1326 + for (i = _oBcIndex_find.lpIndex + 1; i < _internalLpArray.length; i++) {
  1327 + _internalLpArray[i].removeBc(_oBcIndex_find.qIndex, _oBcIndex_find.bcIndex);
  1328 + }
  1329 +
  1330 +
  1331 + },
  1332 +
  1333 + /**
  1334 + * 添加吃饭班次。
  1335 + */
  1336 + fnCalcuEatBc: function() {
  1337 + // 吃午饭时间范围,10:15 到 12:15
  1338 + // 吃晚饭时间范围,18:00 到 19:00
  1339 +
  1340 + if (!_paramObj.fnIsEat()) {
  1341 + return;
  1342 + }
  1343 +
  1344 + // 午饭index
  1345 + var aLEIndex;
  1346 + // 晚饭index
  1347 + var aDEIndex;
  1348 +
  1349 + // 所有吃饭都默认在一个方向,两个方向暂时不考虑
  1350 + if (_paramObj.fnIsUpEat()) {
  1351 + aLEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("10:15"), true, false);
  1352 + aDEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("18:00"), true, false);
  1353 + } else {
  1354 + aLEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("10:15"), false, true);
  1355 + aDEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("18:00"), false, true);
  1356 + }
  1357 +
  1358 + // 午饭第几圈,第几个班次
  1359 + var iLEQIndex = aLEIndex[0];
  1360 + var iLEBIndex = aLEIndex[1];
  1361 + // 晚饭第几圈,第几个班次
  1362 + var iDEQIndex = aDEIndex[0];
  1363 + var iDEBIndex = aDEIndex[1];
  1364 +
  1365 + // 注意,本模型只有连班才有吃饭
  1366 +
  1367 + var i;
  1368 + var oLp;
  1369 + var aLbIndex = []; // 连班班型的路牌索引
  1370 + for (i = 0; i < _internalLpArray.length; i++) {
  1371 + oLp = _internalLpArray[i];
  1372 + if (oLp.isBxLb()) {
  1373 + aLbIndex.push(i);
  1374 + }
  1375 + }
  1376 +
  1377 + var iLTime;
  1378 + var iDtime;
  1379 + var j;
  1380 + for (i = 0; i < aLbIndex.length; i++) {
  1381 + oLp = _internalLpArray[aLbIndex[i]];
  1382 +
  1383 + // 午饭
  1384 + iLTime = oLp.fnAddEatBc(iLEQIndex, iLEBIndex, _factory, _paramObj);
  1385 + // 晚饭
  1386 + iDtime = oLp.fnAddEatBc(iDEQIndex, iDEBIndex, _factory, _paramObj);
  1387 +
  1388 + if (i == aLbIndex.length - 1) {
  1389 + for (j = aLbIndex[i]; j < _internalLpArray.length; j++) {
  1390 + oLp = _internalLpArray[j];
  1391 + if (oLp.isBxFb()) { // 5休2班型不调整
  1392 + // 修正午饭之后路牌班次的发车时间
  1393 + oLp.fnAddMinuteToBcFcsj(iLEQIndex, iLEBIndex, iLTime);
  1394 + oLp.fnAddMinuteToBcFcsj(iDEQIndex, iDEBIndex, iDtime);
  1395 + }
  1396 + }
  1397 + } else {
  1398 + for (j = aLbIndex[i]; j < aLbIndex[i + 1]; j++) {
  1399 + oLp = _internalLpArray[j];
  1400 + if (oLp.isBxFb()) {
  1401 + // 修正午饭之后路牌班次的发车时间
  1402 + oLp.fnAddMinuteToBcFcsj(iLEQIndex, iLEBIndex, iLTime);
  1403 + oLp.fnAddMinuteToBcFcsj(iDEQIndex, iDEBIndex, iDtime);
  1404 + }
  1405 + }
  1406 + }
  1407 + }
  1408 +
  1409 + },
  1410 +
  1411 + /**
  1412 + * 补每个路牌的其他班次(进出场,例保班次)。
  1413 + */
  1414 + fnCalcuOtherBc: function() {
  1415 + var i;
  1416 + var _lpObj;
  1417 + var _minBcIndex;
  1418 + var _maxBcIndex;
  1419 + var _minBc;
  1420 + var _maxBc;
  1421 + var _otherbc = [];
  1422 +
  1423 + for (i = 0; i < _internalLpArray.length; i++) {
  1424 + _lpObj = _internalLpArray[i];
  1425 + _minBcIndex = _lpObj.getMinBcObjPosition();
  1426 + _maxBcIndex = _lpObj.getMaxBcObjPosition();
  1427 + _minBc = _lpObj.getBc(_minBcIndex[0], _minBcIndex[1]);
  1428 + _maxBc = _lpObj.getBc(_maxBcIndex[0], _maxBcIndex[1]);
  1429 +
  1430 + _otherbc = [];
  1431 + //_otherbc.push(_factory.createBcObj(
  1432 + // _lpObj, "bd", true, 1,
  1433 + // _minBc.getFcTimeObj(),
  1434 + // _paramObj
  1435 + //));
  1436 + _otherbc.push(_factory.createBcObj(
  1437 + _lpObj, "out", true, 1,
  1438 + _minBc.getFcTimeObj(),
  1439 + _paramObj
  1440 + ));
  1441 +
  1442 + _maxBc.setArrTimeObj(_paramObj.addMinute(_maxBc.getFcTimeObj(), _maxBc.getBcTime()));
  1443 + _maxBc.setStopTime(0);
  1444 + _otherbc.push(_factory.createBcObj(
  1445 + _lpObj, "in", true, 1,
  1446 + _maxBc.getArrTimeObj(),
  1447 + _paramObj
  1448 + ));
  1449 + //_otherbc.push(_factory.createBcObj(
  1450 + // _lpObj, "lc", true, 1,
  1451 + // _maxBc.getArrTimeObj(),
  1452 + // _paramObj
  1453 + //));
  1454 +
  1455 + _lpObj.addOtherBcArray(_otherbc);
  1456 + }
  1457 +
  1458 + },
  1459 +
  1460 + /**
  1461 + * 祛除上标线有删除标记的班次。
  1462 + */
  1463 + fnRemoveDelFlagBc: function() {
  1464 + var oLp = _internalLpArray[0];
  1465 + var aMinBcIndex = oLp.getMinBcObjPosition();
  1466 + oLp.removeBc(aMinBcIndex[0], aMinBcIndex[1]);
  1467 +
  1468 + var aMaxBcIndex = oLp.getMaxBcObjPosition();
  1469 + if (oLp.getBc(aMaxBcIndex[0], aMaxBcIndex[1]).fnIsDelFlag()) {
  1470 + oLp.removeBc(aMaxBcIndex[0], aMaxBcIndex[1]);
  1471 + }
  1472 + },
  1473 +
  1474 + /**
  1475 + * 调整班次纵向间隔(发车时间调整)。
  1476 + * 1、只调整分班班次的发车时间
  1477 + * 2、调整每两个连班之间的分班班次组
  1478 + * 3、如果不是连续的班次才调整
  1479 + */
  1480 + fnAdjust_vertical_bc_interval: function() {
  1481 + var i;
  1482 + var j;
  1483 + var iBIndex = 0;
  1484 + var oLbGroup = {};
  1485 + var oLp;
  1486 + for (i = 0; i < _qCount; i++) {
  1487 + while (iBIndex <= 1) {
  1488 + oLbGroup[i + "_" + iBIndex] = [];
  1489 + for (j = 0; j < _internalLpArray.length; j++) {
  1490 + oLp = _internalLpArray[j];
  1491 + if (oLp.isBxLb()) {
  1492 + if (oLp.getBc(i, iBIndex)) {
  1493 + oLbGroup[i + "_" + iBIndex].push(j);
  1494 + }
  1495 + }
  1496 + }
  1497 + if (oLbGroup[i + "_" + iBIndex].length == 1) {
  1498 + oLbGroup[i + "_" + iBIndex] = [];
  1499 + }
  1500 +
  1501 + iBIndex ++;
  1502 + }
  1503 + iBIndex = 0;
  1504 + }
  1505 +
  1506 + //console.log(oLbGroup);
  1507 +
  1508 + var sKey;
  1509 + var iQindex;
  1510 + var iBindex;
  1511 + var aBcLb = [];
  1512 +
  1513 + var oLbGroup_m = {};
  1514 + var aLbGroup = [];
  1515 +
  1516 +
  1517 + // 计算需要调整的连班区间
  1518 + for (sKey in oLbGroup) {
  1519 + iQindex = sKey.split('_')[0];
  1520 + iBindex = sKey.split('_')[1];
  1521 + oLbGroup_m[sKey] = [];
  1522 + for (i = 0; i < oLbGroup[sKey].length - 1; i++) {
  1523 + aBcLb = [];
  1524 + for (j = oLbGroup[sKey][i] + 1; j <= oLbGroup[sKey][i + 1] - 1; j++) {
  1525 + oLp = _internalLpArray[j];
  1526 + if (oLp.getBc(iQindex, iBindex)) {
  1527 + aBcLb.push(j);
  1528 + }
  1529 + }
  1530 + if (aBcLb.length != 0 && aBcLb.length < (oLbGroup[sKey][i + 1] - oLbGroup[sKey][i] - 1)) {
  1531 + aLbGroup = [];
  1532 + aLbGroup.push(oLbGroup[sKey][i]);
  1533 + aLbGroup.push(oLbGroup[sKey][i + 1]);
  1534 + aLbGroup.push(aBcLb);
  1535 + oLbGroup_m[sKey].push(aLbGroup);
  1536 + }
  1537 + }
  1538 + }
  1539 +
  1540 + console.log(oLbGroup_m);
  1541 +
  1542 + var iStartLpIndex;
  1543 + var iEndLpIndex;
  1544 + var iDCount;
  1545 + var iDiffTime;
  1546 +
  1547 + var iC1;
  1548 + var iC2;
  1549 + var oKssj;
  1550 +
  1551 + for (sKey in oLbGroup_m) {
  1552 + iQindex = sKey.split('_')[0];
  1553 + iBindex = sKey.split('_')[1];
  1554 +
  1555 + for (i = 0; i < oLbGroup_m[sKey].length; i++) {
  1556 + aLbGroup = oLbGroup_m[sKey][i];
  1557 +
  1558 + iStartLpIndex = aLbGroup[0];
  1559 + iEndLpIndex = aLbGroup[1];
  1560 + iDCount = aLbGroup[2].length + 1;
  1561 +
  1562 + iDiffTime = _internalLpArray[iEndLpIndex].getBc(iQindex, iBindex).getFcTimeObj().diff(
  1563 + _internalLpArray[iStartLpIndex].getBc(iQindex, iBindex).getFcTimeObj(), 'm');
  1564 +
  1565 + iC1 = Math.floor(iDiffTime / iDCount);
  1566 + iC2 = iDiffTime % iDCount;
  1567 + oKssj = _internalLpArray[iStartLpIndex].getBc(iQindex, iBindex).getFcTimeObj();
  1568 +
  1569 + for (j = 1; j <= iDCount - iC2; j++) {
  1570 + if (j - 1 < aLbGroup[2].length) {
  1571 + oKssj = _paramObj.addMinute(oKssj, iC1);
  1572 + _internalLpArray[aLbGroup[2][j - 1]].getBc(
  1573 + iQindex, iBindex).setFcTimeObj(oKssj);
  1574 + }
  1575 + }
  1576 +
  1577 + for (j = 1; j < iC2; j++) {
  1578 + oKssj = _paramObj.addMinute(oKssj, iC1 + 1);
  1579 + _internalLpArray[aLbGroup[2][iDCount - iC2 + j - 1]].getBc(
  1580 + iQindex, iBindex).setFcTimeObj(oKssj);
  1581 + }
  1582 +
  1583 + }
  1584 + }
  1585 +
  1586 + },
  1587 +
  1588 + //------------- 其他方法 -------------//
  1589 + /**
  1590 + * 内部数据转化成显示用的班次数组。
  1591 + */
  1592 + fnToGanttBcArray: function() {
  1593 + var aAllBc = [];
  1594 + var aLpBc = [];
  1595 + var oLp;
  1596 + var i;
  1597 + var j;
  1598 +
  1599 + for (i = 0; i < _internalLpArray.length; i++) {
  1600 + oLp = _internalLpArray[i];
  1601 + aLpBc = [];
  1602 + aLpBc = aLpBc.concat(oLp.getOtherBcArray(), oLp.getBcArray());
  1603 + // 按照发车时间排序
  1604 + aLpBc.sort(function(o1, o2) {
  1605 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1606 + return -1;
  1607 + } else {
  1608 + return 1;
  1609 + }
  1610 + });
  1611 +
  1612 + // 重新赋值fcno
  1613 + for (j = 0; j < aLpBc.length; j++) {
  1614 + aLpBc[j].fnSetFcno(j + 1);
  1615 + }
  1616 +
  1617 + aAllBc = aAllBc.concat(aLpBc);
  1618 + }
  1619 +
  1620 + var aGanttBc = [];
  1621 + for (i = 0; i < aAllBc.length; i++) {
  1622 + aGanttBc.push(aAllBc[i].toGanttBcObj());
  1623 + }
  1624 +
  1625 + return aGanttBc;
  1626 + }
  1627 +
  1628 + };
  1629 +
976 1630 };
977 1631 \ No newline at end of file
... ...
src/main/resources/static/pages/base/timesmodel/js/v2/main_v2.js
1   -/**
2   - * 主类。
3   - */
4   -var Main_v2 = function() {
5   - // 内部工厂类
6   - var _factoryFun = function() {
7   - return {
8   - // 创建参数
9   - createParameterObj: function(formMap, dataMap) {
10   - var paramObj = ParameterObj();
11   - paramObj.wrap(formMap, dataMap);
12   - return paramObj;
13   - },
14   - // 创建班次对象
15   - createBcObj: function(lpObj, bcType, isUp, fcno, fcTimeObj, paramObj) {
16   - var _bclc = paramObj.calcuTravelLcNumber(isUp, bcType);
17   - var _bcsj = paramObj.calcuTravelTime(fcTimeObj, isUp);
18   - var _arrsj = paramObj.addMinute(fcTimeObj, _bcsj);
19   - var _stoptime = paramObj.calcuFixedStopNumber(_arrsj, !isUp);
20   - var _tccid = paramObj.getTTinfoId();
21   - var _ttinfoid = paramObj.getTTinfoId();
22   - var _xl = paramObj.getXlId();
23   - var _qdz = isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;
24   - var _zdz = isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;
25   -
26   - var bcParamObj = {};
27   - bcParamObj.bcType = bcType; // 班次类型(normal,in,out等)
28   - bcParamObj.isUp = isUp; // boolean是否上下行
29   - bcParamObj.fcno = fcno; // 发车顺序号
30   - bcParamObj.fcTimeObj = fcTimeObj; // 发车时间对象
31   - bcParamObj.bclc = _bclc; // 班次里程
32   - bcParamObj.bcsj = _bcsj; // 班次历时
33   - bcParamObj.arrtime = _arrsj; // 到达时间对象
34   - bcParamObj.stoptime = _stoptime; // 停站时间
35   - bcParamObj.tccid = _tccid; // 停车场id
36   - bcParamObj.ttinfoid = _ttinfoid; // 时刻表id
37   - bcParamObj.xl = _xl; // 线路id
38   - bcParamObj.qdzid = _qdz; // 起点站id
39   - bcParamObj.zdzid = _zdz; // 终点站id
40   -
41   - return new InternalBcObj(lpObj, bcParamObj);
42   - }
43   - };
44   - };
45   - var _factory = _factoryFun();
46   -
47   - // 所有的时间使用moment.js计算
48   -
49   - var _paramObj; // 参数对象
50   -
51   - var _bxDesc = [ // 班型描述
52   - {'type':'六工一休','hoursV':6.66, 'minueV':'6:40', 'qcount': 0, 'avertime': 0},
53   - {'type':'五工一休','hoursV':6.85, 'minueV':'6:51', 'qcount': 0, 'avertime': 0},
54   - {'type':'四工一休','hoursV':7.14, 'minueV':'7:08', 'qcount': 0, 'avertime': 0},
55   - {'type':'三工一休','hoursV':7.61, 'minueV':'7:37', 'qcount': 0, 'avertime': 0},
56   - {'type':'二工一休','hoursV':8.57, 'minueV':'8:34', 'qcount': 0, 'avertime': 0},
57   - {'type':'一工一休','hoursV':11.42, 'minueV':'11:25', 'qcount': 0, 'avertime': 0},
58   - {'type':'五工二休','hoursV':7.99, 'minueV':'8:00', 'qcount': 0, 'avertime': 0},
59   - {'type':'无工休', 'hoursV':5.43, 'minueV':'5:43', 'qcount': 0, 'avertime': 0}
60   - ];
61   -
62   - return {
63   - /**
64   - * 工厂对象,创建不同的对象。
65   - * @returns {{createParameterObj, createBcObj}}
66   - */
67   - getFactory: function() {
68   - return _factory;
69   - },
70   -
71   - /**
72   - * 使用发车间隔策略生成时刻表。
73   - * @param paramObj 参数对象
74   - * @param lpArray 路牌数组
75   - * @constructor
76   - */
77   - BXPplaceClassesTime03 : function(paramObj, lpArray) {
78   - // 参数对象
79   - _paramObj = paramObj;
80   -
81   - // 1、初始化行车计划
82   - var schedule = new InternalScheduleObj(_paramObj, lpArray, _factory);
83   - schedule.initDataWithBxLayout();
84   - // 2、计算每个路牌的班型及对应工时
85   - schedule.calcuLpBx_fg();
86   - // 3、将连班路牌的班次补足
87   - schedule.calcuLpBx_lb();
88   -
89   - // 4、修正针对初始化时生成的高峰班次,之前不足的补上,多余的删除
90   - schedule.adjustGfbc(true, true); // 修正上行早高峰
91   - schedule.adjustGfbc(true, false); // 修正下行早高峰
92   - schedule.adjustGfbc(false, true); // 修正上行晚高峰
93   - schedule.adjustGfbc(false, false); // 修正下行晚高峰
94   -
95   - // 5、TODO:根据班型补充所有的不足班次
96   - schedule.calcuLpBx_5_2();
97   -
98   - // TODO:6、确定末班车
99   -
100   - // TODO:8、修正不准确的停站时间,微调发车间隔
101   -
102   - // TODO:9、补进出场报道班次
103   -
104   -
105   - //-------------------- 输出ganut图上的班次,班型描述 ----------------------//
106   - var gBcData = schedule.toGanttBcArray();
107   - // TODO:班型再议
108   - return {'json':gBcData,'bxrcgs':null};
109   -
110   - }
111   -
112   - };
113   -
  1 +/**
  2 + * 主类。
  3 + */
  4 +var Main_v2 = function() {
  5 +
  6 + // 内部工厂类
  7 + var _factoryFun = function() {
  8 + return {
  9 + // 创建参数
  10 + createParameterObj: function(formMap, dataMap) {
  11 + var paramObj = ParameterObj();
  12 + paramObj.wrap(formMap, dataMap);
  13 + return paramObj;
  14 + },
  15 + // 创建班次对象
  16 + createBcObj: function(lpObj, bcType, isUp, fcno, fcTimeObj, paramObj) {
  17 + var _bclc = paramObj.calcuTravelLcNumber(isUp, bcType);
  18 + var _fcsj = fcTimeObj;
  19 + var _bcsj = paramObj.calcuTravelTime(_fcsj, isUp);
  20 + var _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  21 + var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, _bcsj);
  22 + var _tccid = paramObj.getTTinfoId();
  23 + var _ttinfoid = paramObj.getTTinfoId();
  24 + var _xl = paramObj.getXlId();
  25 + var _qdz = isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;
  26 + var _zdz = isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;
  27 +
  28 + if (bcType == "bd") { // 早例保,传过来的发车时间是第一个班次的发车时间
  29 + if (isUp) { // 上行
  30 + _fcsj = paramObj.addMinute(
  31 + _fcsj,
  32 + -(paramObj.getUpOutTime() + paramObj.getLbTime()));
  33 + _bcsj = paramObj.getLbTime();
  34 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  35 + _stoptime = 0;
  36 + } else { // 下行
  37 + _fcsj = paramObj.addMinute(
  38 + _fcsj,
  39 + -(paramObj.getDownOutTime() + paramObj.getLbTime()));
  40 + _bcsj = paramObj.getLbTime();
  41 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  42 + _stoptime = 0;
  43 + }
  44 + } else if (bcType == "lc") { // 晚例保,传过来的发车时间是最后一个班次的到达时间
  45 + if (isUp) { // 上行
  46 + _fcsj = paramObj.addMinute(
  47 + _fcsj,
  48 + paramObj.getUpInTime());
  49 + _bcsj = paramObj.getLbTime();
  50 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  51 + _stoptime = 0;
  52 + } else { // 下行
  53 + _fcsj = paramObj.addMinute(
  54 + _fcsj,
  55 + paramObj.getDownInTime());
  56 + _bcsj = paramObj.getLbTime();
  57 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  58 + _stoptime = 0;
  59 + }
  60 + } else if (bcType == "out") { // 出场,传过来的发车时间是第一个班次的发车时间
  61 + if (isUp) { // 上行
  62 + _fcsj = paramObj.addMinute(
  63 + _fcsj,
  64 + -paramObj.getUpOutTime());
  65 + _bcsj = paramObj.getUpOutTime();
  66 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  67 + _stoptime = 0;
  68 + } else { // 下行
  69 + _fcsj = paramObj.addMinute(
  70 + _fcsj,
  71 + -paramObj.getDownOutTime());
  72 + _bcsj = paramObj.getDownOutTime();
  73 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  74 + _stoptime = 0;
  75 + }
  76 + } else if (bcType == "in") { // 进场,传过来的发车时间是最后一个班次的到达时间
  77 + if (isUp) { // 上行
  78 + _bcsj = paramObj.getUpInTime();
  79 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  80 + _stoptime = 0;
  81 + } else { // 下行
  82 + _bcsj = paramObj.getDownInTime();
  83 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  84 + _stoptime = 0;
  85 + }
  86 + } else if (bcType == "cf") { // 吃饭班次
  87 + // 以13:00为分界,之前的为午饭,之后的为晚饭
  88 + if (fcTimeObj.isBefore(paramObj.toTimeObj("13:00"))) {
  89 + _bcsj = paramObj.fnGetLunchTime();
  90 + } else {
  91 + _bcsj = paramObj.fnGetDinnerTime();
  92 + }
  93 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  94 + _stoptime = 0;
  95 + }
  96 +
  97 + var bcParamObj = {};
  98 + bcParamObj.bcType = bcType; // 班次类型(normal,in_,out, bd, lc, cf等)
  99 + bcParamObj.isUp = isUp; // boolean是否上下行
  100 + bcParamObj.fcno = fcno; // 发车顺序号
  101 + bcParamObj.fcTimeObj = _fcsj; // 发车时间对象
  102 + bcParamObj.bclc = _bclc; // 班次里程
  103 + bcParamObj.bcsj = _bcsj; // 班次历时
  104 + bcParamObj.arrtime = _arrsj; // 到达时间对象
  105 + bcParamObj.stoptime = _stoptime; // 停站时间
  106 + bcParamObj.tccid = _tccid; // 停车场id
  107 + bcParamObj.ttinfoid = _ttinfoid; // 时刻表id
  108 + bcParamObj.xl = _xl; // 线路id
  109 + bcParamObj.qdzid = _qdz; // 起点站id
  110 + bcParamObj.zdzid = _zdz; // 终点站id
  111 +
  112 + return new InternalBcObj(lpObj, bcParamObj);
  113 + }
  114 + };
  115 + };
  116 + var _factory = _factoryFun();
  117 +
  118 + // 所有的时间使用moment.js计算
  119 +
  120 + var _paramObj; // 参数对象
  121 +
  122 + var _bxDesc = [ // 班型描述
  123 + {'type':'六工一休','hoursV':6.66, 'minueV':'6:40', 'qcount': 0, 'avertime': 0},
  124 + {'type':'五工一休','hoursV':6.85, 'minueV':'6:51', 'qcount': 0, 'avertime': 0},
  125 + {'type':'四工一休','hoursV':7.14, 'minueV':'7:08', 'qcount': 0, 'avertime': 0},
  126 + {'type':'三工一休','hoursV':7.61, 'minueV':'7:37', 'qcount': 0, 'avertime': 0},
  127 + {'type':'二工一休','hoursV':8.57, 'minueV':'8:34', 'qcount': 0, 'avertime': 0},
  128 + {'type':'一工一休','hoursV':11.42, 'minueV':'11:25', 'qcount': 0, 'avertime': 0},
  129 + {'type':'五工二休','hoursV':7.99, 'minueV':'8:00', 'qcount': 0, 'avertime': 0},
  130 + {'type':'无工休', 'hoursV':5.43, 'minueV':'5:43', 'qcount': 0, 'avertime': 0}
  131 + ];
  132 +
  133 + return {
  134 + /**
  135 + * 工厂对象,创建不同的对象。
  136 + * @returns {{createParameterObj, createBcObj}}
  137 + */
  138 + getFactory: function() {
  139 + return _factory;
  140 + },
  141 +
  142 + /**
  143 + * 使用发车间隔策略生成时刻表。
  144 + * @param paramObj 参数对象
  145 + * @param lpArray 路牌数组
  146 + * @constructor
  147 + */
  148 + BXPplaceClassesTime03 : function(paramObj, lpArray) {
  149 + // 参数对象
  150 + _paramObj = paramObj;
  151 +
  152 + // 1、初始化行车计划
  153 + var schedule = new InternalScheduleObj(_paramObj, lpArray, _factory);
  154 + schedule.fnInitDataWithBxLayout();
  155 + // 2、将连班路牌的班次补足
  156 + schedule.fnCalcuLpBx_lb();
  157 +
  158 + // 3、修正针对初始化时生成的高峰班次,之前不足的补上,多余的删除
  159 + schedule.fnAdjustGfbc(true, true); // 修正上行早高峰
  160 + schedule.fnAdjustGfbc(true, false); // 修正下行早高峰
  161 + schedule.fnAdjustGfbc(false, true); // 修正上行晚高峰
  162 + schedule.fnAdjustGfbc(false, false); // 修正下行晚高峰
  163 +
  164 + // 4、按照车辆投入运营要求补充班次
  165 + schedule.fnCalcuLpBc_yy();
  166 +
  167 + // 5、根据班型补充所有的不足班次
  168 + schedule.fnCalcuLpBx_5_2();
  169 + schedule.fnCalcuLpBx_other();
  170 +
  171 + // 6、补吃饭班次
  172 + schedule.fnCalcuEatBc();
  173 +
  174 + // 7、祛除有删除标记的班次
  175 + schedule.fnRemoveDelFlagBc();
  176 +
  177 + // 8、调整纵向班次间隔
  178 + schedule.fnAdjust_vertical_bc_interval();
  179 + // TODO:横向调整
  180 +
  181 + // 9、确定末班车
  182 + schedule.fnCalcuLastBc();
  183 +
  184 + // 10、补进出场例保班次
  185 + schedule.fnCalcuOtherBc();
  186 +
  187 + //-------------------- 输出ganut图上的班次,班型描述 ----------------------//
  188 + var gBcData = schedule.fnToGanttBcArray();
  189 + // TODO:班型再议
  190 + return {'json':gBcData,'bxrcgs':null};
  191 +
  192 + }
  193 +
  194 + };
  195 +
114 196 }();
115 197 \ No newline at end of file
... ...
src/main/resources/static/pages/base/timesmodel/js/v3/core/timetable_bc_obj.js 0 → 100644
  1 +/**
  2 + * 时刻表内部班次对象。
  3 + * @param iLpIndex 路牌索引
  4 + * @param iGroupIndex 圈索引
  5 + * @param oParam 其他参数对象
  6 + * @constructor
  7 + */
  8 +var TimeTableBc = function(
  9 + iLpIndex,
  10 + iGroupIndex,
  11 + oParam
  12 +) {
  13 + // 简单验证
  14 + if (isNaN(iLpIndex)) {
  15 + throw "new TimeTableBc 路牌索引" + iLpIndex + " 不是int";
  16 + }
  17 + if (isNaN(iGroupIndex)) {
  18 + throw "new TimeTableBc 圈索引" + iGroupIndex + " 不是int";
  19 + }
  20 + if (typeof oParam == "undefined") {
  21 + throw "new TimeTableBc 其他参数对象" + oParam + " 未定义";
  22 + }
  23 +
  24 + /** 路牌索引 */
  25 + this._$_iLpIndex = iLpIndex;
  26 + /** 圈索引 */
  27 + this._$_iGroupIndex = iGroupIndex;
  28 +
  29 + // 其他参数对象关联的内部参数
  30 +
  31 + /** 班次类型(normal,in,out等) */
  32 + this._$_sBcType = otherParamObj.bcType;
  33 + /** 是否上下行 */
  34 + this._$_bIsUp = otherParamObj.isUp;
  35 + /** 发车顺序号 */
  36 + this._$_iFcno = otherParamObj.fcno;
  37 + /** 发车时间对象 */
  38 + this._$_oFcsjObj = moment(otherParamObj.fcTimeObj);
  39 + /** 班次里程 */
  40 + this._$_flBclc = otherParamObj.bclc;
  41 + /** 班次历时 */
  42 + this._$_iBcsj = otherParamObj.bcsj;
  43 + /** 到达时间对象 */
  44 + this._$_oArrtime = otherParamObj.arrtime;
  45 + /** 停站时间 */
  46 + this._$_iStoptime = otherParamObj.stoptime;
  47 + /** 停车场id */
  48 + this._$_iTccid = otherParamObj.tccid;
  49 + /** 时刻表id */
  50 + this._$_iTtinfoid = otherParamObj.ttinfoid;
  51 + /** 线路id */
  52 + this._$_iXlid = otherParamObj.xl;
  53 + /** 起点站id */
  54 + this._$_iQdzid = otherParamObj.qdzid;
  55 + /** 终点站id */
  56 + this._$_iZdzid = otherParamObj.zdzid;
  57 +
  58 +};
  59 +
  60 +// TODO
0 61 \ No newline at end of file
... ...
src/main/resources/static/pages/base/timesmodel/js/v3/core/timetable_group_obj.js 0 → 100644
  1 +
  2 +// TODO
  3 +var TimeTableGroup = function() {
  4 +
  5 + /** 一圈几个班次(2个) */
  6 + this._$_iUnitBcCount = 2;
  7 + /** 是否上行(指圈的第一个班次是否上行) */
  8 + this._$_bIsUp;
  9 +
  10 + /** 圈组的开始时间(初始化一般由上标线确定,如:06:00,开始时间计算时是闭区间) */
  11 + this._$_oUnitGroupStartTime;
  12 + /** 圈组的结束时间(初始化一般由上标线确定,如:08:41,结束时间计算时是开区间) */
  13 + this._$_oUnitGroupEndTime;
  14 +
  15 + /** 圈组里圈班次可能的总数目(初始化确定,有几个路牌,一个圈组就有几圈-纵向看) */
  16 + this._$_iAllUnitCount;
  17 + /** 圈组里所有可能班次数组(二维数组,行一班表示有几个路牌,列就表示一圈2个班次) */
  18 + this._$_aAllUnitBces = new Array(this._$_iAllUnitBcCount, this._$_iUnitBcCount);
  19 +
  20 + /** 圈组里每圈之间的发车间隔值数组(第一个间隔为0,上下行一样) */
  21 + this._$_aUnitIntervalTime = new Array(this._$_iAllUnitCount);
  22 +
  23 + // TODO
  24 +};
  25 +
  26 +// TODO
0 27 \ No newline at end of file
... ...
src/main/resources/static/pages/base/timesmodel/js/v3/core/timetable_lp_obj.js 0 → 100644
  1 +
  2 +
  3 +// TODO
  4 +var TimeTableLp = function() {
  5 +
  6 + /** 班次可能的总数目(初始化确定) */
  7 + this._$_iAllBcCount;
  8 + /** 所有可能班次数组 */
  9 + this._$_aAllBces = new Array(this._$_iAllBcCount);
  10 +
  11 + /** 车次链的个数 */
  12 + this._$_iBcChainCount;
  13 + /** 车次链数组(每个车次链又是一个数组) */
  14 + this._$_aBcChaines;
  15 +
  16 + // TODO
  17 +};
  18 +
  19 +// TODO
0 20 \ No newline at end of file
... ...
src/main/resources/static/pages/base/timesmodel/js/v3/core/timetable_schedule_obj.js 0 → 100644
src/main/resources/static/pages/base/timesmodel/js/v3/main.js 0 → 100644
src/main/resources/static/pages/base/timesmodel/js/v3/param/param_wrap.js 0 → 100644