Commit 3a45f8f972f3a8c9f6026f1668c8d82678a23686

Authored by 徐烜
1 parent 5af824ef

时刻表v2_2.3.4

1、修正了Main_v2_2_ExcelObj.js的导出功能,可以导出报道,出场,进场,离场班次,每圈的分班点会增加1圈,防止excel导出列不够
2、Main_v2_2_ExcelObj要求给予的班次是按照时间顺序并且按照路牌顺序排序,不允许倒发车,如果存在问题由外部函数解决,Main_v2_2_ExcelObj内部不做修正
3、修改AdjustHeadwayS1,AdjustHeadwayS2,AdustHeadwyS3_eat,当修正班次间隔时,需要修正路牌的间隔
4、修改InternalScheduleObj中的fnAdjustHeadway方法,按照副站,主站圈,一圈一圈的修正所有班次间隔
5、调整main_v2_2中生成时刻表顺序,fnAdjustHeadway在fnCalcuEatBc前执行

Too many changes to show.

To preserve performance only 5 of 6 files are displayed.

src/main/resources/static/pages/base/timesmodel/js/v2_2/InternalScheduleObj.js
1 -/**  
2 - * v2_2版本的行车计划对象。  
3 - *  
4 - * 本次修正和原来区别,一边生成班次,一边调整班次间隔  
5 - * 1、初始化行车计划基本布局,主要是有几辆车,路牌分布情况(连班,分班,5休2分班),上标线的初始班次列表  
6 - *  
7 - */  
8 -var InternalScheduleObj_v2_2 = (function() {  
9 -  
10 - // 内部utils类  
11 - var _utils = function() {  
12 - return {  
13 - /**  
14 - * 创建班次对象。  
15 - * @param lpObj InternalLpObj路牌对象  
16 - * @param bcType 班次类型(normal等等)  
17 - * @param isUp 是否上行  
18 - * @param fcno 发车顺序号  
19 - * @param fcTimeObj 发车时间对象  
20 - * @param paramObj 参数对象  
21 - * @returns {InternalBcObj}  
22 - */  
23 - createBcObj : function(lpObj, bcType, isUp, fcno, fcTimeObj, paramObj) {  
24 - var _bclc = paramObj.calcuTravelLcNumber(isUp, bcType); // 班次里程  
25 - var _fcsj = fcTimeObj; // 发车时间  
26 - // var _bcsj = paramObj.calcuTravelTime(_fcsj, isUp); // 班次历时  
27 - var _bcsj = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(isUp, _fcsj, paramObj); // 使用策略计算班次行驶时间  
28 -  
29 - // console.log("发车时间=" + _fcsj.format("HH:mm") + ",行驶时间=" + _bcsj);  
30 -  
31 - var _arrsj = paramObj.addMinute(_fcsj, _bcsj); // 到达时间  
32 - // 停站时间范围,[最小停站时间,最大停站时间]  
33 - // var _stopTimeRange = paramObj.calcuTripLayoverTimeRange(_arrsj, isUp, _bcsj);  
34 - var _stopTimeRange = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
35 - _fcsj, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), paramObj);  
36 -  
37 - var _stoptime = _stopTimeRange[0]; // 使用最小停站时间  
38 - var _tccid = paramObj.getTTinfoId();  
39 - var _ttinfoid = paramObj.getTTinfoId();  
40 - var _xl = paramObj.getXlId();  
41 - var _qdz = isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;  
42 - var _zdz = isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;  
43 -  
44 - if (bcType == "bd") { // 早例保,传过来的发车时间是第一个班次的发车时间  
45 - if (isUp) { // 上行  
46 - _fcsj = paramObj.addMinute(  
47 - _fcsj,  
48 - -(paramObj.getUpOutTime() + paramObj.getLbTime()));  
49 - _bcsj = paramObj.getLbTime();  
50 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
51 - _stoptime = 0;  
52 - } else { // 下行  
53 - _fcsj = paramObj.addMinute(  
54 - _fcsj,  
55 - -(paramObj.getDownOutTime() + paramObj.getLbTime()));  
56 - _bcsj = paramObj.getLbTime();  
57 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
58 - _stoptime = 0;  
59 - }  
60 - } else if (bcType == "lc") { // 晚例保,传过来的发车时间是最后一个班次的到达时间  
61 - if (isUp) { // 上行  
62 - _fcsj = paramObj.addMinute(  
63 - _fcsj,  
64 - paramObj.getUpInTime());  
65 - _bcsj = paramObj.getLbTime();  
66 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
67 - _stoptime = 0;  
68 - } else { // 下行  
69 - _fcsj = paramObj.addMinute(  
70 - _fcsj,  
71 - paramObj.getDownInTime());  
72 - _bcsj = paramObj.getLbTime();  
73 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
74 - _stoptime = 0;  
75 - }  
76 - } else if (bcType == "out") { // 出场,传过来的发车时间是第一个班次的发车时间  
77 - if (isUp) { // 上行  
78 - _fcsj = paramObj.addMinute(  
79 - _fcsj,  
80 - -paramObj.getUpOutTime());  
81 - _bcsj = paramObj.getUpOutTime();  
82 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
83 - _stoptime = 0;  
84 - } else { // 下行  
85 - _fcsj = paramObj.addMinute(  
86 - _fcsj,  
87 - -paramObj.getDownOutTime());  
88 - _bcsj = paramObj.getDownOutTime();  
89 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
90 - _stoptime = 0;  
91 - }  
92 - } else if (bcType == "in") { // 进场,传过来的发车时间是最后一个班次的到达时间  
93 - if (isUp) { // 上行  
94 - _bcsj = paramObj.getUpInTime();  
95 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
96 - _stoptime = 0;  
97 - } else { // 下行  
98 - _bcsj = paramObj.getDownInTime();  
99 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
100 - _stoptime = 0;  
101 - }  
102 - } else if (bcType == "cf") { // 吃饭班次  
103 - // 以13:00为分界,之前的为午饭,之后的为晚饭  
104 - if (fcTimeObj.isBefore(paramObj.toTimeObj("13:00"))) {  
105 - _bcsj = paramObj.fnGetLunchTime();  
106 - } else {  
107 - _bcsj = paramObj.fnGetDinnerTime();  
108 - }  
109 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
110 - _stoptime = 0;  
111 - }  
112 -  
113 - var bcParamObj = {};  
114 - bcParamObj.bcType = bcType; // 班次类型(normal,in_,out, bd, lc, cf等)  
115 - bcParamObj.isUp = isUp; // boolean是否上下行  
116 - bcParamObj.fcno = fcno; // 发车顺序号  
117 - bcParamObj.fcTimeObj = _fcsj; // 发车时间对象  
118 - bcParamObj.bclc = _bclc; // 班次里程  
119 - bcParamObj.bcsj = _bcsj; // 班次历时  
120 - bcParamObj.arrtime = _arrsj; // 到达时间对象  
121 - bcParamObj.stoptime = _stoptime; // 停站时间  
122 - bcParamObj.tccid = _tccid; // 停车场id  
123 - bcParamObj.ttinfoid = _ttinfoid; // 时刻表id  
124 - bcParamObj.xl = _xl; // 线路id  
125 - bcParamObj.qdzid = _qdz; // 起点站id  
126 - bcParamObj.zdzid = _zdz; // 终点站id  
127 -  
128 - return new InternalBcObj(lpObj, bcParamObj);  
129 - },  
130 -  
131 - /**  
132 - * 修正上标线主站方向班次(一圈的结束班次,也是下一圈的开始班次)以及后续说有班次。  
133 - * @param oLp 上标线路牌  
134 - * @param fromFcsj 开始发车时间对象  
135 - * @param fromGroupIndex 开始圈索引  
136 - * @param fromBcIndex 开始班次索引  
137 - * @param isUp 开始班次是上行还是下行  
138 - * @param oParam 参数对象  
139 - */  
140 - modifySBXMasterBc: function(oLp, fromFcsj, fromGroupIndex, fromBcIndex, isUp, oParam) {  
141 - // 清空指定位置班次及后续班次  
142 - oLp.clearBc(fromGroupIndex, fromBcIndex);  
143 - // 初始化上标线,从指定圈索引开始  
144 - oLp.initDataFromTime(fromFcsj, isUp, fromGroupIndex, oParam, _utils);  
145 -  
146 - }  
147 -  
148 - };  
149 - }();  
150 -  
151 -  
152 -  
153 - /**  
154 - * 内部行车计划对象。  
155 - * @param oParam 参数封装对象  
156 - * @param aLp 路牌(甘特图用的路牌对象)  
157 - * @constructor  
158 - */  
159 - function InternalScheduleObj(oParam, aLp) {  
160 - // 参数对象和甘特图用路牌数组  
161 - this._oParam = oParam;  
162 - this._aGanttLpArray = aLp;  
163 -  
164 - // 目前这个只支持主站停站  
165 - if (this._oParam.isTwoWayStop()) {  
166 - alert("v2_2版本不支持双向停站类型线路!");  
167 - throw "v2_2版本不支持双向停站类型线路";  
168 - }  
169 -  
170 - console.log("//->>>>>>>>>>>>>>>>>>>>>>>>> v2_2行车计划,初始化1,圈信息,路牌 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-//");  
171 - //----------------------- 1、确定上标线的方向,圈的方向 -------------------//  
172 - this._qIsUp = true; // 每一圈是上行开始还是下行开始  
173 -  
174 - // 确定_qIsUp,哪个方向的首班车晚就用哪个  
175 - // this._qIsUp = this._oParam.getUpFirstDTimeObj().isBefore(  
176 - // this._oParam.getDownFirstDTimeObj()) ? false : true;  
177 -  
178 - // 确定_qIsUp,哪个方向的首班车晚就用哪个  
179 - // 使用diff判定,如果两个时间相等 this._qIsUp = false  
180 - this._qIsUp = oParam.getUpFirstDTimeObj().diff(oParam.getDownFirstDTimeObj()) <= 0 ? false : true;  
181 -  
182 -  
183 - // 上标线开始时间,就是方向的首班车时间  
184 - var st = this._qIsUp ? oParam.getUpFirstDTimeObj() : oParam.getDownFirstDTimeObj();  
185 - // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向  
186 - var et;  
187 - var et_IsUp;  
188 - if (oParam.getUpLastDtimeObj().isBefore(  
189 - oParam.getDownLastDTimeObj())) {  
190 - et = oParam.getDownLastDTimeObj();  
191 - et_IsUp = false;  
192 - } else {  
193 - et = oParam.getUpLastDtimeObj();  
194 - et_IsUp = true;  
195 - }  
196 - //------------------------ 2、计算总共有多少圈 ------------------------//  
197 - this._qCount = 0; // 总的圈数  
198 -  
199 - // 以开始时间,结束时间,构造上标线用连班班次发车时间  
200 - var bcFcsjArrays = []; // 班次发车时间对象数组  
201 - var bcArsjArrays = []; // 班次到达时间对象数组  
202 - var isUp = this._qIsUp; // 方向  
203 - var bcCount = 1; // 班次数  
204 -  
205 - var _kssj = st; // 开始时间  
206 - var _bcsj = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(isUp, _kssj, oParam); // 使用策略计算班次行驶时间  
207 - var _arrsj = oParam.addMinute(_kssj, _bcsj); // 到达时间  
208 - var _stoptimeRange = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
209 - _kssj, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam);  
210 - var _stoptime = _stoptimeRange[0]; // 最小停站时间  
211 -  
212 - do {  
213 - bcFcsjArrays.push(_kssj);  
214 - bcArsjArrays.push(_arrsj);  
215 -  
216 - _kssj = oParam.addMinute(_kssj, _bcsj + _stoptime);  
217 - // _bcsj = oParam.calcuTravelTime(_kssj, isUp);  
218 -  
219 - _bcsj = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(isUp, _kssj, oParam); // 使用策略计算班次行驶时间  
220 - _arrsj = oParam.addMinute(_kssj, _bcsj);  
221 - _stoptimeRange = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
222 - _kssj, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam);  
223 - _stoptime = _stoptimeRange[0]; // 最小停站时间  
224 -  
225 - bcCount ++;  
226 - isUp = !isUp;  
227 - } while(_kssj.isBefore(et));  
228 - bcCount--; // 因为先做do,所以总的班次要减1  
229 -  
230 - var _qCount_p1 = Math.floor(bcCount / 2); // 2个班次一圈  
231 - var _qCount_p2 = bcCount % 2; // 余下的1个班次也算一圈  
232 -  
233 - // 利用连班数组计算圈数  
234 - this._qCount = 1; // 前面加1圈,补中标线的班次  
235 - this._qCount += _qCount_p1;  
236 - this._qCount += _qCount_p2;  
237 -  
238 - // 计算最后是不是还要补一圈  
239 - if (this._qCount > 1) { // 总的圈数就1圈,没必要加了(其实是不可能的,除非参数里问题)  
240 - if (_qCount_p2 == 0) { // 没有余下班次,整数圈数  
241 - // 最后一个班次的方向一定和开始的方向相反,如:上-下,上-下,上-下,一共三圈,最后一个班次为下行  
242 - // 判定最后一个班次的方向和上标线判定结束时间的班次方向是否一致  
243 - if (!this._qIsUp == et_IsUp) {  
244 - // 一致不用加圈数  
245 - } else {  
246 - // 不一致需要加圈补最后一个结束时间班次  
247 - this._qCount ++;  
248 - }  
249 - } else {  
250 - // 有余下的圈数,最后要不补的班次不管上行,下行都在这一圈里  
251 - // 不需要在补圈数了  
252 - }  
253 - }  
254 - //------------------------ 3、根据路牌数,圈数创建路牌对象 ----------------------//  
255 - this._internalLpArray = []; // 内部路牌(InternalLpObj对象)数组  
256 -  
257 - // 创建内部的路牌数组  
258 - var i;  
259 - for (i = 0; i < this._aGanttLpArray.length; i++) {  
260 - this._internalLpArray.push(  
261 - new InternalLpObj(this._aGanttLpArray[i], this._qCount, this._qIsUp));  
262 - }  
263 -  
264 - // 初始化上标线,从第1圈开始  
265 - this._internalLpArray[0].initDataFromTimeToTime(  
266 - bcFcsjArrays[0], et, this._qIsUp, 1, oParam, _utils);  
267 -  
268 -  
269 - console.log("上行首班车时间:" + oParam.getUpFirstDTimeObj().format("HH:mm") +  
270 - "上行末班车时间:" + oParam.getUpLastDtimeObj().format("HH:mm"));  
271 - console.log("下行首班车时间:" + oParam.getDownFirstDTimeObj().format("HH:mm") +  
272 - "下行末班车时间:" + oParam.getDownLastDTimeObj().format("HH:mm"));  
273 - console.log("总共计算的圈数:" + this._qCount);  
274 - console.log("圈的方向isUP:" + this._qIsUp);  
275 -  
276 - console.log("//->>>>>>>>>>>>>>>>>>>>>>>>> v2_2行车计划,初始化2,工时,路牌信息 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-//");  
277 - //------------------------ 1、以上标线为基础,计算各种班型工时对应的圈数、班次数 -----------------------//  
278 - var aBcArray = this._internalLpArray[0].getBcArray();  
279 - aBcArray[0].fnSetIsFirstBc(true); // 设置首班班次标识  
280 -  
281 - if (aBcArray.length % 2 != 0) { // 不能整除2,去除一个班次计算  
282 - aBcArray.splice(aBcArray.length - 1, 1);  
283 - }  
284 -  
285 - var iLTime = oParam.fnGetLunchTime(); // 午饭吃饭时间  
286 - var iDTime = oParam.fnGetDinnerTime(); // 晚饭吃饭时间  
287 - var iOutTime = this._qIsUp ? oParam.getUpOutTime() : oParam.getDownOutTime(); // 出场时间  
288 - var iInTime = this._qIsUp ? oParam.getDownInTime() : oParam.getUpInTime(); // 进场时间  
289 - var iBTime = oParam.getLbTime(); // 例保时间  
290 -  
291 - var sum = 0; // 总班次时间  
292 - for (i = 0; i < aBcArray.length; i++) {  
293 - sum += aBcArray[i].getBcTime() + aBcArray[i].getStopTime();  
294 - }  
295 - sum += iLTime; // 加午饭时间  
296 - sum += iDTime; // 加晚饭时间  
297 -  
298 - this._aBxDesc = [ // 各种班型描述(班型名称,平均工时,平均需要的班次数,平均工时)  
299 - {'sType':'六工一休', 'fHoursV':6.66, 'fBcCount': 0, 'fAverTime': 0},  
300 - {'sType':'五工一休', 'fHoursV':6.85, 'fBcCount': 0, 'fAverTime': 0},  
301 - {'sType':'四工一休', 'fHoursV':7.14, 'fBcCount': 0, 'fAverTime': 0},  
302 - {'sType':'三工一休', 'fHoursV':7.61, 'fBcCount': 0, 'fAverTime': 0},  
303 - {'sType':'二工一休', 'fHoursV':8.57, 'fBcCount': 0, 'fAverTime': 0},  
304 - {'sType':'一工一休', 'fHoursV':11.42, 'fBcCount': 0, 'fAverTime': 0},  
305 - {'sType':'五工二休', 'fHoursV':7.99, 'fBcCount': 0, 'fAverTime': 0},  
306 - {'sType':'无工休', 'fHoursV':5.43, 'fBcCount': 0, 'fAverTime': 0}  
307 - ];  
308 -  
309 - for (i = 0; i < this._aBxDesc.length; i++) {  
310 - this._aBxDesc[i].fAverTime = sum / (aBcArray.length / 2); // 平均周转时间不算进出场,例保时间  
311 -  
312 - // 计算5休2的班次数(双进出场,4个例保)  
313 - if (i == 6) {  
314 - this._aBxDesc[i].fQCount =  
315 - (this._aBxDesc[i].fHoursV * 60 - iOutTime * 2 - iInTime * 2 - iBTime * 4) /  
316 - this._aBxDesc[i].fAverTime;  
317 - this._aBxDesc[i].fBcCount = this._aBxDesc[i].fQCount * 2;  
318 - } else { // 进出场,2个例保  
319 - this._aBxDesc[i].fQCount =  
320 - (this._aBxDesc[i].fHoursV * 60 - iOutTime - iInTime - iBTime * 2) /  
321 - this._aBxDesc[i].fAverTime;  
322 - this._aBxDesc[i].fBcCount = this._aBxDesc[i].fQCount * 2;  
323 - }  
324 - }  
325 - console.log("班型描述(以下):");  
326 - console.log(this._aBxDesc);  
327 - //--------------------- 2、计算分班连班班型车辆分布数 --------------------//  
328 - this._iBx_lb_lpcount = 0; // 连班路牌数  
329 - this._iBx_5_2_fb_lpcount = 0; // 5休2分班路牌数  
330 - this._iBx_other_fb_lpcount = 0; // 其他分班路牌数  
331 -  
332 - // 总共车辆数(高峰最大车辆数)  
333 - var iCls = InternalScheduleObj_v2_2.calcuClzx(oParam);  
334 - // 计算低谷最大周转时间  
335 - var _iTroughCycleTime =  
336 - StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(true, oParam.toTimeObj("13:00"), oParam) +  
337 - StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
338 - oParam.toTimeObj("13:00"), true,  
339 - StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam)[1] +  
340 - StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(false, oParam.toTimeObj("13:00"), oParam) +  
341 - StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
342 - oParam.toTimeObj("13:00"), false,  
343 - StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam)[1];  
344 -  
345 - // 低谷最少配车(预估最少连班车数量)  
346 - var iDgminpc = Math.ceil(_iTroughCycleTime / oParam.getTroughMaxFcjx());  
347 - // 加班车路牌数(做5休2的路牌数)  
348 - var i_5_2_lpes = oParam.getJBLpes();  
349 -  
350 - // v2_2版本的路牌分布就是连班分班加班车分布,总车辆数减去加班车,剩下的车对半开连班和其他分班,但是连班必须大于最少连班  
351 - if (iCls < iDgminpc) {  
352 - alert("总配车数小于低谷最小配车");  
353 - throw "总配车数小于低谷最小配车";  
354 - } else {  
355 - // 5_2路牌数  
356 - this._iBx_5_2_fb_lpcount = i_5_2_lpes;  
357 -  
358 - // 剩余车辆数  
359 - var _iOtherCls = iCls - this._iBx_5_2_fb_lpcount;  
360 - var _iHalfCls1; // 连班路牌数  
361 - var _iHalfCls2; // 其他分班路牌数  
362 - if (_iOtherCls % 2 == 0) { // 能整除  
363 - _iHalfCls1 = _iOtherCls / 2;  
364 - _iHalfCls2 = _iOtherCls / 2;  
365 - } else {  
366 - _iHalfCls1 = Math.floor(_iOtherCls / 2) + 1;  
367 - _iHalfCls2 = Math.floor(_iOtherCls / 2);  
368 - }  
369 - if (_iHalfCls1 > iDgminpc) {  
370 - this._iBx_lb_lpcount = _iHalfCls1;  
371 - this._iBx_other_fb_lpcount = _iHalfCls2;  
372 - } else {  
373 - this._iBx_lb_lpcount = iDgminpc;  
374 - this._iBx_other_fb_lpcount = iCls - this._iBx_lb_lpcount - i_5_2_lpes;  
375 - }  
376 - }  
377 -  
378 - //------------------------ 3、利用间隔法计算连班路牌分布 --------------------//  
379 - var i;  
380 - var j;  
381 - var iC1 = Math.floor(this._internalLpArray.length / this._iBx_lb_lpcount);  
382 - var iC2 = this._internalLpArray.length % this._iBx_lb_lpcount;  
383 - var iLpIndex;  
384 -  
385 - for (i = 0; i < this._iBx_lb_lpcount - iC2; i++) {  
386 - iLpIndex = i * iC1;  
387 - this._internalLpArray[iLpIndex].setBxLb(true);  
388 - this._internalLpArray[iLpIndex].setBxDesc("连班");  
389 - }  
390 - for (j = 0; j < iC2; j++) {  
391 - iLpIndex = i * iC1 + j * (iC1 + 1);  
392 - this._internalLpArray[iLpIndex].setBxLb(true);  
393 - this._internalLpArray[iLpIndex].setBxDesc("连班");  
394 - }  
395 - //------------------------ 4、利用间隔法计算分班班型路牌分布 --------------------//  
396 - // 获取分班路牌索引  
397 - var aNotLbIndexes = [];  
398 - for (i = 0; i < this._internalLpArray.length; i++) {  
399 - if (!this._internalLpArray[i].isBxLb()) {  
400 - aNotLbIndexes.push(i);  
401 - }  
402 - }  
403 - // 先5休2分班  
404 - iC1 = Math.floor(aNotLbIndexes.length / this._iBx_5_2_fb_lpcount);  
405 - iC2 = aNotLbIndexes.length % this._iBx_5_2_fb_lpcount;  
406 -  
407 - for (i = 0; i < this._iBx_5_2_fb_lpcount - iC2; i++) {  
408 - iLpIndex = aNotLbIndexes[i * iC1];  
409 - this._internalLpArray[iLpIndex].setBxLb(false);  
410 - this._internalLpArray[iLpIndex].setBxFb(true);  
411 - this._internalLpArray[iLpIndex].setBxFb5_2(true);  
412 - this._internalLpArray[iLpIndex].setBxDesc("5休2分班");  
413 - }  
414 - for (i = 0; i < iC2; i++) {  
415 - iLpIndex = aNotLbIndexes[this._iBx_5_2_fb_lpcount - iC2 + i * (iC1 + 1)];  
416 - this._internalLpArray[iLpIndex].setBxLb(false);  
417 - this._internalLpArray[iLpIndex].setBxFb(true);  
418 - this._internalLpArray[iLpIndex].setBxFb5_2(true);  
419 - this._internalLpArray[iLpIndex].setBxDesc("5休2分班");  
420 - }  
421 - // 其他分班  
422 - for (i = 0; i < aNotLbIndexes.length; i++) {  
423 - iLpIndex = aNotLbIndexes[i];  
424 - if (!this._internalLpArray[iLpIndex].isBxFb5_2()) {  
425 - this._internalLpArray[iLpIndex].setBxLb(false);  
426 - this._internalLpArray[iLpIndex].setBxFb(true);  
427 - this._internalLpArray[iLpIndex].setBxFb5_2(false);  
428 - this._internalLpArray[iLpIndex].setBxDesc("其他分班");  
429 - }  
430 - }  
431 -  
432 - console.log("高峰周转时间:" + oParam.calcuPeakZzsj());  
433 - console.log("连班路牌数:" + this._iBx_lb_lpcount);  
434 - console.log("5休2分班路牌数:" + this._iBx_5_2_fb_lpcount);  
435 - console.log("其他分班路牌数:" + this._iBx_other_fb_lpcount);  
436 - var aLbIndexes = [];  
437 - for (i = 0; i < this._internalLpArray.length; i++) {  
438 - if (this._internalLpArray[i].isBxLb()) {  
439 - aLbIndexes.push(i);  
440 - }  
441 - }  
442 - console.log("连班路牌indexes=" + aLbIndexes);  
443 - var a_5_2_fbIndexes = [];  
444 - for (i = 0; i < this._internalLpArray.length; i++) {  
445 - if (this._internalLpArray[i].isBxFb() && this._internalLpArray[i].isBxFb5_2()) {  
446 - a_5_2_fbIndexes.push(i);  
447 - }  
448 - }  
449 - console.log("5休2分班路牌indexes=" + a_5_2_fbIndexes);  
450 - var a_other_fbIndexes = [];  
451 - for (i = 0; i < this._internalLpArray.length; i++) {  
452 - if (this._internalLpArray[i].isBxFb() && !this._internalLpArray[i].isBxFb5_2()) {  
453 - a_other_fbIndexes.push(i);  
454 - }  
455 - }  
456 - console.log("其他分班路牌indexes=" + a_other_fbIndexes);  
457 -  
458 - console.log("//->>>>>>>>>>>>>>>>> v2_3行车计划,初始化3,计算上标线第一个主站副站班次信息 <<<<<<<<<<<<<<<<<<<<<-//");  
459 - // 计算上标线第一个主站班次,副站班次的位置  
460 - this._oFirstMasterBc = undefined; // 早高峰主站方向班次  
461 - this._iFirstMasterBcGroupIndex = undefined; // 早高峰主站方向圈索引  
462 - this._iFirstMasterBcIndex = undefined; // 早高峰主站方向班次索引  
463 -  
464 - this._oFirstSlaveBc = undefined; // 早高峰副站方向班次  
465 - this._iFirstSlaveBcGroupIndex = undefined; // 早高峰副站方向圈索引  
466 - this._iFirstSlaveBcIndex = undefined; // 早高峰副站方向班次索引  
467 -  
468 - if (this._qIsUp) {  
469 - if (this._oParam.isUpOneWayStop()) {  
470 - this._oFirstMasterBc = this._internalLpArray[0].getBc(1, 0);  
471 - this._iFirstMasterBcGroupIndex = 1;  
472 - this._iFirstMasterBcIndex = 0;  
473 -  
474 - this._oFirstSlaveBc = this._internalLpArray[0].getBc(1, 1);  
475 - this._iFirstSlaveBcGroupIndex = 1;  
476 - this._iFirstSlaveBcIndex = 1;  
477 - } else {  
478 - this._oFirstMasterBc = this._internalLpArray[0].getBc(1, 1);  
479 - this._iFirstMasterBcGroupIndex = 1;  
480 - this._iFirstMasterBcIndex = 1;  
481 -  
482 - this._oFirstSlaveBc = this._internalLpArray[0].getBc(1, 0);  
483 - this._iFirstSlaveBcGroupIndex = 1;  
484 - this._iFirstSlaveBcIndex = 0;  
485 - }  
486 - } else {  
487 - if (this._oParam.isUpOneWayStop()) {  
488 - this._oFirstMasterBc = this._internalLpArray[0].getBc(1, 1);  
489 - this._iFirstMasterBcGroupIndex = 1;  
490 - this._iFirstMasterBcIndex = 1;  
491 -  
492 - this._oFirstSlaveBc = this._internalLpArray[0].getBc(1, 0);  
493 - this._iFirstSlaveBcGroupIndex = 1;  
494 - this._iFirstSlaveBcIndex = 0;  
495 - } else {  
496 - this._oFirstMasterBc = this._internalLpArray[0].getBc(1, 0);  
497 - this._iFirstMasterBcGroupIndex = 1;  
498 - this._iFirstMasterBcIndex = 0;  
499 -  
500 - this._oFirstSlaveBc = this._internalLpArray[0].getBc(1, 1);  
501 - this._iFirstSlaveBcGroupIndex = 1;  
502 - this._iFirstSlaveBcIndex = 1;  
503 - }  
504 - }  
505 -  
506 - console.log("早高峰副站方向(start)班次=" + (this._oFirstSlaveBc ? this._oFirstSlaveBc.getFcTimeObj().format("HH:mm") : "未找到"));  
507 - console.log("早高峰副站方向(start)班次圈索引=" + (this._oFirstSlaveBc ? this._iFirstSlaveBcGroupIndex : "未找到"));  
508 - console.log("早高峰副站方向(start)班次索引=" + (this._oFirstSlaveBc ? this._iFirstSlaveBcIndex : "未找到"));  
509 - console.log("早高峰主站方向(start)班次=" + (this._oFirstMasterBc ? this._oFirstMasterBc.getFcTimeObj().format("HH:mm") : "未找到"));  
510 - console.log("早高峰主站方向(start)班次圈索引=" + (this._oFirstMasterBc ? this._iFirstMasterBcGroupIndex : "未找到"));  
511 - console.log("早高峰主站方向(start)班次索引=" + (this._oFirstMasterBc ? this._iFirstMasterBcIndex : "未找到"));  
512 -  
513 - console.log("//->>>>>>>>>>>>>>>>> v2_4行车计划,初始化4,从上标线第一圈第一个副站班次开始初始化后续路牌班次列表 <<<<<<<<<<<<<<<<<<<<<-//");  
514 - // 初始化上标线副站班次  
515 - var oPreBc; // 上一个班次(从上标线副站班次开始)  
516 - var oNextBc; // 计算的下一个班次  
517 - var oNextBcFcTime; // 下一个班次的发车时间  
518 - var aBcInterval = []; // 班次间隔数组  
519 - var oBcInterval; // 班次间隔对象  
520 - var iNextBcInterval; // 下一个班次发车间隔  
521 -  
522 - // 当初始化完一圈的副站班次后,最后一个班次是下一圈的上标线副站班次(一圈的周转结束班次),需要调整时间及其前一个主站班次的时间  
523 - var _modifyTimeNextGroupIndex; // 上标线下一圈索引  
524 - var _modifyTimeNextBcIndex; // 上标线下一圈班次索引  
525 - var _modifyBc; // 上标线下一个圈的班次  
526 - var _modifyPreBc; // 上标线下一个圈班次的前一个班次  
527 - var _modifyTime; // 上标线下一个圈班次的前一个班次的调整时间  
528 -  
529 - if (this._iFirstSlaveBcIndex == 0) { // 第一圈第二个班次是主站,则第一个班次是副站  
530 - oPreBc = this._internalLpArray[0].getBc(this._iFirstSlaveBcGroupIndex, this._iFirstSlaveBcIndex);  
531 -  
532 - aBcInterval = StrategyUtils_v2_2.sFn("CALCU_HEADWAY_2")(  
533 - this,  
534 - this._oParam,  
535 - 1,  
536 - this._iFirstSlaveBcIndex,  
537 - this._$calcuCycleTime(oPreBc.getFcTimeObj())[0],  
538 - this._$calcuCycleTime(oPreBc.getFcTimeObj())[1]  
539 - );  
540 -  
541 - for (i = 1; i < this._internalLpArray.length; i++) {  
542 - oBcInterval = aBcInterval[i - 1];  
543 -  
544 - if (oBcInterval.hasBc) {  
545 - // 参考的发车间隔  
546 - iNextBcInterval = oBcInterval.iFcInterval;  
547 - oNextBcFcTime = this._oParam.addMinute(oPreBc.getFcTimeObj(), iNextBcInterval);  
548 - this._internalLpArray[i].fnSetVerticalIntervalTime(  
549 - this._iFirstSlaveBcGroupIndex, this._iFirstSlaveBcIndex, iNextBcInterval);  
550 - this._internalLpArray[i].fnSetHeadwayS2_P(  
551 - this._iFirstSlaveBcGroupIndex, this._iFirstSlaveBcIndex, oBcInterval.fP);  
552 -  
553 - oNextBc = _utils.createBcObj(  
554 - this._internalLpArray[i],  
555 - "normal",  
556 - !this._oParam.isUpOneWayStop(),  
557 - 1,  
558 - oNextBcFcTime,  
559 - this._oParam);  
560 -  
561 - this._internalLpArray[i].setBc(  
562 - this._iFirstSlaveBcGroupIndex, this._iFirstSlaveBcIndex, oNextBc);  
563 -  
564 - oPreBc = oNextBc;  
565 - }  
566 - }  
567 -  
568 - // // 修正上标线副站方向班次(一圈的结束班次,也是下一圈的开始班次)以及后续所有班次  
569 - iNextBcInterval = aBcInterval[i - 1].iFcInterval;  
570 - _modifyTimeNextGroupIndex = this._iFirstSlaveBcGroupIndex + 1;  
571 - _modifyTimeNextBcIndex = this._iFirstSlaveBcIndex;  
572 -  
573 - _utils.modifySBXMasterBc(  
574 - this._internalLpArray[0],  
575 - this._oParam.addMinute(oPreBc.getFcTimeObj(), iNextBcInterval),  
576 - this._iFirstSlaveBcGroupIndex + 1,  
577 - this._iFirstSlaveBcIndex,  
578 - oPreBc.isUp(),  
579 - this._oParam  
580 - );  
581 -  
582 - // 调整上标线副站班次一圈后的前一个主站班次时间  
583 - _modifyBc = this._internalLpArray[0].getBc(_modifyTimeNextGroupIndex, _modifyTimeNextBcIndex);  
584 - if (_modifyBc) {  
585 - this._internalLpArray[0].fnSetVerticalIntervalTime(_modifyTimeNextGroupIndex, _modifyTimeNextBcIndex, iNextBcInterval);  
586 -  
587 - _modifyPreBc = this._internalLpArray[0].getPreBc(_modifyBc);  
588 - _modifyTime = _modifyBc.getFcTimeObj().diff(_modifyPreBc.getArrTimeObj(), "m") - 1; // 主站到副站停站使用1分钟  
589 - // 修改发车时间,到达时间,不改行驶时间  
590 - _modifyPreBc.getFcTimeObj().add(_modifyTime, "m");  
591 - _modifyPreBc.getArrTimeObj().add(_modifyTime, "m");  
592 -  
593 - }  
594 -  
595 - }  
596 -  
597 - console.log("//->>>>>>>>>>>>>>>>> v2_6行车计划,初始化6,创建第一圈的主站班次开始班次列表,然后修正 <<<<<<<<<<<<<<<<<<<<<-//");  
598 - this.fnCreateBclistWithMasterBc(1, 1); // 从上标线第一圈的主站班次开始初始化所有路牌的相关班次  
599 - // 第一圈的第一个班次是副站,则需要修正this.fnCreateBclistWithMasterBc(1)班次之间的问题,停站时间为负数  
600 - if (this._iFirstSlaveBcIndex == 0) {  
601 - StrategyUtils_v2_2.sFn("ADJUST_HEADWAY")(  
602 - this, this._oParam,  
603 - this._iFirstSlaveBcGroupIndex, this._iFirstSlaveBcIndex,  
604 - this._iFirstMasterBcGroupIndex, this._iFirstMasterBcIndex,  
605 - 5 // 修正至少要5分钟停站  
606 - );  
607 - }  
608 -  
609 - console.log("//->>>>>>>>>>>>>>>>> v2_7行车计划,初始化7,修正中标线班次列表 <<<<<<<<<<<<<<<<<<<<<-//");  
610 - // // TODO:补充中标线班次,这里假设,前一半圈就是中标线,以后再精细处理  
611 - // // 中标线开始时间,早的首班车时间,和上标线的开始时间方向相反  
612 - // var oSt = !this._qIsUp ? this._oParam.getUpFirstDTimeObj() : this._oParam.getDownFirstDTimeObj();  
613 - // var iStRuntime; // 中标线方向班次行驶时间(使用低谷)  
614 - // if (!this._qIsUp) { // 上行  
615 - // if (this._oParam.isTroughBc(oSt)) {  
616 - // iStRuntime = this._oParam.getUpTroughTime();  
617 - // } else {  
618 - // iStRuntime = this._oParam.getUpMPeakTime();  
619 - // }  
620 - // } else { // 下行  
621 - // if (this._oParam.isTroughBc(oSt)) {  
622 - // iStRuntime = this._oParam.getDownTroughTime();  
623 - // } else {  
624 - // iStRuntime = this._oParam.getDownMPeakTime();  
625 - // }  
626 - // }  
627 - //  
628 - // var oSLp;  
629 - // var oSBc;  
630 - // var oSEmuBcFcTime; // 模拟班次发车时间  
631 - // var iTimeDiff;  
632 - // var iTempTime;  
633 - // var iSModifyLpIndex; // 中标线对应路牌索引  
634 - // for (i = 1; i < this._internalLpArray.length; i++) {  
635 - // oSLp = this._internalLpArray[i];  
636 - // oSBc = oSLp.getBc(1, 0); // 第一圈第一个班次  
637 - // if (!oSBc) { // 可能没有,跳过  
638 - // continue;  
639 - // }  
640 - // oSEmuBcFcTime = this._oParam.addMinute(  
641 - // oSBc.getFcTimeObj(),  
642 - // -(iStRuntime + 1)  
643 - // );  
644 - // iTempTime = oSEmuBcFcTime.diff(oSt, "m");  
645 - // if (iTimeDiff == undefined) {  
646 - // iTimeDiff = iTempTime;  
647 - // iSModifyLpIndex = i;  
648 - // } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff) && oSEmuBcFcTime.isAfter(oSt)) {  
649 - // iTimeDiff = iTempTime;  
650 - // iSModifyLpIndex = i;  
651 - // }  
652 - // }  
653 - //  
654 - // // 添加上标线头班次(分班连班都可能)  
655 - // this._internalLpArray[iSModifyLpIndex].setBc(  
656 - // 0, 1,  
657 - // _utils.createBcObj(  
658 - // this._internalLpArray[iSModifyLpIndex],  
659 - // "normal",  
660 - // !this._qIsUp,  
661 - // 1,  
662 - // oSt,  
663 - // this._oParam)  
664 - // );  
665 - //  
666 - // // 从当前班次开始,如果是低谷,隔开方向加班次,如果是高峰,都加班次  
667 - // var iSInverval = Math.ceil((this._oParam.getMPeakMinFcjx() + this._oParam.getMPeakMaxFcjx()) / 2);  
668 - // for (i = iSModifyLpIndex + 1; i < this._internalLpArray.length; i++) {  
669 - // oSLp = this._internalLpArray[i];  
670 - // oSEmuBcFcTime = this._oParam.addMinute(oSt, iSInverval * (i - iSModifyLpIndex));  
671 - // if (this._oParam.isMPeakBc(oSEmuBcFcTime)) { // 高峰  
672 - // if (!this._qIsUp) { // 上行  
673 - // iStRuntime = this._oParam.getUpMPeakTime();  
674 - // } else { // 下行  
675 - // iStRuntime = this._oParam.getDownMPeakTime();  
676 - // }  
677 - // oSBc = oSLp.getBc(1, 0); // 第一圈第一个班次  
678 - // oSLp.setBc(  
679 - // 0, 1,  
680 - // _utils.createBcObj(  
681 - // oSLp,  
682 - // "normal",  
683 - // !this._qIsUp,  
684 - // 1,  
685 - // this._oParam.addMinute(oSBc.getFcTimeObj(), -(iStRuntime + 1)),  
686 - // this._oParam)  
687 - // );  
688 - // } else { // 低谷隔开出班次  
689 - // if (!this._qIsUp) { // 上行  
690 - // iStRuntime = this._oParam.getUpTroughTime();  
691 - // } else { // 下行  
692 - // iStRuntime = this._oParam.getDownTroughTime();  
693 - // }  
694 - //  
695 - // if (!this._internalLpArray[i - 1].getBc(0, 1)) {  
696 - // // 上一个路牌没有班次,添加  
697 - // oSBc = oSLp.getBc(1, 0); // 第一圈第一个班次  
698 - // if (oSBc) {  
699 - // oSLp.setBc(  
700 - // 0, 1,  
701 - // _utils.createBcObj(  
702 - // oSLp,  
703 - // "normal",  
704 - // !this._qIsUp,  
705 - // 1,  
706 - // this._oParam.addMinute(oSBc.getFcTimeObj(), -(iStRuntime + 1)),  
707 - // this._oParam)  
708 - // );  
709 - //  
710 - // // 如果生成的班次行驶时间不足,删除这个班次  
711 - // if (oSLp.getBc(1, 0).getFcTimeObj().isBefore(oSLp.getBc(0, 1).getArrTimeObj())) {  
712 - // oSLp.getGroup(0).setBc1(undefined);  
713 - // oSLp.getGroup(0).setBc2(undefined);  
714 - // }  
715 - // }  
716 - // }  
717 - // }  
718 - // }  
719 - //  
720 - // console.log("中标线路牌索引=" + iSModifyLpIndex);  
721 -  
722 -  
723 - }  
724 -  
725 - //------------------------- 核心业务方法 -----------------------//  
726 -  
727 - /**  
728 - * 核心方法,从上标线主站班次开始,一圈一圈生成每圈的主站班次,  
729 - * 每生成一个主站班次,尝试生成后面紧邻的副站班次(停站时间1到3分种调整)。  
730 - * @param iGroupIndex 圈索引  
731 - * @param iCount 共几圈  
732 - */  
733 - InternalScheduleObj.prototype.fnCreateBclistWithMasterBc = function(iGroupIndex, iCount) {  
734 - var i;  
735 - var j;  
736 - // var oPreBc = this._oFirstMasterBc; // 上一个班次(从上标线主站班次开始)  
737 - var oPreBc = this._internalLpArray[0].getBc(iGroupIndex, this._iFirstMasterBcIndex);  
738 - var oNextBc; // 计算的下一个班次  
739 - var oNextBcFcTime; // 下一个班次的发车时间  
740 - var aBcInterval = []; // 班次间隔数组  
741 - var oBcInterval; // 班次间隔对象  
742 - var iNextBcInterval; // 下一个班次发车间隔  
743 -  
744 - var oPreSlaveBc; // 上一个副站班次(上标线主站后的一个副站班次)  
745 - var oNextSlaveBc; // 下一个副站班次  
746 -  
747 - // 当初始化完一圈的主站班次后,最后一个班次是下一圈的上标线主站班次,需要判定存在然后添加间隔  
748 - var _modifyTimeNextGroupIndex; // 上标线下一圈索引  
749 - var _modifyTimeNextBcIndex; // 上标线下一圈班次索引  
750 - var _modifyBc; // 上标线下一个圈的班次  
751 -  
752 - var iStart = iGroupIndex;  
753 - var iEnd = iGroupIndex + iCount;  
754 - if (iEnd > this._qCount) {  
755 - iEnd = this._qCount;  
756 - }  
757 -  
758 - for (i = iStart; i < iEnd; i++) {  
759 - aBcInterval = StrategyUtils_v2_2.sFn("CALCU_HEADWAY_2")(  
760 - this,  
761 - this._oParam,  
762 - i,  
763 - this._iFirstMasterBcIndex,  
764 - this._$calcuCycleTime(oPreBc.getFcTimeObj())[0],  
765 - this._$calcuCycleTime(oPreBc.getFcTimeObj())[1]  
766 - );  
767 -  
768 - if (aBcInterval.length == 0) {  
769 - // 等于0说明上标线没班次了  
770 - break;  
771 - }  
772 -  
773 - for (j = 1; j < this._internalLpArray.length; j++) {  
774 - oBcInterval = aBcInterval[j - 1];  
775 - if (oBcInterval.hasBc) {  
776 - iNextBcInterval = oBcInterval.iFcInterval;  
777 - oNextBcFcTime = this._oParam.addMinute(oPreBc.getFcTimeObj(), iNextBcInterval);  
778 - this._internalLpArray[j].fnSetVerticalIntervalTime(i, this._iFirstMasterBcIndex, iNextBcInterval);  
779 - this._internalLpArray[j].fnSetHeadwayS2_P(i, this._iFirstMasterBcIndex, oBcInterval.fP);  
780 -  
781 - oNextBc = _utils.createBcObj(  
782 - this._internalLpArray[j],  
783 - "normal",  
784 - this._oParam.isUpOneWayStop(),  
785 - 1,  
786 - oNextBcFcTime,  
787 - this._oParam);  
788 -  
789 - this._internalLpArray[j].setBc(  
790 - i, this._iFirstMasterBcIndex, oNextBc);  
791 - oPreBc = oNextBc;  
792 - }  
793 - }  
794 -  
795 - // 修正上标线主站方向班次(一圈的结束班次,也是下一圈的开始班次)以及后续所有班次  
796 - oBcInterval = aBcInterval[j - 1];  
797 - if (oBcInterval.hasBc) {  
798 - iNextBcInterval = oBcInterval.iFcInterval;  
799 - _modifyTimeNextGroupIndex = i + 1;  
800 - _modifyTimeNextBcIndex = this._iFirstMasterBcIndex;  
801 -  
802 - _utils.modifySBXMasterBc(  
803 - this._internalLpArray[0],  
804 - this._oParam.addMinute(oPreBc.getFcTimeObj(), iNextBcInterval),  
805 - _modifyTimeNextGroupIndex,  
806 - _modifyTimeNextBcIndex,  
807 - oPreBc.isUp(),  
808 - this._oParam  
809 - );  
810 -  
811 - // 修正上标线主站方向的班次后,一圈结束的班次可能不存在(超过末班车时间了),需要判定  
812 - _modifyBc = this._internalLpArray[0].getBc(_modifyTimeNextGroupIndex, _modifyTimeNextBcIndex);  
813 - if (_modifyBc) { // 存在修正间隔值  
814 - this._internalLpArray[0].fnSetVerticalIntervalTime(  
815 - _modifyTimeNextGroupIndex, _modifyTimeNextBcIndex, iNextBcInterval);  
816 - oPreBc = _modifyBc;  
817 - }  
818 -  
819 - }  
820 -  
821 - // 添加副站班次,就是主站班次到达时间加1分钟  
822 - // TODO:因为副站停站时间1分钟到3分钟,几乎没有停站时间,一般前面主站是多少间隔,后面如果有副站的话也是多少间隔  
823 - // TODO:此时,可能出现临界问题,当主站还是高峰接近低谷时,副站已经是低谷,此时副站发车间隔还是高峰间隔  
824 - // TODO:上述情况可以通过让临界的主站高峰班次使用高峰最大间隔,副站使用3分钟的最大停站使副站间隔达到低谷最小间隔  
825 - oPreSlaveBc = this._internalLpArray[0].getBc(  
826 - this._iFirstMasterBcIndex == 0 ? i : i + 1,  
827 - this._iFirstMasterBcIndex == 0 ? 1 : 0  
828 - );  
829 - for (j = 1; j < this._internalLpArray.length; j++) {  
830 - if (oPreSlaveBc) {  
831 - if (aBcInterval[j - 1].hasBc) { // 有主站必有副站  
832 - // 获取当前路牌前一个主站班次  
833 - if (this._internalLpArray[j].getBc(  
834 - i,  
835 - this._iFirstMasterBcIndex)) { // 相同路牌上一个主站班次存在  
836 - oNextSlaveBc = _utils.createBcObj(  
837 - this._internalLpArray[j],  
838 - "normal",  
839 - !this._oParam.isUpOneWayStop(),  
840 - 1,  
841 - this._oParam.addMinute( // 使用1分钟副站停站  
842 - this._internalLpArray[j].getBc(  
843 - i, this._iFirstMasterBcIndex).getArrTimeObj(),  
844 - 1),  
845 - this._oParam);  
846 -  
847 - if (oNextSlaveBc.isUp()) {  
848 - if (!oNextSlaveBc.getFcTimeObj().isAfter(this._oParam.getUpLastDtimeObj())) {  
849 - this._internalLpArray[j].setBc(  
850 - this._iFirstMasterBcIndex == 0 ? i : i + 1,  
851 - this._iFirstMasterBcIndex == 0 ? 1 : 0,  
852 - oNextSlaveBc);  
853 - oPreSlaveBc = oNextSlaveBc;  
854 - }  
855 - } else {  
856 - if (!oPreSlaveBc.getFcTimeObj().isAfter(this._oParam.getDownLastDTimeObj())) {  
857 - this._internalLpArray[j].setBc(  
858 - this._iFirstMasterBcIndex == 0 ? i : i + 1,  
859 - this._iFirstMasterBcIndex == 0 ? 1 : 0,  
860 - oNextSlaveBc);  
861 - oPreSlaveBc = oNextSlaveBc;  
862 - }  
863 - }  
864 - }  
865 - }  
866 - }  
867 - }  
868 -  
869 -  
870 - }  
871 -  
872 - };  
873 -  
874 - //------------- 其他业务方法 -------------//  
875 -  
876 - /**  
877 - * 调整发车间隔。  
878 - */  
879 - InternalScheduleObj.prototype.fnAdjustHeadway = function() {  
880 - // TODO:572测试,尝试调整第6圈  
881 - StrategyUtils_v2_2.sFn("ADJUST_HEADWAY_2")(  
882 - this, this._oParam,  
883 - 6, 0,  
884 - 6, 1,  
885 - 0.2  
886 - );  
887 - // TODO:843测试  
888 -  
889 -  
890 - };  
891 -  
892 - /**  
893 - * 计算吃饭班次。  
894 - */  
895 - InternalScheduleObj.prototype.fnCalcuEatBc = function() {  
896 - var i;  
897 - var j;  
898 - var oLp;  
899 - var oBc;  
900 - // 1、标记吃饭班次  
901 - var oEatFlag = {}; // {"路牌编号":{isLaunch: false, isDinner: false},...}  
902 - for (i = 0; i < this._internalLpArray.length; i++) {  
903 - oLp = this._internalLpArray[i];  
904 - if (oLp.isBxLb()) { // 暂时判定只有连班吃饭  
905 - oEatFlag[oLp.getLpNo()] = {};  
906 - oEatFlag[oLp.getLpNo()]["isLaunch"] = false;  
907 - oEatFlag[oLp.getLpNo()]["isDinner"] = false;  
908 - for (j = 0; j < oLp.getBcArray().length; j++) {  
909 - oBc = oLp.getBcArray()[j];  
910 - // 午饭,暂时判定10:30到13:00  
911 - if (oBc.isUp() == this._oParam.isUpOneWayStop() &&  
912 - oBc.getFcTimeObj().isAfter(this._oParam.toTimeObj("10:30")) &&  
913 - oBc.getFcTimeObj().isBefore(this._oParam.toTimeObj("13:30"))) {  
914 - if (!oEatFlag[oLp.getLpNo()]["isLaunch"]) {  
915 - oBc.fnSetEatTime(this._oParam.fnGetLunchTime());  
916 - oEatFlag[oLp.getLpNo()]["isLaunch"] = true;  
917 - // console.log("吃饭班次时间=" + oBc.format("HH:mm"));  
918 - }  
919 - }  
920 - // 晚饭,暂时判定17:30  
921 - if (oBc.isUp() == this._oParam.isUpOneWayStop() &&  
922 - oBc.getFcTimeObj().isAfter(this._oParam.toTimeObj("17:00")) &&  
923 - oBc.getFcTimeObj().isBefore(this._oParam.toTimeObj("20:00"))) {  
924 - if (!oEatFlag[oLp.getLpNo()]["isDinner"]) {  
925 - oBc.fnSetEatTime(this._oParam.fnGetDinnerTime());  
926 - oEatFlag[oLp.getLpNo()]["isDinner"] = true;  
927 - // console.log("晚饭班次时间=" + oBc.format("HH:mm"));  
928 - }  
929 - }  
930 - }  
931 - }  
932 - }  
933 -  
934 - // 2、调整吃饭需停站时间  
935 - StrategyUtils_v2_2.sFn("ADJUST_HEADWAY_3_EAT")(  
936 - this, this._oParam  
937 - );  
938 - };  
939 -  
940 - /**  
941 - * 计算末班车。  
942 - * 1、将上下行拉成上下行两个班次列表(包括标记班次)  
943 - * 2、分别找出离末班车发车时间最近的班次,并替换时间  
944 - * 3、删除之后的班次  
945 - */  
946 - InternalScheduleObj.prototype.fnCalcuLastBc = function() {  
947 - var i;  
948 - var iTimeDiff;  
949 - var iTempTime;  
950 - var aBc;  
951 - var oLastBcTime;  
952 - var oLastBcIsUp;  
953 - var iModifyIndex;  
954 -  
955 - // 查找末班车早的末班车时间和方向  
956 - if (this._oParam.getUpLastDtimeObj().isBefore(this._oParam.getDownLastDTimeObj())) {  
957 - oLastBcTime = this._oParam.getUpLastDtimeObj();  
958 - oLastBcIsUp = true;  
959 - } else {  
960 - oLastBcTime = this._oParam.getDownLastDTimeObj();  
961 - oLastBcIsUp = false;  
962 - }  
963 -  
964 - // 确定早的末班车时间  
965 - aBc = this.fnGetBcList(oLastBcIsUp);  
966 - for (i = 0; i < aBc.length; i++) {  
967 - iTempTime = oLastBcTime.diff(aBc[i].getFcTimeObj(), "m");  
968 - if (iTimeDiff == undefined) {  
969 - iTimeDiff = iTempTime;  
970 - iModifyIndex = i;  
971 - } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff)) {  
972 - iTimeDiff = iTempTime;  
973 - iModifyIndex = i;  
974 - }  
975 - }  
976 - aBc[iModifyIndex].addMinuteToFcsj(iTimeDiff); // 替换成末班车时间  
977 - aBc[iModifyIndex].fnSetDelFlag(false);  
978 - aBc[iModifyIndex].fnSetIsLastBc(true);  
979 - for (i = iModifyIndex + 1; i < aBc.length; i++) { // 删除多余班次  
980 - this._qIsUp == oLastBcIsUp ?  
981 - aBc[i]._$$_internal_group_obj.setBc1(undefined) :  
982 - aBc[i]._$$_internal_group_obj.setBc2(undefined);  
983 - }  
984 -  
985 - // 查找末班车晚的末班车时间和方向  
986 - if (this._oParam.getUpLastDtimeObj().isBefore(this._oParam.getDownLastDTimeObj())) {  
987 - oLastBcTime = this._oParam.getDownLastDTimeObj();  
988 - oLastBcIsUp = false;  
989 - } else {  
990 - oLastBcTime = this._oParam.getUpLastDtimeObj();  
991 - oLastBcIsUp = true;  
992 - }  
993 - // 确定晚的末班车时间  
994 - aBc = this.fnGetBcList(oLastBcIsUp);  
995 - var oBc;  
996 - var aBcIndex;  
997 - var iLpIndex;  
998 - var iQIndex;  
999 - var iBcIndex;  
1000 -  
1001 - iTimeDiff = undefined;  
1002 - for (i = 0; i < aBc.length; i++) {  
1003 - oBc = aBc[i];  
1004 - aBcIndex = this.fnGetBcIndex(oBc);  
1005 -  
1006 - iLpIndex = aBcIndex[0];  
1007 - iQIndex = aBcIndex[2] == 0 ? aBcIndex[1] -1 : aBcIndex[1];  
1008 - iBcIndex = aBcIndex[2] == 0 ? 1 : 0;  
1009 -  
1010 - if (!this._internalLpArray[iLpIndex].getBc(iQIndex, iBcIndex)) {  
1011 - continue;  
1012 - }  
1013 -  
1014 - iTempTime = oLastBcTime.diff(aBc[i].getFcTimeObj(), "m");  
1015 - if (iTimeDiff == undefined) {  
1016 - iTimeDiff = iTempTime;  
1017 - iModifyIndex = i;  
1018 - } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff)) {  
1019 - iTimeDiff = iTempTime;  
1020 - iModifyIndex = i;  
1021 - }  
1022 - }  
1023 - aBc[iModifyIndex].addMinuteToFcsj(iTimeDiff); // 替换成末班车时间  
1024 - aBc[iModifyIndex].fnSetDelFlag(false);  
1025 - aBc[iModifyIndex].fnSetIsLastBc(true);  
1026 - for (i = iModifyIndex + 1; i < aBc.length; i++) { // 删除多余班次  
1027 - this._qIsUp == oLastBcIsUp ?  
1028 - aBc[i]._$$_internal_group_obj.setBc1(undefined) :  
1029 - aBc[i]._$$_internal_group_obj.setBc2(undefined);  
1030 - }  
1031 - };  
1032 -  
1033 - /**  
1034 - * 重新设置停站时间(发车时间减到达时间)。  
1035 - */  
1036 - InternalScheduleObj.prototype.fnReSetLayoverTime = function() {  
1037 - for (var i = 0; i < this._internalLpArray.length; i++) {  
1038 - this._internalLpArray[i].modifyLayoverTimeWithoutFcTime();  
1039 - }  
1040 - };  
1041 -  
1042 - /**  
1043 - * 补进出场例保班次。  
1044 - */  
1045 - InternalScheduleObj.prototype.fnCalcuOtherBc = function() {  
1046 - var i;  
1047 - var j;  
1048 - var iBcChainCount;  
1049 - var oLp;  
1050 - var aOtherBc;  
1051 - var oStartBc;  
1052 - var oEndBc;  
1053 -  
1054 - for (i = 0; i < this._internalLpArray.length; i++) {  
1055 - aOtherBc = [];  
1056 - oLp = this._internalLpArray[i];  
1057 - iBcChainCount = oLp.fnGetBcChainCount();  
1058 -  
1059 - if (iBcChainCount == 1) { // 只有一个车次链,是连班班型  
1060 - // 头部要添加出场,例保班次  
1061 - oStartBc = oLp.getBc(  
1062 - oLp.fnGetBcChainInfo(0)["s_q"],  
1063 - oLp.fnGetBcChainInfo(0)["s_b"]  
1064 - );  
1065 - aOtherBc.push(_utils.createBcObj(  
1066 - oLp, "bd", oStartBc.isUp(), 1,  
1067 - oStartBc.getFcTimeObj(),  
1068 - this._oParam  
1069 - ));  
1070 - aOtherBc.push(_utils.createBcObj(  
1071 - oLp, "out", oStartBc.isUp(), 1,  
1072 - oStartBc.getFcTimeObj(),  
1073 - this._oParam  
1074 - ));  
1075 -  
1076 - // 尾部需添加进场,例保班次  
1077 - oEndBc = oLp.getBc(  
1078 - oLp.fnGetBcChainInfo(0)["e_q"],  
1079 - oLp.fnGetBcChainInfo(0)["e_b"]  
1080 - );  
1081 - oEndBc.fnSetIsLastBc(false); // 有可能最后一个班次是吃饭班次,重置  
1082 - oEndBc.fnSetEatTime(0); // 有可能最后一个班次是吃饭班次,重置  
1083 - aOtherBc.push(_utils.createBcObj(  
1084 - oLp, "in", !oEndBc.isUp(), 1,  
1085 - oEndBc.getArrTimeObj(),  
1086 - this._oParam  
1087 - ));  
1088 - aOtherBc.push(_utils.createBcObj(  
1089 - oLp, "lc", !oEndBc.isUp(), 1,  
1090 - oEndBc.getArrTimeObj(),  
1091 - this._oParam  
1092 - ));  
1093 - } else if (iBcChainCount == 2) { // 两个车次链,是分班班型  
1094 - // 第一个车次链开头有出场,报到班次,车次链结尾只有进场班次  
1095 - oStartBc = oLp.getBc(  
1096 - oLp.fnGetBcChainInfo(0)["s_q"],  
1097 - oLp.fnGetBcChainInfo(0)["s_b"]  
1098 - );  
1099 - aOtherBc.push(_utils.createBcObj(  
1100 - oLp, "bd", oStartBc.isUp(), 1,  
1101 - oStartBc.getFcTimeObj(),  
1102 - this._oParam  
1103 - ));  
1104 - aOtherBc.push(_utils.createBcObj(  
1105 - oLp, "out", oStartBc.isUp(), 1,  
1106 - oStartBc.getFcTimeObj(),  
1107 - this._oParam  
1108 - ));  
1109 -  
1110 - oEndBc = oLp.getBc(  
1111 - oLp.fnGetBcChainInfo(0)["e_q"],  
1112 - oLp.fnGetBcChainInfo(0)["e_b"]  
1113 - );  
1114 - aOtherBc.push(_utils.createBcObj(  
1115 - oLp, "in", !oEndBc.isUp(), 1,  
1116 - oEndBc.getArrTimeObj(),  
1117 - this._oParam  
1118 - ));  
1119 -  
1120 - // 第二个车次链开头有出场,报到班次,车次链结尾有进场,报到班次  
1121 - oStartBc = oLp.getBc(  
1122 - oLp.fnGetBcChainInfo(1)["s_q"],  
1123 - oLp.fnGetBcChainInfo(1)["s_b"]  
1124 - );  
1125 - aOtherBc.push(_utils.createBcObj(  
1126 - oLp, "bd", oStartBc.isUp(), 1,  
1127 - oStartBc.getFcTimeObj(),  
1128 - this._oParam  
1129 - ));  
1130 - aOtherBc.push(_utils.createBcObj(  
1131 - oLp, "out", oStartBc.isUp(), 1,  
1132 - oStartBc.getFcTimeObj(),  
1133 - this._oParam  
1134 - ));  
1135 -  
1136 - oEndBc = oLp.getBc(  
1137 - oLp.fnGetBcChainInfo(1)["e_q"],  
1138 - oLp.fnGetBcChainInfo(1)["e_b"]  
1139 - );  
1140 - aOtherBc.push(_utils.createBcObj(  
1141 - oLp, "in", !oEndBc.isUp(), 1,  
1142 - oEndBc.getArrTimeObj(),  
1143 - this._oParam  
1144 - ));  
1145 - aOtherBc.push(_utils.createBcObj(  
1146 - oLp, "lc", !oEndBc.isUp(), 1,  
1147 - oEndBc.getArrTimeObj(),  
1148 - this._oParam  
1149 - ));  
1150 -  
1151 -  
1152 - } else {  
1153 - // 2个车次链以上,暂时没有此班型  
1154 - }  
1155 -  
1156 - oLp.addOtherBcArray(aOtherBc);  
1157 - }  
1158 - };  
1159 -  
1160 -  
1161 - //------------- 其他非业务方法方法 -------------//  
1162 - /**  
1163 - * 获取班次列表。  
1164 - * @param isUp boolean 是否上行  
1165 - * @returns [(InternalBcObj)]  
1166 - */  
1167 - InternalScheduleObj.prototype.fnGetBcList = function(isUp) {  
1168 - var i;  
1169 - var j;  
1170 - var oLp;  
1171 - var oBc;  
1172 - var aBc = [];  
1173 -  
1174 - for (j = 0; j < this._qCount; j++) {  
1175 - for (i = 0; i < this._internalLpArray.length; i++) {  
1176 - oLp = this._internalLpArray[i];  
1177 - oBc = oLp.getBc(  
1178 - j,  
1179 - this._qIsUp == isUp ? 0 : 1  
1180 - );  
1181 - if (oBc) {  
1182 - aBc.push(oBc);  
1183 - }  
1184 - }  
1185 - }  
1186 -  
1187 - var aBcFcTime = [];  
1188 - for (i = 0; i < aBc.length; i++) {  
1189 - oBc = aBc[i];  
1190 - aBcFcTime.push(oBc.getFcTimeObj().format("HH:mm"));  
1191 - }  
1192 - console.log((isUp ? "上行班次列表:" : "下行班次列表:") + aBcFcTime.join(","));  
1193 -  
1194 - return aBc;  
1195 - };  
1196 -  
1197 - /**  
1198 - * 获取班次索引。  
1199 - * @param oBc 班次对象  
1200 - * @returns [{路牌索引},{圈索引},{班次索引}]  
1201 - */  
1202 - InternalScheduleObj.prototype.fnGetBcIndex = function(oBc) {  
1203 - // 路牌索引  
1204 - var i;  
1205 - var iLpIndex;  
1206 - for (i = 0; i < this._internalLpArray.length; i++) {  
1207 - if (this._internalLpArray[i]._$$_orign_lp_obj == oBc._$$_internal_lp_obj._$$_orign_lp_obj) {  
1208 - iLpIndex = i;  
1209 - break;  
1210 - }  
1211 - }  
1212 - // 圈索引  
1213 - var j;  
1214 - var iGroupIndex;  
1215 - var bFlag = false;  
1216 - for (i = 0; i < this._internalLpArray.length; i++) {  
1217 - if (bFlag) {  
1218 - break;  
1219 - }  
1220 - for (j = 0; j < this._qCount; j++) {  
1221 - if (this._internalLpArray[i]._$_groupBcArray[j] == oBc._$$_internal_group_obj) {  
1222 - iGroupIndex = j;  
1223 - bFlag = true;  
1224 - break;  
1225 - }  
1226 - }  
1227 - }  
1228 - // 班次索引  
1229 - var iBcIndex = this._qIsUp == oBc.isUp() ? 0 : 1;  
1230 -  
1231 - if (iLpIndex == undefined) {  
1232 - return null;  
1233 - } else {  
1234 - return [].concat(iLpIndex, iGroupIndex, iBcIndex);  
1235 - }  
1236 - };  
1237 -  
1238 - /**  
1239 - * 返回内部路牌数据列表。  
1240 - * @returns {Array}  
1241 - */  
1242 - InternalScheduleObj.prototype.fnGetLpArray = function() {  
1243 - return this._internalLpArray;  
1244 - };  
1245 -  
1246 - /**  
1247 - * 获取班型描述。  
1248 - * @return {*[]}  
1249 - */  
1250 - InternalScheduleObj.prototype.fnGetBxDesc = function() {  
1251 - return this._aBxDesc;  
1252 - };  
1253 -  
1254 - /**  
1255 - * 获取圈的第一个班次是上行还是下行。  
1256 - * @return {boolean|*}  
1257 - */  
1258 - InternalScheduleObj.prototype.fnGetGroupIsUp = function() {  
1259 - return this._qIsUp;  
1260 - };  
1261 -  
1262 - /**  
1263 - * 返回内部工具对象。  
1264 - * @return {{createBcObj, modifySBXMasterBc}}  
1265 - */  
1266 - InternalScheduleObj.prototype.fnGetUitls = function() {  
1267 - return _utils;  
1268 - };  
1269 -  
1270 - /**  
1271 - * 内部数据转化成显示用的班次数组。  
1272 - */  
1273 - InternalScheduleObj.prototype.fnToGanttBcArray = function() {  
1274 - var aAllBc = [];  
1275 - var aLpBc = [];  
1276 - var aEatBc = [];  
1277 - var oLp;  
1278 - var i;  
1279 - var j;  
1280 -  
1281 - for (i = 0; i < this._internalLpArray.length; i++) {  
1282 - oLp = this._internalLpArray[i];  
1283 - aLpBc = [];  
1284 - aLpBc = aLpBc.concat(oLp.getOtherBcArray(), oLp.getBcArray());  
1285 -  
1286 - aEatBc = [];  
1287 - // TODO:根据班次的吃饭时间添加吃饭班次  
1288 - for (j = 0; j < aLpBc.length; j++) {  
1289 - if (aLpBc[j].fnGetEatTime() > 0) {  
1290 - aEatBc.push(_utils.createBcObj(  
1291 - oLp,  
1292 - "cf",  
1293 - aLpBc[j].isUp(), // 和上一个班次方向相反  
1294 - 1,  
1295 - this._oParam.addMinute(aLpBc[j].getFcTimeObj(), -aLpBc[j].fnGetEatTime()),  
1296 - this._oParam  
1297 - ));  
1298 - }  
1299 - }  
1300 - aLpBc = aLpBc.concat(aEatBc);  
1301 -  
1302 - // 按照发车时间排序  
1303 - aLpBc.sort(function(o1, o2) {  
1304 - if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {  
1305 - return -1;  
1306 - } else {  
1307 - return 1;  
1308 - }  
1309 - });  
1310 -  
1311 - // 重新赋值fcno  
1312 - for (j = 0; j < aLpBc.length; j++) {  
1313 - aLpBc[j].fnSetFcno(j + 1);  
1314 - }  
1315 -  
1316 - aAllBc = aAllBc.concat(aLpBc);  
1317 - }  
1318 -  
1319 - var aGanttBc = [];  
1320 - for (i = 0; i < aAllBc.length; i++) {  
1321 - aGanttBc.push(aAllBc[i].toGanttBcObj());  
1322 - }  
1323 -  
1324 - return aGanttBc;  
1325 - };  
1326 -  
1327 - /**  
1328 - * 计算指定开始时间,指定方向班次执行后的最大最小停站时间。  
1329 - * @param oStartFcTime 开始发车时间  
1330 - * @param isUp 是否上行  
1331 - * @returns array [最小值,最大值]  
1332 - */  
1333 - InternalScheduleObj.prototype._$calcuLayoverTime = function(oStartFcTime, isUp) {  
1334 - var aRtn = [];  
1335 - var _iRunningTime; // 行驶时间  
1336 - var _iLayoverTime; // 停站时间  
1337 -  
1338 - // 最小停站时间  
1339 - _iRunningTime = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(  
1340 - isUp, oStartFcTime, this._oParam);  
1341 - _iLayoverTime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
1342 - oStartFcTime, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"),  
1343 - this._oParam)[0]; // 最小停站  
1344 - aRtn.push(_iLayoverTime);  
1345 -  
1346 - // 最大停站时间  
1347 - _iRunningTime = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(  
1348 - isUp, oStartFcTime, this._oParam);  
1349 - _iLayoverTime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
1350 - oStartFcTime, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"),  
1351 - this._oParam)[1]; // 最大停站  
1352 - aRtn.push(_iLayoverTime);  
1353 -  
1354 - return aRtn;  
1355 - };  
1356 -  
1357 - /**  
1358 - * 计算指定时间,指定方向开始的最大最小周转时间  
1359 - * @param oStartFcTime 开始发车时间  
1360 - * @param isUp 是否上行  
1361 - * @returns array [最小值,最大值]  
1362 - * @private  
1363 - */  
1364 - InternalScheduleObj.prototype._$calcuCycleTime = function(oStartFcTime, isUp) {  
1365 - var aRtn = [];  
1366 - var _iRunningTime; // 行驶时间  
1367 - var _iLayoverTime; // 停站时间  
1368 - var _iCycleTime; // 周转时间  
1369 - var _oNextFcTime;  
1370 -  
1371 - // 最小周转时间  
1372 - _iRunningTime = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(  
1373 - isUp, oStartFcTime, this._oParam);  
1374 - _iLayoverTime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
1375 - oStartFcTime, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"),  
1376 - this._oParam)[0]; // 最小停站  
1377 - _iCycleTime = _iRunningTime + _iLayoverTime;  
1378 - _oNextFcTime = this._oParam.addMinute(oStartFcTime, (_iRunningTime + _iLayoverTime));  
1379 - _iRunningTime = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(  
1380 - !isUp, _oNextFcTime, this._oParam);  
1381 - _iLayoverTime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
1382 - _oNextFcTime, !isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"),  
1383 - this._oParam)[0]; // 最小停站  
1384 - _iCycleTime += _iRunningTime;  
1385 - _iCycleTime += _iLayoverTime;  
1386 -  
1387 - aRtn.push(_iCycleTime);  
1388 -  
1389 - // 最大周转时间  
1390 - _iRunningTime = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(  
1391 - isUp, oStartFcTime, this._oParam);  
1392 - _iLayoverTime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
1393 - oStartFcTime, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"),  
1394 - this._oParam)[1]; // 最大停站  
1395 - _iCycleTime = _iRunningTime + _iLayoverTime;  
1396 - _oNextFcTime = this._oParam.addMinute(oStartFcTime, (_iRunningTime + _iLayoverTime));  
1397 - _iRunningTime = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(  
1398 - !isUp, _oNextFcTime, this._oParam);  
1399 - _iLayoverTime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
1400 - _oNextFcTime, !isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"),  
1401 - this._oParam)[1]; // 最大停站  
1402 - _iCycleTime += _iRunningTime;  
1403 - _iCycleTime += _iLayoverTime;  
1404 -  
1405 - aRtn.push(_iCycleTime);  
1406 -  
1407 - return aRtn;  
1408 - };  
1409 -  
1410 - //-------------------- static静态方法 ----------------------//  
1411 -  
1412 - /**  
1413 - * 计算车辆数(最大周转时间/最大发车间隔)。  
1414 - * @param oParam 参数对象  
1415 - */  
1416 - InternalScheduleObj.calcuClzx = function(oParam) {  
1417 - var _iUpRT; // 上行行驶时间  
1418 - var _iUpLT; // 上行停站时间  
1419 - var _iDownRT; // 下行行驶时间  
1420 - var _iDownLT; // 下行停站时间  
1421 -  
1422 - // 计算早高峰最大周转时间  
1423 - _iUpRT = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(true, oParam.getMPeakStartTimeObj(), oParam);  
1424 - _iUpLT = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
1425 - oParam.getMPeakStartTimeObj(), true,  
1426 - StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam)[1]; // 使用最大停站时间  
1427 - _iDownRT = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(false, oParam.getMPeakStartTimeObj(), oParam);  
1428 - _iDownLT = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
1429 - oParam.getMPeakStartTimeObj(), false,  
1430 - StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam)[1]; // 使用最大停站时间  
1431 - var _iAMPeakRCTime = _iUpRT + _iUpLT + _iDownRT + _iDownLT;  
1432 - // 早高峰预估车辆数,使用早高峰最大发车间隔  
1433 - var _iAMPeakVehicleCount = _iAMPeakRCTime / oParam.getMPeakMaxFcjx();  
1434 -  
1435 - // 计算晚高峰最大周转时间  
1436 - _iUpRT = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(true, oParam.getEPeakStartTimeObj(), oParam);  
1437 - _iUpLT = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
1438 - oParam.getEPeakStartTimeObj(), true,  
1439 - StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam)[1]; // 使用最大停站时间  
1440 - _iDownRT = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(false, oParam.getEPeakStartTimeObj(), oParam);  
1441 - _iDownLT = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
1442 - oParam.getEPeakStartTimeObj(), false,  
1443 - StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam)[1]; // 使用最大停站时间  
1444 - var _iPMPeakRCTime = _iUpRT + _iUpLT + _iDownRT + _iDownLT;  
1445 - // 晚高峰预估车辆数,使用晚高峰最大发车间隔  
1446 - var _iPMPeakVehicleCount = _iPMPeakRCTime / oParam.getEPeakMaxFcjx();  
1447 -  
1448 - // 取最大值为最终车辆数  
1449 - // 大于或等于的最小整数,人话就是有小数点就加1  
1450 - if (_iAMPeakVehicleCount > _iPMPeakVehicleCount) {  
1451 - return Math.ceil(_iAMPeakVehicleCount);  
1452 - } else {  
1453 - return Math.ceil(_iPMPeakVehicleCount);  
1454 - }  
1455 -  
1456 - };  
1457 -  
1458 -  
1459 - return InternalScheduleObj; 1 +/**
  2 + * v2_2版本的行车计划对象。
  3 + *
  4 + * 本次修正和原来区别,一边生成班次,一边调整班次间隔
  5 + * 1、初始化行车计划基本布局,主要是有几辆车,路牌分布情况(连班,分班,5休2分班),上标线的初始班次列表
  6 + *
  7 + */
  8 +var InternalScheduleObj_v2_2 = (function() {
  9 +
  10 + // 内部utils类
  11 + var _utils = function() {
  12 + return {
  13 + /**
  14 + * 创建班次对象。
  15 + * @param lpObj InternalLpObj路牌对象
  16 + * @param bcType 班次类型(normal等等)
  17 + * @param isUp 是否上行
  18 + * @param fcno 发车顺序号
  19 + * @param fcTimeObj 发车时间对象
  20 + * @param paramObj 参数对象
  21 + * @returns {InternalBcObj}
  22 + */
  23 + createBcObj : function(lpObj, bcType, isUp, fcno, fcTimeObj, paramObj) {
  24 + var _bclc = paramObj.calcuTravelLcNumber(isUp, bcType); // 班次里程
  25 + var _fcsj = fcTimeObj; // 发车时间
  26 + // var _bcsj = paramObj.calcuTravelTime(_fcsj, isUp); // 班次历时
  27 + var _bcsj = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(isUp, _fcsj, paramObj); // 使用策略计算班次行驶时间
  28 +
  29 + // console.log("发车时间=" + _fcsj.format("HH:mm") + ",行驶时间=" + _bcsj);
  30 +
  31 + var _arrsj = paramObj.addMinute(_fcsj, _bcsj); // 到达时间
  32 + // 停站时间范围,[最小停站时间,最大停站时间]
  33 + // var _stopTimeRange = paramObj.calcuTripLayoverTimeRange(_arrsj, isUp, _bcsj);
  34 + var _stopTimeRange = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  35 + _fcsj, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), paramObj);
  36 +
  37 + var _stoptime = _stopTimeRange[0]; // 使用最小停站时间
  38 + var _tccid = paramObj.getTTinfoId();
  39 + var _ttinfoid = paramObj.getTTinfoId();
  40 + var _xl = paramObj.getXlId();
  41 + var _qdz = isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;
  42 + var _zdz = isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;
  43 +
  44 + if (bcType == "bd") { // 早例保,传过来的发车时间是第一个班次的发车时间
  45 + if (isUp) { // 上行
  46 + _fcsj = paramObj.addMinute(
  47 + _fcsj,
  48 + -(paramObj.getUpOutTime() + paramObj.getLbTime()));
  49 + _bcsj = paramObj.getLbTime();
  50 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  51 + _stoptime = 0;
  52 + } else { // 下行
  53 + _fcsj = paramObj.addMinute(
  54 + _fcsj,
  55 + -(paramObj.getDownOutTime() + paramObj.getLbTime()));
  56 + _bcsj = paramObj.getLbTime();
  57 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  58 + _stoptime = 0;
  59 + }
  60 + } else if (bcType == "lc") { // 晚例保,传过来的发车时间是最后一个班次的到达时间
  61 + if (isUp) { // 上行
  62 + _fcsj = paramObj.addMinute(
  63 + _fcsj,
  64 + paramObj.getUpInTime());
  65 + _bcsj = paramObj.getLbTime();
  66 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  67 + _stoptime = 0;
  68 + } else { // 下行
  69 + _fcsj = paramObj.addMinute(
  70 + _fcsj,
  71 + paramObj.getDownInTime());
  72 + _bcsj = paramObj.getLbTime();
  73 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  74 + _stoptime = 0;
  75 + }
  76 + } else if (bcType == "out") { // 出场,传过来的发车时间是第一个班次的发车时间
  77 + if (isUp) { // 上行
  78 + _fcsj = paramObj.addMinute(
  79 + _fcsj,
  80 + -paramObj.getUpOutTime());
  81 + _bcsj = paramObj.getUpOutTime();
  82 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  83 + _stoptime = 0;
  84 + } else { // 下行
  85 + _fcsj = paramObj.addMinute(
  86 + _fcsj,
  87 + -paramObj.getDownOutTime());
  88 + _bcsj = paramObj.getDownOutTime();
  89 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  90 + _stoptime = 0;
  91 + }
  92 + } else if (bcType == "in") { // 进场,传过来的发车时间是最后一个班次的到达时间
  93 + if (isUp) { // 上行
  94 + _bcsj = paramObj.getUpInTime();
  95 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  96 + _stoptime = 0;
  97 + } else { // 下行
  98 + _bcsj = paramObj.getDownInTime();
  99 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  100 + _stoptime = 0;
  101 + }
  102 + } else if (bcType == "cf") { // 吃饭班次
  103 + // 以13:00为分界,之前的为午饭,之后的为晚饭
  104 + if (fcTimeObj.isBefore(paramObj.toTimeObj("13:00"))) {
  105 + _bcsj = paramObj.fnGetLunchTime();
  106 + } else {
  107 + _bcsj = paramObj.fnGetDinnerTime();
  108 + }
  109 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  110 + _stoptime = 0;
  111 + }
  112 +
  113 + var bcParamObj = {};
  114 + bcParamObj.bcType = bcType; // 班次类型(normal,in_,out, bd, lc, cf等)
  115 + bcParamObj.isUp = isUp; // boolean是否上下行
  116 + bcParamObj.fcno = fcno; // 发车顺序号
  117 + bcParamObj.fcTimeObj = _fcsj; // 发车时间对象
  118 + bcParamObj.bclc = _bclc; // 班次里程
  119 + bcParamObj.bcsj = _bcsj; // 班次历时
  120 + bcParamObj.arrtime = _arrsj; // 到达时间对象
  121 + bcParamObj.stoptime = _stoptime; // 停站时间
  122 + bcParamObj.tccid = _tccid; // 停车场id
  123 + bcParamObj.ttinfoid = _ttinfoid; // 时刻表id
  124 + bcParamObj.xl = _xl; // 线路id
  125 + bcParamObj.qdzid = _qdz; // 起点站id
  126 + bcParamObj.zdzid = _zdz; // 终点站id
  127 +
  128 + return new InternalBcObj(lpObj, bcParamObj);
  129 + },
  130 +
  131 + /**
  132 + * 修正上标线主站方向班次(一圈的结束班次,也是下一圈的开始班次)以及后续说有班次。
  133 + * @param oLp 上标线路牌
  134 + * @param fromFcsj 开始发车时间对象
  135 + * @param fromGroupIndex 开始圈索引
  136 + * @param fromBcIndex 开始班次索引
  137 + * @param isUp 开始班次是上行还是下行
  138 + * @param oParam 参数对象
  139 + */
  140 + modifySBXMasterBc: function(oLp, fromFcsj, fromGroupIndex, fromBcIndex, isUp, oParam) {
  141 + // 清空指定位置班次及后续班次
  142 + oLp.clearBc(fromGroupIndex, fromBcIndex);
  143 + // 初始化上标线,从指定圈索引开始
  144 + oLp.initDataFromTime(fromFcsj, isUp, fromGroupIndex, oParam, _utils);
  145 +
  146 + }
  147 +
  148 + };
  149 + }();
  150 +
  151 +
  152 +
  153 + /**
  154 + * 内部行车计划对象。
  155 + * @param oParam 参数封装对象
  156 + * @param aLp 路牌(甘特图用的路牌对象)
  157 + * @constructor
  158 + */
  159 + function InternalScheduleObj(oParam, aLp) {
  160 + // 参数对象和甘特图用路牌数组
  161 + this._oParam = oParam;
  162 + this._aGanttLpArray = aLp;
  163 +
  164 + // 目前这个只支持主站停站
  165 + if (this._oParam.isTwoWayStop()) {
  166 + alert("v2_2版本不支持双向停站类型线路!");
  167 + throw "v2_2版本不支持双向停站类型线路";
  168 + }
  169 +
  170 + console.log("//->>>>>>>>>>>>>>>>>>>>>>>>> v2_2行车计划,初始化1,圈信息,路牌 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-//");
  171 + //----------------------- 1、确定上标线的方向,圈的方向 -------------------//
  172 + this._qIsUp = true; // 每一圈是上行开始还是下行开始
  173 +
  174 + // 确定_qIsUp,哪个方向的首班车晚就用哪个
  175 + // this._qIsUp = this._oParam.getUpFirstDTimeObj().isBefore(
  176 + // this._oParam.getDownFirstDTimeObj()) ? false : true;
  177 +
  178 + // 确定_qIsUp,哪个方向的首班车晚就用哪个
  179 + // 使用diff判定,如果两个时间相等 this._qIsUp = false
  180 + this._qIsUp = oParam.getUpFirstDTimeObj().diff(oParam.getDownFirstDTimeObj()) <= 0 ? false : true;
  181 +
  182 +
  183 + // 上标线开始时间,就是方向的首班车时间
  184 + var st = this._qIsUp ? oParam.getUpFirstDTimeObj() : oParam.getDownFirstDTimeObj();
  185 + // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向
  186 + var et;
  187 + var et_IsUp;
  188 + if (oParam.getUpLastDtimeObj().isBefore(
  189 + oParam.getDownLastDTimeObj())) {
  190 + et = oParam.getDownLastDTimeObj();
  191 + et_IsUp = false;
  192 + } else {
  193 + et = oParam.getUpLastDtimeObj();
  194 + et_IsUp = true;
  195 + }
  196 + //------------------------ 2、计算总共有多少圈 ------------------------//
  197 + this._qCount = 0; // 总的圈数
  198 +
  199 + // 以开始时间,结束时间,构造上标线用连班班次发车时间
  200 + var bcFcsjArrays = []; // 班次发车时间对象数组
  201 + var bcArsjArrays = []; // 班次到达时间对象数组
  202 + var isUp = this._qIsUp; // 方向
  203 + var bcCount = 1; // 班次数
  204 +
  205 + var _kssj = st; // 开始时间
  206 + var _bcsj = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(isUp, _kssj, oParam); // 使用策略计算班次行驶时间
  207 + var _arrsj = oParam.addMinute(_kssj, _bcsj); // 到达时间
  208 + var _stoptimeRange = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  209 + _kssj, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam);
  210 + var _stoptime = _stoptimeRange[0]; // 最小停站时间
  211 +
  212 + do {
  213 + bcFcsjArrays.push(_kssj);
  214 + bcArsjArrays.push(_arrsj);
  215 +
  216 + _kssj = oParam.addMinute(_kssj, _bcsj + _stoptime);
  217 + // _bcsj = oParam.calcuTravelTime(_kssj, isUp);
  218 +
  219 + _bcsj = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(isUp, _kssj, oParam); // 使用策略计算班次行驶时间
  220 + _arrsj = oParam.addMinute(_kssj, _bcsj);
  221 + _stoptimeRange = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  222 + _kssj, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam);
  223 + _stoptime = _stoptimeRange[0]; // 最小停站时间
  224 +
  225 + bcCount ++;
  226 + isUp = !isUp;
  227 + } while(_kssj.isBefore(et));
  228 + bcCount--; // 因为先做do,所以总的班次要减1
  229 +
  230 + var _qCount_p1 = Math.floor(bcCount / 2); // 2个班次一圈
  231 + var _qCount_p2 = bcCount % 2; // 余下的1个班次也算一圈
  232 +
  233 + // 利用连班数组计算圈数
  234 + this._qCount = 1; // 前面加1圈,补中标线的班次
  235 + this._qCount += _qCount_p1;
  236 + this._qCount += _qCount_p2;
  237 +
  238 + // 计算最后是不是还要补一圈
  239 + if (this._qCount > 1) { // 总的圈数就1圈,没必要加了(其实是不可能的,除非参数里问题)
  240 + if (_qCount_p2 == 0) { // 没有余下班次,整数圈数
  241 + // 最后一个班次的方向一定和开始的方向相反,如:上-下,上-下,上-下,一共三圈,最后一个班次为下行
  242 + // 判定最后一个班次的方向和上标线判定结束时间的班次方向是否一致
  243 + if (!this._qIsUp == et_IsUp) {
  244 + // 一致不用加圈数
  245 + } else {
  246 + // 不一致需要加圈补最后一个结束时间班次
  247 + this._qCount ++;
  248 + }
  249 + } else {
  250 + // 有余下的圈数,最后要不补的班次不管上行,下行都在这一圈里
  251 + // 不需要在补圈数了
  252 + }
  253 + }
  254 + //------------------------ 3、根据路牌数,圈数创建路牌对象 ----------------------//
  255 + this._internalLpArray = []; // 内部路牌(InternalLpObj对象)数组
  256 +
  257 + // 创建内部的路牌数组
  258 + var i;
  259 + for (i = 0; i < this._aGanttLpArray.length; i++) {
  260 + this._internalLpArray.push(
  261 + new InternalLpObj(this._aGanttLpArray[i], this._qCount, this._qIsUp));
  262 + }
  263 +
  264 + // 初始化上标线,从第1圈开始
  265 + this._internalLpArray[0].initDataFromTimeToTime(
  266 + bcFcsjArrays[0], et, this._qIsUp, 1, oParam, _utils);
  267 +
  268 +
  269 + console.log("上行首班车时间:" + oParam.getUpFirstDTimeObj().format("HH:mm") +
  270 + "上行末班车时间:" + oParam.getUpLastDtimeObj().format("HH:mm"));
  271 + console.log("下行首班车时间:" + oParam.getDownFirstDTimeObj().format("HH:mm") +
  272 + "下行末班车时间:" + oParam.getDownLastDTimeObj().format("HH:mm"));
  273 + console.log("总共计算的圈数:" + this._qCount);
  274 + console.log("圈的方向isUP:" + this._qIsUp);
  275 +
  276 + console.log("//->>>>>>>>>>>>>>>>>>>>>>>>> v2_2行车计划,初始化2,工时,路牌信息 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-//");
  277 + //------------------------ 1、以上标线为基础,计算各种班型工时对应的圈数、班次数 -----------------------//
  278 + var aBcArray = this._internalLpArray[0].getBcArray();
  279 + aBcArray[0].fnSetIsFirstBc(true); // 设置首班班次标识
  280 +
  281 + if (aBcArray.length % 2 != 0) { // 不能整除2,去除一个班次计算
  282 + aBcArray.splice(aBcArray.length - 1, 1);
  283 + }
  284 +
  285 + var iLTime = oParam.fnGetLunchTime(); // 午饭吃饭时间
  286 + var iDTime = oParam.fnGetDinnerTime(); // 晚饭吃饭时间
  287 + var iOutTime = this._qIsUp ? oParam.getUpOutTime() : oParam.getDownOutTime(); // 出场时间
  288 + var iInTime = this._qIsUp ? oParam.getDownInTime() : oParam.getUpInTime(); // 进场时间
  289 + var iBTime = oParam.getLbTime(); // 例保时间
  290 +
  291 + var sum = 0; // 总班次时间
  292 + for (i = 0; i < aBcArray.length; i++) {
  293 + sum += aBcArray[i].getBcTime() + aBcArray[i].getStopTime();
  294 + }
  295 + sum += iLTime; // 加午饭时间
  296 + sum += iDTime; // 加晚饭时间
  297 +
  298 + this._aBxDesc = [ // 各种班型描述(班型名称,平均工时,平均需要的班次数,平均工时)
  299 + {'sType':'六工一休', 'fHoursV':6.66, 'fBcCount': 0, 'fAverTime': 0},
  300 + {'sType':'五工一休', 'fHoursV':6.85, 'fBcCount': 0, 'fAverTime': 0},
  301 + {'sType':'四工一休', 'fHoursV':7.14, 'fBcCount': 0, 'fAverTime': 0},
  302 + {'sType':'三工一休', 'fHoursV':7.61, 'fBcCount': 0, 'fAverTime': 0},
  303 + {'sType':'二工一休', 'fHoursV':8.57, 'fBcCount': 0, 'fAverTime': 0},
  304 + {'sType':'一工一休', 'fHoursV':11.42, 'fBcCount': 0, 'fAverTime': 0},
  305 + {'sType':'五工二休', 'fHoursV':7.99, 'fBcCount': 0, 'fAverTime': 0},
  306 + {'sType':'无工休', 'fHoursV':5.43, 'fBcCount': 0, 'fAverTime': 0}
  307 + ];
  308 +
  309 + for (i = 0; i < this._aBxDesc.length; i++) {
  310 + this._aBxDesc[i].fAverTime = sum / (aBcArray.length / 2); // 平均周转时间不算进出场,例保时间
  311 +
  312 + // 计算5休2的班次数(双进出场,4个例保)
  313 + if (i == 6) {
  314 + this._aBxDesc[i].fQCount =
  315 + (this._aBxDesc[i].fHoursV * 60 - iOutTime * 2 - iInTime * 2 - iBTime * 4) /
  316 + this._aBxDesc[i].fAverTime;
  317 + this._aBxDesc[i].fBcCount = this._aBxDesc[i].fQCount * 2;
  318 + } else { // 进出场,2个例保
  319 + this._aBxDesc[i].fQCount =
  320 + (this._aBxDesc[i].fHoursV * 60 - iOutTime - iInTime - iBTime * 2) /
  321 + this._aBxDesc[i].fAverTime;
  322 + this._aBxDesc[i].fBcCount = this._aBxDesc[i].fQCount * 2;
  323 + }
  324 + }
  325 + console.log("班型描述(以下):");
  326 + console.log(this._aBxDesc);
  327 + //--------------------- 2、计算分班连班班型车辆分布数 --------------------//
  328 + this._iBx_lb_lpcount = 0; // 连班路牌数
  329 + this._iBx_5_2_fb_lpcount = 0; // 5休2分班路牌数
  330 + this._iBx_other_fb_lpcount = 0; // 其他分班路牌数
  331 +
  332 + // 总共车辆数(高峰最大车辆数)
  333 + var iCls = InternalScheduleObj_v2_2.calcuClzx(oParam);
  334 + // 计算低谷最大周转时间
  335 + var _iTroughCycleTime =
  336 + StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(true, oParam.toTimeObj("13:00"), oParam) +
  337 + StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  338 + oParam.toTimeObj("13:00"), true,
  339 + StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam)[1] +
  340 + StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(false, oParam.toTimeObj("13:00"), oParam) +
  341 + StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  342 + oParam.toTimeObj("13:00"), false,
  343 + StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam)[1];
  344 +
  345 + // 低谷最少配车(预估最少连班车数量)
  346 + var iDgminpc = Math.ceil(_iTroughCycleTime / oParam.getTroughMaxFcjx());
  347 + // 加班车路牌数(做5休2的路牌数)
  348 + var i_5_2_lpes = oParam.getJBLpes();
  349 +
  350 + // v2_2版本的路牌分布就是连班分班加班车分布,总车辆数减去加班车,剩下的车对半开连班和其他分班,但是连班必须大于最少连班
  351 + if (iCls < iDgminpc) {
  352 + alert("总配车数小于低谷最小配车");
  353 + throw "总配车数小于低谷最小配车";
  354 + } else {
  355 + // 5_2路牌数
  356 + this._iBx_5_2_fb_lpcount = i_5_2_lpes;
  357 +
  358 + // 剩余车辆数
  359 + var _iOtherCls = iCls - this._iBx_5_2_fb_lpcount;
  360 + var _iHalfCls1; // 连班路牌数
  361 + var _iHalfCls2; // 其他分班路牌数
  362 + if (_iOtherCls % 2 == 0) { // 能整除
  363 + _iHalfCls1 = _iOtherCls / 2;
  364 + _iHalfCls2 = _iOtherCls / 2;
  365 + } else {
  366 + _iHalfCls1 = Math.floor(_iOtherCls / 2) + 1;
  367 + _iHalfCls2 = Math.floor(_iOtherCls / 2);
  368 + }
  369 + if (_iHalfCls1 > iDgminpc) {
  370 + this._iBx_lb_lpcount = _iHalfCls1;
  371 + this._iBx_other_fb_lpcount = _iHalfCls2;
  372 + } else {
  373 + this._iBx_lb_lpcount = iDgminpc;
  374 + this._iBx_other_fb_lpcount = iCls - this._iBx_lb_lpcount - i_5_2_lpes;
  375 + }
  376 + }
  377 +
  378 + //------------------------ 3、利用间隔法计算连班路牌分布 --------------------//
  379 + var i;
  380 + var j;
  381 + var iC1 = Math.floor(this._internalLpArray.length / this._iBx_lb_lpcount);
  382 + var iC2 = this._internalLpArray.length % this._iBx_lb_lpcount;
  383 + var iLpIndex;
  384 +
  385 + for (i = 0; i < this._iBx_lb_lpcount - iC2; i++) {
  386 + iLpIndex = i * iC1;
  387 + this._internalLpArray[iLpIndex].setBxLb(true);
  388 + this._internalLpArray[iLpIndex].setBxDesc("连班");
  389 + }
  390 + for (j = 0; j < iC2; j++) {
  391 + iLpIndex = i * iC1 + j * (iC1 + 1);
  392 + this._internalLpArray[iLpIndex].setBxLb(true);
  393 + this._internalLpArray[iLpIndex].setBxDesc("连班");
  394 + }
  395 + //------------------------ 4、利用间隔法计算分班班型路牌分布 --------------------//
  396 + // 获取分班路牌索引
  397 + var aNotLbIndexes = [];
  398 + for (i = 0; i < this._internalLpArray.length; i++) {
  399 + if (!this._internalLpArray[i].isBxLb()) {
  400 + aNotLbIndexes.push(i);
  401 + }
  402 + }
  403 + // 先5休2分班
  404 + iC1 = Math.floor(aNotLbIndexes.length / this._iBx_5_2_fb_lpcount);
  405 + iC2 = aNotLbIndexes.length % this._iBx_5_2_fb_lpcount;
  406 +
  407 + for (i = 0; i < this._iBx_5_2_fb_lpcount - iC2; i++) {
  408 + iLpIndex = aNotLbIndexes[i * iC1];
  409 + this._internalLpArray[iLpIndex].setBxLb(false);
  410 + this._internalLpArray[iLpIndex].setBxFb(true);
  411 + this._internalLpArray[iLpIndex].setBxFb5_2(true);
  412 + this._internalLpArray[iLpIndex].setBxDesc("5休2分班");
  413 + }
  414 + for (i = 0; i < iC2; i++) {
  415 + iLpIndex = aNotLbIndexes[this._iBx_5_2_fb_lpcount - iC2 + i * (iC1 + 1)];
  416 + this._internalLpArray[iLpIndex].setBxLb(false);
  417 + this._internalLpArray[iLpIndex].setBxFb(true);
  418 + this._internalLpArray[iLpIndex].setBxFb5_2(true);
  419 + this._internalLpArray[iLpIndex].setBxDesc("5休2分班");
  420 + }
  421 + // 其他分班
  422 + for (i = 0; i < aNotLbIndexes.length; i++) {
  423 + iLpIndex = aNotLbIndexes[i];
  424 + if (!this._internalLpArray[iLpIndex].isBxFb5_2()) {
  425 + this._internalLpArray[iLpIndex].setBxLb(false);
  426 + this._internalLpArray[iLpIndex].setBxFb(true);
  427 + this._internalLpArray[iLpIndex].setBxFb5_2(false);
  428 + this._internalLpArray[iLpIndex].setBxDesc("其他分班");
  429 + }
  430 + }
  431 +
  432 + console.log("高峰周转时间:" + oParam.calcuPeakZzsj());
  433 + console.log("连班路牌数:" + this._iBx_lb_lpcount);
  434 + console.log("5休2分班路牌数:" + this._iBx_5_2_fb_lpcount);
  435 + console.log("其他分班路牌数:" + this._iBx_other_fb_lpcount);
  436 + var aLbIndexes = [];
  437 + for (i = 0; i < this._internalLpArray.length; i++) {
  438 + if (this._internalLpArray[i].isBxLb()) {
  439 + aLbIndexes.push(i);
  440 + }
  441 + }
  442 + console.log("连班路牌indexes=" + aLbIndexes);
  443 + var a_5_2_fbIndexes = [];
  444 + for (i = 0; i < this._internalLpArray.length; i++) {
  445 + if (this._internalLpArray[i].isBxFb() && this._internalLpArray[i].isBxFb5_2()) {
  446 + a_5_2_fbIndexes.push(i);
  447 + }
  448 + }
  449 + console.log("5休2分班路牌indexes=" + a_5_2_fbIndexes);
  450 + var a_other_fbIndexes = [];
  451 + for (i = 0; i < this._internalLpArray.length; i++) {
  452 + if (this._internalLpArray[i].isBxFb() && !this._internalLpArray[i].isBxFb5_2()) {
  453 + a_other_fbIndexes.push(i);
  454 + }
  455 + }
  456 + console.log("其他分班路牌indexes=" + a_other_fbIndexes);
  457 +
  458 + console.log("//->>>>>>>>>>>>>>>>> v2_3行车计划,初始化3,计算上标线第一个主站副站班次信息 <<<<<<<<<<<<<<<<<<<<<-//");
  459 + // 计算上标线第一个主站班次,副站班次的位置
  460 + this._oFirstMasterBc = undefined; // 早高峰主站方向班次
  461 + this._iFirstMasterBcGroupIndex = undefined; // 早高峰主站方向圈索引
  462 + this._iFirstMasterBcIndex = undefined; // 早高峰主站方向班次索引
  463 +
  464 + this._oFirstSlaveBc = undefined; // 早高峰副站方向班次
  465 + this._iFirstSlaveBcGroupIndex = undefined; // 早高峰副站方向圈索引
  466 + this._iFirstSlaveBcIndex = undefined; // 早高峰副站方向班次索引
  467 +
  468 + if (this._qIsUp) {
  469 + if (this._oParam.isUpOneWayStop()) {
  470 + this._oFirstMasterBc = this._internalLpArray[0].getBc(1, 0);
  471 + this._iFirstMasterBcGroupIndex = 1;
  472 + this._iFirstMasterBcIndex = 0;
  473 +
  474 + this._oFirstSlaveBc = this._internalLpArray[0].getBc(1, 1);
  475 + this._iFirstSlaveBcGroupIndex = 1;
  476 + this._iFirstSlaveBcIndex = 1;
  477 + } else {
  478 + this._oFirstMasterBc = this._internalLpArray[0].getBc(1, 1);
  479 + this._iFirstMasterBcGroupIndex = 1;
  480 + this._iFirstMasterBcIndex = 1;
  481 +
  482 + this._oFirstSlaveBc = this._internalLpArray[0].getBc(1, 0);
  483 + this._iFirstSlaveBcGroupIndex = 1;
  484 + this._iFirstSlaveBcIndex = 0;
  485 + }
  486 + } else {
  487 + if (this._oParam.isUpOneWayStop()) {
  488 + this._oFirstMasterBc = this._internalLpArray[0].getBc(1, 1);
  489 + this._iFirstMasterBcGroupIndex = 1;
  490 + this._iFirstMasterBcIndex = 1;
  491 +
  492 + this._oFirstSlaveBc = this._internalLpArray[0].getBc(1, 0);
  493 + this._iFirstSlaveBcGroupIndex = 1;
  494 + this._iFirstSlaveBcIndex = 0;
  495 + } else {
  496 + this._oFirstMasterBc = this._internalLpArray[0].getBc(1, 0);
  497 + this._iFirstMasterBcGroupIndex = 1;
  498 + this._iFirstMasterBcIndex = 0;
  499 +
  500 + this._oFirstSlaveBc = this._internalLpArray[0].getBc(1, 1);
  501 + this._iFirstSlaveBcGroupIndex = 1;
  502 + this._iFirstSlaveBcIndex = 1;
  503 + }
  504 + }
  505 +
  506 + console.log("早高峰副站方向(start)班次=" + (this._oFirstSlaveBc ? this._oFirstSlaveBc.getFcTimeObj().format("HH:mm") : "未找到"));
  507 + console.log("早高峰副站方向(start)班次圈索引=" + (this._oFirstSlaveBc ? this._iFirstSlaveBcGroupIndex : "未找到"));
  508 + console.log("早高峰副站方向(start)班次索引=" + (this._oFirstSlaveBc ? this._iFirstSlaveBcIndex : "未找到"));
  509 + console.log("早高峰主站方向(start)班次=" + (this._oFirstMasterBc ? this._oFirstMasterBc.getFcTimeObj().format("HH:mm") : "未找到"));
  510 + console.log("早高峰主站方向(start)班次圈索引=" + (this._oFirstMasterBc ? this._iFirstMasterBcGroupIndex : "未找到"));
  511 + console.log("早高峰主站方向(start)班次索引=" + (this._oFirstMasterBc ? this._iFirstMasterBcIndex : "未找到"));
  512 +
  513 + console.log("//->>>>>>>>>>>>>>>>> v2_4行车计划,初始化4,从上标线第一圈第一个副站班次开始初始化后续路牌班次列表 <<<<<<<<<<<<<<<<<<<<<-//");
  514 + // 初始化上标线副站班次
  515 + var oPreBc; // 上一个班次(从上标线副站班次开始)
  516 + var oNextBc; // 计算的下一个班次
  517 + var oNextBcFcTime; // 下一个班次的发车时间
  518 + var aBcInterval = []; // 班次间隔数组
  519 + var oBcInterval; // 班次间隔对象
  520 + var iNextBcInterval; // 下一个班次发车间隔
  521 +
  522 + // 当初始化完一圈的副站班次后,最后一个班次是下一圈的上标线副站班次(一圈的周转结束班次),需要调整时间及其前一个主站班次的时间
  523 + var _modifyTimeNextGroupIndex; // 上标线下一圈索引
  524 + var _modifyTimeNextBcIndex; // 上标线下一圈班次索引
  525 + var _modifyBc; // 上标线下一个圈的班次
  526 + var _modifyPreBc; // 上标线下一个圈班次的前一个班次
  527 + var _modifyTime; // 上标线下一个圈班次的前一个班次的调整时间
  528 +
  529 + if (this._iFirstSlaveBcIndex == 0) { // 第一圈第二个班次是主站,则第一个班次是副站
  530 + oPreBc = this._internalLpArray[0].getBc(this._iFirstSlaveBcGroupIndex, this._iFirstSlaveBcIndex);
  531 +
  532 + aBcInterval = StrategyUtils_v2_2.sFn("CALCU_HEADWAY_2")(
  533 + this,
  534 + this._oParam,
  535 + 1,
  536 + this._iFirstSlaveBcIndex,
  537 + this._$calcuCycleTime(oPreBc.getFcTimeObj())[0],
  538 + this._$calcuCycleTime(oPreBc.getFcTimeObj())[1]
  539 + );
  540 +
  541 + for (i = 1; i < this._internalLpArray.length; i++) {
  542 + oBcInterval = aBcInterval[i - 1];
  543 +
  544 + if (oBcInterval.hasBc) {
  545 + // 参考的发车间隔
  546 + iNextBcInterval = oBcInterval.iFcInterval;
  547 + oNextBcFcTime = this._oParam.addMinute(oPreBc.getFcTimeObj(), iNextBcInterval);
  548 + this._internalLpArray[i].fnSetVerticalIntervalTime(
  549 + this._iFirstSlaveBcGroupIndex, this._iFirstSlaveBcIndex, iNextBcInterval);
  550 + this._internalLpArray[i].fnSetHeadwayS2_P(
  551 + this._iFirstSlaveBcGroupIndex, this._iFirstSlaveBcIndex, oBcInterval.fP);
  552 +
  553 + oNextBc = _utils.createBcObj(
  554 + this._internalLpArray[i],
  555 + "normal",
  556 + !this._oParam.isUpOneWayStop(),
  557 + 1,
  558 + oNextBcFcTime,
  559 + this._oParam);
  560 +
  561 + this._internalLpArray[i].setBc(
  562 + this._iFirstSlaveBcGroupIndex, this._iFirstSlaveBcIndex, oNextBc);
  563 +
  564 + oPreBc = oNextBc;
  565 + }
  566 + }
  567 +
  568 + // 修正上标线副站方向班次(一圈的结束班次,也是下一圈的开始班次)以及后续所有班次
  569 + iNextBcInterval = aBcInterval[i - 1].iFcInterval;
  570 + _modifyTimeNextGroupIndex = this._iFirstSlaveBcGroupIndex + 1;
  571 + _modifyTimeNextBcIndex = this._iFirstSlaveBcIndex;
  572 +
  573 + _utils.modifySBXMasterBc(
  574 + this._internalLpArray[0],
  575 + this._oParam.addMinute(oPreBc.getFcTimeObj(), iNextBcInterval),
  576 + this._iFirstSlaveBcGroupIndex + 1,
  577 + this._iFirstSlaveBcIndex,
  578 + oPreBc.isUp(),
  579 + this._oParam
  580 + );
  581 +
  582 + // 调整上标线副站班次一圈后的前一个主站班次时间
  583 + _modifyBc = this._internalLpArray[0].getBc(_modifyTimeNextGroupIndex, _modifyTimeNextBcIndex);
  584 + if (_modifyBc) {
  585 + this._internalLpArray[0].fnSetVerticalIntervalTime(_modifyTimeNextGroupIndex, _modifyTimeNextBcIndex, iNextBcInterval);
  586 +
  587 + _modifyPreBc = this._internalLpArray[0].getPreBc(_modifyBc);
  588 + _modifyTime = _modifyBc.getFcTimeObj().diff(_modifyPreBc.getArrTimeObj(), "m") - 1; // 主站到副站停站使用1分钟
  589 + // 修改发车时间,到达时间,不改行驶时间
  590 + _modifyPreBc.getFcTimeObj().add(_modifyTime, "m");
  591 + _modifyPreBc.getArrTimeObj().add(_modifyTime, "m");
  592 +
  593 + }
  594 +
  595 + }
  596 +
  597 + console.log("//->>>>>>>>>>>>>>>>> v2_6行车计划,初始化6,创建第一圈的主站班次开始班次列表,然后修正 <<<<<<<<<<<<<<<<<<<<<-//");
  598 + this.fnCreateBclistWithMasterBc(1, 1); // 从上标线第一圈的主站班次开始初始化所有路牌的相关班次
  599 + // 第一圈的第一个班次是副站,则需要修正this.fnCreateBclistWithMasterBc(1)班次之间的问题,停站时间为负数
  600 + if (this._iFirstSlaveBcIndex == 0) {
  601 + StrategyUtils_v2_2.sFn("ADJUST_HEADWAY")(
  602 + this, this._oParam,
  603 + this._iFirstSlaveBcGroupIndex, this._iFirstSlaveBcIndex,
  604 + this._iFirstMasterBcGroupIndex, this._iFirstMasterBcIndex,
  605 + 5 // 修正至少要5分钟停站
  606 + );
  607 + }
  608 +
  609 + console.log("//->>>>>>>>>>>>>>>>> v2_7行车计划,初始化7,修正中标线班次列表 <<<<<<<<<<<<<<<<<<<<<-//");
  610 + // // TODO:补充中标线班次,这里假设,前一半圈就是中标线,以后再精细处理
  611 + // // 中标线开始时间,早的首班车时间,和上标线的开始时间方向相反
  612 + // var oSt = !this._qIsUp ? this._oParam.getUpFirstDTimeObj() : this._oParam.getDownFirstDTimeObj();
  613 + // var iStRuntime; // 中标线方向班次行驶时间(使用低谷)
  614 + // if (!this._qIsUp) { // 上行
  615 + // if (this._oParam.isTroughBc(oSt)) {
  616 + // iStRuntime = this._oParam.getUpTroughTime();
  617 + // } else {
  618 + // iStRuntime = this._oParam.getUpMPeakTime();
  619 + // }
  620 + // } else { // 下行
  621 + // if (this._oParam.isTroughBc(oSt)) {
  622 + // iStRuntime = this._oParam.getDownTroughTime();
  623 + // } else {
  624 + // iStRuntime = this._oParam.getDownMPeakTime();
  625 + // }
  626 + // }
  627 + //
  628 + // var oSLp;
  629 + // var oSBc;
  630 + // var oSEmuBcFcTime; // 模拟班次发车时间
  631 + // var iTimeDiff;
  632 + // var iTempTime;
  633 + // var iSModifyLpIndex; // 中标线对应路牌索引
  634 + // for (i = 1; i < this._internalLpArray.length; i++) {
  635 + // oSLp = this._internalLpArray[i];
  636 + // oSBc = oSLp.getBc(1, 0); // 第一圈第一个班次
  637 + // if (!oSBc) { // 可能没有,跳过
  638 + // continue;
  639 + // }
  640 + // oSEmuBcFcTime = this._oParam.addMinute(
  641 + // oSBc.getFcTimeObj(),
  642 + // -(iStRuntime + 1)
  643 + // );
  644 + // iTempTime = oSEmuBcFcTime.diff(oSt, "m");
  645 + // if (iTimeDiff == undefined) {
  646 + // iTimeDiff = iTempTime;
  647 + // iSModifyLpIndex = i;
  648 + // } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff) && oSEmuBcFcTime.isAfter(oSt)) {
  649 + // iTimeDiff = iTempTime;
  650 + // iSModifyLpIndex = i;
  651 + // }
  652 + // }
  653 + //
  654 + // // 添加上标线头班次(分班连班都可能)
  655 + // this._internalLpArray[iSModifyLpIndex].setBc(
  656 + // 0, 1,
  657 + // _utils.createBcObj(
  658 + // this._internalLpArray[iSModifyLpIndex],
  659 + // "normal",
  660 + // !this._qIsUp,
  661 + // 1,
  662 + // oSt,
  663 + // this._oParam)
  664 + // );
  665 + //
  666 + // // 从当前班次开始,如果是低谷,隔开方向加班次,如果是高峰,都加班次
  667 + // var iSInverval = Math.ceil((this._oParam.getMPeakMinFcjx() + this._oParam.getMPeakMaxFcjx()) / 2);
  668 + // for (i = iSModifyLpIndex + 1; i < this._internalLpArray.length; i++) {
  669 + // oSLp = this._internalLpArray[i];
  670 + // oSEmuBcFcTime = this._oParam.addMinute(oSt, iSInverval * (i - iSModifyLpIndex));
  671 + // if (this._oParam.isMPeakBc(oSEmuBcFcTime)) { // 高峰
  672 + // if (!this._qIsUp) { // 上行
  673 + // iStRuntime = this._oParam.getUpMPeakTime();
  674 + // } else { // 下行
  675 + // iStRuntime = this._oParam.getDownMPeakTime();
  676 + // }
  677 + // oSBc = oSLp.getBc(1, 0); // 第一圈第一个班次
  678 + // oSLp.setBc(
  679 + // 0, 1,
  680 + // _utils.createBcObj(
  681 + // oSLp,
  682 + // "normal",
  683 + // !this._qIsUp,
  684 + // 1,
  685 + // this._oParam.addMinute(oSBc.getFcTimeObj(), -(iStRuntime + 1)),
  686 + // this._oParam)
  687 + // );
  688 + // } else { // 低谷隔开出班次
  689 + // if (!this._qIsUp) { // 上行
  690 + // iStRuntime = this._oParam.getUpTroughTime();
  691 + // } else { // 下行
  692 + // iStRuntime = this._oParam.getDownTroughTime();
  693 + // }
  694 + //
  695 + // if (!this._internalLpArray[i - 1].getBc(0, 1)) {
  696 + // // 上一个路牌没有班次,添加
  697 + // oSBc = oSLp.getBc(1, 0); // 第一圈第一个班次
  698 + // if (oSBc) {
  699 + // oSLp.setBc(
  700 + // 0, 1,
  701 + // _utils.createBcObj(
  702 + // oSLp,
  703 + // "normal",
  704 + // !this._qIsUp,
  705 + // 1,
  706 + // this._oParam.addMinute(oSBc.getFcTimeObj(), -(iStRuntime + 1)),
  707 + // this._oParam)
  708 + // );
  709 + //
  710 + // // 如果生成的班次行驶时间不足,删除这个班次
  711 + // if (oSLp.getBc(1, 0).getFcTimeObj().isBefore(oSLp.getBc(0, 1).getArrTimeObj())) {
  712 + // oSLp.getGroup(0).setBc1(undefined);
  713 + // oSLp.getGroup(0).setBc2(undefined);
  714 + // }
  715 + // }
  716 + // }
  717 + // }
  718 + // }
  719 + //
  720 + // console.log("中标线路牌索引=" + iSModifyLpIndex);
  721 +
  722 +
  723 + }
  724 +
  725 + //------------------------- 核心业务方法 -----------------------//
  726 +
  727 + /**
  728 + * 核心方法,从上标线主站班次开始,一圈一圈生成每圈的主站班次,
  729 + * 每生成一个主站班次,尝试生成后面紧邻的副站班次(停站时间1到3分种调整)。
  730 + * @param iGroupIndex 圈索引
  731 + * @param iCount 共几圈
  732 + */
  733 + InternalScheduleObj.prototype.fnCreateBclistWithMasterBc = function(iGroupIndex, iCount) {
  734 + var i;
  735 + var j;
  736 + // var oPreBc = this._oFirstMasterBc; // 上一个班次(从上标线主站班次开始)
  737 + var oPreBc = this._internalLpArray[0].getBc(iGroupIndex, this._iFirstMasterBcIndex);
  738 + var oNextBc; // 计算的下一个班次
  739 + var oNextBcFcTime; // 下一个班次的发车时间
  740 + var aBcInterval = []; // 班次间隔数组
  741 + var oBcInterval; // 班次间隔对象
  742 + var iNextBcInterval; // 下一个班次发车间隔
  743 +
  744 + var oPreSlaveBc; // 上一个副站班次(上标线主站后的一个副站班次)
  745 + var oNextSlaveBc; // 下一个副站班次
  746 +
  747 + // 当初始化完一圈的主站班次后,最后一个班次是下一圈的上标线主站班次,需要判定存在然后添加间隔
  748 + var _modifyTimeNextGroupIndex; // 上标线下一圈索引
  749 + var _modifyTimeNextBcIndex; // 上标线下一圈班次索引
  750 + var _modifyBc; // 上标线下一个圈的班次
  751 +
  752 + var iStart = iGroupIndex;
  753 + var iEnd = iGroupIndex + iCount;
  754 + if (iEnd > this._qCount) {
  755 + iEnd = this._qCount;
  756 + }
  757 +
  758 + for (i = iStart; i < iEnd; i++) {
  759 + aBcInterval = StrategyUtils_v2_2.sFn("CALCU_HEADWAY_2")(
  760 + this,
  761 + this._oParam,
  762 + i,
  763 + this._iFirstMasterBcIndex,
  764 + this._$calcuCycleTime(oPreBc.getFcTimeObj())[0],
  765 + this._$calcuCycleTime(oPreBc.getFcTimeObj())[1]
  766 + );
  767 +
  768 + if (aBcInterval.length == 0) {
  769 + // 等于0说明上标线没班次了
  770 + break;
  771 + }
  772 +
  773 + for (j = 1; j < this._internalLpArray.length; j++) {
  774 + oBcInterval = aBcInterval[j - 1];
  775 + if (oBcInterval.hasBc) {
  776 + iNextBcInterval = oBcInterval.iFcInterval;
  777 + oNextBcFcTime = this._oParam.addMinute(oPreBc.getFcTimeObj(), iNextBcInterval);
  778 + this._internalLpArray[j].fnSetVerticalIntervalTime(i, this._iFirstMasterBcIndex, iNextBcInterval);
  779 + this._internalLpArray[j].fnSetHeadwayS2_P(i, this._iFirstMasterBcIndex, oBcInterval.fP);
  780 +
  781 + oNextBc = _utils.createBcObj(
  782 + this._internalLpArray[j],
  783 + "normal",
  784 + this._oParam.isUpOneWayStop(),
  785 + 1,
  786 + oNextBcFcTime,
  787 + this._oParam);
  788 +
  789 + this._internalLpArray[j].setBc(
  790 + i, this._iFirstMasterBcIndex, oNextBc);
  791 + oPreBc = oNextBc;
  792 + }
  793 + }
  794 +
  795 + // 修正上标线主站方向班次(一圈的结束班次,也是下一圈的开始班次)以及后续所有班次
  796 + oBcInterval = aBcInterval[j - 1];
  797 + if (oBcInterval.hasBc) {
  798 + iNextBcInterval = oBcInterval.iFcInterval;
  799 + _modifyTimeNextGroupIndex = i + 1;
  800 + _modifyTimeNextBcIndex = this._iFirstMasterBcIndex;
  801 +
  802 + _utils.modifySBXMasterBc(
  803 + this._internalLpArray[0],
  804 + this._oParam.addMinute(oPreBc.getFcTimeObj(), iNextBcInterval),
  805 + _modifyTimeNextGroupIndex,
  806 + _modifyTimeNextBcIndex,
  807 + oPreBc.isUp(),
  808 + this._oParam
  809 + );
  810 +
  811 + // 修正上标线主站方向的班次后,一圈结束的班次可能不存在(超过末班车时间了),需要判定
  812 + _modifyBc = this._internalLpArray[0].getBc(_modifyTimeNextGroupIndex, _modifyTimeNextBcIndex);
  813 + if (_modifyBc) { // 存在修正间隔值
  814 + this._internalLpArray[0].fnSetVerticalIntervalTime(
  815 + _modifyTimeNextGroupIndex, _modifyTimeNextBcIndex, iNextBcInterval);
  816 + oPreBc = _modifyBc;
  817 + }
  818 +
  819 + }
  820 +
  821 + // 添加副站班次,就是主站班次到达时间加1分钟
  822 + // TODO:因为副站停站时间1分钟到3分钟,几乎没有停站时间,一般前面主站是多少间隔,后面如果有副站的话也是多少间隔
  823 + // TODO:此时,可能出现临界问题,当主站还是高峰接近低谷时,副站已经是低谷,此时副站发车间隔还是高峰间隔
  824 + // TODO:上述情况可以通过让临界的主站高峰班次使用高峰最大间隔,副站使用3分钟的最大停站使副站间隔达到低谷最小间隔
  825 + oPreSlaveBc = this._internalLpArray[0].getBc(
  826 + this._iFirstMasterBcIndex == 0 ? i : i + 1,
  827 + this._iFirstMasterBcIndex == 0 ? 1 : 0
  828 + );
  829 + for (j = 1; j < this._internalLpArray.length; j++) {
  830 + if (oPreSlaveBc) {
  831 + if (aBcInterval[j - 1].hasBc) { // 有主站必有副站
  832 + // 获取当前路牌前一个主站班次
  833 + if (this._internalLpArray[j].getBc(
  834 + i,
  835 + this._iFirstMasterBcIndex)) { // 相同路牌上一个主站班次存在
  836 + oNextSlaveBc = _utils.createBcObj(
  837 + this._internalLpArray[j],
  838 + "normal",
  839 + !this._oParam.isUpOneWayStop(),
  840 + 1,
  841 + this._oParam.addMinute( // 使用1分钟副站停站
  842 + this._internalLpArray[j].getBc(
  843 + i, this._iFirstMasterBcIndex).getArrTimeObj(),
  844 + 1),
  845 + this._oParam);
  846 +
  847 + if (oNextSlaveBc.isUp()) {
  848 + if (!oNextSlaveBc.getFcTimeObj().isAfter(this._oParam.getUpLastDtimeObj())) {
  849 + this._internalLpArray[j].setBc(
  850 + this._iFirstMasterBcIndex == 0 ? i : i + 1,
  851 + this._iFirstMasterBcIndex == 0 ? 1 : 0,
  852 + oNextSlaveBc);
  853 + oPreSlaveBc = oNextSlaveBc;
  854 + }
  855 + } else {
  856 + if (!oPreSlaveBc.getFcTimeObj().isAfter(this._oParam.getDownLastDTimeObj())) {
  857 + this._internalLpArray[j].setBc(
  858 + this._iFirstMasterBcIndex == 0 ? i : i + 1,
  859 + this._iFirstMasterBcIndex == 0 ? 1 : 0,
  860 + oNextSlaveBc);
  861 + oPreSlaveBc = oNextSlaveBc;
  862 + }
  863 + }
  864 + }
  865 + }
  866 + }
  867 + }
  868 +
  869 +
  870 + }
  871 +
  872 + };
  873 +
  874 + //------------- 其他业务方法 -------------//
  875 +
  876 + /**
  877 + * 调整发车间隔。
  878 + */
  879 + InternalScheduleObj.prototype.fnAdjustHeadway = function() {
  880 + // // TODO:572测试,尝试调整第6圈
  881 + // StrategyUtils_v2_2.sFn("ADJUST_HEADWAY_2")(
  882 + // this, this._oParam,
  883 + // 6, 0,
  884 + // 6, 1,
  885 + // 0.2
  886 + // );
  887 + // // TODO:843测试
  888 + // StrategyUtils_v2_2.sFn("ADJUST_HEADWAY_2")(
  889 + // this, this._oParam,
  890 + // 3, 0,
  891 + // 3, 1,
  892 + // 0.2
  893 + // );
  894 +
  895 + var i;
  896 + var bQIsAnotherWay; // 圈的第一个班次是否副站
  897 + if (this._qIsUp) {
  898 + if (this._oParam.getDirAnotherWayStop()) {
  899 + bQIsAnotherWay = true;
  900 + } else {
  901 + bQIsAnotherWay = false;
  902 + }
  903 + } else {
  904 + if (this._oParam.getDirAnotherWayStop()) {
  905 + bQIsAnotherWay = false;
  906 + } else {
  907 + bQIsAnotherWay = true;
  908 + }
  909 + }
  910 +
  911 + if (this._qIsUp == bQIsAnotherWay) {
  912 + for (i = 0; i < this._qCount; i++) {
  913 + StrategyUtils_v2_2.sFn("ADJUST_HEADWAY_2")(
  914 + this, this._oParam,
  915 + i, 0,
  916 + i, 1,
  917 + 0.2
  918 + );
  919 + }
  920 + } else { // 圈的第一个班次是主站班次
  921 + for (i = 0; i < this._qCount; i++) {
  922 + if ((i + 1) < this._qCount) {
  923 + StrategyUtils_v2_2.sFn("ADJUST_HEADWAY_2")(
  924 + this, this._oParam,
  925 + i, 1,
  926 + (i + 1), 0,
  927 + 0.2
  928 + );
  929 + }
  930 + }
  931 + }
  932 +
  933 +
  934 + };
  935 +
  936 + /**
  937 + * 计算吃饭班次。
  938 + */
  939 + InternalScheduleObj.prototype.fnCalcuEatBc = function() {
  940 + var i;
  941 + var j;
  942 + var oLp;
  943 + var oBc;
  944 + // 1、标记吃饭班次
  945 + var oEatFlag = {}; // {"路牌编号":{isLaunch: false, isDinner: false},...}
  946 + for (i = 0; i < this._internalLpArray.length; i++) {
  947 + oLp = this._internalLpArray[i];
  948 + if (oLp.isBxLb()) { // 暂时判定只有连班吃饭
  949 + oEatFlag[oLp.getLpNo()] = {};
  950 + oEatFlag[oLp.getLpNo()]["isLaunch"] = false;
  951 + oEatFlag[oLp.getLpNo()]["isDinner"] = false;
  952 + for (j = 0; j < oLp.getBcArray().length; j++) {
  953 + oBc = oLp.getBcArray()[j];
  954 + // 午饭,暂时判定10:30到13:00
  955 + if (oBc.isUp() == this._oParam.isUpOneWayStop() &&
  956 + oBc.getFcTimeObj().isAfter(this._oParam.toTimeObj("10:30")) &&
  957 + oBc.getFcTimeObj().isBefore(this._oParam.toTimeObj("13:30"))) {
  958 + if (!oEatFlag[oLp.getLpNo()]["isLaunch"]) {
  959 + oBc.fnSetEatTime(this._oParam.fnGetLunchTime());
  960 + oEatFlag[oLp.getLpNo()]["isLaunch"] = true;
  961 + // console.log("吃饭班次时间=" + oBc.format("HH:mm"));
  962 + }
  963 + }
  964 + // 晚饭,暂时判定17:30
  965 + if (oBc.isUp() == this._oParam.isUpOneWayStop() &&
  966 + oBc.getFcTimeObj().isAfter(this._oParam.toTimeObj("17:00")) &&
  967 + oBc.getFcTimeObj().isBefore(this._oParam.toTimeObj("20:00"))) {
  968 + if (!oEatFlag[oLp.getLpNo()]["isDinner"]) {
  969 + oBc.fnSetEatTime(this._oParam.fnGetDinnerTime());
  970 + oEatFlag[oLp.getLpNo()]["isDinner"] = true;
  971 + // console.log("晚饭班次时间=" + oBc.format("HH:mm"));
  972 + }
  973 + }
  974 + }
  975 + }
  976 + }
  977 +
  978 + // 2、调整吃饭所需的停站时间
  979 + StrategyUtils_v2_2.sFn("ADJUST_HEADWAY_3_EAT")(
  980 + this, this._oParam
  981 + );
  982 + };
  983 +
  984 + /**
  985 + * 计算末班车。
  986 + * 1、将上下行拉成上下行两个班次列表(包括标记班次)
  987 + * 2、分别找出离末班车发车时间最近的班次,并替换时间
  988 + * 3、删除之后的班次
  989 + */
  990 + InternalScheduleObj.prototype.fnCalcuLastBc = function() {
  991 + var i;
  992 + var iTimeDiff;
  993 + var iTempTime;
  994 + var aBc;
  995 + var oLastBcTime;
  996 + var oLastBcIsUp;
  997 + var iModifyIndex;
  998 +
  999 + // 查找末班车早的末班车时间和方向
  1000 + if (this._oParam.getUpLastDtimeObj().isBefore(this._oParam.getDownLastDTimeObj())) {
  1001 + oLastBcTime = this._oParam.getUpLastDtimeObj();
  1002 + oLastBcIsUp = true;
  1003 + } else {
  1004 + oLastBcTime = this._oParam.getDownLastDTimeObj();
  1005 + oLastBcIsUp = false;
  1006 + }
  1007 +
  1008 + // 确定早的末班车时间
  1009 + aBc = this.fnGetBcList(oLastBcIsUp);
  1010 + for (i = 0; i < aBc.length; i++) {
  1011 + iTempTime = oLastBcTime.diff(aBc[i].getFcTimeObj(), "m");
  1012 + if (iTimeDiff == undefined) {
  1013 + iTimeDiff = iTempTime;
  1014 + iModifyIndex = i;
  1015 + } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff)) {
  1016 + iTimeDiff = iTempTime;
  1017 + iModifyIndex = i;
  1018 + }
  1019 + }
  1020 + aBc[iModifyIndex].addMinuteToFcsj(iTimeDiff); // 替换成末班车时间
  1021 + aBc[iModifyIndex].fnSetDelFlag(false);
  1022 + aBc[iModifyIndex].fnSetIsLastBc(true);
  1023 + for (i = iModifyIndex + 1; i < aBc.length; i++) { // 删除多余班次
  1024 + this._qIsUp == oLastBcIsUp ?
  1025 + aBc[i]._$$_internal_group_obj.setBc1(undefined) :
  1026 + aBc[i]._$$_internal_group_obj.setBc2(undefined);
  1027 + }
  1028 +
  1029 + // 查找末班车晚的末班车时间和方向
  1030 + if (this._oParam.getUpLastDtimeObj().isBefore(this._oParam.getDownLastDTimeObj())) {
  1031 + oLastBcTime = this._oParam.getDownLastDTimeObj();
  1032 + oLastBcIsUp = false;
  1033 + } else {
  1034 + oLastBcTime = this._oParam.getUpLastDtimeObj();
  1035 + oLastBcIsUp = true;
  1036 + }
  1037 + // 确定晚的末班车时间
  1038 + aBc = this.fnGetBcList(oLastBcIsUp);
  1039 + var oBc;
  1040 + var aBcIndex;
  1041 + var iLpIndex;
  1042 + var iQIndex;
  1043 + var iBcIndex;
  1044 +
  1045 + iTimeDiff = undefined;
  1046 + for (i = 0; i < aBc.length; i++) {
  1047 + oBc = aBc[i];
  1048 + aBcIndex = this.fnGetBcIndex(oBc);
  1049 +
  1050 + iLpIndex = aBcIndex[0];
  1051 + iQIndex = aBcIndex[2] == 0 ? aBcIndex[1] -1 : aBcIndex[1];
  1052 + iBcIndex = aBcIndex[2] == 0 ? 1 : 0;
  1053 +
  1054 + if (!this._internalLpArray[iLpIndex].getBc(iQIndex, iBcIndex)) {
  1055 + continue;
  1056 + }
  1057 +
  1058 + iTempTime = oLastBcTime.diff(aBc[i].getFcTimeObj(), "m");
  1059 + if (iTimeDiff == undefined) {
  1060 + iTimeDiff = iTempTime;
  1061 + iModifyIndex = i;
  1062 + } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff)) {
  1063 + iTimeDiff = iTempTime;
  1064 + iModifyIndex = i;
  1065 + }
  1066 + }
  1067 + aBc[iModifyIndex].addMinuteToFcsj(iTimeDiff); // 替换成末班车时间
  1068 + aBc[iModifyIndex].fnSetDelFlag(false);
  1069 + aBc[iModifyIndex].fnSetIsLastBc(true);
  1070 + for (i = iModifyIndex + 1; i < aBc.length; i++) { // 删除多余班次
  1071 + this._qIsUp == oLastBcIsUp ?
  1072 + aBc[i]._$$_internal_group_obj.setBc1(undefined) :
  1073 + aBc[i]._$$_internal_group_obj.setBc2(undefined);
  1074 + }
  1075 + };
  1076 +
  1077 + /**
  1078 + * 重新设置停站时间(发车时间减到达时间)。
  1079 + */
  1080 + InternalScheduleObj.prototype.fnReSetLayoverTime = function() {
  1081 + for (var i = 0; i < this._internalLpArray.length; i++) {
  1082 + this._internalLpArray[i].modifyLayoverTimeWithoutFcTime();
  1083 + }
  1084 + };
  1085 +
  1086 + /**
  1087 + * 补进出场例保班次。
  1088 + */
  1089 + InternalScheduleObj.prototype.fnCalcuOtherBc = function() {
  1090 + var i;
  1091 + var j;
  1092 + var iBcChainCount;
  1093 + var oLp;
  1094 + var aOtherBc;
  1095 + var oStartBc;
  1096 + var oEndBc;
  1097 +
  1098 + for (i = 0; i < this._internalLpArray.length; i++) {
  1099 + aOtherBc = [];
  1100 + oLp = this._internalLpArray[i];
  1101 + iBcChainCount = oLp.fnGetBcChainCount();
  1102 +
  1103 + if (iBcChainCount == 1) { // 只有一个车次链,是连班班型
  1104 + // 头部要添加出场,例保班次
  1105 + oStartBc = oLp.getBc(
  1106 + oLp.fnGetBcChainInfo(0)["s_q"],
  1107 + oLp.fnGetBcChainInfo(0)["s_b"]
  1108 + );
  1109 + aOtherBc.push(_utils.createBcObj(
  1110 + oLp, "bd", oStartBc.isUp(), 1,
  1111 + oStartBc.getFcTimeObj(),
  1112 + this._oParam
  1113 + ));
  1114 + aOtherBc.push(_utils.createBcObj(
  1115 + oLp, "out", oStartBc.isUp(), 1,
  1116 + oStartBc.getFcTimeObj(),
  1117 + this._oParam
  1118 + ));
  1119 +
  1120 + // 尾部需添加进场,例保班次
  1121 + oEndBc = oLp.getBc(
  1122 + oLp.fnGetBcChainInfo(0)["e_q"],
  1123 + oLp.fnGetBcChainInfo(0)["e_b"]
  1124 + );
  1125 + oEndBc.fnSetIsLastBc(false); // 有可能最后一个班次是吃饭班次,重置
  1126 + oEndBc.fnSetEatTime(0); // 有可能最后一个班次是吃饭班次,重置
  1127 + aOtherBc.push(_utils.createBcObj(
  1128 + oLp, "in", !oEndBc.isUp(), 1,
  1129 + oEndBc.getArrTimeObj(),
  1130 + this._oParam
  1131 + ));
  1132 + aOtherBc.push(_utils.createBcObj(
  1133 + oLp, "lc", !oEndBc.isUp(), 1,
  1134 + oEndBc.getArrTimeObj(),
  1135 + this._oParam
  1136 + ));
  1137 + } else if (iBcChainCount == 2) { // 两个车次链,是分班班型
  1138 + // 第一个车次链开头有出场,报到班次,车次链结尾只有进场班次
  1139 + oStartBc = oLp.getBc(
  1140 + oLp.fnGetBcChainInfo(0)["s_q"],
  1141 + oLp.fnGetBcChainInfo(0)["s_b"]
  1142 + );
  1143 + aOtherBc.push(_utils.createBcObj(
  1144 + oLp, "bd", oStartBc.isUp(), 1,
  1145 + oStartBc.getFcTimeObj(),
  1146 + this._oParam
  1147 + ));
  1148 + aOtherBc.push(_utils.createBcObj(
  1149 + oLp, "out", oStartBc.isUp(), 1,
  1150 + oStartBc.getFcTimeObj(),
  1151 + this._oParam
  1152 + ));
  1153 +
  1154 + oEndBc = oLp.getBc(
  1155 + oLp.fnGetBcChainInfo(0)["e_q"],
  1156 + oLp.fnGetBcChainInfo(0)["e_b"]
  1157 + );
  1158 + aOtherBc.push(_utils.createBcObj(
  1159 + oLp, "in", !oEndBc.isUp(), 1,
  1160 + oEndBc.getArrTimeObj(),
  1161 + this._oParam
  1162 + ));
  1163 +
  1164 + // 第二个车次链开头有出场,报到班次,车次链结尾有进场,报到班次
  1165 + oStartBc = oLp.getBc(
  1166 + oLp.fnGetBcChainInfo(1)["s_q"],
  1167 + oLp.fnGetBcChainInfo(1)["s_b"]
  1168 + );
  1169 + aOtherBc.push(_utils.createBcObj(
  1170 + oLp, "bd", oStartBc.isUp(), 1,
  1171 + oStartBc.getFcTimeObj(),
  1172 + this._oParam
  1173 + ));
  1174 + aOtherBc.push(_utils.createBcObj(
  1175 + oLp, "out", oStartBc.isUp(), 1,
  1176 + oStartBc.getFcTimeObj(),
  1177 + this._oParam
  1178 + ));
  1179 +
  1180 + oEndBc = oLp.getBc(
  1181 + oLp.fnGetBcChainInfo(1)["e_q"],
  1182 + oLp.fnGetBcChainInfo(1)["e_b"]
  1183 + );
  1184 + aOtherBc.push(_utils.createBcObj(
  1185 + oLp, "in", !oEndBc.isUp(), 1,
  1186 + oEndBc.getArrTimeObj(),
  1187 + this._oParam
  1188 + ));
  1189 + aOtherBc.push(_utils.createBcObj(
  1190 + oLp, "lc", !oEndBc.isUp(), 1,
  1191 + oEndBc.getArrTimeObj(),
  1192 + this._oParam
  1193 + ));
  1194 +
  1195 +
  1196 + } else {
  1197 + // 2个车次链以上,暂时没有此班型
  1198 + }
  1199 +
  1200 + oLp.addOtherBcArray(aOtherBc);
  1201 + }
  1202 + };
  1203 +
  1204 +
  1205 + //------------- 其他非业务方法方法 -------------//
  1206 + /**
  1207 + * 获取班次列表。
  1208 + * @param isUp boolean 是否上行
  1209 + * @returns [(InternalBcObj)]
  1210 + */
  1211 + InternalScheduleObj.prototype.fnGetBcList = function(isUp) {
  1212 + var i;
  1213 + var j;
  1214 + var oLp;
  1215 + var oBc;
  1216 + var aBc = [];
  1217 +
  1218 + for (j = 0; j < this._qCount; j++) {
  1219 + for (i = 0; i < this._internalLpArray.length; i++) {
  1220 + oLp = this._internalLpArray[i];
  1221 + oBc = oLp.getBc(
  1222 + j,
  1223 + this._qIsUp == isUp ? 0 : 1
  1224 + );
  1225 + if (oBc) {
  1226 + aBc.push(oBc);
  1227 + }
  1228 + }
  1229 + }
  1230 +
  1231 + var aBcFcTime = [];
  1232 + for (i = 0; i < aBc.length; i++) {
  1233 + oBc = aBc[i];
  1234 + aBcFcTime.push(oBc.getFcTimeObj().format("HH:mm"));
  1235 + }
  1236 + console.log((isUp ? "上行班次列表:" : "下行班次列表:") + aBcFcTime.join(","));
  1237 +
  1238 + return aBc;
  1239 + };
  1240 +
  1241 + /**
  1242 + * 获取班次索引。
  1243 + * @param oBc 班次对象
  1244 + * @returns [{路牌索引},{圈索引},{班次索引}]
  1245 + */
  1246 + InternalScheduleObj.prototype.fnGetBcIndex = function(oBc) {
  1247 + // 路牌索引
  1248 + var i;
  1249 + var iLpIndex;
  1250 + for (i = 0; i < this._internalLpArray.length; i++) {
  1251 + if (this._internalLpArray[i]._$$_orign_lp_obj == oBc._$$_internal_lp_obj._$$_orign_lp_obj) {
  1252 + iLpIndex = i;
  1253 + break;
  1254 + }
  1255 + }
  1256 + // 圈索引
  1257 + var j;
  1258 + var iGroupIndex;
  1259 + var bFlag = false;
  1260 + for (i = 0; i < this._internalLpArray.length; i++) {
  1261 + if (bFlag) {
  1262 + break;
  1263 + }
  1264 + for (j = 0; j < this._qCount; j++) {
  1265 + if (this._internalLpArray[i]._$_groupBcArray[j] == oBc._$$_internal_group_obj) {
  1266 + iGroupIndex = j;
  1267 + bFlag = true;
  1268 + break;
  1269 + }
  1270 + }
  1271 + }
  1272 + // 班次索引
  1273 + var iBcIndex = this._qIsUp == oBc.isUp() ? 0 : 1;
  1274 +
  1275 + if (iLpIndex == undefined) {
  1276 + return null;
  1277 + } else {
  1278 + return [].concat(iLpIndex, iGroupIndex, iBcIndex);
  1279 + }
  1280 + };
  1281 +
  1282 + /**
  1283 + * 返回内部路牌数据列表。
  1284 + * @returns {Array}
  1285 + */
  1286 + InternalScheduleObj.prototype.fnGetLpArray = function() {
  1287 + return this._internalLpArray;
  1288 + };
  1289 +
  1290 + /**
  1291 + * 获取班型描述。
  1292 + * @return {*[]}
  1293 + */
  1294 + InternalScheduleObj.prototype.fnGetBxDesc = function() {
  1295 + return this._aBxDesc;
  1296 + };
  1297 +
  1298 + /**
  1299 + * 获取圈的第一个班次是上行还是下行。
  1300 + * @return {boolean|*}
  1301 + */
  1302 + InternalScheduleObj.prototype.fnGetGroupIsUp = function() {
  1303 + return this._qIsUp;
  1304 + };
  1305 +
  1306 + /**
  1307 + * 返回内部工具对象。
  1308 + * @return {{createBcObj, modifySBXMasterBc}}
  1309 + */
  1310 + InternalScheduleObj.prototype.fnGetUitls = function() {
  1311 + return _utils;
  1312 + };
  1313 +
  1314 + /**
  1315 + * 内部数据转化成显示用的班次数组。
  1316 + */
  1317 + InternalScheduleObj.prototype.fnToGanttBcArray = function() {
  1318 + var aAllBc = [];
  1319 + var aLpBc = [];
  1320 + var aEatBc = [];
  1321 + var oLp;
  1322 + var i;
  1323 + var j;
  1324 +
  1325 + for (i = 0; i < this._internalLpArray.length; i++) {
  1326 + oLp = this._internalLpArray[i];
  1327 + aLpBc = [];
  1328 + aLpBc = aLpBc.concat(oLp.getOtherBcArray(), oLp.getBcArray());
  1329 +
  1330 + aEatBc = [];
  1331 + // TODO:根据班次的吃饭时间添加吃饭班次
  1332 + for (j = 0; j < aLpBc.length; j++) {
  1333 + if (aLpBc[j].fnGetEatTime() > 0) {
  1334 + aEatBc.push(_utils.createBcObj(
  1335 + oLp,
  1336 + "cf",
  1337 + aLpBc[j].isUp(), // 和上一个班次方向相反
  1338 + 1,
  1339 + this._oParam.addMinute(aLpBc[j].getFcTimeObj(), -aLpBc[j].fnGetEatTime()),
  1340 + this._oParam
  1341 + ));
  1342 + }
  1343 + }
  1344 + aLpBc = aLpBc.concat(aEatBc);
  1345 +
  1346 + // 按照发车时间排序
  1347 + aLpBc.sort(function(o1, o2) {
  1348 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1349 + return -1;
  1350 + } else {
  1351 + return 1;
  1352 + }
  1353 + });
  1354 +
  1355 + // 重新赋值fcno
  1356 + for (j = 0; j < aLpBc.length; j++) {
  1357 + aLpBc[j].fnSetFcno(j + 1);
  1358 + }
  1359 +
  1360 + aAllBc = aAllBc.concat(aLpBc);
  1361 + }
  1362 +
  1363 + var aGanttBc = [];
  1364 + for (i = 0; i < aAllBc.length; i++) {
  1365 + aGanttBc.push(aAllBc[i].toGanttBcObj());
  1366 + }
  1367 +
  1368 + return aGanttBc;
  1369 + };
  1370 +
  1371 + /**
  1372 + * 计算指定开始时间,指定方向班次执行后的最大最小停站时间。
  1373 + * @param oStartFcTime 开始发车时间
  1374 + * @param isUp 是否上行
  1375 + * @returns array [最小值,最大值]
  1376 + */
  1377 + InternalScheduleObj.prototype._$calcuLayoverTime = function(oStartFcTime, isUp) {
  1378 + var aRtn = [];
  1379 + var _iRunningTime; // 行驶时间
  1380 + var _iLayoverTime; // 停站时间
  1381 +
  1382 + // 最小停站时间
  1383 + _iRunningTime = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(
  1384 + isUp, oStartFcTime, this._oParam);
  1385 + _iLayoverTime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  1386 + oStartFcTime, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"),
  1387 + this._oParam)[0]; // 最小停站
  1388 + aRtn.push(_iLayoverTime);
  1389 +
  1390 + // 最大停站时间
  1391 + _iRunningTime = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(
  1392 + isUp, oStartFcTime, this._oParam);
  1393 + _iLayoverTime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  1394 + oStartFcTime, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"),
  1395 + this._oParam)[1]; // 最大停站
  1396 + aRtn.push(_iLayoverTime);
  1397 +
  1398 + return aRtn;
  1399 + };
  1400 +
  1401 + /**
  1402 + * 计算指定时间,指定方向开始的最大最小周转时间
  1403 + * @param oStartFcTime 开始发车时间
  1404 + * @param isUp 是否上行
  1405 + * @returns array [最小值,最大值]
  1406 + * @private
  1407 + */
  1408 + InternalScheduleObj.prototype._$calcuCycleTime = function(oStartFcTime, isUp) {
  1409 + var aRtn = [];
  1410 + var _iRunningTime; // 行驶时间
  1411 + var _iLayoverTime; // 停站时间
  1412 + var _iCycleTime; // 周转时间
  1413 + var _oNextFcTime;
  1414 +
  1415 + // 最小周转时间
  1416 + _iRunningTime = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(
  1417 + isUp, oStartFcTime, this._oParam);
  1418 + _iLayoverTime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  1419 + oStartFcTime, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"),
  1420 + this._oParam)[0]; // 最小停站
  1421 + _iCycleTime = _iRunningTime + _iLayoverTime;
  1422 + _oNextFcTime = this._oParam.addMinute(oStartFcTime, (_iRunningTime + _iLayoverTime));
  1423 + _iRunningTime = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(
  1424 + !isUp, _oNextFcTime, this._oParam);
  1425 + _iLayoverTime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  1426 + _oNextFcTime, !isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"),
  1427 + this._oParam)[0]; // 最小停站
  1428 + _iCycleTime += _iRunningTime;
  1429 + _iCycleTime += _iLayoverTime;
  1430 +
  1431 + aRtn.push(_iCycleTime);
  1432 +
  1433 + // 最大周转时间
  1434 + _iRunningTime = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(
  1435 + isUp, oStartFcTime, this._oParam);
  1436 + _iLayoverTime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  1437 + oStartFcTime, isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"),
  1438 + this._oParam)[1]; // 最大停站
  1439 + _iCycleTime = _iRunningTime + _iLayoverTime;
  1440 + _oNextFcTime = this._oParam.addMinute(oStartFcTime, (_iRunningTime + _iLayoverTime));
  1441 + _iRunningTime = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(
  1442 + !isUp, _oNextFcTime, this._oParam);
  1443 + _iLayoverTime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  1444 + _oNextFcTime, !isUp, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"),
  1445 + this._oParam)[1]; // 最大停站
  1446 + _iCycleTime += _iRunningTime;
  1447 + _iCycleTime += _iLayoverTime;
  1448 +
  1449 + aRtn.push(_iCycleTime);
  1450 +
  1451 + return aRtn;
  1452 + };
  1453 +
  1454 + //-------------------- static静态方法 ----------------------//
  1455 +
  1456 + /**
  1457 + * 计算车辆数(最大周转时间/最大发车间隔)。
  1458 + * @param oParam 参数对象
  1459 + */
  1460 + InternalScheduleObj.calcuClzx = function(oParam) {
  1461 + var _iUpRT; // 上行行驶时间
  1462 + var _iUpLT; // 上行停站时间
  1463 + var _iDownRT; // 下行行驶时间
  1464 + var _iDownLT; // 下行停站时间
  1465 +
  1466 + // 计算早高峰最大周转时间
  1467 + _iUpRT = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(true, oParam.getMPeakStartTimeObj(), oParam);
  1468 + _iUpLT = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  1469 + oParam.getMPeakStartTimeObj(), true,
  1470 + StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam)[1]; // 使用最大停站时间
  1471 + _iDownRT = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(false, oParam.getMPeakStartTimeObj(), oParam);
  1472 + _iDownLT = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  1473 + oParam.getMPeakStartTimeObj(), false,
  1474 + StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam)[1]; // 使用最大停站时间
  1475 + var _iAMPeakRCTime = _iUpRT + _iUpLT + _iDownRT + _iDownLT;
  1476 + // 早高峰预估车辆数,使用早高峰最大发车间隔
  1477 + var _iAMPeakVehicleCount = _iAMPeakRCTime / oParam.getMPeakMaxFcjx();
  1478 +
  1479 + // 计算晚高峰最大周转时间
  1480 + _iUpRT = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(true, oParam.getEPeakStartTimeObj(), oParam);
  1481 + _iUpLT = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  1482 + oParam.getEPeakStartTimeObj(), true,
  1483 + StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam)[1]; // 使用最大停站时间
  1484 + _iDownRT = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(false, oParam.getEPeakStartTimeObj(), oParam);
  1485 + _iDownLT = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  1486 + oParam.getEPeakStartTimeObj(), false,
  1487 + StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), oParam)[1]; // 使用最大停站时间
  1488 + var _iPMPeakRCTime = _iUpRT + _iUpLT + _iDownRT + _iDownLT;
  1489 + // 晚高峰预估车辆数,使用晚高峰最大发车间隔
  1490 + var _iPMPeakVehicleCount = _iPMPeakRCTime / oParam.getEPeakMaxFcjx();
  1491 +
  1492 + // 取最大值为最终车辆数
  1493 + // 大于或等于的最小整数,人话就是有小数点就加1
  1494 + if (_iAMPeakVehicleCount > _iPMPeakVehicleCount) {
  1495 + return Math.ceil(_iAMPeakVehicleCount);
  1496 + } else {
  1497 + return Math.ceil(_iPMPeakVehicleCount);
  1498 + }
  1499 +
  1500 + };
  1501 +
  1502 +
  1503 + return InternalScheduleObj;
1460 }()); 1504 }());
1461 \ No newline at end of file 1505 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/Main_v2_2_ExcelObj.js
@@ -300,8 +300,62 @@ var Main_v2_2_ExcelObj = (function() { @@ -300,8 +300,62 @@ var Main_v2_2_ExcelObj = (function() {
300 oExcelLp.groupCount = iGroupCount; 300 oExcelLp.groupCount = iGroupCount;
301 oExcelLp.stationRouteId1 = stationRouteId1; 301 oExcelLp.stationRouteId1 = stationRouteId1;
302 oExcelLp.stationRouteId2 = stationRouteId2; 302 oExcelLp.stationRouteId2 = stationRouteId2;
  303 +
  304 + // 删除临时参数
  305 + delete oExcelLp["_bcObjGroupList"];
  306 + }
  307 +
  308 + // 路牌数据统计
  309 + var j = 0;
  310 + var aLpBc;
  311 + var oLpBc;
  312 + for (i = 0; i < this._aExcelLp.length; i++) {
  313 + oExcelLp = this._aExcelLp[i];
  314 + aLpBc = oExcelLp.bcObjList;
  315 + for (j = 0; j < aLpBc.length; j++) {
  316 + oLpBc = aLpBc[j];
  317 + if (oLpBc.bcType == "normal") {
  318 + oExcelLp.zlc = oExcelLp.zlc +
  319 + oLpBc._bclc; // 总里程
  320 + oExcelLp.yylc = oExcelLp.yylc +
  321 + oLpBc._bclc; // 营运里程
  322 + oExcelLp.yygs = oExcelLp.yygs +
  323 + oLpBc.bcsj + // 班次时间
  324 + oLpBc.ssj + // 停站时间
  325 + oLpBc.eatsj; // 吃饭时间
  326 + oExcelLp.yybc = oExcelLp.yybc + 1;
  327 +
  328 + oExcelLp.zgs = oExcelLp.zgs +
  329 + oLpBc.bcsj + // 班次时间
  330 + oLpBc.ssj + // 停站时间
  331 + oLpBc.eatsj; // 吃饭时间
  332 + oExcelLp.zbc = oExcelLp.zbc + 1;
  333 + } else if (
  334 + oLpBc.bcType == "bd" ||
  335 + oLpBc.bcType == "out" ||
  336 + oLpBc.bcType == "in" ||
  337 + oLpBc.bcType == "lc") {
  338 + oExcelLp.kslc = oExcelLp.kslc +
  339 + oLpBc._bclc; // 里程
  340 + oExcelLp.zlc = oExcelLp.zlc +
  341 + oLpBc._bclc; // 里程
  342 + oExcelLp.zgs = oExcelLp.zgs +
  343 + oLpBc.bcsj + // 班次时间
  344 + oLpBc.ssj; // 停站时间
  345 +
  346 + if (oLpBc.bcType != "bd" && oLpBc.bcType != "lc") {
  347 + oExcelLp.zbc = oExcelLp.zbc + 1;
  348 + }
  349 +
  350 + }
  351 +
  352 + delete oLpBc._bclc; // 删除临时变量
  353 +
  354 + }
303 } 355 }
304 356
  357 +
  358 +
305 return this._aExcelLp; 359 return this._aExcelLp;
306 }; 360 };
307 361
@@ -310,7 +364,22 @@ var Main_v2_2_ExcelObj = (function() { @@ -310,7 +364,22 @@ var Main_v2_2_ExcelObj = (function() {
310 InternalCalcuExcelBc1.prototype._fnSortBc = function(aGanttBc) { 364 InternalCalcuExcelBc1.prototype._fnSortBc = function(aGanttBc) {
311 var oParam = this._oParam; 365 var oParam = this._oParam;
312 aGanttBc.sort(function (o1, o2) { // 时间从早到晚排序 366 aGanttBc.sort(function (o1, o2) { // 时间从早到晚排序
313 - if (oParam.toTimeObj(o1.fcsj).isBefore(oParam.toTimeObj(o2.fcsj))) { 367 + var o1_fcsj;
  368 + var o2_fcsj;
  369 + if (o1.fcsj.indexOf("00:") >= 0) { // 大于00点是第二天
  370 + o1_fcsj = oParam.toTimeObj(o1.fcsj).add(1, "d");
  371 + } else {
  372 + o1_fcsj = oParam.toTimeObj(o1.fcsj);
  373 + }
  374 +
  375 + if (o2.fcsj.indexOf("00:") >= 0) { // 大于00点是第二天
  376 + o2_fcsj = oParam.toTimeObj(o2.fcsj).add(1, "d");
  377 + } else {
  378 + o2_fcsj = oParam.toTimeObj(o2.fcsj);
  379 + }
  380 +
  381 +
  382 + if (o1_fcsj.isBefore(o2_fcsj)) {
314 return -1; 383 return -1;
315 } else { 384 } else {
316 return 1; 385 return 1;
@@ -340,6 +409,9 @@ var Main_v2_2_ExcelObj = (function() { @@ -340,6 +409,9 @@ var Main_v2_2_ExcelObj = (function() {
340 j = this._calcuExcelBcPerGroup(!this._bQIsUp, j); 409 j = this._calcuExcelBcPerGroup(!this._bQIsUp, j);
341 } while(i < aUpBc.length || j < aDownBc.length); 410 } while(i < aUpBc.length || j < aDownBc.length);
342 411
  412 + // 重新计算报到,出场,进场,离场班次的圈,班次索引
  413 + this._resetBdOutInLcBcGroup();
  414 +
343 }; 415 };
344 416
345 /** 417 /**
@@ -350,7 +422,6 @@ var Main_v2_2_ExcelObj = (function() { @@ -350,7 +422,6 @@ var Main_v2_2_ExcelObj = (function() {
350 */ 422 */
351 InternalCalcuExcelBc1.prototype._calcuExcelBcPerGroup = function(bIsUp, iBcIndex) { 423 InternalCalcuExcelBc1.prototype._calcuExcelBcPerGroup = function(bIsUp, iBcIndex) {
352 this._oLpGroupNormalGanttBc = {}; 424 this._oLpGroupNormalGanttBc = {};
353 - this._aLpGroupCfGanttBc = [];  
354 425
355 var i; 426 var i;
356 var j = 0; 427 var j = 0;
@@ -361,15 +432,16 @@ var Main_v2_2_ExcelObj = (function() { @@ -361,15 +432,16 @@ var Main_v2_2_ExcelObj = (function() {
361 for (i = iBcIndex; i < aGBc.length; i++) { 432 for (i = iBcIndex; i < aGBc.length; i++) {
362 oGanttBc = aGBc[i]; 433 oGanttBc = aGBc[i];
363 434
  435 + // 添加到场,出场,进场,离场班次
  436 + this._addBdOutInLcBc(oGanttBc, bIsUp);
  437 +
364 while(j < this._aExcelLp.length) { 438 while(j < this._aExcelLp.length) {
365 oExcelLp = this._aExcelLp[j]; 439 oExcelLp = this._aExcelLp[j];
366 440
367 if (oGanttBc.bcType == "cf") { // 吃饭班次 441 if (oGanttBc.bcType == "cf") { // 吃饭班次
368 this._aLpGroupCfGanttBc.push(oGanttBc); 442 this._aLpGroupCfGanttBc.push(oGanttBc);
369 break; 443 break;
370 - }  
371 -  
372 - if (oGanttBc.bcType == "normal") { // 正常班次 444 + } else if (oGanttBc.bcType == "normal") { // 正常班次
373 this._oLpGroupNormalGanttBc[oExcelLp.lpname] = { 445 this._oLpGroupNormalGanttBc[oExcelLp.lpname] = {
374 "isFlag": true, "normal": null 446 "isFlag": true, "normal": null
375 }; 447 };
@@ -381,6 +453,9 @@ var Main_v2_2_ExcelObj = (function() { @@ -381,6 +453,9 @@ var Main_v2_2_ExcelObj = (function() {
381 } else { 453 } else {
382 j++; 454 j++;
383 } 455 }
  456 + } else {
  457 +
  458 + break;
384 } 459 }
385 460
386 } 461 }
@@ -433,6 +508,7 @@ var Main_v2_2_ExcelObj = (function() { @@ -433,6 +508,7 @@ var Main_v2_2_ExcelObj = (function() {
433 oGroupGanttNormalBc = this._oLpGroupNormalGanttBc[oExcelLp.lpname].normal; 508 oGroupGanttNormalBc = this._oLpGroupNormalGanttBc[oExcelLp.lpname].normal;
434 509
435 // 获取吃饭班次 510 // 获取吃饭班次
  511 + oGroupGanttEatBc = null;
436 if (this._aLpGroupCfGanttBc.length > 0) { 512 if (this._aLpGroupCfGanttBc.length > 0) {
437 if (this._aLpGroupCfGanttBc[0].lpName == oExcelLp.lpname) { 513 if (this._aLpGroupCfGanttBc[0].lpName == oExcelLp.lpname) {
438 if (this._oParam.toTimeObj(this._aLpGroupCfGanttBc[0].fcsj).isBefore( 514 if (this._oParam.toTimeObj(this._aLpGroupCfGanttBc[0].fcsj).isBefore(
@@ -440,8 +516,6 @@ var Main_v2_2_ExcelObj = (function() { @@ -440,8 +516,6 @@ var Main_v2_2_ExcelObj = (function() {
440 oGroupGanttEatBc = this._aLpGroupCfGanttBc.shift(); 516 oGroupGanttEatBc = this._aLpGroupCfGanttBc.shift();
441 } 517 }
442 } 518 }
443 - } else {  
444 - oGroupGanttEatBc = null;  
445 } 519 }
446 520
447 oExcelLp.bcObjList.push({ 521 oExcelLp.bcObjList.push({
@@ -464,9 +538,17 @@ var Main_v2_2_ExcelObj = (function() { @@ -464,9 +538,17 @@ var Main_v2_2_ExcelObj = (function() {
464 oGroupGanttNormalBc.fcsj, // 发车时间描述2 538 oGroupGanttNormalBc.fcsj, // 发车时间描述2
465 539
466 "groupNo": bIsUp ? this._iUpGroupIndex : this._iDownGroupIndex, // 第几圈 540 "groupNo": bIsUp ? this._iUpGroupIndex : this._iDownGroupIndex, // 第几圈
467 - "groupBcNo": bIsUp == this._bQIsUp ? 0 : 1 // 圈里第几个班次 541 + "groupBcNo": bIsUp == this._bQIsUp ? 0 : 1, // 圈里第几个班次
  542 +
  543 + "_bclc": oGroupGanttNormalBc.jhlc // 班次里程(最后需要删除)
468 544
469 }); 545 });
  546 +
  547 + oExcelLp._bcObjGroupList.push({
  548 + fcsj: oGroupGanttNormalBc.fcsj, // 发车时间
  549 + groupIndex: bIsUp ? this._iUpGroupIndex : this._iDownGroupIndex, // 第几圈
  550 + bcIndex: bIsUp == this._bQIsUp ? 0 : 1 // 圈里第几个班次
  551 + });
470 } 552 }
471 } 553 }
472 } 554 }
@@ -478,6 +560,297 @@ var Main_v2_2_ExcelObj = (function() { @@ -478,6 +560,297 @@ var Main_v2_2_ExcelObj = (function() {
478 } 560 }
479 this._oLpGroupNormalGanttBc = {}; 561 this._oLpGroupNormalGanttBc = {};
480 }; 562 };
  563 +
  564 + // 添加报到,出场,进场,离场班次
  565 + InternalCalcuExcelBc1.prototype._addBdOutInLcBc = function(oGanttBc, bIsUp) {
  566 + var i;
  567 + var oExcelLp;
  568 + var bcType;
  569 + for (i = 0; i < this._aExcelLp.length; i++) {
  570 + oExcelLp = this._aExcelLp[i];
  571 + if (oGanttBc.lpName == oExcelLp.lpname) {
  572 + bcType = oGanttBc.bcType;
  573 + if (bcType == "bd" || bcType == "out" || bcType == "in" || bcType == "lc") {
  574 + oExcelLp.bcObjList.push({
  575 + "bcsj": oGanttBc.bcsj, // 班次时间
  576 + "ssj": oGanttBc.STOPTIME, // 停站时间
  577 + "eatsj": 0, // 吃饭时间
  578 +
  579 + "tccid": oGanttBc.tcc, // 停车场id
  580 + "qdzid": oGanttBc.qdz, // 起点站id
  581 + "zdzid": oGanttBc.zdz, // 终点站id
  582 +
  583 + "isUp": bIsUp, // 是否上行
  584 + "isFb": null, // 是否分班(_resetBdOutInLcBcGroup方法修正)
  585 +
  586 + "bcType": oGanttBc.bcType, // 班次类型(bc、out、in、lc)
  587 + "fcsj": oGanttBc.fcsj, // 发车时间描述
  588 +
  589 + "groupNo": -99, // 第几圈(_resetBdOutInLcBcGroup方法修正)
  590 + "groupBcNo": -99, // 圈里第几个班次(_resetBdOutInLcBcGroup方法修正)
  591 +
  592 + "_bclc": oGanttBc.jhlc // 班次里程(最后需要删除)
  593 + });
  594 + break;
  595 + }
  596 + }
  597 + }
  598 +
  599 + };
  600 + // 重新计算报到,出场,进场,离场班次的圈索引及班次索引
  601 + InternalCalcuExcelBc1.prototype._resetBdOutInLcBcGroup = function() {
  602 + var i;
  603 + var j;
  604 + var k;
  605 + var sFcsjDesc = [];
  606 + var oExcelLp;
  607 + var oLpBc;
  608 +
  609 + // {"bd":到场班次index,"out":出场班次index, "nextBc": 出场后第一个normal班次索引, "nextBcGroup":出场后第一个normal班次group索引}
  610 + var oBdOutLpBc = {};
  611 + // 到场出场班次组合数组
  612 + var aBdOutLpBc = [];
  613 +
  614 + // {"in":进场班次index,"lc":离场班次index, "preBc": 进场前一个normal班次索引, "preBcGroup":进场前一个normal班次group索引}
  615 + var oInLcLpBc = {};
  616 + // 进场离场班次组合数组
  617 + var aInLcLpBc = [];
  618 +
  619 + for (i = 0; i < this._aExcelLp.length; i++) {
  620 + oExcelLp = this._aExcelLp[i];
  621 +
  622 + // 排序oExcelLp班次列表
  623 + this._fnSortBc(oExcelLp.bcObjList);
  624 +
  625 + aBdOutLpBc = [];
  626 + aInLcLpBc = [];
  627 +
  628 + for (j = 0; j < oExcelLp.bcObjList.length; j++) {
  629 + oLpBc = oExcelLp.bcObjList[j];
  630 +
  631 + if (oLpBc.bcType == "out") { // 出场班次
  632 + oBdOutLpBc = {"bd": null, "out": null, "nextBc": null, "nextBcGroup": null};
  633 + oBdOutLpBc["out"] = j;
  634 + // 查找上一个班次是否是报到班次(不存在有可能,中间分班班次可能没有报到时间)
  635 + if ((j - 1) >= 0 && (j - 1) < oExcelLp.bcObjList.length) {
  636 + if (oExcelLp.bcObjList[j - 1].bcType == "bd") {
  637 + oBdOutLpBc["bd"] = j - 1;
  638 + }
  639 + }
  640 + // 查找下一个班次是否是normal班次(不存在或者不是normal班次,这个报到出场班次组合忽略)
  641 + if ((j + 1) < oExcelLp.bcObjList.length) {
  642 + if (oExcelLp.bcObjList[j + 1].bcType == "normal") {
  643 + for (k = 0; k < oExcelLp._bcObjGroupList.length; k++) {
  644 + if (oExcelLp.bcObjList[j + 1].fcsj == oExcelLp._bcObjGroupList[k].fcsj) {
  645 + oBdOutLpBc["nextBc"] = j + 1;
  646 + oBdOutLpBc["nextBcGroup"] = k;
  647 + aBdOutLpBc.push(oBdOutLpBc);
  648 + break;
  649 + }
  650 + }
  651 + }
  652 + }
  653 + } else if (oLpBc.bcType == "in") { // 进场班次
  654 + oInLcLpBc = {"in": null, "lc": null, "preBc": null, "preBcGroup": null};
  655 + oInLcLpBc["in"] = j;
  656 + // 查找系一个班次是否是离场班次(不存在有可能,中间分班班次可能没有离场时间)
  657 + if ((j + 1) < oExcelLp.bcObjList.length) {
  658 + if (oExcelLp.bcObjList[j + 1].bcType == "lc") {
  659 + oInLcLpBc["lc"] = j + 1;
  660 + }
  661 + }
  662 + // 查找上一个班次是否是normal班次(不存在或者不是normal班次,这个进场离场班次组合忽略)
  663 + if ((j - 1) >= 0 && (j - 1) < oExcelLp.bcObjList.length) {
  664 + if (oExcelLp.bcObjList[j - 1].bcType == "normal") {
  665 + for (k = 0; k < oExcelLp._bcObjGroupList.length; k++) {
  666 + if (oExcelLp.bcObjList[j - 1].fcsj == oExcelLp._bcObjGroupList[k].fcsj) {
  667 + oInLcLpBc["preBc"] = j - 1;
  668 + oInLcLpBc["preBcGroup"] = k;
  669 + aInLcLpBc.push(oInLcLpBc);
  670 + break;
  671 + }
  672 + }
  673 + }
  674 + }
  675 +
  676 + }
  677 +
  678 + }
  679 +
  680 + if (aBdOutLpBc.length == 2) { // 分班(以出场班次为主)
  681 + // 处理第一个出场
  682 + sFcsjDesc = [];
  683 + oBdOutLpBc = aBdOutLpBc[0];
  684 + if (oBdOutLpBc.bd != null) {
  685 + oLpBc = oExcelLp.bcObjList[oBdOutLpBc.bd];
  686 + oLpBc.isFb = false;
  687 + oLpBc.groupNo = -1;
  688 + oLpBc.groupBcNo = -1;
  689 + sFcsjDesc.push("(到" + oLpBc.fcsj + ")");
  690 + }
  691 +
  692 + oLpBc = oExcelLp.bcObjList[oBdOutLpBc.out];
  693 + oLpBc.isFb = false;
  694 + oLpBc.groupNo = -1;
  695 + oLpBc.groupBcNo = -2;
  696 + sFcsjDesc.push("(出" + oLpBc.fcsj + ")");
  697 +
  698 + oLpBc = oExcelLp.bcObjList[oBdOutLpBc.nextBc];
  699 + sFcsjDesc.push("(" + oLpBc.fcsj + ")");
  700 + oLpBc.fcsjDesc = sFcsjDesc.join("");
  701 +
  702 + // 处理第二个出场
  703 + sFcsjDesc = [];
  704 + oBdOutLpBc = aBdOutLpBc[1];
  705 + if (oBdOutLpBc.bd != null) {
  706 + oLpBc = oExcelLp.bcObjList[oBdOutLpBc.bd];
  707 + oLpBc.isFb = true;
  708 + oLpBc.groupNo = oExcelLp._bcObjGroupList[oBdOutLpBc.nextBcGroup].groupIndex - 1;
  709 + oLpBc.groupBcNo = oExcelLp._bcObjGroupList[oBdOutLpBc.nextBcGroup].bcIndex;
  710 + sFcsjDesc.push("(到" + oLpBc.fcsj + ")");
  711 + }
  712 +
  713 + oLpBc = oExcelLp.bcObjList[oBdOutLpBc.out];
  714 + oLpBc.isFb = true;
  715 + oLpBc.groupNo = ((oExcelLp._bcObjGroupList[oBdOutLpBc.nextBcGroup].bcIndex == 0) ?
  716 + (oExcelLp._bcObjGroupList[oBdOutLpBc.nextBcGroup].groupIndex - 1) :
  717 + oExcelLp._bcObjGroupList[oBdOutLpBc.nextBcGroup].groupIndex);
  718 + oLpBc.groupBcNo = ((oExcelLp._bcObjGroupList[oBdOutLpBc.nextBcGroup].bcIndex == 0) ? 1 : 0);
  719 + sFcsjDesc.push("(出" + oLpBc.fcsj + ")");
  720 +
  721 + oLpBc = oExcelLp.bcObjList[oBdOutLpBc.nextBc];
  722 + sFcsjDesc.push("(" + oLpBc.fcsj + ")");
  723 + oLpBc.fcsjDesc = sFcsjDesc.join("");
  724 +
  725 + // 2个以上进场班次,处理第一个和第二个,第一个做为中间进场
  726 + if (aInLcLpBc.length >= 2) {
  727 + sFcsjDesc = [];
  728 + oInLcLpBc = aInLcLpBc[0];
  729 +
  730 + oLpBc = oExcelLp.bcObjList[oInLcLpBc.preBc];
  731 + sFcsjDesc.push("(" + oLpBc.fcsj + ")");
  732 +
  733 + oLpBc = oExcelLp.bcObjList[oInLcLpBc.in];
  734 + oLpBc.isFb = true;
  735 + oLpBc.groupNo = ((oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].bcIndex == 0) ?
  736 + oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].groupIndex :
  737 + (oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].groupIndex + 1));
  738 + oLpBc.groupBcNo = ((oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].bcIndex == 0) ? 1 : 0);
  739 + sFcsjDesc.push("(进" + oLpBc.fcsj + ")");
  740 +
  741 + oExcelLp.bcObjList[oInLcLpBc.preBc].fcsjDesc = sFcsjDesc.join("");
  742 +
  743 + sFcsjDesc = [];
  744 + oInLcLpBc = aInLcLpBc[1];
  745 +
  746 + oLpBc = oExcelLp.bcObjList[oInLcLpBc.preBc];
  747 + sFcsjDesc.push("(" + oLpBc.fcsj + ")");
  748 +
  749 + oLpBc = oExcelLp.bcObjList[oInLcLpBc.in];
  750 + oLpBc.isFb = false;
  751 + oLpBc.groupNo = ((oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].bcIndex == 0) ?
  752 + oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].groupIndex :
  753 + (oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].groupIndex + 1));
  754 + oLpBc.groupBcNo = ((oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].bcIndex == 0) ? 1 : 0);
  755 + sFcsjDesc.push("(进" + oLpBc.fcsj + ")");
  756 +
  757 + if (oInLcLpBc.lc) {
  758 + oLpBc = oExcelLp.bcObjList[oInLcLpBc.lc];
  759 + oLpBc.isFb = false;
  760 + oLpBc.groupNo = -2;
  761 + oLpBc.groupBcNo = -4;
  762 + sFcsjDesc.push("(离" + oLpBc.fcsj + ")");
  763 + }
  764 + oExcelLp.bcObjList[oInLcLpBc.preBc].fcsjDesc = sFcsjDesc.join("");
  765 + }
  766 +
  767 + // 一个进场班次,做为最后一个进场班次处理
  768 + if (aInLcLpBc.length == 1) {
  769 + sFcsjDesc = [];
  770 + oInLcLpBc = aInLcLpBc[0];
  771 +
  772 + oLpBc = oExcelLp.bcObjList[oInLcLpBc.preBc];
  773 + sFcsjDesc.push("(" + oLpBc.fcsj + ")");
  774 +
  775 + oLpBc = oExcelLp.bcObjList[oInLcLpBc.in];
  776 + oLpBc.isFb = false;
  777 + oLpBc.groupNo = ((oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].bcIndex == 0) ?
  778 + oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].groupIndex :
  779 + (oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].groupIndex + 1));
  780 + oLpBc.groupBcNo = ((oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].bcIndex == 0) ? 1 : 0);
  781 + sFcsjDesc.push("(进" + oLpBc.fcsj + ")");
  782 +
  783 + if (oInLcLpBc.lc) {
  784 + oLpBc = oExcelLp.bcObjList[oInLcLpBc.lc];
  785 + oLpBc.isFb = false;
  786 + oLpBc.groupNo = -2;
  787 + oLpBc.groupBcNo = -4;
  788 + sFcsjDesc.push("(离" + oLpBc.fcsj + ")");
  789 + }
  790 + oExcelLp.bcObjList[oInLcLpBc.preBc].fcsjDesc = sFcsjDesc.join("");
  791 + }
  792 +
  793 +
  794 + } else if (aBdOutLpBc.length == 1) {
  795 + // 处理出场
  796 + sFcsjDesc = [];
  797 + oBdOutLpBc = aBdOutLpBc[0];
  798 + if (oBdOutLpBc.bd != null) {
  799 + oLpBc = oExcelLp.bcObjList[oBdOutLpBc.bd];
  800 + oLpBc.isFb = false;
  801 + oLpBc.groupNo = -1;
  802 + oLpBc.groupBcNo = -1;
  803 + sFcsjDesc.push("(到" + oLpBc.fcsj + ")");
  804 + }
  805 +
  806 + oLpBc = oExcelLp.bcObjList[oBdOutLpBc.out];
  807 + oLpBc.isFb = false;
  808 + oLpBc.groupNo = -1;
  809 + oLpBc.groupBcNo = -2;
  810 + sFcsjDesc.push("(出" + oLpBc.fcsj + ")");
  811 +
  812 + oLpBc = oExcelLp.bcObjList[oBdOutLpBc.nextBc];
  813 + sFcsjDesc.push("(" + oLpBc.fcsj + ")");
  814 + oLpBc.fcsjDesc = sFcsjDesc.join("");
  815 +
  816 + // 处理进场
  817 + if (aInLcLpBc.length > 0) {
  818 + sFcsjDesc = [];
  819 + oInLcLpBc = aInLcLpBc[0];
  820 +
  821 + oLpBc = oExcelLp.bcObjList[oInLcLpBc.preBc];
  822 + sFcsjDesc.push("(" + oLpBc.fcsj + ")");
  823 +
  824 + oLpBc = oExcelLp.bcObjList[oInLcLpBc.in];
  825 + oLpBc.isFb = false;
  826 + oLpBc.groupNo = ((oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].bcIndex == 0) ?
  827 + oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].groupIndex :
  828 + (oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].groupIndex + 1));
  829 + oLpBc.groupBcNo = ((oExcelLp._bcObjGroupList[oInLcLpBc.preBcGroup].bcIndex == 0) ? 1 : 0);
  830 + sFcsjDesc.push("(进" + oLpBc.fcsj + ")");
  831 +
  832 + if (oInLcLpBc.lc) {
  833 + oLpBc = oExcelLp.bcObjList[oInLcLpBc.lc];
  834 + oLpBc.isFb = false;
  835 + oLpBc.groupNo = -2;
  836 + oLpBc.groupBcNo = -4;
  837 + sFcsjDesc.push("(离" + oLpBc.fcsj + ")");
  838 + }
  839 + oExcelLp.bcObjList[oInLcLpBc.preBc].fcsjDesc = sFcsjDesc.join("");
  840 +
  841 + }
  842 +
  843 + }
  844 +
  845 + // console.log("todo");
  846 +
  847 +
  848 + }
  849 +
  850 + // console.log("ddd");
  851 +
  852 + };
  853 +
481 // 判定当前圈是否是有分班后的第一个normal班次 854 // 判定当前圈是否是有分班后的第一个normal班次
482 InternalCalcuExcelBc1.prototype._fnIsFBcQ = function(bIsUp) { 855 InternalCalcuExcelBc1.prototype._fnIsFBcQ = function(bIsUp) {
483 var oExcelLp; 856 var oExcelLp;
@@ -514,7 +887,7 @@ var Main_v2_2_ExcelObj = (function() { @@ -514,7 +887,7 @@ var Main_v2_2_ExcelObj = (function() {
514 887
515 return bFbFlag; 888 return bFbFlag;
516 889
517 - } 890 + };
518 891
519 /** 892 /**
520 * 内部Excel对象。 893 * 内部Excel对象。
@@ -572,6 +945,7 @@ var Main_v2_2_ExcelObj = (function() { @@ -572,6 +945,7 @@ var Main_v2_2_ExcelObj = (function() {
572 "lpname": oGanttBc.lpName, // 路牌名字 945 "lpname": oGanttBc.lpName, // 路牌名字
573 "isUp": this._qIsUp, // 每圈的第一个班次是否上行 946 "isUp": this._qIsUp, // 每圈的第一个班次是否上行
574 "bcObjList": [], // 内部班次列表(后面计算班次列表) 947 "bcObjList": [], // 内部班次列表(后面计算班次列表)
  948 + "_bcObjGroupList": [], // 每个normal班次对应的group对象 {fcsj: 发车时间, groupIndex: 圈索引, bcIndex: 班次索引},最后返回要删除
575 "groupCount": 0, // 总圈数(后面计算总圈数) 949 "groupCount": 0, // 总圈数(后面计算总圈数)
576 "zlc": 0, // 总里程 950 "zlc": 0, // 总里程
577 "yylc": 0, // 营运里程 951 "yylc": 0, // 营运里程
src/main/resources/static/pages/base/timesmodel/js/v2_2/main_v2_2.js
1 -/**  
2 - * 主类(v2_2版本)。  
3 - */  
4 -var Main_v2_2 = function() {  
5 -  
6 - var _paramObj; // 参数对象  
7 -  
8 - return {  
9 - /**  
10 - * 使用发车间隔策略生成时刻表。  
11 - * @param paramObj 参数对象  
12 - * @param lpArray 路牌数组  
13 - * @constructor  
14 - */  
15 - BXPplaceClassesTime03 : function(paramObj, lpArray) {  
16 - // 参数对象  
17 - _paramObj = paramObj;  
18 -  
19 - // // 测试行驶时间  
20 - // var _fcsj = paramObj.toTimeObj("16:20");  
21 - // var _bcsj = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(false, _fcsj, paramObj); // 使用策略计算班次行驶时间  
22 - // console.log("发车时间=" + _fcsj.format("HH:mm") + ",行驶时间=" + _bcsj);  
23 - //  
24 -  
25 - // // 测试停站时间  
26 - // var _fcsj = paramObj.toTimeObj("05:30");  
27 - // var _layovertime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(  
28 - // _fcsj, false, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), paramObj);  
29 - // console.log("发车时间=" + _fcsj.format("HH:mm") + ",停站layover时间=" + _layovertime);  
30 - //  
31 - // var schedule = {};  
32 -  
33 - // // 测试间隔时间  
34 - // var _fcsj = paramObj.toTimeObj("07:30");  
35 - // var _headway = StrategyUtils_v2_2.sFn("CALCU_HEADWAY_2")(true, _fcsj, _paramObj);  
36 - // console.log("发车时间=" + _fcsj.format("HH:mm") + ",发车间隔=" + _headway);  
37 -  
38 - // 1、初始化行车计划  
39 - var schedule = new InternalScheduleObj_v2_2(paramObj, lpArray);  
40 - // 2、生成班次(从第2圈开始)  
41 - schedule.fnCreateBclistWithMasterBc(2, 20);  
42 - // 3、计算吃饭班次  
43 - schedule.fnCalcuEatBc();  
44 - // 4、调整发车间隔  
45 - schedule.fnAdjustHeadway();  
46 - // // 6、计算末班车  
47 - // schedule.fnCalcuLastBc();  
48 - // 7、重新设置停站时间  
49 - schedule.fnReSetLayoverTime();  
50 - // // 8、补进出场例保班次  
51 - // schedule.fnCalcuOtherBc();  
52 -  
53 - //-------------------- 输出ganut图上的班次,班型描述 ----------------------//  
54 - // TODO:班型再议  
55 - return {  
56 - 'json':schedule.fnToGanttBcArray(),'bxrcgs':null,  
57 - 'aInternalLpObj': schedule.fnGetLpArray()  
58 - };  
59 - },  
60 -  
61 - //----------------------------------- 导入导出配置 -----------------------------------//  
62 -  
63 - /**  
64 - * 导出时刻表配置。  
65 - * @param fnGetGanttBc 获取gantt班次方法  
66 - */  
67 - exportExcelConfig: function(fnGetGanttBc) {  
68 - var oExcel = new Main_v2_2_ExcelObj(_paramObj, fnGetGanttBc);  
69 -  
70 - $('.exportAddXls').off('click');  
71 - $('.exportAddXlsx').off('click');  
72 -  
73 - $('.exportAddXls').on('click', function() {  
74 - alert("dddd");  
75 -  
76 -  
77 - var aInfos = {  
78 - "lpObjList": oExcel.fnGetLpBcInfoList(), // 路牌班次信息列表  
79 - "statInfoList": oExcel.fnGetStatInfoList(), // 统计项目列表  
80 - "parameterInfoList" : oExcel.fnGetParamInfoList() // 参数对象  
81 - };  
82 -  
83 - console.log(aInfos);  
84 -  
85 - $(".exportAdd").addClass("disabled");  
86 - $(".exportAddSpan").html("正在导出...");  
87 -  
88 - // 提交  
89 - $.ajax({  
90 - type: 'POST',  
91 - url: "/tidc/exportDTDFile/xls",  
92 - dataType: 'binary',  
93 - contentType: "application/json",  
94 - data: JSON.stringify(aInfos),  
95 - success: function(data){  
96 - oExcel.downloadFile(data, "application/octet-stream", "时刻表信息.xls");  
97 -  
98 - $(".exportAdd").removeClass("disabled");  
99 - $(".exportAddSpan").html(" 导出数据");  
100 - },  
101 - error: function(xhr, type){  
102 - alert('错误:TODO');  
103 -  
104 - $(".exportAdd").removeClass("disabled");  
105 - $(".exportAddSpan").html(" 导出数据");  
106 - }  
107 - });  
108 - });  
109 -  
110 - $('.exportAddXlsx').on('click', function() {  
111 - var aInfos = {  
112 - "lpObjList": oExcel.fnGetLpBcInfoList(), // 路牌班次信息列表  
113 - "statInfoList": oExcel.fnGetStatInfoList(), // 统计项目列表  
114 - "parameterInfoList" : oExcel.fnGetParamInfoList() // 参数对象  
115 - };  
116 -  
117 - console.log(aInfos);  
118 -  
119 - $(".exportAdd").addClass("disabled");  
120 - $(".exportAddSpan").html("正在导出...");  
121 -  
122 - // 提交  
123 - $.ajax({  
124 - type: 'POST',  
125 - url: "/tidc/exportDTDFile/xlsx",  
126 - dataType: 'binary',  
127 - contentType: "application/json",  
128 - data: JSON.stringify(aInfos),  
129 - success: function(data){  
130 - oExcel.downloadFile(data, "application/octet-stream", "时刻表信息.xlsx");  
131 -  
132 - $(".exportAdd").removeClass("disabled");  
133 - $(".exportAddSpan").html(" 导出数据");  
134 - },  
135 - error: function(xhr, type){  
136 - alert('错误:TODO');  
137 -  
138 - $(".exportAdd").removeClass("disabled");  
139 - $(".exportAddSpan").html(" 导出数据");  
140 - }  
141 - });  
142 - });  
143 - }  
144 -  
145 -  
146 - } 1 +/**
  2 + * 主类(v2_2版本)。
  3 + */
  4 +var Main_v2_2 = function() {
  5 +
  6 + var _paramObj; // 参数对象
  7 +
  8 + return {
  9 + /**
  10 + * 使用发车间隔策略生成时刻表。
  11 + * @param paramObj 参数对象
  12 + * @param lpArray 路牌数组
  13 + * @constructor
  14 + */
  15 + BXPplaceClassesTime03 : function(paramObj, lpArray) {
  16 + // 参数对象
  17 + _paramObj = paramObj;
  18 +
  19 + // // 测试行驶时间
  20 + // var _fcsj = paramObj.toTimeObj("16:20");
  21 + // var _bcsj = StrategyUtils_v2_2.sFn("CALCU_RUNTIME")(false, _fcsj, paramObj); // 使用策略计算班次行驶时间
  22 + // console.log("发车时间=" + _fcsj.format("HH:mm") + ",行驶时间=" + _bcsj);
  23 + //
  24 +
  25 + // // 测试停站时间
  26 + // var _fcsj = paramObj.toTimeObj("05:30");
  27 + // var _layovertime = StrategyUtils_v2_2.sFn("CALCU_LAYOVER_TIME")(
  28 + // _fcsj, false, StrategyUtils_v2_2.sFn("CALCU_RUNTIME"), paramObj);
  29 + // console.log("发车时间=" + _fcsj.format("HH:mm") + ",停站layover时间=" + _layovertime);
  30 + //
  31 + // var schedule = {};
  32 +
  33 + // // 测试间隔时间
  34 + // var _fcsj = paramObj.toTimeObj("07:30");
  35 + // var _headway = StrategyUtils_v2_2.sFn("CALCU_HEADWAY_2")(true, _fcsj, _paramObj);
  36 + // console.log("发车时间=" + _fcsj.format("HH:mm") + ",发车间隔=" + _headway);
  37 +
  38 + // 1、初始化行车计划
  39 + var schedule = new InternalScheduleObj_v2_2(paramObj, lpArray);
  40 + // 2、生成班次(从第2圈开始)
  41 + schedule.fnCreateBclistWithMasterBc(2, 20);
  42 + // 3、调整发车间隔
  43 + schedule.fnAdjustHeadway();
  44 + // 4、计算吃饭班次
  45 + schedule.fnCalcuEatBc();
  46 + // // 6、计算末班车
  47 + // schedule.fnCalcuLastBc();
  48 + // 7、重新设置停站时间
  49 + schedule.fnReSetLayoverTime();
  50 + // 8、补进出场例保班次
  51 + schedule.fnCalcuOtherBc();
  52 +
  53 + //-------------------- 输出ganut图上的班次,班型描述 ----------------------//
  54 + // TODO:班型再议
  55 + return {
  56 + 'json':schedule.fnToGanttBcArray(),'bxrcgs':null,
  57 + 'aInternalLpObj': schedule.fnGetLpArray()
  58 + };
  59 + },
  60 +
  61 + //----------------------------------- 导入导出配置 -----------------------------------//
  62 +
  63 + /**
  64 + * 导出时刻表配置。
  65 + * @param fnGetGanttBc 获取gantt班次方法
  66 + */
  67 + exportExcelConfig: function(fnGetGanttBc) {
  68 + var oExcel = new Main_v2_2_ExcelObj(_paramObj, fnGetGanttBc);
  69 +
  70 + $('.exportAddXls').off('click');
  71 + $('.exportAddXlsx').off('click');
  72 +
  73 + $('.exportAddXls').on('click', function() {
  74 +
  75 + var aInfos = {
  76 + "lpObjList": oExcel.fnGetLpBcInfoList(), // 路牌班次信息列表
  77 + "statInfoList": oExcel.fnGetStatInfoList(), // 统计项目列表
  78 + "parameterInfoList" : oExcel.fnGetParamInfoList() // 参数对象
  79 + };
  80 +
  81 + console.log(aInfos);
  82 +
  83 + $(".exportAdd").addClass("disabled");
  84 + $(".exportAddSpan").html("正在导出...");
  85 +
  86 + // 提交
  87 + $.ajax({
  88 + type: 'POST',
  89 + url: "/tidc/exportDTDFile/xls",
  90 + dataType: 'binary',
  91 + contentType: "application/json",
  92 + data: JSON.stringify(aInfos),
  93 + success: function(data){
  94 + oExcel.downloadFile(data, "application/octet-stream", "时刻表信息.xls");
  95 +
  96 + $(".exportAdd").removeClass("disabled");
  97 + $(".exportAddSpan").html(" 导出数据");
  98 + },
  99 + error: function(xhr, type){
  100 + alert('错误:TODO');
  101 +
  102 + $(".exportAdd").removeClass("disabled");
  103 + $(".exportAddSpan").html(" 导出数据");
  104 + }
  105 + });
  106 + });
  107 +
  108 + $('.exportAddXlsx').on('click', function() {
  109 + var aInfos = {
  110 + "lpObjList": oExcel.fnGetLpBcInfoList(), // 路牌班次信息列表
  111 + "statInfoList": oExcel.fnGetStatInfoList(), // 统计项目列表
  112 + "parameterInfoList" : oExcel.fnGetParamInfoList() // 参数对象
  113 + };
  114 +
  115 + console.log(aInfos);
  116 +
  117 + $(".exportAdd").addClass("disabled");
  118 + $(".exportAddSpan").html("正在导出...");
  119 +
  120 + // 提交
  121 + $.ajax({
  122 + type: 'POST',
  123 + url: "/tidc/exportDTDFile/xlsx",
  124 + dataType: 'binary',
  125 + contentType: "application/json",
  126 + data: JSON.stringify(aInfos),
  127 + success: function(data){
  128 + oExcel.downloadFile(data, "application/octet-stream", "时刻表信息.xlsx");
  129 +
  130 + $(".exportAdd").removeClass("disabled");
  131 + $(".exportAddSpan").html(" 导出数据");
  132 + },
  133 + error: function(xhr, type){
  134 + alert('错误:TODO');
  135 +
  136 + $(".exportAdd").removeClass("disabled");
  137 + $(".exportAddSpan").html(" 导出数据");
  138 + }
  139 + });
  140 + });
  141 + }
  142 +
  143 +
  144 + }
147 }(); 145 }();
148 \ No newline at end of file 146 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/headway/AdjustHeadwayS1.js
1 -/**  
2 - * 调整某一圈的发车间隔,在已有的间隔上做修正。  
3 - * 1、圈的第一个班次,最后一个班次发车时间固定不变,调整其余班次间隔  
4 - * 2、调整的判定原则是某个班次和该路牌下一个班次之间的layovertime为负值,需要调整当前班次间隔  
5 - * 3、TODO:如果仅靠调整间隔无法调整,可以考虑删除某个路牌的班次  
6 - * 4、TODO:目前只用在第一圈第一个方向班次列表上,低谷在前,高峰在后  
7 - */  
8 -var AdjustHeadwayS1 = (function() {  
9 -  
10 - /**  
11 - * 从指定路牌的班次开始往下所有的班次发车时间尝试减一分钟。  
12 - * @param aLp 路牌数组  
13 - * @param lpIndex 从下往上第一个停站时间不足的班次所在路牌索引  
14 - * @param iCurrentGroupIndex 班次圈索引  
15 - * @param iCurrentBcIndex 班次索引  
16 - * @param oParam 参数对象  
17 - */  
18 - function _a_down(aLp, lpIndex, iCurrentGroupIndex, iCurrentBcIndex, oParam) {  
19 - // 如果最后一个路牌的班次就停站时间不足,则不调整  
20 - if (lpIndex == aLp.length - 1) {  
21 - return false;  
22 - }  
23 - // 有班次的路牌索引数组(往下)  
24 - var i;  
25 - var aLpIndex = [];  
26 - for (i = lpIndex; i < aLp.length; i++) {  
27 - if (aLp[i].getBc(iCurrentGroupIndex, iCurrentBcIndex)) {  
28 - aLpIndex.push(i);  
29 - }  
30 - }  
31 -  
32 - // 当前班次开始与下一个路牌的对应班次的发车时间间隔  
33 - var aHeadWay = [];  
34 - var oHeadWay;  
35 - for (i = 0; i < aLpIndex.length - 1; i++) {  
36 - oHeadWay = {};  
37 - oHeadWay.iStartLpIndex = aLpIndex[i];  
38 - oHeadWay.iEndLpIndex = aLpIndex[i + 1];  
39 - if (oParam.isMPeakBc(aLp[aLpIndex[i]].getBc(iCurrentGroupIndex, iCurrentBcIndex).getFcTimeObj())) {  
40 - oHeadWay.bMPeakBc = true;  
41 - } else {  
42 - oHeadWay.bMPeakBc = false;  
43 - }  
44 - oHeadWay.iHeadWay = aLp[aLpIndex[i + 1]].getBc(iCurrentGroupIndex, iCurrentBcIndex).getFcTimeObj().diff(  
45 - aLp[aLpIndex[i]].getBc(iCurrentGroupIndex, iCurrentBcIndex).getFcTimeObj(), "m"  
46 - );  
47 -  
48 - aHeadWay.push(oHeadWay);  
49 - }  
50 -  
51 - // 找出第一个间隔小于高峰最大发车间隔的位置,  
52 - // 然后从lpIndex开始到这个位置减发车时间,  
53 - // 从而达到从lpIndex开始到这个位置,局部减少发车时间的作用  
54 - // 最终的结果是停站时间足够,并且停站时间也是一个过渡效果  
55 - var bIsFind = false;  
56 - var iFindIndex;  
57 - for (i = 0; i < aHeadWay.length; i++) {  
58 - if (aHeadWay[i].bMPeakBc) {  
59 - if (aHeadWay[i].iHeadWay < oParam.getMPeakMaxFcjx()) {  
60 - iFindIndex = i;  
61 - bIsFind = true;  
62 - break;  
63 - }  
64 - } else {  
65 - iFindIndex = i;  
66 - bIsFind = true;  
67 - break;  
68 - }  
69 - }  
70 -  
71 - if (!bIsFind) {  
72 - return false;  
73 - }  
74 -  
75 - // 调整间隔  
76 - var iStartLpIndex = aHeadWay[iFindIndex].iStartLpIndex;  
77 - var oLp;  
78 - var oBc;  
79 - for (i = 0; i < aLpIndex.length; i++) {  
80 - if (aLpIndex[i] <= iStartLpIndex && aLpIndex[i] > lpIndex) {  
81 - oLp = aLp[aLpIndex[i]];  
82 - oBc = oLp.getBc(iCurrentGroupIndex, iCurrentBcIndex);  
83 - oBc.addMinuteToFcsj(-1); // 发车时间,到达时间减1分钟  
84 - }  
85 - }  
86 -  
87 - return true;  
88 - }  
89 - // // TODO:向上局部减少发车调整有问题,不能下上所有的班次都减发车时间,需要像_a_down逐步减,下次修正  
90 - // function _a_up2(lpIndex, aLp,  
91 - // iCurrentGroupIndex, iCurrentBcIndex, oParam) {  
92 - // // 有班次的路牌索引数组(往上)  
93 - // var i;  
94 - // var aLpIndex = [];  
95 - // for (i = lpIndex; i >= 0; i--) {  
96 - // if (aLp[i].getBc(iCurrentGroupIndex, iCurrentBcIndex)) {  
97 - // aLpIndex.push(i);  
98 - // }  
99 - // }  
100 - // // 当前班次开始与下一个路牌的对应班次的发车时间间隔  
101 - // var aHeadWay = [];  
102 - // var oHeadWay = {};  
103 - // for (i = 0; i < aLpIndex.length - 1; i++) {  
104 - // oHeadWay = {};  
105 - // oHeadWay.iStartLpIndex = aLpIndex[i + 1];  
106 - // oHeadWay.iEndLpIndex = aLpIndex[i];  
107 - // if (oParam.isMPeakBc(aLp[aLpIndex[i + 1]].getBc(iCurrentGroupIndex, iCurrentBcIndex).getFcTimeObj())) {  
108 - // oHeadWay.bMPeakBc = true;  
109 - // } else {  
110 - // oHeadWay.bMPeakBc = false;  
111 - // }  
112 - // oHeadWay.iHeadWay = aLp[aLpIndex[i]].getBc(iCurrentGroupIndex, iCurrentBcIndex).getFcTimeObj().diff(  
113 - // aLp[aLpIndex[i + 1]].getBc(iCurrentGroupIndex, iCurrentBcIndex).getFcTimeObj(), "m"  
114 - // );  
115 - //  
116 - // aHeadWay.push(oHeadWay);  
117 - // }  
118 - //  
119 - // // 找出第一个间隔小的班次间隔  
120 - // var bIsFind = false;  
121 - // var iFindIndex;  
122 - // for (i = 0; i < aHeadWay.length; i++) {  
123 - // if (aHeadWay[i].bMPeakBc) {  
124 - // if (aHeadWay[i].iHeadWay > oParam.getMPeakMinFcjx()) {  
125 - // iFindIndex = i;  
126 - // bIsFind = true;  
127 - // break;  
128 - // }  
129 - // } else {  
130 - // iFindIndex = i;  
131 - // bIsFind = true;  
132 - // break;  
133 - // }  
134 - // }  
135 - //  
136 - // if (!bIsFind) {  
137 - // return false;  
138 - // }  
139 - //  
140 - // // 调整间隔  
141 - // var iStartLpIndex = aHeadWay[iFindIndex].iStartLpIndex;  
142 - // var oLp;  
143 - // var oBc;  
144 - // for (i = 0; i < aLpIndex.length; i++) {  
145 - // if (aLpIndex[i] <= lpIndex && aLpIndex[i] >= iStartLpIndex) {  
146 - // oLp = aLp[aLpIndex[i]];  
147 - // oBc = oLp.getBc(iCurrentGroupIndex, iCurrentBcIndex);  
148 - // oBc.addMinuteToFcsj(-1); // 发车时间,到达时间减1分钟  
149 - // }  
150 - // }  
151 - //  
152 - // return true;  
153 - //  
154 - // }  
155 -  
156 - /**  
157 - * 从指定路牌的班次开始往上所有的班次发车时间尝试减一分钟。  
158 - * @param lpIndex 开始路牌索引  
159 - * @param aLp 路牌列表  
160 - * @param iCurrentGroupIndex 当前班次圈索引  
161 - * @param iCurrentBcIndex 当前班次索引  
162 - * @param oParam 参数对象  
163 - */  
164 - function _a_up(lpIndex, aLp,  
165 - iCurrentGroupIndex, iCurrentBcIndex, oParam) {  
166 - var i;  
167 - var oLp;  
168 - var oBc;  
169 - for (i = lpIndex; i > 0; i--) { // 第一个路牌的班次不能动  
170 - oLp = aLp[i];  
171 - oBc = oLp.getBc(iCurrentGroupIndex, iCurrentBcIndex);  
172 - if (oBc) {  
173 - oBc.addMinuteToFcsj(-1); // 发车时间,到达时间减1分钟  
174 - }  
175 -  
176 - }  
177 - }  
178 -  
179 - /**  
180 - * 主函数。  
181 - * @param oInternalSchedule 行车计划  
182 - * @param oParam 参数对象  
183 - * @param iCGIndex 圈索引  
184 - * @param iCBIndex 班次索引  
185 - * @param iNGIndex 同路牌下一个邻接圈索引  
186 - * @param iNBIndex 同路牌下一个邻接班次索引  
187 - * @param iMinLayoverTime 要求的最小停站时间  
188 - */  
189 - function main(oInternalSchedule, oParam,  
190 - iCGIndex, iCBIndex,  
191 - iNGIndex, iNBIndex,  
192 - iMinLayoverTime) {  
193 - var _iIterCount = 0; // 当前迭代次数  
194 - var _iMaxIter = 100; // 最大迭代100次  
195 -  
196 - var bLpFind = false;  
197 - var iLpIndex;  
198 - var i;  
199 - var aLp = oInternalSchedule.fnGetLpArray();  
200 - var oLp;  
201 - var oCBc;  
202 - var oNBc;  
203 - while (_iIterCount <= _iMaxIter) {  
204 - // 反方向查找第一个停站时间不足的班次  
205 - for (i = aLp.length - 1; i > 0; i--) {  
206 - oLp = aLp[i];  
207 - oCBc = oLp.getBc(iCGIndex, iCBIndex);  
208 - oNBc = oLp.getBc(iNGIndex, iNBIndex);  
209 - if (oCBc && oNBc) {  
210 - if (oNBc.getFcTimeObj().diff(oCBc.getArrTimeObj(), "m") <= (iMinLayoverTime - 1)) {  
211 - iLpIndex = i;  
212 - bLpFind = true;  
213 - break;  
214 - }  
215 - }  
216 - }  
217 - if (!bLpFind) {  
218 - break;  
219 - }  
220 -  
221 - if (iLpIndex == aLp.length - 1) { // 最后一个路牌的班次停站时间不足,不能调整了  
222 - break;  
223 - }  
224 -  
225 - // 如果当前班次和下一个班次的间隔是早高峰最大发车间隔,需要尝试下面的班次发车时间减1分钟  
226 - if (aLp[iLpIndex + 1].getBc(iCGIndex, iCBIndex).getFcTimeObj().diff(  
227 - aLp[iLpIndex].getBc(iCGIndex, iCBIndex).getFcTimeObj(), "m") == oParam.getMPeakMaxFcjx()) {  
228 - if (_a_down(aLp, iLpIndex, iCGIndex, iCBIndex, oParam)) {  
229 - _a_up(iLpIndex, aLp,iCGIndex, iCBIndex, oParam);  
230 - } else {  
231 - break;  
232 - }  
233 - } else {  
234 - _a_up(iLpIndex, aLp,iCGIndex, iCBIndex, oParam);  
235 - }  
236 -  
237 - bLpFind = false;  
238 - _iIterCount ++;  
239 - }  
240 -  
241 - }  
242 -  
243 - return main; 1 +/**
  2 + * 调整某一圈的发车间隔,在已有的间隔上做修正。
  3 + * 1、圈的第一个班次,最后一个班次发车时间固定不变,调整其余班次间隔
  4 + * 2、调整的判定原则是某个班次和该路牌下一个班次之间的layovertime为负值,需要调整当前班次间隔
  5 + * 3、TODO:如果仅靠调整间隔无法调整,可以考虑删除某个路牌的班次
  6 + * 4、TODO:目前只用在第一圈第一个方向班次列表上,低谷在前,高峰在后
  7 + */
  8 +var AdjustHeadwayS1 = (function() {
  9 +
  10 + /**
  11 + * 从指定路牌的班次开始往下所有的班次发车时间尝试减一分钟。
  12 + * @param aLp 路牌数组
  13 + * @param lpIndex 从下往上第一个停站时间不足的班次所在路牌索引
  14 + * @param iCurrentGroupIndex 班次圈索引
  15 + * @param iCurrentBcIndex 班次索引
  16 + * @param oParam 参数对象
  17 + */
  18 + function _a_down(aLp, lpIndex, iCurrentGroupIndex, iCurrentBcIndex, oParam) {
  19 + // 如果最后一个路牌的班次就停站时间不足,则不调整
  20 + if (lpIndex == aLp.length - 1) {
  21 + return false;
  22 + }
  23 + // 有班次的路牌索引数组(往下)
  24 + var i;
  25 + var aLpIndex = [];
  26 + for (i = lpIndex; i < aLp.length; i++) {
  27 + if (aLp[i].getBc(iCurrentGroupIndex, iCurrentBcIndex)) {
  28 + aLpIndex.push(i);
  29 + }
  30 + }
  31 +
  32 + // 当前班次开始与下一个路牌的对应班次的发车时间间隔
  33 + var aHeadWay = [];
  34 + var oHeadWay;
  35 + for (i = 0; i < aLpIndex.length - 1; i++) {
  36 + oHeadWay = {};
  37 + oHeadWay.iStartLpIndex = aLpIndex[i];
  38 + oHeadWay.iEndLpIndex = aLpIndex[i + 1];
  39 + if (oParam.isMPeakBc(aLp[aLpIndex[i]].getBc(iCurrentGroupIndex, iCurrentBcIndex).getFcTimeObj())) {
  40 + oHeadWay.bMPeakBc = true;
  41 + } else {
  42 + oHeadWay.bMPeakBc = false;
  43 + }
  44 + oHeadWay.iHeadWay = aLp[aLpIndex[i + 1]].getBc(iCurrentGroupIndex, iCurrentBcIndex).getFcTimeObj().diff(
  45 + aLp[aLpIndex[i]].getBc(iCurrentGroupIndex, iCurrentBcIndex).getFcTimeObj(), "m"
  46 + );
  47 +
  48 + aHeadWay.push(oHeadWay);
  49 + }
  50 +
  51 + // 找出第一个间隔小于高峰最大发车间隔的位置,
  52 + // 然后从lpIndex开始到这个位置减发车时间,
  53 + // 从而达到从lpIndex开始到这个位置,局部减少发车时间的作用
  54 + // 最终的结果是停站时间足够,并且停站时间也是一个过渡效果
  55 + var bIsFind = false;
  56 + var iFindIndex;
  57 + for (i = 0; i < aHeadWay.length; i++) {
  58 + if (aHeadWay[i].bMPeakBc) {
  59 + if (aHeadWay[i].iHeadWay < oParam.getMPeakMaxFcjx()) {
  60 + iFindIndex = i;
  61 + bIsFind = true;
  62 + break;
  63 + }
  64 + } else {
  65 + iFindIndex = i;
  66 + bIsFind = true;
  67 + break;
  68 + }
  69 + }
  70 +
  71 + if (!bIsFind) {
  72 + return false;
  73 + }
  74 +
  75 + // 调整间隔
  76 + var iStartLpIndex = aHeadWay[iFindIndex].iStartLpIndex;
  77 + var oLp;
  78 + var oBc;
  79 + for (i = 0; i < aLpIndex.length; i++) {
  80 + if (aLpIndex[i] <= iStartLpIndex && aLpIndex[i] > lpIndex) {
  81 + oLp = aLp[aLpIndex[i]];
  82 + oBc = oLp.getBc(iCurrentGroupIndex, iCurrentBcIndex);
  83 + oBc.addMinuteToFcsj(-1); // 发车时间,到达时间减1分钟
  84 +
  85 + oLp.fnSetVerticalIntervalTime( // 调整对应的路牌发车间隔
  86 + iCurrentGroupIndex, iCurrentBcIndex,
  87 + oLp.fnGetVerticalIntervalTime(iCurrentGroupIndex, iCurrentBcIndex) - 1);
  88 + }
  89 + }
  90 +
  91 + return true;
  92 + }
  93 + // // TODO:向上局部减少发车调整有问题,不能下上所有的班次都减发车时间,需要像_a_down逐步减,下次修正
  94 + // function _a_up2(lpIndex, aLp,
  95 + // iCurrentGroupIndex, iCurrentBcIndex, oParam) {
  96 + // // 有班次的路牌索引数组(往上)
  97 + // var i;
  98 + // var aLpIndex = [];
  99 + // for (i = lpIndex; i >= 0; i--) {
  100 + // if (aLp[i].getBc(iCurrentGroupIndex, iCurrentBcIndex)) {
  101 + // aLpIndex.push(i);
  102 + // }
  103 + // }
  104 + // // 当前班次开始与下一个路牌的对应班次的发车时间间隔
  105 + // var aHeadWay = [];
  106 + // var oHeadWay = {};
  107 + // for (i = 0; i < aLpIndex.length - 1; i++) {
  108 + // oHeadWay = {};
  109 + // oHeadWay.iStartLpIndex = aLpIndex[i + 1];
  110 + // oHeadWay.iEndLpIndex = aLpIndex[i];
  111 + // if (oParam.isMPeakBc(aLp[aLpIndex[i + 1]].getBc(iCurrentGroupIndex, iCurrentBcIndex).getFcTimeObj())) {
  112 + // oHeadWay.bMPeakBc = true;
  113 + // } else {
  114 + // oHeadWay.bMPeakBc = false;
  115 + // }
  116 + // oHeadWay.iHeadWay = aLp[aLpIndex[i]].getBc(iCurrentGroupIndex, iCurrentBcIndex).getFcTimeObj().diff(
  117 + // aLp[aLpIndex[i + 1]].getBc(iCurrentGroupIndex, iCurrentBcIndex).getFcTimeObj(), "m"
  118 + // );
  119 + //
  120 + // aHeadWay.push(oHeadWay);
  121 + // }
  122 + //
  123 + // // 找出第一个间隔小的班次间隔
  124 + // var bIsFind = false;
  125 + // var iFindIndex;
  126 + // for (i = 0; i < aHeadWay.length; i++) {
  127 + // if (aHeadWay[i].bMPeakBc) {
  128 + // if (aHeadWay[i].iHeadWay > oParam.getMPeakMinFcjx()) {
  129 + // iFindIndex = i;
  130 + // bIsFind = true;
  131 + // break;
  132 + // }
  133 + // } else {
  134 + // iFindIndex = i;
  135 + // bIsFind = true;
  136 + // break;
  137 + // }
  138 + // }
  139 + //
  140 + // if (!bIsFind) {
  141 + // return false;
  142 + // }
  143 + //
  144 + // // 调整间隔
  145 + // var iStartLpIndex = aHeadWay[iFindIndex].iStartLpIndex;
  146 + // var oLp;
  147 + // var oBc;
  148 + // for (i = 0; i < aLpIndex.length; i++) {
  149 + // if (aLpIndex[i] <= lpIndex && aLpIndex[i] >= iStartLpIndex) {
  150 + // oLp = aLp[aLpIndex[i]];
  151 + // oBc = oLp.getBc(iCurrentGroupIndex, iCurrentBcIndex);
  152 + // oBc.addMinuteToFcsj(-1); // 发车时间,到达时间减1分钟
  153 + // }
  154 + // }
  155 + //
  156 + // return true;
  157 + //
  158 + // }
  159 +
  160 + /**
  161 + * 从指定路牌的班次开始往上所有的班次发车时间尝试减一分钟。
  162 + * @param lpIndex 开始路牌索引
  163 + * @param aLp 路牌列表
  164 + * @param iCurrentGroupIndex 当前班次圈索引
  165 + * @param iCurrentBcIndex 当前班次索引
  166 + * @param oParam 参数对象
  167 + */
  168 + function _a_up(lpIndex, aLp,
  169 + iCurrentGroupIndex, iCurrentBcIndex, oParam) {
  170 + var i;
  171 + var oLp;
  172 + var oBc;
  173 + for (i = lpIndex; i > 0; i--) { // 第一个路牌的班次不能动
  174 + oLp = aLp[i];
  175 + oBc = oLp.getBc(iCurrentGroupIndex, iCurrentBcIndex);
  176 + if (oBc) {
  177 + oBc.addMinuteToFcsj(-1); // 发车时间,到达时间减1分钟
  178 +
  179 + oLp.fnSetVerticalIntervalTime( // 调整对应的路牌发车间隔
  180 + iCurrentGroupIndex, iCurrentBcIndex,
  181 + oLp.fnGetVerticalIntervalTime(iCurrentGroupIndex, iCurrentBcIndex) - 1);
  182 + }
  183 +
  184 + }
  185 + }
  186 +
  187 + /**
  188 + * 主函数。
  189 + * @param oInternalSchedule 行车计划
  190 + * @param oParam 参数对象
  191 + * @param iCGIndex 圈索引
  192 + * @param iCBIndex 班次索引
  193 + * @param iNGIndex 同路牌下一个邻接圈索引
  194 + * @param iNBIndex 同路牌下一个邻接班次索引
  195 + * @param iMinLayoverTime 要求的最小停站时间
  196 + */
  197 + function main(oInternalSchedule, oParam,
  198 + iCGIndex, iCBIndex,
  199 + iNGIndex, iNBIndex,
  200 + iMinLayoverTime) {
  201 + var _iIterCount = 0; // 当前迭代次数
  202 + var _iMaxIter = 100; // 最大迭代100次
  203 +
  204 + var bLpFind = false;
  205 + var iLpIndex;
  206 + var i;
  207 + var aLp = oInternalSchedule.fnGetLpArray();
  208 + var oLp;
  209 + var oCBc;
  210 + var oNBc;
  211 + while (_iIterCount <= _iMaxIter) {
  212 + // 反方向查找第一个停站时间不足的班次
  213 + for (i = aLp.length - 1; i > 0; i--) {
  214 + oLp = aLp[i];
  215 + oCBc = oLp.getBc(iCGIndex, iCBIndex);
  216 + oNBc = oLp.getBc(iNGIndex, iNBIndex);
  217 + if (oCBc && oNBc) {
  218 + if (oNBc.getFcTimeObj().diff(oCBc.getArrTimeObj(), "m") <= (iMinLayoverTime - 1)) {
  219 + iLpIndex = i;
  220 + bLpFind = true;
  221 + break;
  222 + }
  223 + }
  224 + }
  225 + if (!bLpFind) {
  226 + break;
  227 + }
  228 +
  229 + if (iLpIndex == aLp.length - 1) { // 最后一个路牌的班次停站时间不足,不能调整了
  230 + break;
  231 + }
  232 +
  233 + // 如果当前班次和下一个班次的间隔是早高峰最大发车间隔,需要尝试下面的班次发车时间减1分钟
  234 + if (aLp[iLpIndex + 1].getBc(iCGIndex, iCBIndex).getFcTimeObj().diff(
  235 + aLp[iLpIndex].getBc(iCGIndex, iCBIndex).getFcTimeObj(), "m") == oParam.getMPeakMaxFcjx()) {
  236 + if (_a_down(aLp, iLpIndex, iCGIndex, iCBIndex, oParam)) {
  237 + _a_up(iLpIndex, aLp,iCGIndex, iCBIndex, oParam);
  238 + } else {
  239 + break;
  240 + }
  241 + } else {
  242 + _a_up(iLpIndex, aLp,iCGIndex, iCBIndex, oParam);
  243 + }
  244 +
  245 + bLpFind = false;
  246 + _iIterCount ++;
  247 + }
  248 +
  249 + }
  250 +
  251 + return main;
244 } ()); 252 } ());
245 \ No newline at end of file 253 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/headway/AdjustHeadwayS2.js
1 -/**  
2 - * 调整某一圈的发车间隔,在已有的间隔上做修正。  
3 - * 1、圈的第一个班次,发车时间固定不变,调整其余班次间隔  
4 - * 2、当前圈一般是副站圈,与邻接的主站班次之间的layovertime太大,调整  
5 - */  
6 -var AdjustHeadwayS2 = (function() {  
7 -  
8 - /**  
9 - * 调整班次发车时间(当前班次和紧领的下一个班次)  
10 - * @param oBcInfo 内部班次对象  
11 - * @param aLp 路牌列表  
12 - * @param iMinute 时间  
13 - * @private  
14 - */  
15 - function _modifyHeadway(oBcInfo, aLp, iMinute) {  
16 - if (!oBcInfo) {  
17 - return;  
18 - }  
19 -  
20 - // 调整班次发车间隔  
21 - var iBcGroupIndex = oBcInfo.iGroupIndex;  
22 - var iBcIndex = oBcInfo.iBcIndex;  
23 - var oLp = aLp[oBcInfo.iLpIndex];  
24 -  
25 - var oBc = oLp.getBc(iBcGroupIndex, iBcIndex);  
26 - var oNextBc = oLp.getBc(  
27 - iBcIndex == 1 ? iBcGroupIndex + 1 : iBcGroupIndex,  
28 - iBcIndex == 0 ? 1 : 0  
29 - );  
30 - if (oBc) {  
31 - oBc.addMinuteToFcsj(iMinute);  
32 - }  
33 - if (oNextBc) {  
34 - oNextBc.addMinuteToFcsj(iMinute);  
35 - }  
36 - }  
37 -  
38 - /**  
39 - * 从当前班次开始向上尝试减一分钟。  
40 - * @param oBcInfo 内部班次对象  
41 - * @param aLp 路牌列表  
42 - * @param oParam 参数对象  
43 - * @private  
44 - */  
45 - function _headway_up(oBcInfo, aLp, oParam) {  
46 - if (!oBcInfo) {  
47 - return;  
48 - }  
49 -  
50 - // 有班次的路牌索引数组(往下)  
51 - var i;  
52 - var aLpIndex = [];  
53 - for (i = oBcInfo.iLpIndex; i >= 0; i--) {  
54 - if (aLp[i].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex)) {  
55 - aLpIndex.push(i);  
56 - }  
57 - }  
58 -  
59 - // 当前班次与上一个班次之间的间隔列表  
60 - var aHeadWay = [];  
61 - var oHeadWay;  
62 - for (i = 0; i < aLpIndex.length - 1; i++) {  
63 - oHeadWay = {};  
64 - oHeadWay.iStartLpIndex = aLpIndex[i + 1];  
65 - oHeadWay.iEndLpIndex = aLpIndex[i];  
66 - if (oParam.isMPeakBc(aLp[aLpIndex[i + 1]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj())) {  
67 - oHeadWay.bMPeakBc = true;  
68 - } else if (oParam.isEPeakBc(aLp[aLpIndex[i + 1]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj())) {  
69 - oHeadWay.bEPeakBc = true;  
70 - } else {  
71 - oHeadWay.bTroughBc = true;  
72 - }  
73 -  
74 - oHeadWay.iHeadWay = aLp[aLpIndex[i]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj().diff(  
75 - aLp[aLpIndex[i + 1]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj(), "m"  
76 - );  
77 -  
78 - aHeadWay.push(oHeadWay);  
79 - }  
80 -  
81 - // 找出第一个间隔大于最小发车间隔的位置  
82 - // 从当前位置往上到此位置所有班次往前减一分钟  
83 - var bIsFind = false;  
84 - var iFindIndex;  
85 - for (i = 0; i < aHeadWay.length; i++) {  
86 - if (aHeadWay[i].bMPeakBc) { // 早高峰  
87 - if (aHeadWay[i].iHeadWay > oParam.getMPeakMinFcjx()) {  
88 - iFindIndex = i;  
89 - bIsFind = true;  
90 - break;  
91 - }  
92 - } else if (aHeadWay[i].bEPeakBc) { // 晚高峰  
93 - if (aHeadWay[i].iHeadWay > oParam.getEPeakMinFcjx()) {  
94 - iFindIndex = i;  
95 - bIsFind = true;  
96 - break;  
97 - }  
98 - } else { // 低谷  
99 - if (aHeadWay[i].iHeadWay > oParam.getTroughMinFcjx()) {  
100 - iFindIndex = i;  
101 - bIsFind = true;  
102 - break;  
103 - }  
104 - }  
105 - }  
106 -  
107 - if (!bIsFind) {  
108 - return;  
109 - }  
110 -  
111 - // 调整间隔  
112 - var _oBcInfo;  
113 - for (i = 0; i < iFindIndex; i++) {  
114 - _oBcInfo = {};  
115 - _oBcInfo.iLpIndex = aHeadWay[i].iStartLpIndex;  
116 - _oBcInfo.iGroupIndex = oBcInfo.iGroupIndex;  
117 - _oBcInfo.iBcIndex = oBcInfo.iBcIndex;  
118 - _modifyHeadway(_oBcInfo, aLp, -1);  
119 - }  
120 -  
121 - }  
122 -  
123 - /**  
124 - * 从当前班次开始向下尝试减一分钟。  
125 - * @param oBcInfo 内部班次对象  
126 - * @param aLp 路牌列表  
127 - * @param oParam 参数对象  
128 - * @private  
129 - */  
130 - function _headway_down(oBcInfo, aLp, oParam) {  
131 - if (!oBcInfo) {  
132 - return;  
133 - }  
134 -  
135 - // 有班次的路牌索引数组(往下)  
136 - var i;  
137 - var aLpIndex = [];  
138 - for (i = oBcInfo.iLpIndex; i < aLp.length; i++) {  
139 - if (aLp[i].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex)) {  
140 - aLpIndex.push(i);  
141 - }  
142 - }  
143 -  
144 - // 当前班次与下一个班次之间的间隔列表  
145 - var aHeadWay = [];  
146 - var oHeadWay;  
147 - for (i = 0; i < aLpIndex.length - 1; i++) {  
148 - oHeadWay = {};  
149 - oHeadWay.iStartLpIndex = aLpIndex[i];  
150 - oHeadWay.iEndLpIndex = aLpIndex[i + 1];  
151 - if (oParam.isMPeakBc(aLp[aLpIndex[i]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj())) {  
152 - oHeadWay.bMPeakBc = true;  
153 - } else if (oParam.isEPeakBc(aLp[aLpIndex[i]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj())) {  
154 - oHeadWay.bEPeakBc = true;  
155 - } else {  
156 - oHeadWay.bTroughBc = true;  
157 - }  
158 -  
159 - oHeadWay.iHeadWay = aLp[aLpIndex[i + 1]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj().diff(  
160 - aLp[aLpIndex[i]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj(), "m"  
161 - );  
162 -  
163 - aHeadWay.push(oHeadWay);  
164 - }  
165 -  
166 - // 找出第一个间隔小于最大发车间隔的位置  
167 - // 从当前位置往下到此位置所有班次往前减一分钟  
168 - var bIsFind = false;  
169 - var iFindIndex;  
170 - for (i = 0; i < aHeadWay.length; i++) {  
171 - if (aHeadWay[i].bMPeakBc) { // 早高峰  
172 - if (aHeadWay[i].iHeadWay < oParam.getMPeakMaxFcjx()) {  
173 - iFindIndex = i;  
174 - bIsFind = true;  
175 - break;  
176 - }  
177 - } else if (aHeadWay[i].bEPeakBc) { // 晚高峰  
178 - if (aHeadWay[i].iHeadWay < oParam.getEPeakMaxFcjx()) {  
179 - iFindIndex = i;  
180 - bIsFind = true;  
181 - break;  
182 - }  
183 - } else { // 低谷  
184 - if (aHeadWay[i].iHeadWay < oParam.getTroughMaxFcjx()) {  
185 - iFindIndex = i;  
186 - bIsFind = true;  
187 - break;  
188 - }  
189 - }  
190 - }  
191 -  
192 - if (!bIsFind) {  
193 - return;  
194 - }  
195 -  
196 - // 调整间隔  
197 - var _oBcInfo;  
198 - for (i = 0; i < iFindIndex; i++) {  
199 - _oBcInfo = {};  
200 - _oBcInfo.iLpIndex = aHeadWay[i].iStartLpIndex;  
201 - _oBcInfo.iGroupIndex = oBcInfo.iGroupIndex;  
202 - _oBcInfo.iBcIndex = oBcInfo.iBcIndex;  
203 - if (_oBcInfo.iLpIndex != oBcInfo.iLpIndex) {  
204 - // 跳过当前班次  
205 - _modifyHeadway(_oBcInfo, aLp, -1);  
206 - }  
207 - }  
208 - }  
209 -  
210 - /**  
211 - * 找出当前圈最大需要修正停站时间的班次对象。  
212 - * @param oInternalSchedule 行车计划  
213 - * @param iCGIndex 圈索引(副站班次圈)  
214 - * @param iCBIndex 班次索引  
215 - * @param iNGIndex 同路牌下一个邻接圈索引(主站班次圈)  
216 - * @param iNBIndex 同路牌下一个邻接班次索引  
217 - * @param fPercent 最大超出百分比  
218 - * @return {*} {路牌索引,圈索引,班次索引}  
219 - * @private  
220 - */  
221 - function _maxMoreLayoverBcInfo(  
222 - oInternalSchedule,  
223 - iCGIndex, iCBIndex,  
224 - iNGIndex, iNBIndex,  
225 - fPercent  
226 - ) {  
227 - var i;  
228 - var oLp;  
229 - var oBc;  
230 - var oNextBc;  
231 - var iMaxLayoverTime;  
232 - var iActualLayoverTime;  
233 - var iActualMaxLayoverTime = 0;  
234 - var iActualMaxLayoverTimeLpIndex;  
235 -  
236 - for (i = 0; i < oInternalSchedule.fnGetLpArray().length; i++) {  
237 - oLp = oInternalSchedule.fnGetLpArray()[i];  
238 - oBc = oLp.getBc(iCGIndex, iCBIndex);  
239 - oNextBc = oLp.getBc(iNGIndex, iNBIndex);  
240 - if (oBc && oNextBc) {  
241 - iMaxLayoverTime = oInternalSchedule._$calcuLayoverTime(  
242 - oBc.getFcTimeObj(), oBc.isUp())[1];  
243 - iActualLayoverTime = oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m");  
244 -  
245 - if (iActualLayoverTime > iMaxLayoverTime &&  
246 - iActualLayoverTime > iMaxLayoverTime * (1 + fPercent) &&  
247 - iActualLayoverTime > iActualMaxLayoverTime  
248 - ) {  
249 - iActualMaxLayoverTime = iActualLayoverTime;  
250 - iActualMaxLayoverTimeLpIndex = i;  
251 - }  
252 - }  
253 - }  
254 -  
255 - if (iActualMaxLayoverTimeLpIndex == undefined) {  
256 - return false;  
257 - } else {  
258 - return {  
259 - iLpIndex: iActualMaxLayoverTimeLpIndex,  
260 - iGroupIndex: iNGIndex, // 主站班次圈索引  
261 - iBcIndex: iNBIndex  
262 - };  
263 - }  
264 - }  
265 -  
266 - /**  
267 - * 计算当前圈是否需要修正layovertime。  
268 - * @param oInternalSchedule 行车计划对象  
269 - * @param iCGIndex 圈索引(副站班次圈)  
270 - * @param iCBIndex 班次索引  
271 - * @param iNGIndex 同路牌下一个邻接圈索引(主站班次圈)  
272 - * @param iNBIndex 同路牌下一个邻接班次索引  
273 - * @param fPercent 最大超出百分比  
274 - * @return {boolean}  
275 - * @private  
276 - */  
277 - function _isNeedModify(  
278 - oInternalSchedule,  
279 - iCGIndex, iCBIndex,  
280 - iNGIndex, iNBIndex,  
281 - fPercent  
282 - ) {  
283 - var i;  
284 - var oLp;  
285 - var oBc;  
286 - var oNextBc;  
287 - var iMaxLayoverTime = 0;  
288 - // 计算当前圈的所有相关班次总最大标准停站时间  
289 - for (i = 0; i < oInternalSchedule.fnGetLpArray().length; i++) {  
290 - oLp = oInternalSchedule.fnGetLpArray()[i];  
291 - oBc = oLp.getBc(iCGIndex, iCBIndex);  
292 - oNextBc = oLp.getBc(iNGIndex, iNBIndex);  
293 - if (oBc && oNextBc) {  
294 - iMaxLayoverTime += oInternalSchedule._$calcuLayoverTime(  
295 - oBc.getFcTimeObj(), oBc.isUp())[1];  
296 - }  
297 - }  
298 -  
299 - var iActualLayoverTime = 0;  
300 - // 计算当前圈的所有相关班次总停站时间  
301 - for (i = 0; i < oInternalSchedule.fnGetLpArray().length; i++) {  
302 - oLp = oInternalSchedule.fnGetLpArray()[i];  
303 - oBc = oLp.getBc(iCGIndex, iCBIndex);  
304 - oNextBc = oLp.getBc(iNGIndex, iNBIndex);  
305 - if (oBc && oNextBc) {  
306 - iActualLayoverTime += oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m");  
307 - }  
308 - }  
309 -  
310 - // console.log("iMaxLayoverTime=" + iMaxLayoverTime);  
311 - // console.log("iActualLayoverTime=" + iActualLayoverTime);  
312 -  
313 - // 判定是否超出指定范围  
314 - if (iActualLayoverTime > iMaxLayoverTime &&  
315 - iActualLayoverTime > iMaxLayoverTime * (1 + fPercent)) {  
316 - return true;  
317 - } else {  
318 - return false;  
319 - }  
320 - }  
321 -  
322 - /**  
323 - * 主函数。  
324 - * @param oInternalSchedule 行车计划  
325 - * @param oParam 参数对象  
326 - * @param iCGIndex 圈索引(副站班次圈)  
327 - * @param iCBIndex 班次索引  
328 - * @param iNGIndex 同路牌下一个邻接圈索引(主站班次圈)  
329 - * @param iNBIndex 同路牌下一个邻接班次索引  
330 - * @param fPercent 最大超出百分比  
331 - */  
332 - function main(  
333 - oInternalSchedule, oParam,  
334 - iCGIndex, iCBIndex,  
335 - iNGIndex, iNBIndex,  
336 - fPercent  
337 - ) {  
338 - var _iIterCount = 0; // 当前迭代次数  
339 - var _iMaxIter = 100; // 最大迭代次数  
340 -  
341 - var oBcInfo; // 内部班次对象  
342 -  
343 - while (_iIterCount <= _iMaxIter) {  
344 -  
345 - // 判定当前圈的layovertime是否超出百分比  
346 - if (_isNeedModify(oInternalSchedule,  
347 - iCGIndex, iCBIndex,  
348 - iNGIndex, iNBIndex, fPercent)) {  
349 - // 找出超出最大的班次对象  
350 - oBcInfo = _maxMoreLayoverBcInfo(  
351 - oInternalSchedule,  
352 - iCGIndex, iCBIndex,  
353 - iNGIndex, iNBIndex, fPercent  
354 - );  
355 - // 尝试向上部分班次逐个调整  
356 - _headway_up(oBcInfo, oInternalSchedule.fnGetLpArray(), oParam);  
357 - // 尝试调整当前班次  
358 - _modifyHeadway(oBcInfo, oInternalSchedule.fnGetLpArray(), -1);  
359 - // 尝试向下部分班次逐个调整  
360 - _headway_down(oBcInfo, oInternalSchedule.fnGetLpArray(), oParam);  
361 -  
362 - }  
363 -  
364 - _iIterCount ++;  
365 - }  
366 -  
367 - }  
368 -  
369 - return main; 1 +/**
  2 + * 调整某一圈的发车间隔,在已有的间隔上做修正。
  3 + * 1、圈的第一个班次,发车时间固定不变,调整其余班次间隔
  4 + * 2、当前圈一般是副站圈,与邻接的主站班次之间的layovertime太大,调整
  5 + */
  6 +var AdjustHeadwayS2 = (function() {
  7 +
  8 + /**
  9 + * 调整班次发车时间(当前班次和紧领的下一个班次)
  10 + * @param oBcInfo 内部班次对象
  11 + * @param aLp 路牌列表
  12 + * @param iMinute 时间
  13 + * @private
  14 + */
  15 + function _modifyHeadway(oBcInfo, aLp, iMinute) {
  16 + if (!oBcInfo) {
  17 + return;
  18 + }
  19 +
  20 + // 调整班次发车间隔
  21 + var iBcGroupIndex = oBcInfo.iGroupIndex;
  22 + var iBcIndex = oBcInfo.iBcIndex;
  23 + var oLp = aLp[oBcInfo.iLpIndex];
  24 +
  25 + var oBc = oLp.getBc(iBcGroupIndex, iBcIndex);
  26 + var oNextBc = oLp.getBc(
  27 + iBcIndex == 1 ? iBcGroupIndex + 1 : iBcGroupIndex,
  28 + iBcIndex == 0 ? 1 : 0
  29 + );
  30 + if (oBc) {
  31 + oBc.addMinuteToFcsj(iMinute);
  32 +
  33 + oLp.fnSetVerticalIntervalTime( // 调整对应的路牌发车间隔
  34 + iBcGroupIndex, iBcIndex,
  35 + oLp.fnGetVerticalIntervalTime(iBcGroupIndex, iBcIndex) + iMinute);
  36 + }
  37 + if (oNextBc) {
  38 + oNextBc.addMinuteToFcsj(iMinute);
  39 + }
  40 + }
  41 +
  42 + /**
  43 + * 从当前班次开始向上尝试减一分钟。
  44 + * @param oBcInfo 内部班次对象
  45 + * @param aLp 路牌列表
  46 + * @param oParam 参数对象
  47 + * @private
  48 + */
  49 + function _headway_up(oBcInfo, aLp, oParam) {
  50 + if (!oBcInfo) {
  51 + return;
  52 + }
  53 +
  54 + // 有班次的路牌索引数组(往下)
  55 + var i;
  56 + var aLpIndex = [];
  57 + for (i = oBcInfo.iLpIndex; i >= 0; i--) {
  58 + if (aLp[i].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex)) {
  59 + aLpIndex.push(i);
  60 + }
  61 + }
  62 +
  63 + // 当前班次与上一个班次之间的间隔列表
  64 + var aHeadWay = [];
  65 + var oHeadWay;
  66 + for (i = 0; i < aLpIndex.length - 1; i++) {
  67 + oHeadWay = {};
  68 + oHeadWay.iStartLpIndex = aLpIndex[i + 1];
  69 + oHeadWay.iEndLpIndex = aLpIndex[i];
  70 + if (oParam.isMPeakBc(aLp[aLpIndex[i + 1]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj())) {
  71 + oHeadWay.bMPeakBc = true;
  72 + } else if (oParam.isEPeakBc(aLp[aLpIndex[i + 1]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj())) {
  73 + oHeadWay.bEPeakBc = true;
  74 + } else {
  75 + oHeadWay.bTroughBc = true;
  76 + }
  77 +
  78 + oHeadWay.iHeadWay = aLp[aLpIndex[i]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj().diff(
  79 + aLp[aLpIndex[i + 1]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj(), "m"
  80 + );
  81 +
  82 + aHeadWay.push(oHeadWay);
  83 + }
  84 +
  85 + // 找出第一个间隔大于最小发车间隔的位置
  86 + // 从当前位置往上到此位置所有班次往前减一分钟
  87 + var bIsFind = false;
  88 + var iFindIndex;
  89 + for (i = 0; i < aHeadWay.length; i++) {
  90 + if (aHeadWay[i].bMPeakBc) { // 早高峰
  91 + if (aHeadWay[i].iHeadWay > oParam.getMPeakMinFcjx()) {
  92 + iFindIndex = i;
  93 + bIsFind = true;
  94 + break;
  95 + }
  96 + } else if (aHeadWay[i].bEPeakBc) { // 晚高峰
  97 + if (aHeadWay[i].iHeadWay > oParam.getEPeakMinFcjx()) {
  98 + iFindIndex = i;
  99 + bIsFind = true;
  100 + break;
  101 + }
  102 + } else { // 低谷
  103 + if (aHeadWay[i].iHeadWay > oParam.getTroughMinFcjx()) {
  104 + iFindIndex = i;
  105 + bIsFind = true;
  106 + break;
  107 + }
  108 + }
  109 + }
  110 +
  111 + if (!bIsFind) {
  112 + return;
  113 + }
  114 +
  115 + // 调整间隔
  116 + var _oBcInfo;
  117 + for (i = 0; i < iFindIndex; i++) {
  118 + _oBcInfo = {};
  119 + _oBcInfo.iLpIndex = aHeadWay[i].iStartLpIndex;
  120 + _oBcInfo.iGroupIndex = oBcInfo.iGroupIndex;
  121 + _oBcInfo.iBcIndex = oBcInfo.iBcIndex;
  122 + _modifyHeadway(_oBcInfo, aLp, -1);
  123 + }
  124 +
  125 + }
  126 +
  127 + /**
  128 + * 从当前班次开始向下尝试减一分钟。
  129 + * @param oBcInfo 内部班次对象
  130 + * @param aLp 路牌列表
  131 + * @param oParam 参数对象
  132 + * @private
  133 + */
  134 + function _headway_down(oBcInfo, aLp, oParam) {
  135 + if (!oBcInfo) {
  136 + return;
  137 + }
  138 +
  139 + // 有班次的路牌索引数组(往下)
  140 + var i;
  141 + var aLpIndex = [];
  142 + for (i = oBcInfo.iLpIndex; i < aLp.length; i++) {
  143 + if (aLp[i].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex)) {
  144 + aLpIndex.push(i);
  145 + }
  146 + }
  147 +
  148 + // 当前班次与下一个班次之间的间隔列表
  149 + var aHeadWay = [];
  150 + var oHeadWay;
  151 + for (i = 0; i < aLpIndex.length - 1; i++) {
  152 + oHeadWay = {};
  153 + oHeadWay.iStartLpIndex = aLpIndex[i];
  154 + oHeadWay.iEndLpIndex = aLpIndex[i + 1];
  155 + if (oParam.isMPeakBc(aLp[aLpIndex[i]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj())) {
  156 + oHeadWay.bMPeakBc = true;
  157 + } else if (oParam.isEPeakBc(aLp[aLpIndex[i]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj())) {
  158 + oHeadWay.bEPeakBc = true;
  159 + } else {
  160 + oHeadWay.bTroughBc = true;
  161 + }
  162 +
  163 + oHeadWay.iHeadWay = aLp[aLpIndex[i + 1]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj().diff(
  164 + aLp[aLpIndex[i]].getBc(oBcInfo.iGroupIndex, oBcInfo.iBcIndex).getFcTimeObj(), "m"
  165 + );
  166 +
  167 + aHeadWay.push(oHeadWay);
  168 + }
  169 +
  170 + // 找出第一个间隔小于最大发车间隔的位置
  171 + // 从当前位置往下到此位置所有班次往前减一分钟
  172 + var bIsFind = false;
  173 + var iFindIndex;
  174 + for (i = 0; i < aHeadWay.length; i++) {
  175 + if (aHeadWay[i].bMPeakBc) { // 早高峰
  176 + if (aHeadWay[i].iHeadWay < oParam.getMPeakMaxFcjx()) {
  177 + iFindIndex = i;
  178 + bIsFind = true;
  179 + break;
  180 + }
  181 + } else if (aHeadWay[i].bEPeakBc) { // 晚高峰
  182 + if (aHeadWay[i].iHeadWay < oParam.getEPeakMaxFcjx()) {
  183 + iFindIndex = i;
  184 + bIsFind = true;
  185 + break;
  186 + }
  187 + } else { // 低谷
  188 + if (aHeadWay[i].iHeadWay < oParam.getTroughMaxFcjx()) {
  189 + iFindIndex = i;
  190 + bIsFind = true;
  191 + break;
  192 + }
  193 + }
  194 + }
  195 +
  196 + if (!bIsFind) {
  197 + return;
  198 + }
  199 +
  200 + // 调整间隔
  201 + var _oBcInfo;
  202 + for (i = 0; i < iFindIndex; i++) {
  203 + _oBcInfo = {};
  204 + _oBcInfo.iLpIndex = aHeadWay[i].iStartLpIndex;
  205 + _oBcInfo.iGroupIndex = oBcInfo.iGroupIndex;
  206 + _oBcInfo.iBcIndex = oBcInfo.iBcIndex;
  207 + if (_oBcInfo.iLpIndex != oBcInfo.iLpIndex) {
  208 + // 跳过当前班次
  209 + _modifyHeadway(_oBcInfo, aLp, -1);
  210 + }
  211 + }
  212 + }
  213 +
  214 + /**
  215 + * 找出当前圈最大需要修正停站时间的班次对象。
  216 + * @param oInternalSchedule 行车计划
  217 + * @param iCGIndex 圈索引(副站班次圈)
  218 + * @param iCBIndex 班次索引
  219 + * @param iNGIndex 同路牌下一个邻接圈索引(主站班次圈)
  220 + * @param iNBIndex 同路牌下一个邻接班次索引
  221 + * @param fPercent 最大超出百分比
  222 + * @return {*} {路牌索引,圈索引,班次索引}
  223 + * @private
  224 + */
  225 + function _maxMoreLayoverBcInfo(
  226 + oInternalSchedule,
  227 + iCGIndex, iCBIndex,
  228 + iNGIndex, iNBIndex,
  229 + fPercent
  230 + ) {
  231 + var i;
  232 + var oLp;
  233 + var oBc;
  234 + var oNextBc;
  235 + var iMaxLayoverTime;
  236 + var iActualLayoverTime;
  237 + var iActualMaxLayoverTime = 0;
  238 + var iActualMaxLayoverTimeLpIndex;
  239 +
  240 + for (i = 0; i < oInternalSchedule.fnGetLpArray().length; i++) {
  241 + oLp = oInternalSchedule.fnGetLpArray()[i];
  242 + oBc = oLp.getBc(iCGIndex, iCBIndex);
  243 + oNextBc = oLp.getBc(iNGIndex, iNBIndex);
  244 + if (oBc && oNextBc) {
  245 + iMaxLayoverTime = oInternalSchedule._$calcuLayoverTime(
  246 + oBc.getFcTimeObj(), oBc.isUp())[1];
  247 + iActualLayoverTime = oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m");
  248 +
  249 + if (iActualLayoverTime > iMaxLayoverTime &&
  250 + iActualLayoverTime > iMaxLayoverTime * (1 + fPercent) &&
  251 + iActualLayoverTime > iActualMaxLayoverTime
  252 + ) {
  253 + iActualMaxLayoverTime = iActualLayoverTime;
  254 + iActualMaxLayoverTimeLpIndex = i;
  255 + }
  256 + }
  257 + }
  258 +
  259 + if (iActualMaxLayoverTimeLpIndex == undefined) {
  260 + return false;
  261 + } else {
  262 + return {
  263 + iLpIndex: iActualMaxLayoverTimeLpIndex,
  264 + iGroupIndex: iNGIndex, // 主站班次圈索引
  265 + iBcIndex: iNBIndex
  266 + };
  267 + }
  268 + }
  269 +
  270 + /**
  271 + * 计算当前圈是否需要修正layovertime。
  272 + * @param oInternalSchedule 行车计划对象
  273 + * @param iCGIndex 圈索引(副站班次圈)
  274 + * @param iCBIndex 班次索引
  275 + * @param iNGIndex 同路牌下一个邻接圈索引(主站班次圈)
  276 + * @param iNBIndex 同路牌下一个邻接班次索引
  277 + * @param fPercent 最大超出百分比
  278 + * @return {boolean}
  279 + * @private
  280 + */
  281 + function _isNeedModify(
  282 + oInternalSchedule,
  283 + iCGIndex, iCBIndex,
  284 + iNGIndex, iNBIndex,
  285 + fPercent
  286 + ) {
  287 + var i;
  288 + var oLp;
  289 + var oBc;
  290 + var oNextBc;
  291 + var iMaxLayoverTime = 0;
  292 + // 计算当前圈的所有相关班次总最大标准停站时间
  293 + for (i = 0; i < oInternalSchedule.fnGetLpArray().length; i++) {
  294 + oLp = oInternalSchedule.fnGetLpArray()[i];
  295 + oBc = oLp.getBc(iCGIndex, iCBIndex);
  296 + oNextBc = oLp.getBc(iNGIndex, iNBIndex);
  297 + if (oBc && oNextBc) {
  298 + iMaxLayoverTime += oInternalSchedule._$calcuLayoverTime(
  299 + oBc.getFcTimeObj(), oBc.isUp())[1];
  300 + }
  301 + }
  302 +
  303 + var iActualLayoverTime = 0;
  304 + // 计算当前圈的所有相关班次总停站时间
  305 + for (i = 0; i < oInternalSchedule.fnGetLpArray().length; i++) {
  306 + oLp = oInternalSchedule.fnGetLpArray()[i];
  307 + oBc = oLp.getBc(iCGIndex, iCBIndex);
  308 + oNextBc = oLp.getBc(iNGIndex, iNBIndex);
  309 + if (oBc && oNextBc) {
  310 + iActualLayoverTime += oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m");
  311 + }
  312 + }
  313 +
  314 + // console.log("iMaxLayoverTime=" + iMaxLayoverTime);
  315 + // console.log("iActualLayoverTime=" + iActualLayoverTime);
  316 +
  317 + // 判定是否超出指定范围
  318 + if (iActualLayoverTime > iMaxLayoverTime &&
  319 + iActualLayoverTime > iMaxLayoverTime * (1 + fPercent)) {
  320 + return true;
  321 + } else {
  322 + return false;
  323 + }
  324 + }
  325 +
  326 + /**
  327 + * 主函数。
  328 + * @param oInternalSchedule 行车计划
  329 + * @param oParam 参数对象
  330 + * @param iCGIndex 圈索引(副站班次圈)
  331 + * @param iCBIndex 班次索引
  332 + * @param iNGIndex 同路牌下一个邻接圈索引(主站班次圈)
  333 + * @param iNBIndex 同路牌下一个邻接班次索引
  334 + * @param fPercent 最大超出百分比
  335 + */
  336 + function main(
  337 + oInternalSchedule, oParam,
  338 + iCGIndex, iCBIndex,
  339 + iNGIndex, iNBIndex,
  340 + fPercent
  341 + ) {
  342 + var _iIterCount = 0; // 当前迭代次数
  343 + var _iMaxIter = 100; // 最大迭代次数
  344 +
  345 + var oBcInfo; // 内部班次对象
  346 +
  347 + while (_iIterCount <= _iMaxIter) {
  348 +
  349 + // 判定当前圈的layovertime是否超出百分比
  350 + if (_isNeedModify(oInternalSchedule,
  351 + iCGIndex, iCBIndex,
  352 + iNGIndex, iNBIndex, fPercent)) {
  353 + // 找出超出最大的班次对象
  354 + oBcInfo = _maxMoreLayoverBcInfo(
  355 + oInternalSchedule,
  356 + iCGIndex, iCBIndex,
  357 + iNGIndex, iNBIndex, fPercent
  358 + );
  359 + // 尝试向上部分班次逐个调整
  360 + _headway_up(oBcInfo, oInternalSchedule.fnGetLpArray(), oParam);
  361 + // 尝试调整当前班次
  362 + _modifyHeadway(oBcInfo, oInternalSchedule.fnGetLpArray(), -1);
  363 + // 尝试向下部分班次逐个调整
  364 + _headway_down(oBcInfo, oInternalSchedule.fnGetLpArray(), oParam);
  365 +
  366 + }
  367 +
  368 + _iIterCount ++;
  369 + }
  370 +
  371 + }
  372 +
  373 + return main;
370 } ()); 374 } ());
371 \ No newline at end of file 375 \ No newline at end of file