Commit 12665bca2c6f42adcd87bedb8809c75bbfc13753

Authored by 徐烜
1 parent e1790793

时刻表v2.6

1、中标线可以和上标线在同一个路牌上,就是两个方向的首班车同一辆车开
2、给班次对象添加是否首末班的标识,在调整路牌班次横向间隔的时候需要过滤首班车次

Too many changes to show.

To preserve performance only 2 of 3 files are displayed.

src/main/resources/static/pages/base/timesmodel/js/v2/core/InternalBcObj.js
... ... @@ -42,10 +42,28 @@ var InternalBcObj = function(
42 42 // 标记参数,这个班次用于计算,最后必须删除
43 43 this._$_bDelFlag = false;
44 44  
  45 + // 是否首末站
  46 + this._$_bIsFirstBc = false;
  47 + this._$_bIsLastBc = false;
  48 +
45 49 };
46 50  
47 51 //------------------- get/set 方法 -------------------//
48 52  
  53 +InternalBcObj.prototype.fnSetIsFirstBc = function(bFlag) {
  54 + this._$_bIsFirstBc = true;
  55 +};
  56 +InternalBcObj.prototype.fnIsFirstBc = function() {
  57 + return this._$_bIsFirstBc;
  58 +};
  59 +
  60 +InternalBcObj.prototype.fnSetIsLastBc = function(bFlag) {
  61 + this._$_bIsLastBc = bFlag;
  62 +};
  63 +InternalBcObj.prototype.fnIsLastBc = function() {
  64 + return this._$_bIsLastBc;
  65 +};
  66 +
49 67 InternalBcObj.prototype.fnSetEatTime = function(iTime) {
50 68 this._$_iEatTime = iTime;
51 69 };
... ...
src/main/resources/static/pages/base/timesmodel/js/v2/core/InternalLpObj.js
1   -/**
2   - * 内部路牌对象。
3   - * @constructor
4   - */
5   -var InternalLpObj = function(
6   - orilpObj, // 原始路牌对象
7   - qCount, // 总共多少圈
8   - isUp // 圈是以上行开始还是下行开始
9   -) {
10   - // TODO:原始路牌对象(这个路牌是对接外部gantt图像,以后有机会改了)
11   - this._$$_orign_lp_obj = orilpObj;
12   -
13   - this._$_isUp = isUp;
14   -
15   - // 路牌的圈数,注意每个路牌的圈数都是一致的,
16   - // 但并不是每一圈都有值
17   - // 第1圈从上标线开始
18   - // 第0圈表示中标线的第一个班次组成的半圈
19   - // 有多少圈根据最终迭代的结果来看
20   - this._$_qCount = qCount;
21   - // 保存的是 InternalGroupBcObj 对象
22   - this._$_groupBcArray = new Array(qCount);
23   -
24   - var i;
25   - for (i = 0; i < this._$_qCount; i++) {
26   - this._$_groupBcArray[i] = new InternalGroupObj(
27   - this, this._$_isUp, undefined, undefined);
28   - }
29   -
30   - // 距离上一个路牌的最小发车间隔时间
31   - // 用于纵向添加班次的时候使用
32   - // 默认第一个路牌为0
33   - this._$_minVerticalIntervalTime = 0;
34   -
35   - // 详细记录每圈每个方向上的发车间隔时间
36   - // 第一维度表示圈数,第二维度表示第一个方向,第二个方向
37   - // 第一个方向是否上行由 _$_isUp 决定
38   - // 这里的间隔表示下一个路牌上的班次距离本路牌的班次发车时间间隔
39   - // 如果当前是最后一个路牌,表示第一个路牌的下一圈同方向班次距离本班次的间隔
40   - this._$_aVerticalIntervalTime = new Array(this._$_qCount);
41   - var i;
42   - for (i = 0; i < this._$_aVerticalIntervalTime.length; i++) {
43   - this._$_aVerticalIntervalTime[i] = new Array(2);
44   - }
45   -
46   - // 班型的相关变量
47   - this._$_bx_isLb = false; // 是否连班
48   - this._$_bx_isfb = false; // 是否分班
49   - this._$_bx_isfb_5_2 = false; // 是否5休2分班
50   - this._$_bx_desc; // 班型描述(默认为路牌编号)
51   -
52   - // 其他班次(进出场,例包,吃饭等),TODO:以后再拆
53   - this._$_other_bc_array = [];
54   -
55   - // TODO:
56   -
57   -};
58   -
59   -//------------------- get/set 方法 -------------------//
60   -
61   -InternalLpObj.prototype.getOtherBcArray = function() {
62   - return this._$_other_bc_array;
63   -};
64   -InternalLpObj.prototype.addOtherBcArray = function(ba) {
65   - this._$_other_bc_array = this._$_other_bc_array.concat(ba);
66   -};
67   -
68   -/**
69   - * 获取圈
70   - * @param qIndex 圈index
71   - */
72   -InternalLpObj.prototype.getGroup = function(qIndex) {
73   - return this._$_groupBcArray[qIndex];
74   -};
75   -
76   -/**
77   - * 获取班次。
78   - * @param qIndex 第几圈
79   - * @param bcIndex 第几个班次
80   - */
81   -InternalLpObj.prototype.getBc = function(qIndex, bcIndex) {
82   - var group = this._$_groupBcArray[qIndex];
83   - var bc;
84   - if (bcIndex == 0) {
85   - bc = group.getBc1();
86   - } else if (bcIndex == 1) {
87   - bc = group.getBc2();
88   - }
89   - return bc;
90   -};
91   -
92   -/**
93   - * 在具体位置设置班次。
94   - * @param qIndex 第几圈
95   - * @param bcIndex 第几个班次
96   - * @param bc 班次对象
97   - */
98   -InternalLpObj.prototype.setBc = function(qIndex, bcIndex, bc) {
99   - var group = this._$_groupBcArray[qIndex];
100   - if (bcIndex == 0) {
101   - group.setBc1(bc);
102   - bc.setGroup(group);
103   - } else if (bcIndex == 1) {
104   - group.setBc2(bc);
105   - bc.setGroup(group);
106   - }
107   -};
108   -
109   -/**
110   - * 设置原始路牌对象。
111   - * @param lpObj 原始路牌对象
112   - */
113   -InternalLpObj.prototype.setLp = function(lpObj) {
114   - this._$$_orign_lp_obj = lpObj;
115   - var i;
116   - var group;
117   - for (i = 0; i < this._$_groupBcArray.length; i++) {
118   - group = this._$_groupBcArray[i];
119   - if (group) {
120   - group.setLp(this); // 圈和班次保存都是 InternalLpObj 对象
121   - }
122   - }
123   -};
124   -
125   -InternalLpObj.prototype.getLpNo = function() {
126   - return this._$$_orign_lp_obj.lpNo;
127   -};
128   -InternalLpObj.prototype.getLpName = function() {
129   - return this._$$_orign_lp_obj.lpName;
130   -};
131   -InternalLpObj.prototype.setBxFb5_2 = function(fb) {
132   - this._$_bx_isfb_5_2 = fb;
133   -};
134   -InternalLpObj.prototype.isBxFb5_2 = function() {
135   - return this._$_bx_isfb_5_2;
136   -};
137   -InternalLpObj.prototype.setBxLb = function(lb) {
138   - this._$_bx_isLb = lb;
139   -};
140   -InternalLpObj.prototype.isBxLb = function() {
141   - return this._$_bx_isLb;
142   -};
143   -
144   -InternalLpObj.prototype.setBxFb = function(fb) {
145   - this._$_bx_isfb = fb;
146   -};
147   -InternalLpObj.prototype.isBxFb = function() {
148   - return this._$_bx_isfb;
149   -};
150   -
151   -/**
152   - * 设置路牌的班型描述(最终是设置班次的路牌名字)。
153   - * @param desc 描述
154   - */
155   -InternalLpObj.prototype.setBxDesc = function(desc) {
156   - // 最终原始路牌的名字
157   - this._$$_orign_lp_obj.lpName = desc + "_" + this._$$_orign_lp_obj.lpNo;
158   - // 内部对象的班型描述
159   - this._$_bx_desc = desc;
160   -};
161   -/**
162   - * 获取版型描述
163   - * @returns string
164   - */
165   -InternalLpObj.prototype.getBxDesc = function() {
166   - return this._$_bx_desc;
167   -};
168   -
169   -/**
170   - * 设置纵向最小发车间隔时间。
171   - * @param v
172   - */
173   -InternalLpObj.prototype.setVerticalMinIntervalTime = function(v) {
174   - // 第一个路牌,都为0
175   - this._$_minVerticalIntervalTime = v;
176   -};
177   -/**
178   - * 获取纵向最小发车间隔时间。
179   - * @returns {number|*}
180   - */
181   -InternalLpObj.prototype.getVerticalMinIntervalTime = function() {
182   - return this._$_minVerticalIntervalTime;
183   -};
184   -
185   -/**
186   - * 设置纵向发车间隔。
187   - * @param iQindex 圈index
188   - * @param iBindex 班次index
189   - * @param iTime 间隔时间
190   - */
191   -InternalLpObj.prototype.fnSetVerticalIntervalTime = function(iQindex, iBindex, iTime) {
192   - this._$_aVerticalIntervalTime[iQindex][iBindex] = iTime;
193   -};
194   -
195   -/**
196   - * 返回纵向发车间隔。
197   - * @param iQindex 圈index
198   - * @param iBindex 班次index
199   - */
200   -InternalLpObj.prototype.fnGetVerticalIntervalTime = function(iQindex, iBindex) {
201   - return this._$_aVerticalIntervalTime[iQindex][iBindex];
202   -};
203   -
204   -//-------------------- 班次操作方法(查询,统计,删除) -----------------------//
205   -
206   -/**
207   - * 返回总共班次数。
208   - */
209   -InternalLpObj.prototype.getBcCount = function() {
210   - var i;
211   - var group;
212   - var bccount = 0;
213   - for (i = 0; i < this._$_groupBcArray.length; i++) {
214   - group = this._$_groupBcArray[i];
215   - if (group) {
216   - if (group.getBc1()) {
217   - bccount += 1;
218   - }
219   - if (group.getBc2()) {
220   - bccount += 1;
221   - }
222   - }
223   - }
224   -
225   - return bccount;
226   -};
227   -
228   -/**
229   - * 返回班次列表,过滤空的班次,将所有存在的班次连成连续的对象数组返回。
230   - * @returns arrays (InternalBcObj)
231   - */
232   -InternalLpObj.prototype.getBcArray = function() {
233   - var bcArray = [];
234   - var i;
235   - var group;
236   - for (i = 0; i < this._$_groupBcArray.length; i++) {
237   - group = this._$_groupBcArray[i];
238   - if (group) {
239   - group.getBc1() ? bcArray.push(group.getBc1()) : "";
240   - group.getBc2() ? bcArray.push(group.getBc2()) : "";
241   - }
242   - }
243   -
244   - return bcArray;
245   -};
246   -
247   -/**
248   - * 获取最小(最早)班次对象。
249   - * @returns [{圈index},{班次index}]
250   - */
251   -InternalLpObj.prototype.getMinBcObjPosition = function() {
252   - var i;
253   - var bIndex = [];
254   - for (i = 0; i < this._$_groupBcArray.length; i++) {
255   - if (this._$_groupBcArray[i].getBc1()) {
256   - bIndex.push(i);
257   - bIndex.push(0);
258   - break;
259   - }
260   - if (this._$_groupBcArray[i].getBc2()) {
261   - bIndex.push(i);
262   - bIndex.push(1);
263   - break;
264   - }
265   - }
266   - return bIndex;
267   -};
268   -
269   -/**
270   - * 获取最大(最晚)班次对象。
271   - * @returns [{圈index},{班次index}]
272   - */
273   -InternalLpObj.prototype.getMaxBcObjPosition = function() {
274   - var i;
275   - var bIndex = [];
276   - for (i = this._$_groupBcArray.length - 1; i >= 0; i--) {
277   - if (this._$_groupBcArray[i].getBc2()) {
278   - bIndex.push(i);
279   - bIndex.push(1);
280   - break;
281   - }
282   - if (this._$_groupBcArray[i].getBc1()) {
283   - bIndex.push(i);
284   - bIndex.push(0);
285   - break;
286   - }
287   - }
288   - return bIndex;
289   -};
290   -
291   -InternalLpObj.prototype.getMinBcObj = function() {
292   - var i;
293   - var bcObj;
294   - for (i = 0; i < this._$_groupBcArray.length; i++) {
295   - bcObj = this._$_groupBcArray[i].getBc1();
296   - if (bcObj) {
297   - break;
298   - }
299   - bcObj = this._$_groupBcArray[i].getBc2();
300   - if (bcObj) {
301   - break;
302   - }
303   - }
304   - return bcObj;
305   -};
306   -InternalLpObj.prototype.getMaxBcObj = function() {
307   - var i;
308   - var bcObj;
309   - for (i = this._$_groupBcArray.length - 1; i >= 0; i--) {
310   - bcObj = this._$_groupBcArray[i].getBc2();
311   - if (bcObj) {
312   - break;
313   - }
314   - bcObj = this._$_groupBcArray[i].getBc1();
315   - if (bcObj) {
316   - break;
317   - }
318   - }
319   - return bcObj;
320   -};
321   -
322   -/**
323   - * 获取车次链信息。
324   - * @param num 第几个车次链
325   - * @returns object {s_q: {开始圈索引},s_b : {开始班次索引},e_q : {结束圈索引},e_b : {结束班次索引}, bcount : {班次数}}
326   - */
327   -InternalLpObj.prototype.fnGetBcChainInfo = function(num) {
328   - // 计算总的车次链信息
329   - var aChainInfo = [];
330   - var oChainInfo;
331   - var aBcIndex = this.getMinBcObjPosition();
332   - var oBc;
333   - var iQIndex;
334   - var iBcIndex;
335   - var i;
336   - var bFlag;
337   -
338   - var iBcount = 0;
339   -
340   - if (aBcIndex.length == 2) {
341   - iBcount = 1;
342   - oChainInfo = {s_q : aBcIndex[0], s_b : aBcIndex[1], e_q : aBcIndex[0], e_b : aBcIndex[1], bcount: 1};
343   - aChainInfo.push(oChainInfo);
344   - bFlag = true;
345   -
346   - // 下一个班次的索引
347   - iQIndex = aBcIndex[1] == 0 ? aBcIndex[0] : aBcIndex[0] + 1;
348   - iBcIndex = aBcIndex[1] == 0 ? 1 : 0;
349   -
350   - for (i = iQIndex; i < this._$_qCount; i++) {
351   - while (iBcIndex <= 1) {
352   - oBc = this.getBc(i, iBcIndex);
353   - if (!oBc) {
354   - if (bFlag) {
355   - // 车次链结尾是这个班次的前一个班次
356   - oChainInfo.e_q = iBcIndex == 0 ? i - 1 : i;
357   - oChainInfo.e_b = iBcIndex == 0 ? 1 : 0;
358   - oChainInfo.bcount = iBcount;
359   - }
360   -
361   - bFlag = false;
362   - } else {
363   - if (bFlag) {
364   - iBcount ++;
365   - oChainInfo.bcount = iBcount;
366   - } else {
367   - // 下一个车次链开始
368   - iBcount = 1;
369   - oChainInfo = {s_q : i, s_b : iBcIndex, e_q : i, e_b : iBcIndex, bcount: 1};
370   - aChainInfo.push(oChainInfo);
371   - bFlag = true;
372   - }
373   - }
374   -
375   -
376   - iBcIndex ++;
377   - }
378   - iBcIndex = 0;
379   - }
380   -
381   - }
382   -
383   - return aChainInfo[num];
384   -};
385   -
386   -/**
387   - * 获取车次链的个数。
388   - * @returns int
389   - */
390   -InternalLpObj.prototype.fnGetBcChainCount = function() {
391   - var iChainCount = 0;
392   - var aBcIndex = this.getMinBcObjPosition();
393   -
394   - var oBc;
395   - var iQIndex;
396   - var iBcIndex;
397   - var i;
398   - var bFlag;
399   -
400   - if (aBcIndex.length == 2) {
401   - iChainCount = 1;
402   - bFlag = true;
403   -
404   - // 下一个班次的索引
405   - iQIndex = aBcIndex[1] == 0 ? aBcIndex[0] : aBcIndex[0] + 1;
406   - iBcIndex = aBcIndex[1] == 0 ? 1 : 0;
407   -
408   - for (i = iQIndex; i < this._$_qCount; i++) {
409   - while (iBcIndex <= 1) {
410   - oBc = this.getBc(i, iBcIndex);
411   - if (!oBc) {
412   - bFlag = false;
413   - } else {
414   - if (bFlag) {
415   -
416   - } else {
417   - iChainCount ++;
418   - bFlag = true;
419   - }
420   - }
421   -
422   -
423   - iBcIndex ++;
424   - }
425   - iBcIndex = 0;
426   - }
427   -
428   - }
429   -
430   -
431   - return iChainCount;
432   -};
433   -
434   -/**
435   - * 在具体位置移除班次。
436   - * @param qIndex 第几圈
437   - * @param bcIndex 第几个班次
438   - */
439   -InternalLpObj.prototype.removeBc = function(qIndex, bcIndex) {
440   - var group = this._$_groupBcArray[qIndex];
441   - if (bcIndex == 0) {
442   - group.removeBc1();
443   - } else if (bcIndex == 1) {
444   - group.removeBc2();
445   - }
446   -};
447   -
448   -/**
449   - * 使用指定时间匹配返回离之最近的第几圈第几个班次,
450   - * 使用时间差的绝度值,比较,取最小的
451   - * 如果有两个一样的时间差,取比fctime大的时间
452   - * @param fctime moment 比较用时间
453   - * @param groupArray 圈数组
454   - * @param hasUp boolean 计算上行班次
455   - * @param hasDown boolean 计算下行班次
456   - * @returns [{第几圈},{第几个班次}]
457   - */
458   -InternalLpObj.prototype.getgetQBcIndexWithFcTimeFromGroupArray = function(
459   - fctime, groupArray, hasUp, hasDown
460   -) {
461   - var i;
462   - var timediff; // 时间差取绝对值
463   - var qIndex;
464   - var bcIndex;
465   -
466   - var group;
467   - var bc1time;
468   - var bc2time;
469   -
470   - var tempdiff;
471   - for (i = 0; i < this._$_qCount; i++) {
472   - group = groupArray[i];
473   - if (group) {
474   - if (group.getBc1() && hasUp) {
475   - bc1time = group.getBc1().getFcTimeObj();
476   - tempdiff = Math.abs(bc1time.diff(fctime));
477   -
478   - if (!timediff) {
479   - timediff = Math.abs(tempdiff);
480   - qIndex = i;
481   - bcIndex = 0;
482   - } else {
483   - if (tempdiff < timediff) {
484   - timediff = tempdiff;
485   - qIndex = i;
486   - bcIndex = 0;
487   - } if (Math.abs(tempdiff) == timediff) {
488   - if (bc1time.isBefore(fctime)) {
489   - timediff = tempdiff;
490   - qIndex = i;
491   - bcIndex = 0;
492   - }
493   -
494   - }
495   - }
496   - }
497   -
498   - if (group.getBc2() && hasDown) {
499   - bc2time = group.getBc2().getFcTimeObj();
500   - tempdiff = Math.abs(bc2time.diff(fctime));
501   -
502   - if (!timediff) {
503   - timediff = Math.abs(tempdiff);
504   - qIndex = i;
505   - bcIndex = 1;
506   - } else {
507   - if (tempdiff < timediff) {
508   - timediff = tempdiff;
509   - qIndex = i;
510   - bcIndex = 1;
511   - } if (Math.abs(tempdiff) == timediff) {
512   - if (bc2time.isBefore(fctime)) {
513   - timediff = tempdiff;
514   - qIndex = i;
515   - bcIndex = 1;
516   - }
517   -
518   - }
519   - }
520   - }
521   - }
522   - }
523   -
524   - var rst = [];
525   - rst.push(qIndex);
526   - rst.push(bcIndex);
527   -
528   - return rst;
529   -};
530   -
531   -/**
532   - * 使用指定时间匹配返回离之最近的第几圈第几个班次,
533   - * 使用时间差的绝度值,比较,取最小的
534   - * 如果有两个一样的时间差,取比fctime大的时间
535   - * @param fctime moment 比较用时间
536   - * @param hasUp boolean 计算上行班次
537   - * @param hasDown boolean 计算下行班次
538   - * @returns [{第几圈},{第几个班次}]
539   - */
540   -InternalLpObj.prototype.getQBcIndexWithFcTime = function(
541   - fctime, hasUp, hasDown
542   -) {
543   - return this.getgetQBcIndexWithFcTimeFromGroupArray(fctime, this._$_groupBcArray, hasUp, hasDown);
544   -};
545   -
546   -//---------------------- 内部数据初始化方法(不同于构造函数)---------------------//
547   -
548   -/**
549   - * 从指定开始时间到结束时间创建不间断班次(连班),并初始化路牌
550   - * 注意,之前有班次会删除后再创建。
551   - * @param startTime 开始时间
552   - * @param endTime 结束时间
553   - * @param isUp 第一个班次是上行还是下行
554   - * @param fromQ 从第几圈开始加入
555   - * @param paramObj 参数对象
556   - * @param factory 工厂对象
557   - */
558   -InternalLpObj.prototype.initDataFromTimeToTime = function(
559   - startTime,
560   - endTime,
561   - isUp,
562   - fromQ,
563   - paramObj,
564   - factory) {
565   -
566   - var bcData = []; // 班次数组
567   - var bcObj;
568   - var kssj = startTime;
569   - var fcno = 1; // 发车顺序号
570   - var bcCount = 1; // 班次数
571   - do {
572   - bcObj = factory.createBcObj(
573   - this, "normal", isUp, fcno, kssj, paramObj); // this就是所属路牌对象
574   - bcData.push(bcObj);
575   -
576   - kssj = paramObj.addMinute(kssj, bcObj.getBcTime() + bcObj.getStopTime());
577   - fcno ++;
578   - bcCount ++;
579   - isUp = !isUp;
580   - } while(kssj.isBefore(endTime));
581   - bcCount--;
582   -
583   - //console.log("last -1;" + bcData[bcCount -2].getFcTimeObj().format("HH:mm"));
584   - //console.log("last;" + bcData[bcCount -1].getFcTimeObj().format("HH:mm"));
585   - //console.log("endtime: " + endTime.format("HH:mm"));
586   -
587   - //if (bcCount > 0 && bcData[bcCount - 1].getArrTimeObj().isAfter(endTime)) {
588   - // // 如果最后一个班次的到达时间超过结束时间,也要去除
589   - // bcData.splice(bcCount - 1, 1);
590   - //}
591   -
592   - this._initDataFromLbBcArray(bcData, fromQ);
593   -
594   -};
595   -
596   -/**
597   - * 使用连班的班次数组初始化路牌(相应的圈会被覆盖)。
598   - * @param bcArray 连班班次数组
599   - * @param fromQ 从第几圈开始加入
600   - */
601   -InternalLpObj.prototype._initDataFromLbBcArray = function(
602   - bcArray,
603   - fromQ
604   -) {
605   - var _bc1Obj;
606   - var _bc2Obj;
607   - var _qObj;
608   -
609   - // 第一班次是上行还是下行
610   - var isUp = bcArray[0].isUp();
611   -
612   - if (bcArray.length > 0 && fromQ < this._$_qCount) {
613   - // 构造圈数
614   - if (isUp != this._$_isUp) {
615   - // 如果方向不一致,意味着第一个班次是半圈
616   - // 加半圈,并加在bc2上
617   - _bc2Obj = bcArray.slice(0, 1)[0];
618   - _qObj = new InternalGroupObj(
619   - this,
620   - this._$_isUp,
621   - undefined,
622   - _bc2Obj
623   - );
624   - _bc2Obj.setGroup(_qObj);
625   - this._$_groupBcArray[fromQ] = _qObj;
626   -
627   - bcArray.splice(0, 1);
628   - fromQ ++;
629   - }
630   -
631   - var qCount1 = Math.floor(bcArray.length / 2); // 需要添加多少圈
632   - var qCount2 = bcArray.length % 2; // 最后是否有半圈
633   -
634   - while (fromQ < this._$_qCount) {
635   - if (qCount1 > 0) {
636   - _bc1Obj = bcArray.slice(0, 1)[0];
637   - _bc2Obj = bcArray.slice(1, 2)[0];
638   - _qObj = new InternalGroupObj(
639   - this,
640   - this._$_isUp,
641   - _bc1Obj,
642   - _bc2Obj
643   - );
644   - _bc1Obj.setGroup(_qObj);
645   - _bc2Obj.setGroup(_qObj);
646   - this._$_groupBcArray[fromQ] = _qObj;
647   -
648   - bcArray.splice(0, 2);
649   - qCount1 --;
650   - } else if (qCount2 > 0) {
651   - // 加半圈,并加在bc1上
652   - _bc1Obj = bcArray.slice(0, 1)[0];
653   - _qObj = new InternalGroupObj(
654   - this,
655   - this._$_isUp,
656   - _bc1Obj,
657   - undefined
658   - );
659   - _bc1Obj.setGroup(_qObj);
660   - this._$_groupBcArray[fromQ] = _qObj;
661   -
662   - bcArray.splice(0, 1);
663   - qCount2 --;
664   - } else {
665   - break;
666   - }
667   -
668   - fromQ ++;
669   - }
670   - }
671   -};
672   -
673   -//-------------------------- 其他方法 ----------------------------//
674   -
675   -/**
676   - * 从指定位置的班次开始,往后所有的班次修正发车时间
677   - * @param groupIndex
678   - * @param bcIndex
679   - * @param time
680   - */
681   -InternalLpObj.prototype.fnAddMinuteToBcFcsj = function(groupIndex, bcIndex, time) {
682   - var i;
683   - var oCurBc;
684   -
685   - // 修正之前班次的停站时间
686   - //oCurBc = this.getBc(
687   - // bcIndex == 0 ? groupIndex - 1 : groupIndex,
688   - // bcIndex == 1 ? 0 : 1
689   - //);
690   - //if (oCurBc) {
691   - // oCurBc.setStopTime(oCurBc.getStopTime() + time);
692   - //}
693   -
694   -
695   - for (i = groupIndex; i < this._$_qCount; i++) {
696   - if (bcIndex == 0) {
697   - oCurBc = this.getBc(i, 0);
698   - if (oCurBc) {
699   - oCurBc.addMinuteToFcsj(time);
700   - }
701   - oCurBc = this.getBc(i, 1);
702   - if (oCurBc) {
703   - oCurBc.addMinuteToFcsj(time);
704   - }
705   -
706   - } else {
707   - oCurBc = this.getBc(i, 1);
708   - if (oCurBc) {
709   - oCurBc.addMinuteToFcsj(time);
710   - }
711   -
712   - }
713   -
714   - bcIndex = 0;
715   - }
716   -};
717   -
718   -/**
719   - * 在指定位置添加一个吃饭班次。
720   - * 注1:吃饭班次不是普通班次,不记录进圈,记录进_$_other_bc_array
721   - * 注2:添加吃饭班次时,会修改之前班次的停战时间,所以导致之后的班次的停战都会发生变化
722   - * @param groupIndex
723   - * @param bcIndex
724   - * @param factory
725   - * @param paramObj
726   - * @returns int 相差时间(吃饭时间距离和停站时间相差值)
727   - */
728   -InternalLpObj.prototype.fnAddEatBc = function(groupIndex, bcIndex, factory, paramObj) {
729   - var oPreBc;
730   - var oEatBc;
731   - var iBcModifyTime;
732   - oPreBc = this.getBc( // 前一个邻接班次
733   - bcIndex == 0 ? groupIndex - 1 : groupIndex,
734   - bcIndex == 1 ? 0 : 1);
735   - if (oPreBc) { // 存在前一个班次
736   - oEatBc = factory.createBcObj(
737   - this,
738   - "cf",
739   - !oPreBc.isUp(), // 和上一个班次方向相反
740   - 1,
741   - paramObj.addMinute(oPreBc.getArrTimeObj(), oPreBc.getStopTime()), // 使用上一个班次的到达时间作为开始时间
742   - paramObj
743   - );
744   -
745   - //iBcModifyTime = oEatBc.getBcTime() - oPreBc.getStopTime(); // 后续班次要调整的时间
746   -
747   - // 修正之后的班次发车时间
748   - // 注意:之后那个班次发车时间就是吃饭班次的到达时间
749   - iBcModifyTime = oEatBc.getArrTimeObj().diff(this.getBc(groupIndex, bcIndex).getFcTimeObj(), "m");
750   - this.fnAddMinuteToBcFcsj(groupIndex, bcIndex, iBcModifyTime);
751   -
752   - oPreBc.setStopTime(0); // 不重置停站时间
753   - oPreBc.fnSetEatTime(oEatBc.getBcTime());
754   -
755   - //this._$_other_bc_array.push(oEatBc);
756   -
757   - return iBcModifyTime;
758   - } else {
759   - return false;
760   - }
761   -
762   -};
763   -
764   -/**
765   - * 调整路牌的班次,通过调整停站时间,或者班次发车时间,不能让班次的到达时间和下一个班次的发车时间重叠。
766   - * @param iPeakAverStopTime 高峰平均停站时间
767   - * @param iTroughAverStopTime 低谷平均停站时间
768   - * @param oParam 参数对象
769   - */
770   -InternalLpObj.prototype.fnAdjustBcInterval = function(iPeakAverStopTime, iTroughAverStopTime, oParam) {
771   - // 获取车次链个数
772   - var iBcChainCount = this.fnGetBcChainCount();
773   -
774   - var i;
775   - var j;
776   - var oBcIndex;
777   - var iQIndex;
778   - var iBcIndex;
779   - var iBcCount;
780   - var oBc;
781   - var oNextBc;
782   -
783   - var iBcStopTime;
784   -
785   - for (i = 0; i < iBcChainCount; i++) {
786   - oBcIndex = this.fnGetBcChainInfo(i);
787   - iQIndex = oBcIndex["s_q"];
788   - iBcIndex = oBcIndex["s_b"];
789   - iBcCount = oBcIndex["bcount"];
790   -
791   - for (j = 0; j < iBcCount - 1; j++) {
792   - oBc = this.getBc(iQIndex, iBcIndex);
793   - oNextBc = this.getBc(
794   - iBcIndex == 0 ? iQIndex : iQIndex + 1,
795   - iBcIndex == 0 ? 1 : 0);
796   -
797   - // 不改变当前班次的行驶时间,修正停站时间和下一个班次的发车时间
798   - iBcStopTime = oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m");
799   - if (iBcStopTime < 0) {
800   - // 当前班次使用最小停站时间
801   - oBc.setStopTime(oParam.fnCalcuFixedMinStopNumber(oBc.getArrTimeObj(), oBc.isUp()));
802   - oNextBc.addMinuteToFcsj(oBc.getStopTime() + oBc.fnGetEatTime() - iBcStopTime);
803   -
804   - } else {
805   - if (iBcStopTime == oBc.getStopTime() + oBc.fnGetEatTime()) {
806   - // 停站时间一致,没有问题
807   -
808   -
809   - } else {
810   - // TODO:当前班次使用最小停站时间
811   - oBc.setStopTime(oParam.fnCalcuFixedMinStopNumber(oBc.getArrTimeObj(), oBc.isUp()));
812   - oNextBc.addMinuteToFcsj(oBc.getStopTime() + oBc.fnGetEatTime() - iBcStopTime);
813   -
814   - }
815   - }
816   -
817   - iBcIndex = iBcIndex == 0 ? 1 : 0;
818   - iQIndex = iBcIndex == 0 ? iQIndex + 1 : iQIndex;
819   - }
820   -
821   - this.getBc(iQIndex, iBcIndex).setStopTime(0);
822   - }
823   -
824   -
825   -};
826   -
827   -
828   -// TODO
829   -
830   -/**
831   - *
832   - *
833   - */
834   -InternalLpObj.prototype.calcuLpBx = function() {
835   -
836   -};
837   -
838   -
839   -
840   -
841   -
842   -
843   -
  1 +/**
  2 + * 内部路牌对象。
  3 + * @constructor
  4 + */
  5 +var InternalLpObj = function(
  6 + orilpObj, // 原始路牌对象
  7 + qCount, // 总共多少圈
  8 + isUp // 圈是以上行开始还是下行开始
  9 +) {
  10 + // TODO:原始路牌对象(这个路牌是对接外部gantt图像,以后有机会改了)
  11 + this._$$_orign_lp_obj = orilpObj;
  12 +
  13 + this._$_isUp = isUp;
  14 +
  15 + // 路牌的圈数,注意每个路牌的圈数都是一致的,
  16 + // 但并不是每一圈都有值
  17 + // 第1圈从上标线开始
  18 + // 第0圈表示中标线的第一个班次组成的半圈
  19 + // 有多少圈根据最终迭代的结果来看
  20 + this._$_qCount = qCount;
  21 + // 保存的是 InternalGroupBcObj 对象
  22 + this._$_groupBcArray = new Array(qCount);
  23 +
  24 + var i;
  25 + for (i = 0; i < this._$_qCount; i++) {
  26 + this._$_groupBcArray[i] = new InternalGroupObj(
  27 + this, this._$_isUp, undefined, undefined);
  28 + }
  29 +
  30 + // 距离上一个路牌的最小发车间隔时间
  31 + // 用于纵向添加班次的时候使用
  32 + // 默认第一个路牌为0
  33 + this._$_minVerticalIntervalTime = 0;
  34 +
  35 + // 详细记录每圈每个方向上的发车间隔时间
  36 + // 第一维度表示圈数,第二维度表示第一个方向,第二个方向
  37 + // 第一个方向是否上行由 _$_isUp 决定
  38 + // 这里的间隔表示下一个路牌上的班次距离本路牌的班次发车时间间隔
  39 + // 如果当前是最后一个路牌,表示第一个路牌的下一圈同方向班次距离本班次的间隔
  40 + this._$_aVerticalIntervalTime = new Array(this._$_qCount);
  41 + var i;
  42 + for (i = 0; i < this._$_aVerticalIntervalTime.length; i++) {
  43 + this._$_aVerticalIntervalTime[i] = new Array(2);
  44 + }
  45 +
  46 + // 班型的相关变量
  47 + this._$_bx_isLb = false; // 是否连班
  48 + this._$_bx_isfb = false; // 是否分班
  49 + this._$_bx_isfb_5_2 = false; // 是否5休2分班
  50 + this._$_bx_desc; // 班型描述(默认为路牌编号)
  51 +
  52 + // 其他班次(进出场,例包,吃饭等),TODO:以后再拆
  53 + this._$_other_bc_array = [];
  54 +
  55 + // TODO:
  56 +
  57 +};
  58 +
  59 +//------------------- get/set 方法 -------------------//
  60 +
  61 +InternalLpObj.prototype.getOtherBcArray = function() {
  62 + return this._$_other_bc_array;
  63 +};
  64 +InternalLpObj.prototype.addOtherBcArray = function(ba) {
  65 + this._$_other_bc_array = this._$_other_bc_array.concat(ba);
  66 +};
  67 +
  68 +/**
  69 + * 获取圈
  70 + * @param qIndex 圈index
  71 + */
  72 +InternalLpObj.prototype.getGroup = function(qIndex) {
  73 + return this._$_groupBcArray[qIndex];
  74 +};
  75 +
  76 +/**
  77 + * 获取班次。
  78 + * @param qIndex 第几圈
  79 + * @param bcIndex 第几个班次
  80 + */
  81 +InternalLpObj.prototype.getBc = function(qIndex, bcIndex) {
  82 + var group = this._$_groupBcArray[qIndex];
  83 + var bc;
  84 + if (bcIndex == 0) {
  85 + bc = group.getBc1();
  86 + } else if (bcIndex == 1) {
  87 + bc = group.getBc2();
  88 + }
  89 + return bc;
  90 +};
  91 +
  92 +/**
  93 + * 在具体位置设置班次。
  94 + * @param qIndex 第几圈
  95 + * @param bcIndex 第几个班次
  96 + * @param bc 班次对象
  97 + */
  98 +InternalLpObj.prototype.setBc = function(qIndex, bcIndex, bc) {
  99 + var group = this._$_groupBcArray[qIndex];
  100 + if (bcIndex == 0) {
  101 + group.setBc1(bc);
  102 + bc.setGroup(group);
  103 + } else if (bcIndex == 1) {
  104 + group.setBc2(bc);
  105 + bc.setGroup(group);
  106 + }
  107 +};
  108 +
  109 +/**
  110 + * 设置原始路牌对象。
  111 + * @param lpObj 原始路牌对象
  112 + */
  113 +InternalLpObj.prototype.setLp = function(lpObj) {
  114 + this._$$_orign_lp_obj = lpObj;
  115 + var i;
  116 + var group;
  117 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  118 + group = this._$_groupBcArray[i];
  119 + if (group) {
  120 + group.setLp(this); // 圈和班次保存都是 InternalLpObj 对象
  121 + }
  122 + }
  123 +};
  124 +
  125 +InternalLpObj.prototype.getLpNo = function() {
  126 + return this._$$_orign_lp_obj.lpNo;
  127 +};
  128 +InternalLpObj.prototype.getLpName = function() {
  129 + return this._$$_orign_lp_obj.lpName;
  130 +};
  131 +InternalLpObj.prototype.setBxFb5_2 = function(fb) {
  132 + this._$_bx_isfb_5_2 = fb;
  133 +};
  134 +InternalLpObj.prototype.isBxFb5_2 = function() {
  135 + return this._$_bx_isfb_5_2;
  136 +};
  137 +InternalLpObj.prototype.setBxLb = function(lb) {
  138 + this._$_bx_isLb = lb;
  139 +};
  140 +InternalLpObj.prototype.isBxLb = function() {
  141 + return this._$_bx_isLb;
  142 +};
  143 +
  144 +InternalLpObj.prototype.setBxFb = function(fb) {
  145 + this._$_bx_isfb = fb;
  146 +};
  147 +InternalLpObj.prototype.isBxFb = function() {
  148 + return this._$_bx_isfb;
  149 +};
  150 +
  151 +/**
  152 + * 设置路牌的班型描述(最终是设置班次的路牌名字)。
  153 + * @param desc 描述
  154 + */
  155 +InternalLpObj.prototype.setBxDesc = function(desc) {
  156 + // 最终原始路牌的名字
  157 + this._$$_orign_lp_obj.lpName = desc + "_" + this._$$_orign_lp_obj.lpNo;
  158 + // 内部对象的班型描述
  159 + this._$_bx_desc = desc;
  160 +};
  161 +/**
  162 + * 获取版型描述
  163 + * @returns string
  164 + */
  165 +InternalLpObj.prototype.getBxDesc = function() {
  166 + return this._$_bx_desc;
  167 +};
  168 +
  169 +/**
  170 + * 设置纵向最小发车间隔时间。
  171 + * @param v
  172 + */
  173 +InternalLpObj.prototype.setVerticalMinIntervalTime = function(v) {
  174 + // 第一个路牌,都为0
  175 + this._$_minVerticalIntervalTime = v;
  176 +};
  177 +/**
  178 + * 获取纵向最小发车间隔时间。
  179 + * @returns {number|*}
  180 + */
  181 +InternalLpObj.prototype.getVerticalMinIntervalTime = function() {
  182 + return this._$_minVerticalIntervalTime;
  183 +};
  184 +
  185 +/**
  186 + * 设置纵向发车间隔。
  187 + * @param iQindex 圈index
  188 + * @param iBindex 班次index
  189 + * @param iTime 间隔时间
  190 + */
  191 +InternalLpObj.prototype.fnSetVerticalIntervalTime = function(iQindex, iBindex, iTime) {
  192 + this._$_aVerticalIntervalTime[iQindex][iBindex] = iTime;
  193 +};
  194 +
  195 +/**
  196 + * 返回纵向发车间隔。
  197 + * @param iQindex 圈index
  198 + * @param iBindex 班次index
  199 + */
  200 +InternalLpObj.prototype.fnGetVerticalIntervalTime = function(iQindex, iBindex) {
  201 + return this._$_aVerticalIntervalTime[iQindex][iBindex];
  202 +};
  203 +
  204 +//-------------------- 班次操作方法(查询,统计,删除) -----------------------//
  205 +
  206 +/**
  207 + * 返回总共班次数。
  208 + */
  209 +InternalLpObj.prototype.getBcCount = function() {
  210 + var i;
  211 + var group;
  212 + var bccount = 0;
  213 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  214 + group = this._$_groupBcArray[i];
  215 + if (group) {
  216 + if (group.getBc1()) {
  217 + bccount += 1;
  218 + }
  219 + if (group.getBc2()) {
  220 + bccount += 1;
  221 + }
  222 + }
  223 + }
  224 +
  225 + return bccount;
  226 +};
  227 +
  228 +/**
  229 + * 返回班次列表,过滤空的班次,将所有存在的班次连成连续的对象数组返回。
  230 + * @returns arrays (InternalBcObj)
  231 + */
  232 +InternalLpObj.prototype.getBcArray = function() {
  233 + var bcArray = [];
  234 + var i;
  235 + var group;
  236 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  237 + group = this._$_groupBcArray[i];
  238 + if (group) {
  239 + group.getBc1() ? bcArray.push(group.getBc1()) : "";
  240 + group.getBc2() ? bcArray.push(group.getBc2()) : "";
  241 + }
  242 + }
  243 +
  244 + return bcArray;
  245 +};
  246 +
  247 +/**
  248 + * 获取最小(最早)班次对象。
  249 + * @returns [{圈index},{班次index}]
  250 + */
  251 +InternalLpObj.prototype.getMinBcObjPosition = function() {
  252 + var i;
  253 + var bIndex = [];
  254 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  255 + if (this._$_groupBcArray[i].getBc1()) {
  256 + bIndex.push(i);
  257 + bIndex.push(0);
  258 + break;
  259 + }
  260 + if (this._$_groupBcArray[i].getBc2()) {
  261 + bIndex.push(i);
  262 + bIndex.push(1);
  263 + break;
  264 + }
  265 + }
  266 + return bIndex;
  267 +};
  268 +
  269 +/**
  270 + * 获取最大(最晚)班次对象。
  271 + * @returns [{圈index},{班次index}]
  272 + */
  273 +InternalLpObj.prototype.getMaxBcObjPosition = function() {
  274 + var i;
  275 + var bIndex = [];
  276 + for (i = this._$_groupBcArray.length - 1; i >= 0; i--) {
  277 + if (this._$_groupBcArray[i].getBc2()) {
  278 + bIndex.push(i);
  279 + bIndex.push(1);
  280 + break;
  281 + }
  282 + if (this._$_groupBcArray[i].getBc1()) {
  283 + bIndex.push(i);
  284 + bIndex.push(0);
  285 + break;
  286 + }
  287 + }
  288 + return bIndex;
  289 +};
  290 +
  291 +InternalLpObj.prototype.getMinBcObj = function() {
  292 + var i;
  293 + var bcObj;
  294 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  295 + bcObj = this._$_groupBcArray[i].getBc1();
  296 + if (bcObj) {
  297 + break;
  298 + }
  299 + bcObj = this._$_groupBcArray[i].getBc2();
  300 + if (bcObj) {
  301 + break;
  302 + }
  303 + }
  304 + return bcObj;
  305 +};
  306 +InternalLpObj.prototype.getMaxBcObj = function() {
  307 + var i;
  308 + var bcObj;
  309 + for (i = this._$_groupBcArray.length - 1; i >= 0; i--) {
  310 + bcObj = this._$_groupBcArray[i].getBc2();
  311 + if (bcObj) {
  312 + break;
  313 + }
  314 + bcObj = this._$_groupBcArray[i].getBc1();
  315 + if (bcObj) {
  316 + break;
  317 + }
  318 + }
  319 + return bcObj;
  320 +};
  321 +
  322 +/**
  323 + * 获取车次链信息。
  324 + * @param num 第几个车次链
  325 + * @returns object {s_q: {开始圈索引},s_b : {开始班次索引},e_q : {结束圈索引},e_b : {结束班次索引}, bcount : {班次数}}
  326 + */
  327 +InternalLpObj.prototype.fnGetBcChainInfo = function(num) {
  328 + // 计算总的车次链信息
  329 + var aChainInfo = [];
  330 + var oChainInfo;
  331 + var aBcIndex = this.getMinBcObjPosition();
  332 + var oBc;
  333 + var iQIndex;
  334 + var iBcIndex;
  335 + var i;
  336 + var bFlag;
  337 +
  338 + var iBcount = 0;
  339 +
  340 + if (aBcIndex.length == 2) {
  341 + iBcount = 1;
  342 + oChainInfo = {s_q : aBcIndex[0], s_b : aBcIndex[1], e_q : aBcIndex[0], e_b : aBcIndex[1], bcount: 1};
  343 + aChainInfo.push(oChainInfo);
  344 + bFlag = true;
  345 +
  346 + // 下一个班次的索引
  347 + iQIndex = aBcIndex[1] == 0 ? aBcIndex[0] : aBcIndex[0] + 1;
  348 + iBcIndex = aBcIndex[1] == 0 ? 1 : 0;
  349 +
  350 + for (i = iQIndex; i < this._$_qCount; i++) {
  351 + while (iBcIndex <= 1) {
  352 + oBc = this.getBc(i, iBcIndex);
  353 + if (!oBc) {
  354 + if (bFlag) {
  355 + // 车次链结尾是这个班次的前一个班次
  356 + oChainInfo.e_q = iBcIndex == 0 ? i - 1 : i;
  357 + oChainInfo.e_b = iBcIndex == 0 ? 1 : 0;
  358 + oChainInfo.bcount = iBcount;
  359 + }
  360 +
  361 + bFlag = false;
  362 + } else {
  363 + if (bFlag) {
  364 + iBcount ++;
  365 + oChainInfo.bcount = iBcount;
  366 + } else {
  367 + // 下一个车次链开始
  368 + iBcount = 1;
  369 + oChainInfo = {s_q : i, s_b : iBcIndex, e_q : i, e_b : iBcIndex, bcount: 1};
  370 + aChainInfo.push(oChainInfo);
  371 + bFlag = true;
  372 + }
  373 + }
  374 +
  375 +
  376 + iBcIndex ++;
  377 + }
  378 + iBcIndex = 0;
  379 + }
  380 +
  381 + }
  382 +
  383 + return aChainInfo[num];
  384 +};
  385 +
  386 +/**
  387 + * 获取车次链的个数。
  388 + * @returns int
  389 + */
  390 +InternalLpObj.prototype.fnGetBcChainCount = function() {
  391 + var iChainCount = 0;
  392 + var aBcIndex = this.getMinBcObjPosition();
  393 +
  394 + var oBc;
  395 + var iQIndex;
  396 + var iBcIndex;
  397 + var i;
  398 + var bFlag;
  399 +
  400 + if (aBcIndex.length == 2) {
  401 + iChainCount = 1;
  402 + bFlag = true;
  403 +
  404 + // 下一个班次的索引
  405 + iQIndex = aBcIndex[1] == 0 ? aBcIndex[0] : aBcIndex[0] + 1;
  406 + iBcIndex = aBcIndex[1] == 0 ? 1 : 0;
  407 +
  408 + for (i = iQIndex; i < this._$_qCount; i++) {
  409 + while (iBcIndex <= 1) {
  410 + oBc = this.getBc(i, iBcIndex);
  411 + if (!oBc) {
  412 + bFlag = false;
  413 + } else {
  414 + if (bFlag) {
  415 +
  416 + } else {
  417 + iChainCount ++;
  418 + bFlag = true;
  419 + }
  420 + }
  421 +
  422 +
  423 + iBcIndex ++;
  424 + }
  425 + iBcIndex = 0;
  426 + }
  427 +
  428 + }
  429 +
  430 +
  431 + return iChainCount;
  432 +};
  433 +
  434 +/**
  435 + * 在具体位置移除班次。
  436 + * @param qIndex 第几圈
  437 + * @param bcIndex 第几个班次
  438 + */
  439 +InternalLpObj.prototype.removeBc = function(qIndex, bcIndex) {
  440 + var group = this._$_groupBcArray[qIndex];
  441 + if (bcIndex == 0) {
  442 + group.removeBc1();
  443 + } else if (bcIndex == 1) {
  444 + group.removeBc2();
  445 + }
  446 +};
  447 +
  448 +/**
  449 + * 使用指定时间匹配返回离之最近的第几圈第几个班次,
  450 + * 使用时间差的绝度值,比较,取最小的
  451 + * 如果有两个一样的时间差,取比fctime大的时间
  452 + * @param fctime moment 比较用时间
  453 + * @param groupArray 圈数组
  454 + * @param hasUp boolean 计算上行班次
  455 + * @param hasDown boolean 计算下行班次
  456 + * @returns [{第几圈},{第几个班次}]
  457 + */
  458 +InternalLpObj.prototype.fnGetQBcIndexWithFcTimeFromGroupArray = function(
  459 + fctime, groupArray, hasUp, hasDown
  460 +) {
  461 + var i;
  462 + var timediff; // 时间差取绝对值
  463 + var qIndex;
  464 + var bcIndex;
  465 +
  466 + var group;
  467 + var bc1time;
  468 + var bc2time;
  469 +
  470 + var tempdiff;
  471 +
  472 + console.log("比较时间=" + fctime.format("HH:mm"));
  473 +
  474 + for (i = 0; i < this._$_qCount; i++) {
  475 + group = groupArray[i];
  476 + if (group) {
  477 + if (group.getBc1() && hasUp) {
  478 + bc1time = group.getBc1().getFcTimeObj();
  479 + console.log("bc1time=" + bc1time.format("HH:mm") + " tempdiff=" + tempdiff);
  480 + tempdiff = Math.abs(bc1time.diff(fctime));
  481 +
  482 + if (!timediff) {
  483 + timediff = Math.abs(tempdiff);
  484 + qIndex = i;
  485 + bcIndex = 0;
  486 + } else {
  487 + if (tempdiff < timediff) {
  488 + timediff = tempdiff;
  489 + qIndex = i;
  490 + bcIndex = 0;
  491 + } if (Math.abs(tempdiff) == timediff) {
  492 + if (bc1time.isAfter(fctime)) {
  493 + timediff = tempdiff;
  494 + qIndex = i;
  495 + bcIndex = 0;
  496 + }
  497 +
  498 + }
  499 + }
  500 + }
  501 +
  502 + if (group.getBc2() && hasDown) {
  503 + bc2time = group.getBc2().getFcTimeObj();
  504 + console.log("bc2time=" + bc2time.format("HH:mm") + " tempdiff=" + tempdiff);
  505 + tempdiff = Math.abs(bc2time.diff(fctime));
  506 +
  507 + if (!timediff) {
  508 + timediff = Math.abs(tempdiff);
  509 + qIndex = i;
  510 + bcIndex = 1;
  511 + } else {
  512 + if (tempdiff < timediff) {
  513 + timediff = tempdiff;
  514 + qIndex = i;
  515 + bcIndex = 1;
  516 + } if (Math.abs(tempdiff) == timediff) {
  517 + if (bc2time.isBefore(fctime)) {
  518 + timediff = tempdiff;
  519 + qIndex = i;
  520 + bcIndex = 1;
  521 + }
  522 +
  523 + }
  524 + }
  525 + }
  526 + }
  527 + }
  528 +
  529 + console.log("中标线对应数组索引=" + qIndex);
  530 +
  531 + var rst = [];
  532 + rst.push(qIndex);
  533 + rst.push(bcIndex);
  534 +
  535 + return rst;
  536 +};
  537 +
  538 +/**
  539 + * 使用指定时间匹配返回离之最近的第几圈第几个班次,
  540 + * 使用时间差的绝度值,比较,取最小的
  541 + * 如果有两个一样的时间差,取比fctime大的时间
  542 + * @param fctime moment 比较用时间
  543 + * @param hasUp boolean 计算上行班次
  544 + * @param hasDown boolean 计算下行班次
  545 + * @returns [{第几圈},{第几个班次}]
  546 + */
  547 +InternalLpObj.prototype.getQBcIndexWithFcTime = function(
  548 + fctime, hasUp, hasDown
  549 +) {
  550 + return this.fnGetQBcIndexWithFcTimeFromGroupArray(fctime, this._$_groupBcArray, hasUp, hasDown);
  551 +};
  552 +
  553 +//---------------------- 内部数据初始化方法(不同于构造函数)---------------------//
  554 +
  555 +/**
  556 + * 从指定开始时间到结束时间创建不间断班次(连班),并初始化路牌
  557 + * 注意,之前有班次会删除后再创建。
  558 + * @param startTime 开始时间
  559 + * @param endTime 结束时间
  560 + * @param isUp 第一个班次是上行还是下行
  561 + * @param fromQ 从第几圈开始加入
  562 + * @param paramObj 参数对象
  563 + * @param factory 工厂对象
  564 + */
  565 +InternalLpObj.prototype.initDataFromTimeToTime = function(
  566 + startTime,
  567 + endTime,
  568 + isUp,
  569 + fromQ,
  570 + paramObj,
  571 + factory) {
  572 +
  573 + var bcData = []; // 班次数组
  574 + var bcObj;
  575 + var kssj = startTime;
  576 + var fcno = 1; // 发车顺序号
  577 + var bcCount = 1; // 班次数
  578 + do {
  579 + bcObj = factory.createBcObj(
  580 + this, "normal", isUp, fcno, kssj, paramObj); // this就是所属路牌对象
  581 + bcData.push(bcObj);
  582 +
  583 + kssj = paramObj.addMinute(kssj, bcObj.getBcTime() + bcObj.getStopTime());
  584 + fcno ++;
  585 + bcCount ++;
  586 + isUp = !isUp;
  587 + } while(kssj.isBefore(endTime));
  588 + bcCount--;
  589 +
  590 + //console.log("last -1;" + bcData[bcCount -2].getFcTimeObj().format("HH:mm"));
  591 + //console.log("last;" + bcData[bcCount -1].getFcTimeObj().format("HH:mm"));
  592 + //console.log("endtime: " + endTime.format("HH:mm"));
  593 +
  594 + //if (bcCount > 0 && bcData[bcCount - 1].getArrTimeObj().isAfter(endTime)) {
  595 + // // 如果最后一个班次的到达时间超过结束时间,也要去除
  596 + // bcData.splice(bcCount - 1, 1);
  597 + //}
  598 +
  599 + this._initDataFromLbBcArray(bcData, fromQ);
  600 +
  601 +};
  602 +
  603 +/**
  604 + * 使用连班的班次数组初始化路牌(相应的圈会被覆盖)。
  605 + * @param bcArray 连班班次数组
  606 + * @param fromQ 从第几圈开始加入
  607 + */
  608 +InternalLpObj.prototype._initDataFromLbBcArray = function(
  609 + bcArray,
  610 + fromQ
  611 +) {
  612 + var _bc1Obj;
  613 + var _bc2Obj;
  614 + var _qObj;
  615 +
  616 + // 第一班次是上行还是下行
  617 + var isUp = bcArray[0].isUp();
  618 +
  619 + if (bcArray.length > 0 && fromQ < this._$_qCount) {
  620 + // 构造圈数
  621 + if (isUp != this._$_isUp) {
  622 + // 如果方向不一致,意味着第一个班次是半圈
  623 + // 加半圈,并加在bc2上
  624 + _bc2Obj = bcArray.slice(0, 1)[0];
  625 + _qObj = new InternalGroupObj(
  626 + this,
  627 + this._$_isUp,
  628 + undefined,
  629 + _bc2Obj
  630 + );
  631 + _bc2Obj.setGroup(_qObj);
  632 + this._$_groupBcArray[fromQ] = _qObj;
  633 +
  634 + bcArray.splice(0, 1);
  635 + fromQ ++;
  636 + }
  637 +
  638 + var qCount1 = Math.floor(bcArray.length / 2); // 需要添加多少圈
  639 + var qCount2 = bcArray.length % 2; // 最后是否有半圈
  640 +
  641 + while (fromQ < this._$_qCount) {
  642 + if (qCount1 > 0) {
  643 + _bc1Obj = bcArray.slice(0, 1)[0];
  644 + _bc2Obj = bcArray.slice(1, 2)[0];
  645 + _qObj = new InternalGroupObj(
  646 + this,
  647 + this._$_isUp,
  648 + _bc1Obj,
  649 + _bc2Obj
  650 + );
  651 + _bc1Obj.setGroup(_qObj);
  652 + _bc2Obj.setGroup(_qObj);
  653 + this._$_groupBcArray[fromQ] = _qObj;
  654 +
  655 + bcArray.splice(0, 2);
  656 + qCount1 --;
  657 + } else if (qCount2 > 0) {
  658 + // 加半圈,并加在bc1上
  659 + _bc1Obj = bcArray.slice(0, 1)[0];
  660 + _qObj = new InternalGroupObj(
  661 + this,
  662 + this._$_isUp,
  663 + _bc1Obj,
  664 + undefined
  665 + );
  666 + _bc1Obj.setGroup(_qObj);
  667 + this._$_groupBcArray[fromQ] = _qObj;
  668 +
  669 + bcArray.splice(0, 1);
  670 + qCount2 --;
  671 + } else {
  672 + break;
  673 + }
  674 +
  675 + fromQ ++;
  676 + }
  677 + }
  678 +};
  679 +
  680 +//-------------------------- 其他方法 ----------------------------//
  681 +
  682 +/**
  683 + * 从指定位置的班次开始,往后所有的班次修正发车时间
  684 + * @param groupIndex
  685 + * @param bcIndex
  686 + * @param time
  687 + */
  688 +InternalLpObj.prototype.fnAddMinuteToBcFcsj = function(groupIndex, bcIndex, time) {
  689 + var i;
  690 + var oCurBc;
  691 +
  692 + // 修正之前班次的停站时间
  693 + //oCurBc = this.getBc(
  694 + // bcIndex == 0 ? groupIndex - 1 : groupIndex,
  695 + // bcIndex == 1 ? 0 : 1
  696 + //);
  697 + //if (oCurBc) {
  698 + // oCurBc.setStopTime(oCurBc.getStopTime() + time);
  699 + //}
  700 +
  701 +
  702 + for (i = groupIndex; i < this._$_qCount; i++) {
  703 + if (bcIndex == 0) {
  704 + oCurBc = this.getBc(i, 0);
  705 + if (oCurBc) {
  706 + oCurBc.addMinuteToFcsj(time);
  707 + }
  708 + oCurBc = this.getBc(i, 1);
  709 + if (oCurBc) {
  710 + oCurBc.addMinuteToFcsj(time);
  711 + }
  712 +
  713 + } else {
  714 + oCurBc = this.getBc(i, 1);
  715 + if (oCurBc) {
  716 + oCurBc.addMinuteToFcsj(time);
  717 + }
  718 +
  719 + }
  720 +
  721 + bcIndex = 0;
  722 + }
  723 +};
  724 +
  725 +/**
  726 + * 在指定位置添加一个吃饭班次。
  727 + * 注1:吃饭班次不是普通班次,不记录进圈,记录进_$_other_bc_array
  728 + * 注2:添加吃饭班次时,会修改之前班次的停战时间,所以导致之后的班次的停战都会发生变化
  729 + * @param groupIndex
  730 + * @param bcIndex
  731 + * @param factory
  732 + * @param paramObj
  733 + * @returns int 相差时间(吃饭时间距离和停站时间相差值)
  734 + */
  735 +InternalLpObj.prototype.fnAddEatBc = function(groupIndex, bcIndex, factory, paramObj) {
  736 + var oPreBc;
  737 + var oEatBc;
  738 + var iBcModifyTime;
  739 + oPreBc = this.getBc( // 前一个邻接班次
  740 + bcIndex == 0 ? groupIndex - 1 : groupIndex,
  741 + bcIndex == 1 ? 0 : 1);
  742 + if (oPreBc) { // 存在前一个班次
  743 + oEatBc = factory.createBcObj(
  744 + this,
  745 + "cf",
  746 + !oPreBc.isUp(), // 和上一个班次方向相反
  747 + 1,
  748 + paramObj.addMinute(oPreBc.getArrTimeObj(), oPreBc.getStopTime()), // 使用上一个班次的到达时间作为开始时间
  749 + paramObj
  750 + );
  751 +
  752 + //iBcModifyTime = oEatBc.getBcTime() - oPreBc.getStopTime(); // 后续班次要调整的时间
  753 +
  754 + // 修正之后的班次发车时间
  755 + // 注意:之后那个班次发车时间就是吃饭班次的到达时间
  756 + iBcModifyTime = oEatBc.getArrTimeObj().diff(this.getBc(groupIndex, bcIndex).getFcTimeObj(), "m");
  757 + this.fnAddMinuteToBcFcsj(groupIndex, bcIndex, iBcModifyTime);
  758 +
  759 + oPreBc.setStopTime(0); // 不重置停站时间
  760 + oPreBc.fnSetEatTime(oEatBc.getBcTime());
  761 +
  762 + //this._$_other_bc_array.push(oEatBc);
  763 +
  764 + return iBcModifyTime;
  765 + } else {
  766 + return false;
  767 + }
  768 +
  769 +};
  770 +
  771 +/**
  772 + * 调整路牌的班次,通过调整停站时间,或者班次发车时间,不能让班次的到达时间和下一个班次的发车时间重叠。
  773 + * @param iPeakAverStopTime 高峰平均停站时间
  774 + * @param iTroughAverStopTime 低谷平均停站时间
  775 + * @param oParam 参数对象
  776 + */
  777 +InternalLpObj.prototype.fnAdjustBcInterval = function(iPeakAverStopTime, iTroughAverStopTime, oParam) {
  778 + // 获取车次链个数
  779 + var iBcChainCount = this.fnGetBcChainCount();
  780 +
  781 + var i;
  782 + var j;
  783 + var oBcIndex;
  784 + var iQIndex;
  785 + var iBcIndex;
  786 + var iBcCount;
  787 + var oBc;
  788 + var oNextBc;
  789 +
  790 + var iBcStopTime;
  791 +
  792 + for (i = 0; i < iBcChainCount; i++) {
  793 + oBcIndex = this.fnGetBcChainInfo(i);
  794 + iQIndex = oBcIndex["s_q"];
  795 + iBcIndex = oBcIndex["s_b"];
  796 + iBcCount = oBcIndex["bcount"];
  797 +
  798 + for (j = 0; j < iBcCount - 1; j++) {
  799 + oBc = this.getBc(iQIndex, iBcIndex);
  800 + oNextBc = this.getBc(
  801 + iBcIndex == 0 ? iQIndex : iQIndex + 1,
  802 + iBcIndex == 0 ? 1 : 0);
  803 +
  804 + if (oNextBc.fnIsFirstBc()) { // 如果同一路牌连续2个方向首站班次,都不做处理
  805 + continue;
  806 + }
  807 +
  808 + // 不改变当前班次的行驶时间,修正停站时间和下一个班次的发车时间
  809 + iBcStopTime = oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m");
  810 + if (iBcStopTime < 0) {
  811 + // 当前班次使用最小停站时间
  812 + oBc.setStopTime(oParam.fnCalcuFixedMinStopNumber(oBc.getArrTimeObj(), oBc.isUp()));
  813 + oNextBc.addMinuteToFcsj(oBc.getStopTime() + oBc.fnGetEatTime() - iBcStopTime);
  814 +
  815 + } else {
  816 + if (iBcStopTime == oBc.getStopTime() + oBc.fnGetEatTime()) {
  817 + // 停站时间一致,没有问题
  818 +
  819 +
  820 + } else {
  821 + // TODO:当前班次使用最小停站时间
  822 + oBc.setStopTime(oParam.fnCalcuFixedMinStopNumber(oBc.getArrTimeObj(), oBc.isUp()));
  823 + oNextBc.addMinuteToFcsj(oBc.getStopTime() + oBc.fnGetEatTime() - iBcStopTime);
  824 +
  825 + }
  826 + }
  827 +
  828 + iBcIndex = iBcIndex == 0 ? 1 : 0;
  829 + iQIndex = iBcIndex == 0 ? iQIndex + 1 : iQIndex;
  830 + }
  831 +
  832 + this.getBc(iQIndex, iBcIndex).setStopTime(0);
  833 + }
  834 +
  835 +
  836 +};
  837 +
  838 +
  839 +// TODO
  840 +
  841 +/**
  842 + *
  843 + *
  844 + */
  845 +InternalLpObj.prototype.calcuLpBx = function() {
  846 +
  847 +};
  848 +
  849 +
  850 +
  851 +
  852 +
  853 +
  854 +
... ...