Commit 2553e02beb0ea43c108c497ff6e4ca3b67843e2a

Authored by 徐烜
1 parent 16b2b3db

时刻表v2.5

1、修改添加例保班次的逻辑,单一车次链的路牌头尾都有例保班次,两个车次链的路牌,
   第一个车次链结尾和第二个车次链开头没有例保时间,分班都有进出场的,不考虑停驶
2、如果中标线的位置和上标线一致,将中标线移至第二个连班路牌上,
   以后可能考虑中标线放在分班路牌上
3、修正初始化方法3,计算5休2分班路牌分布的小bug
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   -
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   - */
1491   - fnCalcuOtherBc: function() {
1492   - var i;
1493   - var j;
1494   - var iBcChainCount;
1495   - var oLp;
1496   - var aOtherBc;
1497   - var oStartBc;
1498   - var oEndBc;
1499   -
1500   - for (i = 0; i < _internalLpArray.length; i++) {
1501   - aOtherBc = [];
1502   - oLp = _internalLpArray[i];
1503   - iBcChainCount = oLp.fnGetBcChainCount();
1504   -
1505   - for (j = 0; j < iBcChainCount; j++) {
1506   - oStartBc = oLp.getBc(
1507   - oLp.fnGetBcChainInfo(j)["s_q"],
1508   - oLp.fnGetBcChainInfo(j)["s_b"]
1509   - );
1510   - oEndBc = oLp.getBc(
1511   - oLp.fnGetBcChainInfo(j)["e_q"],
1512   - oLp.fnGetBcChainInfo(j)["e_b"]
1513   - );
1514   -
1515   - // 车次链开头添加出场班次
1516   - aOtherBc.push(_factory.createBcObj(
1517   - oLp, "bd", true, 1,
1518   - oStartBc.getFcTimeObj(),
1519   - _paramObj
1520   - ));
1521   - aOtherBc.push(_factory.createBcObj(
1522   - oLp, "out", true, 1,
1523   - oStartBc.getFcTimeObj(),
1524   - _paramObj
1525   - ));
1526   -
1527   - // 车次链结尾添加进场班次
1528   - aOtherBc.push(_factory.createBcObj(
1529   - oLp, "in", true, 1,
1530   - oEndBc.getArrTimeObj(),
1531   - _paramObj
1532   - ));
1533   - aOtherBc.push(_factory.createBcObj(
1534   - oLp, "lc", true, 1,
1535   - oEndBc.getArrTimeObj(),
1536   - _paramObj
1537   - ));
1538   - }
1539   -
1540   - oLp.addOtherBcArray(aOtherBc);
1541   - }
1542   - },
1543   -
1544   - /**
1545   - * 祛除上标线开头的删除标记的班次。
1546   - */
1547   - fnRemoveDelFirstFlagBc: function() {
1548   - var oLp = _internalLpArray[0];
1549   - var aMinBcIndex = oLp.getMinBcObjPosition();
1550   - oLp.removeBc(aMinBcIndex[0], aMinBcIndex[1]);
1551   - },
1552   - /**
1553   - * 祛除上标线结尾的删除标记的班次。
1554   - */
1555   - fnRemoveDelLastFlagBc: function() {
1556   - var oLp = _internalLpArray[0];
1557   - var aMaxBcIndex = oLp.getMaxBcObjPosition();
1558   - if (oLp.getBc(aMaxBcIndex[0], aMaxBcIndex[1]).fnIsDelFlag()) {
1559   - oLp.removeBc(aMaxBcIndex[0], aMaxBcIndex[1]);
1560   - }
1561   - },
1562   -
1563   - /**
1564   - * 调整路牌班次间隔(核准周转时间,停站时间)。
1565   - * @param iFre int 迭代次数
1566   - */
1567   - fnAdjustLpBcInterval: function(iFre) {
1568   - if (iFre > 0) {
1569   - for (var i = 0; i < _internalLpArray.length; i++) {
1570   - _internalLpArray[i].fnAdjustBcInterval(
1571   - this.fnCalcuAverPeakStopTime(),
1572   - this.fnCalcuAverTroughStopTime(),
1573   - _paramObj);
1574   - }
1575   -
1576   - this.fnAdjustLpBcInterval(iFre - 1);
1577   - }
1578   - },
1579   -
1580   - /**
1581   - * 调整班次间隔。
1582   - * @param bIsUp 是否上行
1583   - * @param oStartTime 开始时间对象
1584   - * @param iFre 迭代次数
1585   - */
1586   - fnAdjustBcInterval2_: function(bIsUp, oStartTime, iFre) {
1587   - if (iFre > 0) {
1588   - var aBc = _fnGetBcList2(bIsUp, oStartTime); // 指定方向的班次列表
1589   - aBc.sort(function(o1, o2) {
1590   - if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
1591   - return -1;
1592   - } else {
1593   - return 1;
1594   - }
1595   - });
1596   - var i;
1597   - var j;
1598   -
1599   - var iBcCountOfGroup = 3; // 3个班次取一次计算
1600   - var aBcOfGroup; // 3个班次列表
1601   - var aBcIntervalOfGroup; // 班次间隔列表,如:3个班次,2个间隔
1602   -
1603   - for (i = 0; i <= aBc.length - iBcCountOfGroup; i++) {
1604   - aBcOfGroup = [];
1605   - aBcIntervalOfGroup = [];
1606   - for (j = i; j < i + iBcCountOfGroup; j++) {
1607   - aBcOfGroup.push(aBc[j]);
1608   - }
1609   -
1610   - for (j = 0; j < aBcOfGroup.length; j++) {
1611   - if (j < aBcOfGroup.length - 1) {
1612   - aBcIntervalOfGroup.push(aBcOfGroup[j + 1].getFcTimeObj().diff(
1613   - aBcOfGroup[j].getFcTimeObj(), "m"));
1614   - }
1615   - }
1616   -
1617   - if (aBcIntervalOfGroup[0] < 19) {
1618   - aBcOfGroup[1].addMinuteToFcsj(1);
1619   - } else if (aBcIntervalOfGroup[0] > 20) {
1620   - aBcOfGroup[1].addMinuteToFcsj(-1);
1621   - } else {
1622   - if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {
1623   - //continue;
1624   - } else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {
1625   - aBcOfGroup[1].addMinuteToFcsj(-1);
1626   - } else {
1627   - aBcOfGroup[1].addMinuteToFcsj(1);
1628   - }
1629   - }
1630   -
1631   - }
1632   -
1633   - this.fnAdjustBcInterval2(bIsUp, oStartTime, iFre - 1);
1634   - }
1635   - },
1636   -
1637   - /**
1638   - * 调整班次间隔。
1639   - * @param boolean isUp 是否上行
1640   - * @param oStartTime 开始时间对象
1641   - * @param fre int 迭代次数
1642   - */
1643   - fnAdjustBcInterval: function(isUp, oStartTime, fre) {
1644   - if (fre > 0) {
1645   - var aBc = !oStartTime ? _fnGetBcList(isUp) : _fnGetBcList2(isUp, oStartTime); // 指定方向的班次列表
1646   -
1647   - aBc.sort(function(o1, o2) {
1648   - if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
1649   - return -1;
1650   - } else {
1651   - return 1;
1652   - }
1653   - });
1654   -
1655   - var i;
1656   - var j;
1657   -
1658   - var iBcCountOfGroup = 3; // 3个班次取一次计算
1659   - var aBcOfGroup; // 3个班次列表
1660   - var aBcIntervalOfGroup; // 班次间隔列表,如:3个班次,2个间隔
1661   - var oBcFcTime; // 班次发车时间
1662   -
1663   - for (i = 0; i <= aBc.length - iBcCountOfGroup; i++) {
1664   - aBcOfGroup = [];
1665   - aBcIntervalOfGroup = [];
1666   - for (j = i; j < i + iBcCountOfGroup; j++) {
1667   - aBcOfGroup.push(aBc[j]);
1668   - }
1669   -
1670   - for (j = 0; j < aBcOfGroup.length; j++) {
1671   - if (j < aBcOfGroup.length - 1) {
1672   - aBcIntervalOfGroup.push(aBcOfGroup[j + 1].getFcTimeObj().diff(
1673   - aBcOfGroup[j].getFcTimeObj(), "m"));
1674   - }
1675   - }
1676   -
1677   - // 判定规则
1678   - oBcFcTime = aBcOfGroup[1].getFcTimeObj();
1679   -
1680   - // 第一个班次发车时间不动,根据间隔,调整中间一个班次
1681   - // 如果3个班次2个间隔时间差1分钟,不调整
1682   - // 如果第一个间隔大,调整第二个班次往前1分钟
1683   - // 如果第二个间隔大,调整第二个班次往后1分钟
1684   -
1685   - if (_paramObj.isTroughBc(oBcFcTime) &&
1686   - aBcIntervalOfGroup[0] > _paramObj.getTroughMaxFcjx()) {
1687   - aBcOfGroup[1].addMinuteToFcsj(-1);
1688   - }
1689   -
1690   - //else if (_paramObj.isMPeakBc(oBcFcTime) &&
1691   - // aBcIntervalOfGroup[0] < _paramObj.getMPeakMinFcjx()) {
1692   - // aBcOfGroup[1].addMinuteToFcsj(1);
1693   - //} else if (_paramObj.isMPeakBc(oBcFcTime) &&
1694   - // aBcIntervalOfGroup[0] > _paramObj.getMPeakMaxFcjx()) {
1695   - // aBcOfGroup[1].addMinuteToFcsj(-1);
1696   - //} else if (_paramObj.isEPeakBc(oBcFcTime) &&
1697   - // aBcIntervalOfGroup[0] < _paramObj.getEPeakMinFcjx()) {
1698   - // aBcOfGroup[1].addMinuteToFcsj(1);
1699   - //} else if (_paramObj.isEPeakBc(oBcFcTime) &&
1700   - // aBcIntervalOfGroup[0] > _paramObj.getEPeakMaxFcjx()) {
1701   - // aBcOfGroup[1].addMinuteToFcsj(-1);
1702   - //}
1703   -
1704   -
1705   - else {
1706   - if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {
1707   - //continue;
1708   - } else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {
1709   - aBcOfGroup[1].addMinuteToFcsj(-1);
1710   - } else {
1711   - aBcOfGroup[1].addMinuteToFcsj(1);
1712   - }
1713   - }
1714   -
1715   - //if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {
1716   - // //continue;
1717   - //} else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {
1718   - // aBcOfGroup[1].addMinuteToFcsj(-1);
1719   - //} else {
1720   - // aBcOfGroup[1].addMinuteToFcsj(1);
1721   - //}
1722   -
1723   -
1724   - }
1725   -
1726   - this.fnAdjustBcInterval(isUp, oStartTime, fre - 1);
1727   - }
1728   -
1729   - },
1730   -
1731   - /**
1732   - * 调整班次间隔(平均间隔)。
1733   - * @param bIsUp 是否上行
1734   - * @param oStartTime 开始时间对象
1735   - */
1736   - fnAdjustBcInterval2_avg: function(bIsUp, oStartTime) {
1737   - var aBc = !oStartTime ? _fnGetBcList(bIsUp) : _fnGetBcList2(bIsUp, oStartTime); // 指定方向的班次列表
1738   - aBc.sort(function(o1, o2) {
1739   - if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
1740   - return -1;
1741   - } else {
1742   - return 1;
1743   - }
1744   - });
1745   -
1746   - var j;
1747   - var iCount = aBc.length - 1;
1748   - var iC1 = Math.floor(aBc[aBc.length - 1].getFcTimeObj().diff(aBc[0].getFcTimeObj(), "m") / iCount);
1749   - var iC2 = aBc[aBc.length - 1].getFcTimeObj().diff(aBc[0].getFcTimeObj(), "m") % iCount;
1750   - var iTempTime;
1751   -
1752   - for (j = 0; j < iCount - iC2; j++) {
1753   - iTempTime = aBc[j + 1].getFcTimeObj().diff(aBc[j].getFcTimeObj(), "m");
1754   - aBc[j + 1].addMinuteToFcsj(iC1 - iTempTime);
1755   - }
1756   - for (j = 0; j < iC2; j++) {
1757   - iTempTime = aBc[iCount - iC2 + j + 1].getFcTimeObj().diff(aBc[iCount - iC2 + j].getFcTimeObj(), "m");
1758   - aBc[iCount - iC2 + j + 1].addMinuteToFcsj(iC1 + 1 - iTempTime);
1759   - }
1760   -
1761   - },
1762   -
1763   - /**
1764   - * 计算高峰平均停站时间。
1765   - */
1766   - fnCalcuAverPeakStopTime: function() {
1767   - var i;
1768   - var j;
1769   - var aBc;
1770   - var iBcCount = 0;
1771   - var iSum = 0;
1772   - for (i = 0; i < _internalLpArray.length; i++) {
1773   - aBc = _internalLpArray[i].getBcArray();
1774   -
1775   - for (j = 0; j < aBc.length; j++) {
1776   - if (!_paramObj.isTroughBc(aBc[j].getArrTimeObj())) {
1777   - iBcCount ++;
1778   - iSum += aBc[j].getStopTime();
1779   - }
1780   - }
1781   - }
1782   -
1783   - return Math.floor(iSum / iBcCount);
1784   - },
1785   -
1786   - /**
1787   - * 计算低谷平均停站时间。
1788   - */
1789   - fnCalcuAverTroughStopTime: function() {
1790   - var i;
1791   - var j;
1792   - var aBc;
1793   - var iBcCount = 0;
1794   - var iSum = 0;
1795   - for (i = 0; i < _internalLpArray.length; i++) {
1796   - aBc = _internalLpArray[i].getBcArray();
1797   - for (j = 0; j < aBc.length; j++) {
1798   - if (_paramObj.isTroughBc(aBc[j].getArrTimeObj())) {
1799   - iBcCount ++;
1800   - iSum += aBc[j].getStopTime();
1801   - }
1802   - }
1803   - }
1804   -
1805   - return Math.floor(iSum / iBcCount);
1806   - },
1807   -
1808   - //------------- 其他方法 -------------//
1809   - /**
1810   - * 内部数据转化成显示用的班次数组。
1811   - */
1812   - fnToGanttBcArray: function() {
1813   - var aAllBc = [];
1814   - var aLpBc = [];
1815   - var aEatBc = [];
1816   - var oLp;
1817   - var i;
1818   - var j;
1819   -
1820   - for (i = 0; i < _internalLpArray.length; i++) {
1821   - oLp = _internalLpArray[i];
1822   - aLpBc = [];
1823   - aLpBc = aLpBc.concat(oLp.getOtherBcArray(), oLp.getBcArray());
1824   -
1825   - aEatBc = [];
1826   - // 根据班次的吃饭时间添加吃饭班次
1827   - for (j = 0; j < aLpBc.length; j++) {
1828   - if (aLpBc[j].fnGetEatTime() > 0) {
1829   - aEatBc.push(_factory.createBcObj(
1830   - oLp,
1831   - "cf",
1832   - !aLpBc[j].isUp(), // 和上一个班次方向相反
1833   - 1,
1834   - _paramObj.addMinute(aLpBc[j].getArrTimeObj(), aLpBc[j].getStopTime()), // 使用上一个班次的到达时间作为开始时间
1835   - _paramObj
1836   - ));
1837   - }
1838   - }
1839   - aLpBc = aLpBc.concat(aEatBc);
1840   -
1841   - // 按照发车时间排序
1842   - aLpBc.sort(function(o1, o2) {
1843   - if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
1844   - return -1;
1845   - } else {
1846   - return 1;
1847   - }
1848   - });
1849   -
1850   - // 重新赋值fcno
1851   - for (j = 0; j < aLpBc.length; j++) {
1852   - aLpBc[j].fnSetFcno(j + 1);
1853   - }
1854   -
1855   - aAllBc = aAllBc.concat(aLpBc);
1856   - }
1857   -
1858   - var aGanttBc = [];
1859   - for (i = 0; i < aAllBc.length; i++) {
1860   - aGanttBc.push(aAllBc[i].toGanttBcObj());
1861   - }
1862   -
1863   - return aGanttBc;
1864   - }
1865   -
1866   - };
  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_5_2_fb_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("//---------------- 行车计划,初始化方法4 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 + // 注意:如果中标线和上标线同一个路牌,需要把中标线移到下一个路牌
  527 + if (aTtindex[0] == 0) { // 0是上标线路牌索引
  528 + aTtindex[0] = aLbIndexes[1]; // 选择下一个连班路牌索引
  529 + }
  530 +
  531 + _iZbx_lpIndex = aTtindex[0]; // 中标线放在第几个路牌
  532 + oTempLp.setLp(_lpArray[_iZbx_lpIndex]); // 设置原始路牌对象
  533 + oTempLp._$_aVerticalIntervalTime = _internalLpArray[_iZbx_lpIndex]._$_aVerticalIntervalTime; // 设置纵向最小发车间隔
  534 + oTempLp.setBxLb(_internalLpArray[_iZbx_lpIndex].isBxLb());
  535 + oTempLp.setBxFb(_internalLpArray[_iZbx_lpIndex].isBxFb());
  536 + oTempLp.setBxFb5_2(_internalLpArray[_iZbx_lpIndex].isBxFb5_2());
  537 +
  538 + // 修正除了第一个班次外,其余其他班次
  539 + var iBcindex = 0;
  540 + for (i = 1; i < _qCount; i++) {
  541 + while (iBcindex <= 1) {
  542 + if (oTempLp.getBc(i, iBcindex)) { // 替换存在的班次
  543 + oTempLp.setBc(i, iBcindex, _fnGenerateBc(_iZbx_lpIndex, i, iBcindex));
  544 + }
  545 + iBcindex ++;
  546 + }
  547 + iBcindex = 0;
  548 + }
  549 +
  550 + _internalLpArray[_iZbx_lpIndex] = oTempLp;
  551 +
  552 + console.log("中标线对应第" + (_iZbx_lpIndex + 1) + "个路牌");
  553 +
  554 + console.log("//---------------- 行车计划,初始化方法4 end ----------------//");
  555 + };
  556 +
  557 + //-------------------- 重要的内部方法 -----------------------//
  558 + /**
  559 + * 核心方法,利用路牌间隔纵向生成班次。
  560 + * @param iLpindex 路牌索引
  561 + * @param iQindex 圈索引
  562 + * @param iBcindex 班次索引
  563 + * @returns object InternalBcObj,失败 false
  564 + */
  565 + var _fnGenerateBc = function(iLpindex, iQindex, iBcindex) {
  566 + // 以上标线为起始点,使用路牌在不同圈,班次索引的发车间隔,计算班次
  567 + // 注意,发车间隔是指下一个班次应该距离当前班次间隔,是从下往上的
  568 +
  569 + // 1、参数验证
  570 + if (iLpindex == 0) { // 上标线的班次不需要生成
  571 + return false;
  572 + }
  573 +
  574 + // 2、计算间隔
  575 + var i;
  576 + var oLp;
  577 + var iTime = 0;
  578 + for (i = 0; i < iLpindex; i++) {
  579 + oLp = _internalLpArray[i];
  580 + iTime += oLp.fnGetVerticalIntervalTime(iQindex, iBcindex);
  581 + }
  582 +
  583 + // 3、生成班次
  584 + var _oKsbc = _internalLpArray[0].getBc(iQindex, iBcindex);
  585 + if (!_oKsbc) {
  586 + return false;
  587 + }
  588 + var _oKssj = _paramObj.addMinute(_oKsbc.getFcTimeObj(), iTime);
  589 + var _oBc = _factory.createBcObj(
  590 + _internalLpArray[iLpindex],
  591 + "normal", _oKsbc.isUp(),
  592 + 1, _oKssj, _paramObj);
  593 +
  594 + return _oBc;
  595 +
  596 + };
  597 +
  598 + /**
  599 + * 核心方法,在指定位置生成班次并添加到路牌指定位置中。
  600 + * @param lpIndex 第几个路牌
  601 + * @param qIndex 第几圈
  602 + * @param bcIndex 第几个班次
  603 + */
  604 + var _fnGenerateBcAndSetBc = function(lpIndex, qIndex, bcIndex) {
  605 + var _bcObj = _fnGenerateBc(lpIndex, qIndex, bcIndex);
  606 + if (_bcObj) {
  607 + _internalLpArray[lpIndex].setBc(qIndex, bcIndex, _bcObj);
  608 + }
  609 + };
  610 +
  611 + /**
  612 + * 获取班次列表。
  613 + * @param oIsUp 是否上行
  614 + * @param oStartTime 开始时间对象
  615 + * @returns [(InternalBcObj)]
  616 + */
  617 + var _fnGetBcList2 = function(oIsUp, oStartTime) {
  618 + var i;
  619 + var j;
  620 + var oLp;
  621 + var oBc;
  622 + var aBc = [];
  623 +
  624 + for (j = 0; j < _qCount; j++) {
  625 + for (i = 0; i < _internalLpArray.length; i++) {
  626 + oLp = _internalLpArray[i];
  627 + oBc = oLp.getBc(
  628 + j,
  629 + _qIsUp == oIsUp ? 0 : 1
  630 + );
  631 + if (oBc && oBc.getFcTimeObj().isAfter(oStartTime)) {
  632 + aBc.push(oBc);
  633 + }
  634 + }
  635 + }
  636 +
  637 + var aBcFcTime = [];
  638 + for (i = 0; i < aBc.length; i++) {
  639 + oBc = aBc[i];
  640 + aBcFcTime.push(oBc.getFcTimeObj().format("HH:mm"));
  641 + }
  642 + console.log((oIsUp ? "上行班次列表:" : "下行班次列表:") + aBcFcTime.join(","));
  643 +
  644 + return aBc;
  645 + };
  646 +
  647 + /**
  648 + * 获取班次列表。
  649 + * @param isUp boolean 是否上行
  650 + * @returns [(InternalBcObj)]
  651 + */
  652 + var _fnGetBcList = function(isUp) {
  653 + var i;
  654 + var j;
  655 + var oLp;
  656 + var oBc;
  657 + var aBc = [];
  658 +
  659 + for (j = 0; j < _qCount; j++) {
  660 + for (i = 0; i < _internalLpArray.length; i++) {
  661 + oLp = _internalLpArray[i];
  662 + oBc = oLp.getBc(
  663 + j,
  664 + _qIsUp == isUp ? 0 : 1
  665 + );
  666 + if (oBc) {
  667 + aBc.push(oBc);
  668 + }
  669 + }
  670 + }
  671 +
  672 + var aBcFcTime = [];
  673 + for (i = 0; i < aBc.length; i++) {
  674 + oBc = aBc[i];
  675 + aBcFcTime.push(oBc.getFcTimeObj().format("HH:mm"));
  676 + }
  677 + console.log((isUp ? "上行班次列表:" : "下行班次列表:") + aBcFcTime.join(","));
  678 +
  679 + return aBc;
  680 + };
  681 +
  682 + /**
  683 + * 查找离指定时间最近的前面的班次索引信息
  684 + * @param timeObj 查找时间
  685 + * @param isUp 是否上行
  686 + * @returns [{路牌index},{圈index},{班次index}]
  687 + */
  688 + var _fnFindUpClosedBcIndexWithTime = function(timeObj, isUp) {
  689 +
  690 + var _lpObj;
  691 + var _groupObj;
  692 + var _bcObj;
  693 + var _i;
  694 + var _j;
  695 + var timediff; // 时间差取绝对值
  696 +
  697 + var _lpIndex;
  698 + var _up_qIndex;
  699 + var _up_bIndex;
  700 +
  701 + for (_i = 0; _i < _qCount; _i++) {
  702 + for (_j = 0; _j < _internalLpArray.length; _j++) {
  703 + _lpObj = _internalLpArray[_j];
  704 + _groupObj = _lpObj.getGroup(_i);
  705 + _bcObj = isUp == _qIsUp ? _groupObj.getBc1() : _groupObj.getBc2();
  706 + if (!_bcObj) { // 没有班次动态生成一个,可能生成不出的
  707 + _bcObj = _fnGenerateBc(_j, _i, isUp == _qIsUp ? 0 : 1);
  708 + }
  709 + if (_bcObj) {
  710 + if (timeObj.diff(_bcObj.getFcTimeObj()) >= 0) {
  711 + if (!timediff) {
  712 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  713 + _lpIndex = _j;
  714 + _up_qIndex = _i;
  715 + _up_bIndex = isUp == _qIsUp ? 0 : 1;
  716 + } else {
  717 + if (timeObj.diff(_bcObj.getFcTimeObj()) < timediff) {
  718 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  719 + _lpIndex = _j;
  720 + _up_qIndex = _i;
  721 + _up_bIndex = isUp == _qIsUp ? 0 : 1;
  722 + }
  723 + }
  724 + }
  725 + }
  726 + }
  727 + }
  728 +
  729 + if (_lpIndex == undefined) {
  730 + return false;
  731 + }
  732 +
  733 + var bcindex = [];
  734 + bcindex.push(_lpIndex);
  735 + bcindex.push(_up_qIndex);
  736 + bcindex.push(_up_bIndex);
  737 +
  738 + return bcindex;
  739 + };
  740 +
  741 + /**
  742 + * 查找离指定时间最近的后面的班次索引信息
  743 + * @param timeObj 查找时间
  744 + * @param isUp 是否上行
  745 + * @returns [{路牌index},{圈index},{班次index}]
  746 + */
  747 + var _fnFindDownClosedBcIndexWithTime = function(timeObj, isUp) {
  748 + var _lpObj;
  749 + var _groupObj;
  750 + var _bcObj;
  751 + var _i;
  752 + var _j;
  753 + var timediff; // 时间差取绝对值
  754 +
  755 + var _lpIndex;
  756 + var _down_qIndex;
  757 + var _down_bIndex;
  758 +
  759 + var flag;
  760 +
  761 + for (_i = 0; _i < _qCount; _i++) {
  762 + for (_j = 0; _j < _internalLpArray.length; _j++) {
  763 + _lpObj = _internalLpArray[_j];
  764 + _groupObj = _lpObj.getGroup(_i);
  765 + // TODO:bug
  766 + _bcObj = isUp == _qIsUp ? _groupObj.getBc1() : _groupObj.getBc2();
  767 + if (!_bcObj) { // 没有班次动态生成一个,可能生成不出的
  768 + _bcObj = _fnGenerateBc(_j, _i, isUp == _qIsUp ? 0 : 1);
  769 + }
  770 + if (_bcObj) {
  771 + //console.log("timeobj -> bcobj diff flag " +
  772 + // timeObj.format("HH:mm") + "->" +
  773 + // _bcObj.getFcTimeObj().format("HH:mm") +
  774 + // timeObj.diff(_bcObj.getFcTimeObj()) +
  775 + // (timeObj.diff(_bcObj.getFcTimeObj()) <= 0)
  776 + //);
  777 +
  778 + flag = (timeObj.diff(_bcObj.getFcTimeObj())) <= 0;
  779 +
  780 + if (flag) {
  781 + if (!timediff) {
  782 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  783 + _lpIndex = _j;
  784 + _down_qIndex = _i;
  785 + _down_bIndex = isUp == _qIsUp ? 0 : 1;
  786 + } else {
  787 + if ((timeObj.diff(_bcObj.getFcTimeObj())) > timediff) {
  788 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  789 + _lpIndex = _j;
  790 + _down_qIndex = _i;
  791 + _down_bIndex = isUp == _qIsUp ? 0 : 1;
  792 + }
  793 + }
  794 + }
  795 + }
  796 + }
  797 + }
  798 +
  799 + if (_lpIndex == undefined) {
  800 + return false;
  801 + }
  802 +
  803 + var bcindex = [];
  804 + bcindex.push(_lpIndex);
  805 + bcindex.push(_down_qIndex);
  806 + bcindex.push(_down_bIndex);
  807 +
  808 + return bcindex;
  809 + };
  810 +
  811 + /**
  812 + * 获取班次索引。
  813 + * @param oBc 班次对象
  814 + * @returns [{路牌索引},{圈索引},{班次索引}]
  815 + */
  816 + var _fnGetBcIndex = function(oBc) {
  817 + // 路牌索引
  818 + var i;
  819 + var iLpIndex;
  820 + for (i = 0; i < _internalLpArray.length; i++) {
  821 + if (_internalLpArray[i]._$$_orign_lp_obj == oBc._$$_internal_lp_obj._$$_orign_lp_obj) {
  822 + iLpIndex = i;
  823 + break;
  824 + }
  825 + }
  826 + // 圈索引
  827 + var j;
  828 + var iGroupIndex;
  829 + var bFlag = false;
  830 + for (i = 0; i < _internalLpArray.length; i++) {
  831 + if (bFlag) {
  832 + break;
  833 + }
  834 + for (j = 0; j < _qCount; j++) {
  835 + if (_internalLpArray[i]._$_groupBcArray[j] == oBc._$$_internal_group_obj) {
  836 + iGroupIndex = j;
  837 + bFlag = true;
  838 + break;
  839 + }
  840 + }
  841 + }
  842 + // 班次索引
  843 + var iBcIndex = _qIsUp == oBc.isUp() ? 0 : 1;
  844 +
  845 + if (iLpIndex == undefined) {
  846 + return null;
  847 + } else {
  848 + return [].concat(iLpIndex, iGroupIndex, iBcIndex);
  849 + }
  850 +
  851 + };
  852 +
  853 + return {
  854 + //------------- 布局初始化方法 ------------//
  855 + /**
  856 + * 初始化数据,使用标线初始化
  857 + */
  858 + fnInitDataWithBxLayout: function() {
  859 + // 初始化布局1,构造上标线,计算圈数,把上标线数据放入第一个路牌中
  860 + _fnInitFun1();
  861 + // 初始化布局2,从上标线的某个班次开始,构造所有路牌的早高峰班次,晚高峰班次,计算路牌在各个圈中的间隔
  862 + _fnInitFun2();
  863 + // 初始化布局3,计算连班分班路牌分布
  864 + _fnInitFun3();
  865 + // 初始化布局4,计算中标线位置
  866 + //_fnInitFun4();
  867 +
  868 + },
  869 +
  870 + /**
  871 + * 调整高峰班次,
  872 + * 初始化生成早高峰,晚高峰班次并不准确,因为根据高峰时间段,并不在一个完整圈内,应该是在两个或多个圈之间
  873 + * 当初始化定好布局后(上标线,中标线),然后确定每个路牌的班型(连班,分班,5休2分班)后
  874 + * 然后重新计算框在高峰时间段内的班次索引,不足的添加,之前多加的删除(只删除分班路牌上的)
  875 + * @param isZgf 是否早高峰
  876 + * @param isUp 是否上行
  877 + */
  878 + fnAdjustGfbc : function(isZgf, isUp) {
  879 + var oStartTime; // 开始时间
  880 + var oEndTime; // 结束时间
  881 + var aStartBcIndex; // 开始班次索引
  882 + var aEndBcIndex; // 结束班次索引
  883 +
  884 + oStartTime = isZgf ? _paramObj.getMPeakStartTimeObj() : _paramObj.getEPeakStartTimeObj();
  885 + oEndTime = isZgf ? _paramObj.getMPeakEndTimeObj() : _paramObj.getEPeakEndTimeObj();
  886 +
  887 + aStartBcIndex = _fnFindUpClosedBcIndexWithTime(oStartTime, isUp);
  888 + aEndBcIndex = _fnFindDownClosedBcIndexWithTime(oEndTime, isUp);
  889 +
  890 + var iLpIndex;
  891 + var iQIndex;
  892 + var iBcIndex;
  893 + var iQInternelCount; // 高峰时间段中间包含的圈数
  894 + var i;
  895 + var j;
  896 +
  897 + var oLp;
  898 +
  899 + if (aStartBcIndex && aEndBcIndex) {
  900 + iLpIndex = aStartBcIndex[0];
  901 + iQIndex = aStartBcIndex[1];
  902 + iBcIndex = aStartBcIndex[2];
  903 +
  904 + // 处理头
  905 + // 删除头部多余班次
  906 + for (j = 0; j < iLpIndex; j++) {
  907 + oLp = _internalLpArray[j];
  908 + if (oLp.isBxFb() && oLp.getBc(iQIndex, iBcIndex)) {
  909 + oLp.removeBc(iQIndex, iBcIndex);
  910 + }
  911 + }
  912 +
  913 + for (j = iLpIndex; j < _internalLpArray.length; j++) {
  914 + oLp = _internalLpArray[j];
  915 + if (!oLp.getBc(iQIndex, iBcIndex)) {
  916 + _fnGenerateBcAndSetBc(j, iQIndex, iBcIndex);
  917 + }
  918 + }
  919 +
  920 + // 处理中间
  921 + iQInternelCount = aEndBcIndex[1] - aStartBcIndex[1] - 1;
  922 + for (i = 1; i <= iQInternelCount; i++) {
  923 + oLp = _internalLpArray[iQIndex + i];
  924 +
  925 + if (!oLp.getBc(iQIndex + i, iBcIndex)) {
  926 + _fnGenerateBcAndSetBc(i, iQIndex + i, iBcIndex);
  927 + }
  928 + }
  929 +
  930 + // 处理尾部
  931 + iLpIndex = aEndBcIndex[0];
  932 + iQIndex = aEndBcIndex[1];
  933 + iBcIndex = aEndBcIndex[2];
  934 +
  935 + // 删除尾部多余的班次
  936 + for (j = iLpIndex; j < _internalLpArray.length; j++) {
  937 + oLp = _internalLpArray[j];
  938 + if (oLp.isBxFb() && oLp.getBc(iQIndex, iBcIndex)) {
  939 + oLp.removeBc(iQIndex, iBcIndex);
  940 + }
  941 + }
  942 +
  943 + if (aStartBcIndex[1] != aEndBcIndex[1]) { // 指定时间范围跨圈
  944 + for (j = 0; j < iLpIndex; j++) {
  945 + oLp = _internalLpArray[j];
  946 + if (!oLp.getBc(iQIndex, iBcIndex)) {
  947 + _fnGenerateBcAndSetBc(j, iQIndex, iBcIndex);
  948 + }
  949 + }
  950 + } else {
  951 + // 不跨圈,不用处理,处理头的时候已经加了
  952 + }
  953 +
  954 + }
  955 +
  956 + },
  957 +
  958 + /**
  959 + * 按照营运时间要求补充班次,
  960 + * 早高峰7:45分以前出场运营,
  961 + * 晚高峰16:10分以前出场运营
  962 + */
  963 + fnCalcuLpBc_yy: function() {
  964 + // 补班次的时候,针对的是分班班型
  965 + var i;
  966 + var _oLp;
  967 + var _oBc;
  968 + var _aMinBcIndex;
  969 + var _aMaxBcIndex;
  970 +
  971 + var _qIndex;
  972 + var _bIndex;
  973 +
  974 + var _zgfCDate = _paramObj.toTimeObj("7:45");
  975 + var _wgfCDate = _paramObj.toTimeObj("16:10");
  976 + var _ccsj;
  977 +
  978 + for (i = 0; i < _internalLpArray.length; i++) {
  979 + _oLp = _internalLpArray[i];
  980 + if (_oLp.isBxFb()) { // 分班路牌
  981 + // 早高峰部分
  982 + _aMinBcIndex = _oLp.getMinBcObjPosition();
  983 + _qIndex = _aMinBcIndex[0];
  984 + _bIndex = _aMinBcIndex[1];
  985 + _oBc = _oLp.getBc(_qIndex, _bIndex);
  986 + if (_qIsUp) {
  987 + _ccsj = _bIndex == 0 ?
  988 + _paramObj.getUpOutTime() :
  989 + _paramObj.getDownOutTime();
  990 + } else {
  991 + _ccsj = _bIndex == 0 ?
  992 + _paramObj.getDownOutTime() :
  993 + _paramObj.getUpOutTime();
  994 + }
  995 + if (_zgfCDate.isBefore(_paramObj.addMinute(_oBc.getFcTimeObj(), -_ccsj))) {
  996 + _fnGenerateBcAndSetBc(
  997 + i,
  998 + _bIndex == 0 ? _qIndex - 1 : _qIndex,
  999 + _bIndex == 0 ? 1 : 0
  1000 + )
  1001 + }
  1002 +
  1003 + // 晚高峰部分
  1004 + _aMaxBcIndex = _oLp.getMaxBcObjPosition();
  1005 + _qIndex = _aMaxBcIndex[0];
  1006 + _bIndex = _aMaxBcIndex[1];
  1007 + _oBc = _oLp.getBc(
  1008 + _bIndex == 0 ? _qIndex - 1 : _qIndex,
  1009 + _bIndex == 0 ? 1 : 0
  1010 + );
  1011 + if (!_oBc) { // 前一个班次不存在,再判定加不加
  1012 + _oBc = _oLp.getBc(_qIndex, _bIndex);
  1013 + if (_qIsUp) {
  1014 + _ccsj = _bIndex == 0 ?
  1015 + _paramObj.getUpOutTime() :
  1016 + _paramObj.getDownOutTime();
  1017 + } else {
  1018 + _ccsj = _bIndex == 0 ?
  1019 + _paramObj.getDownOutTime() :
  1020 + _paramObj.getUpOutTime();
  1021 + }
  1022 + if (_wgfCDate.isBefore(_paramObj.addMinute(_oBc.getFcTimeObj(), -_ccsj))) {
  1023 + _fnGenerateBcAndSetBc(
  1024 + i,
  1025 + _bIndex == 0 ? _qIndex - 1 : _qIndex,
  1026 + _bIndex == 0 ? 1 : 0
  1027 + )
  1028 + }
  1029 + }
  1030 + }
  1031 + }
  1032 + },
  1033 +
  1034 + /**
  1035 + * 补充做5休2的班型班次。
  1036 + * 1、确认5_2班型大致多少圈(小数点过.7进位)
  1037 + * 2、获取当前5_2两端车次链的信息,每段的班次数目,还差几个班次没加
  1038 + * 3、如果前面的车次链班次少,则从前面的车次链开始加
  1039 + * 4、如果车次链班次数一样,从从后面的车次链开始加
  1040 + * 5、加班次时都是往车次链前方加
  1041 + * 6、如果前面车次链不能再加班次了,从后面车次链加
  1042 + */
  1043 + fnCalcuLpBx_5_2: function() {
  1044 + // 计算做5休2班型所需的班次数
  1045 + var iBxBcount = _aBxDesc[6].fBcCount;
  1046 + if (iBxBcount - Math.floor(iBxBcount) > 0.7) {
  1047 + iBxBcount = Math.floor(iBxBcount) + 1;
  1048 + } else {
  1049 + iBxBcount = Math.floor(iBxBcount);
  1050 + }
  1051 +
  1052 + var i;
  1053 + var j;
  1054 + var oLp;
  1055 + var iAddBcCount;
  1056 + var oBcChain1;
  1057 + var oBcChain2;
  1058 + var iQindex;
  1059 + var iBindex;
  1060 +
  1061 + for (i = 0; i < _internalLpArray.length; i++) {
  1062 + oLp = _internalLpArray[i];
  1063 + if (oLp.isBxFb5_2()) {
  1064 + iAddBcCount = iBxBcount - oLp.getBcArray().length; // 需要添加的班次数
  1065 + for (j = 1; j <= iAddBcCount; j++) {
  1066 + oBcChain1 = oLp.fnGetBcChainInfo(0);
  1067 + oBcChain2 = oLp.fnGetBcChainInfo(1);
  1068 +
  1069 + if (oBcChain1.bcount < oBcChain2.bcount) {
  1070 + iQindex = oBcChain1.s_b == 0 ? oBcChain1.s_q - 1 : oBcChain1.s_q;
  1071 + iBindex = oBcChain1.s_b == 0 ? 1 : 0;
  1072 + // 往车次链往前不能加,就往后加
  1073 + if (_fnGenerateBc(i, iQindex, iBindex)) {
  1074 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1075 + } else {
  1076 + iQindex = oBcChain1.e_b == 0 ? oBcChain1.e_q : oBcChain1.e_q + 1;
  1077 + iBindex = oBcChain1.e_b == 0 ? 1 : 0;
  1078 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1079 + }
  1080 +
  1081 + } else if (oBcChain1.bcount > oBcChain2.bcount) {
  1082 + iQindex = oBcChain2.s_b == 0 ? oBcChain2.s_q - 1 : oBcChain2.s_q;
  1083 + iBindex = oBcChain2.s_b == 0 ? 1 : 0;
  1084 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1085 + } else {
  1086 + iQindex = oBcChain2.s_b == 0 ? oBcChain2.s_q - 1 : oBcChain2.s_q;
  1087 + iBindex = oBcChain2.s_b == 0 ? 1 : 0;
  1088 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1089 + }
  1090 + }
  1091 + }
  1092 + }
  1093 +
  1094 + },
  1095 +
  1096 + /**
  1097 + * 补其他分班班型班次。
  1098 + * 从车次链的后面开始加
  1099 + */
  1100 + fnCalcuLpBx_other: function() {
  1101 + // TODO:根据上标线的首班时间确定班型,小于05:59的做一休一,否则做二休一
  1102 + var oSt = _qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();
  1103 + var iBxIndex = 4;
  1104 + if (oSt.isBefore(_paramObj.toTimeObj("05:59"))) {
  1105 + iBxIndex = 5;
  1106 + }
  1107 + // 计算做5休2班型所需的班次数
  1108 + var iQBcount = _aBxDesc[iBxIndex].fQCount;
  1109 + var iBxBcount = Math.round(iQBcount) * 2;
  1110 +
  1111 + var i;
  1112 + var j;
  1113 + var oLp;
  1114 + var iAddBcCount;
  1115 + var oBcChain1;
  1116 + var oBcChain2;
  1117 + var iQindex;
  1118 + var iBindex;
  1119 +
  1120 + for (i = 0; i < _internalLpArray.length; i++) {
  1121 + oLp = _internalLpArray[i];
  1122 + if (oLp.isBxFb() && !oLp.isBxFb5_2()) {
  1123 + iAddBcCount = iBxBcount - oLp.getBcArray().length; // 需要添加的班次数
  1124 + for (j = 1; j <= iAddBcCount; j++) {
  1125 + oBcChain1 = oLp.fnGetBcChainInfo(0);
  1126 + oBcChain2 = oLp.fnGetBcChainInfo(1);
  1127 +
  1128 + if (oBcChain1.bcount < oBcChain2.bcount) {
  1129 + iQindex = oBcChain1.e_b == 0 ? oBcChain1.e_q : oBcChain1.e_q + 1;
  1130 + iBindex = oBcChain1.e_b == 0 ? 1 : 0;
  1131 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1132 + } else if (oBcChain1.bcount > oBcChain2.bcount) {
  1133 + iQindex = oBcChain2.e_b == 0 ? oBcChain2.e_q : oBcChain2.e_q + 1;
  1134 + iBindex = oBcChain2.e_b == 0 ? 1 : 0;
  1135 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1136 + } else {
  1137 + iQindex = oBcChain2.e_b == 0 ? oBcChain2.e_q : oBcChain2.e_q + 1;
  1138 + iBindex = oBcChain2.e_b == 0 ? 1 : 0;
  1139 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1140 + }
  1141 + }
  1142 + }
  1143 + }
  1144 +
  1145 + },
  1146 +
  1147 + /**
  1148 + * 补充连班路牌班次。
  1149 + * 1、上标线,中标线中间的连班路牌班次从早高峰班次一直拉到底,从早高峰班次向上标线起始班次靠拢
  1150 + * 2、中标线以下的连班路牌班次从早高峰班次一直拉到底,从早高峰班次向中标线起始班次靠拢
  1151 + */
  1152 + fnCalcuLpBx_lb: function() {
  1153 + // 补充连班的班次,参照上标线,中标线补充不足的班次
  1154 +
  1155 + var aLbLpindexes = []; // 除上标线,中标线的连班路牌索引
  1156 + var i;
  1157 + for (i = 0; i < _internalLpArray.length; i++) {
  1158 + if (_internalLpArray[i].isBxLb() && i != 0 && i != _iZbx_lpIndex) {
  1159 + aLbLpindexes.push(i);
  1160 + }
  1161 + }
  1162 +
  1163 + var oEndsj = // 结束时间
  1164 + _paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj()) ?
  1165 + _paramObj.getDownLastDTimeObj() :
  1166 + _paramObj.getUpLastDtimeObj();
  1167 +
  1168 + var oLp;
  1169 + var aMinbcPos;
  1170 + var oBc;
  1171 + var j;
  1172 + var iTempBcIndex;
  1173 +
  1174 + // 1、从最小班次开始,往后补充班次
  1175 + for (i = 0; i < aLbLpindexes.length; i++) {
  1176 + oLp = _internalLpArray[aLbLpindexes[i]];
  1177 +
  1178 + // 最小班次索引
  1179 + aMinbcPos = oLp.getMinBcObjPosition();
  1180 + // 使用纵向分隔补充班次,从最小班次向后补
  1181 + iTempBcIndex = aMinbcPos[1] == 0 ? 1 : 0;
  1182 + j = iTempBcIndex == 0 ? aMinbcPos[0] + 1 : aMinbcPos[0];
  1183 +
  1184 + while (j < _qCount) {
  1185 + while (iTempBcIndex <= 1) {
  1186 + oBc = _fnGenerateBc(aLbLpindexes[i], j, iTempBcIndex);
  1187 + if (oBc &&
  1188 + oBc.getFcTimeObj().isBefore(oEndsj) ) {
  1189 + oLp.setBc(j, iTempBcIndex, oBc);
  1190 + }
  1191 + iTempBcIndex++;
  1192 + }
  1193 + iTempBcIndex = 0;
  1194 + j++;
  1195 + }
  1196 +
  1197 + }
  1198 +
  1199 + // 2、上标线中标线之间的路牌,从最小的班次往前补充班次
  1200 +
  1201 + // 还要补充缺失的班次,差上标线几个班次要往前补上
  1202 + var iBccount;
  1203 + var iQindex;
  1204 + var iBindex;
  1205 + // 补上标线到中标线之间的连班路牌的班次
  1206 + for (i = 0; i < aLbLpindexes.length; i++) {
  1207 + if (aLbLpindexes[i] > 0 && aLbLpindexes[i] < _iZbx_lpIndex) {
  1208 + oLp = _internalLpArray[aLbLpindexes[i]];
  1209 + aMinbcPos = oLp.getMinBcObjPosition();
  1210 + iQindex = aMinbcPos[0];
  1211 + iBindex = aMinbcPos[1];
  1212 + iBccount = (iQindex - 1) * 2 + iBindex; // 距离上标线起始站点差几个班次
  1213 + for (j = 0; j < iBccount; j++) {
  1214 + if (iBindex == 0) {
  1215 + iQindex --;
  1216 + iBindex = 1;
  1217 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1218 + } else if (iBindex == 1) {
  1219 + iBindex --;
  1220 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1221 + }
  1222 + }
  1223 +
  1224 + }
  1225 +
  1226 + }
  1227 +
  1228 + // 3、中标线之后的路牌,从最小的班次往前补充班次
  1229 +
  1230 + // 补中标线以下的连班路牌的班次
  1231 + for (i = 0; i < aLbLpindexes.length; i++) {
  1232 + if (aLbLpindexes[i] > _iZbx_lpIndex) {
  1233 + oLp = _internalLpArray[aLbLpindexes[i]];
  1234 + aMinbcPos = oLp.getMinBcObjPosition();
  1235 + iQindex = aMinbcPos[0];
  1236 + iBindex = aMinbcPos[1];
  1237 + iBccount = (iQindex - 0) * 2 + iBindex - 1; // 距离上标线起始站点差几个班次
  1238 + for (j = 0; j < iBccount; j++) {
  1239 + if (iBindex == 0) {
  1240 + iQindex --;
  1241 + iBindex = 1;
  1242 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1243 + } else if (iBindex == 1) {
  1244 + iBindex --;
  1245 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1246 + }
  1247 + }
  1248 + }
  1249 + }
  1250 +
  1251 + },
  1252 +
  1253 + /**
  1254 + * 计算末班车。
  1255 + * 1、将上下行拉成上下行两个班次列表(包括标记班次)
  1256 + * 2、分别找出离末班车发车时间最近的班次,并替换时间
  1257 + * 3、删除之后的班次
  1258 + */
  1259 + fnCalcuLastBc: function() {
  1260 + var i;
  1261 + var iTimeDiff;
  1262 + var iTempTime;
  1263 + var aBc;
  1264 + var oLastBcTime;
  1265 + var oLastBcIsUp;
  1266 + var iModifyIndex;
  1267 +
  1268 + // 查找末班车早的末班车时间和方向
  1269 + if (_paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj())) {
  1270 + oLastBcTime = _paramObj.getUpLastDtimeObj();
  1271 + oLastBcIsUp = true;
  1272 + } else {
  1273 + oLastBcTime = _paramObj.getDownLastDTimeObj();
  1274 + oLastBcIsUp = false;
  1275 + }
  1276 +
  1277 + // 确定早的末班车时间
  1278 + aBc = _fnGetBcList(oLastBcIsUp);
  1279 + for (i = 0; i < aBc.length; i++) {
  1280 + iTempTime = oLastBcTime.diff(aBc[i].getFcTimeObj(), "m");
  1281 + if (iTimeDiff == undefined) {
  1282 + iTimeDiff = iTempTime;
  1283 + iModifyIndex = i;
  1284 + } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff)) {
  1285 + iTimeDiff = iTempTime;
  1286 + iModifyIndex = i;
  1287 + }
  1288 + }
  1289 + aBc[iModifyIndex].addMinuteToFcsj(iTimeDiff); // 替换成末班车时间
  1290 + aBc[iModifyIndex].fnSetDelFlag(false);
  1291 + for (i = iModifyIndex + 1; i < aBc.length; i++) { // 删除多余班次
  1292 + _qIsUp == oLastBcIsUp ?
  1293 + aBc[i]._$$_internal_group_obj.setBc1(undefined) :
  1294 + aBc[i]._$$_internal_group_obj.setBc2(undefined);
  1295 + }
  1296 +
  1297 + // 查找末班车晚的末班车时间和方向
  1298 + if (_paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj())) {
  1299 + oLastBcTime = _paramObj.getDownLastDTimeObj();
  1300 + oLastBcIsUp = false;
  1301 + } else {
  1302 + oLastBcTime = _paramObj.getUpLastDtimeObj();
  1303 + oLastBcIsUp = true;
  1304 + }
  1305 + // 确定晚的末班车时间
  1306 + aBc = _fnGetBcList(oLastBcIsUp);
  1307 + var oBc;
  1308 + var aBcIndex;
  1309 + var iLpIndex;
  1310 + var iQIndex;
  1311 + var iBcIndex;
  1312 +
  1313 + iTimeDiff = undefined;
  1314 + for (i = 0; i < aBc.length; i++) {
  1315 + oBc = aBc[i];
  1316 + aBcIndex = _fnGetBcIndex(oBc);
  1317 +
  1318 + iLpIndex = aBcIndex[0];
  1319 + iQIndex = aBcIndex[2] == 0 ? aBcIndex[1] -1 : aBcIndex[1];
  1320 + iBcIndex = aBcIndex[2] == 0 ? 1 : 0;
  1321 +
  1322 + if (!_internalLpArray[iLpIndex].getBc(iQIndex, iBcIndex)) {
  1323 + continue;
  1324 + }
  1325 +
  1326 + iTempTime = oLastBcTime.diff(aBc[i].getFcTimeObj(), "m");
  1327 + if (iTimeDiff == undefined) {
  1328 + iTimeDiff = iTempTime;
  1329 + iModifyIndex = i;
  1330 + } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff)) {
  1331 + iTimeDiff = iTempTime;
  1332 + iModifyIndex = i;
  1333 + }
  1334 + }
  1335 + aBc[iModifyIndex].addMinuteToFcsj(iTimeDiff); // 替换成末班车时间
  1336 + aBc[iModifyIndex].fnSetDelFlag(false);
  1337 + for (i = iModifyIndex + 1; i < aBc.length; i++) { // 删除多余班次
  1338 + _qIsUp == oLastBcIsUp ?
  1339 + aBc[i]._$$_internal_group_obj.setBc1(undefined) :
  1340 + aBc[i]._$$_internal_group_obj.setBc2(undefined);
  1341 + }
  1342 +
  1343 + },
  1344 +
  1345 + /**
  1346 + * 添加吃饭班次。
  1347 + */
  1348 + fnCalcuEatBc: function() {
  1349 + // 吃午饭时间范围,10:15 到 12:15
  1350 + // 吃晚饭时间范围,18:00 到 19:00
  1351 +
  1352 + if (!_paramObj.fnIsEat()) {
  1353 + return;
  1354 + }
  1355 +
  1356 + // 午饭index
  1357 + var aLEIndex;
  1358 + // 晚饭index
  1359 + var aDEIndex;
  1360 +
  1361 + // 所有吃饭都默认在一个方向,两个方向暂时不考虑
  1362 + if (_paramObj.fnIsUpEat()) {
  1363 + aLEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("10:15"), true, false);
  1364 + aDEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("18:00"), true, false);
  1365 + } else {
  1366 + aLEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("10:15"), false, true);
  1367 + aDEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("18:00"), false, true);
  1368 + }
  1369 +
  1370 + // 午饭第几圈,第几个班次
  1371 + var iLEQIndex = aLEIndex[0];
  1372 + var iLEBIndex = aLEIndex[1];
  1373 + // 晚饭第几圈,第几个班次
  1374 + var iDEQIndex = aDEIndex[0];
  1375 + var iDEBIndex = aDEIndex[1];
  1376 +
  1377 + // 注意,本模型只有连班才有吃饭
  1378 +
  1379 + var i;
  1380 + var oLp;
  1381 + var aLbIndex = []; // 连班班型的路牌索引
  1382 + for (i = 0; i < _internalLpArray.length; i++) {
  1383 + oLp = _internalLpArray[i];
  1384 + if (oLp.isBxLb()) {
  1385 + aLbIndex.push(i);
  1386 + }
  1387 + }
  1388 +
  1389 + var iLTime;
  1390 + var iDtime;
  1391 + var j;
  1392 + for (i = 0; i < aLbIndex.length; i++) {
  1393 + oLp = _internalLpArray[aLbIndex[i]];
  1394 +
  1395 + // 午饭
  1396 + iLTime = oLp.fnAddEatBc(iLEQIndex, iLEBIndex, _factory, _paramObj);
  1397 + // 晚饭
  1398 + iDtime = oLp.fnAddEatBc(iDEQIndex, iDEBIndex, _factory, _paramObj);
  1399 +
  1400 + if (i == aLbIndex.length - 1) {
  1401 + for (j = aLbIndex[i]; j < _internalLpArray.length; j++) {
  1402 + oLp = _internalLpArray[j];
  1403 + if (oLp.isBxFb()) { // 5休2班型不调整
  1404 + // 修正午饭之后路牌班次的发车时间
  1405 + oLp.fnAddMinuteToBcFcsj(iLEQIndex, iLEBIndex, iLTime);
  1406 + oLp.fnAddMinuteToBcFcsj(iDEQIndex, iDEBIndex, iDtime);
  1407 + }
  1408 + }
  1409 + } else {
  1410 + for (j = aLbIndex[i]; j < aLbIndex[i + 1]; j++) {
  1411 + oLp = _internalLpArray[j];
  1412 + if (oLp.isBxFb()) {
  1413 + // 修正午饭之后路牌班次的发车时间
  1414 + oLp.fnAddMinuteToBcFcsj(iLEQIndex, iLEBIndex, iLTime);
  1415 + oLp.fnAddMinuteToBcFcsj(iDEQIndex, iDEBIndex, iDtime);
  1416 + }
  1417 + }
  1418 + }
  1419 + }
  1420 +
  1421 + },
  1422 +
  1423 + /**
  1424 + * 补每个路牌的其他班次(进出场,例保班次)。
  1425 + */
  1426 + fnCalcuOtherBc_: function() {
  1427 + var i;
  1428 + var _lpObj;
  1429 + var _minBcIndex;
  1430 + var _maxBcIndex;
  1431 + var _minBc;
  1432 + var _maxBc;
  1433 + var _otherbc = [];
  1434 + var _oFbbc;
  1435 +
  1436 + for (i = 0; i < _internalLpArray.length; i++) {
  1437 + _lpObj = _internalLpArray[i];
  1438 + _minBcIndex = _lpObj.getMinBcObjPosition();
  1439 + _maxBcIndex = _lpObj.getMaxBcObjPosition();
  1440 + _minBc = _lpObj.getBc(_minBcIndex[0], _minBcIndex[1]);
  1441 + _maxBc = _lpObj.getBc(_maxBcIndex[0], _maxBcIndex[1]);
  1442 +
  1443 + _otherbc = [];
  1444 + _otherbc.push(_factory.createBcObj(
  1445 + _lpObj, "bd", true, 1,
  1446 + _minBc.getFcTimeObj(),
  1447 + _paramObj
  1448 + ));
  1449 + _otherbc.push(_factory.createBcObj(
  1450 + _lpObj, "out", true, 1,
  1451 + _minBc.getFcTimeObj(),
  1452 + _paramObj
  1453 + ));
  1454 +
  1455 + _maxBc.setArrTimeObj(_paramObj.addMinute(_maxBc.getFcTimeObj(), _maxBc.getBcTime()));
  1456 + _maxBc.setStopTime(0);
  1457 + _otherbc.push(_factory.createBcObj(
  1458 + _lpObj, "in", true, 1,
  1459 + _maxBc.getArrTimeObj(),
  1460 + _paramObj
  1461 + ));
  1462 + _otherbc.push(_factory.createBcObj(
  1463 + _lpObj, "lc", true, 1,
  1464 + _maxBc.getArrTimeObj(),
  1465 + _paramObj
  1466 + ));
  1467 +
  1468 + // 5休2分班出场例保班次
  1469 + if (_lpObj.isBxFb5_2()) {
  1470 + _oFbbc = _lpObj.getBc(
  1471 + _lpObj.fnGetBcChainInfo(1)["s_q"],
  1472 + _lpObj.fnGetBcChainInfo(1)["s_b"]
  1473 + );
  1474 +
  1475 + _otherbc.push(_factory.createBcObj(
  1476 + _lpObj, "bd", true, 1,
  1477 + _oFbbc.getFcTimeObj(),
  1478 + _paramObj
  1479 + ));
  1480 + _otherbc.push(_factory.createBcObj(
  1481 + _lpObj, "out", true, 1,
  1482 + _oFbbc.getFcTimeObj(),
  1483 + _paramObj
  1484 + ));
  1485 + }
  1486 +
  1487 + _lpObj.addOtherBcArray(_otherbc);
  1488 + }
  1489 +
  1490 + },
  1491 +
  1492 + /**
  1493 + * 补每个路牌的其他班次(进出场,例保班次)
  1494 + * 所有的车次链前后都加进出场、报道班次
  1495 + */
  1496 + fnCalcuOtherBc: function() {
  1497 + var i;
  1498 + var j;
  1499 + var iBcChainCount;
  1500 + var oLp;
  1501 + var aOtherBc;
  1502 + var oStartBc;
  1503 + var oEndBc;
  1504 +
  1505 + for (i = 0; i < _internalLpArray.length; i++) {
  1506 + aOtherBc = [];
  1507 + oLp = _internalLpArray[i];
  1508 + iBcChainCount = oLp.fnGetBcChainCount();
  1509 +
  1510 + if (iBcChainCount == 1) { // 只有一个车次链,是连班班型
  1511 + // 头部要添加出场,例保班次
  1512 + oStartBc = oLp.getBc(
  1513 + oLp.fnGetBcChainInfo(0)["s_q"],
  1514 + oLp.fnGetBcChainInfo(0)["s_b"]
  1515 + );
  1516 + aOtherBc.push(_factory.createBcObj(
  1517 + oLp, "bd", true, 1,
  1518 + oStartBc.getFcTimeObj(),
  1519 + _paramObj
  1520 + ));
  1521 + aOtherBc.push(_factory.createBcObj(
  1522 + oLp, "out", true, 1,
  1523 + oStartBc.getFcTimeObj(),
  1524 + _paramObj
  1525 + ));
  1526 +
  1527 + // 尾部需添加进场,例保班次
  1528 + oEndBc = oLp.getBc(
  1529 + oLp.fnGetBcChainInfo(0)["e_q"],
  1530 + oLp.fnGetBcChainInfo(0)["e_b"]
  1531 + );
  1532 + aOtherBc.push(_factory.createBcObj(
  1533 + oLp, "in", true, 1,
  1534 + oEndBc.getArrTimeObj(),
  1535 + _paramObj
  1536 + ));
  1537 + aOtherBc.push(_factory.createBcObj(
  1538 + oLp, "lc", true, 1,
  1539 + oEndBc.getArrTimeObj(),
  1540 + _paramObj
  1541 + ));
  1542 + } else if (iBcChainCount == 2) { // 两个车次链,是分班班型
  1543 + // 第一个车次链开头有出场,报到班次,车次链结尾只有进场班次
  1544 + oStartBc = oLp.getBc(
  1545 + oLp.fnGetBcChainInfo(0)["s_q"],
  1546 + oLp.fnGetBcChainInfo(0)["s_b"]
  1547 + );
  1548 + aOtherBc.push(_factory.createBcObj(
  1549 + oLp, "bd", true, 1,
  1550 + oStartBc.getFcTimeObj(),
  1551 + _paramObj
  1552 + ));
  1553 + aOtherBc.push(_factory.createBcObj(
  1554 + oLp, "out", true, 1,
  1555 + oStartBc.getFcTimeObj(),
  1556 + _paramObj
  1557 + ));
  1558 +
  1559 + oEndBc = oLp.getBc(
  1560 + oLp.fnGetBcChainInfo(0)["e_q"],
  1561 + oLp.fnGetBcChainInfo(0)["e_b"]
  1562 + );
  1563 + aOtherBc.push(_factory.createBcObj(
  1564 + oLp, "in", true, 1,
  1565 + oEndBc.getArrTimeObj(),
  1566 + _paramObj
  1567 + ));
  1568 +
  1569 + // 第二个车次链开头只有出场班次,车次链结尾有进场,报到班次
  1570 + oStartBc = oLp.getBc(
  1571 + oLp.fnGetBcChainInfo(1)["s_q"],
  1572 + oLp.fnGetBcChainInfo(1)["s_b"]
  1573 + );
  1574 + aOtherBc.push(_factory.createBcObj(
  1575 + oLp, "out", true, 1,
  1576 + oStartBc.getFcTimeObj(),
  1577 + _paramObj
  1578 + ));
  1579 +
  1580 + oEndBc = oLp.getBc(
  1581 + oLp.fnGetBcChainInfo(1)["e_q"],
  1582 + oLp.fnGetBcChainInfo(1)["e_b"]
  1583 + );
  1584 + aOtherBc.push(_factory.createBcObj(
  1585 + oLp, "in", true, 1,
  1586 + oEndBc.getArrTimeObj(),
  1587 + _paramObj
  1588 + ));
  1589 + aOtherBc.push(_factory.createBcObj(
  1590 + oLp, "lc", true, 1,
  1591 + oEndBc.getArrTimeObj(),
  1592 + _paramObj
  1593 + ));
  1594 +
  1595 +
  1596 + } else {
  1597 + // 2个车次链以上,暂时没有此班型
  1598 + }
  1599 +
  1600 + oLp.addOtherBcArray(aOtherBc);
  1601 + }
  1602 + },
  1603 +
  1604 + /**
  1605 + * 祛除上标线开头的删除标记的班次。
  1606 + */
  1607 + fnRemoveDelFirstFlagBc: function() {
  1608 + var oLp = _internalLpArray[0];
  1609 + var aMinBcIndex = oLp.getMinBcObjPosition();
  1610 + oLp.removeBc(aMinBcIndex[0], aMinBcIndex[1]);
  1611 + },
  1612 + /**
  1613 + * 祛除上标线结尾的删除标记的班次。
  1614 + */
  1615 + fnRemoveDelLastFlagBc: function() {
  1616 + var oLp = _internalLpArray[0];
  1617 + var aMaxBcIndex = oLp.getMaxBcObjPosition();
  1618 + if (oLp.getBc(aMaxBcIndex[0], aMaxBcIndex[1]).fnIsDelFlag()) {
  1619 + oLp.removeBc(aMaxBcIndex[0], aMaxBcIndex[1]);
  1620 + }
  1621 + },
  1622 +
  1623 + /**
  1624 + * 调整路牌班次间隔(核准周转时间,停站时间)。
  1625 + * @param iFre int 迭代次数
  1626 + */
  1627 + fnAdjustLpBcInterval: function(iFre) {
  1628 + if (iFre > 0) {
  1629 + for (var i = 0; i < _internalLpArray.length; i++) {
  1630 + _internalLpArray[i].fnAdjustBcInterval(
  1631 + this.fnCalcuAverPeakStopTime(),
  1632 + this.fnCalcuAverTroughStopTime(),
  1633 + _paramObj);
  1634 + }
  1635 +
  1636 + this.fnAdjustLpBcInterval(iFre - 1);
  1637 + }
  1638 + },
  1639 +
  1640 + /**
  1641 + * 调整班次间隔。
  1642 + * @param bIsUp 是否上行
  1643 + * @param oStartTime 开始时间对象
  1644 + * @param iFre 迭代次数
  1645 + */
  1646 + fnAdjustBcInterval2_: function(bIsUp, oStartTime, iFre) {
  1647 + if (iFre > 0) {
  1648 + var aBc = _fnGetBcList2(bIsUp, oStartTime); // 指定方向的班次列表
  1649 + aBc.sort(function(o1, o2) {
  1650 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1651 + return -1;
  1652 + } else {
  1653 + return 1;
  1654 + }
  1655 + });
  1656 + var i;
  1657 + var j;
  1658 +
  1659 + var iBcCountOfGroup = 3; // 3个班次取一次计算
  1660 + var aBcOfGroup; // 3个班次列表
  1661 + var aBcIntervalOfGroup; // 班次间隔列表,如:3个班次,2个间隔
  1662 +
  1663 + for (i = 0; i <= aBc.length - iBcCountOfGroup; i++) {
  1664 + aBcOfGroup = [];
  1665 + aBcIntervalOfGroup = [];
  1666 + for (j = i; j < i + iBcCountOfGroup; j++) {
  1667 + aBcOfGroup.push(aBc[j]);
  1668 + }
  1669 +
  1670 + for (j = 0; j < aBcOfGroup.length; j++) {
  1671 + if (j < aBcOfGroup.length - 1) {
  1672 + aBcIntervalOfGroup.push(aBcOfGroup[j + 1].getFcTimeObj().diff(
  1673 + aBcOfGroup[j].getFcTimeObj(), "m"));
  1674 + }
  1675 + }
  1676 +
  1677 + if (aBcIntervalOfGroup[0] < 19) {
  1678 + aBcOfGroup[1].addMinuteToFcsj(1);
  1679 + } else if (aBcIntervalOfGroup[0] > 20) {
  1680 + aBcOfGroup[1].addMinuteToFcsj(-1);
  1681 + } else {
  1682 + if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {
  1683 + //continue;
  1684 + } else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {
  1685 + aBcOfGroup[1].addMinuteToFcsj(-1);
  1686 + } else {
  1687 + aBcOfGroup[1].addMinuteToFcsj(1);
  1688 + }
  1689 + }
  1690 +
  1691 + }
  1692 +
  1693 + this.fnAdjustBcInterval2(bIsUp, oStartTime, iFre - 1);
  1694 + }
  1695 + },
  1696 +
  1697 + /**
  1698 + * 调整班次间隔。
  1699 + * @param boolean isUp 是否上行
  1700 + * @param oStartTime 开始时间对象
  1701 + * @param fre int 迭代次数
  1702 + */
  1703 + fnAdjustBcInterval: function(isUp, oStartTime, fre) {
  1704 + if (fre > 0) {
  1705 + var aBc = !oStartTime ? _fnGetBcList(isUp) : _fnGetBcList2(isUp, oStartTime); // 指定方向的班次列表
  1706 +
  1707 + aBc.sort(function(o1, o2) {
  1708 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1709 + return -1;
  1710 + } else {
  1711 + return 1;
  1712 + }
  1713 + });
  1714 +
  1715 + var i;
  1716 + var j;
  1717 +
  1718 + var iBcCountOfGroup = 3; // 3个班次取一次计算
  1719 + var aBcOfGroup; // 3个班次列表
  1720 + var aBcIntervalOfGroup; // 班次间隔列表,如:3个班次,2个间隔
  1721 + var oBcFcTime; // 班次发车时间
  1722 +
  1723 + for (i = 0; i <= aBc.length - iBcCountOfGroup; i++) {
  1724 + aBcOfGroup = [];
  1725 + aBcIntervalOfGroup = [];
  1726 + for (j = i; j < i + iBcCountOfGroup; j++) {
  1727 + aBcOfGroup.push(aBc[j]);
  1728 + }
  1729 +
  1730 + for (j = 0; j < aBcOfGroup.length; j++) {
  1731 + if (j < aBcOfGroup.length - 1) {
  1732 + aBcIntervalOfGroup.push(aBcOfGroup[j + 1].getFcTimeObj().diff(
  1733 + aBcOfGroup[j].getFcTimeObj(), "m"));
  1734 + }
  1735 + }
  1736 +
  1737 + // 判定规则
  1738 + oBcFcTime = aBcOfGroup[1].getFcTimeObj();
  1739 +
  1740 + // 第一个班次发车时间不动,根据间隔,调整中间一个班次
  1741 + // 如果3个班次2个间隔时间差1分钟,不调整
  1742 + // 如果第一个间隔大,调整第二个班次往前1分钟
  1743 + // 如果第二个间隔大,调整第二个班次往后1分钟
  1744 +
  1745 + if (_paramObj.isTroughBc(oBcFcTime) &&
  1746 + aBcIntervalOfGroup[0] > _paramObj.getTroughMaxFcjx()) {
  1747 + aBcOfGroup[1].addMinuteToFcsj(-1);
  1748 + }
  1749 +
  1750 + //else if (_paramObj.isMPeakBc(oBcFcTime) &&
  1751 + // aBcIntervalOfGroup[0] < _paramObj.getMPeakMinFcjx()) {
  1752 + // aBcOfGroup[1].addMinuteToFcsj(1);
  1753 + //} else if (_paramObj.isMPeakBc(oBcFcTime) &&
  1754 + // aBcIntervalOfGroup[0] > _paramObj.getMPeakMaxFcjx()) {
  1755 + // aBcOfGroup[1].addMinuteToFcsj(-1);
  1756 + //} else if (_paramObj.isEPeakBc(oBcFcTime) &&
  1757 + // aBcIntervalOfGroup[0] < _paramObj.getEPeakMinFcjx()) {
  1758 + // aBcOfGroup[1].addMinuteToFcsj(1);
  1759 + //} else if (_paramObj.isEPeakBc(oBcFcTime) &&
  1760 + // aBcIntervalOfGroup[0] > _paramObj.getEPeakMaxFcjx()) {
  1761 + // aBcOfGroup[1].addMinuteToFcsj(-1);
  1762 + //}
  1763 +
  1764 +
  1765 + else {
  1766 + if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {
  1767 + //continue;
  1768 + } else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {
  1769 + aBcOfGroup[1].addMinuteToFcsj(-1);
  1770 + } else {
  1771 + aBcOfGroup[1].addMinuteToFcsj(1);
  1772 + }
  1773 + }
  1774 +
  1775 + //if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {
  1776 + // //continue;
  1777 + //} else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {
  1778 + // aBcOfGroup[1].addMinuteToFcsj(-1);
  1779 + //} else {
  1780 + // aBcOfGroup[1].addMinuteToFcsj(1);
  1781 + //}
  1782 +
  1783 +
  1784 + }
  1785 +
  1786 + this.fnAdjustBcInterval(isUp, oStartTime, fre - 1);
  1787 + }
  1788 +
  1789 + },
  1790 +
  1791 + /**
  1792 + * 调整班次间隔(平均间隔)。
  1793 + * @param bIsUp 是否上行
  1794 + * @param oStartTime 开始时间对象
  1795 + */
  1796 + fnAdjustBcInterval2_avg: function(bIsUp, oStartTime) {
  1797 + var aBc = !oStartTime ? _fnGetBcList(bIsUp) : _fnGetBcList2(bIsUp, oStartTime); // 指定方向的班次列表
  1798 + aBc.sort(function(o1, o2) {
  1799 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1800 + return -1;
  1801 + } else {
  1802 + return 1;
  1803 + }
  1804 + });
  1805 +
  1806 + var j;
  1807 + var iCount = aBc.length - 1;
  1808 + var iC1 = Math.floor(aBc[aBc.length - 1].getFcTimeObj().diff(aBc[0].getFcTimeObj(), "m") / iCount);
  1809 + var iC2 = aBc[aBc.length - 1].getFcTimeObj().diff(aBc[0].getFcTimeObj(), "m") % iCount;
  1810 + var iTempTime;
  1811 +
  1812 + for (j = 0; j < iCount - iC2; j++) {
  1813 + iTempTime = aBc[j + 1].getFcTimeObj().diff(aBc[j].getFcTimeObj(), "m");
  1814 + aBc[j + 1].addMinuteToFcsj(iC1 - iTempTime);
  1815 + }
  1816 + for (j = 0; j < iC2; j++) {
  1817 + iTempTime = aBc[iCount - iC2 + j + 1].getFcTimeObj().diff(aBc[iCount - iC2 + j].getFcTimeObj(), "m");
  1818 + aBc[iCount - iC2 + j + 1].addMinuteToFcsj(iC1 + 1 - iTempTime);
  1819 + }
  1820 +
  1821 + },
  1822 +
  1823 + /**
  1824 + * 计算高峰平均停站时间。
  1825 + */
  1826 + fnCalcuAverPeakStopTime: function() {
  1827 + var i;
  1828 + var j;
  1829 + var aBc;
  1830 + var iBcCount = 0;
  1831 + var iSum = 0;
  1832 + for (i = 0; i < _internalLpArray.length; i++) {
  1833 + aBc = _internalLpArray[i].getBcArray();
  1834 +
  1835 + for (j = 0; j < aBc.length; j++) {
  1836 + if (!_paramObj.isTroughBc(aBc[j].getArrTimeObj())) {
  1837 + iBcCount ++;
  1838 + iSum += aBc[j].getStopTime();
  1839 + }
  1840 + }
  1841 + }
  1842 +
  1843 + return Math.floor(iSum / iBcCount);
  1844 + },
  1845 +
  1846 + /**
  1847 + * 计算低谷平均停站时间。
  1848 + */
  1849 + fnCalcuAverTroughStopTime: function() {
  1850 + var i;
  1851 + var j;
  1852 + var aBc;
  1853 + var iBcCount = 0;
  1854 + var iSum = 0;
  1855 + for (i = 0; i < _internalLpArray.length; i++) {
  1856 + aBc = _internalLpArray[i].getBcArray();
  1857 + for (j = 0; j < aBc.length; j++) {
  1858 + if (_paramObj.isTroughBc(aBc[j].getArrTimeObj())) {
  1859 + iBcCount ++;
  1860 + iSum += aBc[j].getStopTime();
  1861 + }
  1862 + }
  1863 + }
  1864 +
  1865 + return Math.floor(iSum / iBcCount);
  1866 + },
  1867 +
  1868 + //------------- 其他方法 -------------//
  1869 + /**
  1870 + * 内部数据转化成显示用的班次数组。
  1871 + */
  1872 + fnToGanttBcArray: function() {
  1873 + var aAllBc = [];
  1874 + var aLpBc = [];
  1875 + var aEatBc = [];
  1876 + var oLp;
  1877 + var i;
  1878 + var j;
  1879 +
  1880 + for (i = 0; i < _internalLpArray.length; i++) {
  1881 + oLp = _internalLpArray[i];
  1882 + aLpBc = [];
  1883 + aLpBc = aLpBc.concat(oLp.getOtherBcArray(), oLp.getBcArray());
  1884 +
  1885 + aEatBc = [];
  1886 + // 根据班次的吃饭时间添加吃饭班次
  1887 + for (j = 0; j < aLpBc.length; j++) {
  1888 + if (aLpBc[j].fnGetEatTime() > 0) {
  1889 + aEatBc.push(_factory.createBcObj(
  1890 + oLp,
  1891 + "cf",
  1892 + !aLpBc[j].isUp(), // 和上一个班次方向相反
  1893 + 1,
  1894 + _paramObj.addMinute(aLpBc[j].getArrTimeObj(), aLpBc[j].getStopTime()), // 使用上一个班次的到达时间作为开始时间
  1895 + _paramObj
  1896 + ));
  1897 + }
  1898 + }
  1899 + aLpBc = aLpBc.concat(aEatBc);
  1900 +
  1901 + // 按照发车时间排序
  1902 + aLpBc.sort(function(o1, o2) {
  1903 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1904 + return -1;
  1905 + } else {
  1906 + return 1;
  1907 + }
  1908 + });
  1909 +
  1910 + // 重新赋值fcno
  1911 + for (j = 0; j < aLpBc.length; j++) {
  1912 + aLpBc[j].fnSetFcno(j + 1);
  1913 + }
  1914 +
  1915 + aAllBc = aAllBc.concat(aLpBc);
  1916 + }
  1917 +
  1918 + var aGanttBc = [];
  1919 + for (i = 0; i < aAllBc.length; i++) {
  1920 + aGanttBc.push(aAllBc[i].toGanttBcObj());
  1921 + }
  1922 +
  1923 + return aGanttBc;
  1924 + }
  1925 +
  1926 + };
1867 1927 };
1868 1928 \ No newline at end of file
... ...