Commit cf8d49f23809ce9d4257cf1d7befdb8739630d86

Authored by 廖磊
2 parents 103d57a1 4646ad5d

Merge branch 'pudong' of http://222.66.0.204:8090/panzhaov5/bsth_control

into pudong
Showing 31 changed files with 5489 additions and 1878 deletions
src/main/resources/static/pages/base/timesmodel/add.html
@@ -149,7 +149,10 @@ @@ -149,7 +149,10 @@
149 <input type="radio" class="icheck" name="baseRes" value=1> 班型/人次/车辆 149 <input type="radio" class="icheck" name="baseRes" value=1> 班型/人次/车辆
150 </label> 150 </label>
151 <label> 151 <label>
152 - <input type="radio" class="icheck" name="baseRes" value=2 checked> 发车间隔分析 152 + <input type="radio" class="icheck" name="baseRes" value=2 > 发车间隔分析(旧:一步调整)
  153 + </label>
  154 + <label>
  155 + <input type="radio" class="icheck" name="baseRes" value=3 checked> 发车间隔分析(新:增量调整-单向进出场)
153 </label> 156 </label>
154 <label> 157 <label>
155 <input type="radio" class="icheck" name="baseRes" value=0> 客流大数据分析 158 <input type="radio" class="icheck" name="baseRes" value=0> 客流大数据分析
src/main/resources/static/pages/base/timesmodel/gantt.html
@@ -169,7 +169,6 @@ @@ -169,7 +169,6 @@
169 <script src="/pages/base/timesmodel/js/v1/lpFun.js"></script> 169 <script src="/pages/base/timesmodel/js/v1/lpFun.js"></script>
170 <script src="/pages/base/timesmodel/js/v1/scheduleInitialize.js"></script> 170 <script src="/pages/base/timesmodel/js/v1/scheduleInitialize.js"></script>
171 <script src="/pages/base/timesmodel/js/v1/AdjustTrip.js"></script> 171 <script src="/pages/base/timesmodel/js/v1/AdjustTrip.js"></script>
172 -<script src="/pages/base/timesmodel/js/v1/AdjustTrip2.js"></script>  
173 <script src="/pages/base/timesmodel/js/v2/ParameterObj.js"></script> 172 <script src="/pages/base/timesmodel/js/v2/ParameterObj.js"></script>
174 <script src="/pages/base/timesmodel/js/v2/core/InternalBcObj.js"></script> 173 <script src="/pages/base/timesmodel/js/v2/core/InternalBcObj.js"></script>
175 <script src="/pages/base/timesmodel/js/v2/core/InternalGroupObj.js"></script> 174 <script src="/pages/base/timesmodel/js/v2/core/InternalGroupObj.js"></script>
@@ -179,9 +178,27 @@ @@ -179,9 +178,27 @@
179 <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS2.js"></script> 178 <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS2.js"></script>
180 <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS3.js"></script> 179 <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS3.js"></script>
181 <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS4.js"></script> 180 <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS4.js"></script>
182 -<script src="/pages/base/timesmodel/js/v2/strategy/StrategyUtils.js"></script>  
183 <script src="/pages/base/timesmodel/js/v2/main_v2.js"></script> 181 <script src="/pages/base/timesmodel/js/v2/main_v2.js"></script>
184 -<!--<script src="/pages/base/timesmodel/js/d3.relationshipgraph.js"></script>--> 182 +
  183 +<!--
  184 +使用新的echart画图,暂时不用d3,之后会吧d3的放到新的文件里
  185 +<script src="/pages/base/timesmodel/js/d3.relationshipgraph.js"></script>
  186 +-->
  187 +
  188 +<script src="/pages/base/timesmodel/js/v2_2/InternalScheduleObj.js"></script>
  189 +<script src="/pages/base/timesmodel/js/v2_2/main_v2_2_excel.js"></script>
  190 +<script src="/pages/base/timesmodel/js/v2_2/main_v2_2.js"></script>
  191 +<script src="/pages/base/timesmodel/js/v2_2/strategy/workhours/ModifyBcTripWHS1.js"></script>
  192 +<script src="/pages/base/timesmodel/js/v2_2/strategy/headway/CalcuHeadwayS1.js"></script>
  193 +<script src="/pages/base/timesmodel/js/v2_2/strategy/headway/CalcuHeadwayS2.js"></script>
  194 +<script src="/pages/base/timesmodel/js/v2_2/strategy/headway/AdjustHeadwayS1.js"></script>
  195 +<script src="/pages/base/timesmodel/js/v2_2/strategy/headway/AdjustHeadwayS2.js"></script>
  196 +<script src="/pages/base/timesmodel/js/v2_2/strategy/headway/AdjustHeadwayS3_eat.js"></script>
  197 +<script src="/pages/base/timesmodel/js/v2_2/strategy/runtime/LinearRuntimeS1.js"></script>
  198 +<script src="/pages/base/timesmodel/js/v2_2/strategy/layovertime/LayoverTimeS1.js"></script>
  199 +<script src="/pages/base/timesmodel/js/v2/strategy/StrategyUtils.js"></script>
  200 +<script src="/pages/base/timesmodel/js/v2_2/strategy/StrategyUtils.js"></script>
  201 +
185 <script src="/pages/base/timesmodel/js/errorinfo.js"></script> 202 <script src="/pages/base/timesmodel/js/errorinfo.js"></script>
186 <script src="/pages/base/timesmodel/js/parameters.js"></script> 203 <script src="/pages/base/timesmodel/js/parameters.js"></script>
187 <script src="/pages/base/timesmodel/js/systemTools.js"></script> 204 <script src="/pages/base/timesmodel/js/systemTools.js"></script>
src/main/resources/static/pages/base/timesmodel/js/add-form-wizard.js
@@ -322,7 +322,7 @@ var SKBFormWizard = function() { @@ -322,7 +322,7 @@ var SKBFormWizard = function() {
322 tempName = 'carnum_temp'; 322 tempName = 'carnum_temp';
323 else if(n==1) 323 else if(n==1)
324 tempName = 'bctype_temp'; 324 tempName = 'bctype_temp';
325 - else if (n==2) 325 + else if (n==2 || n == 3)
326 tempName = 'fcjx_temp'; 326 tempName = 'fcjx_temp';
327 // 2、获参数详情模版html内容. 327 // 2、获参数详情模版html内容.
328 $.get('/pages/base/timesmodel/tepms/'+ tempName + '.html', function(html){ 328 $.get('/pages/base/timesmodel/tepms/'+ tempName + '.html', function(html){
@@ -394,7 +394,7 @@ var SKBFormWizard = function() { @@ -394,7 +394,7 @@ var SKBFormWizard = function() {
394 }else if(n==1) { 394 }else if(n==1) {
395 // 返回参数详情模版. 395 // 返回参数详情模版.
396 return cb && cb ({'forminput':template(tempName,{map:map}),'datadisplay': template(tempName +'config',{map:null})}); 396 return cb && cb ({'forminput':template(tempName,{map:map}),'datadisplay': template(tempName +'config',{map:null})});
397 - }else if (n==2) { 397 + }else if (n==2 || n == 3) {
398 // 更具站点路由版本获取起点终点站 398 // 更具站点路由版本获取起点终点站
399 var iversion = $('#lineVersionSelect').val(); 399 var iversion = $('#lineVersionSelect').val();
400 $get('/stationroute/all',{'line.id_eq':lineId,'destroy_eq':0, 'versions_eq': iversion},function(result) { 400 $get('/stationroute/all',{'line.id_eq':lineId,'destroy_eq':0, 'versions_eq': iversion},function(result) {
@@ -974,7 +974,7 @@ var SKBFormWizard = function() { @@ -974,7 +974,7 @@ var SKBFormWizard = function() {
974 layer.close(i); 974 layer.close(i);
975 }); 975 });
976 976
977 - } else if (baseRes == 2) { // 发车间隔分析 977 + } else if (baseRes == 2 || baseRes == 3) { // 发车间隔分析
978 // 上下行首末班日期控件 978 // 上下行首末班日期控件
979 $('#startStationFirstTime_id').datetimepicker({format : 'HH:mm',locale: 'zh-cn'}); 979 $('#startStationFirstTime_id').datetimepicker({format : 'HH:mm',locale: 'zh-cn'});
980 $('#startStationEndTime_id').datetimepicker({format : 'HH:mm',locale: 'zh-cn'}); 980 $('#startStationEndTime_id').datetimepicker({format : 'HH:mm',locale: 'zh-cn'});
src/main/resources/static/pages/base/timesmodel/js/d3.relationshipgraph.js
@@ -321,7 +321,7 @@ $(&#39;.parambtn&#39;).on(&#39;click&#39;, function() { @@ -321,7 +321,7 @@ $(&#39;.parambtn&#39;).on(&#39;click&#39;, function() {
321 $.get('/pages/base/timesmodel/paramadd.html', function(m){ 321 $.get('/pages/base/timesmodel/paramadd.html', function(m){
322 $(pjaxContainer).append(m); 322 $(pjaxContainer).append(m);
323 // 规定被选元素要触发的事件。可以使自定义事件(使用 bind() 函数来附加),或者任何标准事件。 323 // 规定被选元素要触发的事件。可以使自定义事件(使用 bind() 函数来附加),或者任何标准事件。
324 - $('#paramadd_mobal').trigger('paramAddMobal.show', Main_v2); 324 + $('#paramadd_mobal').trigger('paramAddMobal.show', [Main_v2, Main_v2_2, InternalScheduleObj_v2_2]);
325 }); 325 });
326 }); 326 });
327 327
src/main/resources/static/pages/base/timesmodel/js/gantt.js
@@ -72,6 +72,10 @@ @@ -72,6 +72,10 @@
72 _paramObj = Main_v2.getFactory().createParameterObj(map, dataMap); 72 _paramObj = Main_v2.getFactory().createParameterObj(map, dataMap);
73 map.clzs = _paramObj.calcuClzx(); 73 map.clzs = _paramObj.calcuClzx();
74 CSMap = getMaxCarAndStopSpace1(map); 74 CSMap = getMaxCarAndStopSpace1(map);
  75 + } else if (map.baseRes == '3') { // 主站停站使用v2_2版本
  76 + _paramObj = Main_v2.getFactory().createParameterObj(map, dataMap); // TODO:暂时使用v2_1版本的方法,通用的,后续再放到v2_2版本中
  77 + map.clzs = InternalScheduleObj_v2_2.calcuClzx(_paramObj);
  78 + CSMap = getMaxCarAndStopSpace1(map);
75 } 79 }
76 80
77 // 定义时间参数. 81 // 定义时间参数.
@@ -93,6 +97,9 @@ @@ -93,6 +97,9 @@
93 // TODO:CSMap.maxCar 之后要设定一下的 97 // TODO:CSMap.maxCar 之后要设定一下的
94 data = Main_v2.BXPplaceClassesTime03(_paramObj, CSMap.maxCar); 98 data = Main_v2.BXPplaceClassesTime03(_paramObj, CSMap.maxCar);
95 Main_v2.exportDataConfig(data.aInternalLpObj); 99 Main_v2.exportDataConfig(data.aInternalLpObj);
  100 + } else if (map.baseRes == '3') { // 主站停站使用v2_2版本
  101 + data = Main_v2_2.BXPplaceClassesTime03(_paramObj, CSMap.maxCar);
  102 + Main_v2_2.exportDataConfig(data.aInternalLpObj);
96 } 103 }
97 104
98 }else { 105 }else {
src/main/resources/static/pages/base/timesmodel/js/strategy/BcObj.js deleted 100644 → 0
1 -/**  
2 - * 班次类型对象(最后转换成显示用bc对象)  
3 - * @param bcType  
4 - * @param isUp  
5 - * @param lp  
6 - * @param fcno  
7 - * @param fcTimeObj  
8 - * @param paramObj  
9 - * @returns {{}}  
10 - * @constructor  
11 - */  
12 -var BcObj = function(bcType, isUp, lp, fcno, fcTimeObj, paramObj) {  
13 -  
14 - //---------- 内部属性 ----------//  
15 - var _bcType = bcType; // 班次类型(normal,in,out等)  
16 - var _isUp = isUp; // true表示上行,false表示下行  
17 - var _lp = lp; // 路牌  
18 - var _fcno = fcno; // 发车顺序号  
19 -  
20 - // 计算的属性,TODO:还有其他属性  
21 - // 上标线里属于第几圈(本班次方向和标线方向一致,才有意义)  
22 - var qCount;  
23 -  
24 - // 班次里程  
25 - var _bclc = StrategyUtils.calcuTravelLcNumber(_isUp, _bcType, paramObj);  
26 - // 发车时间  
27 - var _fcsjObj = moment(fcTimeObj);  
28 - // 班次时间  
29 - var _bcsj = StrategyUtils.calcuTravelTime(_fcsjObj, _isUp, paramObj);  
30 - // 到达时间  
31 - var _arrsj = StrategyUtils.addMinute(_fcsjObj, _bcsj);  
32 - // 到达后的停站时间(使用到达时间判定)  
33 - var _stopTime = StrategyUtils.calcuFixedStopNumber(_arrsj, !_isUp, paramObj);  
34 -  
35 - return {  
36 - /**  
37 - * 是否上行。  
38 - * @returns boolean  
39 - */  
40 - isUp: function() {  
41 - return _isUp;  
42 - },  
43 - /**  
44 - * 获取发车时间。  
45 - * @returns {*|moment.Moment}  
46 - */  
47 - getFcTimeObj: function() {  
48 - return _fcsjObj;  
49 - },  
50 - /**  
51 - * 获取班次时间。  
52 - */  
53 - getBcTime: function() {  
54 - return _bcsj;  
55 - },  
56 - /**  
57 - * 获取停站时间。  
58 - * @returns {*}  
59 - */  
60 - getStopTime: function() {  
61 - return _stopTime;  
62 - },  
63 -  
64 - /**  
65 - * 转换成显示用班次对象。  
66 - */  
67 - toGanttBcObj: function() {  
68 - var _bcObj = {  
69 - parent: _lp,  
70 - lpNo: _lp,  
71 - lp: null,  
72 - lpName: _lp,  
73 - lpType: '普通路牌',  
74 - bcType: _bcType,  
75 - fcno: _fcno,  
76 - isfb: 0,  
77 - isSwitchXl: null,  
78 - bz: null  
79 - };  
80 -  
81 - // 线路上下行  
82 - _bcObj.xlDir = _isUp ? "relationshipGraph-up" : "relationshipGraph-down";  
83 -  
84 - // 里程  
85 - _bcObj.jhlc = _bclc;  
86 -  
87 - // 停车场  
88 - _bcObj.tcc = paramObj.getTccId();  
89 -  
90 - // 时刻表  
91 - _bcObj.ttinfo = paramObj.getTTinfoId();  
92 -  
93 - // 线路  
94 - _bcObj.xl = paramObj.getXlId();  
95 -  
96 - // 起点站、终点站  
97 - _bcObj.qdz = _isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;  
98 - _bcObj.zdz = _isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;  
99 -  
100 - // 发车时间,行驶时间,到达时间,停站时间  
101 - _bcObj.fcsj = _fcsjObj.format("HH:mm");  
102 - _bcObj.bcsj = _bcsj;  
103 - _bcObj.ARRIVALTIME = _arrsj.format("HH:mm");  
104 - _bcObj.STOPTIME = _stopTime;  
105 -  
106 - return _bcObj;  
107 - }  
108 - };  
109 -};  
110 \ No newline at end of file 0 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/strategy/BcObjMatrix.js deleted 100644 → 0
1 -/**  
2 - * 班次对象矩阵(二维数组)。  
3 - * @param paramObj 参数对象  
4 - * @constructor  
5 - */  
6 -var BcObjMatrix = function(paramObj) {  
7 - // 内部参数  
8 - var _paramObj = paramObj;  
9 -  
10 - var lpObj = function() { // 路牌对象  
11 - return {  
12 - bxType: 6, // 班型描述,默认做5休2  
13 - qArray: [] // 圈对象数组,一圈二个班次  
14 - };  
15 - }  
16 -};  
17 \ No newline at end of file 0 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/strategy/ParameterObj.js deleted 100644 → 0
1 -/**  
2 - * 包装表单参数为内部参数对象。  
3 - * @param formMap 表单form参数map  
4 - * @param dataMap  
5 - * @constructor  
6 - *  
7 - * 注意:moment是mutable,所有的moment操作都会改变原有对象的值,  
8 - * 所以所有的操作都要小心处理。  
9 - */  
10 -var ParameterObj = function(formMap, dataMap) {  
11 - // 内部保存的form参数  
12 - var _formMap = formMap;  
13 - // 计算行驶时间对象  
14 - var _travelTimeObj_fun = function() {  
15 - var upMoningPeakTravelTime =  
16 - isNaN(_formMap.earlyUpTime) ?  
17 - parseInt(_formMap.upTravelTime) :  
18 - parseInt(_formMap.earlyUpTime);  
19 - var downMoningPeakTravelTime =  
20 - isNaN(_formMap.earlyDownTime) ?  
21 - parseInt(_formMap.downTravelTime) :  
22 - parseInt(_formMap.earlyDownTime);  
23 - var upEveningPeakTravelTime =  
24 - isNaN(_formMap.lateUpTime) ?  
25 - parseInt(_formMap.upTravelTime) :  
26 - parseInt(_formMap.lateUpTime);  
27 - var downEveningPeakTravelTime =  
28 - isNaN(_formMap.lateDownTime) ?  
29 - parseInt(_formMap.downTravelTime) :  
30 - parseInt(_formMap.lateDownTime);  
31 - var upTroughTravelTime =  
32 - isNaN(_formMap.troughUpTime) ?  
33 - parseInt(_formMap.upTravelTime) :  
34 - parseInt(_formMap.troughUpTime);  
35 - var downTroughTravelTime =  
36 - isNaN(_formMap.troughDownTime) ?  
37 - parseInt(_formMap.downTravelTime) :  
38 - parseInt(_formMap.troughDownTime);  
39 -  
40 - return { // TODO:暂时获取标准信息,之后改成历史数据,可能需要使用promise封装  
41 - "moningpeak": [  
42 - upMoningPeakTravelTime,  
43 - downMoningPeakTravelTime  
44 - ],  
45 - "eveningpeak": [  
46 - upEveningPeakTravelTime,  
47 - downEveningPeakTravelTime  
48 - ],  
49 - "trough": [  
50 - upTroughTravelTime,  
51 - downTroughTravelTime  
52 - ]  
53 - }  
54 - };  
55 - var _travelTimeObj = _travelTimeObj_fun();  
56 -  
57 - // 计算行驶里程对象  
58 - var _travelLcObj_fun = function() {  
59 - return [  
60 - { // 上行里程  
61 - "normalLc": isNaN(_formMap.upMileage) ? 0 : parseFloat(_formMap.upMileage),  
62 - "inLc": isNaN(_formMap.upInMileage) ? 0 : parseFloat(_formMap.upInMileage),  
63 - "outLc": isNaN(_formMap.upOutMileage) ? 0 : parseFloat(_formMap.upOutMileage)  
64 - },  
65 - { // 下行里程  
66 - "normalLc": isNaN(_formMap.downMileage) ? 0 : parseFloat(_formMap.downMileage),  
67 - "inLc": isNaN(_formMap.downInMileage) ? 0 : parseFloat(_formMap.downInMileage),  
68 - "outLc": isNaN(_formMap.downOutMileage) ? 0 : parseFloat(_formMap.downOutMileage)  
69 - }  
70 - ];  
71 - };  
72 - var _travelLcObj = _travelLcObj_fun();  
73 -  
74 - // 计算首班车,末班车行驶时间字符串  
75 - var _firstLastDepartureTimeStrObj_fun = function() {  
76 - return {  
77 - up: { // 上行  
78 - firstVehicleDepartureTimeStr: _formMap.startStationFirstTime,  
79 - lastVehicleDepartureTimeStr: _formMap.startStationEndTime  
80 - },  
81 - down: { // 下行  
82 - firstVehicleDepartureTimeStr: _formMap.endStationFirstTime,  
83 - lastVehicleDepartureTimeStr: _formMap.endStationEndTime  
84 - }  
85 - };  
86 - };  
87 - var _firstLastDepartureTimeStrObj = _firstLastDepartureTimeStrObj_fun();  
88 -  
89 - // 计算时间段划分对象  
90 - var _timeIntervalObj_fun = function() {  
91 - return {  
92 - moningPeakTimeStrs: {  
93 - start: _formMap.earlyStartTime,  
94 - end: _formMap.earlyEndTime  
95 - },  
96 - eveningPeakTimeStrs: {  
97 - start: _formMap.lateStartTime,  
98 - end: _formMap.lateEndTime  
99 - }  
100 -  
101 - // TODO:其他时间段以后再加  
102 - };  
103 - };  
104 - var _timeIntervalObj = _timeIntervalObj_fun();  
105 -  
106 - // 计算各个时段的发车间隙  
107 - var _fcjxIntervalObj_fun = function() {  
108 - var _rtn = {  
109 - mpeakfcjx : {}, // 早高峰  
110 - epeakfcjx : {}, // 晚高峰  
111 - troughfcjx: {} //低谷  
112 - };  
113 - var _fcjx = [];  
114 - var i = 0;  
115 -  
116 - // TODO:这里只有3个间隔,以后加其他的  
117 - // 1、早高峰间隙  
118 - // 2、晚高峰间隙  
119 - // 3、低谷  
120 -  
121 - _rtn.mpeakfcjx.min = parseInt(_formMap.zgffcjxmin);  
122 - _rtn.mpeakfcjx.max = parseInt(_formMap.zgffcjxmax);  
123 -  
124 - _rtn.epeakfcjx.min = parseInt(_formMap.wffcjxmin);  
125 - _rtn.epeakfcjx.max = parseInt(_formMap.wffcjxmax);  
126 -  
127 - _rtn.troughfcjx.min = parseInt(_formMap.dgfcjxmin);  
128 - _rtn.troughfcjx.max = parseInt(_formMap.dgfcjxmax);  
129 -  
130 - // 做一些逻辑检查  
131 - if (_rtn.mpeakfcjx.min > _rtn.mpeakfcjx.max) {  
132 - alert("早高峰最小间隔大于最大间隔");  
133 - throw "早高峰最小间隔大于最大间隔";  
134 - }  
135 - if (_rtn.epeakfcjx.min > _rtn.epeakfcjx.max) {  
136 - alert("晚高峰最小间隔大于最大间隔");  
137 - throw "晚高峰最小间隔大于最大间隔";  
138 - }  
139 - if (_rtn.troughfcjx.min > _rtn.troughfcjx.max) {  
140 - alert("低谷最小间隔大于最大间隔");  
141 - throw "低谷最小间隔大于最大间隔";  
142 - }  
143 -  
144 -  
145 - return _rtn;  
146 - };  
147 - var _fcjxIntervalObj = _fcjxIntervalObj_fun();  
148 -  
149 - // 获取停站类型  
150 - var _stopTypeObj_fun = function() {  
151 - var isMasterStop = false; // 是否主站停  
152 - var isMasterUpStop = false; // 主站停是否上行站点  
153 - if (_formMap) {  
154 - var fm_temp = _formMap.stt.split("/");  
155 - if (fm_temp.length == 1) { // 双向停站  
156 - isMasterStop = false;  
157 - } else {  
158 - isMasterStop = true;  
159 - if (fm_temp[1] == "0") {  
160 - isMasterUpStop = true;  
161 - } else {  
162 - isMasterUpStop = false;  
163 - }  
164 - }  
165 - } else {  
166 - throw "停站类型没有选择!";  
167 - }  
168 -  
169 - return {  
170 - isMasterStop: isMasterStop,  
171 - isMasterUpStop: isMasterUpStop  
172 - }  
173 - };  
174 - var _stopTypeObj = _stopTypeObj_fun();  
175 -  
176 - // 计算线路对象  
177 - var _xlObj_fun = function() {  
178 - return { // TODO:其他属性再议  
179 - xl: {  
180 - id: _formMap.lineName.split('_')[0]  
181 - }  
182 - };  
183 - };  
184 - var _xlObj = _xlObj_fun();  
185 -  
186 - // 计算停车场对象  
187 - var _parkObj_fun = function() {  
188 - return { // TODO:其他属性再议  
189 - park: {  
190 - id: _formMap.tcc_id  
191 - }  
192 - };  
193 - };  
194 - var _parkObj = _parkObj_fun();  
195 -  
196 - // 计算时刻表对象  
197 - var _ttInfoObj_fun = function() {  
198 - return { // TODO:其他属性再议  
199 - ttinfo: {  
200 - id: _formMap.skbName  
201 - }  
202 - };  
203 - };  
204 - var _ttInfoObj = _ttInfoObj_fun();  
205 -  
206 - // 计算起点站终点站对象  
207 - var _startEndStopObj_fun = function() {  
208 - return { // TODO:其他属性再议  
209 - up: {  
210 - qdz: { // 起点站  
211 - id: dataMap.qdzArr[0]  
212 - },  
213 - zdz: { // 终点站  
214 - id: dataMap.zdzArr[0]  
215 - }  
216 - },  
217 - down: {  
218 - qdz: { // 起点站  
219 - id: dataMap.qdzArr[1]  
220 - },  
221 - zdz: { // 终点站  
222 - id: dataMap.zdzArr[1]  
223 - }  
224 - }  
225 -  
226 - };  
227 - };  
228 - var _startEndStopObj = _startEndStopObj_fun();  
229 -  
230 - return {  
231 - /**  
232 - * 重置内部form参数。  
233 - * @param formMap  
234 - */  
235 - reset: function(formMap) {  
236 - _formMap = formMap;  
237 -  
238 - // 首班车,末班车行驶时间字符串  
239 - _firstLastDepartureTimeStrObj = _firstLastDepartureTimeStrObj_fun();  
240 - // 行驶时间对象  
241 - _travelTimeObj = _travelTimeObj_fun();  
242 - // 行驶里程对象  
243 - _travelLcObj = _travelLcObj_fun();  
244 - // 时间段划分对象  
245 - _timeIntervalObj = _timeIntervalObj_fun();  
246 - // 各个时段的发车间隙  
247 - _fcjxIntervalObj = _fcjxIntervalObj_fun();  
248 - // 停站类型  
249 - _stopTypeObj = _stopTypeObj_fun();  
250 - // 线路对象  
251 - _xlObj = _xlObj_fun();  
252 - // 停车场对象  
253 - _parkObj = _parkObj_fun();  
254 - // 时刻表对象  
255 - _ttInfoObj = _ttInfoObj_fun();  
256 - // 起点站终点站对象  
257 - _startEndStopObj = _startEndStopObj_fun();  
258 -  
259 - // TODO:其他再议  
260 - },  
261 -  
262 - //------------ 获取首班末班时间 ------------//  
263 - /**  
264 - * 获取上行首班时间对象。  
265 - * @return moment obj  
266 - */  
267 - getUpFirstDTimeObj: function() {  
268 - return StrategyUtils.toTimeObj(  
269 - _firstLastDepartureTimeStrObj.up.firstVehicleDepartureTimeStr  
270 - );  
271 - },  
272 - /**  
273 - * 获取上行末班时间对象。  
274 - * @return moment obj  
275 - */  
276 - getUpLastDtimeObj: function() {  
277 - return StrategyUtils.toTimeObj(  
278 - _firstLastDepartureTimeStrObj.up.lastVehicleDepartureTimeStr  
279 - );  
280 - },  
281 - /**  
282 - * 获取下行首班时间对象。  
283 - * @return moment obj  
284 - */  
285 - getDownFirstDTimeObj: function() {  
286 - return StrategyUtils.toTimeObj(  
287 - _firstLastDepartureTimeStrObj.down.firstVehicleDepartureTimeStr  
288 - );  
289 - },  
290 - /**  
291 - * 获取下行末班时间对象。  
292 - * @return moment obj  
293 - */  
294 - getDownLastDTimeObj: function() {  
295 - return StrategyUtils.toTimeObj(  
296 - _firstLastDepartureTimeStrObj.down.lastVehicleDepartureTimeStr  
297 - );  
298 - },  
299 -  
300 - //-------------- 获取行驶时间 ----------------//  
301 - /**  
302 - * 获取上行早高峰行驶时间。  
303 - * @returns int number  
304 - */  
305 - getUpMPeakTime: function() {  
306 - return _travelTimeObj.moningpeak[0];  
307 - },  
308 - /**  
309 - * 获取上行晚高峰行驶时间。  
310 - * @returns int number  
311 - */  
312 - getUpEPeakTime: function() {  
313 - return _travelTimeObj.eveningpeak[0];  
314 - },  
315 - /**  
316 - * 获取上行低谷行驶时间。  
317 - * @returns int number  
318 - */  
319 - getUpTroughTime: function() {  
320 - return _travelTimeObj.trough[0];  
321 - },  
322 - /**  
323 - * 获取下行早高峰行驶时间。  
324 - * @returns int number  
325 - */  
326 - getDownMPeakTime: function() {  
327 - return _travelTimeObj.moningpeak[1];  
328 - },  
329 - /**  
330 - * 获取下行晚高峰行驶时间。  
331 - * @returns int number  
332 - */  
333 - getDownEPeakTime: function() {  
334 - return _travelTimeObj.eveningpeak[1];  
335 - },  
336 - /**  
337 - * 获取下行低谷行驶时间。  
338 - * @returns int number  
339 - */  
340 - getDownTroughTime: function() {  
341 - return _travelTimeObj.trough[1];  
342 - },  
343 -  
344 - //---------------- 获取行驶里程 -----------------//  
345 - /**  
346 - * 获取上行normal班次里程。  
347 - * @returns number  
348 - */  
349 - getUpNormalLc: function() {  
350 - return _travelLcObj[0].normalLc;  
351 - },  
352 - /**  
353 - * 获取上行进场班次类型。  
354 - * @returns number  
355 - */  
356 - getUpInLc: function() {  
357 - return _travelLcObj[0].inLc;  
358 - },  
359 - /**  
360 - * 获取上行出场班次类型。  
361 - * @returns number  
362 - */  
363 - getUpOutLc: function() {  
364 - return _travelLcObj[0].outLc;  
365 - },  
366 - /**  
367 - * 获取下行normal班次类型。  
368 - * @returns number  
369 - */  
370 - getDownNormalLc: function() {  
371 - return _travelLcObj[1].normalLc;  
372 - },  
373 - /**  
374 - * 获取下行进场班次类型。  
375 - * @returns number  
376 - */  
377 - getDownInLc: function() {  
378 - return _travelLcObj[1].inLc;  
379 - },  
380 - /**  
381 - * 获取下行出场班次类型。  
382 - * @returns number  
383 - */  
384 - getDownOutLc: function() {  
385 - return _travelLcObj[1].outLc;  
386 - },  
387 -  
388 - //---------------- 获取时间段信息 --------------//  
389 - /**  
390 - * 获取早高峰开始时间对象。  
391 - * @returns moment obj  
392 - */  
393 - getMPeakStartTimeObj: function() {  
394 - return StrategyUtils.toTimeObj(  
395 - _timeIntervalObj.moningPeakTimeStrs.start  
396 - );  
397 - },  
398 - /**  
399 - * 获取早高峰结束时间对象。  
400 - * @returns moment obj  
401 - */  
402 - getMPeakEndTimeObj: function() {  
403 - return StrategyUtils.toTimeObj(  
404 - _timeIntervalObj.moningPeakTimeStrs.end  
405 - );  
406 - },  
407 - /**  
408 - * 获取晚高峰开始时间对象。  
409 - * @returns moment obj  
410 - */  
411 - getEPeakStartTimeObj: function() {  
412 - return StrategyUtils.toTimeObj(  
413 - _timeIntervalObj.eveningPeakTimeStrs.start  
414 - );  
415 - },  
416 - /**  
417 - * 获取晚高峰结束时间对象。  
418 - * @returns moment obj  
419 - */  
420 - getEPeakEndTimeObj: function() {  
421 - return StrategyUtils.toTimeObj(  
422 - _timeIntervalObj.eveningPeakTimeStrs.end  
423 - );  
424 - },  
425 -  
426 - //----------------- 获取发车间隙(TODO:以后通过客流估算)-----------------//  
427 - /**  
428 - * 获取早高峰最小发车间隙。  
429 - * @returns int  
430 - */  
431 - getMPeakMinFcjx: function() {  
432 - return _fcjxIntervalObj.mpeakfcjx.min;  
433 - },  
434 - /**  
435 - * 获取早高峰最大发车间隙。  
436 - * @returns int  
437 - */  
438 - getMPeakMaxFcjx: function() {  
439 - return _fcjxIntervalObj.mpeakfcjx.max;  
440 - },  
441 - /**  
442 - * 获取晚高峰最小发车间隙。  
443 - * @returns int  
444 - */  
445 - getEPeakMinFcjx: function() {  
446 - return _fcjxIntervalObj.epeakfcjx.min;  
447 - },  
448 - /**  
449 - * 获取晚高峰最小发车间隙。  
450 - * @returns int  
451 - */  
452 - getEPeakMaxFcjx: function() {  
453 - return _fcjxIntervalObj.epeakfcjx.max;  
454 - },  
455 - /**  
456 - * 获取低谷最小发车间隙。  
457 - * @returns int  
458 - */  
459 - getTroughMinFcjx: function() {  
460 - return _fcjxIntervalObj.troughfcjx.min;  
461 - },  
462 - /**  
463 - * 获取低谷最大发车间隙。  
464 - * @returns int  
465 - */  
466 - getTroughMaxFcjx: function() {  
467 - return _fcjxIntervalObj.troughfcjx.max;  
468 - },  
469 -  
470 - //----------------- 获取停站方式 -------------------//  
471 - /**  
472 - * 是否双向停站。  
473 - * @returns {boolean}  
474 - */  
475 - isTwoWayStop: function() {  
476 - return !_stopTypeObj.isMasterStop;  
477 - },  
478 - /**  
479 - * 是否上行单向停站。  
480 - * @returns {boolean}  
481 - */  
482 - isUpOneWayStop: function() {  
483 - return _stopTypeObj.isMasterStop && _stopTypeObj.isMasterUpStop;  
484 - },  
485 - /**  
486 - * 是否下行单向停站。  
487 - * @returns {boolean}  
488 - */  
489 - isDownOneWayStop: function() {  
490 - return _stopTypeObj.isMasterStop && (!_stopTypeObj.isMasterUpStop);  
491 - },  
492 -  
493 - //----------------- 获取高峰配车数、加班路牌数 ----------------//  
494 - /**  
495 - * 获取高峰建议配车数(TODO:参照一下)。  
496 - * @returns {Number|*}  
497 - */  
498 - getAdvicePeakClzs: function() {  
499 - return parseInt(_formMap.gfjypcs);  
500 - },  
501 - /**  
502 - * 获取加班路牌数(5休2路牌的个数)。  
503 - * @returns {Number|*}  
504 - */  
505 - getJBLpes: function() {  
506 - return parseInt(_formMap.jbclcount);  
507 - },  
508 -  
509 - //----------------- 获取关联数据信息 -----------------//  
510 - /**  
511 - * 获取线路id。  
512 - */  
513 - getXlId: function() {  
514 - return _xlObj.xl.id;  
515 - },  
516 - /**  
517 - * 获取停车场id。  
518 - */  
519 - getTccId: function() {  
520 - return _parkObj.park.id;  
521 - },  
522 - /**  
523 - * 获取时刻表id。  
524 - */  
525 - getTTinfoId: function() {  
526 - return _ttInfoObj.ttinfo.id;  
527 - },  
528 - /**  
529 - * 获取上行起点站对象。  
530 - * @returns {{id: *}}  
531 - */  
532 - getUpQdzObj: function() {  
533 - return {  
534 - id: _startEndStopObj.up.qdz.id  
535 - };  
536 - },  
537 - /**  
538 - * 获取上行终点站对象。  
539 - * @returns {{id: *}}  
540 - */  
541 - getUpZdzObj: function() {  
542 - return {  
543 - id: _startEndStopObj.up.zdz.id  
544 - };  
545 - },  
546 - /**  
547 - * 获取下行起点站对象。  
548 - * @returns {{id: *}}  
549 - */  
550 - getDownQdzObj: function() {  
551 - return {  
552 - id: _startEndStopObj.down.qdz.id  
553 - };  
554 - },  
555 - /**  
556 - * 获取下行终点站对象。  
557 - * @returns {{id: *}}  
558 - */  
559 - getDownZdzObj: function() {  
560 - return {  
561 - id: _startEndStopObj.down.zdz.id  
562 - };  
563 - }  
564 -  
565 -  
566 - };  
567 -};  
568 \ No newline at end of file 0 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/strategy/RelatedObjes.js deleted 100644 → 0
1 -// 相关的内部对象  
2 -/**  
3 - * 班次类型对象(最后转换成显示用bc对象)  
4 - * @param bcType 班次类型(normal,in,out等)  
5 - * @param isUp boolean 是否上行  
6 - * @param lp 路牌编号  
7 - * @param fcno 发车编号  
8 - * @param fcTimeObj 发车时间对象  
9 - * @param paramObj 参数对象  
10 - * @returns 班次对象  
11 - */  
12 -var BcObj = function(bcType, isUp, lp, fcno, fcTimeObj, paramObj) {  
13 -  
14 - //---------- 内部属性 ----------//  
15 - var _bcType = bcType; // 班次类型(normal,in,out等)  
16 - var _isUp = isUp; // true表示上行,false表示下行  
17 - var _lp = lp; // 路牌  
18 - var _fcno = fcno; // 发车顺序号  
19 -  
20 - // 计算的属性,TODO:还有其他属性  
21 - // 上标线里属于第几圈(本班次方向和标线方向一致,才有意义)  
22 - var qCount;  
23 -  
24 - // 班次里程  
25 - var _bclc = StrategyUtils.calcuTravelLcNumber(_isUp, _bcType, paramObj);  
26 - // 发车时间  
27 - var _fcsjObj = moment(fcTimeObj);  
28 - // 班次时间  
29 - var _bcsj = StrategyUtils.calcuTravelTime(_fcsjObj, _isUp, paramObj);  
30 - // 到达时间  
31 - var _arrsj = StrategyUtils.addMinute(_fcsjObj, _bcsj);  
32 - // 到达后的停站时间(使用到达时间判定)  
33 - var _stopTime = StrategyUtils.calcuFixedStopNumber(_arrsj, !_isUp, paramObj);  
34 -  
35 - return {  
36 - /**  
37 - * 是否上行。  
38 - * @returns boolean  
39 - */  
40 - isUp: function() {  
41 - return _isUp;  
42 - },  
43 - /**  
44 - * 获取发车时间。  
45 - * @returns {*|moment.Moment}  
46 - */  
47 - getFcTimeObj: function() {  
48 - return _fcsjObj;  
49 - },  
50 - /**  
51 - * 获取班次时间。  
52 - */  
53 - getBcTime: function() {  
54 - return _bcsj;  
55 - },  
56 - /**  
57 - * 获取停站时间。  
58 - * @returns {*}  
59 - */  
60 - getStopTime: function() {  
61 - return _stopTime;  
62 - },  
63 -  
64 - /**  
65 - * 转换成显示用班次对象。  
66 - */  
67 - toGanttBcObj: function() {  
68 - var _bcObj = {  
69 - parent: _lp,  
70 - lpNo: _lp,  
71 - lp: null,  
72 - lpName: _lp,  
73 - lpType: '普通路牌',  
74 - bcType: _bcType,  
75 - fcno: _fcno,  
76 - isfb: 0,  
77 - isSwitchXl: null,  
78 - bz: null  
79 - };  
80 -  
81 - // 线路上下行  
82 - _bcObj.xlDir = _isUp ? "relationshipGraph-up" : "relationshipGraph-down";  
83 -  
84 - // 里程  
85 - _bcObj.jhlc = _bclc;  
86 -  
87 - // 停车场  
88 - _bcObj.tcc = paramObj.getTccId();  
89 -  
90 - // 时刻表  
91 - _bcObj.ttinfo = paramObj.getTTinfoId();  
92 -  
93 - // 线路  
94 - _bcObj.xl = paramObj.getXlId();  
95 -  
96 - // 起点站、终点站  
97 - _bcObj.qdz = _isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;  
98 - _bcObj.zdz = _isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;  
99 -  
100 - // 发车时间,行驶时间,到达时间,停站时间  
101 - _bcObj.fcsj = _fcsjObj.format("HH:mm");  
102 - _bcObj.bcsj = _bcsj;  
103 - _bcObj.ARRIVALTIME = _arrsj.format("HH:mm");  
104 - _bcObj.STOPTIME = _stopTime;  
105 -  
106 - return _bcObj;  
107 - }  
108 - };  
109 -};  
110 \ No newline at end of file 0 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/strategy/StrategyUtils.js deleted 100644 → 0
1 -/**  
2 - * 工具类。  
3 - * 注意:moment是mutable,所有的moment操作都会改变原有对象的值,  
4 - * 所以所有的操作都要小心处理。  
5 - */  
6 -var StrategyUtils = function() {  
7 - var date_wrap_prefix = "2000-01-01 "; // 包装日期的前缀  
8 - var date_wrap_format = "YYYY-MM-DD HH:mm"; // 日期格式  
9 - /**  
10 - * 将时间包装成日期,方便计算。  
11 - * @param timeStr 时间格式,如 06:30  
12 - * @returns moment对象  
13 - */  
14 - var _wrapTimeFun = function(timeStr) {  
15 - return moment(  
16 - date_wrap_prefix + timeStr,  
17 - date_wrap_format  
18 - );  
19 - };  
20 - /**  
21 - * 添加时间(注意,返回一个新的moment对象,此方法是immutable)  
22 - * @param timeObj moment 对象  
23 - * @param time 时间  
24 - * @param type 时间单位  
25 - * @returns 重新创建一个moment返回  
26 - */  
27 - var _addTimeFun = function(timeObj, time, type) {  
28 - var _timeObj = moment(timeObj); // clone  
29 - _timeObj.add(time, type);  
30 - return _timeObj;  
31 - };  
32 -  
33 - // 内部工厂类  
34 - var _factoryFun = function() {  
35 - return {  
36 - // 创建参数  
37 - createParameterObj: function(formMap, dataMap) {  
38 - return ParameterObj(formMap, dataMap);  
39 - },  
40 - // 创建班次对象  
41 - createBcObj: function(bcType, isUp, lp, fcno, fcTimeObj, paramObj) {  
42 - var _bclc = StrategyUtils.calcuTravelLcNumber(isUp, bcType, paramObj);  
43 - var _bcsj = StrategyUtils.calcuTravelTime(fcTimeObj, isUp, paramObj);  
44 - var _arrsj = StrategyUtils.addMinute(fcTimeObj, _bcsj);  
45 - var _stoptime = StrategyUtils.calcuFixedStopNumber(_arrsj, !isUp, paramObj);  
46 - var _tccid = paramObj.getTTinfoId();  
47 - var _ttinfoid = paramObj.getTTinfoId();  
48 - var _xl = paramObj.getXlId();  
49 - var _qdz = isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;  
50 - var _zdz = isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;  
51 -  
52 - return new InternalBcObj(  
53 - bcType, // 班次类型(normal,in,out等)  
54 - isUp, // boolean是否上下行  
55 - lp, // 路牌标识符  
56 - fcno, // 发车顺序号  
57 - fcTimeObj, // 发车时间对象  
58 - _bclc, // 班次里程  
59 - _bcsj, // 班次历时  
60 - _arrsj, // 到达时间对象  
61 - _stoptime, // 停站时间  
62 - _tccid, // 停车场id  
63 - _ttinfoid, // 时刻表id  
64 - _xl, // 线路id  
65 - _qdz, // 起点站id  
66 - _zdz // 终点站id  
67 - );  
68 - }  
69 - };  
70 - };  
71 -  
72 - return {  
73 - /**  
74 - * 工厂对象,创建不同的对象。  
75 - * @returns {{createParameterObj, createBcObj}}  
76 - */  
77 - getFactory: function() {  
78 - return _factoryFun();  
79 - },  
80 -  
81 - //-------------- 时间操作 ------------//  
82 - /**  
83 - * 通过字符串创建时间对象。  
84 - * @param timeStr 时间字符串  
85 - * @returns {moment对象}  
86 - */  
87 - toTimeObj: function(timeStr) {  
88 - return _wrapTimeFun(timeStr);  
89 - },  
90 - /**  
91 - * 增加分钟。  
92 - * @param timeObj 时间对象  
93 - * @param minute 分钟  
94 - * @returns {重新创建一个moment返回}  
95 - */  
96 - addMinute: function(timeObj, minute) {  
97 - return _addTimeFun(timeObj, minute, "m");  
98 - },  
99 -  
100 - //-------------- 时间业务操作 ------------//  
101 - /**  
102 - * 判定某个班次是否是早高峰班次。  
103 - * @param timeObj 班次时间  
104 - * @param paramObj 参数对象  
105 - * @returns true false  
106 - */  
107 - isMPeakBc: function(timeObj, paramObj) {  
108 - // 早高峰开始时间  
109 - var st = paramObj.getMPeakStartTimeObj();  
110 - // 早高峰结束时间  
111 - var et = paramObj.getMPeakEndTimeObj();  
112 - // 包装日期  
113 - return timeObj.isBetween(st, et, null, "[]");  
114 - },  
115 - /**  
116 - * 判定某个班次是否是晚高峰班次。  
117 - * @param timeObj 班次时间  
118 - * @param paramObj 参数对象  
119 - * @returns true false  
120 - */  
121 - isEPeakBc: function(timeObj, paramObj) {  
122 - // 晚高峰开始时间  
123 - var st = paramObj.getEPeakStartTimeObj();  
124 - // 晚高峰结束时间  
125 - var et = paramObj.getEPeakEndTimeObj();  
126 - // 包装日期  
127 - return timeObj.isBetween(st, et, null, "[]");  
128 - },  
129 - /**  
130 - * 判定某个班次是否是低谷班次。  
131 - * @param timeObj 班次时间  
132 - * @param paramObj 参数对象  
133 - * @returns true false  
134 - */  
135 - isTroughBc: function(timeObj, paramObj) {  
136 - return (  
137 - !this.isMPeakBc(timeObj, paramObj) &&  
138 - !this.isEPeakBc(timeObj, paramObj)  
139 - );  
140 - },  
141 - /**  
142 - * 判定某个低谷班次是否在早高峰开始之前。  
143 - * @param timeObj 班次时间  
144 - * @param paramObj 参数对象  
145 - * @returns true false  
146 - */  
147 - isTroughBeforMPeakStartBc: function(timeObj, paramObj) {  
148 - // 早高峰开始时间  
149 - var st = paramObj.getMPeakStartTimeObj();  
150 - // 包装日期  
151 - return timeObj.isBefore(st);  
152 - },  
153 - /**  
154 - * 判定某个低谷班次是否在晚高峰结束之后。  
155 - * @param timeObj 班次时间  
156 - * @param paramObj 参数对象  
157 - * @returns true false  
158 - */  
159 - isTroughAfterEPeakEndBc: function(timeObj, paramObj) {  
160 - // 晚高峰结束时间  
161 - var et = paramObj.getEPeakEndTimeObj();  
162 - // 包装日期  
163 - return timeObj.isAfter(et);  
164 - },  
165 -  
166 - /**  
167 - * 获取固定的停站时间(固定停站时间都是选的最大值)  
168 - * @param timeObj 时间对象  
169 - * @param isUp 是否上行  
170 - * @param paramObj 参数对象  
171 - * @returns number  
172 - */  
173 - calcuFixedStopNumber: function(timeObj, isUp, paramObj) {  
174 - var peakStopTime; // 高峰停站时间  
175 - var troughStopTime; // 低谷停站时间  
176 - var secondaryStopTime; // 副站停站时间  
177 -  
178 - // 双向停站  
179 - if (paramObj.isTwoWayStop()) {  
180 - if (isUp) { // 上行  
181 - if (this.isMPeakBc(timeObj, paramObj)) { // 早高峰  
182 - peakStopTime = Math.floor(paramObj.getUpMPeakTime() * 0.1); // 行驶时间的10%  
183 - if (peakStopTime < 3) { // 不少于3分钟  
184 - peakStopTime = 3;  
185 - }  
186 - return peakStopTime;  
187 - } else if (this.isEPeakBc(timeObj, paramObj)) { // 晚高峰  
188 - peakStopTime = Math.floor(paramObj.getUpEPeakTime() * 0.1); // 行驶时间的10%  
189 - if (peakStopTime < 3) { // 不少于3分钟  
190 - peakStopTime = 3;  
191 - }  
192 - return peakStopTime;  
193 - } else { // 低谷  
194 - if (this.isTroughBeforMPeakStartBc(timeObj, paramObj)) { // 早高峰开始前  
195 - troughStopTime = Math.floor(paramObj.getUpTroughTime() * 0.2); // 行驶时间20%  
196 - if (troughStopTime < 10) { // 不少于10分钟  
197 - troughStopTime = 10;  
198 - }  
199 - return troughStopTime;  
200 - } else if (this.isTroughAfterEPeakEndBc(timeObj, paramObj)) { // 晚高峰结束后  
201 - troughStopTime = Math.floor(paramObj.getUpTroughTime() * 0.2); // 行驶时间20%  
202 - if (troughStopTime < 10) { // 不少于10分钟  
203 - troughStopTime = 10;  
204 - }  
205 - return troughStopTime;  
206 - } else { // 早高峰,晚高峰之间  
207 - troughStopTime = Math.floor(paramObj.getUpTroughTime() * 0.15); // 行驶时间15%  
208 - if (troughStopTime < 10) { // 不少于10分钟  
209 - troughStopTime = 10;  
210 - }  
211 - return troughStopTime;  
212 - }  
213 - }  
214 - } else { // 下行  
215 - if (this.isMPeakBc(timeObj, paramObj)) { // 早高峰  
216 - peakStopTime = Math.floor(paramObj.getDownMPeakTime() * 0.1); // 行驶时间的10%  
217 - if (peakStopTime < 3) { // 不少于3分钟  
218 - peakStopTime = 3;  
219 - }  
220 - return peakStopTime;  
221 - } else if (this.isEPeakBc(timeObj, paramObj)) { // 晚高峰  
222 - peakStopTime = Math.floor(paramObj.getDownEPeakTime() * 0.1); // 行驶时间的10%  
223 - if (peakStopTime < 3) { // 不少于3分钟  
224 - peakStopTime = 3;  
225 - }  
226 - return peakStopTime;  
227 - } else { // 低谷  
228 - if (this.isTroughBeforMPeakStartBc(timeObj, paramObj)) { // 早高峰开始前  
229 - troughStopTime = Math.floor(paramObj.getDownTroughTime() * 0.2); // 行驶时间20%  
230 - if (troughStopTime < 10) { // 不少于10分钟  
231 - troughStopTime = 10;  
232 - }  
233 - return troughStopTime;  
234 - } else if (this.isTroughAfterEPeakEndBc(timeObj, paramObj)) { // 晚高峰结束后  
235 - troughStopTime = Math.floor(paramObj.getDownTroughTime() * 0.2); // 行驶时间20%  
236 - if (troughStopTime < 10) { // 不少于10分钟  
237 - troughStopTime = 10;  
238 - }  
239 - return troughStopTime;  
240 - } else { // 早高峰,晚高峰之间  
241 - troughStopTime = Math.floor(paramObj.getDownTroughTime() * 0.15); // 行驶时间15%  
242 - if (troughStopTime < 10) { // 不少于10分钟  
243 - troughStopTime = 10;  
244 - }  
245 - return troughStopTime;  
246 - }  
247 - }  
248 - }  
249 - } else { // 主站停站  
250 - if (isUp == paramObj.isUpOneWayStop()) {  
251 - if (isUp) { // 上行  
252 - if (this.isMPeakBc(timeObj, paramObj)) { // 早高峰  
253 - peakStopTime = Math.floor(paramObj.getUpMPeakTime() * 0.1); // 行驶时间的10%  
254 - if (peakStopTime < 3) { // 不少于3分钟  
255 - peakStopTime = 3;  
256 - }  
257 - return peakStopTime;  
258 - } else if (this.isEPeakBc(timeObj, paramObj)) { // 晚高峰  
259 - peakStopTime = Math.floor(paramObj.getUpEPeakTime() * 0.1); // 行驶时间的10%  
260 - if (peakStopTime < 3) { // 不少于3分钟  
261 - peakStopTime = 3;  
262 - }  
263 - return peakStopTime;  
264 - } else { // 低谷  
265 - if (this.isTroughBeforMPeakStartBc(timeObj, paramObj)) { // 早高峰开始前  
266 - troughStopTime = Math.floor(paramObj.getUpTroughTime() * 0.2); // 行驶时间20%  
267 - if (troughStopTime < 10) { // 不少于10分钟  
268 - troughStopTime = 10;  
269 - }  
270 - return troughStopTime;  
271 - } else if (this.isTroughAfterEPeakEndBc(timeObj, paramObj)) { // 晚高峰结束后  
272 - troughStopTime = Math.floor(paramObj.getUpTroughTime() * 0.2); // 行驶时间20%  
273 - if (troughStopTime < 10) { // 不少于10分钟  
274 - troughStopTime = 10;  
275 - }  
276 - return troughStopTime;  
277 - } else { // 早高峰,晚高峰之间  
278 - troughStopTime = Math.floor(paramObj.getUpTroughTime() * 0.15); // 行驶时间15%  
279 - if (troughStopTime < 10) { // 不少于10分钟  
280 - troughStopTime = 10;  
281 - }  
282 - return troughStopTime;  
283 - }  
284 - }  
285 - } else { // 下行  
286 - if (this.isMPeakBc(timeObj, paramObj)) { // 早高峰  
287 - peakStopTime = Math.floor(paramObj.getDownMPeakTime() * 0.1); // 行驶时间的10%  
288 - if (peakStopTime < 3) { // 不少于3分钟  
289 - peakStopTime = 3;  
290 - }  
291 - return peakStopTime;  
292 - } else if (this.isEPeakBc(timeObj, paramObj)) { // 晚高峰  
293 - peakStopTime = Math.floor(paramObj.getDownEPeakTime() * 0.1); // 行驶时间的10%  
294 - if (peakStopTime < 3) { // 不少于3分钟  
295 - peakStopTime = 3;  
296 - }  
297 - return peakStopTime;  
298 - } else { // 低谷  
299 - if (this.isTroughBeforMPeakStartBc(timeObj, paramObj)) { // 早高峰开始前  
300 - troughStopTime = Math.floor(paramObj.getDownTroughTime() * 0.2); // 行驶时间20%  
301 - if (troughStopTime < 10) { // 不少于10分钟  
302 - troughStopTime = 10;  
303 - }  
304 - return troughStopTime;  
305 - } else if (this.isTroughAfterEPeakEndBc(timeObj, paramObj)) { // 晚高峰结束后  
306 - troughStopTime = Math.floor(paramObj.getDownTroughTime() * 0.2); // 行驶时间20%  
307 - if (troughStopTime < 10) { // 不少于10分钟  
308 - troughStopTime = 10;  
309 - }  
310 - return troughStopTime;  
311 - } else { // 早高峰,晚高峰之间  
312 - troughStopTime = Math.floor(paramObj.getDownTroughTime() * 0.15); // 行驶时间15%  
313 - if (troughStopTime < 10) { // 不少于10分钟  
314 - troughStopTime = 10;  
315 - }  
316 - return troughStopTime;  
317 - }  
318 - }  
319 - }  
320 - } else { // 副站停战,2到3分钟  
321 - secondaryStopTime = 3;  
322 - return secondaryStopTime; // 直接返回3分钟  
323 - }  
324 - }  
325 -  
326 - },  
327 -  
328 - /**  
329 - * 获取行驶时间。  
330 - * @param timeObj 班次时间字符串  
331 - * @param isUp 是否上行  
332 - * @param paramObj 参数对象  
333 - */  
334 - calcuTravelTime: function(timeObj, isUp, paramObj) {  
335 - if (isUp) {  
336 - if (this.isMPeakBc(timeObj, paramObj)) {  
337 - return paramObj.getUpMPeakTime();  
338 - } else if (this.isEPeakBc(timeObj, paramObj)) {  
339 - return paramObj.getUpEPeakTime();  
340 - } else {  
341 - return paramObj.getUpTroughTime();  
342 - }  
343 - } else {  
344 - if (this.isMPeakBc(timeObj, paramObj)) {  
345 - return paramObj.getDownMPeakTime();  
346 - } else if (this.isEPeakBc(timeObj, paramObj)) {  
347 - return paramObj.getDownEPeakTime();  
348 - } else {  
349 - return paramObj.getDownTroughTime();  
350 - }  
351 - }  
352 - },  
353 -  
354 - /**  
355 - * 获取行驶里程。  
356 - * @param isUp 是否上行  
357 - * @param bcType 班次类型  
358 - * @param paramObj 参数对象  
359 - */  
360 - calcuTravelLcNumber: function(isUp, bcType, paramObj) {  
361 - if (isUp) {  
362 - if (bcType == "in") {  
363 - return paramObj.getUpInLc();  
364 - } else if (bcType == "out") {  
365 - return paramObj.getUpOutLc();  
366 - } else {  
367 - // 基本班次类型,暂时不考虑区间等其他班次类型  
368 - // 暂时不考虑高峰低谷里程的区分  
369 - return paramObj.getUpNormalLc();  
370 - }  
371 - } else {  
372 - if (bcType == "in") {  
373 - return paramObj.getDownInLc();  
374 - } else if (bcType == "out") {  
375 - return paramObj.getDownOutLc();  
376 - } else {  
377 - // 基本班次类型,暂时不考虑区间等其他班次类型  
378 - // 暂时不考虑高峰低谷里程的区分  
379 - return paramObj.getDownNormalLc();  
380 - }  
381 - }  
382 - },  
383 -  
384 - /**  
385 - * 计算高峰周转时间。  
386 - * @param paramObj 参数对象  
387 - * @returns 周转时间  
388 - */  
389 - calcuPeakZzsj: function(paramObj) {  
390 - // 使用早高峰的周转时间  
391 - var _time = paramObj.getMPeakStartTimeObj();  
392 - var _zzsj = // 早高峰上行行驶时间+停站时间+早高峰下行行驶时间+停站时间  
393 - this.calcuTravelTime(_time, true, paramObj) +  
394 - this.calcuFixedStopNumber(_time, true, paramObj) +  
395 - this.calcuTravelTime(_time, false, paramObj) +  
396 - this.calcuFixedStopNumber(_time, false, paramObj);  
397 - return _zzsj;  
398 - },  
399 -  
400 - /**  
401 - * 计算低谷周转时间。  
402 - * @param paramObj 参数对象  
403 - * @returns 周转时间  
404 - */  
405 - calcuTroughZzsj: function(paramObj) {  
406 - // 使用低谷的周转时间  
407 - var _time = this.addMinute(paramObj.getMPeakStartTimeObj(), -1); // 使用任意一个低谷时间  
408 - var _zzsj = // 低谷上行行驶时间+停站时间+低谷下行行驶时间+停站时间  
409 - this.calcuTravelTime(_time, true, paramObj) +  
410 - this.calcuFixedStopNumber(_time, true, paramObj) +  
411 - this.calcuTravelTime(_time, false, paramObj) +  
412 - this.calcuFixedStopNumber(_time, false, paramObj);  
413 -  
414 - return _zzsj;  
415 - },  
416 -  
417 - /**  
418 - * 计算车辆总数。  
419 - * @param paramObj 参数对象  
420 - * @returns 车辆数  
421 - */  
422 - calcuClzx: function(paramObj) {  
423 - // 使用早高峰平均间隔  
424 - var _fcjx_avg = Math.floor((paramObj.getMPeakMinFcjx() + paramObj.getMPeakMaxFcjx()) / 2);  
425 - return Math.round(this.calcuPeakZzsj(paramObj) / _fcjx_avg);  
426 - }  
427 -  
428 - };  
429 -}();  
430 \ No newline at end of file 0 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/strategy/core/InternalBcObj.js deleted 100644 → 0
1 -/**  
2 - * 内部班次对象。  
3 - * @constructor  
4 - */  
5 -var InternalBcObj = function(  
6 - bcType, // 班次类型(normal,in,out等)  
7 - isUp, // boolean是否上下行  
8 - lp, // 路牌标识符  
9 - fcno, // 发车顺序号  
10 - fcTimeObj, // 发车时间对象  
11 - bclc, // 班次里程  
12 - bcsj, // 班次历时  
13 - arrtime, // 到达时间对象  
14 - stoptime, // 停站时间  
15 - tccid, // 停车场id  
16 - ttinfoid, // 时刻表id  
17 - xl, // 线路id  
18 - qdzid, // 起点站id  
19 - zdzid // 终点站id  
20 -) {  
21 - // 属性重新复制一遍,加前缀 _$_ 表示内部属性,不要直接访问k  
22 - // 外部函数使用 prototype 方式  
23 - this._$_bcType = bcType;  
24 - this._$_isUp = isUp;  
25 - this._$_lp = lp;  
26 - this._$_fcno = fcno;  
27 - this._$_fcsjObj = moment(fcTimeObj);  
28 - this._$_bclc = bclc;  
29 - this._$_bcsj = bcsj;  
30 - this._$_arrtime = arrtime;  
31 - this._$_stoptime = stoptime;  
32 - this._$_tccid = tccid;  
33 - this._$_ttinfoid = ttinfoid;  
34 - this._$_xlid = xl;  
35 - this._$_qdzid = qdzid;  
36 - this._$_zdzid = zdzid;  
37 -  
38 -};  
39 -  
40 -/**  
41 - * 是否上行。  
42 - * @returns boolean  
43 - */  
44 -InternalBcObj.prototype.isUp = function() {  
45 - return this._$_isUp;  
46 -};  
47 -/**  
48 - * 获取发车时间。  
49 - * @returns {*|moment.Moment}  
50 - */  
51 -InternalBcObj.prototype.getFcTimeObj = function() {  
52 - return this._$_fcsjObj;  
53 -};  
54 -/**  
55 - * 获取班次时间。  
56 - * @returns int  
57 - */  
58 -InternalBcObj.prototype.getBcTime = function() {  
59 - return this._$_bcsj;  
60 -};  
61 -/**  
62 - * 获取停站时间。  
63 - * @returns int  
64 - */  
65 -InternalBcObj.prototype.getStopTime = function() {  
66 - return this._$_stoptime;  
67 -};  
68 -/**  
69 - * 转换成显示用班次对象。  
70 - * @returns {{}}  
71 - */  
72 -InternalBcObj.prototype.toGanttBcObj = function() {  
73 - var _bcObj = {  
74 - parent: this._$_lp,  
75 - lpNo: this._$_lp,  
76 - lp: null,  
77 - lpName: this._$_lp,  
78 - lpType: '普通路牌',  
79 - bcType: this._$_bcType,  
80 - fcno: this._$_fcno,  
81 - isfb: 0,  
82 - isSwitchXl: null,  
83 - bz: null  
84 - };  
85 -  
86 - // 线路上下行  
87 - _bcObj.xlDir = this._$_isUp ? "relationshipGraph-up" : "relationshipGraph-down";  
88 -  
89 - // 里程  
90 - _bcObj.jhlc = this._$_bclc;  
91 -  
92 - // 停车场  
93 - _bcObj.tcc = this._$_tccid;  
94 -  
95 - // 时刻表  
96 - _bcObj.ttinfo = this._$_ttinfoid;  
97 -  
98 - // 线路  
99 - _bcObj.xl = this._$_xlid;  
100 -  
101 - // 起点站、终点站  
102 - _bcObj.qdz = this._$_qdzid;  
103 - _bcObj.zdz = this._$_zdzid;  
104 -  
105 - // 发车时间,行驶时间,到达时间,停站时间  
106 - _bcObj.fcsj = this._$_fcsjObj.format("HH:mm");  
107 - _bcObj.bcsj = this._$_bcsj;  
108 - _bcObj.ARRIVALTIME = this._$_arrtime;  
109 - _bcObj.STOPTIME = this._$_stoptime;  
110 -  
111 - return _bcObj;  
112 -};  
113 -  
src/main/resources/static/pages/base/timesmodel/js/strategy/strategy-headway.js deleted 100644 → 0
1 -/**  
2 - * 使用发车间隔模拟客流的策略,生成时刻表。  
3 - */  
4 -var StrategyHeadway = function() {  
5 - // 所有的时间使用moment.js计算  
6 -  
7 - var _paramObj; // 参数对象  
8 -  
9 - var _bxDesc = [ // 班型描述  
10 - {'type':'六工一休','hoursV':6.66, 'minueV':'6:40', 'qcount': 0, 'avertime': 0},  
11 - {'type':'五工一休','hoursV':6.85, 'minueV':'6:51', 'qcount': 0, 'avertime': 0},  
12 - {'type':'四工一休','hoursV':7.14, 'minueV':'7:08', 'qcount': 0, 'avertime': 0},  
13 - {'type':'三工一休','hoursV':7.61, 'minueV':'7:37', 'qcount': 0, 'avertime': 0},  
14 - {'type':'二工一休','hoursV':8.57, 'minueV':'8:34', 'qcount': 0, 'avertime': 0},  
15 - {'type':'一工一休','hoursV':11.42, 'minueV':'11:25', 'qcount': 0, 'avertime': 0},  
16 - {'type':'五工二休','hoursV':7.99, 'minueV':'8:00', 'qcount': 0, 'avertime': 0},  
17 - {'type':'无工休', 'hoursV':5.43, 'minueV':'5:43', 'qcount': 0, 'avertime': 0}  
18 - ];  
19 -  
20 - // 重要数据结构,二维数组的形式保存班次信息  
21 - // 行表示几个路牌,列表示几圈,每个元素表示一圈包含两个班次对象(一个也有可能)  
22 - // TODO:之后会把这个结构定义成一个类  
23 - var _headWayBcArray = [];  
24 -  
25 - var headWayF = {  
26 - /**  
27 - * 使用发车间隔策略生成时刻表。  
28 - * @param paramObj 参数对象  
29 - * @param lpArray 路牌数组  
30 - * @constructor  
31 - */  
32 - BXPplaceClassesTime03 : function(paramObj, lpArray) {  
33 - //console.log(lpArray);  
34 -  
35 - _paramObj = paramObj;  
36 -  
37 - var i = 0;  
38 - var j = 0;  
39 - var data = [];  
40 -  
41 - // 第一步,计算标准线,计算所有班型工时,创建二维班次结构,并把标准线数据作为第一个路牌的班次数据  
42 - this._01_buildBasicLine(lpArray);  
43 - // 第二步,构造所有高峰班次  
44 - this._02_buildAllGfbc(lpArray);  
45 - // 第三步,计算班型类型(每个路牌的班型)  
46 - this._03_calcuBxtype();  
47 - // 第四步,根据每个路牌的班型构造所有班次  
48 - this._04_buildAllOtherBc(lpArray);  
49 -  
50 -  
51 - // TODO:先定死参数  
52 - // 早高峰间隔时间 7分钟  
53 - // 晚高峰间隔时间 7分钟  
54 - // 早高峰之前 15分钟  
55 - // 早高峰结束,晚高峰开始之前 15分钟  
56 - // 晚高峰之后 20分钟  
57 -  
58 - // 做5休2路牌数目 6  
59 - //var data1 = {};  
60 - //  
61 - //// TODO:计算基准线,不画,使用下行,以后根据哪个首班早,用哪个方向  
62 - //data = data.concat(this._buildNormalLine(false, 12));  
63 - //data = data.concat(this._01_buildBasicLine(lpArray));  
64 - //console.log(_bxDesc);  
65 -  
66 - //// TODO:按照早高峰开始时间,以及间隔时间从头创建班次  
67 - //var avertime = _bxDesc.avertime; // 平均周转时间  
68 - //var maxgftime = 75 + 80 + 7 + 8; // 高峰最大周转时间  
69 - //var data1 = this._buildAllGfBc(false);  
70 - //console.log(data1);  
71 - //  
72 - //// TODO:分割路牌,选出正路牌,从早高峰班次开始添加到晚高峰结束  
73 - //// TODO:写死,使用奇数路牌添加正路牌  
74 - //// TODO:按照做一休一来,4.5圈  
75 - //var maxdgtime = 75 + 75 + 15 + 15; // 低谷最大周转时间  
76 - //var zlp = [1, 4, 7, 10, 13, 16, 19, 22, 23]; // 9个正路牌,使用低谷最小配车数  
77 - //var xldir_z = true;  
78 - //var bc_index = 1;  
79 - //var bc_obj;  
80 - //var kssj_gfstart;  
81 - //for (i = 0; i < zlp.length; i++) {  
82 - // // TODO:删除正路牌的bcWgf  
83 - // delete data1[zlp[i]].bcWgf;  
84 - //  
85 - // kssj_gfstart = StrategyUtils.toWrapTime(data1[zlp[i]].bcZgf.fcsj);  
86 - // kssj_gfstart = kssj_gfstart.add(data1[zlp[i]].bcZgf.bcsj, "m").add(data1[zlp[i]].bcZgf.STOPTIME, "m");  
87 - // for (bc_index = 1; bc_index <= 9; bc_index++) {  
88 - // bc_obj = StrategyUtils.getFactory().creatBcObjWithFixedStopTime(  
89 - // "normal",  
90 - // xldir_z, zlp[i], 3,  
91 - // kssj_gfstart.format("HH:mm"),  
92 - // _paramObj  
93 - // );  
94 - // data.push(bc_obj);  
95 - //  
96 - // xldir_z = !xldir_z;  
97 - // kssj_gfstart = StrategyUtils.toWrapTime(bc_obj.ARRIVALTIME).add(bc_obj.STOPTIME, "m");  
98 - // }  
99 - //  
100 - // bc_index = 1;  
101 - // xldir_z = true;  
102 - //}  
103 - //  
104 - //// TODO:修正bcWgf  
105 - //for (var key in data1) {  
106 - // if (data1[key].bcWgf) {  
107 - // // TODO:第一块正路牌的bcWgf晚了18分钟,分班路牌的bcWgf向后移动18分钟  
108 - // // TODO:还要改成上行  
109 - // data1[key].bcWgf = StrategyUtils.getFactory().creatBcObjWithFixedStopTime(  
110 - // "normal",  
111 - // true, key, 3,  
112 - // StrategyUtils.toWrapTime(data1[key].bcWgf.fcsj).add(18, "m").format("HH:mm"),  
113 - // _paramObj  
114 - // );  
115 - // }  
116 - //  
117 - //}  
118 - //  
119 - //// TODO:6个做5休二,大致3圈  
120 - //// TODO:暂时写死路牌分割位置,然后以bcZgf,bcWgf为基准向左右两侧各加2各班次  
121 - //var _5_2_lp = [5, 8, 11, 14, 17, 20];  
122 - //for (i = 0; i < _5_2_lp.length; i++) {  
123 - // // TODO:先向后加一个班次  
124 - // data.push(StrategyUtils.getFactory().creatBcObjWithFixedStopTime(  
125 - // "normal",  
126 - // "relationshipGraph-down", _5_2_lp[i], 3,  
127 - // StrategyUtils.toWrapTime(data1[_5_2_lp[i]].bcZgf.ARRIVALTIME).add(data1[_5_2_lp[i]].bcZgf.STOPTIME, "m").format("HH:mm"),  
128 - // _paramObj  
129 - // ));  
130 - // data.push(StrategyUtils.getFactory().creatBcObjWithFixedStopTime(  
131 - // "normal",  
132 - // "relationshipGraph-up", _5_2_lp[i], 3,  
133 - // StrategyUtils.toWrapTime(data1[_5_2_lp[i]].bcWgf.ARRIVALTIME).add(data1[_5_2_lp[i]].bcWgf.STOPTIME, "m").format("HH:mm"),  
134 - // _paramObj  
135 - // ));  
136 - //}  
137 -  
138 -  
139 - // TODO:8个其他形式分班  
140 -  
141 -  
142 - // final: 添加班次  
143 - for (i = 0; i < _headWayBcArray.length; i++) {  
144 - for (j = 0; j < _headWayBcArray[i]["qObj"].length; j++) {  
145 - if (_headWayBcArray[i]["qObj"][j].hasBc1) {  
146 - data.push(_headWayBcArray[i]["qObj"][j]["_bc1_"].toGanttBcObj());  
147 - }  
148 - if (_headWayBcArray[i]["qObj"][j].hasBc2) {  
149 - data.push(_headWayBcArray[i]["qObj"][j]["_bc2_"].toGanttBcObj());  
150 - }  
151 - }  
152 - }  
153 -  
154 - return {'json':data,'bxrcgs':null};  
155 - },  
156 -  
157 - // TODO:构造所有路牌早晚高峰班次(假设早高峰和晚高峰相同的车辆数)  
158 - _buildAllGfBc: function(isUp) {  
159 - // TODO:按照早高峰开始时间,以及间隔时间从头创建班次  
160 - var _travelTimeObj = _paramObj.getTravelTimeObj();  
161 - var _timeIntervalObj = _paramObj.getTimeIntervalObj();  
162 -  
163 - var avertime = _bxDesc.avertime; // 平均周转时间  
164 - var maxzgftime = // 早高峰最大周转时间  
165 - _travelTimeObj.moningpeak[0] +  
166 - _travelTimeObj.moningpeak[1] +  
167 - Math.floor(_travelTimeObj.moningpeak[0] * 0.1) +  
168 - Math.floor(_travelTimeObj.moningpeak[1] * 0.1);  
169 - var maxwgftime = // 晚早高峰最大周转时间  
170 - _travelTimeObj.eveningpeak[0] +  
171 - _travelTimeObj.eveningpeak[1] +  
172 - Math.floor(_travelTimeObj.eveningpeak[0] * 0.1) +  
173 - Math.floor(_travelTimeObj.eveningpeak[1] * 0.1);  
174 -  
175 - // 计算早高峰间隔  
176 - var data1 = {};  
177 - var kssj_gfstart = StrategyUtils.toWrapTime(_timeIntervalObj.moningPeakTimeStrs.start);  
178 - var clCount = _paramObj.getClzs();  
179 - var c1 = Math.floor(maxzgftime / clCount);  
180 - var c2 = maxzgftime % clCount;  
181 - var i = 0;  
182 - for (i = 1; i <= clCount - c2; i ++) {  
183 - data1[i] = {};  
184 - data1[i].bcZgf = StrategyUtils.getFactory().creatBcObjWithFixedStopTime(  
185 - "normal",  
186 - isUp, i, 3,  
187 - kssj_gfstart.format("HH:mm"),  
188 - _paramObj  
189 - );  
190 - kssj_gfstart = kssj_gfstart.add(c1, "m");  
191 - }  
192 - for (i = 1; i <= c2; i++) {  
193 - data1[clCount - c2 + i] = {};  
194 - data1[clCount - c2 + i].bcZgf = StrategyUtils.getFactory().creatBcObjWithFixedStopTime(  
195 - "normal",  
196 - isUp, clCount - c2 + i, 3,  
197 - kssj_gfstart.format("HH:mm"),  
198 - _paramObj  
199 - );  
200 - kssj_gfstart = kssj_gfstart.add(c1 + 1, "m");  
201 - }  
202 -  
203 - // 计算晚高峰间隔  
204 - kssj_gfstart = StrategyUtils.toWrapTime(_timeIntervalObj.eveningPeakTimeStrs.start);  
205 - c1 = Math.floor(maxwgftime / clCount);  
206 - c2 = maxwgftime % clCount;  
207 - for (i = 1; i <= clCount - c2; i ++) {  
208 - data1[i].bcWgf = StrategyUtils.getFactory().creatBcObjWithFixedStopTime(  
209 - "normal",  
210 - isUp, i, 3,  
211 - kssj_gfstart.format("HH:mm"),  
212 - _paramObj  
213 - );  
214 - kssj_gfstart = kssj_gfstart.add(c1, "m");  
215 - }  
216 - for (i = 1; i <= c2; i++) {  
217 - data1[clCount - c2 + i].bcWgf = StrategyUtils.getFactory().creatBcObjWithFixedStopTime(  
218 - "normal",  
219 - isUp, clCount - c2 + i, 3,  
220 - kssj_gfstart.format("HH:mm"),  
221 - _paramObj  
222 - );  
223 - kssj_gfstart = kssj_gfstart.add(c1 + 1, "m");  
224 - }  
225 -  
226 - return data1;  
227 - },  
228 -  
229 - /**  
230 - * 第一步,创建标准线,并放置在第一个路牌上。  
231 - * @param lpArray 路牌列表  
232 - */  
233 - _01_buildBasicLine: function(lpArray) {  
234 - // TODO:放置上标线,中标线在议  
235 -  
236 - // 确定使用上行还是下行首班车作为上标线开始  
237 - var _isUp = _paramObj.getUpFirstDTimeObj().isBefore(_paramObj.getDownFirstDTimeObj()) ? false : true;  
238 - var firstTime = _isUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();  
239 - var downTime = _isUp ? _paramObj.getUpLastDtimeObj() : _paramObj.getDownLastDTimeObj();  
240 -  
241 - var data = [];  
242 - var bcObj;  
243 - var kssj = firstTime;  
244 - var fcno = 1; // 发车顺序号  
245 - var qBcCount = 1; // 班次数  
246 - var qArray = [_isUp, !_isUp]; // 圈的方向(true:上行,false:下行)  
247 - var qIndex = 0;  
248 - do {  
249 - bcObj = StrategyUtils.getFactory().createBcObj(  
250 - "normal", qArray[qIndex], lpArray[0].lpNo, fcno, kssj, _paramObj);  
251 - kssj = StrategyUtils.addMinute(kssj, bcObj.getBcTime() + bcObj.getStopTime());  
252 - fcno ++;  
253 - qBcCount ++;  
254 - qIndex = (qBcCount - 1) % 2;  
255 - data.push(bcObj);  
256 - } while(kssj.isBefore(downTime));  
257 - qBcCount = data.length;  
258 -  
259 - // 根据圈数,初始化  
260 - var i = 0;  
261 - var j = 0;  
262 - var n = 0;  
263 - for (i = 0; i < lpArray.length; i++) {  
264 - // 前后都预留一圈  
265 - n = 1 + (Math.floor(qBcCount / 2) + qBcCount % 2) + 1;  
266 - _headWayBcArray[i] = {  
267 - "bxIndex" : 6, // 默认做五休二  
268 - "qObj" : new Array(n) // 圈数  
269 - };  
270 -  
271 - for (j = 0; j < n; j++) {  
272 - _headWayBcArray[i]["qObj"][j] = {  
273 - "hasBc1" : false, // 是否有第一个班次  
274 - "hasBc2" : false, // 是否有第二个班次  
275 - "_bc1_" : {}, // 第一个班次  
276 - "_bc2_" : {} // 第二个班次  
277 -  
278 - // TODO:其他参数再议  
279 - };  
280 - }  
281 - }  
282 - for (i = 1; i <= Math.floor(qBcCount / 2); i++) {  
283 - _headWayBcArray[0]["qObj"][i]["hasBc1"] = true;  
284 - _headWayBcArray[0]["qObj"][i]["_bc1_"] = data[(i - 1) * 2];  
285 - _headWayBcArray[0]["qObj"][i]["hasBc2"] = true;  
286 - _headWayBcArray[0]["qObj"][i]["_bc2_"] = data[(i - 1) * 2 + 1];  
287 - }  
288 - if (qBcCount % 2 != 0) {  
289 - _headWayBcArray[0]["qObj"][Math.floor(qBcCount / 2) + 1]["hasBc1"] = true;  
290 - _headWayBcArray[0]["qObj"][Math.floor(qBcCount / 2) + 1]["_bc1_"] = data[qBcCount - 1];  
291 - }  
292 -  
293 - //console.log(_headWayBcArray);  
294 -  
295 - // 计算每种班型在基准线下对应的大致圈数(1表示1圈2个班次,.5表示半圈1个班次)  
296 - i = 0;  
297 - var avertime = 0;  
298 - var sum = 0;  
299 - var size_sub = qBcCount % 2; // 剩下的班次  
300 - if (qBcCount > 1) {  
301 - // 计算平均周转时间  
302 - for (i = 0; i < data.length - size_sub; i ++) {  
303 - sum += data[i].getBcTime() + data[i].getStopTime();  
304 - }  
305 - avertime = sum / ((qBcCount - size_sub) / 2);  
306 - // 计算班型圈数  
307 - for (i = 0; i < _bxDesc.length; i ++) {  
308 - _bxDesc[i].avertime = avertime;  
309 - _bxDesc[i].qcount = _bxDesc[i].hoursV * 60 / avertime;  
310 - }  
311 - }  
312 -  
313 - console.log(_headWayBcArray);  
314 - console.log(_bxDesc);  
315 -  
316 - },  
317 -  
318 - /**  
319 - * 第二步,构造所有高峰班次。  
320 - */  
321 - _02_buildAllGfbc: function(lpArray) {  
322 - // TODO:先设定死,以标准线为起点从哪个班次出来,以后再用算法确定  
323 - // 早高峰,从第一圈,第一个班次全部出来  
324 - // 晚高峰,从第四圈,第二个班次全部出来  
325 -  
326 - var _kssj;  
327 - var _zzsj;  
328 - var _clCount = StrategyUtils.calcuClzx(_paramObj);;  
329 - var _c1;  
330 - var _c2;  
331 - var i;  
332 - var _bc1_;  
333 - var _bc2_;  
334 -  
335 - // 计算早高峰  
336 - _bc1_ = _headWayBcArray[0]["qObj"][1]["_bc1_"];  
337 - _bc2_ = _headWayBcArray[0]["qObj"][1]["_bc2_"];  
338 - _zzsj = _bc1_.getBcTime() + _bc1_.getStopTime() +  
339 - _bc2_.getBcTime() + _bc2_.getStopTime();  
340 - _c1 = Math.floor(_zzsj / _clCount);  
341 - _c2 = _zzsj % _clCount;  
342 - _kssj = _bc1_.getFcTimeObj();  
343 -  
344 - for (i = 2; i <= _clCount - _c2; i++) {  
345 - _kssj = StrategyUtils.addMinute(_kssj, _c1);  
346 - _headWayBcArray[i - 1]["qObj"][1]["hasBc1"] = true;  
347 - _headWayBcArray[i - 1]["qObj"][1]["_bc1_"] =  
348 - StrategyUtils.getFactory().createBcObj(  
349 - "normal", true, lpArray[i - 1].lpNo,  
350 - 3, _kssj, _paramObj);  
351 - }  
352 - for (i = 1; i <= _c2; i++) {  
353 - _kssj = StrategyUtils.addMinute(_kssj, _c1 + 1);  
354 - _headWayBcArray[_clCount - _c2 + i - 1]["qObj"][1]["hasBc1"] = true;  
355 - _headWayBcArray[_clCount - _c2 + i - 1]["qObj"][1]["_bc1_"] =  
356 - StrategyUtils.getFactory().createBcObj(  
357 - "normal", true, lpArray[_clCount - _c2 + i - 1].lpNo,  
358 - 3, _kssj, _paramObj);  
359 - }  
360 -  
361 - // 计算晚高峰  
362 - _bc1_ = _headWayBcArray[0]["qObj"][4]["_bc2_"];  
363 - _bc2_ = _headWayBcArray[0]["qObj"][5]["_bc1_"];  
364 - _zzsj = _bc1_.getBcTime() + _bc1_.getStopTime() +  
365 - _bc2_.getBcTime() + _bc2_.getStopTime();  
366 - _c1 = Math.floor(_zzsj / _clCount);  
367 - _c2 = _zzsj % _clCount;  
368 - _kssj = _bc1_.getFcTimeObj();  
369 -  
370 - for (i = 2; i <= _clCount - _c2; i++) {  
371 - _kssj = StrategyUtils.addMinute(_kssj, _c1);  
372 - _headWayBcArray[i - 1]["qObj"][4]["hasBc1"] = true;  
373 - _headWayBcArray[i - 1]["qObj"][4]["_bc1_"] =  
374 - StrategyUtils.getFactory().createBcObj(  
375 - "normal", false, lpArray[i - 1].lpNo,  
376 - 3, _kssj, _paramObj);  
377 - }  
378 - for (i = 1; i <= _c2; i++) {  
379 - _kssj = StrategyUtils.addMinute(_kssj, _c1 + 1);  
380 - _headWayBcArray[_clCount - _c2 + i - 1]["qObj"][4]["hasBc1"] = true;  
381 - _headWayBcArray[_clCount - _c2 + i - 1]["qObj"][4]["_bc1_"] =  
382 - StrategyUtils.getFactory().createBcObj(  
383 - "normal", false, lpArray[_clCount - _c2 + i - 1].lpNo,  
384 - 3, _kssj, _paramObj);  
385 - }  
386 -  
387 -  
388 -  
389 -  
390 - },  
391 -  
392 - /**  
393 - * 第三步,计算班型类型(每个路牌的班型)。  
394 - */  
395 - _03_calcuBxtype: function() {  
396 - // 路牌数和车辆数是一致的  
397 -  
398 - // 总共车辆数(高峰最大车辆数)  
399 - var cls = StrategyUtils.calcuClzx(_paramObj);  
400 - // 低谷最少配车  
401 - var dgminpc = Math.round(StrategyUtils.calcuTroughZzsj(_paramObj) / _paramObj.getTroughMaxFcjx());  
402 - // 加班车路牌数(做5休2的路牌数)  
403 - var _5_2_lpes = _paramObj.getJBLpes();  
404 -  
405 - // 做些简单的验证  
406 - if (cls < dgminpc) {  
407 - alert("总配车数小于低谷最小配车");  
408 - throw "总配车数小于低谷最小配车";  
409 - }  
410 - if (cls - dgminpc < _5_2_lpes) {  
411 - alert("总分班路牌数小于加班路牌数");  
412 - throw "总分班路牌数小于加班路牌数";  
413 - }  
414 -  
415 - // 早高峰间隔时间 7分钟  
416 - // 晚高峰间隔时间 7分钟  
417 - // 早高峰之前 15分钟  
418 - // 早高峰结束,晚高峰开始之前 15分钟  
419 - // 晚高峰之后 20分钟  
420 -  
421 - // 做5休2路牌数目 6  
422 -  
423 -  
424 -  
425 - // TODO:不用间隔法,直接拉,先正路牌,再分班  
426 - var _zlpCount = dgminpc;  
427 - var _5_2_Count = _5_2_lpes;  
428 - var _otherfb_ = cls - dgminpc - _5_2_lpes;  
429 - var i = 0;  
430 - for (i = 0; i < _zlpCount; i++) {  
431 - _headWayBcArray[i].bxIndex = 5; // 做一休一  
432 - }  
433 - for (i = _zlpCount; i < _5_2_Count; i++) {  
434 - _headWayBcArray[i].bxIndex = 6; // 做五休二  
435 - }  
436 - for (i = _zlpCount + _5_2_Count; i < _otherfb_; i++) {  
437 - _headWayBcArray[i].bxIndex = 3; // 做三休一  
438 - }  
439 -  
440 - },  
441 -  
442 - /**  
443 - * 第四步,根据每个路牌的班型构造所有班次。  
444 - */  
445 - _04_buildAllOtherBc: function(lpArray) {  
446 - var _bcCount;  
447 - var _qArray;  
448 - var i;  
449 - var j;  
450 - var z;  
451 - var _kssj;  
452 -  
453 - // 构造正路牌,从早高峰一直加到晚高峰,不够晚高峰后再加  
454 - _bcCount = Math.floor(_bxDesc[_headWayBcArray[0].bxIndex].qcount * 2);  
455 - // TODO:都是从第一圈第一个班次开始  
456 - for (i = 1; i < _headWayBcArray.length; i++) {  
457 - _qArray = _headWayBcArray[i].qObj;  
458 -  
459 - j = 1;  
460 - _kssj = StrategyUtils.addMinute(  
461 - _qArray[1]._bc1_.getFcTimeObj(),  
462 - _qArray[1]._bc1_.getBcTime() +  
463 - _qArray[1]._bc1_.getStopTime()  
464 - );  
465 - // TODO:向后拉6个班次  
466 - _qArray[1].hasBc2 = true;  
467 - _qArray[1]._bc2_ =  
468 - StrategyUtils.getFactory().createBcObj(  
469 - "normal", false, lpArray[i].lpNo,  
470 - 3, _kssj, _paramObj);  
471 - _kssj = StrategyUtils.addMinute(  
472 - _qArray[1]._bc2_.getFcTimeObj(),  
473 - _qArray[1]._bc2_.getBcTime() +  
474 - _qArray[1]._bc2_.getStopTime()  
475 - );  
476 -  
477 - _qArray[2].hasBc1 = true;  
478 - _qArray[2]._bc1_ =  
479 - StrategyUtils.getFactory().createBcObj(  
480 - "normal", true, lpArray[i].lpNo,  
481 - 3, _kssj, _paramObj);  
482 - _kssj = StrategyUtils.addMinute(  
483 - _qArray[2]._bc1_.getFcTimeObj(),  
484 - _qArray[2]._bc1_.getBcTime() +  
485 - _qArray[2]._bc1_.getStopTime()  
486 - );  
487 - _qArray[2].hasBc2 = true;  
488 - _qArray[2]._bc2_ =  
489 - StrategyUtils.getFactory().createBcObj(  
490 - "normal", false, lpArray[i].lpNo,  
491 - 3, _kssj, _paramObj);  
492 -  
493 -  
494 - }  
495 -  
496 - }  
497 -  
498 -  
499 -  
500 - };  
501 -  
502 - return headWayF;  
503 -  
504 -}();  
505 \ No newline at end of file 0 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/systemTools.js
@@ -460,6 +460,6 @@ $(&#39;.parambtn&#39;).on(&#39;click&#39;, function() { @@ -460,6 +460,6 @@ $(&#39;.parambtn&#39;).on(&#39;click&#39;, function() {
460 $.get('/pages/base/timesmodel/paramadd.html', function(m){ 460 $.get('/pages/base/timesmodel/paramadd.html', function(m){
461 $(pjaxContainer).append(m); 461 $(pjaxContainer).append(m);
462 // 规定被选元素要触发的事件。可以使自定义事件(使用 bind() 函数来附加),或者任何标准事件。 462 // 规定被选元素要触发的事件。可以使自定义事件(使用 bind() 函数来附加),或者任何标准事件。
463 - $('#paramadd_mobal').trigger('paramAddMobal.show', Main_v2); 463 + $('#paramadd_mobal').trigger('paramAddMobal.show', [Main_v2, Main_v2_2, InternalScheduleObj_v2_2]);
464 }); 464 });
465 }); 465 });
466 \ No newline at end of file 466 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2/core/InternalLpObj.js
@@ -42,6 +42,13 @@ var InternalLpObj = function( @@ -42,6 +42,13 @@ var InternalLpObj = function(
42 this._$_aVerticalIntervalTime[i] = new Array(2); 42 this._$_aVerticalIntervalTime[i] = new Array(2);
43 } 43 }
44 44
  45 + // 间隔修正百分比,主要配和CalcuHeadwayS2策略生成预估发车间隔
  46 + this._$_CalcuHeadwayS2_p = new Array(this._$_qCount);
  47 + for (i = 0; i < this._$_CalcuHeadwayS2_p.length; i++) {
  48 + this._$_CalcuHeadwayS2_p[i] = new Array(2);
  49 + }
  50 +
  51 +
45 // 班型的相关变量 52 // 班型的相关变量
46 this._$_bx_isLb = false; // 是否连班 53 this._$_bx_isLb = false; // 是否连班
47 this._$_bx_isfb = false; // 是否分班 54 this._$_bx_isfb = false; // 是否分班
@@ -94,7 +101,14 @@ InternalLpObj.prototype.isUp = function() { @@ -94,7 +101,14 @@ InternalLpObj.prototype.isUp = function() {
94 * @param bcIndex 第几个班次 101 * @param bcIndex 第几个班次
95 */ 102 */
96 InternalLpObj.prototype.getBc = function(qIndex, bcIndex) { 103 InternalLpObj.prototype.getBc = function(qIndex, bcIndex) {
  104 + if (qIndex < 0 || qIndex >= this._$_qCount) {
  105 + return undefined;
  106 + }
  107 +
97 var group = this._$_groupBcArray[qIndex]; 108 var group = this._$_groupBcArray[qIndex];
  109 + if (!group) {
  110 + return undefined;
  111 + }
98 var bc; 112 var bc;
99 if (bcIndex == 0) { 113 if (bcIndex == 0) {
100 bc = group.getBc1(); 114 bc = group.getBc1();
@@ -216,6 +230,14 @@ InternalLpObj.prototype.fnGetVerticalIntervalTime = function(iQindex, iBindex) { @@ -216,6 +230,14 @@ InternalLpObj.prototype.fnGetVerticalIntervalTime = function(iQindex, iBindex) {
216 return this._$_aVerticalIntervalTime[iQindex][iBindex]; 230 return this._$_aVerticalIntervalTime[iQindex][iBindex];
217 }; 231 };
218 232
  233 +InternalLpObj.prototype.fnSetHeadwayS2_P = function(iQindex, iBindex, i) {
  234 + this._$_CalcuHeadwayS2_p[iQindex][iBindex] = i;
  235 +};
  236 +InternalLpObj.prototype.fnGetHeadwayS2_P = function(iQindex, iBindex) {
  237 + return this._$_CalcuHeadwayS2_p[iQindex][iBindex];
  238 +};
  239 +
  240 +
219 //-------------------- 班次操作方法(查询,统计,删除) -----------------------// 241 //-------------------- 班次操作方法(查询,统计,删除) -----------------------//
220 242
221 /** 243 /**
@@ -260,6 +282,33 @@ InternalLpObj.prototype.getBcArray = function() { @@ -260,6 +282,33 @@ InternalLpObj.prototype.getBcArray = function() {
260 }; 282 };
261 283
262 /** 284 /**
  285 + * 返回指定时间后的班次列表。
  286 + * @param oFromTime
  287 + * @return {Array}
  288 + */
  289 +InternalLpObj.prototype.getBcArrayFromTime = function(oFromTime) {
  290 + var bcArray = [];
  291 + var i;
  292 + var group;
  293 + var oBc;
  294 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  295 + group = this._$_groupBcArray[i];
  296 + if (group) {
  297 + oBc = group.getBc1();
  298 + if (oBc && oBc.getFcTimeObj().isAfter(oFromTime)) {
  299 + bcArray.push(oBc);
  300 + }
  301 + oBc = group.getBc2();
  302 + if (oBc && oBc.getFcTimeObj().isAfter(oFromTime)) {
  303 + bcArray.push(oBc);
  304 + }
  305 + }
  306 + }
  307 +
  308 + return bcArray;
  309 +};
  310 +
  311 +/**
263 * 获取最小(最早)班次对象。 312 * 获取最小(最早)班次对象。
264 * @returns [{圈index},{班次index}] 313 * @returns [{圈index},{班次index}]
265 */ 314 */
@@ -634,6 +683,9 @@ InternalLpObj.prototype._initDataFromLbBcArray = function( @@ -634,6 +683,9 @@ InternalLpObj.prototype._initDataFromLbBcArray = function(
634 var _qObj; 683 var _qObj;
635 684
636 // 第一班次是上行还是下行 685 // 第一班次是上行还是下行
  686 + if (bcArray.length == 0) {
  687 + return;
  688 + }
637 var isUp = bcArray[0].isUp(); 689 var isUp = bcArray[0].isUp();
638 690
639 if (bcArray.length > 0 && fromQ < this._$_qCount) { 691 if (bcArray.length > 0 && fromQ < this._$_qCount) {
@@ -645,7 +697,7 @@ InternalLpObj.prototype._initDataFromLbBcArray = function( @@ -645,7 +697,7 @@ InternalLpObj.prototype._initDataFromLbBcArray = function(
645 _qObj = new InternalGroupObj( 697 _qObj = new InternalGroupObj(
646 this, 698 this,
647 this._$_isUp, 699 this._$_isUp,
648 - undefined, 700 + this.getGroup(fromQ).getBc1(), // 之前group的前半个班次要保留
649 _bc2Obj 701 _bc2Obj
650 ); 702 );
651 _bc2Obj.setGroup(_qObj); 703 _bc2Obj.setGroup(_qObj);
@@ -681,7 +733,7 @@ InternalLpObj.prototype._initDataFromLbBcArray = function( @@ -681,7 +733,7 @@ InternalLpObj.prototype._initDataFromLbBcArray = function(
681 this, 733 this,
682 this._$_isUp, 734 this._$_isUp,
683 _bc1Obj, 735 _bc1Obj,
684 - undefined 736 + undefined // 如果之前的组这里有班次,不保留,直接祛除
685 ); 737 );
686 _bc1Obj.setGroup(_qObj); 738 _bc1Obj.setGroup(_qObj);
687 this._$_groupBcArray[fromQ] = _qObj; 739 this._$_groupBcArray[fromQ] = _qObj;
@@ -897,7 +949,7 @@ InternalLpObj.prototype.getPreBc = function(oBc) { @@ -897,7 +949,7 @@ InternalLpObj.prototype.getPreBc = function(oBc) {
897 } 949 }
898 950
899 if (_bFindCurrentBc) { 951 if (_bFindCurrentBc) {
900 - if (iQIndex == oBcIndex["s_q"] && iBcIndex == oBcIndex["s_q"]) { // 第一个班次 952 + if (iQIndex == oBcIndex["s_q"] && iBcIndex == oBcIndex["s_b"]) { // 第一个班次
901 break; 953 break;
902 } else { 954 } else {
903 _oPreBc = this.getBc( 955 _oPreBc = this.getBc(
@@ -1013,14 +1065,156 @@ InternalLpObj.prototype.fnAdjustBcTime_layover = function(oParam) { @@ -1013,14 +1065,156 @@ InternalLpObj.prototype.fnAdjustBcTime_layover = function(oParam) {
1013 } 1065 }
1014 }; 1066 };
1015 1067
1016 -// TODO 1068 +/**
  1069 + * 从指定区间时间范围内找出指定班次列表。
  1070 + * @param oFromTime 开始时间
  1071 + * @param oEndTime 结束时间
  1072 + * @param isUp 是否上行
  1073 + */
  1074 +InternalLpObj.prototype.fnFindBcWithTimeRange = function(oFromTime, oEndTime, isUp) {
  1075 + // oBc:班次对象,iGroupIndex:圈索引,iBcIndex:第几个班次
  1076 + var oBc;
  1077 + var oBcIndex = {oBc: null, iGroupIndex: 0, iBcIndex: 0};
  1078 + var aBc = [];
  1079 + var iFdiff = 0; // 距离开始时间的差值
  1080 + var iEdiff = 0; // 距离结束时间的差值
  1081 + for (var i = 0; i < this._$_qCount; i++) {
  1082 + for (var j = 0; j < 2; j++) {
  1083 + oBc = this.getBc(i, j);
  1084 + if (oBc) {
  1085 + iFdiff = oBc.getFcTimeObj().diff(oFromTime);
  1086 + iEdiff = oBc.getFcTimeObj().diff(oEndTime);
  1087 + if (iFdiff >= 0 && iEdiff <= 0 && oBc.isUp() == isUp) {
  1088 + oBcIndex = {oBc: oBc, iGroupIndex: i, iBcIndex: j};
  1089 + aBc.push(oBcIndex);
  1090 + }
  1091 + }
  1092 + }
  1093 + }
  1094 +
  1095 + return aBc;
  1096 +};
1017 1097
1018 /** 1098 /**
1019 - *  
1020 - * 1099 + * 清空班次。
  1100 + * @param fromQ 从第几圈开始(圈索引)
  1101 + * @param iBcIndex 班次索引
1021 */ 1102 */
1022 -InternalLpObj.prototype.calcuLpBx = function() { 1103 +InternalLpObj.prototype.clearBc = function(fromQ, iBcIndex) {
  1104 + var i;
  1105 + var group;
  1106 +
  1107 + if (fromQ >= 0 && fromQ < this._$_qCount) {
  1108 + group = this._$_groupBcArray[fromQ];
  1109 +
  1110 + // 先清除第一圈
  1111 + if (iBcIndex == 1) {
  1112 + group.setBc2(undefined);
  1113 + } else if (iBcIndex == 0) {
  1114 + group.setBc1(undefined);
  1115 + group.setBc2(undefined);
  1116 + }
  1117 +
  1118 + // 清除后续圈的班次
  1119 + for (i = fromQ + 1; i < this._$_qCount; i++) {
  1120 + group = this._$_groupBcArray[i];
  1121 + group.setBc1(undefined);
  1122 + group.setBc2(undefined);
  1123 + }
  1124 + }
  1125 +};
  1126 +
  1127 +/**
  1128 + * 从指定方向,指定时间开始重新生成连续的班次。
  1129 + * @param startTime 开始时间
  1130 + * @param isUp 第一个班次是上行还是下行
  1131 + * @param fromQ 从第几圈开始加入
  1132 + * @param paramObj 参数对象
  1133 + * @param factory 工厂对象
  1134 + */
  1135 +InternalLpObj.prototype.initDataFromTime = function(
  1136 + startTime,
  1137 + isUp,
  1138 + fromQ,
  1139 + paramObj,
  1140 + factory) {
  1141 +
  1142 + var bcData = []; // 班次数组
  1143 + var bcObj;
  1144 + var kssj = startTime;
  1145 + var fcno = 1; // 发车顺序号
  1146 + var endTime = isUp ? paramObj.getUpLastDtimeObj() : paramObj.getDownLastDTimeObj(); // 结束时间
  1147 +
  1148 + while (!kssj.isAfter(endTime)) {
  1149 + bcObj = factory.createBcObj(
  1150 + this, "normal", isUp, fcno, kssj, paramObj); // this就是所属路牌对象
  1151 + bcData.push(bcObj);
  1152 +
  1153 + kssj = paramObj.addMinute(kssj, bcObj.getBcTime() + bcObj.getStopTime());
  1154 + fcno ++;
  1155 + isUp = !isUp;
  1156 + endTime = isUp ? paramObj.getUpLastDtimeObj() : paramObj.getDownLastDTimeObj(); // 结束时间
  1157 + }
  1158 +
  1159 + this._initDataFromLbBcArray(bcData, fromQ);
1023 1160
1024 }; 1161 };
1025 1162
  1163 +/**
  1164 + * 修正停站时间(不修改发车时间)。
  1165 + */
  1166 +InternalLpObj.prototype.modifyLayoverTimeWithoutFcTime = function() {
  1167 + var i;
  1168 + var aBc = this.getBcArray();
  1169 + var oBc;
  1170 + var oNextBc;
  1171 + var iDiff;
  1172 + for (i = 0; i < aBc.length; i++) {
  1173 + oBc = aBc[i];
  1174 + if (i == aBc.length - 1) { // 最后一个班次,停站0
  1175 + oBc.setStopTime(0);
  1176 + } else {
  1177 + oNextBc = aBc[i + 1];
  1178 + iDiff = oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m");
  1179 + if (oNextBc.fnGetEatTime() > 0) {
  1180 + oBc.setStopTime(iDiff - oNextBc.fnGetEatTime());
  1181 + } else if (iDiff > 120) { // 大于60分钟,肯定车次链结束班次,停站0
  1182 + oBc.setStopTime(0);
  1183 + } else {
  1184 + oBc.setStopTime(iDiff);
  1185 + }
  1186 + }
  1187 + }
  1188 +};
  1189 +
  1190 +/**
  1191 + * 判定班型班次。
  1192 + * 主要判定是否需要添加班次(5休2,连班,其他分班班型)。
  1193 + * @param oInternalSchedule 行车计划对象
  1194 + * @param oParam 参数对象
  1195 + * @param oPreLpBc 上一个班次
  1196 + * @param iPreLpIndex 上一个班次路牌索引
  1197 + * @param iCurrentLpIndex 当前路牌索引
  1198 + * @param iCurrentGroupIndex 当前圈索引
  1199 + * @param iCurrentBcIndex 当前班次索引
  1200 + */
  1201 +InternalLpObj.prototype.fnDecideBxBc = function(
  1202 + oInternalSchedule, oParam,
  1203 + oPreLpBc, iPreLpIndex,
  1204 + iCurrentLpIndex, iCurrentGroupIndex, iCurrentBcIndex) {
  1205 +
  1206 + // 使用策略函数方式
  1207 + return StrategyUtils_v2_2.sFn("MODIFY_TRIP")(
  1208 + oInternalSchedule, oParam,
  1209 + oPreLpBc, iPreLpIndex,
  1210 + iCurrentLpIndex, iCurrentGroupIndex, iCurrentBcIndex
  1211 + );
  1212 +
  1213 +};
  1214 +
  1215 +
  1216 +// TODO
  1217 +InternalLpObj.prototype.calcuLpBx = function() {
  1218 +
  1219 +};
1026 1220
src/main/resources/static/pages/base/timesmodel/js/v2/main_v2.js
@@ -783,6 +783,10 @@ var Main_v2 = function() { @@ -783,6 +783,10 @@ var Main_v2 = function() {
783 }; 783 };
784 784
785 return { 785 return {
  786 + setParam: function(paramObj) {
  787 + // 参数对象
  788 + _paramObj = paramObj;
  789 + },
786 /** 790 /**
787 * 工厂对象,创建不同的对象。 791 * 工厂对象,创建不同的对象。
788 * @returns {{createParameterObj, createBcObj}} 792 * @returns {{createParameterObj, createBcObj}}
@@ -1004,4 +1008,3 @@ var Main_v2 = function() { @@ -1004,4 +1008,3 @@ var Main_v2 = function() {
1004 1008
1005 }(); 1009 }();
1006 1010
1007 -  
src/main/resources/static/pages/base/timesmodel/js/v2_2/InternalScheduleObj.js 0 → 100644
  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;
  1460 +}());
0 \ No newline at end of file 1461 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/main_v2_2.js 0 → 100644
  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 aInternalLpObj 内部路牌对象列表
  66 + */
  67 + exportDataConfig: function(aInternalLpObj) {
  68 + $('.exportAddXls').off('click');
  69 + $('.exportAddXlsx').off('click');
  70 +
  71 + $('.exportAddXls').on('click', function() {
  72 + var aInfos = {
  73 + "lpObjList": Main_v2_2_excel[0](aInternalLpObj, _paramObj), // 路牌班次信息列表
  74 + "statInfoList": Main_v2_2_excel[1](aInternalLpObj, _paramObj), // 统计项目列表
  75 + "parameterInfoList" : Main_v2_2_excel[2](_paramObj) // 参数对象
  76 + };
  77 +
  78 + console.log(aInfos);
  79 +
  80 + $(".exportAdd").addClass("disabled");
  81 + $(".exportAddSpan").html("正在导出...");
  82 +
  83 + // 提交
  84 + $.ajax({
  85 + type: 'POST',
  86 + url: "/tidc/exportDTDFile/xls",
  87 + dataType: 'binary',
  88 + contentType: "application/json",
  89 + data: JSON.stringify(aInfos),
  90 + success: function(data){
  91 + Main_v2.downloadFile(data, "application/octet-stream", "时刻表信息.xls");
  92 +
  93 + $(".exportAdd").removeClass("disabled");
  94 + $(".exportAddSpan").html(" 导出数据");
  95 + },
  96 + error: function(xhr, type){
  97 + alert('错误:TODO');
  98 +
  99 + $(".exportAdd").removeClass("disabled");
  100 + $(".exportAddSpan").html(" 导出数据");
  101 + }
  102 + });
  103 + });
  104 +
  105 + $('.exportAddXlsx').on('click', function() {
  106 + var aInfos = {
  107 + "lpObjList": _funCalcuExportData_lpObjList(aInternalLpObj), // 路牌班次信息列表
  108 + "statInfoList": _funCalcuExportData_statInfoList(aInternalLpObj), // 统计项目列表
  109 + "parameterInfoList" : __funCalcuExportData_paramInfoList() // 参数对象
  110 + };
  111 +
  112 + console.log(aInfos);
  113 +
  114 + $(".exportAdd").addClass("disabled");
  115 + $(".exportAddSpan").html("正在导出...");
  116 +
  117 + // 提交
  118 + $.ajax({
  119 + type: 'POST',
  120 + url: "/tidc/exportDTDFile/xlsx",
  121 + dataType: 'binary',
  122 + contentType: "application/json",
  123 + data: JSON.stringify(aInfos),
  124 + success: function(data){
  125 + Main_v2.downloadFile(data, "application/octet-stream", "时刻表信息.xlsx");
  126 +
  127 + $(".exportAdd").removeClass("disabled");
  128 + $(".exportAddSpan").html(" 导出数据");
  129 + },
  130 + error: function(xhr, type){
  131 + alert('错误:TODO');
  132 +
  133 + $(".exportAdd").removeClass("disabled");
  134 + $(".exportAddSpan").html(" 导出数据");
  135 + }
  136 + });
  137 + });
  138 + },
  139 +
  140 + downloadFile: function (data, mimeType, fileName) {
  141 + var success = false;
  142 + var blob = new Blob([data], { type: mimeType });
  143 + try {
  144 + if (navigator.msSaveBlob)
  145 + navigator.msSaveBlob(blob, fileName);
  146 + else {
  147 + // Try using other saveBlob implementations, if available
  148 + var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;
  149 + if (saveBlob === undefined) throw "Not supported";
  150 + saveBlob(blob, fileName);
  151 + }
  152 + success = true;
  153 + } catch (ex) {
  154 + console.log("saveBlob method failed with the following exception:");
  155 + console.log(ex);
  156 + }
  157 +
  158 + if (!success) {
  159 + // Get the blob url creator
  160 + var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
  161 + if (urlCreator) {
  162 + // Try to use a download link
  163 + var link = document.createElement('a');
  164 + if ('download' in link) {
  165 + // Try to simulate a click
  166 + try {
  167 + // Prepare a blob URL
  168 + var url = urlCreator.createObjectURL(blob);
  169 + link.setAttribute('href', url);
  170 +
  171 + // Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
  172 + link.setAttribute("download", fileName);
  173 +
  174 + // Simulate clicking the download link
  175 + var event = document.createEvent('MouseEvents');
  176 + event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
  177 + link.dispatchEvent(event);
  178 + success = true;
  179 +
  180 + } catch (ex) {
  181 + console.log("Download link method with simulated click failed with the following exception:");
  182 + console.log(ex);
  183 + }
  184 + }
  185 +
  186 + if (!success) {
  187 + // Fallback to window.location method
  188 + try {
  189 + // Prepare a blob URL
  190 + // Use application/octet-stream when using window.location to force download
  191 + var url = urlCreator.createObjectURL(blob);
  192 + window.location = url;
  193 + console.log("Download link method with window.location succeeded");
  194 + success = true;
  195 + } catch (ex) {
  196 + console.log("Download link method with window.location failed with the following exception:");
  197 + console.log(ex);
  198 + }
  199 + }
  200 + }
  201 + }
  202 +
  203 + if (!success) {
  204 + // Fallback to window.open method
  205 + console.log("No methods worked for saving the arraybuffer, using last resort window.open");
  206 + window.open("", '_blank', '');
  207 + }
  208 + }
  209 + }
  210 +}();
0 \ No newline at end of file 211 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/main_v2_2_excel.js 0 → 100644
  1 +/**
  2 + * 主类(v2_2版本)excel导出功能类。
  3 + * // TODO:
  4 + */
  5 +var Main_v2_2_excel = (function() {
  6 + // TODO:后面慢慢改
  7 +
  8 + var _factory = { // TODO:以后移走
  9 + // 创建班次对象
  10 + createBcObj: function(lpObj, bcType, isUp, fcno, fcTimeObj, paramObj) {
  11 + var _bclc = paramObj.calcuTravelLcNumber(isUp, bcType);
  12 + var _fcsj = fcTimeObj;
  13 + var _bcsj = paramObj.calcuTravelTime(_fcsj, isUp);
  14 + var _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  15 + var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, _bcsj);
  16 + var _tccid = paramObj.getTTinfoId();
  17 + var _ttinfoid = paramObj.getTTinfoId();
  18 + var _xl = paramObj.getXlId();
  19 + var _qdz = isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;
  20 + var _zdz = isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;
  21 +
  22 + if (bcType == "bd") { // 早例保,传过来的发车时间是第一个班次的发车时间
  23 + if (isUp) { // 上行
  24 + _fcsj = paramObj.addMinute(
  25 + _fcsj,
  26 + -(paramObj.getUpOutTime() + paramObj.getLbTime()));
  27 + _bcsj = paramObj.getLbTime();
  28 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  29 + _stoptime = 0;
  30 + } else { // 下行
  31 + _fcsj = paramObj.addMinute(
  32 + _fcsj,
  33 + -(paramObj.getDownOutTime() + paramObj.getLbTime()));
  34 + _bcsj = paramObj.getLbTime();
  35 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  36 + _stoptime = 0;
  37 + }
  38 + } else if (bcType == "lc") { // 晚例保,传过来的发车时间是最后一个班次的到达时间
  39 + if (isUp) { // 上行
  40 + _fcsj = paramObj.addMinute(
  41 + _fcsj,
  42 + paramObj.getUpInTime());
  43 + _bcsj = paramObj.getLbTime();
  44 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  45 + _stoptime = 0;
  46 + } else { // 下行
  47 + _fcsj = paramObj.addMinute(
  48 + _fcsj,
  49 + paramObj.getDownInTime());
  50 + _bcsj = paramObj.getLbTime();
  51 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  52 + _stoptime = 0;
  53 + }
  54 + } else if (bcType == "out") { // 出场,传过来的发车时间是第一个班次的发车时间
  55 + if (isUp) { // 上行
  56 + _fcsj = paramObj.addMinute(
  57 + _fcsj,
  58 + -paramObj.getUpOutTime());
  59 + _bcsj = paramObj.getUpOutTime();
  60 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  61 + _stoptime = 0;
  62 + } else { // 下行
  63 + _fcsj = paramObj.addMinute(
  64 + _fcsj,
  65 + -paramObj.getDownOutTime());
  66 + _bcsj = paramObj.getDownOutTime();
  67 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  68 + _stoptime = 0;
  69 + }
  70 + } else if (bcType == "in") { // 进场,传过来的发车时间是最后一个班次的到达时间
  71 + if (isUp) { // 上行
  72 + _bcsj = paramObj.getUpInTime();
  73 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  74 + _stoptime = 0;
  75 + } else { // 下行
  76 + _bcsj = paramObj.getDownInTime();
  77 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  78 + _stoptime = 0;
  79 + }
  80 + } else if (bcType == "cf") { // 吃饭班次
  81 + // 以13:00为分界,之前的为午饭,之后的为晚饭
  82 + if (fcTimeObj.isBefore(paramObj.toTimeObj("13:00"))) {
  83 + _bcsj = paramObj.fnGetLunchTime();
  84 + } else {
  85 + _bcsj = paramObj.fnGetDinnerTime();
  86 + }
  87 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  88 + _stoptime = 0;
  89 + }
  90 +
  91 + var bcParamObj = {};
  92 + bcParamObj.bcType = bcType; // 班次类型(normal,in_,out, bd, lc, cf等)
  93 + bcParamObj.isUp = isUp; // boolean是否上下行
  94 + bcParamObj.fcno = fcno; // 发车顺序号
  95 + bcParamObj.fcTimeObj = _fcsj; // 发车时间对象
  96 + bcParamObj.bclc = _bclc; // 班次里程
  97 + bcParamObj.bcsj = _bcsj; // 班次历时
  98 + bcParamObj.arrtime = _arrsj; // 到达时间对象
  99 + bcParamObj.stoptime = _stoptime; // 停站时间
  100 + bcParamObj.tccid = _tccid; // 停车场id
  101 + bcParamObj.ttinfoid = _ttinfoid; // 时刻表id
  102 + bcParamObj.xl = _xl; // 线路id
  103 + bcParamObj.qdzid = _qdz; // 起点站id
  104 + bcParamObj.zdzid = _zdz; // 终点站id
  105 +
  106 + return new InternalBcObj(lpObj, bcParamObj);
  107 + }
  108 + };
  109 +
  110 + var _funCalcuExportData_lpObjList = function(aInternalLpObj, _paramObj) {
  111 + // 构造路牌对象
  112 + var aLpObj = [];
  113 + var i;
  114 + var j;
  115 + var z;
  116 + var oInternalLp;
  117 + var oInternalBc;
  118 + var oInternalBc_temp;
  119 + var oLp;
  120 + var iZlc;
  121 + var iYylc;
  122 + var iKslc;
  123 + var iZbc;
  124 + var iZgs;
  125 + var iYygs;
  126 + var iYybc;
  127 + for (i = 0; i < aInternalLpObj.length; i++) {
  128 + oInternalLp = aInternalLpObj[i];
  129 + iZlc = 0;
  130 + iYylc = 0;
  131 + iKslc = 0;
  132 + iZgs = 0;
  133 + iZbc = 0;
  134 + iYygs = 0;
  135 + iYybc = 0;
  136 + oLp = {
  137 + "lpname": oInternalLp.getLpName(), // 路牌名字
  138 + "isUp": oInternalLp.isUp(), // 每圈的第一个班次是否上行
  139 + "bcObjList": [], // 班次列表
  140 + "groupCount": oInternalLp.fnGetGroupCount(), // 总圈数
  141 + "zlc": 0, // 总里程
  142 + "yylc": 0, // 营运里程
  143 + "kslc": 0, // 空驶里程
  144 + "zgs": 0, // 总工时
  145 + "zbc": 0, // 总班次
  146 + "yygs": 0, // 营运工时
  147 + "yybc": 0, // 营运班次
  148 + "stationRouteId1": 0, // 第一个班次起点站路由id
  149 + "stationRouteId2": 0 // 第二个班次起点站路由id
  150 + };
  151 +
  152 + // 将报到班次,进出场班次加到班次的时间上
  153 + var iBcChainCount;
  154 + var oStartBc;
  155 + var oEndBc;
  156 + var oTempBc;
  157 + var aFcsj = [];
  158 +
  159 + iBcChainCount = oInternalLp.fnGetBcChainCount();
  160 + if (iBcChainCount == 1) { // 单一车次链,连班班型
  161 + oStartBc = oInternalLp.getBc(
  162 + oInternalLp.fnGetBcChainInfo(0)["s_q"],
  163 + oInternalLp.fnGetBcChainInfo(0)["s_b"]
  164 + );
  165 + oTempBc = _factory.createBcObj(
  166 + oLp, "bd", oStartBc.isUp(), 1,
  167 + oStartBc.getFcTimeObj(),
  168 + _paramObj
  169 + );
  170 + aFcsj.push("(到" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  171 + oLp.bcObjList.push({ // 报到班次
  172 + "bcsj": oTempBc.getBcTime(), // 班次时间
  173 + "ssj": oTempBc.getStopTime(), // 停站时间
  174 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  175 +
  176 + "tccid": oTempBc._$_tccid, // 停车场id
  177 + "qdzid": oTempBc._$_qdzid, // 起点站id
  178 + "zdzid": oTempBc._$_zdzid, // 终点站id
  179 +
  180 + "isUp": oTempBc._$_isUp, // 是否上行
  181 + "isFb": false, // 是否分班
  182 +
  183 + "bcType": oTempBc._$_bcType, // 班次类型
  184 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  185 +
  186 + "groupNo": -1, // 第几圈
  187 + "groupBcNo": -1 // 圈里第几个班次
  188 +
  189 + });
  190 +
  191 + oTempBc = _factory.createBcObj(
  192 + oLp, "out", oStartBc.isUp(), 1,
  193 + oStartBc.getFcTimeObj(),
  194 + _paramObj
  195 + );
  196 + aFcsj.push("(出" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  197 + aFcsj.push("(" + oStartBc.getFcTimeObj().format("HH:mm") + ")");
  198 + oStartBc._$_fcsj_desc = aFcsj.join("");
  199 +
  200 + oLp.bcObjList.push({ // 出场班次
  201 + "bcsj": oTempBc.getBcTime(), // 班次时间
  202 + "ssj": oTempBc.getStopTime(), // 停站时间
  203 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  204 +
  205 + "tccid": oTempBc._$_tccid, // 停车场id
  206 + "qdzid": oTempBc._$_qdzid, // 起点站id
  207 + "zdzid": oTempBc._$_zdzid, // 终点站id
  208 +
  209 + "isUp": oTempBc._$_isUp, // 是否上行
  210 + "isFb": false, // 是否分班
  211 +
  212 + "bcType": oTempBc._$_bcType, // 班次类型
  213 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  214 +
  215 + "groupNo": -1, // 第几圈
  216 + "groupBcNo": -2 // 圈里第几个班次
  217 +
  218 + });
  219 +
  220 + aFcsj = [];
  221 +
  222 + oEndBc = oInternalLp.getBc(
  223 + oInternalLp.fnGetBcChainInfo(0)["e_q"],
  224 + oInternalLp.fnGetBcChainInfo(0)["e_b"]
  225 + );
  226 + aFcsj.push("(" + oEndBc.getFcTimeObj().format("HH:mm") + ")");
  227 + oTempBc = _factory.createBcObj(
  228 + oLp, "in", !oEndBc.isUp(), 1,
  229 + oEndBc.getArrTimeObj(),
  230 + _paramObj
  231 + );
  232 + aFcsj.push("(进" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  233 +
  234 + oLp.bcObjList.push({ // 进场班次
  235 + "bcsj": oTempBc.getBcTime(), // 班次时间
  236 + "ssj": oTempBc.getStopTime(), // 停站时间
  237 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  238 +
  239 + "tccid": oTempBc._$_tccid, // 停车场id
  240 + "qdzid": oTempBc._$_qdzid, // 起点站id
  241 + "zdzid": oTempBc._$_zdzid, // 终点站id
  242 +
  243 + "isUp": oTempBc._$_isUp, // 是否上行
  244 + "isFb": false, // 是否分班
  245 +
  246 + "bcType": oTempBc._$_bcType, // 班次类型
  247 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  248 +
  249 + "groupNo": oInternalLp.fnGetBcChainInfo(0)["e_b"] == 0 ?
  250 + oInternalLp.fnGetBcChainInfo(0)["e_q"] :
  251 + oInternalLp.fnGetBcChainInfo(0)["e_q"] + 1, // 第几圈
  252 + "groupBcNo": oInternalLp.fnGetBcChainInfo(0)["e_b"] == 0 ? 1 : 0 // 圈里第几个班次
  253 +
  254 + });
  255 +
  256 + oTempBc = _factory.createBcObj(
  257 + oLp, "lc", !oEndBc.isUp(), 1,
  258 + oEndBc.getArrTimeObj(),
  259 + _paramObj
  260 + );
  261 + aFcsj.push("(离" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  262 + oLp.bcObjList.push({ // 离场班次
  263 + "bcsj": oTempBc.getBcTime(), // 班次时间
  264 + "ssj": oTempBc.getStopTime(), // 停站时间
  265 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  266 +
  267 + "tccid": oTempBc._$_tccid, // 停车场id
  268 + "qdzid": oTempBc._$_qdzid, // 起点站id
  269 + "zdzid": oTempBc._$_zdzid, // 终点站id
  270 +
  271 + "isUp": oTempBc._$_isUp, // 是否上行
  272 + "isFb": false, // 是否分班
  273 +
  274 + "bcType": oTempBc._$_bcType, // 班次类型
  275 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  276 +
  277 + "groupNo": -2, // 第几圈
  278 + "groupBcNo": -4 // 圈里第几个班次
  279 +
  280 + });
  281 +
  282 + oEndBc._$_fcsj_desc = aFcsj.join("");
  283 +
  284 + } else if (iBcChainCount == 2) { // 两个车次链,分班班型
  285 + oStartBc = oInternalLp.getBc(
  286 + oInternalLp.fnGetBcChainInfo(0)["s_q"],
  287 + oInternalLp.fnGetBcChainInfo(0)["s_b"]
  288 + );
  289 + oTempBc = _factory.createBcObj(
  290 + oLp, "bd", oStartBc.isUp(), 1,
  291 + oStartBc.getFcTimeObj(),
  292 + _paramObj
  293 + );
  294 + aFcsj.push("(到" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  295 + oLp.bcObjList.push({ // 报到班次
  296 + "bcsj": oTempBc.getBcTime(), // 班次时间
  297 + "ssj": oTempBc.getStopTime(), // 停站时间
  298 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  299 +
  300 + "tccid": oTempBc._$_tccid, // 停车场id
  301 + "qdzid": oTempBc._$_qdzid, // 起点站id
  302 + "zdzid": oTempBc._$_zdzid, // 终点站id
  303 +
  304 + "isUp": oTempBc._$_isUp, // 是否上行
  305 + "isFb": false, // 是否分班
  306 +
  307 + "bcType": oTempBc._$_bcType, // 班次类型
  308 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  309 +
  310 + "groupNo": -1, // 第几圈
  311 + "groupBcNo": -1 // 圈里第几个班次
  312 +
  313 + });
  314 +
  315 + oTempBc = _factory.createBcObj(
  316 + oLp, "out", oStartBc.isUp(), 1,
  317 + oStartBc.getFcTimeObj(),
  318 + _paramObj
  319 + );
  320 + aFcsj.push("(出" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  321 + aFcsj.push("(" + oStartBc.getFcTimeObj().format("HH:mm") + ")");
  322 + oStartBc._$_fcsj_desc = aFcsj.join("");
  323 +
  324 + oLp.bcObjList.push({ // 出场班次
  325 + "bcsj": oTempBc.getBcTime(), // 班次时间
  326 + "ssj": oTempBc.getStopTime(), // 停站时间
  327 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  328 +
  329 + "tccid": oTempBc._$_tccid, // 停车场id
  330 + "qdzid": oTempBc._$_qdzid, // 起点站id
  331 + "zdzid": oTempBc._$_zdzid, // 终点站id
  332 +
  333 + "isUp": oTempBc._$_isUp, // 是否上行
  334 + "isFb": false, // 是否分班
  335 +
  336 + "bcType": oTempBc._$_bcType, // 班次类型
  337 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  338 +
  339 + "groupNo": -1, // 第几圈
  340 + "groupBcNo": -2 // 圈里第几个班次
  341 +
  342 + });
  343 +
  344 + aFcsj = [];
  345 +
  346 + oEndBc = oInternalLp.getBc(
  347 + oInternalLp.fnGetBcChainInfo(0)["e_q"],
  348 + oInternalLp.fnGetBcChainInfo(0)["e_b"]
  349 + );
  350 + aFcsj.push("(" + oEndBc.getFcTimeObj().format("HH:mm") + ")");
  351 + oTempBc = _factory.createBcObj(
  352 + oLp, "in", !oEndBc.isUp(), 1,
  353 + oEndBc.getArrTimeObj(),
  354 + _paramObj
  355 + );
  356 + aFcsj.push("(进" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  357 + oLp.bcObjList.push({ // 进场班次
  358 + "bcsj": oTempBc.getBcTime(), // 班次时间
  359 + "ssj": oTempBc.getStopTime(), // 停站时间
  360 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  361 +
  362 + "tccid": oTempBc._$_tccid, // 停车场id
  363 + "qdzid": oTempBc._$_qdzid, // 起点站id
  364 + "zdzid": oTempBc._$_zdzid, // 终点站id
  365 +
  366 + "isUp": oTempBc._$_isUp, // 是否上行
  367 + "isFb": true, // 是否分班
  368 +
  369 + "bcType": oTempBc._$_bcType, // 班次类型
  370 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  371 +
  372 + "groupNo": oInternalLp.fnGetBcChainInfo(0)["e_b"] == 0 ?
  373 + oInternalLp.fnGetBcChainInfo(0)["e_q"] :
  374 + oInternalLp.fnGetBcChainInfo(0)["e_q"] + 1, // 第几圈
  375 + "groupBcNo": oInternalLp.fnGetBcChainInfo(0)["e_b"] == 0 ? 1 : 0 // 圈里第几个班次
  376 +
  377 + });
  378 + oEndBc._$_fcsj_desc = aFcsj.join("");
  379 +
  380 + aFcsj = [];
  381 +
  382 + oStartBc = oInternalLp.getBc(
  383 + oInternalLp.fnGetBcChainInfo(1)["s_q"],
  384 + oInternalLp.fnGetBcChainInfo(1)["s_b"]
  385 + );
  386 + oTempBc = _factory.createBcObj(
  387 + oLp, "bd", oStartBc.isUp(), 1,
  388 + oStartBc.getFcTimeObj(),
  389 + _paramObj
  390 + );
  391 + aFcsj.push("(到" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  392 + oLp.bcObjList.push({ // 报到班次
  393 + "bcsj": oTempBc.getBcTime(), // 班次时间
  394 + "ssj": oTempBc.getStopTime(), // 停站时间
  395 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  396 +
  397 + "tccid": oTempBc._$_tccid, // 停车场id
  398 + "qdzid": oTempBc._$_qdzid, // 起点站id
  399 + "zdzid": oTempBc._$_zdzid, // 终点站id
  400 +
  401 + "isUp": oTempBc._$_isUp, // 是否上行
  402 + "isFb": true, // 是否分班
  403 +
  404 + "bcType": oTempBc._$_bcType, // 班次类型
  405 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  406 +
  407 + "groupNo": oInternalLp.fnGetBcChainInfo(1)["s_q"] - 1, // 第几圈
  408 + "groupBcNo": oInternalLp.fnGetBcChainInfo(1)["s_b"] // 圈里第几个班次
  409 +
  410 + });
  411 +
  412 + oTempBc = _factory.createBcObj(
  413 + oLp, "out", oStartBc.isUp(), 1,
  414 + oStartBc.getFcTimeObj(),
  415 + _paramObj
  416 + );
  417 + oLp.bcObjList.push({ // 出场班次
  418 + "bcsj": oTempBc.getBcTime(), // 班次时间
  419 + "ssj": oTempBc.getStopTime(), // 停站时间
  420 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  421 +
  422 + "tccid": oTempBc._$_tccid, // 停车场id
  423 + "qdzid": oTempBc._$_qdzid, // 起点站id
  424 + "zdzid": oTempBc._$_zdzid, // 终点站id
  425 +
  426 + "isUp": oTempBc._$_isUp, // 是否上行
  427 + "isFb": true, // 是否分班
  428 +
  429 + "bcType": oTempBc._$_bcType, // 班次类型
  430 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  431 +
  432 + "groupNo": oInternalLp.fnGetBcChainInfo(1)["s_b"] == 0 ?
  433 + oInternalLp.fnGetBcChainInfo(1)["s_q"] - 1 :
  434 + oInternalLp.fnGetBcChainInfo(1)["s_q"], // 第几圈
  435 + "groupBcNo": oInternalLp.fnGetBcChainInfo(1)["s_b"] == 0 ? 1 : 0 // 圈里第几个班次
  436 +
  437 + });
  438 + aFcsj.push("(出" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  439 + aFcsj.push("(" + oStartBc.getFcTimeObj().format("HH:mm") + ")");
  440 + oStartBc._$_fcsj_desc = aFcsj.join("");
  441 +
  442 + aFcsj = [];
  443 +
  444 + oEndBc = oInternalLp.getBc(
  445 + oInternalLp.fnGetBcChainInfo(1)["e_q"],
  446 + oInternalLp.fnGetBcChainInfo(1)["e_b"]
  447 + );
  448 + aFcsj.push("(" + oEndBc.getFcTimeObj().format("HH:mm") + ")");
  449 + oTempBc = _factory.createBcObj(
  450 + oLp, "in", !oEndBc.isUp(), 1,
  451 + oEndBc.getArrTimeObj(),
  452 + _paramObj
  453 + );
  454 + aFcsj.push("(进" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  455 +
  456 + oLp.bcObjList.push({ // 进场班次
  457 + "bcsj": oTempBc.getBcTime(), // 班次时间
  458 + "ssj": oTempBc.getStopTime(), // 停站时间
  459 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  460 +
  461 + "tccid": oTempBc._$_tccid, // 停车场id
  462 + "qdzid": oTempBc._$_qdzid, // 起点站id
  463 + "zdzid": oTempBc._$_zdzid, // 终点站id
  464 +
  465 + "isUp": oTempBc._$_isUp, // 是否上行
  466 + "isFb": false, // 是否分班
  467 +
  468 + "bcType": oTempBc._$_bcType, // 班次类型
  469 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  470 +
  471 + "groupNo": oInternalLp.fnGetBcChainInfo(1)["e_b"] == 0 ?
  472 + oInternalLp.fnGetBcChainInfo(1)["e_q"] :
  473 + oInternalLp.fnGetBcChainInfo(1)["e_q"] + 1, // 第几圈
  474 + "groupBcNo": oInternalLp.fnGetBcChainInfo(1)["e_b"] == 0 ? 1 : 0 // 圈里第几个班次
  475 +
  476 + });
  477 +
  478 + oTempBc = _factory.createBcObj(
  479 + oLp, "lc", !oEndBc.isUp(), 1,
  480 + oEndBc.getArrTimeObj(),
  481 + _paramObj
  482 + );
  483 +
  484 + oLp.bcObjList.push({ // 离场班次
  485 + "bcsj": oTempBc.getBcTime(), // 班次时间
  486 + "ssj": oTempBc.getStopTime(), // 停站时间
  487 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  488 +
  489 + "tccid": oTempBc._$_tccid, // 停车场id
  490 + "qdzid": oTempBc._$_qdzid, // 起点站id
  491 + "zdzid": oTempBc._$_zdzid, // 终点站id
  492 +
  493 + "isUp": oTempBc._$_isUp, // 是否上行
  494 + "isFb": false, // 是否分班
  495 +
  496 + "bcType": oTempBc._$_bcType, // 班次类型
  497 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  498 +
  499 + "groupNo": -2, // 第几圈
  500 + "groupBcNo": -4 // 圈里第几个班次
  501 +
  502 + });
  503 +
  504 + aFcsj.push("(离" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  505 + oEndBc._$_fcsj_desc = aFcsj.join("");
  506 +
  507 + }
  508 +
  509 + for (j = 0; j < oInternalLp.fnGetGroupCount(); j++) {
  510 + for (z = 0; z < 2; z++) {
  511 + oInternalBc = oInternalLp.getBc(j, z);
  512 + if (oInternalBc) {
  513 + if (oInternalBc.fnGetEatTime() > 0) {
  514 + // 和v2版本不一样,有吃饭时间就是吃饭班次
  515 + oInternalBc._$_isRealEat = true;
  516 + oInternalBc._$_fcsj_desc = "(吃" + oInternalBc.getFcTimeObj().format("HH:mm") + ")";
  517 + }
  518 +
  519 + oLp.bcObjList.push({
  520 + "bcsj": oInternalBc.getBcTime(), // 班次时间
  521 + "ssj": oInternalBc.getStopTime(), // 停站时间
  522 + "eatsj": oInternalBc.fnGetEatTime(), // 吃饭时间
  523 +
  524 + "tccid": oInternalBc._$_tccid, // 停车场id
  525 + "qdzid": oInternalBc._$_qdzid, // 起点站id
  526 + "zdzid": oInternalBc._$_zdzid, // 终点站id
  527 +
  528 + "isUp": oInternalBc._$_isUp, // 是否上行
  529 +
  530 + "bcType": oInternalBc._$_bcType, // 班次类型
  531 + "fcsj": oInternalBc._$_isRealEat ?
  532 + ("*" + oInternalBc._$_fcsjObj.format("HH:mm")) :
  533 + oInternalBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  534 + "fcsjDesc" : oInternalBc._$_fcsj_desc || oInternalBc._$_fcsjObj.format("HH:mm"),
  535 +
  536 + "groupNo": j, // 第几圈
  537 + "groupBcNo": z // 圈里第几个班次
  538 +
  539 + });
  540 +
  541 + // iZlc = 0;
  542 + // iYylc = 0;
  543 + // iKslc = 0;
  544 + // iZgs = 0;
  545 + // iZbc = 0;
  546 + // iYygs = 0;
  547 + // iYybc = 0;
  548 +
  549 + iZlc = iZlc +
  550 + oInternalBc._$_bclc; // 里程
  551 + iYylc = iYylc +
  552 + oInternalBc._$_bclc; // 里程
  553 + iYygs = iYygs +
  554 + oInternalBc.getBcTime() + // 班次时间
  555 + oInternalBc.getStopTime() + // 停站时间
  556 + oInternalBc.fnGetEatTime(); // 吃饭时间
  557 + iYybc = iYybc + 1;
  558 +
  559 + iZgs = iZgs +
  560 + oInternalBc.getBcTime() + // 班次时间
  561 + oInternalBc.getStopTime() + // 停站时间
  562 + oInternalBc.fnGetEatTime(); // 吃饭时间
  563 + iZbc = iZbc + 1;
  564 +
  565 + // 设置圈站点路由id
  566 + if (oInternalBc.isUp() == oInternalLp.isUp()) { // 第一个班次
  567 + if (oLp.stationRouteId1 == 0) {
  568 + oLp.stationRouteId1 = oInternalBc._$_qdzid;
  569 + }
  570 + } else { // 第二个班次
  571 + if (oLp.stationRouteId2 == 0) {
  572 + oLp.stationRouteId2 = oInternalBc._$_qdzid;
  573 + }
  574 + }
  575 +
  576 + }
  577 + }
  578 +
  579 + }
  580 +
  581 + for (z = 0; z < oInternalLp.getOtherBcArray().length; z++) {
  582 + oInternalBc = oInternalLp.getOtherBcArray()[z];
  583 + iKslc = iKslc +
  584 + oInternalBc._$_bclc; // 里程
  585 + iZlc = iZlc +
  586 + oInternalBc._$_bclc; // 里程
  587 + iZgs = iZgs +
  588 + oInternalBc.getBcTime() + // 班次时间
  589 + oInternalBc.getStopTime(); // 停站时间
  590 + if (oInternalBc._$_bcType != "bd" &&
  591 + oInternalBc._$_bcType != "lc" &&
  592 + oInternalBc._$_bcType != "cf") {
  593 + iZbc = iZbc + 1;
  594 + }
  595 + }
  596 +
  597 + oLp.zlc = iZlc;
  598 + oLp.yylc = iYylc;
  599 + oLp.kslc = iKslc;
  600 + oLp.zgs = iZgs;
  601 + oLp.zbc = iZbc;
  602 + oLp.yygs = iYygs;
  603 + oLp.yybc = iYybc;
  604 + aLpObj.push(oLp);
  605 + }
  606 +
  607 + return aLpObj;
  608 + };
  609 +
  610 + var _funCalcuExportData_statInfoList = function(aInternalLpObj, _paramObj) {
  611 + var countBc = 0, // 总班次
  612 + serviceBc = 0, // 营运班次
  613 + jcbc = 0, // 进场总班次.
  614 + ccbc = 0, // 出场总班次.
  615 + cfbc = 0, // 吃饭总班次.
  616 + zwlbbc = 0, // 早晚例保总班次.
  617 + countGs = 0.0, // 总工时
  618 + servicesj = 0, // 营运班次总时间
  619 + jcsj = 0.0, // 进场总时间.
  620 + ccsj = 0.0, // 出场总时间.
  621 + cfsj = 0.0, // 吃饭总时间.
  622 + zwlbsj = 0.0, // 早晚例保总时间.
  623 + ksBc = 0, // 空驶班次
  624 + serviceLc = 0.0, // 营运里程
  625 + ksLc = 0.0, // 空驶里程
  626 + avgTzjx = 0.0, // 平均停站间隙
  627 + gfServiceBc = 0, // 高峰营运班次
  628 + dgServiceBc = 0, // 低谷营运班次
  629 + gfAvgTzjx = 0.0, // 高峰平均停站间隙
  630 + dgAvgTzjx = 0.0; // 低谷平均停站间隙
  631 +
  632 + var aAllBc = [];
  633 + var oLp;
  634 + var oBc;
  635 + var i;
  636 + var j;
  637 +
  638 + for (i = 0; i < aInternalLpObj.length; i++) {
  639 + oLp = aInternalLpObj[i];
  640 + for (j = 0; j < oLp.getBcArray().length; j++) {
  641 + aAllBc.push(oLp.getBcArray()[j]);
  642 + }
  643 + for (j = 0; j < oLp.getOtherBcArray().length; j++) {
  644 + aAllBc.push(oLp.getOtherBcArray()[j]);
  645 + }
  646 + }
  647 +
  648 + for (i = 0; i < aAllBc.length; i++) {
  649 + oBc = aAllBc[i];
  650 +
  651 + if (oBc.getBcTime() > 0) {
  652 + countBc = countBc + 1;
  653 + countGs = countGs + oBc.getStopTime() + oBc.getBcTime();
  654 + if (_paramObj.isTroughBc(oBc.getFcTimeObj())) {
  655 + if (oBc._$_bcType == "normal") {
  656 + dgServiceBc = dgServiceBc + 1;
  657 + dgAvgTzjx = dgAvgTzjx + oBc.getStopTime();
  658 + }
  659 + } else {
  660 + if (oBc._$_bcType == "normal") {
  661 + gfServiceBc = gfServiceBc + 1;
  662 + gfAvgTzjx = gfAvgTzjx + oBc.getStopTime();
  663 + }
  664 + }
  665 +
  666 + if (oBc._$_bcType == "normal") {
  667 + serviceBc = serviceBc + 1;
  668 + serviceLc = serviceLc + oBc._$_bclc;
  669 + servicesj = servicesj + oBc.getBcTime();
  670 + avgTzjx = avgTzjx + oBc.getStopTime();
  671 +
  672 + if (oBc.fnGetEatTime() > 0) {
  673 + cfbc = cfbc + 1;
  674 + cfsj = cfsj + oBc.fnGetEatTime();
  675 + }
  676 + } else if (oBc._$_bcType == "in") {
  677 + jcbc = jcbc + 1;
  678 + jcsj = jcsj + oBc.getBcTime();
  679 + } else if (oBc._$_bcType == "out") {
  680 + ccbc = ccbc + 1;
  681 + ccsj = ccsj + oBc.getBcTime();
  682 + } else if (oBc._$_bcType == "bd") {
  683 + zwlbbc = zwlbbc + 1;
  684 + zwlbsj = zwlbsj + oBc.getBcTime();
  685 + } else if (oBc._$_bcType == "lc") {
  686 + zwlbbc = zwlbbc + 1;
  687 + zwlbsj = zwlbsj + oBc.getBcTime();
  688 + }
  689 + }
  690 + }
  691 +
  692 + dgAvgTzjx = dgAvgTzjx / dgServiceBc;
  693 + gfAvgTzjx = gfAvgTzjx / gfServiceBc;
  694 + avgTzjx = avgTzjx / dgServiceBc;
  695 +
  696 + return [
  697 + {'statItem': '总班次(包括进出场、吃饭时间、早晚例保、营运且班次时间大于零的班次)', 'statValue': countBc},
  698 + {'statItem': '进场总班次(包括进场且班次时间大于零的班次)', 'statValue': jcbc},
  699 + {'statItem': '出场总班次(包括进场且班次时间大于零的班次)', 'statValue': ccbc},
  700 + {'statItem': '吃饭总班次(包括吃饭且班次时间大于零的班次)', 'statValue': cfbc},
  701 + {'statItem': '早晚例保总班次(包括早晚例保且时间大于零的班次)', 'statValue': zwlbbc},
  702 + {'statItem': '营运总班次(包括正常、区间、放大站且班次时间大于零班次)','statValue': serviceBc},
  703 + {'statItem': '进场总时间(包括进场班次且班次时间大于零)', 'statValue': jcsj/60},
  704 + {'statItem': '出场总时间(包括进场班次且班次时间大于零)', 'statValue': ccsj/60},
  705 + {'statItem': '吃饭总时间(包括吃饭班次且班次时间大于零)', 'statValue': cfsj/60},
  706 + {'statItem': '早晚例保总时间(包括早晚例保班次且时间大于零的)', 'statValue': zwlbsj/60},
  707 + {'statItem': '营运班次总时间(包括正常、区间、放大站且班次时间大于零)', 'statValue': servicesj/60},
  708 + {'statItem': '总工时(包括进出场、吃饭时间、早晚例保、营运班次时间)', 'statValue': countGs/60},
  709 + {'statItem': '空驶班次(包括直放班次)', 'statValue': ksBc},
  710 + {'statItem': '营运里程(包括正常、区间、放大站里程)', 'statValue': serviceLc},
  711 + {'statItem': '空驶里程(包括直放里程)', 'statValue': ksLc},
  712 + {'statItem': '平均停站时间(营运班次停站时间总和/营运总班次)', 'statValue': avgTzjx},
  713 + {'statItem': '高峰营运班次(包括早晚高峰时段的正常、区间、放大站班次)', 'statValue': gfServiceBc},
  714 + {'statItem': '低谷营运班次(包括低谷时段的正常、区间、放大站班次)', 'statValue': dgServiceBc},
  715 + {'statItem': '高峰平均停站间隙(高峰营运班次停站时间总和/高峰营运班次总和)', 'statValue': gfAvgTzjx},
  716 + {'statItem': '低谷平均停站间隙(低谷营运班次停站时间总和/低谷营运班次总和)', 'statValue': dgAvgTzjx},
  717 + {'statItem': '综合评估', 'statValue': 3}
  718 + ];
  719 +
  720 + };
  721 +
  722 + var __funCalcuExportData_paramInfoList = function(_paramObj) {
  723 + return [
  724 + {'paramItem' : '上行首班时间', 'paramValue' : _paramObj.getUpFirstDTimeObj().format("HH:mm")},
  725 + {'paramItem' : '上行末班时间', 'paramValue' : _paramObj.getUpLastDtimeObj().format("HH:mm")},
  726 + {'paramItem' : '下行首班时间', 'paramValue' : _paramObj.getDownFirstDTimeObj().format("HH:mm")},
  727 + {'paramItem' : '下行末班时间', 'paramValue' : _paramObj.getDownLastDTimeObj().format("HH:mm")},
  728 + {'paramItem' : '早高峰开始时间', 'paramValue' : _paramObj.getMPeakStartTimeObj().format("HH:mm")},
  729 + {'paramItem' : '早高峰结束时间', 'paramValue' : _paramObj.getMPeakEndTimeObj().format("HH:mm")},
  730 + {'paramItem' : '晚高峰开始时间', 'paramValue' : _paramObj.getEPeakStartTimeObj().format("HH:mm")},
  731 + {'paramItem' : '晚高峰结束时间', 'paramValue' : _paramObj.getEPeakEndTimeObj().format("HH:mm")},
  732 + {'paramItem' : '上行进场时间', 'paramValue' : _paramObj.getUpInTime()},
  733 + {'paramItem' : '上行出场时间', 'paramValue' : _paramObj.getUpOutTime()},
  734 + {'paramItem' : '下行进场时间', 'paramValue' : _paramObj.getDownInTime()},
  735 + {'paramItem' : '下行出场时间', 'paramValue' : _paramObj.getDownOutTime()},
  736 + {'paramItem' : '早高峰上行时间', 'paramValue' : _paramObj.getUpMPeakTime()},
  737 + {'paramItem' : '早高峰下行时间', 'paramValue' : _paramObj.getDownMPeakTime()},
  738 + {'paramItem' : '晚高峰上行时间', 'paramValue' : _paramObj.getUpEPeakTime()},
  739 + {'paramItem' : '晚高峰下行时间', 'paramValue' : _paramObj.getDownEPeakTime()},
  740 + {'paramItem' : '低谷上行时间', 'paramValue' : _paramObj.getUpTroughTime()},
  741 + {'paramItem' : '低谷下行时间', 'paramValue' : _paramObj.getDownTroughTime()},
  742 + {'paramItem' : '线路规划类型', 'paramValue' : "双向"},
  743 + {'paramItem' : '吃饭地点', 'paramValue' : _paramObj.fnIsEat() ? (_paramObj.fnIsBothEat() ? "上下行" : (_paramObj.fnIsUpEat() ? "上行" : "下行")) : "不吃饭"},
  744 + {'paramItem' : '早晚例行保养', 'paramValue' : _paramObj.getLbTime()},
  745 + {'paramItem' : '停车场', 'paramValue' : _paramObj.getTccId()},
  746 + {'paramItem' : '工作餐午餐时间', 'paramValue' : _paramObj.fnGetLunchTime()},
  747 + {'paramItem' : '工作餐晚餐时间', 'paramValue' : _paramObj.fnGetDinnerTime()},
  748 + {'paramItem' : '早高峰发车间隔', 'paramValue' : "[" + _paramObj.getMPeakMinFcjx() + "," + _paramObj.getMPeakMaxFcjx() + "]"},
  749 + {'paramItem' : '晚高峰发车间隔', 'paramValue' : "[" + _paramObj.getEPeakMinFcjx() + "," + _paramObj.getEPeakMaxFcjx() + "]"},
  750 + {'paramItem' : '低谷发车间隔', 'paramValue' : "[" + _paramObj.getTroughMinFcjx() + "," + _paramObj.getTroughMaxFcjx() + "]"},
  751 + {'paramItem' : '建议加班路牌数', 'paramValue' : _paramObj.getJBLpes()},
  752 + {'paramItem' : '停站类型', 'paramValue' : _paramObj.isTwoWayStop() ? "双向停站" : (_paramObj.isUpOneWayStop() ? "上行主站" : "下行主站") },
  753 + {'paramItem' : '建议高峰配车数', 'paramValue' : _paramObj.getAdvicePeakClzs()}
  754 + ]
  755 + };
  756 +
  757 +
  758 +
  759 +
  760 + return [
  761 + _funCalcuExportData_lpObjList, // 返回路牌班次信息列表方法
  762 + _funCalcuExportData_statInfoList, // 返回统计项目列表方法
  763 + __funCalcuExportData_paramInfoList // 返回参数对象方法
  764 + ];
  765 +
  766 +} ());
0 \ No newline at end of file 767 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/StrategyUtils.js 0 → 100644
  1 +/**
  2 + * 策略工具类。
  3 + */
  4 +var StrategyUtils_v2_2 = (function() {
  5 + /**
  6 + * 内部策略配置封装类。
  7 + * @constructor
  8 + */
  9 + function InternalStrategy() {
  10 + // 策略函数对应,每个函数都由一个标识符号对应,类似配置函数
  11 + this._oSTRATIGIS = {
  12 + // 每种策略对应一个js文件,里面的变量名就是策略名
  13 + // MODIFY_TRIP 修改班次工时,v2_2版本中使用
  14 + "MODIFY_TRIP": ModifyBcTripWHS1,
  15 + // CALCU_HEADWAY 计算每一圈的发车间隔,v2_2版本中使用
  16 + "CALCU_HEADWAY": CalcuHeadwayS1,
  17 + // CALCU_HEADWAY_2 计算每一圈的发车间隔,v2_2版本中使用
  18 + "CALCU_HEADWAY_2": CalcuHeadwayS2,
  19 + // ADJUST_HEADWAY 调整班次间隔,停站不够,v2_2版本中使用
  20 + "ADJUST_HEADWAY": AdjustHeadwayS1,
  21 + // ADJUST_HEADWAY_2 调整班次间隔,停站太多,v2_2版本中使用
  22 + "ADJUST_HEADWAY_2": AdjustHeadwayS2,
  23 + // ADJUST_HEADWAY_3_EAT 调整班次间隔,吃饭时间不足调整,v2_2版本中使用
  24 + "ADJUST_HEADWAY_3_EAT": AdjustHeadwayS3_eat,
  25 + // CALCU_RUNTIME 计算行驶时间,v2_2版本中使用
  26 + "CALCU_RUNTIME": LinearRuntimeS1,
  27 + // CALCU_LAYOVER_TIME 计算停站时间,v2_2版本中使用
  28 + "CALCU_LAYOVER_TIME": LayoverTimeS1
  29 + };
  30 + }
  31 +
  32 + /**
  33 + * 返回策略函数
  34 + * @param str 标识
  35 + * @returns {function}
  36 + */
  37 + InternalStrategy.prototype.sFn = function(str) {
  38 + if (!this._oSTRATIGIS[str]) {
  39 + throw "指定标识" + str + "策略函数不存在!";
  40 + }
  41 + return this._oSTRATIGIS[str];
  42 + };
  43 + /**
  44 + * 替换策略配置
  45 + * @param str 策略函数标识
  46 + * @param fn 策略函数
  47 + */
  48 + InternalStrategy.prototype.sConfig = function(str, fn) {
  49 + this._oSTRATIGIS[str] = fn;
  50 + };
  51 +
  52 + return new InternalStrategy();
  53 +} ());
0 \ No newline at end of file 54 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/bc/DecideBcTripS1.js 0 → 100644
  1 +/**
  2 + * 判定路牌每圈是否出班次。
  3 + */
  4 +var DecideBcTripS1 = (function() {
  5 +
  6 + /**
  7 + * 判定班型班次,主方法。
  8 + * @param oInternalSchedule
  9 + * @param oParam
  10 + * @param oPreBc
  11 + * @param iPreLpIndex
  12 + * @param iCurrentLpIndex
  13 + * @param iCurrentGroupIndex
  14 + * @param iCurrentBcIndex
  15 + */
  16 + function main(
  17 + oInternalSchedule, oParam,
  18 + oPreBc, iPreLpIndex,
  19 + iCurrentLpIndex, iCurrentGroupIndex, iCurrentBcIndex) {
  20 +
  21 +
  22 + var oCurrentLp = oInternalSchedule.fnGetLpArray()[iCurrentLpIndex]; // 当前路牌
  23 + var oLpPreBc; // 当前路牌前一个班次
  24 +
  25 + var iBxBcount; // 分班班型的可能班次数
  26 +
  27 + if (oCurrentLp.isBxFb()) { // 分班
  28 + // 关联的因素
  29 + // 1、当前班次方向
  30 + // 2、上一个班次情况
  31 + // 3、同路牌前一个班次情况
  32 + // 4、分班路牌工时限制
  33 +
  34 +
  35 + if (oCurrentLp.isBxFb5_2()) { // 5休2分班
  36 + // 大致计算5休2班型班次数
  37 + iBxBcount = oInternalSchedule.fnGetBxDesc()[6].fBcCount;
  38 + if (iBxBcount - Math.floor(iBxBcount) > 0.7) {
  39 + iBxBcount = Math.floor(iBxBcount) + 1;
  40 + } else {
  41 + iBxBcount = Math.floor(iBxBcount);
  42 + }
  43 +
  44 + // 计算可能的5休2班次时间,供下一步判定
  45 + var oNext5_2_bc_fctime_m = undefined; // 上午车次链参考班次时间
  46 + var oNext5_2_bc_fctime_e = undefined; // 下午车次链参考班次时间
  47 + if (oPreBc.getFcTimeObj().isBefore(oParam.toTimeObj("12:00"))) { // 上午车次链
  48 + oNext5_2_bc_fctime_m = oParam.addMinute(
  49 + oPreBc.getFcTimeObj(),
  50 + Math.ceil((oParam.getMPeakMinFcjx() + oParam.getMPeakMaxFcjx()) / 2)
  51 + );
  52 + } else { // 下午车次链
  53 + oNext5_2_bc_fctime_e = oParam.addMinute(
  54 + oPreBc.getFcTimeObj(),
  55 + Math.ceil((oParam.getEPeakMinFcjx() + oParam.getEPeakMaxFcjx()) / 2)
  56 + );
  57 + }
  58 +
  59 + // 先处理上午车次链
  60 + if (oNext5_2_bc_fctime_m) {
  61 + if (oNext5_2_bc_fctime_m.isBefore(oParam.getMPeakStartTimeObj())) {
  62 + // 5休2班型第一个班次,如果在早高峰开始前低谷,不添加
  63 + return false;
  64 + } else if (!oNext5_2_bc_fctime_m.isAfter(oParam.getMPeakEndTimeObj())) {
  65 + // 早高峰期间,添加
  66 + return true;
  67 + } else {
  68 + // 早高峰之后低谷到12:00之间
  69 +
  70 + // 当前路牌的前一个班次
  71 + oLpPreBc = oCurrentLp.getBc(iCurrentBcIndex == 0 ?
  72 + iCurrentGroupIndex - 1 : iCurrentGroupIndex, iCurrentBcIndex == 0 ? 1 : 0);
  73 + if (oCurrentLp.getBcArray().length > 0 && (!oLpPreBc)) {
  74 + // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加
  75 + return false;
  76 + } else {
  77 + if (oCurrentLp.getBcArray().length < Math.ceil(iBxBcount / 2)) {
  78 + // 如果总班次数比iBxBcount的一半的班次(ceil)少,加班次
  79 + return true;
  80 + } else if (oLpPreBc.isUp() == oParam.isUpOneWayStop()) {
  81 + // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站
  82 + // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次
  83 + return true;
  84 + } else {
  85 + return false;
  86 + }
  87 + }
  88 + }
  89 + }
  90 +
  91 + // 再处理下午车次链
  92 + if (oNext5_2_bc_fctime_e) {
  93 + if (oNext5_2_bc_fctime_e.isBefore(oParam.getEPeakStartTimeObj())) {
  94 + if (oParam.isEPeakBc(oPreBc.getArrTimeObj())) {
  95 + // 如果上一个班次的到达时间在高峰内,也要加
  96 + return true;
  97 + }
  98 +
  99 + // 5休2班型第一个班次,如果在晚高峰开始前低谷,不添加
  100 + return false;
  101 + } else if (!oNext5_2_bc_fctime_e.isAfter(oParam.getEPeakEndTimeObj())) {
  102 + // 晚高峰期间,添加
  103 + return true;
  104 + } else {
  105 + // 晚高峰之后低谷
  106 +
  107 + // 当前路牌的前一个班次
  108 + oLpPreBc = oCurrentLp.getBc(iCurrentBcIndex == 0 ?
  109 + iCurrentGroupIndex - 1 : iCurrentGroupIndex, iCurrentBcIndex == 0 ? 1 : 0);
  110 + if (oCurrentLp.getBcArray().length > 0 && (!oLpPreBc)) {
  111 + // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加
  112 + return false;
  113 + } else {
  114 + if (oCurrentLp.getBcArray().length < iBxBcount) {
  115 + // 如果总班次数比iBxBcount少,加班次
  116 + return true;
  117 + } else if (oLpPreBc.isUp() == oParam.isUpOneWayStop()) {
  118 + // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站
  119 + // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次
  120 + return true;
  121 + } else {
  122 + return false;
  123 + }
  124 + }
  125 + }
  126 + }
  127 +
  128 + } else { // 其他分班
  129 + // TODO:根据上标线的首班时间确定班型,小于05:59的做一休一,否则做二休一
  130 + var oSt = oInternalSchedule.fnGetGroupIsUp() ?
  131 + oParam.getUpFirstDTimeObj() : oParam.getDownFirstDTimeObj();
  132 + var iBxIndex = 4;
  133 + if (oSt.isBefore(oParam.toTimeObj("05:59"))) {
  134 + iBxIndex = 5;
  135 + }
  136 + // 大致计算做其他班型所需的班次数
  137 + var iQBcount = oInternalSchedule.fnGetBxDesc()[iBxIndex].fQCount;
  138 + iBxBcount = Math.ceil(iQBcount) * 2;
  139 +
  140 + // 计算可能的其他分班当前班次时间,供下一步判定
  141 + var oNext_other_bc_fctime_m = undefined; // 上午车次链参考班次时间
  142 + var oNext_other_bc_fctime_e = undefined; // 下午车次链参考班次时间
  143 + if (oPreBc.getFcTimeObj().isBefore(oParam.toTimeObj("15:00"))) { // 上午车次链
  144 + oNext_other_bc_fctime_m = oParam.addMinute(
  145 + oPreBc.getFcTimeObj(),
  146 + Math.ceil((oParam.getMPeakMinFcjx() + oParam.getMPeakMaxFcjx()) / 2)
  147 + );
  148 + } else { // 下午车次链
  149 + oNext_other_bc_fctime_e = oParam.addMinute(
  150 + oPreBc.getFcTimeObj(),
  151 + Math.ceil((oParam.getEPeakMinFcjx() + oParam.getEPeakMaxFcjx()) / 2)
  152 + );
  153 + }
  154 +
  155 + // 先处理上午车次链
  156 + if (oNext_other_bc_fctime_m) {
  157 + // TODO:其他分班随连班上午开始就出车,具体出车时间可能还要和低谷周转时间一起考虑
  158 + // 当前路牌的前一个班次
  159 + oLpPreBc = oCurrentLp.getBc(iCurrentBcIndex == 0 ?
  160 + iCurrentGroupIndex - 1 : iCurrentGroupIndex, iCurrentBcIndex == 0 ? 1 : 0);
  161 + if (oCurrentLp.getBcArray().length == 0) {
  162 + return true;
  163 + } else if (!oLpPreBc) {
  164 + // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加
  165 + return false;
  166 + } else {
  167 + if (oCurrentLp.getBcArray().length < Math.ceil(iBxBcount / 2)) {
  168 + // 如果总班次数比iBxBcount的一半的班次(ceil)少,加班次
  169 + return true;
  170 + } else if (oLpPreBc.isUp() == oParam.isUpOneWayStop()) {
  171 + // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站
  172 + // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次
  173 + return true;
  174 + } else {
  175 + return false;
  176 + }
  177 + }
  178 +
  179 + }
  180 +
  181 + // 再处理下午车次链
  182 + if (oNext_other_bc_fctime_e) {
  183 + // TODO:下午14:00后开始添加,加入时间可能还要和低谷周转时间一起考虑
  184 + // 当前路牌的前一个班次
  185 + oLpPreBc = oCurrentLp.getBc(iCurrentBcIndex == 0 ?
  186 + iCurrentGroupIndex - 1 : iCurrentGroupIndex, iCurrentBcIndex == 0 ? 1 : 0);
  187 + if (oCurrentLp.getBcArrayFromTime(oParam.toTimeObj("15:00")).length == 0) {
  188 + return true;
  189 + } else if (!oLpPreBc) {
  190 + // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加
  191 + return false;
  192 + } else {
  193 + if (oCurrentLp.getBcArray().length < iBxBcount) {
  194 + // 如果总班次数比iBxBcount少,加班次
  195 + return true;
  196 + } else if (oParam.isEPeakBc(oNext_other_bc_fctime_e)) {
  197 + return true;
  198 + }
  199 + else if (oLpPreBc.isUp() == oParam.isUpOneWayStop()) {
  200 + // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站
  201 + // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次
  202 + return true;
  203 + } else {
  204 + return false;
  205 + }
  206 + }
  207 +
  208 + }
  209 +
  210 + }
  211 + } else { // 连班班型,高峰低谷都有班次
  212 + return true;
  213 + }
  214 +
  215 +
  216 + }
  217 +
  218 + return main;
  219 +} ());
0 \ No newline at end of file 220 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/headway/AdjustHeadwayS1.js 0 → 100644
  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;
  244 +} ());
0 \ No newline at end of file 245 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/headway/AdjustHeadwayS2.js 0 → 100644
  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;
  370 +} ());
0 \ No newline at end of file 371 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/headway/AdjustHeadwayS3_eat.js 0 → 100644
  1 +/**
  2 + * 调整待吃饭班次的发车间隔,从而调整停站时间满足吃饭时间。
  3 + * 1、因为是单向进场,所以班次一定在主站方向上
  4 + * 2、一般吃饭班次都是跨圈的,所以需要把指定方向上的所有班次组成数组参与判定
  5 + */
  6 +var AdjustHeadwayS3_eat = (function() {
  7 +
  8 + /**
  9 + * 获取班次列表。
  10 + * @param oInternalSchedule 行车计划
  11 + * @param oParam 参数对象
  12 + * @param isUp 是否上行
  13 + */
  14 + function _getBcList(oInternalSchedule, oParam, isUp) {
  15 + var aRtnBc = [];
  16 + var oRtnBc = {oBc: null, iBcIndex: -1, lpIndex: 0, groupIndex: 0, bcIndex: 0};
  17 +
  18 + var i;
  19 + var j;
  20 + var aLp = oInternalSchedule.fnGetLpArray();
  21 + var oLp;
  22 + var oBc;
  23 +
  24 + for (j = 0; j < oInternalSchedule._qCount; j++) {
  25 + for (i = 0; i < aLp.length; i++) {
  26 + oLp = aLp[i];
  27 + oBc = oLp.getBc(
  28 + j,
  29 + oInternalSchedule._qIsUp == isUp ? 0 : 1
  30 + );
  31 +
  32 + if (oBc) {
  33 + oRtnBc = {
  34 + "oBc": oBc,
  35 + "lpIndex": i,
  36 + "groupIndex": j,
  37 + "bcIndex": oInternalSchedule._qIsUp == isUp ? 0 : 1
  38 + };
  39 + oRtnBc.iBcIndex = aRtnBc.length;
  40 + aRtnBc.push(oRtnBc);
  41 + }
  42 + }
  43 + }
  44 +
  45 + return aRtnBc;
  46 + }
  47 +
  48 + /**
  49 + * 判定是否是吃饭班次,是否需要调整相关的时间。
  50 + * @param oRtnBc 内部班次对象
  51 + * @param aLp 路牌列表
  52 + */
  53 + function _isNeedModifyLayoverTime(oRtnBc, aLp) {
  54 + var oBc = oRtnBc.oBc; // 当前班次
  55 + var oLp = aLp[oRtnBc.lpIndex]; // 所在路牌
  56 + var oPreBc = oLp.getPreBc(oBc); // 所在路牌前一个相邻班次
  57 +
  58 + if (!oPreBc) { // 如果当前路牌没有之前的班次,不能吃饭,一般不可能的
  59 + return false;
  60 + }
  61 +
  62 + // 发车之前的停站时间(用于吃饭)
  63 + var recoverTime = oBc.getFcTimeObj().diff(oPreBc.getArrTimeObj(), 'm');
  64 + if (recoverTime < 20) { // 小于20分钟,需要调整
  65 + return true;
  66 + } else {
  67 + return false;
  68 + }
  69 +
  70 + }
  71 +
  72 + /**
  73 + * 调整班次发车时间(当前班次和紧领的下一个班次)
  74 + * @param oRtnBc 内部班次对象
  75 + * @param aLp 路牌列表
  76 + * @param iMinute 时间
  77 + * @private
  78 + */
  79 + function _modifyHeadway(oRtnBc, aLp, iMinute) {
  80 + var iBcGroupIndex = oRtnBc.groupIndex;
  81 + var iBcIndex = oRtnBc.bcIndex;
  82 + var oLp = aLp[oRtnBc.lpIndex];
  83 +
  84 + var oBc = oLp.getBc(iBcGroupIndex, iBcIndex);
  85 + var oNextBc = oLp.getBc(
  86 + iBcIndex == 1 ? iBcGroupIndex + 1 : iBcGroupIndex,
  87 + iBcIndex == 0 ? 1 : 0
  88 + );
  89 + if (oBc) {
  90 + oBc.addMinuteToFcsj(iMinute);
  91 + }
  92 + if (oNextBc) {
  93 + oNextBc.addMinuteToFcsj(iMinute);
  94 + }
  95 + }
  96 +
  97 + /**
  98 + * 从当前班次开始向上尝试加一分钟。
  99 + * @param oRtnBc 内部班次对象
  100 + * @param aRtnBc 内部班次列表
  101 + * @param aLp 路牌列表
  102 + * @param oParam 参数对象
  103 + * @private
  104 + */
  105 + function _headway_up(oRtnBc, aRtnBc, aLp, oParam) {
  106 + var i;
  107 +
  108 + // 当前班次与上一个班次之间的间隔列表
  109 + var aHeadWay = [];
  110 + var oHeadWay;
  111 + for (i = oRtnBc.iBcIndex; i > 0; i--) {
  112 + oHeadWay = {};
  113 + oHeadWay.iStartRtnBcIndex = (i - 1);
  114 + oHeadWay.iEndRtnBcIndex = i;
  115 + if (oParam.isMPeakBc(aRtnBc[i - 1].oBc.getFcTimeObj())) {
  116 + oHeadWay.bMPeakBc = true;
  117 + } else if (oParam.isEPeakBc(aRtnBc[i - 1].oBc.getFcTimeObj())) {
  118 + oHeadWay.bEPeakBc = true;
  119 + } else {
  120 + oHeadWay.bTroughBc = true;
  121 + }
  122 +
  123 + oHeadWay.iHeadWay = aRtnBc[i].oBc.getFcTimeObj().diff(
  124 + aRtnBc[i - 1].oBc.getFcTimeObj(), "m"
  125 + );
  126 +
  127 + aHeadWay.push(oHeadWay);
  128 + }
  129 +
  130 + // 找出第一个间隔小于最大发车间隔的位置
  131 + // 从当前位置往上到此位置所有班次往后加1分钟
  132 + var bIsFind = false;
  133 + var iFindIndex;
  134 + for (i = 0; i < aHeadWay.length; i++) {
  135 + if (aHeadWay[i].bMPeakBc) { // 早高峰
  136 + if (aHeadWay[i].iHeadWay < oParam.getMPeakMaxFcjx()) {
  137 + iFindIndex = i;
  138 + bIsFind = true;
  139 + break;
  140 + }
  141 + } else if (aHeadWay[i].bEPeakBc) { // 晚高峰
  142 + if (aHeadWay[i].iHeadWay < oParam.getEPeakMaxFcjx()) {
  143 + iFindIndex = i;
  144 + bIsFind = true;
  145 + break;
  146 + }
  147 + } else { // 低谷
  148 + if (aHeadWay[i].iHeadWay < oParam.getTroughMaxFcjx()) {
  149 + iFindIndex = i;
  150 + bIsFind = true;
  151 + break;
  152 + }
  153 + }
  154 + }
  155 +
  156 + if (!bIsFind) {
  157 + return;
  158 + }
  159 +
  160 + // 调整间隔
  161 + for (i = 0; i < iFindIndex; i++) {
  162 + _modifyHeadway(aRtnBc[aHeadWay[i].iStartRtnBcIndex], aLp, 1);
  163 + }
  164 +
  165 + }
  166 +
  167 + /**
  168 + * 从当前班次开始向下尝试加一分钟。
  169 + * @param oRtnBc 内部班次对象
  170 + * @param aRtnBc 内部班次列表
  171 + * @param aLp 路牌列表
  172 + * @param oParam 参数对象
  173 + * @private
  174 + */
  175 + function _headway_down(oRtnBc, aRtnBc, aLp, oParam) {
  176 + var i;
  177 +
  178 + // 当前班次与下一个班次之间的间隔列表
  179 + var aHeadWay = [];
  180 + var oHeadWay;
  181 + for (i = oRtnBc.iBcIndex; i < aRtnBc.length - 1; i++) {
  182 + oHeadWay = {};
  183 + oHeadWay.iStartRtnBcIndex = i;
  184 + oHeadWay.iEndRtnBcIndex = i + 1;
  185 + if (oParam.isMPeakBc(aRtnBc[i].oBc.getFcTimeObj())) {
  186 + oHeadWay.bMPeakBc = true;
  187 + } else if (oParam.isEPeakBc(aRtnBc[i].oBc.getFcTimeObj())) {
  188 + oHeadWay.bEPeakBc = true;
  189 + } else {
  190 + oHeadWay.bTroughBc = true;
  191 + }
  192 +
  193 + oHeadWay.iHeadWay = aRtnBc[i + 1].oBc.getFcTimeObj().diff(
  194 + aRtnBc[i].oBc.getFcTimeObj(), "m"
  195 + );
  196 +
  197 + aHeadWay.push(oHeadWay);
  198 + }
  199 +
  200 + // 找出第一个间隔大于最小发车间隔的位置
  201 + // 从当前位置往上到此位置所有班次往后加1分钟
  202 + var bIsFind = false;
  203 + var iFindIndex;
  204 + for (i = 0; i < aHeadWay.length; i++) {
  205 + if (aHeadWay[i].bMPeakBc) { // 早高峰
  206 + if (aHeadWay[i].iHeadWay > oParam.getMPeakMinFcjx()) {
  207 + iFindIndex = i;
  208 + bIsFind = true;
  209 + break;
  210 + }
  211 + } else if (aHeadWay[i].bEPeakBc) { // 晚高峰
  212 + if (aHeadWay[i].iHeadWay > oParam.getEPeakMinFcjx()) {
  213 + iFindIndex = i;
  214 + bIsFind = true;
  215 + break;
  216 + }
  217 + } else { // 低谷
  218 + if (aHeadWay[i].iHeadWay > oParam.getTroughMinFcjx()) {
  219 + iFindIndex = i;
  220 + bIsFind = true;
  221 + break;
  222 + }
  223 + }
  224 + }
  225 +
  226 + if (!bIsFind) {
  227 + return;
  228 + }
  229 +
  230 + // 调整间隔
  231 + for (i = 0; i <= iFindIndex; i++) {
  232 + _modifyHeadway(aRtnBc[aHeadWay[i].iStartRtnBcIndex], aLp, 1);
  233 + }
  234 + }
  235 +
  236 + /**
  237 + * 主函数。
  238 + * @param oInternalSchedule 行车计划
  239 + * @param oParam 参数对象
  240 + */
  241 + function main(
  242 + oInternalSchedule, oParam
  243 + ) {
  244 + var _iIterCount = 0; // 当前迭代次数
  245 + var _iMaxIter = 100; // 最大迭代次数
  246 +
  247 + var i;
  248 + var oRtnBc;
  249 + var oBc;
  250 +
  251 + while (_iIterCount <= _iMaxIter) {
  252 + // 获取主站方向班次列表
  253 + var aRtnBc = _getBcList(
  254 + oInternalSchedule,
  255 + oParam,
  256 + oParam.isUpOneWayStop());
  257 +
  258 + for (i = 0; i < aRtnBc.length; i++) {
  259 + oRtnBc = aRtnBc[i];
  260 + oBc = oRtnBc.oBc;
  261 + if (oBc.fnGetEatTime() > 0) { // 标记了吃饭时间,吃饭班次
  262 + if (_isNeedModifyLayoverTime(oRtnBc, oInternalSchedule.fnGetLpArray())) { // 是否需要调整停站时间满足吃饭
  263 + // 尝试向上部分班次逐个调整
  264 + _headway_up(oRtnBc, aRtnBc, oInternalSchedule.fnGetLpArray(), oParam);
  265 + // 尝试调整本班次,以及向下部分班次逐个调整
  266 + _headway_down(oRtnBc, aRtnBc, oInternalSchedule.fnGetLpArray(), oParam);
  267 +
  268 + break;
  269 + }
  270 + }
  271 + }
  272 +
  273 +
  274 + _iIterCount ++;
  275 + }
  276 +
  277 +
  278 + }
  279 +
  280 + return main;
  281 +
  282 +} ());
0 \ No newline at end of file 283 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/headway/CalcuHeadwayS1.js 0 → 100644
  1 +/**
  2 + * 计算发车间隔,每一圈的间隔,从上标线的班次开始。
  3 + * TODO:
  4 + */
  5 +var CalcuHeadwayS1 = (function() {
  6 +
  7 +
  8 + /**
  9 + * 根据上一个班次的发车时间计算下一个班次的发车间隔。
  10 + * @param oPreBcFcTime 上一个班次发车时间
  11 + * @param oParam 参数对象
  12 + * @private
  13 + */
  14 + function _peakInterval(oPreBcFcTime, oParam, normalStep) {
  15 + var iBcInterval;
  16 + if (oParam.isMPeakBc(oPreBcFcTime)) {
  17 + iBcInterval = oParam.getMPeakMinFcjx() + normalStep;
  18 + return iBcInterval > oParam.getMPeakMaxFcjx() ? oParam.getMPeakMaxFcjx() : iBcInterval;
  19 +
  20 + } else if (oParam.isEPeakBc(oPreBcFcTime)) {
  21 + iBcInterval = oParam.getEPeakMinFcjx() + normalStep;
  22 + return iBcInterval > oParam.getEPeakMaxFcjx() ? oParam.getEPeakMaxFcjx() : iBcInterval;
  23 + } else {
  24 + throw "必须高峰班次";
  25 + }
  26 +
  27 +
  28 +
  29 + // 一般高峰时间段2个小时,使用如下间隔方法,以后还会修正
  30 + // 1、第一个20分钟使用高峰最大发车间隔
  31 + // 2、第二个20分钟使用高峰平均发车间隔(floor)
  32 + // 3、第三个20分钟使用高峰最小发车间隔
  33 + // 4、第四个20分钟使用高峰最小发车间隔
  34 + // 5、第五个20分钟使用高峰平均发车间隔(floor)
  35 + // 6、第六个20分钟使用高峰最大发车间隔
  36 +
  37 + // if (oParam.isMPeakBc(oPreBcFcTime)) {
  38 + // return oParam.getMPeakMaxFcjx();
  39 + // // if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 1 * 20))) {
  40 + // // return oParam.getMPeakMaxFcjx();
  41 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 2 * 20))) {
  42 + // // return Math.floor((oParam.getMPeakMinFcjx() + oParam.getMPeakMaxFcjx()) / 2);
  43 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 3 * 20))) {
  44 + // // return oParam.getMPeakMinFcjx();
  45 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 4 * 20))) {
  46 + // // return oParam.getMPeakMinFcjx();
  47 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 5 * 20))) {
  48 + // // return Math.floor((oParam.getMPeakMinFcjx() + oParam.getMPeakMaxFcjx()) / 2);
  49 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 6 * 20))) {
  50 + // // return oParam.getMPeakMaxFcjx();
  51 + // // } else {
  52 + // // return oParam.getMPeakMaxFcjx();
  53 + // // }
  54 + // } else if (oParam.isEPeakBc(oPreBcFcTime)) {
  55 + // return oParam.getEPeakMaxFcjx();
  56 + // // if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 1 * 20))) {
  57 + // // return oParam.getEPeakMaxFcjx();
  58 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 2 * 20))) {
  59 + // // return Math.floor((oParam.getEPeakMinFcjx() + oParam.getEPeakMaxFcjx()) / 2);
  60 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 3 * 20))) {
  61 + // // return oParam.getEPeakMinFcjx();
  62 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 4 * 20))) {
  63 + // // return oParam.getEPeakMinFcjx();
  64 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 5 * 20))) {
  65 + // // return Math.floor((oParam.getEPeakMinFcjx() + oParam.getEPeakMaxFcjx()) / 2);
  66 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 6 * 20))) {
  67 + // // return oParam.getEPeakMaxFcjx();
  68 + // // } else {
  69 + // // return oParam.getEPeakMaxFcjx();
  70 + // // }
  71 + // } else {
  72 + // throw "必须高峰班次";
  73 + // }
  74 + }
  75 +
  76 +
  77 +
  78 +
  79 + /**
  80 + * 计算班次发车间隔。
  81 + * @param oInternalSchedule 行车计划对象
  82 + * @param oParam 参数对象
  83 + * @param groupIndex 圈索引
  84 + * @param bcIndex 班次索引
  85 + * @param normalFre 相同发车间隔班次数,频率
  86 + * @param normalStep 每次间隔变化的添加的分钟,步长
  87 + * @return {Array}
  88 + * @private
  89 + */
  90 + function _internalBcInterval(
  91 + oInternalSchedule, oParam,
  92 + groupIndex, bcIndex, normalFre, normalStep) {
  93 +
  94 + // 路牌列表
  95 + var aLp = oInternalSchedule.fnGetLpArray();
  96 +
  97 + if (normalFre < 1 || normalFre > aLp.length) {
  98 + alert("连续相同发车间隔班次数区间[1,路牌数],当前值=" + normalFre);
  99 + throw "连续相同发车间隔班次数区间[1,路牌数],当前值=" + normalFre;
  100 + }
  101 +
  102 + // 这个方法很重要用于生成每圈每个方向上的班次发车间隔
  103 + // 1、高峰班次全部高峰最大发车间隔
  104 + // 2、低谷第一个班次使用低谷最小发车间隔,连续相等的间隔班次数=normalFre,然后加1分钟,最大值是高峰最大发车间隔
  105 + // 5、TODO:主站方向在低谷拉间隔的时候,低谷拉到多少才是合理的(当行驶时间很大时,低谷最大发车间隔不一定合理),
  106 + // TODO: 此时需要和连班的间隔分班路牌数(抽车数),以及吃饭时间的大小共同考虑,
  107 + // TODO: 目前这样考虑,因为要抽车,如果没有足够的停站时间做调整,肯定会大间隔,当要抽车时,
  108 + // TODO:获取当前连班路牌和上一个连班路牌在前半圈的间隔值,当前连班路牌班次的停站时间至少大于低谷最大发车间隔减去这个值
  109 +
  110 + var i;
  111 + var j;
  112 + var oPreBc; // 上一个班次(从上标线班次开始)
  113 + var oCurrentBcFcTime; // 当前班次的发车时间
  114 + var oCurrentBcInterval; // 当前班次的发车间隔
  115 +
  116 + // 班次发车间隔,从oPreBc向前推normalFre个班次
  117 + var aBcInterval = [];
  118 + var iBcInterval;
  119 + var bIsIntervalEquale;
  120 + var iPreBcIntervalIndex;
  121 + var aBcInterval_rtn = []; // 最终返回的对象数组
  122 +
  123 + oPreBc = aLp[0].getBc(groupIndex, bcIndex);
  124 + if (oPreBc) {
  125 + // 先尝试获取上标线班次的interval
  126 + iBcInterval = aLp[0].fnGetVerticalIntervalTime(
  127 + groupIndex, bcIndex);
  128 + if (iBcInterval) { // 存在发车间隔
  129 + aBcInterval.push(iBcInterval);
  130 +
  131 + // 尝试获取前一圈同方向的(normalFre -1)个班次的发车间隔
  132 + j = 1;
  133 + if (groupIndex - 1 >= 0) {
  134 + for (i = aLp.length - 1; i >= 0; i--) {
  135 + if (j < normalFre) {
  136 + iBcInterval = aLp[i].fnGetVerticalIntervalTime(
  137 + groupIndex - 1, bcIndex);
  138 + if (iBcInterval) { // 存在发车间隔
  139 + aBcInterval.push(iBcInterval);
  140 + j++;
  141 + }
  142 + } else {
  143 + break;
  144 + }
  145 + }
  146 + }
  147 + }
  148 +
  149 + aBcInterval.reverse();
  150 + // 上一个班次间隔index
  151 + iPreBcIntervalIndex = aBcInterval.length - 1;
  152 +
  153 + var _iLpIndex;
  154 + for (i = 1; i <= aLp.length; i++) {
  155 + var oBcInterval_rtn =
  156 + {iLpIndex: null, hasBc: false, iFcInterval: null, iGroupIndex: null, iBcIndex: null};
  157 + // 注意这里是 this._internalLpArray.length,最后一个班次是下标线下一圈的同方向班次
  158 + _iLpIndex = i % aLp.length;
  159 +
  160 + if (_iLpIndex == 0) { // 下一圈的上标线同方向班次
  161 + oBcInterval_rtn.iLpIndex = 0;
  162 + oBcInterval_rtn.iGroupIndex = groupIndex + 1;
  163 + oBcInterval_rtn.iBcIndex = bcIndex;
  164 + } else {
  165 + oBcInterval_rtn.iLpIndex = _iLpIndex;
  166 + oBcInterval_rtn.iGroupIndex = groupIndex;
  167 + oBcInterval_rtn.iBcIndex = bcIndex;
  168 + }
  169 +
  170 + // 班型判定
  171 + if (_iLpIndex != 0) { // 回到上标线不用判定了
  172 + if (!aLp[_iLpIndex].fnDecideBxBc(
  173 + oInternalSchedule, oParam,
  174 + oPreBc, _iLpIndex - 1,
  175 + _iLpIndex, groupIndex, bcIndex
  176 + )) {
  177 + aBcInterval_rtn.push(oBcInterval_rtn);
  178 + continue;
  179 + }
  180 +
  181 + }
  182 +
  183 + if (oParam.isMPeakBc(oPreBc.getFcTimeObj())) { // 早高峰
  184 + // 如果上一个班次是早高峰班次,下一个班次使用_peakInterval计算早高峰发车间隔
  185 + // 如果下一个班次(加上_peakInterval计算的早高峰发车间隔后)是低谷班次,使用低谷最小发车间隔加一个步长值
  186 + oCurrentBcFcTime = oParam.addMinute(
  187 + oPreBc.getFcTimeObj(),
  188 + _peakInterval(oPreBc.getFcTimeObj(), oParam, normalStep));
  189 + // if (oParam.isTroughBc(oCurrentBcFcTime)) {
  190 + // iBcInterval = oParam.getTroughMinFcjx() + normalStep;
  191 + // oCurrentBcFcTime = oParam.addMinute(
  192 + // oPreBc.getFcTimeObj(),
  193 + // iBcInterval > oParam.getTroughMaxFcjx() ? oParam.getTroughMaxFcjx() : iBcInterval
  194 + // );
  195 + // }
  196 +
  197 + } else if (oParam.isEPeakBc(oPreBc.getFcTimeObj())) { // 晚高峰
  198 + // 如果上一个班次是晚高峰班次,下一个班次使用_peakInterval计算晚高峰发车间隔
  199 + // 如果下一个班次(加上_peakInterval计算的晚高峰发车间隔后)是低谷班次,使用低谷最小发车间隔加一个步长值
  200 + oCurrentBcFcTime = oParam.addMinute(
  201 + oPreBc.getFcTimeObj(),
  202 + _peakInterval(oPreBc.getFcTimeObj(), oParam, normalStep));
  203 + // if (oParam.isTroughBc(oCurrentBcFcTime)) {
  204 + // iBcInterval = oParam.getTroughMinFcjx() + normalStep;
  205 + // oCurrentBcFcTime = oParam.addMinute(
  206 + // oPreBc.getFcTimeObj(),
  207 + // iBcInterval > oParam.getTroughMaxFcjx() ? oParam.getTroughMaxFcjx() : iBcInterval
  208 + // );
  209 + // }
  210 + } else { // 上一个班次是低谷
  211 + if (aBcInterval.length < normalFre) { // 没有足够的连续班次间隔
  212 + // 如果没有足够的连续班次间隔,那一定是在初始化第一圈的班次
  213 + // 使用低谷最小发车间隔加一个步长值
  214 + iBcInterval = oParam.getTroughMinFcjx() + normalStep;
  215 + oCurrentBcFcTime = oParam.addMinute(
  216 + oPreBc.getFcTimeObj(),
  217 + iBcInterval > oParam.getTroughMaxFcjx() ? oParam.getTroughMaxFcjx() : iBcInterval
  218 + );
  219 + // // 如果进入高峰,使用最大发车间隔
  220 + // if (oParam.isMPeakBc(oCurrentBcFcTime)) {
  221 + // oCurrentBcFcTime = oParam.addMinute(
  222 + // oPreBc.getFcTimeObj(),
  223 + // oParam.getMPeakMaxFcjx()
  224 + // );
  225 + // }
  226 + // if (oParam.isEPeakBc(oCurrentBcFcTime)) {
  227 + // oCurrentBcFcTime = oParam.addMinute(
  228 + // oPreBc.getFcTimeObj(),
  229 + // oParam.getEPeakMaxFcjx()
  230 + // );
  231 + // }
  232 + } else { // 有足够的连续班次间隔
  233 + // 看连续班次间隔是否一致,一致 加 normalStep 分钟(不能超过低谷最大发车间隔),不一致就相等间隔
  234 + // 加了间隔后,如果是高峰班次,则使用高峰最大发车间隔
  235 + // TODO:什么时候开始减低谷发车间隔到最小发车间隔,应该是在吃了饭之后
  236 +
  237 + bIsIntervalEquale = true;
  238 + for (j = iPreBcIntervalIndex; j > iPreBcIntervalIndex - normalFre + 1; j--) {
  239 + if (aBcInterval[j] != aBcInterval[j - 1]) {
  240 + bIsIntervalEquale = false;
  241 + break;
  242 + }
  243 + }
  244 + if (bIsIntervalEquale) {
  245 + // 需要变换频率数据了
  246 +
  247 + // TODO:14:00后开始到16:00之间减少低谷发车间隔
  248 + if (oPreBc.getFcTimeObj().isAfter(oParam.toTimeObj("14:00")) &&
  249 + oPreBc.getFcTimeObj().isBefore(oParam.toTimeObj("16:00"))) {
  250 + iBcInterval = aBcInterval[iPreBcIntervalIndex] - normalStep;
  251 + oCurrentBcFcTime = oParam.addMinute(
  252 + oPreBc.getFcTimeObj(),
  253 + iBcInterval < oParam.getTroughMinFcjx() ? oParam.getTroughMinFcjx() : iBcInterval
  254 + );
  255 + } else {
  256 + iBcInterval = aBcInterval[iPreBcIntervalIndex] + normalStep;
  257 + oCurrentBcFcTime = oParam.addMinute(
  258 + oPreBc.getFcTimeObj(),
  259 + iBcInterval > oParam.getTroughMaxFcjx() ? oParam.getTroughMaxFcjx() : iBcInterval
  260 + );
  261 + }
  262 + } else {
  263 + // 不需要变换频率,使用上一个班次的间隔
  264 + oCurrentBcFcTime = oParam.addMinute(
  265 + oPreBc.getFcTimeObj(),
  266 + aBcInterval[iPreBcIntervalIndex]
  267 + );
  268 + }
  269 +
  270 + // // 如果进入高峰使用高峰最大发车间隔
  271 + // if (oParam.isMPeakBc(oCurrentBcFcTime)) {
  272 + // oCurrentBcFcTime = oParam.addMinute(
  273 + // oPreBc.getFcTimeObj(),
  274 + // oParam.getMPeakMaxFcjx()
  275 + // );
  276 + // }
  277 + // if (oParam.isEPeakBc(oCurrentBcFcTime)) {
  278 + // oCurrentBcFcTime = oParam.addMinute(
  279 + // oPreBc.getFcTimeObj(),
  280 + // oParam.getEPeakMaxFcjx()
  281 + // );
  282 + // }
  283 +
  284 + }
  285 +
  286 + }
  287 +
  288 + // 判定超出末班车,就没有班次
  289 + if (oPreBc.isUp()) {
  290 + if (oCurrentBcFcTime.isAfter(
  291 + oParam.addMinute(oParam.getUpLastDtimeObj(), 30))) {
  292 + aBcInterval_rtn.push(oBcInterval_rtn);
  293 + continue;
  294 + }
  295 + } else {
  296 + if (oCurrentBcFcTime.isAfter(
  297 + oParam.addMinute(oParam.getDownLastDTimeObj(), 30))) {
  298 + aBcInterval_rtn.push(oBcInterval_rtn);
  299 + continue;
  300 + }
  301 + }
  302 +
  303 + oCurrentBcInterval = oCurrentBcFcTime.diff(oPreBc.getFcTimeObj(), "m");
  304 + aBcInterval.push(oCurrentBcInterval);
  305 + oPreBc = oInternalSchedule.fnGetUitls().createBcObj(
  306 + aLp[_iLpIndex],
  307 + "normal",
  308 + oPreBc.isUp(),
  309 + 1,
  310 + oCurrentBcFcTime,
  311 + oParam
  312 + );
  313 + iPreBcIntervalIndex++;
  314 + oBcInterval_rtn.hasBc = true;
  315 + oBcInterval_rtn.iFcInterval = oCurrentBcInterval;
  316 + aBcInterval_rtn.push(oBcInterval_rtn);
  317 + }
  318 +
  319 + }
  320 +
  321 + return aBcInterval_rtn;
  322 + }
  323 +
  324 +
  325 + function main(
  326 + oInternalSchedule, oParam,
  327 + iGroupIndex, iBcIndex, iMinCycleTime, iMaxCycleTime) {
  328 +
  329 + var iFre = 3; // 频率,连续相同发车间隔班次数
  330 + var iStep = 1; // 步长,每个频率后变化1分钟
  331 + var aBcInterval; // 每次计算返回的指定圈的间隔数组
  332 + var iCycleTime = 0; // 每次计算放回的周转时间(把所有的间隔加在一起)
  333 + var i;
  334 +
  335 + var iterCount = 0;
  336 + var maxIter = 50; // 最多5次迭代,防止死循环
  337 +
  338 + console.log(iMinCycleTime);
  339 + console.log(iMaxCycleTime);
  340 +
  341 + // TODO:先用最小值判定,后面再考虑最大值
  342 + while (iCycleTime < iMinCycleTime && iterCount <= maxIter) {
  343 + aBcInterval = _internalBcInterval(
  344 + oInternalSchedule, oParam,
  345 + iGroupIndex, iBcIndex, iFre, iStep);
  346 + iCycleTime = 0; // 间隔加在一起就是周转
  347 + for (i = 0; i < aBcInterval.length; i++) {
  348 + if (aBcInterval[i].hasBc) {
  349 + iCycleTime += aBcInterval[i].iFcInterval;
  350 + }
  351 + }
  352 +
  353 + // 下一次迭代,先降低频率直到1,然后再增加步长
  354 + iFre = iFre > 1 ? iFre - 1 : 1;
  355 + iStep = iFre == 1 ? (iStep + 1) : 1;
  356 + iterCount ++;
  357 + }
  358 +
  359 + return aBcInterval;
  360 +
  361 + }
  362 +
  363 + return main;
  364 +
  365 +} ());
  366 +
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/headway/CalcuHeadwayS2.js 0 → 100644
  1 +/**
  2 + * 计算发车间隔策略2。
  3 + * 参数提供高峰,低谷发车间隔范围。
  4 + * 具体的发车间隔使用线性函数计算,f(x)=ax+b x=班次发车时间,是一个分段函数,说明如下:
  5 + * 1、低谷到早高峰开始:使用低谷最大发车间隔线性变化到最小发车间隔。
  6 + * 2、早高峰开始到结束:使用早高峰最大发车间隔线性变化到最小,然后到中间时间开始从最小线性变化到最大间隔。
  7 + * 3、早高峰结束到10:30:从低谷最小发车间隔线性变化到低谷最大发车间隔。
  8 + * 4、10:30到一个周转时间结束:保持低谷最大发车间间隔。
  9 + * 5、从上一个时间结束到晚高峰开始:从低谷最大发车间隔线性变化到最小发车间隔。
  10 + * 6、晚高峰开始到结束:使用晚高峰最大发车间隔线性变化到最小,然后到中间时间开始从最小线性变化到最大间隔。
  11 + * 7、晚高分结束到末班车:使用晚高峰最小发车间隔线性变化到最大间隔。
  12 + *
  13 + *
  14 + */
  15 +var CalcuHeadwayS2 = (function() {
  16 + // 1、低谷到早高峰开始:使用低谷最大发车间隔线性变化到最小发车间隔
  17 + function _fn1(bIsUp, oFcTime, iSHeadWay, oParam, percent) {
  18 + var a; // slope, 斜率
  19 + var b; // 偏置值
  20 + var _iDeltaY;
  21 + var _iDeltaX;
  22 + if (iSHeadWay) {
  23 + _iDeltaY = oParam.getTroughMinFcjx() - iSHeadWay;
  24 + } else {
  25 + _iDeltaY = oParam.getTroughMinFcjx() - oParam.getTroughMaxFcjx();
  26 + }
  27 +
  28 + if (bIsUp) { // 上行
  29 + _iDeltaX = oParam.getMPeakStartTimeObj().valueOf() - oParam.getUpFirstDTimeObj().valueOf();
  30 + a = _iDeltaY / _iDeltaX;
  31 + b = oParam.getTroughMinFcjx() - a * oParam.getMPeakStartTimeObj().valueOf();
  32 + } else { // 下行
  33 + _iDeltaX = oParam.getMPeakStartTimeObj().valueOf() - oParam.getDownFirstDTimeObj().valueOf();
  34 + a = _iDeltaY / _iDeltaX;
  35 + b = oParam.getTroughMinFcjx() - a * oParam.getMPeakStartTimeObj().valueOf();
  36 + }
  37 +
  38 + var _iEHeadWay = Math.floor((a * oFcTime.valueOf() + b) * (1 + percent));
  39 + if (_iEHeadWay < oParam.getTroughMinFcjx()) {
  40 + return oParam.getTroughMinFcjx();
  41 + } else if (_iEHeadWay > oParam.getTroughMaxFcjx()) {
  42 + return oParam.getTroughMaxFcjx();
  43 + } else {
  44 + return _iEHeadWay;
  45 + }
  46 + }
  47 + // 2、早高峰开始到结束:使用早高峰最大发车间隔线性变化到最小,然后到中间时间开始从最小线性变化到最大间隔
  48 + function _fn2_1(bIsUp, oFcTime, iSHeadWay, oParam, percent) {
  49 + var a; // slope,斜率
  50 + var b; // 偏置值
  51 + var _iDeltaY;
  52 + var _iDeltaX;
  53 + var _middle = oParam.getMPeakStartTimeObj().valueOf() +
  54 + (oParam.getMPeakEndTimeObj().valueOf() - oParam.getMPeakStartTimeObj().valueOf()) / 2;
  55 +
  56 + if (iSHeadWay) {
  57 + _iDeltaY = oParam.getMPeakMinFcjx() - iSHeadWay;
  58 + } else {
  59 + _iDeltaY = oParam.getMPeakMinFcjx() - oParam.getMPeakMaxFcjx();
  60 + }
  61 +
  62 + _iDeltaX = _middle - oParam.getMPeakStartTimeObj().valueOf();
  63 + a = _iDeltaY / _iDeltaX;
  64 + b = oParam.getMPeakMinFcjx() - a * _middle;
  65 +
  66 + var _iEHeadWay = Math.floor((a * oFcTime.valueOf() + b) * (1 + percent));
  67 + if (_iEHeadWay < oParam.getMPeakMinFcjx()) {
  68 + return oParam.getMPeakMinFcjx();
  69 + } else if (_iEHeadWay > oParam.getMPeakMaxFcjx()) {
  70 + return oParam.getMPeakMaxFcjx();
  71 + } else {
  72 + return _iEHeadWay;
  73 + }
  74 + }
  75 + function _fn2_2(bIsUp, oFcTime, iSHeadWay, oParam, percent) {
  76 + var a; // slope,斜率
  77 + var b; // 偏置值
  78 + var _iDeltaY;
  79 + var _iDeltaX;
  80 + var _middle = oParam.getMPeakStartTimeObj().valueOf() +
  81 + (oParam.getMPeakEndTimeObj().valueOf() - oParam.getMPeakStartTimeObj().valueOf()) / 2;
  82 +
  83 + if (iSHeadWay) {
  84 + _iDeltaY = oParam.getMPeakMaxFcjx() - iSHeadWay;
  85 + } else {
  86 + _iDeltaY = oParam.getMPeakMaxFcjx() - oParam.getMPeakMinFcjx();
  87 + }
  88 +
  89 + _iDeltaX = oParam.getMPeakEndTimeObj().valueOf() - _middle;
  90 + a = _iDeltaY / _iDeltaX;
  91 + b = oParam.getMPeakMaxFcjx() - a * oParam.getMPeakEndTimeObj().valueOf();
  92 +
  93 + var _iEHeadWay = Math.floor((a * oFcTime.valueOf() + b) * (1 + percent));
  94 + if (_iEHeadWay < oParam.getMPeakMinFcjx()) {
  95 + return oParam.getMPeakMinFcjx();
  96 + } else if (_iEHeadWay > oParam.getMPeakMaxFcjx()) {
  97 + return oParam.getMPeakMaxFcjx();
  98 + } else {
  99 + return _iEHeadWay;
  100 + }
  101 + }
  102 + // 3、早高峰结束到14:00:从低谷最小发车间隔线性变化到低谷最大发车间隔
  103 + function _fn3(bIsUp, oFcTime, iSHeadWay, oParam, percent) {
  104 + var a; // slope,斜率
  105 + var b; // 偏置值
  106 + var _iDeltaY;
  107 + var _iDeltaX;
  108 +
  109 + if (iSHeadWay) {
  110 + _iDeltaY = oParam.getTroughMaxFcjx() - iSHeadWay;
  111 + } else {
  112 + _iDeltaY = oParam.getTroughMaxFcjx() - oParam.getTroughMinFcjx();
  113 + }
  114 +
  115 + _iDeltaX = oParam.toTimeObj("14:00").valueOf() - oParam.getMPeakEndTimeObj().valueOf();
  116 + a = _iDeltaY / _iDeltaX;
  117 + b = oParam.getTroughMaxFcjx() - a * oParam.toTimeObj("14:00").valueOf();
  118 +
  119 + var _iEHeadWay = Math.floor((a * oFcTime.valueOf() + b) * (1 + percent));
  120 + if (_iEHeadWay < oParam.getTroughMinFcjx()) {
  121 + return oParam.getTroughMinFcjx();
  122 + } else if (_iEHeadWay > oParam.getTroughMaxFcjx()) {
  123 + return oParam.getTroughMaxFcjx();
  124 + } else {
  125 + return _iEHeadWay;
  126 + }
  127 + }
  128 + // 4、14:00到一个周转时间结束:保持低谷最大发车间间隔
  129 + function _fn4(bIsUp, oFcTime, iSHeadWay, oParam, percent) {
  130 + var _iEHeadWay = Math.floor(oParam.getTroughMaxFcjx() * (1 + percent));
  131 + if (_iEHeadWay < oParam.getTroughMinFcjx()) {
  132 + return oParam.getTroughMinFcjx();
  133 + } else if (_iEHeadWay > oParam.getTroughMaxFcjx()) {
  134 + return oParam.getTroughMaxFcjx();
  135 + } else {
  136 + return _iEHeadWay;
  137 + }
  138 + }
  139 + // 5、从上一个时间结束到晚高峰开始:从低谷最大发车间隔线性变化到最小发车间隔
  140 + function _fn5(bIsUp, oFcTime, iSHeadWay, oParam, iMinutes, percent) {
  141 + var a; // slope,斜率
  142 + var b; // 偏置值
  143 + var _iDeltaY;
  144 + var _iDeltaX;
  145 + var _middle = oParam.addMinute(oParam.toTimeObj("14:00"), iMinutes).valueOf();
  146 +
  147 + if (iSHeadWay) {
  148 + _iDeltaY = oParam.getTroughMinFcjx() - iSHeadWay;
  149 + } else {
  150 + _iDeltaY = oParam.getTroughMinFcjx() - oParam.getTroughMaxFcjx();
  151 + }
  152 +
  153 + _iDeltaX = oParam.getEPeakStartTimeObj().valueOf() - _middle;
  154 + a = _iDeltaY / _iDeltaX;
  155 + b = oParam.getTroughMinFcjx() - a * oParam.getEPeakStartTimeObj().valueOf();
  156 +
  157 + var _iEHeadWay = Math.floor((a * oFcTime.valueOf() + b) * (1 + percent));
  158 +
  159 + if (_iEHeadWay < oParam.getTroughMinFcjx()) {
  160 + return oParam.getTroughMinFcjx();
  161 + } else if (_iEHeadWay > oParam.getTroughMaxFcjx()) {
  162 + return oParam.getTroughMaxFcjx();
  163 + } else {
  164 + return _iEHeadWay;
  165 + }
  166 + }
  167 + // 6、晚高峰开始到结束:使用晚高峰最大发车间隔线性变化到最小,然后到中间时间开始从最小线性变化到最大间隔
  168 + function _fn6_1(bIsUp, oFcTime, iSHeadWay, oParam, percent) {
  169 + var a; // slope,斜率
  170 + var b; // 偏置值
  171 + var _iDeltaY;
  172 + var _iDeltaX;
  173 + var _middle = oParam.getEPeakStartTimeObj().valueOf() +
  174 + (oParam.getEPeakEndTimeObj().valueOf() - oParam.getEPeakStartTimeObj().valueOf()) / 2;
  175 +
  176 + if (iSHeadWay) {
  177 + _iDeltaY = oParam.getEPeakMinFcjx() - iSHeadWay;
  178 + } else {
  179 + _iDeltaY = oParam.getEPeakMinFcjx() - oParam.getEPeakMaxFcjx();
  180 + }
  181 +
  182 + _iDeltaX = _middle - oParam.getEPeakStartTimeObj().valueOf();
  183 + a = _iDeltaY / _iDeltaX;
  184 + b = oParam.getEPeakMinFcjx() - a * _middle;
  185 +
  186 + var _iEHeadWay = Math.floor((a * oFcTime.valueOf() + b) * (1 + percent));
  187 + if (_iEHeadWay < oParam.getEPeakMinFcjx()) {
  188 + return oParam.getEPeakMinFcjx();
  189 + } else if (_iEHeadWay > oParam.getEPeakMaxFcjx()) {
  190 + return oParam.getEPeakMaxFcjx();
  191 + } else {
  192 + return _iEHeadWay;
  193 + }
  194 + }
  195 + function _fn6_2(bIsUp, oFcTime, iSHeadWay, oParam, percent) {
  196 + var a; // slope,斜率
  197 + var b; // 偏置值
  198 + var _iDeltaY;
  199 + var _iDeltaX;
  200 + var _middle = oParam.getEPeakStartTimeObj().valueOf() +
  201 + (oParam.getEPeakEndTimeObj().valueOf() - oParam.getEPeakStartTimeObj().valueOf()) / 2;
  202 +
  203 + if (iSHeadWay) {
  204 + _iDeltaY = oParam.getEPeakMaxFcjx() - iSHeadWay;
  205 + } else {
  206 + _iDeltaY = oParam.getEPeakMaxFcjx() - oParam.getEPeakMinFcjx();
  207 + }
  208 +
  209 + _iDeltaX = oParam.getEPeakEndTimeObj().valueOf() - _middle;
  210 + a = _iDeltaY / _iDeltaX;
  211 + b = oParam.getEPeakMaxFcjx() - a * oParam.getEPeakEndTimeObj().valueOf();
  212 +
  213 + var _iEHeadWay = Math.floor((a * oFcTime.valueOf() + b) * (1 + percent));
  214 + if (_iEHeadWay < oParam.getEPeakMinFcjx()) {
  215 + return oParam.getEPeakMinFcjx();
  216 + } else if (_iEHeadWay > oParam.getEPeakMaxFcjx()) {
  217 + return oParam.getEPeakMaxFcjx();
  218 + } else {
  219 + return _iEHeadWay;
  220 + }
  221 + }
  222 + // 7、晚高分结束到末班车:使用晚高峰最小发车间隔线性变化到最大间隔
  223 + function _fn7(bIsUp, oFcTime, iSHeadWay, oParam, percent) {
  224 + var a; // slope,斜率
  225 + var b; // 偏置值
  226 + var _iDeltaY;
  227 + var _iDeltaX;
  228 +
  229 + if (iSHeadWay) {
  230 + _iDeltaY = oParam.getTroughMaxFcjx() - iSHeadWay;
  231 + } else {
  232 + _iDeltaY = oParam.getTroughMaxFcjx() - oParam.getTroughMinFcjx();
  233 + }
  234 +
  235 + if (bIsUp) { // 上行
  236 + _iDeltaX = oParam.getUpLastDtimeObj().valueOf() - oParam.getEPeakEndTimeObj().valueOf();
  237 + a = _iDeltaY / _iDeltaX;
  238 + b = oParam.getTroughMaxFcjx() - a * oParam.getUpLastDtimeObj().valueOf();
  239 + } else { // 下行
  240 + _iDeltaX = oParam.getDownLastDTimeObj().valueOf() - oParam.getEPeakEndTimeObj().valueOf();
  241 + a = _iDeltaY / _iDeltaX;
  242 + b = oParam.getTroughMaxFcjx() - a * oParam.getDownLastDTimeObj().valueOf();
  243 + }
  244 +
  245 + var _iEHeadWay = Math.floor((a * oFcTime.valueOf() + b) * (1 + percent));
  246 + if (_iEHeadWay < oParam.getTroughMinFcjx()) {
  247 + return oParam.getTroughMinFcjx();
  248 + } else if (_iEHeadWay > oParam.getTroughMaxFcjx()) {
  249 + return oParam.getTroughMaxFcjx();
  250 + } else {
  251 + return _iEHeadWay;
  252 + }
  253 + }
  254 +
  255 + /**
  256 + * 产生发车间隔。
  257 + * @param bIsUp 是否上行
  258 + * @param oFcTime 发车时间
  259 + * @param iSHeadWay 参考的发车间隔
  260 + * @param oParam 参数对象
  261 + * @param ib 修正百分比
  262 + */
  263 + function _getBcHeadway(bIsUp, oFcTime, iSHeadWay, oParam, percent) {
  264 + var _iHeadWay;
  265 + if (!percent) {
  266 + percent = 0.0;
  267 + }
  268 + var o_temp = oParam.toTimeObj("10:30"); // 10:30
  269 + var iMinutes = 10; // 14:00后维持低谷最大间隔的时间
  270 + var oMPeakMiddle = moment(oParam.getMPeakStartTimeObj().valueOf() +
  271 + (oParam.getMPeakEndTimeObj().valueOf() - oParam.getMPeakStartTimeObj().valueOf()) / 2);
  272 + // console.log(oMPeakMiddle.format("HH:mm"));
  273 + var oEPeakMiddle = moment(oParam.getEPeakStartTimeObj().valueOf() +
  274 + (oParam.getEPeakEndTimeObj().valueOf() - oParam.getEPeakStartTimeObj().valueOf()) / 2);
  275 + if (oFcTime.isBefore(oParam.getMPeakStartTimeObj())) {
  276 + _iHeadWay = _fn1(bIsUp, oFcTime, iSHeadWay, oParam, percent);
  277 + // console.log("_fn1=" + _iHeadWay);
  278 + } else if (oFcTime.isBefore(oMPeakMiddle)) {
  279 + _iHeadWay = _fn2_1(bIsUp, oFcTime, iSHeadWay, oParam, percent);
  280 + // console.log("_fn2_1=" + _iHeadWay);
  281 + } else if (oFcTime.isBefore(oParam.getMPeakEndTimeObj())) {
  282 + _iHeadWay = _fn2_2(bIsUp, oFcTime, iSHeadWay, oParam, percent);
  283 + // console.log("_fn2_2=" + _iHeadWay);
  284 + } else if (oFcTime.isBefore(o_temp)) {
  285 + _iHeadWay = _fn3(bIsUp, oFcTime, iSHeadWay, oParam, percent);
  286 + // console.log("_fn3=" + _iHeadWay);
  287 + } else if (oFcTime.isBefore(oParam.addMinute(o_temp, iMinutes))) {
  288 + _iHeadWay = _fn4(bIsUp, oFcTime, iSHeadWay, oParam, percent);
  289 + // console.log("_fn4=" + _iHeadWay);
  290 + } else if (oFcTime.isBefore(oParam.getEPeakStartTimeObj())) {
  291 + _iHeadWay = _fn5(bIsUp, oFcTime, iSHeadWay, oParam, iMinutes, percent);
  292 + // console.log("_fn5=" + _iHeadWay);
  293 + } else if (oFcTime.isBefore(oEPeakMiddle)) {
  294 + _iHeadWay = _fn6_1(bIsUp, oFcTime, iSHeadWay, oParam, percent);
  295 + // console.log("_fn6_1=" + _iHeadWay);
  296 + } else if (oFcTime.isBefore(oParam.getEPeakEndTimeObj())) {
  297 + _iHeadWay = _fn6_2(bIsUp, oFcTime, iSHeadWay, oParam, percent);
  298 + // console.log("_fn6_2=" + _iHeadWay);
  299 + } else {
  300 + _iHeadWay = _fn7(bIsUp, oFcTime, iSHeadWay, oParam, percent);
  301 + // console.log("_fn7=" + _iHeadWay);
  302 + }
  303 +
  304 + return _iHeadWay;
  305 +
  306 + }
  307 +
  308 + /**
  309 + * 以上标线班次为标准,往下拉一圈的便次。
  310 + * @param oInternalSchedule 行车计划对象
  311 + * @param oParam 参数对象
  312 + * @param groupIndex 圈索引
  313 + * @param bcIndex 班次索引
  314 + * @param percent 修正百分比
  315 + *
  316 + */
  317 + function _internalGroupBcInterval(
  318 + oInternalSchedule, oParam,
  319 + groupIndex, bcIndex, percent) {
  320 +
  321 + // 路牌列表
  322 + var aLp = oInternalSchedule.fnGetLpArray();
  323 +
  324 + var i;
  325 + var oPreBc; // 上一个班次(从上标线班次开始)
  326 + var oCurrentBcFcTime; // 当前班次的发车时间
  327 + var iCurrentBcInterval; // 当前班次的发车间隔
  328 +
  329 + // 班次发车间隔,从oPreBc向前推normalFre个班次
  330 + var aBcInterval_rtn = []; // 最终返回的对象数组
  331 + // 上标线班次的发车间隔,做为后续班次间隔的参考值
  332 + var iSHeadWay = aLp[0].fnGetVerticalIntervalTime(groupIndex, bcIndex);
  333 +
  334 + oPreBc = aLp[0].getBc(groupIndex, bcIndex);
  335 + if (oPreBc) { // 必须有上标线班次为标准
  336 + var _iLpIndex;
  337 + for (i = 1; i <= aLp.length; i++) {
  338 + var oBcInterval_rtn = {
  339 + iLpIndex: null, // 路牌索引
  340 + hasBc: false, // 是否有班次
  341 + iFcInterval: null, // 参考班次发车间隔
  342 + fP: null, // 本次参考修正百分比
  343 + iGroupIndex: null, // 圈索引
  344 + iBcIndex: null // 班次索引
  345 + };
  346 + // 注意这里是 this._internalLpArray.length,最后一个班次是下标线下一圈的同方向班次
  347 + _iLpIndex = i % aLp.length;
  348 +
  349 + if (_iLpIndex == 0) { // 下一圈的上标线同方向班次
  350 + oBcInterval_rtn.iLpIndex = 0;
  351 + oBcInterval_rtn.iGroupIndex = groupIndex + 1;
  352 + oBcInterval_rtn.iBcIndex = bcIndex;
  353 + } else {
  354 + oBcInterval_rtn.iLpIndex = _iLpIndex;
  355 + oBcInterval_rtn.iGroupIndex = groupIndex;
  356 + oBcInterval_rtn.iBcIndex = bcIndex;
  357 + }
  358 +
  359 + // 路牌班型工时判定
  360 + if (_iLpIndex != 0) { // 回到上标线不用判定了
  361 + if (!aLp[_iLpIndex].fnDecideBxBc(
  362 + oInternalSchedule, oParam,
  363 + oPreBc, _iLpIndex - 1,
  364 + _iLpIndex, groupIndex, bcIndex
  365 + )) {
  366 + aBcInterval_rtn.push(oBcInterval_rtn);
  367 + continue;
  368 + }
  369 + }
  370 +
  371 + iCurrentBcInterval = _getBcHeadway(oPreBc.isUp(), oPreBc.getFcTimeObj(), iSHeadWay, oParam, percent);
  372 + oCurrentBcFcTime = oParam.addMinute(oPreBc.getFcTimeObj(), iCurrentBcInterval);
  373 +
  374 + // 判定超出末班车,就没有班次
  375 + if (oPreBc.isUp()) {
  376 + if (oCurrentBcFcTime.isAfter(
  377 + oParam.addMinute(oParam.getUpLastDtimeObj(), 30))) {
  378 + aBcInterval_rtn.push(oBcInterval_rtn);
  379 + continue;
  380 + }
  381 + } else {
  382 + if (oCurrentBcFcTime.isAfter(
  383 + oParam.addMinute(oParam.getDownLastDTimeObj(), 30))) {
  384 + aBcInterval_rtn.push(oBcInterval_rtn);
  385 + continue;
  386 + }
  387 + }
  388 +
  389 + oPreBc = oInternalSchedule.fnGetUitls().createBcObj(
  390 + aLp[_iLpIndex],
  391 + "normal",
  392 + oPreBc.isUp(),
  393 + 1,
  394 + oCurrentBcFcTime,
  395 + oParam
  396 + );
  397 +
  398 + oBcInterval_rtn.hasBc = true;
  399 + oBcInterval_rtn.iFcInterval = iCurrentBcInterval;
  400 + oBcInterval_rtn.fP = percent;
  401 + aBcInterval_rtn.push(oBcInterval_rtn);
  402 + }
  403 +
  404 + }
  405 +
  406 + return aBcInterval_rtn;
  407 +
  408 + }
  409 +
  410 + /**
  411 + * 主函数。
  412 + * 迭代生成间隔。
  413 + * @param oInternalSchedule 行车计划
  414 + * @param oParam 参数对象
  415 + * @param iGroupIndex 圈索引
  416 + * @param iBcIndex 班次索引
  417 + * @param iGroupMinCycleTime 圈最小周转时间
  418 + * @param iGroupMaxCycleTime 圈最大周转时间
  419 + */
  420 + function main(
  421 + oInternalSchedule, oParam,
  422 + iGroupIndex, iBcIndex,
  423 + iGroupMinCycleTime, iGroupMaxCycleTime) {
  424 +
  425 + var _iMin = iGroupMinCycleTime - 0; // 最小值修正3分钟
  426 + var _iMax = iGroupMaxCycleTime + 0; // 最大值修正3分钟
  427 + var _iMaxIter = 100; // 最大迭代100次
  428 + var _fP = 0.05; // 修正百分比
  429 +
  430 + var i;
  431 + var _iCycleTime = 0; // 周转时间
  432 +
  433 + var aBcInterval; // 每次计算返回的指定圈的间隔数组
  434 +
  435 + var _iIterCount = 0;
  436 +
  437 + // console.log("_Min=" + _iMin);
  438 + // console.log("_Max=" + _iMax);
  439 +
  440 + while (_iIterCount <= _iMaxIter) {
  441 + aBcInterval = _internalGroupBcInterval(
  442 + oInternalSchedule, oParam,
  443 + iGroupIndex, iBcIndex, _fP
  444 + );
  445 +
  446 + // 计算周转时间
  447 + for (i = 0; i < aBcInterval.length; i++) {
  448 + if (aBcInterval[i].hasBc) {
  449 + _iCycleTime += aBcInterval[i].iFcInterval;
  450 + }
  451 + }
  452 +
  453 + // console.log(_iCycleTime);
  454 +
  455 + if (_iCycleTime < _iMin) {
  456 + // 周转小,加间隔修正百分比
  457 + _fP += 0.05;
  458 + } else if (_iCycleTime > _iMax) {
  459 + // 周转大,减间隔修正百分比
  460 + _fP -= 0.05;
  461 + } else {
  462 + break;
  463 + }
  464 +
  465 + _iCycleTime = 0;
  466 + _iIterCount ++;
  467 + }
  468 +
  469 + // console.log(_fP);
  470 +
  471 + return aBcInterval;
  472 +
  473 + }
  474 +
  475 + return main;
  476 +
  477 +} ());
0 \ No newline at end of file 478 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/interval/CalcuIntervalS1.js 0 → 100644
  1 +/**
  2 + * 计算发车间隔,每一圈的间隔,从上标线的班次开始。
  3 + */
  4 +var CalcuIntervalS1 = (function() {
  5 +
  6 +
  7 + /**
  8 + * 根据上一个班次的发车时间计算下一个班次的发车间隔。
  9 + * @param oPreBcFcTime 上一个班次发车时间
  10 + * @param oParam 参数对象
  11 + * @private
  12 + */
  13 + function _peakInterval(oPreBcFcTime, oParam, normalStep) {
  14 + var iBcInterval;
  15 + if (oParam.isMPeakBc(oPreBcFcTime)) {
  16 + iBcInterval = oParam.getMPeakMinFcjx() + normalStep;
  17 + return iBcInterval > oParam.getMPeakMaxFcjx() ? oParam.getMPeakMaxFcjx() : iBcInterval;
  18 +
  19 + } else if (oParam.isEPeakBc(oPreBcFcTime)) {
  20 + iBcInterval = oParam.getEPeakMinFcjx() + normalStep;
  21 + return iBcInterval > oParam.getEPeakMaxFcjx() ? oParam.getEPeakMaxFcjx() : iBcInterval;
  22 + } else {
  23 + throw "必须高峰班次";
  24 + }
  25 +
  26 +
  27 +
  28 + // 一般高峰时间段2个小时,使用如下间隔方法,以后还会修正
  29 + // 1、第一个20分钟使用高峰最大发车间隔
  30 + // 2、第二个20分钟使用高峰平均发车间隔(floor)
  31 + // 3、第三个20分钟使用高峰最小发车间隔
  32 + // 4、第四个20分钟使用高峰最小发车间隔
  33 + // 5、第五个20分钟使用高峰平均发车间隔(floor)
  34 + // 6、第六个20分钟使用高峰最大发车间隔
  35 +
  36 + // if (oParam.isMPeakBc(oPreBcFcTime)) {
  37 + // return oParam.getMPeakMaxFcjx();
  38 + // // if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 1 * 20))) {
  39 + // // return oParam.getMPeakMaxFcjx();
  40 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 2 * 20))) {
  41 + // // return Math.floor((oParam.getMPeakMinFcjx() + oParam.getMPeakMaxFcjx()) / 2);
  42 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 3 * 20))) {
  43 + // // return oParam.getMPeakMinFcjx();
  44 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 4 * 20))) {
  45 + // // return oParam.getMPeakMinFcjx();
  46 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 5 * 20))) {
  47 + // // return Math.floor((oParam.getMPeakMinFcjx() + oParam.getMPeakMaxFcjx()) / 2);
  48 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 6 * 20))) {
  49 + // // return oParam.getMPeakMaxFcjx();
  50 + // // } else {
  51 + // // return oParam.getMPeakMaxFcjx();
  52 + // // }
  53 + // } else if (oParam.isEPeakBc(oPreBcFcTime)) {
  54 + // return oParam.getEPeakMaxFcjx();
  55 + // // if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 1 * 20))) {
  56 + // // return oParam.getEPeakMaxFcjx();
  57 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 2 * 20))) {
  58 + // // return Math.floor((oParam.getEPeakMinFcjx() + oParam.getEPeakMaxFcjx()) / 2);
  59 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 3 * 20))) {
  60 + // // return oParam.getEPeakMinFcjx();
  61 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 4 * 20))) {
  62 + // // return oParam.getEPeakMinFcjx();
  63 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 5 * 20))) {
  64 + // // return Math.floor((oParam.getEPeakMinFcjx() + oParam.getEPeakMaxFcjx()) / 2);
  65 + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 6 * 20))) {
  66 + // // return oParam.getEPeakMaxFcjx();
  67 + // // } else {
  68 + // // return oParam.getEPeakMaxFcjx();
  69 + // // }
  70 + // } else {
  71 + // throw "必须高峰班次";
  72 + // }
  73 + }
  74 +
  75 +
  76 +
  77 +
  78 + /**
  79 + * 计算班次发车间隔。
  80 + * @param oInternalSchedule 行车计划对象
  81 + * @param oParam 参数对象
  82 + * @param groupIndex 圈索引
  83 + * @param bcIndex 班次索引
  84 + * @param normalFre 相同发车间隔班次数,频率
  85 + * @param normalStep 每次间隔变化的添加的分钟,步长
  86 + * @return {Array}
  87 + * @private
  88 + */
  89 + function _internalBcInterval(
  90 + oInternalSchedule, oParam,
  91 + groupIndex, bcIndex, normalFre, normalStep) {
  92 +
  93 + // 路牌列表
  94 + var aLp = oInternalSchedule.fnGetLpArray();
  95 +
  96 + if (normalFre < 1 || normalFre > aLp.length) {
  97 + alert("连续相同发车间隔班次数区间[1,路牌数],当前值=" + normalFre);
  98 + throw "连续相同发车间隔班次数区间[1,路牌数],当前值=" + normalFre;
  99 + }
  100 +
  101 + // 这个方法很重要用于生成每圈每个方向上的班次发车间隔
  102 + // 1、高峰班次全部高峰最大发车间隔
  103 + // 2、低谷第一个班次使用低谷最小发车间隔,连续相等的间隔班次数=normalFre,然后加1分钟,最大值是高峰最大发车间隔
  104 + // 5、TODO:主站方向在低谷拉间隔的时候,低谷拉到多少才是合理的(当行驶时间很大时,低谷最大发车间隔不一定合理),
  105 + // TODO: 此时需要和连班的间隔分班路牌数(抽车数),以及吃饭时间的大小共同考虑,
  106 + // TODO: 目前这样考虑,因为要抽车,如果没有足够的停站时间做调整,肯定会大间隔,当要抽车时,
  107 + // TODO:获取当前连班路牌和上一个连班路牌在前半圈的间隔值,当前连班路牌班次的停站时间至少大于低谷最大发车间隔减去这个值
  108 +
  109 + var i;
  110 + var j;
  111 + var oPreBc; // 上一个班次(从上标线班次开始)
  112 + var oCurrentBcFcTime; // 当前班次的发车时间
  113 + var oCurrentBcInterval; // 当前班次的发车间隔
  114 +
  115 + // 班次发车间隔,从oPreBc向前推normalFre个班次
  116 + var aBcInterval = [];
  117 + var iBcInterval;
  118 + var bIsIntervalEquale;
  119 + var iPreBcIntervalIndex;
  120 + var aBcInterval_rtn = []; // 最终返回的对象数组
  121 +
  122 + oPreBc = aLp[0].getBc(groupIndex, bcIndex);
  123 + if (oPreBc) {
  124 + // 先尝试获取上标线班次的interval
  125 + iBcInterval = aLp[0].fnGetVerticalIntervalTime(
  126 + groupIndex, bcIndex);
  127 + if (iBcInterval) { // 存在发车间隔
  128 + aBcInterval.push(iBcInterval);
  129 +
  130 + // 尝试获取前一圈同方向的(normalFre -1)个班次的发车间隔
  131 + j = 1;
  132 + if (groupIndex - 1 >= 0) {
  133 + for (i = aLp.length - 1; i >= 0; i--) {
  134 + if (j < normalFre) {
  135 + iBcInterval = aLp[i].fnGetVerticalIntervalTime(
  136 + groupIndex - 1, bcIndex);
  137 + if (iBcInterval) { // 存在发车间隔
  138 + aBcInterval.push(iBcInterval);
  139 + j++;
  140 + }
  141 + } else {
  142 + break;
  143 + }
  144 + }
  145 + }
  146 + }
  147 +
  148 + aBcInterval.reverse();
  149 + // 上一个班次间隔index
  150 + iPreBcIntervalIndex = aBcInterval.length - 1;
  151 +
  152 + var _iLpIndex;
  153 + for (i = 1; i <= aLp.length; i++) {
  154 + var oBcInterval_rtn =
  155 + {iLpIndex: null, hasBc: false, iFcInterval: null, iGroupIndex: null, iBcIndex: null};
  156 + // 注意这里是 this._internalLpArray.length,最后一个班次是下标线下一圈的同方向班次
  157 + _iLpIndex = i % aLp.length;
  158 +
  159 + if (_iLpIndex == 0) { // 下一圈的上标线同方向班次
  160 + oBcInterval_rtn.iLpIndex = 0;
  161 + oBcInterval_rtn.iGroupIndex = groupIndex + 1;
  162 + oBcInterval_rtn.iBcIndex = bcIndex;
  163 + } else {
  164 + oBcInterval_rtn.iLpIndex = _iLpIndex;
  165 + oBcInterval_rtn.iGroupIndex = groupIndex;
  166 + oBcInterval_rtn.iBcIndex = bcIndex;
  167 + }
  168 +
  169 + // 班型判定
  170 + if (_iLpIndex != 0) { // 回到上标线不用判定了
  171 + if (!oInternalSchedule._$fnDecideBxBc(
  172 + oPreBc, _iLpIndex - 1,
  173 + _iLpIndex,
  174 + groupIndex, bcIndex
  175 + )) {
  176 + aBcInterval_rtn.push(oBcInterval_rtn);
  177 + continue;
  178 + }
  179 + }
  180 +
  181 + if (oParam.isMPeakBc(oPreBc.getFcTimeObj())) { // 早高峰
  182 + // 如果上一个班次是早高峰班次,下一个班次使用_peakInterval计算早高峰发车间隔
  183 + // 如果下一个班次(加上_peakInterval计算的早高峰发车间隔后)是低谷班次,使用低谷最小发车间隔加一个步长值
  184 + oCurrentBcFcTime = oParam.addMinute(
  185 + oPreBc.getFcTimeObj(),
  186 + _peakInterval(oPreBc.getFcTimeObj(), oParam, normalStep));
  187 + // if (oParam.isTroughBc(oCurrentBcFcTime)) {
  188 + // iBcInterval = oParam.getTroughMinFcjx() + normalStep;
  189 + // oCurrentBcFcTime = oParam.addMinute(
  190 + // oPreBc.getFcTimeObj(),
  191 + // iBcInterval > oParam.getTroughMaxFcjx() ? oParam.getTroughMaxFcjx() : iBcInterval
  192 + // );
  193 + // }
  194 +
  195 + } else if (oParam.isEPeakBc(oPreBc.getFcTimeObj())) { // 晚高峰
  196 + // 如果上一个班次是晚高峰班次,下一个班次使用_peakInterval计算晚高峰发车间隔
  197 + // 如果下一个班次(加上_peakInterval计算的晚高峰发车间隔后)是低谷班次,使用低谷最小发车间隔加一个步长值
  198 + oCurrentBcFcTime = oParam.addMinute(
  199 + oPreBc.getFcTimeObj(),
  200 + _peakInterval(oPreBc.getFcTimeObj(), oParam, normalStep));
  201 + // if (oParam.isTroughBc(oCurrentBcFcTime)) {
  202 + // iBcInterval = oParam.getTroughMinFcjx() + normalStep;
  203 + // oCurrentBcFcTime = oParam.addMinute(
  204 + // oPreBc.getFcTimeObj(),
  205 + // iBcInterval > oParam.getTroughMaxFcjx() ? oParam.getTroughMaxFcjx() : iBcInterval
  206 + // );
  207 + // }
  208 + } else { // 上一个班次是低谷
  209 + if (aBcInterval.length < normalFre) { // 没有足够的连续班次间隔
  210 + // 如果没有足够的连续班次间隔,那一定是在初始化第一圈的班次
  211 + // 使用低谷最小发车间隔加一个步长值
  212 + iBcInterval = oParam.getTroughMinFcjx() + normalStep;
  213 + oCurrentBcFcTime = oParam.addMinute(
  214 + oPreBc.getFcTimeObj(),
  215 + iBcInterval > oParam.getTroughMaxFcjx() ? oParam.getTroughMaxFcjx() : iBcInterval
  216 + );
  217 + // // 如果进入高峰,使用最大发车间隔
  218 + // if (oParam.isMPeakBc(oCurrentBcFcTime)) {
  219 + // oCurrentBcFcTime = oParam.addMinute(
  220 + // oPreBc.getFcTimeObj(),
  221 + // oParam.getMPeakMaxFcjx()
  222 + // );
  223 + // }
  224 + // if (oParam.isEPeakBc(oCurrentBcFcTime)) {
  225 + // oCurrentBcFcTime = oParam.addMinute(
  226 + // oPreBc.getFcTimeObj(),
  227 + // oParam.getEPeakMaxFcjx()
  228 + // );
  229 + // }
  230 + } else { // 有足够的连续班次间隔
  231 + // 看连续班次间隔是否一致,一致 加 normalStep 分钟(不能超过低谷最大发车间隔),不一致就相等间隔
  232 + // 加了间隔后,如果是高峰班次,则使用高峰最大发车间隔
  233 + // TODO:什么时候开始减低谷发车间隔到最小发车间隔,应该是在吃了饭之后
  234 +
  235 + bIsIntervalEquale = true;
  236 + for (j = iPreBcIntervalIndex; j > iPreBcIntervalIndex - normalFre + 1; j--) {
  237 + if (aBcInterval[j] != aBcInterval[j - 1]) {
  238 + bIsIntervalEquale = false;
  239 + break;
  240 + }
  241 + }
  242 + if (bIsIntervalEquale) {
  243 + // 需要变换频率数据了
  244 +
  245 + // TODO:14:00后开始到16:00之间减少低谷发车间隔
  246 + if (oPreBc.getFcTimeObj().isAfter(oParam.toTimeObj("14:00")) &&
  247 + oPreBc.getFcTimeObj().isBefore(oParam.toTimeObj("16:00"))) {
  248 + iBcInterval = aBcInterval[iPreBcIntervalIndex] - normalStep;
  249 + oCurrentBcFcTime = oParam.addMinute(
  250 + oPreBc.getFcTimeObj(),
  251 + iBcInterval < oParam.getTroughMinFcjx() ? oParam.getTroughMinFcjx() : iBcInterval
  252 + );
  253 + } else {
  254 + iBcInterval = aBcInterval[iPreBcIntervalIndex] + normalStep;
  255 + oCurrentBcFcTime = oParam.addMinute(
  256 + oPreBc.getFcTimeObj(),
  257 + iBcInterval > oParam.getTroughMaxFcjx() ? oParam.getTroughMaxFcjx() : iBcInterval
  258 + );
  259 + }
  260 + } else {
  261 + // 不需要变换频率,使用上一个班次的间隔
  262 + oCurrentBcFcTime = oParam.addMinute(
  263 + oPreBc.getFcTimeObj(),
  264 + aBcInterval[iPreBcIntervalIndex]
  265 + );
  266 + }
  267 +
  268 + // // 如果进入高峰使用高峰最大发车间隔
  269 + // if (oParam.isMPeakBc(oCurrentBcFcTime)) {
  270 + // oCurrentBcFcTime = oParam.addMinute(
  271 + // oPreBc.getFcTimeObj(),
  272 + // oParam.getMPeakMaxFcjx()
  273 + // );
  274 + // }
  275 + // if (oParam.isEPeakBc(oCurrentBcFcTime)) {
  276 + // oCurrentBcFcTime = oParam.addMinute(
  277 + // oPreBc.getFcTimeObj(),
  278 + // oParam.getEPeakMaxFcjx()
  279 + // );
  280 + // }
  281 +
  282 + }
  283 +
  284 + }
  285 +
  286 + // 判定超出末班车,就没有班次
  287 + if (oPreBc.isUp()) {
  288 + if (oCurrentBcFcTime.isAfter(
  289 + oParam.addMinute(oParam.getUpLastDtimeObj(), 30))) {
  290 + aBcInterval_rtn.push(oBcInterval_rtn);
  291 + continue;
  292 + }
  293 + } else {
  294 + if (oCurrentBcFcTime.isAfter(
  295 + oParam.addMinute(oParam.getDownLastDTimeObj(), 30))) {
  296 + aBcInterval_rtn.push(oBcInterval_rtn);
  297 + continue;
  298 + }
  299 + }
  300 +
  301 + oCurrentBcInterval = oCurrentBcFcTime.diff(oPreBc.getFcTimeObj(), "m");
  302 + aBcInterval.push(oCurrentBcInterval);
  303 + oPreBc = oInternalSchedule.fnGetUitls().createBcObj(
  304 + aLp[_iLpIndex],
  305 + "normal",
  306 + oPreBc.isUp(),
  307 + 1,
  308 + oCurrentBcFcTime,
  309 + oParam
  310 + );
  311 + iPreBcIntervalIndex++;
  312 + oBcInterval_rtn.hasBc = true;
  313 + oBcInterval_rtn.iFcInterval = oCurrentBcInterval;
  314 + aBcInterval_rtn.push(oBcInterval_rtn);
  315 + }
  316 +
  317 + }
  318 +
  319 + return aBcInterval_rtn;
  320 + }
  321 +
  322 +
  323 + function main(
  324 + oInternalSchedule, oParam,
  325 + iGroupIndex, iBcIndex, iMinCycleTime, iMaxCycleTime) {
  326 +
  327 + var iFre = 3; // 频率,连续相同发车间隔班次数
  328 + var iStep = 1; // 步长,每个频率后变化1分钟
  329 + var aBcInterval; // 每次计算返回的指定圈的间隔数组
  330 + var iCycleTime = 0; // 每次计算放回的周转时间(把所有的间隔加在一起)
  331 + var i;
  332 +
  333 + var iterCount = 0;
  334 + var maxIter = 50; // 最多5次迭代,防止死循环
  335 +
  336 + console.log(iMinCycleTime);
  337 + console.log(iMaxCycleTime);
  338 +
  339 + // TODO:先用最小值判定,后面再考虑最大值
  340 + while (iCycleTime < iMinCycleTime && iterCount <= maxIter) {
  341 + aBcInterval = _internalBcInterval(
  342 + oInternalSchedule, oParam,
  343 + iGroupIndex, iBcIndex, iFre, iStep);
  344 + iCycleTime = 0; // 间隔加在一起就是周转
  345 + for (i = 0; i < aBcInterval.length; i++) {
  346 + if (aBcInterval[i].hasBc) {
  347 + iCycleTime += aBcInterval[i].iFcInterval;
  348 + }
  349 + }
  350 +
  351 + // 下一次迭代,先降低频率直到1,然后再增加步长
  352 + iFre = iFre > 1 ? iFre - 1 : 1;
  353 + iStep = iFre == 1 ? (iStep + 1) : 1;
  354 + iterCount ++;
  355 + }
  356 +
  357 + return aBcInterval;
  358 +
  359 + }
  360 +
  361 + return main;
  362 +
  363 +} ());
  364 +
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/layovertime/LayoverTimeS1.js 0 → 100644
  1 +/**
  2 + * 计算班次停站layover时间S1。
  3 + * 主站停站,返回时间范围[最小,最大]
  4 + */
  5 +var LayoverTimeS1 = (function() {
  6 +
  7 + /**
  8 + * 主函数。
  9 + * @param oFcTime 发车时间
  10 + * @param isUp 是否上下行
  11 + * @param fnCalcuRuntime 计算行驶时间函数(LinearRuntimeS1策略函数)
  12 + * @param oParam 参数对象
  13 + */
  14 + function main(oFcTime, isUp, fnCalcuRuntime, oParam) {
  15 + var iMinLT; // 最小停站时间
  16 + var iMaxLT; // 最大停站时间
  17 + if (oParam.getDirAnotherWayStop() == isUp) {
  18 + // 副站停站
  19 + iMinLT = 1; // 最小1分钟
  20 + iMaxLT = 3; // 最大3分钟
  21 + } else {
  22 + // 计算当前方向行驶时间
  23 + var iRT1 = fnCalcuRuntime(isUp, oFcTime, oParam);
  24 + // 计算下一个方向的行驶时间
  25 + var oArrTime = oParam.addMinute(oFcTime, iRT1);
  26 + var iRT2 = fnCalcuRuntime(!isUp, oArrTime, oParam);
  27 +
  28 + if (oParam.isTroughBc(oArrTime)) {
  29 + // 低谷,行驶时间的15%-20%,最少10分钟
  30 + iMinLT = Math.floor((iRT1 + iRT2) * 0.15);
  31 + iMaxLT = Math.ceil((iRT1 + iRT2) * 0.20);
  32 + if (iMaxLT < 10) {
  33 + iMinLT = 10;
  34 + iMaxLT = 10;
  35 + }
  36 + } else {
  37 + // 早晚高峰,行驶时间的10%-15%,最少3分钟
  38 + iMinLT = Math.floor((iRT1 + iRT2) * 0.10);
  39 + iMaxLT = Math.ceil((iRT1 + iRT2) * 0.15);
  40 + if (iMaxLT < 3) {
  41 + iMinLT = 3;
  42 + iMaxLT = 3;
  43 + }
  44 + }
  45 +
  46 +
  47 + }
  48 + return [iMinLT, iMaxLT];
  49 + }
  50 +
  51 + return main;
  52 +
  53 +} ());
0 \ No newline at end of file 54 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/runtime/LinearRuntimeS1.js 0 → 100644
  1 +/**
  2 + * 计算行驶时间策略1.
  3 + * 参数提供早晚高峰行驶时间,低谷行驶时间。
  4 + * 具体班次的行驶时间使用线性函数计算,f(x)=ax+b x=班次发车时间,是一个分段函数,说明如下:
  5 + * 1、低谷到早高峰开始:使用低谷行驶时间作线性变化到早高峰行驶时间(一般是从小到大)
  6 + * 2、早高峰:使用早高峰行驶时间
  7 + * 3、早高峰结束到14:00:使用早高峰行驶时间线性变化到低谷行驶时间(一般是从大到小)
  8 + * 4、14:00到晚高峰开始:使用低谷行驶时间线性变化到晚高峰行驶时间(一般是从小到大)
  9 + * 5、晚高峰:使用晚高峰行驶时间
  10 + * 6、晚高峰结束到低谷:使用晚高峰行驶时间线性变化到低谷行驶时间(一般是从大到小)
  11 + */
  12 +var LinearRuntimeS1 = (function() {
  13 + // 1、低谷到早高峰开始:使用低谷行驶时间作线性变化到早高峰行驶时间(一般是从小到大)
  14 + function _fn1(bIsUp, oFcTime, oParam) {
  15 + var a; // slope,斜率
  16 + var b; // 偏置值
  17 + var _a1;
  18 + var _a2;
  19 + if (bIsUp) { // 上行
  20 + _a1 = oParam.getUpMPeakTime() - oParam.getUpTroughTime();
  21 + _a2 = oParam.getMPeakStartTimeObj().valueOf() - oParam.getUpFirstDTimeObj().valueOf();
  22 + a = _a1 / _a2;
  23 + b = oParam.getUpMPeakTime() - a * oParam.getMPeakStartTimeObj().valueOf();
  24 + } else { // 下行
  25 + _a1 = oParam.getDownMPeakTime() - oParam.getDownTroughTime();
  26 + _a2 = oParam.getMPeakStartTimeObj().valueOf() - oParam.getDownFirstDTimeObj().valueOf();
  27 +
  28 + a = _a1 / _a2;
  29 + b = oParam.getDownMPeakTime() - a * oParam.getMPeakStartTimeObj().valueOf();
  30 + }
  31 + return Math.floor(a * oFcTime.valueOf() + b);
  32 + }
  33 + // 2、早高峰:使用早高峰行驶时间
  34 + function _fn2(bIsUp, oFcTime, oParam) {
  35 + if (bIsUp) {
  36 + return oParam.getUpMPeakTime();
  37 + } else {
  38 + return oParam.getDownMPeakTime();
  39 + }
  40 + }
  41 + // 3、早高峰结束到14:00:使用早高峰行驶时间线性变化到低谷行驶时间(一般是从大到小)
  42 + function _fn3(bIsUp, oFcTime, oParam) {
  43 + var a; // slope,斜率
  44 + var b; // 偏置值
  45 + if (bIsUp) {
  46 + a = ((oParam.getUpTroughTime() - oParam.getUpMPeakTime()) /
  47 + (oParam.toTimeObj("14:00").valueOf() - oParam.getMPeakEndTimeObj().valueOf()));
  48 + b = oParam.getUpTroughTime() - a * oParam.toTimeObj("14:00").valueOf();
  49 + } else {
  50 + a = ((oParam.getDownTroughTime() - oParam.getDownMPeakTime()) /
  51 + (oParam.toTimeObj("14:00").valueOf() - oParam.getMPeakEndTimeObj().valueOf()));
  52 + b = oParam.getDownTroughTime() - a * oParam.toTimeObj("14:00").valueOf();
  53 + }
  54 + return Math.floor(a * oFcTime.valueOf() + b);
  55 + }
  56 + // 4、14:00到晚高峰开始:使用低谷行驶时间线性变化到晚高峰行驶时间(一般是从小到大)
  57 + function _fn4(bIsUp, oFcTime, oParam) {
  58 + var a; // slope,斜率
  59 + var b; // 偏置值
  60 + if (bIsUp) {
  61 + a = ((oParam.getUpEPeakTime() - oParam.getUpTroughTime()) /
  62 + (oParam.getEPeakStartTimeObj().valueOf() - oParam.toTimeObj("14:00").valueOf()));
  63 + b = oParam.getUpEPeakTime() - a * oParam.getEPeakStartTimeObj().valueOf();
  64 + } else {
  65 + a = ((oParam.getDownEPeakTime() - oParam.getDownTroughTime()) /
  66 + (oParam.getEPeakStartTimeObj().valueOf() - oParam.toTimeObj("14:00").valueOf()));
  67 + b = oParam.getDownEPeakTime() - a * oParam.getEPeakStartTimeObj().valueOf();
  68 + }
  69 + return Math.floor(a * oFcTime.valueOf() + b);
  70 + }
  71 + // 5、晚高峰:使用晚高峰行驶时间
  72 + function _fn5(bIsUp, oFcTime, oParam) {
  73 + if (bIsUp) {
  74 + return oParam.getUpEPeakTime();
  75 + } else {
  76 + return oParam.getDownEPeakTime();
  77 + }
  78 + }
  79 + // 6、晚高峰结束到低谷:使用晚高峰行驶时间线性变化到低谷行驶时间(一般是从大到小)
  80 + function _fn6(bIsUp, oFcTime, oParam) {
  81 + var a; // slope,斜率
  82 + var b; // 偏置值
  83 + if (bIsUp) {
  84 + a = ((oParam.getUpTroughTime() - oParam.getUpEPeakTime()) /
  85 + (oParam.getUpLastDtimeObj().valueOf() - oParam.getEPeakEndTimeObj().valueOf()));
  86 + b = oParam.getUpTroughTime() - a * oParam.getUpLastDtimeObj().valueOf();
  87 + } else {
  88 + a = ((oParam.getDownTroughTime() - oParam.getDownEPeakTime()) /
  89 + (oParam.getDownLastDTimeObj().valueOf() - oParam.getEPeakEndTimeObj().valueOf()));
  90 + b = oParam.getDownTroughTime() - a * oParam.getDownLastDTimeObj().valueOf();
  91 + }
  92 + return Math.floor(a * oFcTime.valueOf() + b);
  93 + }
  94 +
  95 +
  96 + /**
  97 + * 主函数。
  98 + * @param bIsUp 是否上行
  99 + * @param oFcTime 发车时间
  100 + * @param oParam 参数对象
  101 + */
  102 + function main(bIsUp, oFcTime, oParam) {
  103 + if (oFcTime.isBefore(oParam.getMPeakStartTimeObj())) {
  104 + return _fn1(bIsUp, oFcTime, oParam);
  105 + } else if (oParam.isMPeakBc(oFcTime)) {
  106 + return _fn2(bIsUp, oFcTime, oParam);
  107 + } else if (oFcTime.isBefore(oParam.toTimeObj("14:00"))) {
  108 + return _fn3(bIsUp, oFcTime, oParam);
  109 + } else if (oFcTime.isBefore(oParam.getEPeakStartTimeObj())) {
  110 + return _fn4(bIsUp, oFcTime, oParam);
  111 + } else if (oParam.isEPeakBc(oFcTime)) {
  112 + return _fn5(bIsUp, oFcTime, oParam);
  113 + } else {
  114 + return _fn6(bIsUp, oFcTime, oParam);
  115 + }
  116 + }
  117 +
  118 + return main;
  119 +} ());
0 \ No newline at end of file 120 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/workhours/ModifyBcTripWHS1.js 0 → 100644
  1 +/**
  2 + * 判定路牌每圈是否出班次。
  3 + * TODO:
  4 + */
  5 +var ModifyBcTripWHS1 = (function() {
  6 +
  7 + /**
  8 + * 判定班型班次,主方法。
  9 + * @param oInternalSchedule
  10 + * @param oParam
  11 + * @param oPreBc
  12 + * @param iPreLpIndex
  13 + * @param iCurrentLpIndex
  14 + * @param iCurrentGroupIndex
  15 + * @param iCurrentBcIndex
  16 + */
  17 + function main(
  18 + oInternalSchedule, oParam,
  19 + oPreBc, iPreLpIndex,
  20 + iCurrentLpIndex, iCurrentGroupIndex, iCurrentBcIndex) {
  21 +
  22 +
  23 + var oCurrentLp = oInternalSchedule.fnGetLpArray()[iCurrentLpIndex]; // 当前路牌
  24 + var oLpPreBc; // 当前路牌前一个班次
  25 +
  26 + var iBxBcount; // 分班班型的可能班次数
  27 +
  28 + if (oCurrentLp.isBxFb()) { // 分班
  29 + // 关联的因素
  30 + // 1、当前班次方向
  31 + // 2、上一个班次情况
  32 + // 3、同路牌前一个班次情况
  33 + // 4、分班路牌工时限制
  34 +
  35 +
  36 + if (oCurrentLp.isBxFb5_2()) { // 5休2分班
  37 + // 大致计算5休2班型班次数
  38 + iBxBcount = oInternalSchedule.fnGetBxDesc()[6].fBcCount;
  39 + if (iBxBcount - Math.floor(iBxBcount) > 0.7) {
  40 + iBxBcount = Math.floor(iBxBcount) + 1;
  41 + } else {
  42 + iBxBcount = Math.floor(iBxBcount);
  43 + }
  44 +
  45 + // 计算可能的5休2班次时间,供下一步判定
  46 + var oNext5_2_bc_fctime_m = undefined; // 上午车次链参考班次时间
  47 + var oNext5_2_bc_fctime_e = undefined; // 下午车次链参考班次时间
  48 + if (oPreBc.getFcTimeObj().isBefore(oParam.toTimeObj("12:00"))) { // 上午车次链
  49 + oNext5_2_bc_fctime_m = oParam.addMinute(
  50 + oPreBc.getFcTimeObj(),
  51 + Math.ceil((oParam.getMPeakMinFcjx() + oParam.getMPeakMaxFcjx()) / 2)
  52 + );
  53 + } else { // 下午车次链
  54 + oNext5_2_bc_fctime_e = oParam.addMinute(
  55 + oPreBc.getFcTimeObj(),
  56 + Math.ceil((oParam.getEPeakMinFcjx() + oParam.getEPeakMaxFcjx()) / 2)
  57 + );
  58 + }
  59 +
  60 + // 先处理上午车次链
  61 + if (oNext5_2_bc_fctime_m) {
  62 + if (oNext5_2_bc_fctime_m.isBefore(oParam.getMPeakStartTimeObj())) {
  63 + // 5休2班型第一个班次,如果在早高峰开始前低谷,不添加
  64 + return false;
  65 + } else if (!oNext5_2_bc_fctime_m.isAfter(oParam.getMPeakEndTimeObj())) {
  66 + // 早高峰期间,添加
  67 + return true;
  68 + } else {
  69 + // 早高峰之后低谷到12:00之间
  70 +
  71 + // 当前路牌的前一个班次
  72 + oLpPreBc = oCurrentLp.getBc(iCurrentBcIndex == 0 ?
  73 + iCurrentGroupIndex - 1 : iCurrentGroupIndex, iCurrentBcIndex == 0 ? 1 : 0);
  74 + if (oCurrentLp.getBcArray().length > 0 && (!oLpPreBc)) {
  75 + // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加
  76 + return false;
  77 + } else {
  78 + if (oCurrentLp.getBcArray().length < Math.ceil(iBxBcount / 2)) {
  79 + // 如果总班次数比iBxBcount的一半的班次(ceil)少,加班次
  80 + return true;
  81 + } else if (oLpPreBc.isUp() == oParam.isUpOneWayStop()) {
  82 + // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站
  83 + // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次
  84 + return true;
  85 + } else {
  86 + return false;
  87 + }
  88 + }
  89 + }
  90 + }
  91 +
  92 + // 再处理下午车次链
  93 + if (oNext5_2_bc_fctime_e) {
  94 + if (oNext5_2_bc_fctime_e.isBefore(oParam.getEPeakStartTimeObj())) {
  95 + if (oParam.isEPeakBc(oPreBc.getArrTimeObj())) {
  96 + // 如果上一个班次的到达时间在高峰内,也要加
  97 + return true;
  98 + }
  99 +
  100 + // 5休2班型第一个班次,如果在晚高峰开始前低谷,不添加
  101 + return false;
  102 + } else if (!oNext5_2_bc_fctime_e.isAfter(oParam.getEPeakEndTimeObj())) {
  103 + // 晚高峰期间,添加
  104 + return true;
  105 + } else {
  106 + // 晚高峰之后低谷
  107 +
  108 + // 当前路牌的前一个班次
  109 + oLpPreBc = oCurrentLp.getBc(iCurrentBcIndex == 0 ?
  110 + iCurrentGroupIndex - 1 : iCurrentGroupIndex, iCurrentBcIndex == 0 ? 1 : 0);
  111 + if (oCurrentLp.getBcArray().length > 0 && (!oLpPreBc)) {
  112 + // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加
  113 + return false;
  114 + } else {
  115 + if (oCurrentLp.getBcArray().length < iBxBcount) {
  116 + // 如果总班次数比iBxBcount少,加班次
  117 + return true;
  118 + } else if (oLpPreBc.isUp() == oParam.isUpOneWayStop()) {
  119 + // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站
  120 + // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次
  121 + return true;
  122 + } else {
  123 + return false;
  124 + }
  125 + }
  126 + }
  127 + }
  128 +
  129 + } else { // 其他分班
  130 + // TODO:根据上标线的首班时间确定班型,小于05:59的做一休一,否则做二休一
  131 + var oSt = oInternalSchedule.fnGetGroupIsUp() ?
  132 + oParam.getUpFirstDTimeObj() : oParam.getDownFirstDTimeObj();
  133 + var iBxIndex = 4;
  134 + if (oSt.isBefore(oParam.toTimeObj("05:59"))) {
  135 + iBxIndex = 5;
  136 + }
  137 + // 大致计算做其他班型所需的班次数
  138 + var iQBcount = oInternalSchedule.fnGetBxDesc()[iBxIndex].fQCount;
  139 + iBxBcount = Math.ceil(iQBcount) * 2;
  140 +
  141 + // 计算可能的其他分班当前班次时间,供下一步判定
  142 + var oNext_other_bc_fctime_m = undefined; // 上午车次链参考班次时间
  143 + var oNext_other_bc_fctime_e = undefined; // 下午车次链参考班次时间
  144 + if (oPreBc.getFcTimeObj().isBefore(oParam.toTimeObj("15:00"))) { // 上午车次链
  145 + oNext_other_bc_fctime_m = oParam.addMinute(
  146 + oPreBc.getFcTimeObj(),
  147 + Math.ceil((oParam.getMPeakMinFcjx() + oParam.getMPeakMaxFcjx()) / 2)
  148 + );
  149 + } else { // 下午车次链
  150 + oNext_other_bc_fctime_e = oParam.addMinute(
  151 + oPreBc.getFcTimeObj(),
  152 + Math.ceil((oParam.getEPeakMinFcjx() + oParam.getEPeakMaxFcjx()) / 2)
  153 + );
  154 + }
  155 +
  156 + // 先处理上午车次链
  157 + if (oNext_other_bc_fctime_m) {
  158 + if (oNext_other_bc_fctime_m.isBefore(oParam.getMPeakStartTimeObj())) {
  159 + // 5休2班型第一个班次,如果在早高峰开始前低谷,不添加
  160 + return false;
  161 + }
  162 +
  163 + // TODO:其他分班随连班上午开始就出车,具体出车时间可能还要和低谷周转时间一起考虑
  164 + // 当前路牌的前一个班次
  165 + oLpPreBc = oCurrentLp.getBc(iCurrentBcIndex == 0 ?
  166 + iCurrentGroupIndex - 1 : iCurrentGroupIndex, iCurrentBcIndex == 0 ? 1 : 0);
  167 + if (oCurrentLp.getBcArray().length == 0) {
  168 + return true;
  169 + } else if (!oLpPreBc) {
  170 + // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加
  171 + return false;
  172 + } else {
  173 + if (oCurrentLp.getBcArray().length < Math.ceil(iBxBcount / 2)) {
  174 + // 如果总班次数比iBxBcount的一半的班次(ceil)少,加班次
  175 + return true;
  176 + } else if (oLpPreBc.isUp() == oParam.isUpOneWayStop()) {
  177 + // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站
  178 + // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次
  179 + return true;
  180 + } else {
  181 + return false;
  182 + }
  183 + }
  184 +
  185 + }
  186 +
  187 + // 再处理下午车次链
  188 + if (oNext_other_bc_fctime_e) {
  189 + // TODO:下午14:00后开始添加,加入时间可能还要和低谷周转时间一起考虑
  190 + // 当前路牌的前一个班次
  191 + oLpPreBc = oCurrentLp.getBc(iCurrentBcIndex == 0 ?
  192 + iCurrentGroupIndex - 1 : iCurrentGroupIndex, iCurrentBcIndex == 0 ? 1 : 0);
  193 + if (oCurrentLp.getBcArrayFromTime(oParam.toTimeObj("15:00")).length == 0) {
  194 + return true;
  195 + } else if (!oLpPreBc) {
  196 + // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加
  197 + return false;
  198 + } else {
  199 + if (oCurrentLp.getBcArray().length < iBxBcount) {
  200 + // 如果总班次数比iBxBcount少,加班次
  201 + return true;
  202 + } else if (oParam.isEPeakBc(oNext_other_bc_fctime_e)) {
  203 + return true;
  204 + }
  205 + else if (oLpPreBc.isUp() == oParam.isUpOneWayStop()) {
  206 + // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站
  207 + // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次
  208 + return true;
  209 + } else {
  210 + return false;
  211 + }
  212 + }
  213 +
  214 + }
  215 +
  216 + }
  217 + } else { // 连班班型,高峰低谷都有班次
  218 + return true;
  219 + }
  220 +
  221 +
  222 + }
  223 +
  224 + return main;
  225 +} ());
0 \ No newline at end of file 226 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/paramadd.html
@@ -423,9 +423,10 @@ @@ -423,9 +423,10 @@
423 </script> 423 </script>
424 424
425 <script type="text/javascript"> 425 <script type="text/javascript">
426 - $('#paramadd_mobal').on('paramAddMobal.show', function(e, mainFun){  
427 - 426 + $('#paramadd_mobal').on('paramAddMobal.show', function(e, mainFun, mainFun2_2, oSchedule_v2_2){
428 var _mainFun = mainFun; 427 var _mainFun = mainFun;
  428 + var _mainFun_v2_2 = mainFun2_2;
  429 + var _oSchedule_v2_2 = oSchedule_v2_2;
429 430
430 // 加载延迟200毫秒显示mobal 431 // 加载延迟200毫秒显示mobal
431 setTimeout(function(){$('#paramadd_mobal').modal({show : true,backdrop: 'static', keyboard: false});},200); 432 setTimeout(function(){$('#paramadd_mobal').modal({show : true,backdrop: 'static', keyboard: false});},200);
@@ -540,20 +541,30 @@ @@ -540,20 +541,30 @@
540 var csMap = getCSMap(paramObj); 541 var csMap = getCSMap(paramObj);
541 // console.log(graph); 542 // console.log(graph);
542 543
543 - var data = _mainFun.BXPplaceClassesTime03(paramObj, csMap.maxCar);  
544 - _mainFun.exportDataConfig(data.aInternalLpObj); 544 + var data;
  545 +
  546 + if (ganttMap.baseRes == "2") { // v2版本
  547 + data = _mainFun.BXPplaceClassesTime03(paramObj, csMap.maxCar);
  548 + _mainFun.exportDataConfig(data.aInternalLpObj);
  549 + } else if (ganttMap.baseRes == "3") { // v2_2版本
  550 + csMap = getCSMap_v2(paramObj);
  551 + data = _mainFun_v2_2.BXPplaceClassesTime03(paramObj, csMap.maxCar);
  552 + _mainFun_v2_2.exportDataConfig(data.aInternalLpObj);
  553 + }
  554 +
  555 + echartsDrawGTT.init(data.json,true,true);
545 556
546 // var data = obj.getDataArray(); 557 // var data = obj.getDataArray();
547 // // 2、 调整路牌对应的班次总数 558 // // 2、 调整路牌对应的班次总数
548 // updFormParams(params,data); 559 // updFormParams(params,data);
549 // 删除图形. 560 // 删除图形.
550 - $('svg.svg-chart').remove();  
551 - // 重新创建图形.  
552 - var graph = d3.select('#ganttSvg').relationshipGraph(getGraphArgus(csMap, dataMap, data));  
553 - // 根据数据重新渲染图形.  
554 - graph.data(data.json);  
555 - // 记录早操.并保存历史班次数据  
556 - graph.addHistory(); 561 + // $('svg.svg-chart').remove();
  562 + // // 重新创建图形.
  563 + // var graph = d3.select('#ganttSvg').relationshipGraph(getGraphArgus(csMap, dataMap, data));
  564 + // // 根据数据重新渲染图形.
  565 + // graph.data(data.json);
  566 + // // 记录早操.并保存历史班次数据
  567 + // graph.addHistory();
557 // 隐藏错误提示 568 // 隐藏错误提示
558 paramAlert.hide(); 569 paramAlert.hide();
559 // 隐藏 reladplus_mobal 弹出层 570 // 隐藏 reladplus_mobal 弹出层
@@ -857,7 +868,13 @@ @@ -857,7 +868,13 @@
857 }; 868 };
858 869
859 var _paramObj = _mainFun.getFactory().createParameterObj(map, dataMap); 870 var _paramObj = _mainFun.getFactory().createParameterObj(map, dataMap);
860 - map.clzs = _paramObj.calcuClzx(); 871 +
  872 + if (!_paramObj.isTwoWayStop()) { // 主站停站使用v2_2版本
  873 + map.clzs = _oSchedule_v2_2.calcuClzx(_paramObj);
  874 + } else {
  875 + map.clzs = _paramObj.calcuClzx();
  876 + }
  877 +
861 return [_paramObj, dataMap]; 878 return [_paramObj, dataMap];
862 879
863 } 880 }
@@ -870,6 +887,15 @@ @@ -870,6 +887,15 @@
870 'dgmaxfcjx' : parseInt(map.dgmaxfcjx)}, 887 'dgmaxfcjx' : parseInt(map.dgmaxfcjx)},
871 'maxCar':getYAxisCarArray(parseInt(parmObj.calcuClzx()))}; 888 'maxCar':getYAxisCarArray(parseInt(parmObj.calcuClzx()))};
872 } 889 }
  890 + function getCSMap_v2(parmObj) {
  891 + var map = JSON.parse(window.localStorage.Gantt_AgursData);
  892 + return {'gattA':null,
  893 + 'fcjx': {'gffcjx': Math.round(parmObj.calcuPeakZzsj()/parmObj.calcuClzx()) ,
  894 + 'dgfcjx': Math.round(parmObj.calcuTroughZzsj()/parmObj.calcuClzx()),
  895 + 'dgmaxfcjx' : parseInt(map.dgmaxfcjx)},
  896 + 'maxCar':getYAxisCarArray(_oSchedule_v2_2.calcuClzx(parmObj))};
  897 + }
  898 +
873 899
874 function getGraphArgus(CSMap, dataMap, data) { 900 function getGraphArgus(CSMap, dataMap, data) {
875 // TODO 901 // TODO
src/main/resources/static/pages/scheduleApp/module/core/ttInfoManage/list.html
@@ -176,8 +176,8 @@ @@ -176,8 +176,8 @@
176 <!--class="btn btn-info btn-sm" ng-if="info.isCancel == '0'"> 编辑2 </a>--> 176 <!--class="btn btn-info btn-sm" ng-if="info.isCancel == '0'"> 编辑2 </a>-->
177 <a ui-sref="ttInfoDetailManage_edit3({xlid: info.xl.id, ttid : info.id, xlname: info.xl.name, ttname : info.name, rflag : true, lineversion : info.lineVersion})" 177 <a ui-sref="ttInfoDetailManage_edit3({xlid: info.xl.id, ttid : info.id, xlname: info.xl.name, ttname : info.name, rflag : true, lineversion : info.lineVersion})"
178 class="btn btn-info btn-sm" ng-if="info.isCancel == '0'"> 编辑 </a> 178 class="btn btn-info btn-sm" ng-if="info.isCancel == '0'"> 编辑 </a>
179 - <!--<a ng-click="ctrl.toTtInfoDetailAuto(info.id)"-->  
180 - <!--class="btn btn-info btn-sm" ng-if="info.isCancel == '0'"> 生成 </a>--> 179 + <a ng-click="ctrl.toTtInfoDetailAuto(info.id)"
  180 + class="btn btn-info btn-sm" ng-if="info.isCancel == '0'"> 生成 </a>
181 <a ui-sref="ttInfoDetailManage_form({xlid: info.xl.id, ttid : info.id, xlname: info.xl.name, ttname : info.name})" 181 <a ui-sref="ttInfoDetailManage_form({xlid: info.xl.id, ttid : info.id, xlname: info.xl.name, ttname : info.name})"
182 class="btn btn-info btn-sm" ng-if="info.isCancel == '0'"> 导入 </a> 182 class="btn btn-info btn-sm" ng-if="info.isCancel == '0'"> 导入 </a>
183 <a href="javascript:" class="btn btn-info btn-sm" ng-click="ctrl.exportData(info.id)"> 导出 </a> 183 <a href="javascript:" class="btn btn-info btn-sm" ng-click="ctrl.exportData(info.id)"> 导出 </a>