Commit be2c4b67f2bb4692ee1b5c286ffe67aa4dd9b451

Authored by 徐烜
1 parent ceb8a823

时刻表v2.3

基本实现让班次间隔平滑过渡,但是有些周转班次时间还是有问题,以后修正
1、将吃饭时间作为班次对象的一个属性,类似停站时间,参与计算下一个班次的发车时间,在最后绘制gantt图的时候再动态添加吃饭班次
2、修正从头拉班次的算法(主要是创建上标线,中标线的方法),修正终止条件,只需判定下一个班次的发车时间是否超过endtime,不需再判定下一个班次的到达时间是否超过endtime
3、添加调整单个路牌横向班次周转时间方法(简单调整停站时间,这个方法以后还要改)
4、添加调整所有纵向班次的间隔时间方法,采用3个班次2个间隔趋于平均,让后分别迭代两个方向上的所有班次(算法没有考虑横向间隔-与第3点联动,但是初期试验下来效果还可以,以后优化)
5、添加调整指定时间后所有班次间隔方法,采用平均化所有班次间隔(主要处理晚高峰过后的班次,19:50后的班次,初期效果还可以,以后优化)
6、修改确定末班车班次的方法(比之前的效果好,以后再优化)
7、将删除标记参数分为两步,删除开头的,删除结尾的,将删除结尾的方法调用放在确定末班车之后,因为结尾的删除标记班次可能会被修正为末班车
src/main/resources/static/pages/base/timesmodel/js/v2/ParameterObj.js
... ... @@ -895,7 +895,7 @@ var ParameterObj = function() {
895 895 },
896 896  
897 897 /**
898   - * 获取固定的停站时间(固定停站时间都是选的最大值
  898 + * 获取固定的停站时间(固定停站时间都是选的最大值,非平均停站
899 899 * @param oTimeObj 时间对象
900 900 * @param bIsUp 是否上行
901 901 * @param iXXTime 行驶时间
... ... @@ -1082,6 +1082,85 @@ var ParameterObj = function() {
1082 1082 },
1083 1083  
1084 1084 /**
  1085 + * 获取固定的停站时间(固定停站时间都是选的最小值,非平均停站)
  1086 + * @param oTimeObj 时间对象
  1087 + * @param bIsUp 是否上行
  1088 + * @returns int 停站时间
  1089 + */
  1090 + fnCalcuFixedMinStopNumber: function(oTimeObj, bIsUp) {
  1091 + _validInternal(); // 验证
  1092 + var oParam = this;
  1093 +
  1094 + // 双向停站
  1095 + if (oParam.isTwoWayStop()) {
  1096 + if (bIsUp) { // 上行
  1097 + if (this.isMPeakBc(oTimeObj)) { // 早高峰
  1098 + return 3;
  1099 + } else if (this.isEPeakBc(oTimeObj)) { // 晚高峰
  1100 + return 3;
  1101 + } else { // 低谷
  1102 + if (this.isTroughBeforMPeakStartBc(oTimeObj)) { // 早高峰开始前
  1103 + return 10;
  1104 + } else if (this.isTroughAfterEPeakEndBc(oTimeObj)) { // 晚高峰结束后
  1105 + return 10;
  1106 + } else { // 早高峰,晚高峰之间
  1107 + return 10;
  1108 + }
  1109 + }
  1110 +
  1111 + } else { // 下行
  1112 + if (this.isMPeakBc(oTimeObj)) { // 早高峰
  1113 + return 3;
  1114 + } else if (this.isEPeakBc(oTimeObj)) { // 晚高峰
  1115 + return 3;
  1116 + } else { // 低谷
  1117 + if (this.isTroughBeforMPeakStartBc(oTimeObj)) { // 早高峰开始前
  1118 + return 10;
  1119 + } else if (this.isTroughAfterEPeakEndBc(oTimeObj)) { // 晚高峰结束后
  1120 + return 10;
  1121 + } else { // 早高峰,晚高峰之间
  1122 + return 10;
  1123 + }
  1124 + }
  1125 + }
  1126 + } else { // 主站停站
  1127 + if (bIsUp == oParam.isUpOneWayStop()) {
  1128 + if (bIsUp) { // 上行
  1129 + if (this.isMPeakBc(oTimeObj)) { // 早高峰
  1130 + return 2;
  1131 + } else if (this.isEPeakBc(oTimeObj)) { // 晚高峰
  1132 + return 2;
  1133 + } else { // 低谷
  1134 + if (this.isTroughBeforMPeakStartBc(oTimeObj)) { // 早高峰开始前
  1135 + return 10;
  1136 + } else if (this.isTroughAfterEPeakEndBc(oTimeObj)) { // 晚高峰结束后
  1137 + return 10;
  1138 + } else { // 早高峰,晚高峰之间
  1139 + return 10;
  1140 + }
  1141 + }
  1142 + } else { // 下行
  1143 + if (this.isMPeakBc(oTimeObj)) { // 早高峰
  1144 + return 2;
  1145 + } else if (this.isEPeakBc(oTimeObj)) { // 晚高峰
  1146 + return 2;
  1147 + } else { // 低谷
  1148 + if (this.isTroughBeforMPeakStartBc(oTimeObj)) { // 早高峰开始前
  1149 + return 10;
  1150 + } else if (this.isTroughAfterEPeakEndBc(oTimeObj)) { // 晚高峰结束后
  1151 + return 10;
  1152 + } else { // 早高峰,晚高峰之间
  1153 + return 10;
  1154 + }
  1155 + }
  1156 + }
  1157 + } else { // 副站停战,2到3分钟
  1158 + return 2;
  1159 + }
  1160 + }
  1161 + },
  1162 +
  1163 + /**
1085 1164 * 获取行驶时间。
1086 1165 * @param timeObj 班次时间字符串
1087 1166 * @param isUp 是否上行
... ...
src/main/resources/static/pages/base/timesmodel/js/v2/core/InternalBcObj.js
... ... @@ -32,6 +32,7 @@ var InternalBcObj = function(
32 32 this._$_bcsj = otherParamObj.bcsj; // 班次历时
33 33 this._$_arrtime = otherParamObj.arrtime; // 到达时间对象
34 34 this._$_stoptime = otherParamObj.stoptime; // 停站时间
  35 + this._$_iEatTime = 0; // 吃饭时间
35 36 this._$_tccid = otherParamObj.tccid; // 停车场id
36 37 this._$_ttinfoid = otherParamObj.ttinfoid; // 时刻表id
37 38 this._$_xlid = otherParamObj.xl; // 线路id
... ... @@ -45,6 +46,13 @@ var InternalBcObj = function(
45 46  
46 47 //------------------- get/set 方法 -------------------//
47 48  
  49 +InternalBcObj.prototype.fnSetEatTime = function(iTime) {
  50 + this._$_iEatTime = iTime;
  51 +};
  52 +InternalBcObj.prototype.fnGetEatTime = function() {
  53 + return this._$_iEatTime;
  54 +};
  55 +
48 56 InternalBcObj.prototype.fnSetDelFlag = function(bFlag) {
49 57 this._$_bDelFlag = bFlag;
50 58 };
... ...
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   - // 第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   -
  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 + paramObj.addMinute(oPreBc.getArrTimeObj(), oPreBc.getStopTime()), // 使用上一个班次的到达时间作为开始时间
  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 + oPreBc.fnSetEatTime(oEatBc.getBcTime());
  754 +
  755 + //this._$_other_bc_array.push(oEatBc);
  756 +
  757 + return iBcModifyTime;
  758 + } else {
  759 + return false;
  760 + }
  761 +
  762 +};
  763 +
  764 +/**
  765 + * 调整路牌的班次,通过调整停站时间,或者班次发车时间,不能让班次的到达时间和下一个班次的发车时间重叠。
  766 + * @param iPeakAverStopTime 高峰平均停站时间
  767 + * @param iTroughAverStopTime 低谷平均停站时间
  768 + * @param oParam 参数对象
  769 + */
  770 +InternalLpObj.prototype.fnAdjustBcInterval = function(iPeakAverStopTime, iTroughAverStopTime, oParam) {
  771 + // 获取车次链个数
  772 + var iBcChainCount = this.fnGetBcChainCount();
  773 +
  774 + var i;
  775 + var j;
  776 + var oBcIndex;
  777 + var iQIndex;
  778 + var iBcIndex;
  779 + var iBcCount;
  780 + var oBc;
  781 + var oNextBc;
  782 +
  783 + var iBcStopTime;
  784 +
  785 + for (i = 0; i < iBcChainCount; i++) {
  786 + oBcIndex = this.fnGetBcChainInfo(i);
  787 + iQIndex = oBcIndex["s_q"];
  788 + iBcIndex = oBcIndex["s_b"];
  789 + iBcCount = oBcIndex["bcount"];
  790 +
  791 + for (j = 0; j < iBcCount - 1; j++) {
  792 + oBc = this.getBc(iQIndex, iBcIndex);
  793 + oNextBc = this.getBc(
  794 + iBcIndex == 0 ? iQIndex : iQIndex + 1,
  795 + iBcIndex == 0 ? 1 : 0);
  796 +
  797 + // 不改变当前班次的行驶时间,修正停站时间和下一个班次的发车时间
  798 + iBcStopTime = oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m");
  799 + if (iBcStopTime < 0) {
  800 + // 当前班次使用最小停站时间
  801 + oBc.setStopTime(oParam.fnCalcuFixedMinStopNumber(oBc.getArrTimeObj(), oBc.isUp()));
  802 + oNextBc.addMinuteToFcsj(oBc.getStopTime() + oBc.fnGetEatTime() - iBcStopTime);
  803 +
  804 + } else {
  805 + if (iBcStopTime == oBc.getStopTime() + oBc.fnGetEatTime()) {
  806 + // 停站时间一致,没有问题
  807 +
  808 +
  809 + } else {
  810 + // TODO:当前班次使用最小停站时间
  811 + oBc.setStopTime(oParam.fnCalcuFixedMinStopNumber(oBc.getArrTimeObj(), oBc.isUp()));
  812 + oNextBc.addMinuteToFcsj(oBc.getStopTime() + oBc.fnGetEatTime() - iBcStopTime);
  813 +
  814 + }
  815 + }
  816 +
  817 + iBcIndex = iBcIndex == 0 ? 1 : 0;
  818 + iQIndex = iBcIndex == 0 ? iQIndex + 1 : iQIndex;
  819 + }
  820 +
  821 + this.getBc(iQIndex, iBcIndex).setStopTime(0);
  822 + }
  823 +
  824 +
  825 +};
  826 +
  827 +
  828 +// TODO
  829 +
  830 +/**
  831 + *
  832 + *
  833 + */
  834 +InternalLpObj.prototype.calcuLpBx = function() {
  835 +
  836 +};
  837 +
  838 +
  839 +
  840 +
  841 +
  842 +
  843 +
... ...
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   - 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   -
  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 +
  123 + // 午饭吃饭时间
  124 + var iLTime = _paramObj.fnGetLunchTime();
  125 + // 晚饭吃饭时间
  126 + var iDTime = _paramObj.fnGetDinnerTime();
  127 + // 出场时间
  128 + var iOutTime = _qIsUp ? _paramObj.getUpOutTime() : _paramObj.getDownOutTime();
  129 + // 进场时间
  130 + var iInTime = _qIsUp ? _paramObj.getDownInTime() : _paramObj.getUpInTime();
  131 + // 例保时间
  132 + var iBTime = _paramObj.getLbTime();
  133 +
  134 + var sum = 0; // 总班次时间
  135 + for (i = 0; i < aBcArray.length; i++) {
  136 + sum += aBcArray[i].getBcTime() + aBcArray[i].getStopTime();
  137 + }
  138 + sum += iLTime; // 加午饭时间
  139 + sum += iDTime; // 加晚饭时间
  140 + for (i = 0; i < _aBxDesc.length; i++) {
  141 + _aBxDesc[i].fAverTime = sum / (aBcArray.length / 2); // 平均周转时间不算进出场,例保时间
  142 +
  143 + // 计算5休2的班次数(双进出场,4个例保)
  144 + if (i == 6) {
  145 + _aBxDesc[i].fQCount =
  146 + (_aBxDesc[i].fHoursV * 60 - iOutTime * 2 - iInTime * 2 - iBTime * 4) /
  147 + _aBxDesc[i].fAverTime;
  148 + _aBxDesc[i].fBcCount = _aBxDesc[i].fQCount * 2;
  149 + } else { // 进出场,2个例保
  150 + _aBxDesc[i].fQCount =
  151 + (_aBxDesc[i].fHoursV * 60 - iOutTime - iInTime - iBTime * 2) /
  152 + _aBxDesc[i].fAverTime;
  153 + _aBxDesc[i].fBcCount = _aBxDesc[i].fQCount * 2;
  154 + }
  155 + }
  156 +
  157 +
  158 + // 在第一个班次之前再添加一个模拟班次,用于中标线的作用
  159 + // 那一圈必定是低谷,而且圈索引0,班次索引1,暂时标记,最后删除
  160 + var iFirstStopTime =
  161 + _paramObj.fnCalcuFixedStopNumber(
  162 + _paramObj.addMinute(aBcArray[0].getFcTimeObj(), -10),
  163 + _qIsUp
  164 + );
  165 + var iXXTime = _qIsUp ? _paramObj.getDownTroughTime() : _paramObj.getUpTroughTime();
  166 + var oFlagBc = _factory.createBcObj( // 标记班次
  167 + _internalLpArray[0],
  168 + "normal",
  169 + !_qIsUp,
  170 + 1,
  171 + _paramObj.addMinute(aBcArray[0].getFcTimeObj(), -(iFirstStopTime + iXXTime)),
  172 + _paramObj
  173 + );
  174 + oFlagBc.fnSetDelFlag(true); // 标记了删除记号
  175 +
  176 + _internalLpArray[0].setBc(0, 1, oFlagBc);
  177 +
  178 + // 在最后一圈也补上一个或者2个模拟班次,暂时标记,最后需要删除
  179 + var aMaxBcIndex = _internalLpArray[0].getMaxBcObjPosition();
  180 + if (aMaxBcIndex[0] == _qCount - 1) { // 可能加半圈
  181 + oFlagBc = _factory.createBcObj( // 标记班次
  182 + _internalLpArray[0],
  183 + "normal",
  184 + !_qIsUp,
  185 + 1,
  186 + _paramObj.addMinute(
  187 + _internalLpArray[0].getBc(_qCount - 1, 0).getArrTimeObj(),
  188 + _internalLpArray[0].getBc(_qCount - 1, 0).getStopTime()),
  189 + _paramObj
  190 + );
  191 + oFlagBc.fnSetDelFlag(true); // 标记了删除记号
  192 + _internalLpArray[0].setBc(_qCount - 1, 1, oFlagBc);
  193 +
  194 + } else { // 加完整的一圈
  195 + oFlagBc = _factory.createBcObj( // 标记班次
  196 + _internalLpArray[0],
  197 + "normal",
  198 + _qIsUp,
  199 + 1,
  200 + _paramObj.addMinute(
  201 + _internalLpArray[0].getBc(_qCount - 2, 1).getArrTimeObj(),
  202 + _internalLpArray[0].getBc(_qCount - 2, 1).getStopTime()),
  203 + _paramObj
  204 + );
  205 + oFlagBc.fnSetDelFlag(true); // 标记了删除记号
  206 + _internalLpArray[0].setBc(_qCount - 1, 0, oFlagBc);
  207 +
  208 + oFlagBc = _factory.createBcObj( // 标记班次
  209 + _internalLpArray[0],
  210 + "normal",
  211 + !_qIsUp,
  212 + 1,
  213 + _paramObj.addMinute(
  214 + _internalLpArray[0].getBc(_qCount - 1, 0).getArrTimeObj(),
  215 + _internalLpArray[0].getBc(_qCount - 1, 0).getStopTime()),
  216 + _paramObj
  217 + );
  218 + oFlagBc.fnSetDelFlag(true); // 标记了删除记号
  219 + _internalLpArray[0].setBc(_qCount - 1, 1, oFlagBc);
  220 +
  221 + }
  222 +
  223 + console.log("上行首班车时间:" + _paramObj.getUpFirstDTimeObj().format("HH:mm") +
  224 + "上行末班车时间:" + _paramObj.getUpLastDtimeObj().format("HH:mm"));
  225 + console.log("下行首班车时间:" + _paramObj.getDownFirstDTimeObj().format("HH:mm") +
  226 + "下行末班车时间:" + _paramObj.getDownLastDTimeObj().format("HH:mm"));
  227 + console.log("总共计算的圈数:" + _qCount);
  228 + console.log("圈的方向isUP:" + _qIsUp);
  229 + console.log("班型描述(以下):");
  230 + console.log(_aBxDesc);
  231 + console.log("所有路牌间隔描述(以下):");
  232 + for (i = 0; i < _internalLpArray.length; i++) {
  233 + console.log(_internalLpArray[i]._$_aVerticalIntervalTime);
  234 + }
  235 + console.log("//---------------- 行车计划,初始化方法1 end ----------------//");
  236 +
  237 + };
  238 +
  239 + //------------------ 初始化方法2,以及计算关联的内部变量 ----------------//
  240 + var _approximate_zgfQIndex; // 预估早高峰车辆从第几圈开始全部发出
  241 + var _approximate_zgfBIndex; // 预估早高峰车辆从第几圈第几个班次开始全部发出(上行或下行)
  242 + var _approximate_wgfQIndex; // 预估晚高峰车辆从第几圈开始全部发出
  243 + var _approximate_wgfBIndex; // 预估晚高峰车辆从第几圈第几个班次开始全部发出(上行或下行)
  244 +
  245 + var _fnInitFun2 = function() { // 初始化方法2
  246 + console.log("//---------------- 行车计划,初始化方法2 start ----------------//");
  247 +
  248 + //------------------------ 1、计算车辆总数 ------------------------//
  249 + // 是用高峰上行周转时间除以高峰平均间隔得到的
  250 + // 这样算还算合理,车辆不多不少,待以后有新的算法再修正
  251 + var iClCount = _paramObj.calcuClzx();
  252 +
  253 + //------------------------ 2、计算所有路牌的发车在各个圈中的间隔 --------------------//
  254 + var i;
  255 + var j;
  256 + var iBindex = 1;
  257 + var iZzsj;
  258 + var oLp;
  259 + var iC1;
  260 + var iC2;
  261 +
  262 + for (i = 0; i < _qCount - 1; i++) {
  263 + while (iBindex <= 1) {
  264 + // 每圈每个方向的周转时间不一致,以上标线为主
  265 + oLp = _internalLpArray[0];
  266 + iZzsj = oLp.getBc(i + 1, iBindex).getFcTimeObj().diff(
  267 + oLp.getBc(i, iBindex).getFcTimeObj(), "m"
  268 + );
  269 +
  270 + iC1 = Math.floor(iZzsj / iClCount);
  271 + iC2 = iZzsj % iClCount;
  272 +
  273 + for (j = 0; j < iClCount - iC2; j++) {
  274 + oLp = _internalLpArray[j];
  275 + oLp.fnSetVerticalIntervalTime(i, iBindex, iC1);
  276 + }
  277 +
  278 + for (j = 0; j < iC2; j++) {
  279 + oLp = _internalLpArray[iClCount - iC2 + j];
  280 + oLp.fnSetVerticalIntervalTime(i, iBindex, iC1 + 1);
  281 + }
  282 +
  283 + iBindex ++;
  284 +
  285 + }
  286 + iBindex = 0;
  287 + }
  288 + // 最后一圈没有下一圈的参照,周转时间没发获取,由于都是低谷,所以使用倒数第二圈的间隔最为最后一圈的间隔
  289 + for (i = 0; i < _internalLpArray.length; i++) {
  290 + oLp = _internalLpArray[i];
  291 + oLp.fnSetVerticalIntervalTime(_qCount - 1, 0, oLp.fnGetVerticalIntervalTime(_qCount - 2, 0));
  292 + oLp.fnSetVerticalIntervalTime(_qCount - 1, 1, oLp.fnGetVerticalIntervalTime(_qCount - 2, 1));
  293 + }
  294 +
  295 + //------------------------ 3、预估早高峰全部出车第几圈第几个班次全部出车,计算路牌之间的发车间隔 ------------------//
  296 +
  297 + // 以上标线为标准,查找离早高峰开始时间最近的班次作为早高峰开始班次
  298 + // 以这个班次为早高峰起点,全部出车策略
  299 + var qbcIndexArray = _internalLpArray[0].getQBcIndexWithFcTime(
  300 + _paramObj.getMPeakStartTimeObj(), true, true);
  301 + var qIndex = qbcIndexArray[0]; // 第几圈
  302 + var bIndex = qbcIndexArray[1]; // 第几个班次
  303 +
  304 + for (i = 1; i < _internalLpArray.length; i++) {
  305 + _fnGenerateBcAndSetBc(i, qIndex, bIndex);
  306 + }
  307 +
  308 + _approximate_zgfQIndex = qIndex;
  309 + _approximate_zgfBIndex = bIndex;
  310 +
  311 + //------------------------ 4、预估晚高峰全部出车第几圈第几个班次全部出车,计算路牌之间的发车间隔 ------------------//
  312 +
  313 + // 以上标线为标准,查找离晚高峰开始时间最近的班次作为晚高峰开始班次
  314 + // 以这个班次为早高峰起点,全部出车策略
  315 + qbcIndexArray = _internalLpArray[0].getQBcIndexWithFcTime(
  316 + _paramObj.getEPeakStartTimeObj(), true, true);
  317 + qIndex = qbcIndexArray[0]; // 第几圈
  318 + bIndex = qbcIndexArray[1]; // 第几个班次
  319 +
  320 + for (i = 1; i < _internalLpArray.length; i++) {
  321 + _fnGenerateBcAndSetBc(i, qIndex, bIndex);
  322 + }
  323 +
  324 + _approximate_wgfQIndex = qIndex;
  325 + _approximate_wgfBIndex = bIndex;
  326 +
  327 + console.log("早高峰周转时间(固定最大停战时间):" + _paramObj.calcuPeakZzsj() + "分钟");
  328 + console.log("早高峰发车时间范围:" + _paramObj.getMPeakMinFcjx() + "分钟 --- " + _paramObj.getMPeakMaxFcjx() + "分钟");
  329 + console.log("预估早高峰第" + _approximate_zgfQIndex + "(index)圈,第" + _approximate_zgfBIndex + "(index)班次车辆全部发出");
  330 + console.log("预估晚高峰第" + _approximate_wgfQIndex + "(index)圈,第" + _approximate_wgfBIndex + "(index)班次车辆全部发出");
  331 + console.log("//---------------- 行车计划,初始化方法2 end ----------------//");
  332 + };
  333 +
  334 + //----------------------- 初始化方法3,计算连班分班的路牌分布 ----------------//
  335 + var _iBx_lb_lpcount; // 连班路牌数
  336 + var _iBx_5_2_fb_lpcount; // 5休2分班路牌数
  337 + var _iBx_other_fb_lpcount; // 其他分班路牌数
  338 +
  339 + var _fnInitFun3 = function() { // 初始化方法3
  340 + console.log("//---------------- 行车计划,初始化方法3 start ----------------//");
  341 +
  342 + //--------------------- 1、计算分班连班班型车辆分布数 --------------------//
  343 + // 总共车辆数(高峰最大车辆数)
  344 + var iCls = _paramObj.calcuClzx();
  345 + // 低谷最少配车(连班车数量)
  346 + var iDgminpc = Math.round(_paramObj.calcuTroughZzsj() / _paramObj.getTroughMaxFcjx());
  347 + // 加班车路牌数(做5休2的路牌数)
  348 + var i_5_2_lpes = _paramObj.getJBLpes();
  349 +
  350 + // 做些简单的验证
  351 + if (iCls < iDgminpc) {
  352 + alert("总配车数小于低谷最小配车");
  353 + throw "总配车数小于低谷最小配车";
  354 + }
  355 + if (iDgminpc < 2) {
  356 + alert("连班路牌小于2,办不到啊");
  357 + throw "连班路牌小于2,办不到啊";
  358 + }
  359 + if (iCls - iDgminpc < i_5_2_lpes) {
  360 + alert("总分班路牌数小于加班路牌数");
  361 + throw "总分班路牌数小于加班路牌数";
  362 + }
  363 +
  364 + //// 修正连班路牌数,班次间隔大于20的,加1,直至班次间隔小于20
  365 + //while(_paramObj.calcuPeakZzsj() / iDgminpc > 20) {
  366 + // iDgminpc ++;
  367 + //}
  368 + _iBx_lb_lpcount = iDgminpc;
  369 +
  370 + _iBx_5_2_fb_lpcount = i_5_2_lpes;
  371 + _iBx_other_fb_lpcount = iCls - _iBx_lb_lpcount - i_5_2_lpes;
  372 +
  373 + //------------------------ 2、利用间隔法计算连班路牌分布 --------------------//
  374 + var i;
  375 + var j;
  376 + var iC1 = Math.floor(_internalLpArray.length / _iBx_lb_lpcount);
  377 + var iC2 = _internalLpArray.length % _iBx_lb_lpcount;
  378 + var iLpIndex;
  379 +
  380 + for (i = 0; i < _iBx_lb_lpcount - iC2; i++) {
  381 + iLpIndex = i * iC1;
  382 + _internalLpArray[iLpIndex].setBxLb(true);
  383 + _internalLpArray[iLpIndex].setBxDesc("连班");
  384 + }
  385 + for (j = 0; j < iC2; j++) {
  386 + iLpIndex = i * iC1 + j * (iC1 + 1);
  387 + _internalLpArray[iLpIndex].setBxLb(true);
  388 + _internalLpArray[iLpIndex].setBxDesc("连班");
  389 + }
  390 +
  391 + //------------------------ 3、利用间隔法计算分班班型路牌分布 --------------------//
  392 + // 获取分班路牌索引
  393 + var aNotLbIndexes = [];
  394 + for (i = 0; i < _internalLpArray.length; i++) {
  395 + if (!_internalLpArray[i].isBxLb()) {
  396 + aNotLbIndexes.push(i);
  397 + }
  398 + }
  399 + // 先5休2分班
  400 + iC1 = Math.floor(aNotLbIndexes.length / _iBx_5_2_fb_lpcount);
  401 + iC2 = aNotLbIndexes.length % _iBx_5_2_fb_lpcount;
  402 +
  403 + for (i = 0; i < _iBx_5_2_fb_lpcount - iC2; i++) {
  404 + iLpIndex = aNotLbIndexes[i * iC1];
  405 + _internalLpArray[iLpIndex].setBxLb(false);
  406 + _internalLpArray[iLpIndex].setBxFb(true);
  407 + _internalLpArray[iLpIndex].setBxFb5_2(true);
  408 + _internalLpArray[iLpIndex].setBxDesc("5休2分班");
  409 + }
  410 + for (i = 0; i < iC2; i++) {
  411 + iLpIndex = aNotLbIndexes[_iBx_lb_lpcount - iC2 + i * (iC1 + 1)];
  412 + _internalLpArray[iLpIndex].setBxLb(false);
  413 + _internalLpArray[iLpIndex].setBxFb(true);
  414 + _internalLpArray[iLpIndex].setBxFb5_2(true);
  415 + _internalLpArray[iLpIndex].setBxDesc("5休2分班");
  416 + }
  417 + // 其他分班
  418 + for (i = 0; i < aNotLbIndexes.length; i++) {
  419 + iLpIndex = aNotLbIndexes[i];
  420 + if (!_internalLpArray[iLpIndex].isBxFb5_2()) {
  421 + _internalLpArray[iLpIndex].setBxLb(false);
  422 + _internalLpArray[iLpIndex].setBxFb(true);
  423 + _internalLpArray[iLpIndex].setBxFb5_2(false);
  424 + _internalLpArray[iLpIndex].setBxDesc("其他分班");
  425 + }
  426 + }
  427 +
  428 + console.log("高峰周转时间:" + _paramObj.calcuPeakZzsj());
  429 + console.log("连班路牌数:" + _iBx_lb_lpcount);
  430 + console.log("5休2分班路牌数:" + _iBx_5_2_fb_lpcount);
  431 + console.log("其他分班路牌数:" + _iBx_other_fb_lpcount);
  432 + var aLbIndexes = [];
  433 + for (i = 0; i < _internalLpArray.length; i++) {
  434 + if (_internalLpArray[i].isBxLb()) {
  435 + aLbIndexes.push(i);
  436 + }
  437 + }
  438 + console.log("连班路牌indexes=" + aLbIndexes);
  439 + var a_5_2_fbIndexes = [];
  440 + for (i = 0; i < _internalLpArray.length; i++) {
  441 + if (_internalLpArray[i].isBxFb() && _internalLpArray[i].isBxFb5_2()) {
  442 + a_5_2_fbIndexes.push(i);
  443 + }
  444 + }
  445 + console.log("5休2分班路牌indexes=" + a_5_2_fbIndexes);
  446 + var a_other_fbIndexes = [];
  447 + for (i = 0; i < _internalLpArray.length; i++) {
  448 + if (_internalLpArray[i].isBxFb() && !_internalLpArray[i].isBxFb5_2()) {
  449 + a_other_fbIndexes.push(i);
  450 + }
  451 + }
  452 + console.log("其他分班路牌indexes=" + a_other_fbIndexes);
  453 +
  454 + console.log("//---------------- 行车计划,初始化方法3 end ----------------//");
  455 + };
  456 +
  457 + //----------------------- 初始化方法4,计算中标线位置 -------------------------//
  458 + var _iZbx_lpIndex; // 中标线对应第几个路牌
  459 +
  460 + var _fnInitFun4 = function() { // 初始化方法4
  461 + console.log("//---------------- 行车计划,初始化方法3 start ----------------//");
  462 +
  463 + //---------------------------- 1、模拟一个中标线,使用临时路牌 ----------------------//
  464 + // 构造中标线
  465 + // 中标线开始时间,就是方向的首班车时间
  466 + var oSt = !_qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();
  467 + // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向
  468 + // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向
  469 + var oEt;
  470 + if (_paramObj.getUpLastDtimeObj().isBefore(
  471 + _paramObj.getDownLastDTimeObj())) {
  472 + oEt = _paramObj.getDownLastDTimeObj();
  473 + } else {
  474 + oEt = _paramObj.getUpLastDtimeObj();
  475 + }
  476 +
  477 + var oTempLp = new InternalLpObj({lpNo: -999, lpName: "-999"}, _qCount, _qIsUp);
  478 + oTempLp.initDataFromTimeToTime(
  479 + oSt,
  480 + oEt,
  481 + !_qIsUp,
  482 + 0,
  483 + _paramObj,
  484 + _factory
  485 + );
  486 +
  487 + //------------------------ 2、找出中标线的早高峰班次,计算应该插在当前路牌数组的那个位置 ----------------//
  488 + // 找出中标线对应的早高峰的班次对象
  489 + var oZb_gf_bc = oTempLp.getBc(_approximate_zgfQIndex, _approximate_zgfBIndex);
  490 +
  491 + // 把所有连班路牌高峰班次重新构造成一个一个的圈数组,计算对应中标线最近的是第几个路牌
  492 + // 中标线和上标线一样在连班路牌上
  493 + var aTempq = [];
  494 + var oTempq;
  495 + var oTempb;
  496 + var i;
  497 + var oLp;
  498 +
  499 + var aLbIndexes = []; // 连班的路牌索引
  500 + for (i = 0; i < _internalLpArray.length; i++) {
  501 + if (_internalLpArray[i].isBxLb()) {
  502 + aLbIndexes.push(i);
  503 + }
  504 + }
  505 +
  506 + for (i = 0; i < aLbIndexes.length; i++) {
  507 + oLp = _internalLpArray[aLbIndexes[i]];
  508 +
  509 + oTempb = oLp.getBc(_approximate_zgfQIndex, _approximate_zgfBIndex);
  510 + if (oTempb.isUp() == _qIsUp) {
  511 + oTempq = new InternalGroupObj(oLp, _qIsUp, oTempb, undefined);
  512 + } else {
  513 + oTempq = new InternalGroupObj(oLp, _qIsUp, undefined, oTempb);
  514 + }
  515 + aTempq.push(oTempq);
  516 +
  517 + }
  518 +
  519 + var aTtindex = oTempLp.getgetQBcIndexWithFcTimeFromGroupArray(
  520 + oZb_gf_bc.getFcTimeObj(),
  521 + aTempq,
  522 + true,
  523 + true
  524 + );
  525 +
  526 + _iZbx_lpIndex = aLbIndexes[aTtindex[0]]; // 中标线放在第几个路牌
  527 + oTempLp.setLp(_lpArray[_iZbx_lpIndex]); // 设置原始路牌对象
  528 + oTempLp._$_aVerticalIntervalTime = _internalLpArray[_iZbx_lpIndex]._$_aVerticalIntervalTime; // 设置纵向最小发车间隔
  529 + oTempLp.setBxLb(_internalLpArray[_iZbx_lpIndex].isBxLb());
  530 + oTempLp.setBxFb(_internalLpArray[_iZbx_lpIndex].isBxFb());
  531 + oTempLp.setBxFb5_2(_internalLpArray[_iZbx_lpIndex].isBxFb5_2());
  532 +
  533 + // 修正除了第一个班次外,其余其他班次
  534 + var iBcindex = 0;
  535 + for (i = 1; i < _qCount; i++) {
  536 + while (iBcindex <= 1) {
  537 + if (oTempLp.getBc(i, iBcindex)) { // 替换存在的班次
  538 + oTempLp.setBc(i, iBcindex, _fnGenerateBc(_iZbx_lpIndex, i, iBcindex));
  539 + }
  540 + iBcindex ++;
  541 + }
  542 + iBcindex = 0;
  543 + }
  544 +
  545 + _internalLpArray[_iZbx_lpIndex] = oTempLp;
  546 +
  547 + console.log("中标线对应第" + (_iZbx_lpIndex + 1) + "个路牌");
  548 +
  549 + console.log("//---------------- 行车计划,初始化方法4 end ----------------//");
  550 + };
  551 +
  552 + //-------------------- 重要的内部方法 -----------------------//
  553 + /**
  554 + * 核心方法,利用路牌间隔纵向生成班次。
  555 + * @param iLpindex 路牌索引
  556 + * @param iQindex 圈索引
  557 + * @param iBcindex 班次索引
  558 + * @returns object InternalBcObj,失败 false
  559 + */
  560 + var _fnGenerateBc = function(iLpindex, iQindex, iBcindex) {
  561 + // 以上标线为起始点,使用路牌在不同圈,班次索引的发车间隔,计算班次
  562 + // 注意,发车间隔是指下一个班次应该距离当前班次间隔,是从下往上的
  563 +
  564 + // 1、参数验证
  565 + if (iLpindex == 0) { // 上标线的班次不需要生成
  566 + return false;
  567 + }
  568 +
  569 + // 2、计算间隔
  570 + var i;
  571 + var oLp;
  572 + var iTime = 0;
  573 + for (i = 0; i < iLpindex; i++) {
  574 + oLp = _internalLpArray[i];
  575 + iTime += oLp.fnGetVerticalIntervalTime(iQindex, iBcindex);
  576 + }
  577 +
  578 + // 3、生成班次
  579 + var _oKsbc = _internalLpArray[0].getBc(iQindex, iBcindex);
  580 + if (!_oKsbc) {
  581 + return false;
  582 + }
  583 + var _oKssj = _paramObj.addMinute(_oKsbc.getFcTimeObj(), iTime);
  584 + var _oBc = _factory.createBcObj(
  585 + _internalLpArray[iLpindex],
  586 + "normal", _oKsbc.isUp(),
  587 + 1, _oKssj, _paramObj);
  588 +
  589 + return _oBc;
  590 +
  591 + };
  592 +
  593 + /**
  594 + * 核心方法,在指定位置生成班次并添加到路牌指定位置中。
  595 + * @param lpIndex 第几个路牌
  596 + * @param qIndex 第几圈
  597 + * @param bcIndex 第几个班次
  598 + */
  599 + var _fnGenerateBcAndSetBc = function(lpIndex, qIndex, bcIndex) {
  600 + var _bcObj = _fnGenerateBc(lpIndex, qIndex, bcIndex);
  601 + if (_bcObj) {
  602 + _internalLpArray[lpIndex].setBc(qIndex, bcIndex, _bcObj);
  603 + }
  604 + };
  605 +
  606 + /**
  607 + * 获取班次列表。
  608 + * @param oIsUp 是否上行
  609 + * @param oStartTime 开始时间对象
  610 + * @returns [(InternalBcObj)]
  611 + */
  612 + var _fnGetBcList2 = function(oIsUp, oStartTime) {
  613 + var i;
  614 + var j;
  615 + var oLp;
  616 + var oBc;
  617 + var aBc = [];
  618 +
  619 + for (j = 0; j < _qCount; j++) {
  620 + for (i = 0; i < _internalLpArray.length; i++) {
  621 + oLp = _internalLpArray[i];
  622 + oBc = oLp.getBc(
  623 + j,
  624 + _qIsUp == oIsUp ? 0 : 1
  625 + );
  626 + if (oBc && oBc.getFcTimeObj().isAfter(oStartTime)) {
  627 + aBc.push(oBc);
  628 + }
  629 + }
  630 + }
  631 +
  632 + var aBcFcTime = [];
  633 + for (i = 0; i < aBc.length; i++) {
  634 + oBc = aBc[i];
  635 + aBcFcTime.push(oBc.getFcTimeObj().format("HH:mm"));
  636 + }
  637 + console.log((oIsUp ? "上行班次列表:" : "下行班次列表:") + aBcFcTime.join(","));
  638 +
  639 + return aBc;
  640 + };
  641 +
  642 + /**
  643 + * 获取班次列表。
  644 + * @param isUp boolean 是否上行
  645 + * @returns [(InternalBcObj)]
  646 + */
  647 + var _fnGetBcList = function(isUp) {
  648 + var i;
  649 + var j;
  650 + var oLp;
  651 + var oBc;
  652 + var aBc = [];
  653 +
  654 + for (j = 0; j < _qCount; j++) {
  655 + for (i = 0; i < _internalLpArray.length; i++) {
  656 + oLp = _internalLpArray[i];
  657 + oBc = oLp.getBc(
  658 + j,
  659 + _qIsUp == isUp ? 0 : 1
  660 + );
  661 + if (oBc) {
  662 + aBc.push(oBc);
  663 + }
  664 + }
  665 + }
  666 +
  667 + var aBcFcTime = [];
  668 + for (i = 0; i < aBc.length; i++) {
  669 + oBc = aBc[i];
  670 + aBcFcTime.push(oBc.getFcTimeObj().format("HH:mm"));
  671 + }
  672 + console.log((isUp ? "上行班次列表:" : "下行班次列表:") + aBcFcTime.join(","));
  673 +
  674 + return aBc;
  675 + };
  676 +
  677 + /**
  678 + * 查找离指定时间最近的前面的班次索引信息
  679 + * @param timeObj 查找时间
  680 + * @param isUp 是否上行
  681 + * @returns [{路牌index},{圈index},{班次index}]
  682 + */
  683 + var _fnFindUpClosedBcIndexWithTime = function(timeObj, isUp) {
  684 +
  685 + var _lpObj;
  686 + var _groupObj;
  687 + var _bcObj;
  688 + var _i;
  689 + var _j;
  690 + var timediff; // 时间差取绝对值
  691 +
  692 + var _lpIndex;
  693 + var _up_qIndex;
  694 + var _up_bIndex;
  695 +
  696 + for (_i = 0; _i < _qCount; _i++) {
  697 + for (_j = 0; _j < _internalLpArray.length; _j++) {
  698 + _lpObj = _internalLpArray[_j];
  699 + _groupObj = _lpObj.getGroup(_i);
  700 + _bcObj = isUp == _qIsUp ? _groupObj.getBc1() : _groupObj.getBc2();
  701 + if (!_bcObj) { // 没有班次动态生成一个,可能生成不出的
  702 + _bcObj = _fnGenerateBc(_j, _i, isUp == _qIsUp ? 0 : 1);
  703 + }
  704 + if (_bcObj) {
  705 + if (timeObj.diff(_bcObj.getFcTimeObj()) >= 0) {
  706 + if (!timediff) {
  707 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  708 + _lpIndex = _j;
  709 + _up_qIndex = _i;
  710 + _up_bIndex = isUp == _qIsUp ? 0 : 1;
  711 + } else {
  712 + if (timeObj.diff(_bcObj.getFcTimeObj()) < timediff) {
  713 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  714 + _lpIndex = _j;
  715 + _up_qIndex = _i;
  716 + _up_bIndex = isUp == _qIsUp ? 0 : 1;
  717 + }
  718 + }
  719 + }
  720 + }
  721 + }
  722 + }
  723 +
  724 + if (_lpIndex == undefined) {
  725 + return false;
  726 + }
  727 +
  728 + var bcindex = [];
  729 + bcindex.push(_lpIndex);
  730 + bcindex.push(_up_qIndex);
  731 + bcindex.push(_up_bIndex);
  732 +
  733 + return bcindex;
  734 + };
  735 +
  736 + /**
  737 + * 查找离指定时间最近的后面的班次索引信息
  738 + * @param timeObj 查找时间
  739 + * @param isUp 是否上行
  740 + * @returns [{路牌index},{圈index},{班次index}]
  741 + */
  742 + var _fnFindDownClosedBcIndexWithTime = function(timeObj, isUp) {
  743 + var _lpObj;
  744 + var _groupObj;
  745 + var _bcObj;
  746 + var _i;
  747 + var _j;
  748 + var timediff; // 时间差取绝对值
  749 +
  750 + var _lpIndex;
  751 + var _down_qIndex;
  752 + var _down_bIndex;
  753 +
  754 + var flag;
  755 +
  756 + for (_i = 0; _i < _qCount; _i++) {
  757 + for (_j = 0; _j < _internalLpArray.length; _j++) {
  758 + _lpObj = _internalLpArray[_j];
  759 + _groupObj = _lpObj.getGroup(_i);
  760 + // TODO:bug
  761 + _bcObj = isUp == _qIsUp ? _groupObj.getBc1() : _groupObj.getBc2();
  762 + if (!_bcObj) { // 没有班次动态生成一个,可能生成不出的
  763 + _bcObj = _fnGenerateBc(_j, _i, isUp == _qIsUp ? 0 : 1);
  764 + }
  765 + if (_bcObj) {
  766 + //console.log("timeobj -> bcobj diff flag " +
  767 + // timeObj.format("HH:mm") + "->" +
  768 + // _bcObj.getFcTimeObj().format("HH:mm") +
  769 + // timeObj.diff(_bcObj.getFcTimeObj()) +
  770 + // (timeObj.diff(_bcObj.getFcTimeObj()) <= 0)
  771 + //);
  772 +
  773 + flag = (timeObj.diff(_bcObj.getFcTimeObj())) <= 0;
  774 +
  775 + if (flag) {
  776 + if (!timediff) {
  777 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  778 + _lpIndex = _j;
  779 + _down_qIndex = _i;
  780 + _down_bIndex = isUp == _qIsUp ? 0 : 1;
  781 + } else {
  782 + if ((timeObj.diff(_bcObj.getFcTimeObj())) > timediff) {
  783 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  784 + _lpIndex = _j;
  785 + _down_qIndex = _i;
  786 + _down_bIndex = isUp == _qIsUp ? 0 : 1;
  787 + }
  788 + }
  789 + }
  790 + }
  791 + }
  792 + }
  793 +
  794 + if (_lpIndex == undefined) {
  795 + return false;
  796 + }
  797 +
  798 + var bcindex = [];
  799 + bcindex.push(_lpIndex);
  800 + bcindex.push(_down_qIndex);
  801 + bcindex.push(_down_bIndex);
  802 +
  803 + return bcindex;
  804 + };
  805 +
  806 + /**
  807 + * 获取班次索引。
  808 + * @param oBc 班次对象
  809 + * @returns [{路牌索引},{圈索引},{班次索引}]
  810 + */
  811 + var _fnGetBcIndex = function(oBc) {
  812 + // 路牌索引
  813 + var i;
  814 + var iLpIndex;
  815 + for (i = 0; i < _internalLpArray.length; i++) {
  816 + if (_internalLpArray[i]._$$_orign_lp_obj == oBc._$$_internal_lp_obj._$$_orign_lp_obj) {
  817 + iLpIndex = i;
  818 + break;
  819 + }
  820 + }
  821 + // 圈索引
  822 + var j;
  823 + var iGroupIndex;
  824 + var bFlag = false;
  825 + for (i = 0; i < _internalLpArray.length; i++) {
  826 + if (bFlag) {
  827 + break;
  828 + }
  829 + for (j = 0; j < _qCount; j++) {
  830 + if (_internalLpArray[i]._$_groupBcArray[j] == oBc._$$_internal_group_obj) {
  831 + iGroupIndex = j;
  832 + bFlag = true;
  833 + break;
  834 + }
  835 + }
  836 + }
  837 + // 班次索引
  838 + var iBcIndex = _qIsUp == oBc.isUp() ? 0 : 1;
  839 +
  840 + if (iLpIndex == undefined) {
  841 + return null;
  842 + } else {
  843 + return [].concat(iLpIndex, iGroupIndex, iBcIndex);
  844 + }
  845 +
  846 + };
  847 +
  848 + return {
  849 + //------------- 布局初始化方法 ------------//
  850 + /**
  851 + * 初始化数据,使用标线初始化
  852 + */
  853 + fnInitDataWithBxLayout: function() {
  854 + // 初始化布局1,构造上标线,计算圈数,把上标线数据放入第一个路牌中
  855 + _fnInitFun1();
  856 + // 初始化布局2,从上标线的某个班次开始,构造所有路牌的早高峰班次,晚高峰班次,计算路牌在各个圈中的间隔
  857 + _fnInitFun2();
  858 + // 初始化布局3,计算连班分班路牌分布
  859 + _fnInitFun3();
  860 + // 初始化布局4,计算中标线位置
  861 + _fnInitFun4();
  862 +
  863 + },
  864 +
  865 + /**
  866 + * 调整高峰班次,
  867 + * 初始化生成早高峰,晚高峰班次并不准确,因为根据高峰时间段,并不在一个完整圈内,应该是在两个或多个圈之间
  868 + * 当初始化定好布局后(上标线,中标线),然后确定每个路牌的班型(连班,分班,5休2分班)后
  869 + * 然后重新计算框在高峰时间段内的班次索引,不足的添加,之前多加的删除(只删除分班路牌上的)
  870 + * @param isZgf 是否早高峰
  871 + * @param isUp 是否上行
  872 + */
  873 + fnAdjustGfbc : function(isZgf, isUp) {
  874 + var oStartTime; // 开始时间
  875 + var oEndTime; // 结束时间
  876 + var aStartBcIndex; // 开始班次索引
  877 + var aEndBcIndex; // 结束班次索引
  878 +
  879 + oStartTime = isZgf ? _paramObj.getMPeakStartTimeObj() : _paramObj.getEPeakStartTimeObj();
  880 + oEndTime = isZgf ? _paramObj.getMPeakEndTimeObj() : _paramObj.getEPeakEndTimeObj();
  881 +
  882 + aStartBcIndex = _fnFindUpClosedBcIndexWithTime(oStartTime, isUp);
  883 + aEndBcIndex = _fnFindDownClosedBcIndexWithTime(oEndTime, isUp);
  884 +
  885 + var iLpIndex;
  886 + var iQIndex;
  887 + var iBcIndex;
  888 + var iQInternelCount; // 高峰时间段中间包含的圈数
  889 + var i;
  890 + var j;
  891 +
  892 + var oLp;
  893 +
  894 + if (aStartBcIndex && aEndBcIndex) {
  895 + iLpIndex = aStartBcIndex[0];
  896 + iQIndex = aStartBcIndex[1];
  897 + iBcIndex = aStartBcIndex[2];
  898 +
  899 + // 处理头
  900 + // 删除头部多余班次
  901 + for (j = 0; j < iLpIndex; j++) {
  902 + oLp = _internalLpArray[j];
  903 + if (oLp.isBxFb() && oLp.getBc(iQIndex, iBcIndex)) {
  904 + oLp.removeBc(iQIndex, iBcIndex);
  905 + }
  906 + }
  907 +
  908 + for (j = iLpIndex; j < _internalLpArray.length; j++) {
  909 + oLp = _internalLpArray[j];
  910 + if (!oLp.getBc(iQIndex, iBcIndex)) {
  911 + _fnGenerateBcAndSetBc(j, iQIndex, iBcIndex);
  912 + }
  913 + }
  914 +
  915 + // 处理中间
  916 + iQInternelCount = aEndBcIndex[1] - aStartBcIndex[1] - 1;
  917 + for (i = 1; i <= iQInternelCount; i++) {
  918 + oLp = _internalLpArray[iQIndex + i];
  919 +
  920 + if (!oLp.getBc(iQIndex + i, iBcIndex)) {
  921 + _fnGenerateBcAndSetBc(i, iQIndex + i, iBcIndex);
  922 + }
  923 + }
  924 +
  925 + // 处理尾部
  926 + iLpIndex = aEndBcIndex[0];
  927 + iQIndex = aEndBcIndex[1];
  928 + iBcIndex = aEndBcIndex[2];
  929 +
  930 + // 删除尾部多余的班次
  931 + for (j = iLpIndex; j < _internalLpArray.length; j++) {
  932 + oLp = _internalLpArray[j];
  933 + if (oLp.isBxFb() && oLp.getBc(iQIndex, iBcIndex)) {
  934 + oLp.removeBc(iQIndex, iBcIndex);
  935 + }
  936 + }
  937 +
  938 + if (aStartBcIndex[1] != aEndBcIndex[1]) { // 指定时间范围跨圈
  939 + for (j = 0; j < iLpIndex; j++) {
  940 + oLp = _internalLpArray[j];
  941 + if (!oLp.getBc(iQIndex, iBcIndex)) {
  942 + _fnGenerateBcAndSetBc(j, iQIndex, iBcIndex);
  943 + }
  944 + }
  945 + } else {
  946 + // 不跨圈,不用处理,处理头的时候已经加了
  947 + }
  948 +
  949 + }
  950 +
  951 + },
  952 +
  953 + /**
  954 + * 按照营运时间要求补充班次,
  955 + * 早高峰7:45分以前出场运营,
  956 + * 晚高峰16:10分以前出场运营
  957 + */
  958 + fnCalcuLpBc_yy: function() {
  959 + // 补班次的时候,针对的是分班班型
  960 + var i;
  961 + var _oLp;
  962 + var _oBc;
  963 + var _aMinBcIndex;
  964 + var _aMaxBcIndex;
  965 +
  966 + var _qIndex;
  967 + var _bIndex;
  968 +
  969 + var _zgfCDate = _paramObj.toTimeObj("7:45");
  970 + var _wgfCDate = _paramObj.toTimeObj("16:10");
  971 + var _ccsj;
  972 +
  973 + for (i = 0; i < _internalLpArray.length; i++) {
  974 + _oLp = _internalLpArray[i];
  975 + if (_oLp.isBxFb()) { // 分班路牌
  976 + // 早高峰部分
  977 + _aMinBcIndex = _oLp.getMinBcObjPosition();
  978 + _qIndex = _aMinBcIndex[0];
  979 + _bIndex = _aMinBcIndex[1];
  980 + _oBc = _oLp.getBc(_qIndex, _bIndex);
  981 + if (_qIsUp) {
  982 + _ccsj = _bIndex == 0 ?
  983 + _paramObj.getUpOutTime() :
  984 + _paramObj.getDownOutTime();
  985 + } else {
  986 + _ccsj = _bIndex == 0 ?
  987 + _paramObj.getDownOutTime() :
  988 + _paramObj.getUpOutTime();
  989 + }
  990 + if (_zgfCDate.isBefore(_paramObj.addMinute(_oBc.getFcTimeObj(), -_ccsj))) {
  991 + _fnGenerateBcAndSetBc(
  992 + i,
  993 + _bIndex == 0 ? _qIndex - 1 : _qIndex,
  994 + _bIndex == 0 ? 1 : 0
  995 + )
  996 + }
  997 +
  998 + // 晚高峰部分
  999 + _aMaxBcIndex = _oLp.getMaxBcObjPosition();
  1000 + _qIndex = _aMaxBcIndex[0];
  1001 + _bIndex = _aMaxBcIndex[1];
  1002 + _oBc = _oLp.getBc(
  1003 + _bIndex == 0 ? _qIndex - 1 : _qIndex,
  1004 + _bIndex == 0 ? 1 : 0
  1005 + );
  1006 + if (!_oBc) { // 前一个班次不存在,再判定加不加
  1007 + _oBc = _oLp.getBc(_qIndex, _bIndex);
  1008 + if (_qIsUp) {
  1009 + _ccsj = _bIndex == 0 ?
  1010 + _paramObj.getUpOutTime() :
  1011 + _paramObj.getDownOutTime();
  1012 + } else {
  1013 + _ccsj = _bIndex == 0 ?
  1014 + _paramObj.getDownOutTime() :
  1015 + _paramObj.getUpOutTime();
  1016 + }
  1017 + if (_wgfCDate.isBefore(_paramObj.addMinute(_oBc.getFcTimeObj(), -_ccsj))) {
  1018 + _fnGenerateBcAndSetBc(
  1019 + i,
  1020 + _bIndex == 0 ? _qIndex - 1 : _qIndex,
  1021 + _bIndex == 0 ? 1 : 0
  1022 + )
  1023 + }
  1024 + }
  1025 + }
  1026 + }
  1027 + },
  1028 +
  1029 + /**
  1030 + * 补充做5休2的班型班次。
  1031 + * 1、确认5_2班型大致多少圈(小数点过.7进位)
  1032 + * 2、获取当前5_2两端车次链的信息,每段的班次数目,还差几个班次没加
  1033 + * 3、如果前面的车次链班次少,则从前面的车次链开始加
  1034 + * 4、如果车次链班次数一样,从从后面的车次链开始加
  1035 + * 5、加班次时都是往车次链前方加
  1036 + * 6、如果前面车次链不能再加班次了,从后面车次链加
  1037 + */
  1038 + fnCalcuLpBx_5_2: function() {
  1039 + // 计算做5休2班型所需的班次数
  1040 + var iBxBcount = _aBxDesc[6].fBcCount;
  1041 + if (iBxBcount - Math.floor(iBxBcount) > 0.7) {
  1042 + iBxBcount = Math.floor(iBxBcount) + 1;
  1043 + } else {
  1044 + iBxBcount = Math.floor(iBxBcount);
  1045 + }
  1046 +
  1047 + var i;
  1048 + var j;
  1049 + var oLp;
  1050 + var iAddBcCount;
  1051 + var oBcChain1;
  1052 + var oBcChain2;
  1053 + var iQindex;
  1054 + var iBindex;
  1055 +
  1056 + for (i = 0; i < _internalLpArray.length; i++) {
  1057 + oLp = _internalLpArray[i];
  1058 + if (oLp.isBxFb5_2()) {
  1059 + iAddBcCount = iBxBcount - oLp.getBcArray().length; // 需要添加的班次数
  1060 + for (j = 1; j <= iAddBcCount; j++) {
  1061 + oBcChain1 = oLp.fnGetBcChainInfo(0);
  1062 + oBcChain2 = oLp.fnGetBcChainInfo(1);
  1063 +
  1064 + if (oBcChain1.bcount < oBcChain2.bcount) {
  1065 + iQindex = oBcChain1.s_b == 0 ? oBcChain1.s_q - 1 : oBcChain1.s_q;
  1066 + iBindex = oBcChain1.s_b == 0 ? 1 : 0;
  1067 + // 往车次链往前不能加,就往后加
  1068 + if (_fnGenerateBc(i, iQindex, iBindex)) {
  1069 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1070 + } else {
  1071 + iQindex = oBcChain1.e_b == 0 ? oBcChain1.e_q : oBcChain1.e_q + 1;
  1072 + iBindex = oBcChain1.e_b == 0 ? 1 : 0;
  1073 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1074 + }
  1075 +
  1076 + } else if (oBcChain1.bcount > oBcChain2.bcount) {
  1077 + iQindex = oBcChain2.s_b == 0 ? oBcChain2.s_q - 1 : oBcChain2.s_q;
  1078 + iBindex = oBcChain2.s_b == 0 ? 1 : 0;
  1079 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1080 + } else {
  1081 + iQindex = oBcChain2.s_b == 0 ? oBcChain2.s_q - 1 : oBcChain2.s_q;
  1082 + iBindex = oBcChain2.s_b == 0 ? 1 : 0;
  1083 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1084 + }
  1085 + }
  1086 + }
  1087 + }
  1088 +
  1089 + },
  1090 +
  1091 + /**
  1092 + * 补其他分班班型班次。
  1093 + * 从车次链的后面开始加
  1094 + */
  1095 + fnCalcuLpBx_other: function() {
  1096 + // TODO:根据上标线的首班时间确定班型,小于05:59的做一休一,否则做二休一
  1097 + var oSt = _qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();
  1098 + var iBxIndex = 4;
  1099 + if (oSt.isBefore(_paramObj.toTimeObj("05:59"))) {
  1100 + iBxIndex = 5;
  1101 + }
  1102 + // 计算做5休2班型所需的班次数
  1103 + var iQBcount = _aBxDesc[iBxIndex].fQCount;
  1104 + var iBxBcount = Math.round(iQBcount) * 2;
  1105 +
  1106 + var i;
  1107 + var j;
  1108 + var oLp;
  1109 + var iAddBcCount;
  1110 + var oBcChain1;
  1111 + var oBcChain2;
  1112 + var iQindex;
  1113 + var iBindex;
  1114 +
  1115 + for (i = 0; i < _internalLpArray.length; i++) {
  1116 + oLp = _internalLpArray[i];
  1117 + if (oLp.isBxFb() && !oLp.isBxFb5_2()) {
  1118 + iAddBcCount = iBxBcount - oLp.getBcArray().length; // 需要添加的班次数
  1119 + for (j = 1; j <= iAddBcCount; j++) {
  1120 + oBcChain1 = oLp.fnGetBcChainInfo(0);
  1121 + oBcChain2 = oLp.fnGetBcChainInfo(1);
  1122 +
  1123 + if (oBcChain1.bcount < oBcChain2.bcount) {
  1124 + iQindex = oBcChain1.e_b == 0 ? oBcChain1.e_q : oBcChain1.e_q + 1;
  1125 + iBindex = oBcChain1.e_b == 0 ? 1 : 0;
  1126 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1127 + } else if (oBcChain1.bcount > oBcChain2.bcount) {
  1128 + iQindex = oBcChain2.e_b == 0 ? oBcChain2.e_q : oBcChain2.e_q + 1;
  1129 + iBindex = oBcChain2.e_b == 0 ? 1 : 0;
  1130 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1131 + } else {
  1132 + iQindex = oBcChain2.e_b == 0 ? oBcChain2.e_q : oBcChain2.e_q + 1;
  1133 + iBindex = oBcChain2.e_b == 0 ? 1 : 0;
  1134 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1135 + }
  1136 + }
  1137 + }
  1138 + }
  1139 +
  1140 + },
  1141 +
  1142 + /**
  1143 + * 补充连班路牌班次。
  1144 + * 1、上标线,中标线中间的连班路牌班次从早高峰班次一直拉到底,从早高峰班次向上标线起始班次靠拢
  1145 + * 2、中标线以下的连班路牌班次从早高峰班次一直拉到底,从早高峰班次向中标线起始班次靠拢
  1146 + */
  1147 + fnCalcuLpBx_lb: function() {
  1148 + // 补充连班的班次,参照上标线,中标线补充不足的班次
  1149 +
  1150 + var aLbLpindexes = []; // 除上标线,中标线的连班路牌索引
  1151 + var i;
  1152 + for (i = 0; i < _internalLpArray.length; i++) {
  1153 + if (_internalLpArray[i].isBxLb() && i != 0 && i != _iZbx_lpIndex) {
  1154 + aLbLpindexes.push(i);
  1155 + }
  1156 + }
  1157 +
  1158 + var oEndsj = // 结束时间
  1159 + _paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj()) ?
  1160 + _paramObj.getDownLastDTimeObj() :
  1161 + _paramObj.getUpLastDtimeObj();
  1162 +
  1163 + var oLp;
  1164 + var aMinbcPos;
  1165 + var oBc;
  1166 + var j;
  1167 + var iTempBcIndex;
  1168 +
  1169 + // 1、从最小班次开始,往后补充班次
  1170 + for (i = 0; i < aLbLpindexes.length; i++) {
  1171 + oLp = _internalLpArray[aLbLpindexes[i]];
  1172 +
  1173 + // 最小班次索引
  1174 + aMinbcPos = oLp.getMinBcObjPosition();
  1175 + // 使用纵向分隔补充班次,从最小班次向后补
  1176 + iTempBcIndex = aMinbcPos[1] == 0 ? 1 : 0;
  1177 + j = iTempBcIndex == 0 ? aMinbcPos[0] + 1 : aMinbcPos[0];
  1178 +
  1179 + while (j < _qCount) {
  1180 + while (iTempBcIndex <= 1) {
  1181 + oBc = _fnGenerateBc(aLbLpindexes[i], j, iTempBcIndex);
  1182 + if (oBc &&
  1183 + oBc.getFcTimeObj().isBefore(oEndsj) ) {
  1184 + oLp.setBc(j, iTempBcIndex, oBc);
  1185 + }
  1186 + iTempBcIndex++;
  1187 + }
  1188 + iTempBcIndex = 0;
  1189 + j++;
  1190 + }
  1191 +
  1192 + }
  1193 +
  1194 + // 2、上标线中标线之间的路牌,从最小的班次往前补充班次
  1195 +
  1196 + // 还要补充缺失的班次,差上标线几个班次要往前补上
  1197 + var iBccount;
  1198 + var iQindex;
  1199 + var iBindex;
  1200 + // 补上标线到中标线之间的连班路牌的班次
  1201 + for (i = 0; i < aLbLpindexes.length; i++) {
  1202 + if (aLbLpindexes[i] > 0 && aLbLpindexes[i] < _iZbx_lpIndex) {
  1203 + oLp = _internalLpArray[aLbLpindexes[i]];
  1204 + aMinbcPos = oLp.getMinBcObjPosition();
  1205 + iQindex = aMinbcPos[0];
  1206 + iBindex = aMinbcPos[1];
  1207 + iBccount = (iQindex - 1) * 2 + iBindex; // 距离上标线起始站点差几个班次
  1208 + for (j = 0; j < iBccount; j++) {
  1209 + if (iBindex == 0) {
  1210 + iQindex --;
  1211 + iBindex = 1;
  1212 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1213 + } else if (iBindex == 1) {
  1214 + iBindex --;
  1215 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1216 + }
  1217 + }
  1218 +
  1219 + }
  1220 +
  1221 + }
  1222 +
  1223 + // 3、中标线之后的路牌,从最小的班次往前补充班次
  1224 +
  1225 + // 补中标线以下的连班路牌的班次
  1226 + for (i = 0; i < aLbLpindexes.length; i++) {
  1227 + if (aLbLpindexes[i] > _iZbx_lpIndex) {
  1228 + oLp = _internalLpArray[aLbLpindexes[i]];
  1229 + aMinbcPos = oLp.getMinBcObjPosition();
  1230 + iQindex = aMinbcPos[0];
  1231 + iBindex = aMinbcPos[1];
  1232 + iBccount = (iQindex - 0) * 2 + iBindex - 1; // 距离上标线起始站点差几个班次
  1233 + for (j = 0; j < iBccount; j++) {
  1234 + if (iBindex == 0) {
  1235 + iQindex --;
  1236 + iBindex = 1;
  1237 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1238 + } else if (iBindex == 1) {
  1239 + iBindex --;
  1240 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1241 + }
  1242 + }
  1243 + }
  1244 + }
  1245 +
  1246 + },
  1247 +
  1248 + /**
  1249 + * 计算末班车。
  1250 + * 1、将上下行拉成上下行两个班次列表(包括标记班次)
  1251 + * 2、分别找出离末班车发车时间最近的班次,并替换时间
  1252 + * 3、删除之后的班次
  1253 + */
  1254 + fnCalcuLastBc: function() {
  1255 + var i;
  1256 + var iTimeDiff;
  1257 + var iTempTime;
  1258 + var aBc;
  1259 + var oLastBcTime;
  1260 + var oLastBcIsUp;
  1261 + var iModifyIndex;
  1262 +
  1263 + // 查找末班车早的末班车时间和方向
  1264 + if (_paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj())) {
  1265 + oLastBcTime = _paramObj.getUpLastDtimeObj();
  1266 + oLastBcIsUp = true;
  1267 + } else {
  1268 + oLastBcTime = _paramObj.getDownLastDTimeObj();
  1269 + oLastBcIsUp = false;
  1270 + }
  1271 +
  1272 + // 确定早的末班车时间
  1273 + aBc = _fnGetBcList(oLastBcIsUp);
  1274 + for (i = 0; i < aBc.length; i++) {
  1275 + iTempTime = oLastBcTime.diff(aBc[i].getFcTimeObj(), "m");
  1276 + if (iTimeDiff == undefined) {
  1277 + iTimeDiff = iTempTime;
  1278 + iModifyIndex = i;
  1279 + } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff)) {
  1280 + iTimeDiff = iTempTime;
  1281 + iModifyIndex = i;
  1282 + }
  1283 + }
  1284 + aBc[iModifyIndex].addMinuteToFcsj(iTimeDiff); // 替换成末班车时间
  1285 + aBc[iModifyIndex].fnSetDelFlag(false);
  1286 + for (i = iModifyIndex + 1; i < aBc.length; i++) { // 删除多余班次
  1287 + _qIsUp == oLastBcIsUp ?
  1288 + aBc[i]._$$_internal_group_obj.setBc1(undefined) :
  1289 + aBc[i]._$$_internal_group_obj.setBc2(undefined);
  1290 + }
  1291 +
  1292 + // 查找末班车晚的末班车时间和方向
  1293 + if (_paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj())) {
  1294 + oLastBcTime = _paramObj.getDownLastDTimeObj();
  1295 + oLastBcIsUp = false;
  1296 + } else {
  1297 + oLastBcTime = _paramObj.getUpLastDtimeObj();
  1298 + oLastBcIsUp = true;
  1299 + }
  1300 + // 确定晚的末班车时间
  1301 + aBc = _fnGetBcList(oLastBcIsUp);
  1302 + var oBc;
  1303 + var aBcIndex;
  1304 + var iLpIndex;
  1305 + var iQIndex;
  1306 + var iBcIndex;
  1307 +
  1308 + iTimeDiff = undefined;
  1309 + for (i = 0; i < aBc.length; i++) {
  1310 + oBc = aBc[i];
  1311 + aBcIndex = _fnGetBcIndex(oBc);
  1312 +
  1313 + iLpIndex = aBcIndex[0];
  1314 + iQIndex = aBcIndex[2] == 0 ? aBcIndex[1] -1 : aBcIndex[1];
  1315 + iBcIndex = aBcIndex[2] == 0 ? 1 : 0;
  1316 +
  1317 + if (!_internalLpArray[iLpIndex].getBc(iQIndex, iBcIndex)) {
  1318 + continue;
  1319 + }
  1320 +
  1321 + iTempTime = oLastBcTime.diff(aBc[i].getFcTimeObj(), "m");
  1322 + if (iTimeDiff == undefined) {
  1323 + iTimeDiff = iTempTime;
  1324 + iModifyIndex = i;
  1325 + } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff)) {
  1326 + iTimeDiff = iTempTime;
  1327 + iModifyIndex = i;
  1328 + }
  1329 + }
  1330 + aBc[iModifyIndex].addMinuteToFcsj(iTimeDiff); // 替换成末班车时间
  1331 + aBc[iModifyIndex].fnSetDelFlag(false);
  1332 + for (i = iModifyIndex + 1; i < aBc.length; i++) { // 删除多余班次
  1333 + _qIsUp == oLastBcIsUp ?
  1334 + aBc[i]._$$_internal_group_obj.setBc1(undefined) :
  1335 + aBc[i]._$$_internal_group_obj.setBc2(undefined);
  1336 + }
  1337 +
  1338 + },
  1339 +
  1340 + /**
  1341 + * 添加吃饭班次。
  1342 + */
  1343 + fnCalcuEatBc: function() {
  1344 + // 吃午饭时间范围,10:15 到 12:15
  1345 + // 吃晚饭时间范围,18:00 到 19:00
  1346 +
  1347 + if (!_paramObj.fnIsEat()) {
  1348 + return;
  1349 + }
  1350 +
  1351 + // 午饭index
  1352 + var aLEIndex;
  1353 + // 晚饭index
  1354 + var aDEIndex;
  1355 +
  1356 + // 所有吃饭都默认在一个方向,两个方向暂时不考虑
  1357 + if (_paramObj.fnIsUpEat()) {
  1358 + aLEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("10:15"), true, false);
  1359 + aDEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("18:00"), true, false);
  1360 + } else {
  1361 + aLEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("10:15"), false, true);
  1362 + aDEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("18:00"), false, true);
  1363 + }
  1364 +
  1365 + // 午饭第几圈,第几个班次
  1366 + var iLEQIndex = aLEIndex[0];
  1367 + var iLEBIndex = aLEIndex[1];
  1368 + // 晚饭第几圈,第几个班次
  1369 + var iDEQIndex = aDEIndex[0];
  1370 + var iDEBIndex = aDEIndex[1];
  1371 +
  1372 + // 注意,本模型只有连班才有吃饭
  1373 +
  1374 + var i;
  1375 + var oLp;
  1376 + var aLbIndex = []; // 连班班型的路牌索引
  1377 + for (i = 0; i < _internalLpArray.length; i++) {
  1378 + oLp = _internalLpArray[i];
  1379 + if (oLp.isBxLb()) {
  1380 + aLbIndex.push(i);
  1381 + }
  1382 + }
  1383 +
  1384 + var iLTime;
  1385 + var iDtime;
  1386 + var j;
  1387 + for (i = 0; i < aLbIndex.length; i++) {
  1388 + oLp = _internalLpArray[aLbIndex[i]];
  1389 +
  1390 + // 午饭
  1391 + iLTime = oLp.fnAddEatBc(iLEQIndex, iLEBIndex, _factory, _paramObj);
  1392 + // 晚饭
  1393 + iDtime = oLp.fnAddEatBc(iDEQIndex, iDEBIndex, _factory, _paramObj);
  1394 +
  1395 + if (i == aLbIndex.length - 1) {
  1396 + for (j = aLbIndex[i]; j < _internalLpArray.length; j++) {
  1397 + oLp = _internalLpArray[j];
  1398 + if (oLp.isBxFb()) { // 5休2班型不调整
  1399 + // 修正午饭之后路牌班次的发车时间
  1400 + oLp.fnAddMinuteToBcFcsj(iLEQIndex, iLEBIndex, iLTime);
  1401 + oLp.fnAddMinuteToBcFcsj(iDEQIndex, iDEBIndex, iDtime);
  1402 + }
  1403 + }
  1404 + } else {
  1405 + for (j = aLbIndex[i]; j < aLbIndex[i + 1]; j++) {
  1406 + oLp = _internalLpArray[j];
  1407 + if (oLp.isBxFb()) {
  1408 + // 修正午饭之后路牌班次的发车时间
  1409 + oLp.fnAddMinuteToBcFcsj(iLEQIndex, iLEBIndex, iLTime);
  1410 + oLp.fnAddMinuteToBcFcsj(iDEQIndex, iDEBIndex, iDtime);
  1411 + }
  1412 + }
  1413 + }
  1414 + }
  1415 +
  1416 + },
  1417 +
  1418 + /**
  1419 + * 补每个路牌的其他班次(进出场,例保班次)。
  1420 + */
  1421 + fnCalcuOtherBc: function() {
  1422 + var i;
  1423 + var _lpObj;
  1424 + var _minBcIndex;
  1425 + var _maxBcIndex;
  1426 + var _minBc;
  1427 + var _maxBc;
  1428 + var _otherbc = [];
  1429 + var _oFbbc;
  1430 +
  1431 + for (i = 0; i < _internalLpArray.length; i++) {
  1432 + _lpObj = _internalLpArray[i];
  1433 + _minBcIndex = _lpObj.getMinBcObjPosition();
  1434 + _maxBcIndex = _lpObj.getMaxBcObjPosition();
  1435 + _minBc = _lpObj.getBc(_minBcIndex[0], _minBcIndex[1]);
  1436 + _maxBc = _lpObj.getBc(_maxBcIndex[0], _maxBcIndex[1]);
  1437 +
  1438 + _otherbc = [];
  1439 + _otherbc.push(_factory.createBcObj(
  1440 + _lpObj, "bd", true, 1,
  1441 + _minBc.getFcTimeObj(),
  1442 + _paramObj
  1443 + ));
  1444 + _otherbc.push(_factory.createBcObj(
  1445 + _lpObj, "out", true, 1,
  1446 + _minBc.getFcTimeObj(),
  1447 + _paramObj
  1448 + ));
  1449 +
  1450 + _maxBc.setArrTimeObj(_paramObj.addMinute(_maxBc.getFcTimeObj(), _maxBc.getBcTime()));
  1451 + _maxBc.setStopTime(0);
  1452 + _otherbc.push(_factory.createBcObj(
  1453 + _lpObj, "in", true, 1,
  1454 + _maxBc.getArrTimeObj(),
  1455 + _paramObj
  1456 + ));
  1457 + _otherbc.push(_factory.createBcObj(
  1458 + _lpObj, "lc", true, 1,
  1459 + _maxBc.getArrTimeObj(),
  1460 + _paramObj
  1461 + ));
  1462 +
  1463 + // 5休2分班出场例保班次
  1464 + if (_lpObj.isBxFb5_2()) {
  1465 + _oFbbc = _lpObj.getBc(
  1466 + _lpObj.fnGetBcChainInfo(1)["s_q"],
  1467 + _lpObj.fnGetBcChainInfo(1)["s_b"]
  1468 + );
  1469 +
  1470 + _otherbc.push(_factory.createBcObj(
  1471 + _lpObj, "bd", true, 1,
  1472 + _oFbbc.getFcTimeObj(),
  1473 + _paramObj
  1474 + ));
  1475 + _otherbc.push(_factory.createBcObj(
  1476 + _lpObj, "out", true, 1,
  1477 + _oFbbc.getFcTimeObj(),
  1478 + _paramObj
  1479 + ));
  1480 + }
  1481 +
  1482 + _lpObj.addOtherBcArray(_otherbc);
  1483 + }
  1484 +
  1485 + },
  1486 +
  1487 + /**
  1488 + * 祛除上标线开头的删除标记的班次。
  1489 + */
  1490 + fnRemoveDelFirstFlagBc: function() {
  1491 + var oLp = _internalLpArray[0];
  1492 + var aMinBcIndex = oLp.getMinBcObjPosition();
  1493 + oLp.removeBc(aMinBcIndex[0], aMinBcIndex[1]);
  1494 + },
  1495 + /**
  1496 + * 祛除上标线结尾的删除标记的班次。
  1497 + */
  1498 + fnRemoveDelLastFlagBc: function() {
  1499 + var oLp = _internalLpArray[0];
  1500 + var aMaxBcIndex = oLp.getMaxBcObjPosition();
  1501 + if (oLp.getBc(aMaxBcIndex[0], aMaxBcIndex[1]).fnIsDelFlag()) {
  1502 + oLp.removeBc(aMaxBcIndex[0], aMaxBcIndex[1]);
  1503 + }
  1504 + },
  1505 +
  1506 + /**
  1507 + * 调整路牌班次间隔(核准周转时间,停站时间)。
  1508 + * @param iFre int 迭代次数
  1509 + */
  1510 + fnAdjustLpBcInterval: function(iFre) {
  1511 + if (iFre > 0) {
  1512 + for (var i = 0; i < _internalLpArray.length; i++) {
  1513 + _internalLpArray[i].fnAdjustBcInterval(
  1514 + this.fnCalcuAverPeakStopTime(),
  1515 + this.fnCalcuAverTroughStopTime(),
  1516 + _paramObj);
  1517 + }
  1518 +
  1519 + this.fnAdjustLpBcInterval(iFre - 1);
  1520 + }
  1521 + },
  1522 +
  1523 + /**
  1524 + * 调整班次间隔。
  1525 + * @param bIsUp 是否上行
  1526 + * @param oStartTime 开始时间对象
  1527 + * @param iFre 迭代次数
  1528 + */
  1529 + fnAdjustBcInterval2_: function(bIsUp, oStartTime, iFre) {
  1530 + if (iFre > 0) {
  1531 + var aBc = _fnGetBcList2(bIsUp, oStartTime); // 指定方向的班次列表
  1532 + aBc.sort(function(o1, o2) {
  1533 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1534 + return -1;
  1535 + } else {
  1536 + return 1;
  1537 + }
  1538 + });
  1539 + var i;
  1540 + var j;
  1541 +
  1542 + var iBcCountOfGroup = 3; // 3个班次取一次计算
  1543 + var aBcOfGroup; // 3个班次列表
  1544 + var aBcIntervalOfGroup; // 班次间隔列表,如:3个班次,2个间隔
  1545 +
  1546 + for (i = 0; i <= aBc.length - iBcCountOfGroup; i++) {
  1547 + aBcOfGroup = [];
  1548 + aBcIntervalOfGroup = [];
  1549 + for (j = i; j < i + iBcCountOfGroup; j++) {
  1550 + aBcOfGroup.push(aBc[j]);
  1551 + }
  1552 +
  1553 + for (j = 0; j < aBcOfGroup.length; j++) {
  1554 + if (j < aBcOfGroup.length - 1) {
  1555 + aBcIntervalOfGroup.push(aBcOfGroup[j + 1].getFcTimeObj().diff(
  1556 + aBcOfGroup[j].getFcTimeObj(), "m"));
  1557 + }
  1558 + }
  1559 +
  1560 + if (aBcIntervalOfGroup[0] < 19) {
  1561 + aBcOfGroup[1].addMinuteToFcsj(1);
  1562 + } else if (aBcIntervalOfGroup[0] > 20) {
  1563 + aBcOfGroup[1].addMinuteToFcsj(-1);
  1564 + } else {
  1565 + if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {
  1566 + //continue;
  1567 + } else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {
  1568 + aBcOfGroup[1].addMinuteToFcsj(-1);
  1569 + } else {
  1570 + aBcOfGroup[1].addMinuteToFcsj(1);
  1571 + }
  1572 + }
  1573 +
  1574 + }
  1575 +
  1576 + this.fnAdjustBcInterval2(bIsUp, oStartTime, iFre - 1);
  1577 + }
  1578 + },
  1579 +
  1580 + /**
  1581 + * 调整班次间隔。
  1582 + * @param boolean isUp 是否上行
  1583 + * @param oStartTime 开始时间对象
  1584 + * @param fre int 迭代次数
  1585 + */
  1586 + fnAdjustBcInterval: function(isUp, oStartTime, fre) {
  1587 + if (fre > 0) {
  1588 + var aBc = !oStartTime ? _fnGetBcList(isUp) : _fnGetBcList2(isUp, oStartTime); // 指定方向的班次列表
  1589 +
  1590 + aBc.sort(function(o1, o2) {
  1591 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1592 + return -1;
  1593 + } else {
  1594 + return 1;
  1595 + }
  1596 + });
  1597 +
  1598 + var i;
  1599 + var j;
  1600 +
  1601 + var iBcCountOfGroup = 3; // 3个班次取一次计算
  1602 + var aBcOfGroup; // 3个班次列表
  1603 + var aBcIntervalOfGroup; // 班次间隔列表,如:3个班次,2个间隔
  1604 + var oBcFcTime; // 班次发车时间
  1605 +
  1606 + for (i = 0; i <= aBc.length - iBcCountOfGroup; i++) {
  1607 + aBcOfGroup = [];
  1608 + aBcIntervalOfGroup = [];
  1609 + for (j = i; j < i + iBcCountOfGroup; j++) {
  1610 + aBcOfGroup.push(aBc[j]);
  1611 + }
  1612 +
  1613 + for (j = 0; j < aBcOfGroup.length; j++) {
  1614 + if (j < aBcOfGroup.length - 1) {
  1615 + aBcIntervalOfGroup.push(aBcOfGroup[j + 1].getFcTimeObj().diff(
  1616 + aBcOfGroup[j].getFcTimeObj(), "m"));
  1617 + }
  1618 + }
  1619 +
  1620 + // 判定规则
  1621 + oBcFcTime = aBcOfGroup[1].getFcTimeObj();
  1622 +
  1623 + // 第一个班次发车时间不动,根据间隔,调整中间一个班次
  1624 + // 如果3个班次2个间隔时间差1分钟,不调整
  1625 + // 如果第一个间隔大,调整第二个班次往前1分钟
  1626 + // 如果第二个间隔大,调整第二个班次往后1分钟
  1627 +
  1628 + if (_paramObj.isTroughBc(oBcFcTime) &&
  1629 + aBcIntervalOfGroup[0] > _paramObj.getTroughMaxFcjx()) {
  1630 + aBcOfGroup[1].addMinuteToFcsj(-1);
  1631 + }
  1632 +
  1633 + //else if (_paramObj.isMPeakBc(oBcFcTime) &&
  1634 + // aBcIntervalOfGroup[0] < _paramObj.getMPeakMinFcjx()) {
  1635 + // aBcOfGroup[1].addMinuteToFcsj(1);
  1636 + //} else if (_paramObj.isMPeakBc(oBcFcTime) &&
  1637 + // aBcIntervalOfGroup[0] > _paramObj.getMPeakMaxFcjx()) {
  1638 + // aBcOfGroup[1].addMinuteToFcsj(-1);
  1639 + //} else if (_paramObj.isEPeakBc(oBcFcTime) &&
  1640 + // aBcIntervalOfGroup[0] < _paramObj.getEPeakMinFcjx()) {
  1641 + // aBcOfGroup[1].addMinuteToFcsj(1);
  1642 + //} else if (_paramObj.isEPeakBc(oBcFcTime) &&
  1643 + // aBcIntervalOfGroup[0] > _paramObj.getEPeakMaxFcjx()) {
  1644 + // aBcOfGroup[1].addMinuteToFcsj(-1);
  1645 + //}
  1646 +
  1647 +
  1648 + else {
  1649 + if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {
  1650 + //continue;
  1651 + } else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {
  1652 + aBcOfGroup[1].addMinuteToFcsj(-1);
  1653 + } else {
  1654 + aBcOfGroup[1].addMinuteToFcsj(1);
  1655 + }
  1656 + }
  1657 +
  1658 + //if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {
  1659 + // //continue;
  1660 + //} else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {
  1661 + // aBcOfGroup[1].addMinuteToFcsj(-1);
  1662 + //} else {
  1663 + // aBcOfGroup[1].addMinuteToFcsj(1);
  1664 + //}
  1665 +
  1666 +
  1667 + }
  1668 +
  1669 + this.fnAdjustBcInterval(isUp, oStartTime, fre - 1);
  1670 + }
  1671 +
  1672 + },
  1673 +
  1674 + /**
  1675 + * 调整班次间隔(平均间隔)。
  1676 + * @param bIsUp 是否上行
  1677 + * @param oStartTime 开始时间对象
  1678 + */
  1679 + fnAdjustBcInterval2_avg: function(bIsUp, oStartTime) {
  1680 + var aBc = !oStartTime ? _fnGetBcList(bIsUp) : _fnGetBcList2(bIsUp, oStartTime); // 指定方向的班次列表
  1681 + aBc.sort(function(o1, o2) {
  1682 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1683 + return -1;
  1684 + } else {
  1685 + return 1;
  1686 + }
  1687 + });
  1688 +
  1689 + var j;
  1690 + var iCount = aBc.length - 1;
  1691 + var iC1 = Math.floor(aBc[aBc.length - 1].getFcTimeObj().diff(aBc[0].getFcTimeObj(), "m") / iCount);
  1692 + var iC2 = aBc[aBc.length - 1].getFcTimeObj().diff(aBc[0].getFcTimeObj(), "m") % iCount;
  1693 + var iTempTime;
  1694 +
  1695 + for (j = 0; j < iCount - iC2; j++) {
  1696 + iTempTime = aBc[j + 1].getFcTimeObj().diff(aBc[j].getFcTimeObj(), "m");
  1697 + aBc[j + 1].addMinuteToFcsj(iC1 - iTempTime);
  1698 + }
  1699 + for (j = 0; j < iC2; j++) {
  1700 + iTempTime = aBc[iCount - iC2 + j + 1].getFcTimeObj().diff(aBc[iCount - iC2 + j].getFcTimeObj(), "m");
  1701 + aBc[iCount - iC2 + j + 1].addMinuteToFcsj(iC1 + 1 - iTempTime);
  1702 + }
  1703 +
  1704 + },
  1705 +
  1706 + /**
  1707 + * 计算高峰平均停站时间。
  1708 + */
  1709 + fnCalcuAverPeakStopTime: function() {
  1710 + var i;
  1711 + var j;
  1712 + var aBc;
  1713 + var iBcCount = 0;
  1714 + var iSum = 0;
  1715 + for (i = 0; i < _internalLpArray.length; i++) {
  1716 + aBc = _internalLpArray[i].getBcArray();
  1717 +
  1718 + for (j = 0; j < aBc.length; j++) {
  1719 + if (!_paramObj.isTroughBc(aBc[j].getArrTimeObj())) {
  1720 + iBcCount ++;
  1721 + iSum += aBc[j].getStopTime();
  1722 + }
  1723 + }
  1724 + }
  1725 +
  1726 + return Math.floor(iSum / iBcCount);
  1727 + },
  1728 +
  1729 + /**
  1730 + * 计算低谷平均停站时间。
  1731 + */
  1732 + fnCalcuAverTroughStopTime: function() {
  1733 + var i;
  1734 + var j;
  1735 + var aBc;
  1736 + var iBcCount = 0;
  1737 + var iSum = 0;
  1738 + for (i = 0; i < _internalLpArray.length; i++) {
  1739 + aBc = _internalLpArray[i].getBcArray();
  1740 + for (j = 0; j < aBc.length; j++) {
  1741 + if (_paramObj.isTroughBc(aBc[j].getArrTimeObj())) {
  1742 + iBcCount ++;
  1743 + iSum += aBc[j].getStopTime();
  1744 + }
  1745 + }
  1746 + }
  1747 +
  1748 + return Math.floor(iSum / iBcCount);
  1749 + },
  1750 +
  1751 + //------------- 其他方法 -------------//
  1752 + /**
  1753 + * 内部数据转化成显示用的班次数组。
  1754 + */
  1755 + fnToGanttBcArray: function() {
  1756 + var aAllBc = [];
  1757 + var aLpBc = [];
  1758 + var aEatBc = [];
  1759 + var oLp;
  1760 + var i;
  1761 + var j;
  1762 +
  1763 + for (i = 0; i < _internalLpArray.length; i++) {
  1764 + oLp = _internalLpArray[i];
  1765 + aLpBc = [];
  1766 + aLpBc = aLpBc.concat(oLp.getOtherBcArray(), oLp.getBcArray());
  1767 +
  1768 + aEatBc = [];
  1769 + // 根据班次的吃饭时间添加吃饭班次
  1770 + for (j = 0; j < aLpBc.length; j++) {
  1771 + if (aLpBc[j].fnGetEatTime() > 0) {
  1772 + aEatBc.push(_factory.createBcObj(
  1773 + oLp,
  1774 + "cf",
  1775 + !aLpBc[j].isUp(), // 和上一个班次方向相反
  1776 + 1,
  1777 + _paramObj.addMinute(aLpBc[j].getArrTimeObj(), aLpBc[j].getStopTime()), // 使用上一个班次的到达时间作为开始时间
  1778 + _paramObj
  1779 + ));
  1780 + }
  1781 + }
  1782 + aLpBc = aLpBc.concat(aEatBc);
  1783 +
  1784 + // 按照发车时间排序
  1785 + aLpBc.sort(function(o1, o2) {
  1786 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1787 + return -1;
  1788 + } else {
  1789 + return 1;
  1790 + }
  1791 + });
  1792 +
  1793 + // 重新赋值fcno
  1794 + for (j = 0; j < aLpBc.length; j++) {
  1795 + aLpBc[j].fnSetFcno(j + 1);
  1796 + }
  1797 +
  1798 + aAllBc = aAllBc.concat(aLpBc);
  1799 + }
  1800 +
  1801 + var aGanttBc = [];
  1802 + for (i = 0; i < aAllBc.length; i++) {
  1803 + aGanttBc.push(aAllBc[i].toGanttBcObj());
  1804 + }
  1805 +
  1806 + return aGanttBc;
  1807 + }
  1808 +
  1809 + };
1630 1810 };
1631 1811 \ 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   - // 内部工厂类
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   -
  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 _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, undefined);
  23 + var _tccid = paramObj.getTTinfoId();
  24 + var _ttinfoid = paramObj.getTTinfoId();
  25 + var _xl = paramObj.getXlId();
  26 + var _qdz = isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;
  27 + var _zdz = isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;
  28 +
  29 + if (bcType == "bd") { // 早例保,传过来的发车时间是第一个班次的发车时间
  30 + if (isUp) { // 上行
  31 + _fcsj = paramObj.addMinute(
  32 + _fcsj,
  33 + -(paramObj.getUpOutTime() + paramObj.getLbTime()));
  34 + _bcsj = paramObj.getLbTime();
  35 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  36 + _stoptime = 0;
  37 + } else { // 下行
  38 + _fcsj = paramObj.addMinute(
  39 + _fcsj,
  40 + -(paramObj.getDownOutTime() + paramObj.getLbTime()));
  41 + _bcsj = paramObj.getLbTime();
  42 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  43 + _stoptime = 0;
  44 + }
  45 + } else if (bcType == "lc") { // 晚例保,传过来的发车时间是最后一个班次的到达时间
  46 + if (isUp) { // 上行
  47 + _fcsj = paramObj.addMinute(
  48 + _fcsj,
  49 + paramObj.getUpInTime());
  50 + _bcsj = paramObj.getLbTime();
  51 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  52 + _stoptime = 0;
  53 + } else { // 下行
  54 + _fcsj = paramObj.addMinute(
  55 + _fcsj,
  56 + paramObj.getDownInTime());
  57 + _bcsj = paramObj.getLbTime();
  58 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  59 + _stoptime = 0;
  60 + }
  61 + } else if (bcType == "out") { // 出场,传过来的发车时间是第一个班次的发车时间
  62 + if (isUp) { // 上行
  63 + _fcsj = paramObj.addMinute(
  64 + _fcsj,
  65 + -paramObj.getUpOutTime());
  66 + _bcsj = paramObj.getUpOutTime();
  67 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  68 + _stoptime = 0;
  69 + } else { // 下行
  70 + _fcsj = paramObj.addMinute(
  71 + _fcsj,
  72 + -paramObj.getDownOutTime());
  73 + _bcsj = paramObj.getDownOutTime();
  74 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  75 + _stoptime = 0;
  76 + }
  77 + } else if (bcType == "in") { // 进场,传过来的发车时间是最后一个班次的到达时间
  78 + if (isUp) { // 上行
  79 + _bcsj = paramObj.getUpInTime();
  80 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  81 + _stoptime = 0;
  82 + } else { // 下行
  83 + _bcsj = paramObj.getDownInTime();
  84 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  85 + _stoptime = 0;
  86 + }
  87 + } else if (bcType == "cf") { // 吃饭班次
  88 + // 以13:00为分界,之前的为午饭,之后的为晚饭
  89 + if (fcTimeObj.isBefore(paramObj.toTimeObj("13:00"))) {
  90 + _bcsj = paramObj.fnGetLunchTime();
  91 + } else {
  92 + _bcsj = paramObj.fnGetDinnerTime();
  93 + }
  94 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  95 + _stoptime = 0;
  96 + }
  97 +
  98 + var bcParamObj = {};
  99 + bcParamObj.bcType = bcType; // 班次类型(normal,in_,out, bd, lc, cf等)
  100 + bcParamObj.isUp = isUp; // boolean是否上下行
  101 + bcParamObj.fcno = fcno; // 发车顺序号
  102 + bcParamObj.fcTimeObj = _fcsj; // 发车时间对象
  103 + bcParamObj.bclc = _bclc; // 班次里程
  104 + bcParamObj.bcsj = _bcsj; // 班次历时
  105 + bcParamObj.arrtime = _arrsj; // 到达时间对象
  106 + bcParamObj.stoptime = _stoptime; // 停站时间
  107 + bcParamObj.tccid = _tccid; // 停车场id
  108 + bcParamObj.ttinfoid = _ttinfoid; // 时刻表id
  109 + bcParamObj.xl = _xl; // 线路id
  110 + bcParamObj.qdzid = _qdz; // 起点站id
  111 + bcParamObj.zdzid = _zdz; // 终点站id
  112 +
  113 + return new InternalBcObj(lpObj, bcParamObj);
  114 + }
  115 + };
  116 + };
  117 + var _factory = _factoryFun();
  118 +
  119 + // 所有的时间使用moment.js计算
  120 +
  121 + var _paramObj; // 参数对象
  122 +
  123 + var _bxDesc = [ // 班型描述
  124 + {'type':'六工一休','hoursV':6.66, 'minueV':'6:40', 'qcount': 0, 'avertime': 0},
  125 + {'type':'五工一休','hoursV':6.85, 'minueV':'6:51', 'qcount': 0, 'avertime': 0},
  126 + {'type':'四工一休','hoursV':7.14, 'minueV':'7:08', 'qcount': 0, 'avertime': 0},
  127 + {'type':'三工一休','hoursV':7.61, 'minueV':'7:37', 'qcount': 0, 'avertime': 0},
  128 + {'type':'二工一休','hoursV':8.57, 'minueV':'8:34', 'qcount': 0, 'avertime': 0},
  129 + {'type':'一工一休','hoursV':11.42, 'minueV':'11:25', 'qcount': 0, 'avertime': 0},
  130 + {'type':'五工二休','hoursV':7.99, 'minueV':'8:00', 'qcount': 0, 'avertime': 0},
  131 + {'type':'无工休', 'hoursV':5.43, 'minueV':'5:43', 'qcount': 0, 'avertime': 0}
  132 + ];
  133 +
  134 + return {
  135 + /**
  136 + * 工厂对象,创建不同的对象。
  137 + * @returns {{createParameterObj, createBcObj}}
  138 + */
  139 + getFactory: function() {
  140 + return _factory;
  141 + },
  142 +
  143 + /**
  144 + * 使用发车间隔策略生成时刻表。
  145 + * @param paramObj 参数对象
  146 + * @param lpArray 路牌数组
  147 + * @constructor
  148 + */
  149 + BXPplaceClassesTime03 : function(paramObj, lpArray) {
  150 + // 参数对象
  151 + _paramObj = paramObj;
  152 +
  153 + // 1、初始化行车计划
  154 + var schedule = new InternalScheduleObj(_paramObj, lpArray, _factory);
  155 + schedule.fnInitDataWithBxLayout();
  156 + // 2、将连班路牌的班次补足
  157 + schedule.fnCalcuLpBx_lb();
  158 +
  159 + // 3、修正针对初始化时生成的高峰班次,之前不足的补上,多余的删除
  160 + schedule.fnAdjustGfbc(true, true); // 修正上行早高峰
  161 + schedule.fnAdjustGfbc(true, false); // 修正下行早高峰
  162 + schedule.fnAdjustGfbc(false, true); // 修正上行晚高峰
  163 + schedule.fnAdjustGfbc(false, false); // 修正下行晚高峰
  164 +
  165 + // 6、补吃饭班次
  166 + schedule.fnCalcuEatBc();
  167 +
  168 + // 4、按照车辆投入运营要求补充班次
  169 + schedule.fnCalcuLpBc_yy();
  170 +
  171 + // 5、根据班型补充所有的不足班次
  172 + schedule.fnCalcuLpBx_5_2();
  173 + schedule.fnCalcuLpBx_other();
  174 +
  175 + // 7、祛除上标线开头有删除标记的班次
  176 + schedule.fnRemoveDelFirstFlagBc();
  177 +
  178 + // TODO:8、调整路牌班次间隔
  179 + schedule.fnAdjustLpBcInterval(1);
  180 +
  181 + // TODO:9、调整纵向班次间隔
  182 + schedule.fnAdjustBcInterval(true, false, 10);
  183 + schedule.fnAdjustBcInterval(false, false, 10);
  184 +
  185 + // 10、确定末班车
  186 + schedule.fnCalcuLastBc();
  187 +
  188 + // 11、祛除上标线结尾有删除标记的班次
  189 + schedule.fnRemoveDelLastFlagBc();
  190 +
  191 + // TODO:12、平均化指定时间后的班次列表间隔
  192 + schedule.fnAdjustBcInterval2_avg(true, _paramObj.toTimeObj("19:50"));
  193 + schedule.fnAdjustBcInterval2_avg(false, _paramObj.toTimeObj("19:50"));
  194 +
  195 + // 10、补进出场例保班次
  196 + schedule.fnCalcuOtherBc();
  197 +
  198 + //-------------------- 输出ganut图上的班次,班型描述 ----------------------//
  199 + var gBcData = schedule.fnToGanttBcArray();
  200 + // TODO:班型再议
  201 + return {'json':gBcData,'bxrcgs':null};
  202 +
  203 + }
  204 +
  205 + };
  206 +
196 207 }();
197 208 \ No newline at end of file
... ...