Commit 8bcd7dea7ebf8fd49313e6ffded7ef839877bc06

Authored by 徐烜
1 parent 893a4fd8

时刻表v2.7

将动态时刻表的数据和统计数据导出成格式xlsx文档
src/main/java/com/bsth/controller/schedule/core/TTInfoDetailController.java
@@ -5,9 +5,13 @@ import com.bsth.controller.schedule.BController; @@ -5,9 +5,13 @@ import com.bsth.controller.schedule.BController;
5 import com.bsth.entity.schedule.TTInfoDetail; 5 import com.bsth.entity.schedule.TTInfoDetail;
6 import com.bsth.service.schedule.TTInfoDetailService; 6 import com.bsth.service.schedule.TTInfoDetailService;
7 import com.bsth.service.schedule.datatools.TTInfoDetailForEdit; 7 import com.bsth.service.schedule.datatools.TTInfoDetailForEdit;
  8 +import com.bsth.service.schedule.datatools.TTinfoDetailDynamicData;
  9 +import com.bsth.service.schedule.utils.DataToolsFile;
8 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.beans.factory.annotation.Autowired;
9 import org.springframework.web.bind.annotation.*; 11 import org.springframework.web.bind.annotation.*;
10 12
  13 +import javax.servlet.http.HttpServletResponse;
  14 +import java.io.*;
11 import java.util.HashMap; 15 import java.util.HashMap;
12 import java.util.List; 16 import java.util.List;
13 import java.util.Map; 17 import java.util.Map;
@@ -120,4 +124,32 @@ public class TTInfoDetailController extends BController<TTInfoDetail, Long> { @@ -120,4 +124,32 @@ public class TTInfoDetailController extends BController<TTInfoDetail, Long> {
120 public Map<String, Object> skbDetailMxSave(@RequestParam Map<String, Object> entities){ 124 public Map<String, Object> skbDetailMxSave(@RequestParam Map<String, Object> entities){
121 return ttInfoDetailService.skbDetailMxSave(entities); 125 return ttInfoDetailService.skbDetailMxSave(entities);
122 } 126 }
  127 +
  128 +
  129 + @RequestMapping(value = "/exportDTDFile", method = RequestMethod.POST)
  130 + public void exportFile(
  131 + @RequestBody TTinfoDetailDynamicData.DTInfos dtInfos,
  132 + HttpServletResponse response) throws Exception {
  133 + DataToolsFile dataToolsFile = ttInfoDetailService.exportDynamicTTinfo(dtInfos);
  134 + // 流输出导出文件
  135 + response.setHeader("content-type", "application/octet-stream");
  136 + response.setHeader("Content-Disposition", "attachment; filename=" + dataToolsFile.getFile().getName());
  137 + response.setContentType("application/octet-stream");
  138 +
  139 + OutputStream os = response.getOutputStream();
  140 + BufferedOutputStream bos = new BufferedOutputStream(os);
  141 +
  142 + InputStream is = new FileInputStream(dataToolsFile.getFile());
  143 + BufferedInputStream bis = new BufferedInputStream(is);
  144 +
  145 + int length = 0;
  146 + byte[] temp = new byte[1 * 1024 * 10];
  147 + while ((length = bis.read(temp)) != -1) {
  148 + bos.write(temp, 0, length);
  149 + }
  150 + bos.flush();
  151 + bis.close();
  152 + bos.close();
  153 + is.close();
  154 + }
123 } 155 }
src/main/java/com/bsth/service/schedule/TTInfoDetailService.java
@@ -2,7 +2,9 @@ package com.bsth.service.schedule; @@ -2,7 +2,9 @@ package com.bsth.service.schedule;
2 2
3 import com.bsth.entity.schedule.TTInfoDetail; 3 import com.bsth.entity.schedule.TTInfoDetail;
4 import com.bsth.service.schedule.datatools.TTInfoDetailForEdit; 4 import com.bsth.service.schedule.datatools.TTInfoDetailForEdit;
  5 +import com.bsth.service.schedule.datatools.TTinfoDetailDynamicData;
5 import com.bsth.service.schedule.exception.ScheduleException; 6 import com.bsth.service.schedule.exception.ScheduleException;
  7 +import com.bsth.service.schedule.utils.DataToolsFile;
6 8
7 import java.util.List; 9 import java.util.List;
8 import java.util.Map; 10 import java.util.Map;
@@ -22,6 +24,14 @@ public interface TTInfoDetailService extends BService&lt;TTInfoDetail, Long&gt; { @@ -22,6 +24,14 @@ public interface TTInfoDetailService extends BService&lt;TTInfoDetail, Long&gt; {
22 TTInfoDetailForEdit.EditInfo getEditInfo(Integer xlid, Long ttid, Long maxfcno) throws ScheduleException; 24 TTInfoDetailForEdit.EditInfo getEditInfo(Integer xlid, Long ttid, Long maxfcno) throws ScheduleException;
23 25
24 /** 26 /**
  27 + * 导出动态时刻表。
  28 + * @param dtInfos
  29 + * @return
  30 + * @throws ScheduleException
  31 + */
  32 + DataToolsFile exportDynamicTTinfo(TTinfoDetailDynamicData.DTInfos dtInfos) throws ScheduleException;
  33 +
  34 + /**
25 * 获取时刻表最大发车顺序号 35 * 获取时刻表最大发车顺序号
26 * @param xlid 线路id 36 * @param xlid 线路id
27 * @param ttinfoid 时刻表id 37 * @param ttinfoid 时刻表id
src/main/java/com/bsth/service/schedule/datatools/TTInfoDetailDataToolsImpl.java
1 package com.bsth.service.schedule.datatools; 1 package com.bsth.service.schedule.datatools;
2 2
  3 +import com.bsth.entity.Station;
  4 +import com.bsth.service.StationService;
3 import com.bsth.service.schedule.exception.ScheduleException; 5 import com.bsth.service.schedule.exception.ScheduleException;
4 import com.bsth.service.schedule.utils.*; 6 import com.bsth.service.schedule.utils.*;
5 import jxl.Sheet; 7 import jxl.Sheet;
@@ -8,7 +10,13 @@ import jxl.write.Label; @@ -8,7 +10,13 @@ import jxl.write.Label;
8 import jxl.write.WritableSheet; 10 import jxl.write.WritableSheet;
9 import jxl.write.WritableWorkbook; 11 import jxl.write.WritableWorkbook;
10 import org.apache.commons.lang3.StringUtils; 12 import org.apache.commons.lang3.StringUtils;
  13 +import org.apache.poi.ss.usermodel.Cell;
11 import org.apache.poi.ss.usermodel.Row; 14 import org.apache.poi.ss.usermodel.Row;
  15 +import org.apache.poi.ss.util.CellRangeAddress;
  16 +import org.apache.poi.ss.util.WorkbookUtil;
  17 +import org.apache.poi.xssf.usermodel.XSSFRow;
  18 +import org.apache.poi.xssf.usermodel.XSSFSheet;
  19 +import org.apache.poi.xssf.usermodel.XSSFWorkbook;
12 import org.joda.time.DateTime; 20 import org.joda.time.DateTime;
13 import org.slf4j.Logger; 21 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory; 22 import org.slf4j.LoggerFactory;
@@ -17,20 +25,27 @@ import org.springframework.beans.factory.annotation.Qualifier; @@ -17,20 +25,27 @@ import org.springframework.beans.factory.annotation.Qualifier;
17 import org.springframework.boot.context.properties.EnableConfigurationProperties; 25 import org.springframework.boot.context.properties.EnableConfigurationProperties;
18 import org.springframework.stereotype.Service; 26 import org.springframework.stereotype.Service;
19 27
  28 +import java.awt.*;
20 import java.io.File; 29 import java.io.File;
  30 +import java.io.FileOutputStream;
21 import java.io.PrintWriter; 31 import java.io.PrintWriter;
22 import java.io.StringWriter; 32 import java.io.StringWriter;
23 import java.util.*; 33 import java.util.*;
  34 +import java.util.List;
24 35
25 /** 36 /**
26 * Created by xu on 17/5/16. 37 * Created by xu on 17/5/16.
27 */ 38 */
28 @EnableConfigurationProperties(DataToolsProperties.class) 39 @EnableConfigurationProperties(DataToolsProperties.class)
29 @Service(value = "ttInfoDetail_dataTool") 40 @Service(value = "ttInfoDetail_dataTool")
30 -public class TTInfoDetailDataToolsImpl implements DataToolsService, TTInfoDetailForEdit { 41 +public class TTInfoDetailDataToolsImpl implements DataToolsService, TTInfoDetailForEdit, TTinfoDetailDynamicData {
31 /** 日志记录器 */ 42 /** 日志记录器 */
32 private final static Logger LOGGER = LoggerFactory.getLogger(TTInfoDetailDataToolsImpl.class); 43 private final static Logger LOGGER = LoggerFactory.getLogger(TTInfoDetailDataToolsImpl.class);
33 44
  45 + // TODO:之后改了
  46 + @Autowired
  47 + private StationService stationService;
  48 +
34 @Autowired 49 @Autowired
35 @Qualifier(value = "dataToolsServiceImpl") 50 @Qualifier(value = "dataToolsServiceImpl")
36 private DataToolsService dataToolsService; 51 private DataToolsService dataToolsService;
@@ -363,4 +378,140 @@ public class TTInfoDetailDataToolsImpl implements DataToolsService, TTInfoDetail @@ -363,4 +378,140 @@ public class TTInfoDetailDataToolsImpl implements DataToolsService, TTInfoDetail
363 } 378 }
364 } 379 }
365 380
  381 + @Override
  382 + public DataToolsFile exportDynamicTTinfo(DTInfos dtInfos) throws ScheduleException {
  383 + try {
  384 + // 使用POI,创建xlsx文件
  385 + XSSFWorkbook wb = new XSSFWorkbook();
  386 + XSSFSheet sheet = wb.createSheet(WorkbookUtil.createSafeSheetName("时刻表信息"));
  387 +
  388 + //-------------------------------- 1、路牌班次数据 -------------------------------//
  389 + List<LpObj> lpObjList = dtInfos.getLpObjList();
  390 +
  391 + // 构建第一行数据
  392 + XSSFRow lpHeadRow = sheet.createRow((short) 0);
  393 + if (lpObjList.size() == 0) {
  394 + throw new RuntimeException("没有班次数据!");
  395 + }
  396 + int groupCount = lpObjList.get(0).getGroupCount(); // 获取总圈数
  397 + if (groupCount == 0) {
  398 + throw new RuntimeException("总圈数为0,有问题!");
  399 + }
  400 +
  401 + // 构造表头
  402 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short)0, "路牌", new Color(0x96b9d7));
  403 + Station station1 = stationService.findById(lpObjList.get(0).getStationRouteId1());
  404 + Station station2 = stationService.findById(lpObjList.get(1).getStationRouteId2());
  405 + for (int i = 0; i < groupCount; i++) {
  406 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (i * 2 + 1),
  407 + station1.getStationName(), new Color(0x96b9d7));
  408 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (i * 2 + 2),
  409 + station2.getStationName(), new Color(0x96b9d7));
  410 + }
  411 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (groupCount * 2 + 1),
  412 + "路牌工时", new Color(0x96b9d7));
  413 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (groupCount * 2 + 2),
  414 + "营运班次数", new Color(0x96b9d7));
  415 +
  416 + // 构建每个路牌的班次数据
  417 + for (int i = 0; i < lpObjList.size(); i++) {
  418 + LpObj lpObj = lpObjList.get(i);
  419 + XSSFRow lpRow = sheet.createRow((short) (i + 1));
  420 + PoiUtils.createStringXSSFCell(wb, lpRow, (short) 0, lpObj.getLpname());
  421 + for (int j = 0; j < groupCount; j++) {
  422 + PoiUtils.createStringXSSFCell(wb, lpRow, (short) (j * 2 + 1), "");
  423 + PoiUtils.createStringXSSFCell(wb, lpRow, (short) (j * 2 + 2), "");
  424 + }
  425 + for (BcObj bcObj : lpObj.getBcObjList()) {
  426 + Cell cell = lpRow.getCell((short) (bcObj.getGroupNo() * 2 + bcObj.getGroupBcNo() + 1));
  427 + cell.setCellValue(bcObj.getFcsj());
  428 + }
  429 + // 路牌工时/班次数
  430 + PoiUtils.createDoubleXSSFCell(wb, lpRow, (short) (groupCount * 2 + 1),
  431 + lpObj.getZgs() / 60);
  432 + // 营运班次数
  433 + PoiUtils.createIntegerXSSFCell(wb, lpRow, (short) (groupCount * 2 + 2),
  434 + lpObj.getZbc());
  435 + }
  436 +
  437 + // 自适应单元格长宽
  438 + sheet.autoSizeColumn(0);
  439 + for (int i = 0; i < groupCount; i++) {
  440 + sheet.autoSizeColumn(i * 2 + 1);
  441 + sheet.autoSizeColumn(i * 2 + 2);
  442 + }
  443 + sheet.autoSizeColumn(groupCount * 2 + 1);
  444 + sheet.autoSizeColumn(groupCount * 2 + 2);
  445 +
  446 + // 锁定行首,列首
  447 + sheet.createFreezePane(1, 1);
  448 +
  449 + //-------------------------------- 2、统计数据 -------------------------------//
  450 + List<StatInfo> statInfos = dtInfos.getStatInfoList();
  451 +
  452 + // 创建总的统计数据格式
  453 + // 第一行 统计数据
  454 + // 第二行 序号,统计项目(8个单元格合并),统计数值
  455 + // 第三行开始数据,一共20行
  456 +
  457 + int startrow = lpObjList.size() + 3;
  458 + for (int i = startrow; i <= startrow + 22; i++) {
  459 + XSSFRow xssfRow = sheet.createRow(i);
  460 + for (int j = 0; j < 10; j++) {
  461 + PoiUtils.createStringXSSFCell(wb, xssfRow, (short) j, "");
  462 + }
  463 + }
  464 + // 合并第一行
  465 + sheet.addMergedRegion(new CellRangeAddress(startrow, startrow, 0, 9));
  466 + sheet.getRow(startrow).getCell(0).setCellValue("统计数据");
  467 + // 合并第二行
  468 + sheet.getRow(startrow + 1).getCell(0).setCellValue("序号");
  469 + sheet.getRow(startrow + 1).getCell(1).setCellValue("统计项目");
  470 + sheet.getRow(startrow + 1).getCell(9).setCellValue("统计数值");
  471 + sheet.addMergedRegion(new CellRangeAddress(startrow + 1, startrow + 1, 1, 8));
  472 + // 处理后面具体统计行
  473 + for (int row = startrow + 2; row <= startrow + 2 + statInfos.size(); row++) {
  474 + sheet.addMergedRegion(new CellRangeAddress(row, row, 1, 8));
  475 + }
  476 +
  477 + for (int i = 0; i < statInfos.size(); i++) {
  478 + StatInfo statInfo = statInfos.get(i);
  479 +
  480 + // 1、统计序号
  481 + PoiUtils.setIntegerStyleXSSFCellStyle(wb, sheet.getRow(startrow + 2 + i).getCell(0));
  482 + sheet.getRow(startrow + 2 + i).getCell(0).setCellValue(i);
  483 +
  484 + // 2、统计项目
  485 + sheet.getRow(startrow + 2 + i).getCell(1).setCellValue(statInfo.getStatItem());
  486 +
  487 + // 3、统计数值
  488 + PoiUtils.setDoubleStyleXSSFCellStyle(wb, sheet.getRow(startrow + 2 + i).getCell(9));
  489 + sheet.getRow(startrow + 2 + i).getCell(9).setCellValue(statInfo.getStatValue());
  490 + }
  491 +
  492 + // 最后内存写入文件
  493 + String filepath = dataToolsProperties.getFileoutputDir() +
  494 + File.separator +
  495 + "动态时刻表-" +
  496 + new DateTime().toString("yyyyMMddHHmmss") + ".xlsx";
  497 + FileOutputStream fileOut = new FileOutputStream(filepath);
  498 + wb.write(fileOut);
  499 +
  500 + DataToolsFile dataToolsFile = new DataToolsFile();
  501 + dataToolsFile.setFileType(DataToolsFileType.XLSX);
  502 + dataToolsFile.setFile(new File(filepath));
  503 +
  504 + return dataToolsFile;
  505 +
  506 + } catch (Exception exp) {
  507 + LOGGER.info("//---------------- 动态时刻表输出 failed... ----------------//");
  508 +
  509 + StringWriter sw = new StringWriter();
  510 + exp.printStackTrace(new PrintWriter(sw));
  511 + LOGGER.info(sw.toString());
  512 +
  513 + throw new ScheduleException(exp);
  514 + }
  515 +
  516 + }
366 } 517 }
src/main/java/com/bsth/service/schedule/datatools/TTinfoDetailDynamicData.java 0 → 100644
  1 +package com.bsth.service.schedule.datatools;
  2 +
  3 +import com.bsth.service.schedule.exception.ScheduleException;
  4 +import com.bsth.service.schedule.utils.DataToolsFile;
  5 +import com.fasterxml.jackson.annotation.JsonCreator;
  6 +import com.fasterxml.jackson.annotation.JsonValue;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * 动态时刻表数据。
  12 + */
  13 +public interface TTinfoDetailDynamicData {
  14 +
  15 + //---------------------- 生成时刻表用对象(以下) ---------------------//
  16 + public static enum BcType { // 班次类型枚举
  17 + IN("in"), // 进场
  18 + OUT("out"), // 出场
  19 + BD("bd"), // 早例保
  20 + LC("lc"), // 晚例保
  21 + NORMAL("normal"); // 正常
  22 + private String flag;
  23 +
  24 + @JsonCreator
  25 + private BcType(String flag) {
  26 + this.flag = flag;
  27 + }
  28 +
  29 + @JsonValue
  30 + public String getFlag() {
  31 + return flag;
  32 + }
  33 +
  34 + public void setFlag(String flag) {
  35 + this.flag = flag;
  36 + }
  37 + }
  38 +
  39 + public static class BcObj { // 班次对象
  40 + /** 班次时间 */
  41 + private Integer bcsj;
  42 + /** 停站时间 */
  43 + private Integer ssj;
  44 + /** 吃饭时间 */
  45 + private Integer eatsj;
  46 +
  47 + /** 停车场id */
  48 + private Integer tccid;
  49 + /** 起点站id */
  50 + private Integer qdzid;
  51 + /** 终点站id */
  52 + private Integer zdzid;
  53 +
  54 + /** 是否上行 */
  55 + private Boolean isUp;
  56 +
  57 + /** 班次类型 */
  58 + private BcType bcType;
  59 + /** 发车时刻 */
  60 + private String fcsj;
  61 +
  62 + /** 第几圈(从1开始) */
  63 + private Integer groupNo;
  64 + /** 圈里第几个班次(1或者2) */
  65 + private Integer groupBcNo;
  66 +
  67 + public Integer getBcsj() {
  68 + return bcsj;
  69 + }
  70 +
  71 + public void setBcsj(Integer bcsj) {
  72 + this.bcsj = bcsj;
  73 + }
  74 +
  75 + public Integer getSsj() {
  76 + return ssj;
  77 + }
  78 +
  79 + public void setSsj(Integer ssj) {
  80 + this.ssj = ssj;
  81 + }
  82 +
  83 + public Integer getEatsj() {
  84 + return eatsj;
  85 + }
  86 +
  87 + public void setEatsj(Integer eatsj) {
  88 + this.eatsj = eatsj;
  89 + }
  90 +
  91 + public Integer getTccid() {
  92 + return tccid;
  93 + }
  94 +
  95 + public void setTccid(Integer tccid) {
  96 + this.tccid = tccid;
  97 + }
  98 +
  99 + public Integer getQdzid() {
  100 + return qdzid;
  101 + }
  102 +
  103 + public void setQdzid(Integer qdzid) {
  104 + this.qdzid = qdzid;
  105 + }
  106 +
  107 + public Integer getZdzid() {
  108 + return zdzid;
  109 + }
  110 +
  111 + public void setZdzid(Integer zdzid) {
  112 + this.zdzid = zdzid;
  113 + }
  114 +
  115 + public BcType getBcType() {
  116 + return bcType;
  117 + }
  118 +
  119 + public void setBcType(BcType bcType) {
  120 + this.bcType = bcType;
  121 + }
  122 +
  123 + public String getFcsj() {
  124 + return fcsj;
  125 + }
  126 +
  127 + public void setFcsj(String fcsj) {
  128 + this.fcsj = fcsj;
  129 + }
  130 +
  131 + public Boolean getIsUp() {
  132 + return isUp;
  133 + }
  134 +
  135 + public void setIsUp(Boolean isUp) {
  136 + this.isUp = isUp;
  137 + }
  138 +
  139 + public Integer getGroupNo() {
  140 + return groupNo;
  141 + }
  142 +
  143 + public void setGroupNo(Integer groupNo) {
  144 + this.groupNo = groupNo;
  145 + }
  146 +
  147 + public Integer getGroupBcNo() {
  148 + return groupBcNo;
  149 + }
  150 +
  151 + public void setGroupBcNo(Integer groupBcNo) {
  152 + this.groupBcNo = groupBcNo;
  153 + }
  154 + }
  155 +
  156 + public static class LpObj { // 路牌对象
  157 + /** 路牌名字 */
  158 + private String lpname;
  159 + /** 每圈的第一个班次是否上行 */
  160 + private Boolean isUp;
  161 +
  162 + /** 第一个班次起点站路由id */
  163 + private Integer stationRouteId1;
  164 + /** 第二个班次起点站路由id */
  165 + private Integer stationRouteId2;
  166 +
  167 + /** 班次列表 */
  168 + private List<BcObj> bcObjList;
  169 + /** 总圈数 */
  170 + private Integer groupCount;
  171 +
  172 + /** 总工时 */
  173 + private Double zgs;
  174 + /** 总班次 */
  175 + private Integer zbc;
  176 +
  177 +
  178 + public String getLpname() {
  179 + return lpname;
  180 + }
  181 +
  182 + public void setLpname(String lpname) {
  183 + this.lpname = lpname;
  184 + }
  185 +
  186 + public Boolean getIsUp() {
  187 + return isUp;
  188 + }
  189 +
  190 + public void setIsUp(Boolean isUp) {
  191 + this.isUp = isUp;
  192 + }
  193 +
  194 + public List<BcObj> getBcObjList() {
  195 + return bcObjList;
  196 + }
  197 +
  198 + public void setBcObjList(List<BcObj> bcObjList) {
  199 + this.bcObjList = bcObjList;
  200 + }
  201 +
  202 + public Integer getGroupCount() {
  203 + return groupCount;
  204 + }
  205 +
  206 + public void setGroupCount(Integer groupCount) {
  207 + this.groupCount = groupCount;
  208 + }
  209 +
  210 + public Double getZgs() {
  211 + return zgs;
  212 + }
  213 +
  214 + public void setZgs(Double zgs) {
  215 + this.zgs = zgs;
  216 + }
  217 +
  218 + public Integer getZbc() {
  219 + return zbc;
  220 + }
  221 +
  222 + public void setZbc(Integer zbc) {
  223 + this.zbc = zbc;
  224 + }
  225 +
  226 + public Integer getStationRouteId1() {
  227 + return stationRouteId1;
  228 + }
  229 +
  230 + public void setStationRouteId1(Integer stationRouteId1) {
  231 + this.stationRouteId1 = stationRouteId1;
  232 + }
  233 +
  234 + public Integer getStationRouteId2() {
  235 + return stationRouteId2;
  236 + }
  237 +
  238 + public void setStationRouteId2(Integer stationRouteId2) {
  239 + this.stationRouteId2 = stationRouteId2;
  240 + }
  241 + }
  242 +
  243 + public static class StatInfo { // 统计数据对象
  244 + /** 统计项目 */
  245 + private String statItem;
  246 + /** 统计值 */
  247 + private Double statValue;
  248 +
  249 + public String getStatItem() {
  250 + return statItem;
  251 + }
  252 +
  253 + public void setStatItem(String statItem) {
  254 + this.statItem = statItem;
  255 + }
  256 +
  257 + public Double getStatValue() {
  258 + return statValue;
  259 + }
  260 +
  261 + public void setStatValue(Double statValue) {
  262 + this.statValue = statValue;
  263 + }
  264 + }
  265 +
  266 + public static class DTInfos { // 所有数据信息
  267 + /** 路牌班次数据列表 */
  268 + private List<LpObj> lpObjList;
  269 + /** 统计数据列表 */
  270 + private List<StatInfo> statInfoList;
  271 +
  272 + public List<LpObj> getLpObjList() {
  273 + return lpObjList;
  274 + }
  275 +
  276 + public void setLpObjList(List<LpObj> lpObjList) {
  277 + this.lpObjList = lpObjList;
  278 + }
  279 +
  280 + public List<StatInfo> getStatInfoList() {
  281 + return statInfoList;
  282 + }
  283 +
  284 + public void setStatInfoList(List<StatInfo> statInfoList) {
  285 + this.statInfoList = statInfoList;
  286 + }
  287 + }
  288 +
  289 + //---------------------- 生成时刻表用对象(以上) ---------------------//
  290 +
  291 + /**
  292 + * 导出动态时刻表数据。
  293 + * @param dtInfos
  294 + * @return
  295 + * @throws ScheduleException
  296 + */
  297 + public DataToolsFile exportDynamicTTinfo(DTInfos dtInfos) throws ScheduleException;
  298 +}
src/main/java/com/bsth/service/schedule/impl/TTInfoDetailServiceImpl.java
@@ -19,6 +19,7 @@ import com.bsth.service.StationRouteService; @@ -19,6 +19,7 @@ import com.bsth.service.StationRouteService;
19 import com.bsth.service.schedule.GuideboardInfoService; 19 import com.bsth.service.schedule.GuideboardInfoService;
20 import com.bsth.service.schedule.TTInfoDetailService; 20 import com.bsth.service.schedule.TTInfoDetailService;
21 import com.bsth.service.schedule.datatools.TTInfoDetailForEdit; 21 import com.bsth.service.schedule.datatools.TTInfoDetailForEdit;
  22 +import com.bsth.service.schedule.datatools.TTinfoDetailDynamicData;
22 import com.bsth.service.schedule.exception.ScheduleException; 23 import com.bsth.service.schedule.exception.ScheduleException;
23 import com.bsth.service.schedule.utils.DataToolsFile; 24 import com.bsth.service.schedule.utils.DataToolsFile;
24 import com.bsth.service.schedule.utils.DataToolsFileType; 25 import com.bsth.service.schedule.utils.DataToolsFileType;
@@ -86,6 +87,10 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im @@ -86,6 +87,10 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im
86 private TTInfoDetailForEdit ttInfoDetailForEdit; 87 private TTInfoDetailForEdit ttInfoDetailForEdit;
87 88
88 @Autowired 89 @Autowired
  90 + @Qualifier(value = "ttInfoDetail_dataTool")
  91 + private TTinfoDetailDynamicData tTinfoDetailDynamicData;
  92 +
  93 + @Autowired
89 private JdbcTemplate jdbcTemplate; 94 private JdbcTemplate jdbcTemplate;
90 95
91 /** 96 /**
@@ -134,6 +139,10 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im @@ -134,6 +139,10 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im
134 return dataToolsService.exportData(params); 139 return dataToolsService.exportData(params);
135 } 140 }
136 141
  142 + @Override
  143 + public DataToolsFile exportDynamicTTinfo(TTinfoDetailDynamicData.DTInfos dtInfos) throws ScheduleException {
  144 + return tTinfoDetailDynamicData.exportDynamicTTinfo(dtInfos);
  145 + }
137 146
138 @Override 147 @Override
139 public TTInfoDetailForEdit.EditInfo getEditInfo(Integer xlid, Long ttid, Long maxfcno) throws ScheduleException { 148 public TTInfoDetailForEdit.EditInfo getEditInfo(Integer xlid, Long ttid, Long maxfcno) throws ScheduleException {
src/main/java/com/bsth/service/schedule/utils/PoiUtils.java
1 package com.bsth.service.schedule.utils; 1 package com.bsth.service.schedule.utils;
2 2
3 import org.apache.poi.hssf.usermodel.HSSFDateUtil; 3 import org.apache.poi.hssf.usermodel.HSSFDateUtil;
4 -import org.apache.poi.ss.usermodel.Cell;  
5 -import org.apache.poi.xssf.usermodel.XSSFCell; 4 +import org.apache.poi.ss.usermodel.*;
  5 +import org.apache.poi.ss.util.WorkbookUtil;
  6 +import org.apache.poi.xssf.usermodel.*;
6 7
  8 +import java.awt.Color;
7 import java.text.DecimalFormat; 9 import java.text.DecimalFormat;
8 import java.text.SimpleDateFormat; 10 import java.text.SimpleDateFormat;
9 import java.util.Date; 11 import java.util.Date;
@@ -52,4 +54,136 @@ public class PoiUtils { @@ -52,4 +54,136 @@ public class PoiUtils {
52 } 54 }
53 return cellValue; 55 return cellValue;
54 } 56 }
  57 +
  58 + public static XSSFCell createStringXSSFCell(
  59 + XSSFWorkbook xssfWorkbook, XSSFRow xssfRow, short column, String value,
  60 + Color backgroundColor) {
  61 + return createXSSFCell(
  62 + xssfWorkbook, xssfRow, column,
  63 + value, XSSFCell.CELL_TYPE_STRING,
  64 + HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
  65 + BorderStyle.MEDIUM, new Color(0xdedede),
  66 + (short) 13, new Color(0x2765A7), "宋体",
  67 + backgroundColor, FillPatternType.SOLID_FOREGROUND
  68 + );
  69 + }
  70 +
  71 + public static XSSFCell createStringXSSFCell(
  72 + XSSFWorkbook xssfWorkbook, XSSFRow xssfRow, short column, String value) {
  73 + return createXSSFCell(
  74 + xssfWorkbook, xssfRow, column,
  75 + value, XSSFCell.CELL_TYPE_STRING,
  76 + HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
  77 + BorderStyle.MEDIUM, new Color(0xdedede),
  78 + (short) 13, new Color(0x2765A7), "宋体",
  79 + new Color(0xffffff), FillPatternType.SOLID_FOREGROUND
  80 + );
  81 + }
  82 +
  83 + public static XSSFCell createDoubleXSSFCell(
  84 + XSSFWorkbook xssfWorkbook, XSSFRow xssfRow, short column, Double value) {
  85 + return createXSSFCell(
  86 + xssfWorkbook, xssfRow, column,
  87 + value, XSSFCell.CELL_TYPE_NUMERIC,
  88 + HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
  89 + BorderStyle.MEDIUM, new Color(0xdedede),
  90 + (short) 13, new Color(0x2765A7), "宋体",
  91 + new Color(0xffffff), FillPatternType.SOLID_FOREGROUND
  92 + );
  93 + }
  94 +
  95 + public static XSSFCell createIntegerXSSFCell(
  96 + XSSFWorkbook xssfWorkbook, XSSFRow xssfRow, short column, Integer value) {
  97 + return createXSSFCell(
  98 + xssfWorkbook, xssfRow, column,
  99 + value, XSSFCell.CELL_TYPE_NUMERIC,
  100 + HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
  101 + BorderStyle.MEDIUM, new Color(0xdedede),
  102 + (short) 13, new Color(0x2765A7), "宋体",
  103 + new Color(0xffffff), FillPatternType.SOLID_FOREGROUND
  104 + );
  105 + }
  106 +
  107 + public static XSSFCell setIntegerStyleXSSFCellStyle(XSSFWorkbook xssfWorkbook, XSSFCell xssfCell) {
  108 + CreationHelper creationHelper = xssfWorkbook.getCreationHelper();
  109 + XSSFCellStyle xssfCellStyle = xssfCell.getCellStyle();
  110 + xssfCellStyle.setDataFormat(creationHelper.createDataFormat().getFormat("0"));
  111 + return xssfCell;
  112 + }
  113 + public static XSSFCell setDoubleStyleXSSFCellStyle(XSSFWorkbook xssfWorkbook, XSSFCell xssfCell) {
  114 + CreationHelper creationHelper = xssfWorkbook.getCreationHelper();
  115 + XSSFCellStyle xssfCellStyle = xssfCell.getCellStyle();
  116 + xssfCellStyle.setDataFormat(creationHelper.createDataFormat().getFormat("0.00"));
  117 + return xssfCell;
  118 + }
  119 +
  120 + public static XSSFCell createXSSFCell(
  121 + XSSFWorkbook xssfWorkbook, XSSFRow xssfRow, short column,
  122 + Object value, int valueType,
  123 + HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment,
  124 + BorderStyle borderStyle, Color borderColor,
  125 + short fontSize, Color fontColor, String fontName,
  126 + Color backgroudColor, FillPatternType fillPatternType) {
  127 + CreationHelper creationHelper = xssfWorkbook.getCreationHelper();
  128 +
  129 + // 1、创建单元格对象
  130 + XSSFCell cell = xssfRow.createCell(column);
  131 +
  132 + // 2、设定样式
  133 + XSSFCellStyle cellStyle = xssfWorkbook.createCellStyle();
  134 +
  135 + // 设定值
  136 + if (valueType == XSSFCell.CELL_TYPE_STRING) {
  137 + cell.setCellValue(creationHelper.createRichTextString(
  138 + WorkbookUtil.createSafeSheetName(String.valueOf(value))));
  139 + } else if (valueType == XSSFCell.CELL_TYPE_NUMERIC) {
  140 + if (value instanceof Date) { // 日期
  141 + cellStyle.setDataFormat(creationHelper.createDataFormat().getFormat("yyyy-mm-dd"));
  142 + cell.setCellValue((Date) value);
  143 + } else if (value instanceof Double) {
  144 + cellStyle.setDataFormat(creationHelper.createDataFormat().getFormat("0.00"));
  145 + cell.setCellValue((Double) value);
  146 + } else if (value instanceof Integer) {
  147 + cellStyle.setDataFormat(creationHelper.createDataFormat().getFormat("0"));
  148 + cell.setCellValue(Double.valueOf(value.toString()));
  149 + } else {
  150 + throw new RuntimeException("只支持 Date Double Integer 单元格类型");
  151 + }
  152 + } else {
  153 + throw new RuntimeException("暂时不支持字符串、日期、数字以为的类型");
  154 + }
  155 +
  156 + // 对齐方式
  157 + cellStyle.setAlignment(horizontalAlignment);
  158 + cellStyle.setVerticalAlignment(verticalAlignment);
  159 +
  160 + // 边框样式
  161 + cellStyle.setBorderTop(borderStyle);
  162 + cellStyle.setTopBorderColor(new XSSFColor(borderColor));
  163 + cellStyle.setBorderBottom(borderStyle);
  164 + cellStyle.setBottomBorderColor(new XSSFColor(borderColor));
  165 + cellStyle.setBorderLeft(borderStyle);
  166 + cellStyle.setLeftBorderColor(new XSSFColor(borderColor));
  167 + cellStyle.setBorderRight(borderStyle);
  168 + cellStyle.setRightBorderColor(new XSSFColor(borderColor));
  169 +
  170 + // 字体颜色
  171 + XSSFFont font = xssfWorkbook.createFont();
  172 + font.setColor(new XSSFColor(fontColor));
  173 + font.setFontHeightInPoints(fontSize);
  174 + font.setFontName(fontName);
  175 + cellStyle.setFont(font);
  176 +
  177 +
  178 + // 单元背景色
  179 + cellStyle.setFillForegroundColor(new XSSFColor(backgroudColor));
  180 + cellStyle.setFillPattern(fillPatternType);
  181 +
  182 + // TODO
  183 +
  184 + cell.setCellStyle(cellStyle);
  185 + return cell;
  186 + }
  187 +
55 } 188 }
  189 +
src/main/resources/static/index.html
@@ -61,9 +61,9 @@ @@ -61,9 +61,9 @@
61 href="/metronic_v4.5.4/plugins/bootstrap-datetimepicker-2/css/bootstrap-datetimepicker.min.css" 61 href="/metronic_v4.5.4/plugins/bootstrap-datetimepicker-2/css/bootstrap-datetimepicker.min.css"
62 rel="stylesheet" type="text/css" /> 62 rel="stylesheet" type="text/css" />
63 <!-- table 表格控件 --> 63 <!-- table 表格控件 -->
64 - <link rel="stylesheet"  
65 - href="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.css"  
66 - type="text/css" /> 64 + <!--<link rel="stylesheet"-->
  65 + <!--href="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.css"-->
  66 + <!--type="text/css" />-->
67 <link href="/metronic_v4.5.4/plugins/bootstrap-tagsinput/bootstrap-tagsinput.css" rel="stylesheet" type="text/css"/> 67 <link href="/metronic_v4.5.4/plugins/bootstrap-tagsinput/bootstrap-tagsinput.css" rel="stylesheet" type="text/css"/>
68 <!-- handsontable样式 --> 68 <!-- handsontable样式 -->
69 <link rel="stylesheet" 69 <link rel="stylesheet"
@@ -612,24 +612,24 @@ @@ -612,24 +612,24 @@
612 612
613 <!-- 地图相关 --> 613 <!-- 地图相关 -->
614 <!-- 百度 --> 614 <!-- 百度 -->
615 -<script  
616 - src="http://api.map.baidu.com/api?v=2.0&ak=IGGrr4UjwIYzatoCRFKEL8sT"  
617 - data-exclude=1></script>  
618 -<script  
619 - src="http://api.map.baidu.com/library/TrafficControl/1.4/src/TrafficControl_min.js"  
620 - data-exclude=1></script>  
621 -<script type="text/javascript"  
622 - src="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.js"  
623 - data-exclude=1></script>  
624 -<script type="text/javascript"  
625 - src="http://api.map.baidu.com/library/RichMarker/1.2/src/RichMarker_min.js "  
626 - data-exclude=1></script> 615 +<!--<script-->
  616 + <!--src="http://api.map.baidu.com/api?v=2.0&ak=IGGrr4UjwIYzatoCRFKEL8sT"-->
  617 + <!--data-exclude=1></script>-->
  618 +<!--<script-->
  619 + <!--src="http://api.map.baidu.com/library/TrafficControl/1.4/src/TrafficControl_min.js"-->
  620 + <!--data-exclude=1></script>-->
  621 +<!--<script type="text/javascript"-->
  622 + <!--src="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.js"-->
  623 + <!--data-exclude=1></script>-->
  624 +<!--<script type="text/javascript"-->
  625 + <!--src="http://api.map.baidu.com/library/RichMarker/1.2/src/RichMarker_min.js "-->
  626 + <!--data-exclude=1></script>-->
627 <script src="/assets/js/baidu/TextIconOverlay.js" data-exclude=1></script> 627 <script src="/assets/js/baidu/TextIconOverlay.js" data-exclude=1></script>
628 <script src="/assets/js/baidu//MarkerClusterer.js" data-exclude=1></script> 628 <script src="/assets/js/baidu//MarkerClusterer.js" data-exclude=1></script>
629 <!-- 高德 --> 629 <!-- 高德 -->
630 -<script  
631 - src="http://webapi.amap.com/maps?v=1.3&key=16cb1c5043847e09ef9edafdd77befda"  
632 - data-exclude=1></script> 630 +<!--<script-->
  631 + <!--src="http://webapi.amap.com/maps?v=1.3&key=16cb1c5043847e09ef9edafdd77befda"-->
  632 + <!--data-exclude=1></script>-->
633 633
634 <script src="/real_control_v2/assets/plugins/perfect-scrollbar/perfect-scrollbar.jquery.js" merge="plugins"></script> 634 <script src="/real_control_v2/assets/plugins/perfect-scrollbar/perfect-scrollbar.jquery.js" merge="plugins"></script>
635 635
src/main/resources/static/pages/base/timesmodel/gantt.html
@@ -47,6 +47,9 @@ @@ -47,6 +47,9 @@
47 <div class="btn-group btn-group-devided checkbtn" data-toggle="buttons"> 47 <div class="btn-group btn-group-devided checkbtn" data-toggle="buttons">
48 <a class="btn btn-circle blue checkAdd" href="javascript:;" data-pjax><i class="fa fa-check"></i> 保存数据</a> 48 <a class="btn btn-circle blue checkAdd" href="javascript:;" data-pjax><i class="fa fa-check"></i> 保存数据</a>
49 </div> 49 </div>
  50 + <div class="btn-group btn-group-devided exportbtn" data-toggle="buttons">
  51 + <a class="btn btn-circle blue exportAdd" href="javascript:;" data-pjax><i class="fa fa-file-excel-o"></i> 导出数据</a>
  52 + </div>
50 <div class="btn-group checkbtn"> 53 <div class="btn-group checkbtn">
51 <a href="javascript:" class="btn red btn-outline btn-circle" data-toggle="dropdown" aria-expanded="false"> 54 <a href="javascript:" class="btn red btn-outline btn-circle" data-toggle="dropdown" aria-expanded="false">
52 <i class="fa fa-cog"></i> 55 <i class="fa fa-cog"></i>
src/main/resources/static/pages/base/timesmodel/js/add-form-reload.js
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 $('.openHaveSkb').on('click',function() { 7 $('.openHaveSkb').on('click',function() {
8 var skbId = $("#skbNameSelect").val(); 8 var skbId = $("#skbNameSelect").val();
9 var argus = { 9 var argus = {
10 - baseRes:"0",carPark:"FFFFFF68",downInMileage:"0", 10 + baseRes:"0",czarPark:"FFFFFF68",downInMileage:"0",
11 downInTimer:"0",downMileage:"3.5",downOutMileage:"0", 11 downInTimer:"0",downMileage:"3.5",downOutMileage:"0",
12 downOutTimer:"0",downStopTime:"10",downTravelTime:"7", 12 downOutTimer:"0",downStopTime:"10",downTravelTime:"7",
13 down_s:"26922_26928",earlyDownTime:"7",earlyEndTime:"08:30", 13 down_s:"26922_26928",earlyDownTime:"7",earlyEndTime:"08:30",
src/main/resources/static/pages/base/timesmodel/js/add-form-wizard.js
@@ -372,11 +372,22 @@ var SKBFormWizard = function() { @@ -372,11 +372,22 @@ var SKBFormWizard = function() {
372 } 372 }
373 sjdArr[s].num = num; 373 sjdArr[s].num = num;
374 } 374 }
375 - map.zgfbeforepcs = sjdArr[0].num;// 早高峰前配车数  
376 - map.zgfpcs = sjdArr[2].num;// 早高峰配车数  
377 - map.gfzjpcs = sjdArr[4].num;// 高峰之间配车数  
378 - map.wgfpcs = sjdArr[2].num ;// 晚高峰配车数  
379 - map.wgfafterpcs = sjdArr[1].num + sjdArr[3].num;// 晚高峰后配车数 375 +
  376 + // 注意:如果为0,设置成 10 17默认值
  377 + map.zgfbeforepcs = sjdArr[0].num == 0 ? 10 : sjdArr[0].num;// 早高峰前配车数
  378 + map.zgfpcs = sjdArr[2].num == 0 ? 17 : sjdArr[2].num;// 早高峰配车数
  379 + map.gfzjpcs = sjdArr[4].num == 0 ? 10 : sjdArr[4].num;// 高峰之间配车数
  380 + map.wgfpcs = sjdArr[2].num == 0 ? 17 : sjdArr[2].num ;// 晚高峰配车数
  381 + map.wgfafterpcs = (sjdArr[1].num + sjdArr[3].num) == 0 ? 10 : sjdArr[1].num + sjdArr[3].num;// 晚高峰后配车数
  382 +
  383 + // 注意:高峰 5 低谷 20 其他 10
  384 + map.upStopTime = 10;
  385 + map.downStopTime = 10;
  386 + map.mixstopTime = 5;
  387 + map.maxstopTime = 20;
  388 +
  389 + //alert("dddd");
  390 +
380 // 返回参数详情模版. 391 // 返回参数详情模版.
381 return cb && cb ({'forminput':template(tempName,{map:map}),'datadisplay': template(tempName +'config',{map:null})}); 392 return cb && cb ({'forminput':template(tempName,{map:map}),'datadisplay': template(tempName +'config',{map:null})});
382 }); 393 });
@@ -640,13 +651,49 @@ var SKBFormWizard = function() { @@ -640,13 +651,49 @@ var SKBFormWizard = function() {
640 651
641 // 表单提交. 652 // 表单提交.
642 function submit(p,argus) { 653 function submit(p,argus) {
643 - storage.setItem("Gantt_AgursData",JSON.stringify(argus));  
644 - if(p!=null) {  
645 - storage.setItem('isDoDate',JSON.stringify({'rsD':p.rsD,'rsLP':p.rsLp}));  
646 - }else {  
647 - storage.setItem('isDoDate','');  
648 - }  
649 - loadPage('gantt.html'); 654 + var baseRes2 = $('#submit_argus_form input[name="baseRes"]:checked').val();// 获取参数方式值.
  655 + if (baseRes2 == 0) {
  656 + // TODO:客流暂时有问题,直接使用现有时刻表打开,日后有机会再改好
  657 + var skbId2 = $("#skbNameSelect").val();
  658 + var argus2 = {
  659 + baseRes:"0",carPark:"FFFFFF68",downInMileage:"0",
  660 + downInTimer:"0",downMileage:"3.5",downOutMileage:"0",
  661 + downOutTimer:"0",downStopTime:"10",downTravelTime:"7",
  662 + down_s:"26922_26928",earlyDownTime:"7",earlyEndTime:"08:30",
  663 + earlyStartTime:"06:31",earlyUpTime:"10",endStationEndTime:"22:30",
  664 + endStationFirstTime:"05:50",gfzjpcs:"7",istidc:1,kfsj:"",krl:"50",
  665 + lateDownTime:"7",lateEndTime:"18:30",lateStartTime:"16:31",
  666 + lateUpTime:"10",lb:"15",lineName:"801702_801702_1109路",
  667 + linePlayType:"0",maxstopTime:"20",mixstopTime:"8",qjDownTime:"",
  668 + qjUpTime:"",skbName:skbId2,skbmc:"2016.4.6双时刻表",
  669 + startStationEndTime:"23:00",startStationFirstTime:"06:15",tcc_id:45,troughDownTime:"7",troughUpTime:"10",upInMileage:"0",
  670 + upInTimer:"10",upMileage:"3.5",upOutMileage:"0",upOutTimer:"10",upStopTime:"10",upTravelTime:"10",
  671 + up_s:"26912_26921",wgfafterpcs:"5",wgfpcs:"10",workeDinner:"20",workeLunch:"20",xlmc:"1109路",zgfbeforepcs:"3",zgfpcs:"10",}
  672 + // 获取时刻表明细.
  673 + $get('/tidc/all',{'ttinfo.id_eq':parseInt(argus.skbName)},function(data) {
  674 + var p = formatData(data.data,argus2);
  675 + // TODO:添加parent
  676 + for (var ii = 0; ii < p.rsD.length; ii++) {
  677 + p.rsD[ii].parent = p.rsD[ii].lpNo;// 路牌名称
  678 + }
  679 +
  680 + argus2.istidc = 1;
  681 + var storage = window.localStorage;
  682 + storage.setItem("Gantt_AgursData",JSON.stringify(argus2));
  683 + storage.setItem('isDoDate',JSON.stringify({'rsD':p.rsD,'rsLP':p.rsLp}));
  684 + loadPage('gantt.html');
  685 + });
  686 + } else {
  687 + storage.setItem("Gantt_AgursData",JSON.stringify(argus));
  688 + if(p!=null) {
  689 + storage.setItem('isDoDate',JSON.stringify({'rsD':p.rsD,'rsLP':p.rsLp}));
  690 + }else {
  691 + storage.setItem('isDoDate','');
  692 + }
  693 + loadPage('gantt.html');
  694 + }
  695 +
  696 +
650 } 697 }
651 } 698 }
652 }); 699 });
src/main/resources/static/pages/base/timesmodel/js/gantt.js
@@ -84,6 +84,7 @@ @@ -84,6 +84,7 @@
84 // TODO:var seDate = getksjssj(null,seMap.s); 关联参数必须设置 84 // TODO:var seDate = getksjssj(null,seMap.s); 关联参数必须设置
85 // TODO:CSMap.maxCar 之后要设定一下的 85 // TODO:CSMap.maxCar 之后要设定一下的
86 data = Main_v2.BXPplaceClassesTime03(_paramObj, CSMap.maxCar); 86 data = Main_v2.BXPplaceClassesTime03(_paramObj, CSMap.maxCar);
  87 + Main_v2.exportDataConfig(data.aInternalLpObj);
87 } 88 }
88 89
89 }else { 90 }else {
src/main/resources/static/pages/base/timesmodel/js/v2/core/InternalBcObj.js
@@ -51,7 +51,7 @@ var InternalBcObj = function( @@ -51,7 +51,7 @@ var InternalBcObj = function(
51 //------------------- get/set 方法 -------------------// 51 //------------------- get/set 方法 -------------------//
52 52
53 InternalBcObj.prototype.fnSetIsFirstBc = function(bFlag) { 53 InternalBcObj.prototype.fnSetIsFirstBc = function(bFlag) {
54 - this._$_bIsFirstBc = true; 54 + this._$_bIsFirstBc = bFlag;
55 }; 55 };
56 InternalBcObj.prototype.fnIsFirstBc = function() { 56 InternalBcObj.prototype.fnIsFirstBc = function() {
57 return this._$_bIsFirstBc; 57 return this._$_bIsFirstBc;
src/main/resources/static/pages/base/timesmodel/js/v2/core/InternalLpObj.js
1 -/**  
2 - * 内部路牌对象。  
3 - * @constructor  
4 - */  
5 -var InternalLpObj = function(  
6 - orilpObj, // 原始路牌对象  
7 - qCount, // 总共多少圈  
8 - isUp // 圈是以上行开始还是下行开始  
9 -) {  
10 - // TODO:原始路牌对象(这个路牌是对接外部gantt图像,以后有机会改了)  
11 - this._$$_orign_lp_obj = orilpObj;  
12 -  
13 - this._$_isUp = isUp;  
14 -  
15 - // 路牌的圈数,注意每个路牌的圈数都是一致的,  
16 - // 但并不是每一圈都有值  
17 - // 第1圈从上标线开始  
18 - // 第0圈表示中标线的第一个班次组成的半圈  
19 - // 有多少圈根据最终迭代的结果来看  
20 - this._$_qCount = qCount;  
21 - // 保存的是 InternalGroupBcObj 对象  
22 - this._$_groupBcArray = new Array(qCount);  
23 -  
24 - var i;  
25 - for (i = 0; i < this._$_qCount; i++) {  
26 - this._$_groupBcArray[i] = new InternalGroupObj(  
27 - this, this._$_isUp, undefined, undefined);  
28 - }  
29 -  
30 - // 距离上一个路牌的最小发车间隔时间  
31 - // 用于纵向添加班次的时候使用  
32 - // 默认第一个路牌为0  
33 - this._$_minVerticalIntervalTime = 0;  
34 -  
35 - // 详细记录每圈每个方向上的发车间隔时间  
36 - // 第一维度表示圈数,第二维度表示第一个方向,第二个方向  
37 - // 第一个方向是否上行由 _$_isUp 决定  
38 - // 这里的间隔表示下一个路牌上的班次距离本路牌的班次发车时间间隔  
39 - // 如果当前是最后一个路牌,表示第一个路牌的下一圈同方向班次距离本班次的间隔  
40 - this._$_aVerticalIntervalTime = new Array(this._$_qCount);  
41 - var i;  
42 - for (i = 0; i < this._$_aVerticalIntervalTime.length; i++) {  
43 - this._$_aVerticalIntervalTime[i] = new Array(2);  
44 - }  
45 -  
46 - // 班型的相关变量  
47 - this._$_bx_isLb = false; // 是否连班  
48 - this._$_bx_isfb = false; // 是否分班  
49 - this._$_bx_isfb_5_2 = false; // 是否5休2分班  
50 - this._$_bx_desc; // 班型描述(默认为路牌编号)  
51 -  
52 - // 其他班次(进出场,例包,吃饭等),TODO:以后再拆  
53 - this._$_other_bc_array = [];  
54 -  
55 - // TODO:  
56 -  
57 -};  
58 -  
59 -//------------------- get/set 方法 -------------------//  
60 -  
61 -InternalLpObj.prototype.getOtherBcArray = function() {  
62 - return this._$_other_bc_array;  
63 -};  
64 -InternalLpObj.prototype.addOtherBcArray = function(ba) {  
65 - this._$_other_bc_array = this._$_other_bc_array.concat(ba);  
66 -};  
67 -  
68 -/**  
69 - * 获取圈  
70 - * @param qIndex 圈index  
71 - */  
72 -InternalLpObj.prototype.getGroup = function(qIndex) {  
73 - return this._$_groupBcArray[qIndex];  
74 -};  
75 -  
76 -/**  
77 - * 获取班次。  
78 - * @param qIndex 第几圈  
79 - * @param bcIndex 第几个班次  
80 - */  
81 -InternalLpObj.prototype.getBc = function(qIndex, bcIndex) {  
82 - var group = this._$_groupBcArray[qIndex];  
83 - var bc;  
84 - if (bcIndex == 0) {  
85 - bc = group.getBc1();  
86 - } else if (bcIndex == 1) {  
87 - bc = group.getBc2();  
88 - }  
89 - return bc;  
90 -};  
91 -  
92 -/**  
93 - * 在具体位置设置班次。  
94 - * @param qIndex 第几圈  
95 - * @param bcIndex 第几个班次  
96 - * @param bc 班次对象  
97 - */  
98 -InternalLpObj.prototype.setBc = function(qIndex, bcIndex, bc) {  
99 - var group = this._$_groupBcArray[qIndex];  
100 - if (bcIndex == 0) {  
101 - group.setBc1(bc);  
102 - bc.setGroup(group);  
103 - } else if (bcIndex == 1) {  
104 - group.setBc2(bc);  
105 - bc.setGroup(group);  
106 - }  
107 -};  
108 -  
109 -/**  
110 - * 设置原始路牌对象。  
111 - * @param lpObj 原始路牌对象  
112 - */  
113 -InternalLpObj.prototype.setLp = function(lpObj) {  
114 - this._$$_orign_lp_obj = lpObj;  
115 - var i;  
116 - var group;  
117 - for (i = 0; i < this._$_groupBcArray.length; i++) {  
118 - group = this._$_groupBcArray[i];  
119 - if (group) {  
120 - group.setLp(this); // 圈和班次保存都是 InternalLpObj 对象  
121 - }  
122 - }  
123 -};  
124 -  
125 -InternalLpObj.prototype.getLpNo = function() {  
126 - return this._$$_orign_lp_obj.lpNo;  
127 -};  
128 -InternalLpObj.prototype.getLpName = function() {  
129 - return this._$$_orign_lp_obj.lpName;  
130 -};  
131 -InternalLpObj.prototype.setBxFb5_2 = function(fb) {  
132 - this._$_bx_isfb_5_2 = fb;  
133 -};  
134 -InternalLpObj.prototype.isBxFb5_2 = function() {  
135 - return this._$_bx_isfb_5_2;  
136 -};  
137 -InternalLpObj.prototype.setBxLb = function(lb) {  
138 - this._$_bx_isLb = lb;  
139 -};  
140 -InternalLpObj.prototype.isBxLb = function() {  
141 - return this._$_bx_isLb;  
142 -};  
143 -  
144 -InternalLpObj.prototype.setBxFb = function(fb) {  
145 - this._$_bx_isfb = fb;  
146 -};  
147 -InternalLpObj.prototype.isBxFb = function() {  
148 - return this._$_bx_isfb;  
149 -};  
150 -  
151 -/**  
152 - * 设置路牌的班型描述(最终是设置班次的路牌名字)。  
153 - * @param desc 描述  
154 - */  
155 -InternalLpObj.prototype.setBxDesc = function(desc) {  
156 - // 最终原始路牌的名字  
157 - this._$$_orign_lp_obj.lpName = desc + "_" + this._$$_orign_lp_obj.lpNo;  
158 - // 内部对象的班型描述  
159 - this._$_bx_desc = desc;  
160 -};  
161 -/**  
162 - * 获取版型描述  
163 - * @returns string  
164 - */  
165 -InternalLpObj.prototype.getBxDesc = function() {  
166 - return this._$_bx_desc;  
167 -};  
168 -  
169 -/**  
170 - * 设置纵向最小发车间隔时间。  
171 - * @param v  
172 - */  
173 -InternalLpObj.prototype.setVerticalMinIntervalTime = function(v) {  
174 - // 第一个路牌,都为0  
175 - this._$_minVerticalIntervalTime = v;  
176 -};  
177 -/**  
178 - * 获取纵向最小发车间隔时间。  
179 - * @returns {number|*}  
180 - */  
181 -InternalLpObj.prototype.getVerticalMinIntervalTime = function() {  
182 - return this._$_minVerticalIntervalTime;  
183 -};  
184 -  
185 -/**  
186 - * 设置纵向发车间隔。  
187 - * @param iQindex 圈index  
188 - * @param iBindex 班次index  
189 - * @param iTime 间隔时间  
190 - */  
191 -InternalLpObj.prototype.fnSetVerticalIntervalTime = function(iQindex, iBindex, iTime) {  
192 - this._$_aVerticalIntervalTime[iQindex][iBindex] = iTime;  
193 -};  
194 -  
195 -/**  
196 - * 返回纵向发车间隔。  
197 - * @param iQindex 圈index  
198 - * @param iBindex 班次index  
199 - */  
200 -InternalLpObj.prototype.fnGetVerticalIntervalTime = function(iQindex, iBindex) {  
201 - return this._$_aVerticalIntervalTime[iQindex][iBindex];  
202 -};  
203 -  
204 -//-------------------- 班次操作方法(查询,统计,删除) -----------------------//  
205 -  
206 -/**  
207 - * 返回总共班次数。  
208 - */  
209 -InternalLpObj.prototype.getBcCount = function() {  
210 - var i;  
211 - var group;  
212 - var bccount = 0;  
213 - for (i = 0; i < this._$_groupBcArray.length; i++) {  
214 - group = this._$_groupBcArray[i];  
215 - if (group) {  
216 - if (group.getBc1()) {  
217 - bccount += 1;  
218 - }  
219 - if (group.getBc2()) {  
220 - bccount += 1;  
221 - }  
222 - }  
223 - }  
224 -  
225 - return bccount;  
226 -};  
227 -  
228 -/**  
229 - * 返回班次列表,过滤空的班次,将所有存在的班次连成连续的对象数组返回。  
230 - * @returns arrays (InternalBcObj)  
231 - */  
232 -InternalLpObj.prototype.getBcArray = function() {  
233 - var bcArray = [];  
234 - var i;  
235 - var group;  
236 - for (i = 0; i < this._$_groupBcArray.length; i++) {  
237 - group = this._$_groupBcArray[i];  
238 - if (group) {  
239 - group.getBc1() ? bcArray.push(group.getBc1()) : "";  
240 - group.getBc2() ? bcArray.push(group.getBc2()) : "";  
241 - }  
242 - }  
243 -  
244 - return bcArray;  
245 -};  
246 -  
247 -/**  
248 - * 获取最小(最早)班次对象。  
249 - * @returns [{圈index},{班次index}]  
250 - */  
251 -InternalLpObj.prototype.getMinBcObjPosition = function() {  
252 - var i;  
253 - var bIndex = [];  
254 - for (i = 0; i < this._$_groupBcArray.length; i++) {  
255 - if (this._$_groupBcArray[i].getBc1()) {  
256 - bIndex.push(i);  
257 - bIndex.push(0);  
258 - break;  
259 - }  
260 - if (this._$_groupBcArray[i].getBc2()) {  
261 - bIndex.push(i);  
262 - bIndex.push(1);  
263 - break;  
264 - }  
265 - }  
266 - return bIndex;  
267 -};  
268 -  
269 -/**  
270 - * 获取最大(最晚)班次对象。  
271 - * @returns [{圈index},{班次index}]  
272 - */  
273 -InternalLpObj.prototype.getMaxBcObjPosition = function() {  
274 - var i;  
275 - var bIndex = [];  
276 - for (i = this._$_groupBcArray.length - 1; i >= 0; i--) {  
277 - if (this._$_groupBcArray[i].getBc2()) {  
278 - bIndex.push(i);  
279 - bIndex.push(1);  
280 - break;  
281 - }  
282 - if (this._$_groupBcArray[i].getBc1()) {  
283 - bIndex.push(i);  
284 - bIndex.push(0);  
285 - break;  
286 - }  
287 - }  
288 - return bIndex;  
289 -};  
290 -  
291 -InternalLpObj.prototype.getMinBcObj = function() {  
292 - var i;  
293 - var bcObj;  
294 - for (i = 0; i < this._$_groupBcArray.length; i++) {  
295 - bcObj = this._$_groupBcArray[i].getBc1();  
296 - if (bcObj) {  
297 - break;  
298 - }  
299 - bcObj = this._$_groupBcArray[i].getBc2();  
300 - if (bcObj) {  
301 - break;  
302 - }  
303 - }  
304 - return bcObj;  
305 -};  
306 -InternalLpObj.prototype.getMaxBcObj = function() {  
307 - var i;  
308 - var bcObj;  
309 - for (i = this._$_groupBcArray.length - 1; i >= 0; i--) {  
310 - bcObj = this._$_groupBcArray[i].getBc2();  
311 - if (bcObj) {  
312 - break;  
313 - }  
314 - bcObj = this._$_groupBcArray[i].getBc1();  
315 - if (bcObj) {  
316 - break;  
317 - }  
318 - }  
319 - return bcObj;  
320 -};  
321 -  
322 -/**  
323 - * 获取车次链信息。  
324 - * @param num 第几个车次链  
325 - * @returns object {s_q: {开始圈索引},s_b : {开始班次索引},e_q : {结束圈索引},e_b : {结束班次索引}, bcount : {班次数}}  
326 - */  
327 -InternalLpObj.prototype.fnGetBcChainInfo = function(num) {  
328 - // 计算总的车次链信息  
329 - var aChainInfo = [];  
330 - var oChainInfo;  
331 - var aBcIndex = this.getMinBcObjPosition();  
332 - var oBc;  
333 - var iQIndex;  
334 - var iBcIndex;  
335 - var i;  
336 - var bFlag;  
337 -  
338 - var iBcount = 0;  
339 -  
340 - if (aBcIndex.length == 2) {  
341 - iBcount = 1;  
342 - oChainInfo = {s_q : aBcIndex[0], s_b : aBcIndex[1], e_q : aBcIndex[0], e_b : aBcIndex[1], bcount: 1};  
343 - aChainInfo.push(oChainInfo);  
344 - bFlag = true;  
345 -  
346 - // 下一个班次的索引  
347 - iQIndex = aBcIndex[1] == 0 ? aBcIndex[0] : aBcIndex[0] + 1;  
348 - iBcIndex = aBcIndex[1] == 0 ? 1 : 0;  
349 -  
350 - for (i = iQIndex; i < this._$_qCount; i++) {  
351 - while (iBcIndex <= 1) {  
352 - oBc = this.getBc(i, iBcIndex);  
353 - if (!oBc) {  
354 - if (bFlag) {  
355 - // 车次链结尾是这个班次的前一个班次  
356 - oChainInfo.e_q = iBcIndex == 0 ? i - 1 : i;  
357 - oChainInfo.e_b = iBcIndex == 0 ? 1 : 0;  
358 - oChainInfo.bcount = iBcount;  
359 - }  
360 -  
361 - bFlag = false;  
362 - } else {  
363 - if (bFlag) {  
364 - iBcount ++;  
365 - oChainInfo.bcount = iBcount;  
366 - } else {  
367 - // 下一个车次链开始  
368 - iBcount = 1;  
369 - oChainInfo = {s_q : i, s_b : iBcIndex, e_q : i, e_b : iBcIndex, bcount: 1};  
370 - aChainInfo.push(oChainInfo);  
371 - bFlag = true;  
372 - }  
373 - }  
374 -  
375 -  
376 - iBcIndex ++;  
377 - }  
378 - iBcIndex = 0;  
379 - }  
380 -  
381 - }  
382 -  
383 - return aChainInfo[num];  
384 -};  
385 -  
386 -/**  
387 - * 获取车次链的个数。  
388 - * @returns int  
389 - */  
390 -InternalLpObj.prototype.fnGetBcChainCount = function() {  
391 - var iChainCount = 0;  
392 - var aBcIndex = this.getMinBcObjPosition();  
393 -  
394 - var oBc;  
395 - var iQIndex;  
396 - var iBcIndex;  
397 - var i;  
398 - var bFlag;  
399 -  
400 - if (aBcIndex.length == 2) {  
401 - iChainCount = 1;  
402 - bFlag = true;  
403 -  
404 - // 下一个班次的索引  
405 - iQIndex = aBcIndex[1] == 0 ? aBcIndex[0] : aBcIndex[0] + 1;  
406 - iBcIndex = aBcIndex[1] == 0 ? 1 : 0;  
407 -  
408 - for (i = iQIndex; i < this._$_qCount; i++) {  
409 - while (iBcIndex <= 1) {  
410 - oBc = this.getBc(i, iBcIndex);  
411 - if (!oBc) {  
412 - bFlag = false;  
413 - } else {  
414 - if (bFlag) {  
415 -  
416 - } else {  
417 - iChainCount ++;  
418 - bFlag = true;  
419 - }  
420 - }  
421 -  
422 -  
423 - iBcIndex ++;  
424 - }  
425 - iBcIndex = 0;  
426 - }  
427 -  
428 - }  
429 -  
430 -  
431 - return iChainCount;  
432 -};  
433 -  
434 -/**  
435 - * 在具体位置移除班次。  
436 - * @param qIndex 第几圈  
437 - * @param bcIndex 第几个班次  
438 - */  
439 -InternalLpObj.prototype.removeBc = function(qIndex, bcIndex) {  
440 - var group = this._$_groupBcArray[qIndex];  
441 - if (bcIndex == 0) {  
442 - group.removeBc1();  
443 - } else if (bcIndex == 1) {  
444 - group.removeBc2();  
445 - }  
446 -};  
447 -  
448 -/**  
449 - * 使用指定时间匹配返回离之最近的第几圈第几个班次,  
450 - * 使用时间差的绝度值,比较,取最小的  
451 - * 如果有两个一样的时间差,取比fctime大的时间  
452 - * @param fctime moment 比较用时间  
453 - * @param groupArray 圈数组  
454 - * @param hasUp boolean 计算上行班次  
455 - * @param hasDown boolean 计算下行班次  
456 - * @returns [{第几圈},{第几个班次}]  
457 - */  
458 -InternalLpObj.prototype.fnGetQBcIndexWithFcTimeFromGroupArray = function(  
459 - fctime, groupArray, hasUp, hasDown  
460 -) {  
461 - var i;  
462 - var timediff; // 时间差取绝对值  
463 - var qIndex;  
464 - var bcIndex;  
465 -  
466 - var group;  
467 - var bc1time;  
468 - var bc2time;  
469 -  
470 - var tempdiff;  
471 -  
472 - console.log("比较时间=" + fctime.format("HH:mm"));  
473 -  
474 - for (i = 0; i < this._$_qCount; i++) {  
475 - group = groupArray[i];  
476 - if (group) {  
477 - if (group.getBc1() && hasUp) {  
478 - bc1time = group.getBc1().getFcTimeObj();  
479 - console.log("bc1time=" + bc1time.format("HH:mm") + " tempdiff=" + tempdiff);  
480 - tempdiff = Math.abs(bc1time.diff(fctime));  
481 -  
482 - if (!timediff) {  
483 - timediff = Math.abs(tempdiff);  
484 - qIndex = i;  
485 - bcIndex = 0;  
486 - } else {  
487 - if (tempdiff < timediff) {  
488 - timediff = tempdiff;  
489 - qIndex = i;  
490 - bcIndex = 0;  
491 - } if (Math.abs(tempdiff) == timediff) {  
492 - if (bc1time.isAfter(fctime)) {  
493 - timediff = tempdiff;  
494 - qIndex = i;  
495 - bcIndex = 0;  
496 - }  
497 -  
498 - }  
499 - }  
500 - }  
501 -  
502 - if (group.getBc2() && hasDown) {  
503 - bc2time = group.getBc2().getFcTimeObj();  
504 - console.log("bc2time=" + bc2time.format("HH:mm") + " tempdiff=" + tempdiff);  
505 - tempdiff = Math.abs(bc2time.diff(fctime));  
506 -  
507 - if (!timediff) {  
508 - timediff = Math.abs(tempdiff);  
509 - qIndex = i;  
510 - bcIndex = 1;  
511 - } else {  
512 - if (tempdiff < timediff) {  
513 - timediff = tempdiff;  
514 - qIndex = i;  
515 - bcIndex = 1;  
516 - } if (Math.abs(tempdiff) == timediff) {  
517 - if (bc2time.isBefore(fctime)) {  
518 - timediff = tempdiff;  
519 - qIndex = i;  
520 - bcIndex = 1;  
521 - }  
522 -  
523 - }  
524 - }  
525 - }  
526 - }  
527 - }  
528 -  
529 - console.log("中标线对应数组索引=" + qIndex);  
530 -  
531 - var rst = [];  
532 - rst.push(qIndex);  
533 - rst.push(bcIndex);  
534 -  
535 - return rst;  
536 -};  
537 -  
538 -/**  
539 - * 使用指定时间匹配返回离之最近的第几圈第几个班次,  
540 - * 使用时间差的绝度值,比较,取最小的  
541 - * 如果有两个一样的时间差,取比fctime大的时间  
542 - * @param fctime moment 比较用时间  
543 - * @param hasUp boolean 计算上行班次  
544 - * @param hasDown boolean 计算下行班次  
545 - * @returns [{第几圈},{第几个班次}]  
546 - */  
547 -InternalLpObj.prototype.getQBcIndexWithFcTime = function(  
548 - fctime, hasUp, hasDown  
549 -) {  
550 - return this.fnGetQBcIndexWithFcTimeFromGroupArray(fctime, this._$_groupBcArray, hasUp, hasDown);  
551 -};  
552 -  
553 -//---------------------- 内部数据初始化方法(不同于构造函数)---------------------//  
554 -  
555 -/**  
556 - * 从指定开始时间到结束时间创建不间断班次(连班),并初始化路牌  
557 - * 注意,之前有班次会删除后再创建。  
558 - * @param startTime 开始时间  
559 - * @param endTime 结束时间  
560 - * @param isUp 第一个班次是上行还是下行  
561 - * @param fromQ 从第几圈开始加入  
562 - * @param paramObj 参数对象  
563 - * @param factory 工厂对象  
564 - */  
565 -InternalLpObj.prototype.initDataFromTimeToTime = function(  
566 - startTime,  
567 - endTime,  
568 - isUp,  
569 - fromQ,  
570 - paramObj,  
571 - factory) {  
572 -  
573 - var bcData = []; // 班次数组  
574 - var bcObj;  
575 - var kssj = startTime;  
576 - var fcno = 1; // 发车顺序号  
577 - var bcCount = 1; // 班次数  
578 - do {  
579 - bcObj = factory.createBcObj(  
580 - this, "normal", isUp, fcno, kssj, paramObj); // this就是所属路牌对象  
581 - bcData.push(bcObj);  
582 -  
583 - kssj = paramObj.addMinute(kssj, bcObj.getBcTime() + bcObj.getStopTime());  
584 - fcno ++;  
585 - bcCount ++;  
586 - isUp = !isUp;  
587 - } while(kssj.isBefore(endTime));  
588 - bcCount--;  
589 -  
590 - //console.log("last -1;" + bcData[bcCount -2].getFcTimeObj().format("HH:mm"));  
591 - //console.log("last;" + bcData[bcCount -1].getFcTimeObj().format("HH:mm"));  
592 - //console.log("endtime: " + endTime.format("HH:mm"));  
593 -  
594 - //if (bcCount > 0 && bcData[bcCount - 1].getArrTimeObj().isAfter(endTime)) {  
595 - // // 如果最后一个班次的到达时间超过结束时间,也要去除  
596 - // bcData.splice(bcCount - 1, 1);  
597 - //}  
598 -  
599 - this._initDataFromLbBcArray(bcData, fromQ);  
600 -  
601 -};  
602 -  
603 -/**  
604 - * 使用连班的班次数组初始化路牌(相应的圈会被覆盖)。  
605 - * @param bcArray 连班班次数组  
606 - * @param fromQ 从第几圈开始加入  
607 - */  
608 -InternalLpObj.prototype._initDataFromLbBcArray = function(  
609 - bcArray,  
610 - fromQ  
611 -) {  
612 - var _bc1Obj;  
613 - var _bc2Obj;  
614 - var _qObj;  
615 -  
616 - // 第一班次是上行还是下行  
617 - var isUp = bcArray[0].isUp();  
618 -  
619 - if (bcArray.length > 0 && fromQ < this._$_qCount) {  
620 - // 构造圈数  
621 - if (isUp != this._$_isUp) {  
622 - // 如果方向不一致,意味着第一个班次是半圈  
623 - // 加半圈,并加在bc2上  
624 - _bc2Obj = bcArray.slice(0, 1)[0];  
625 - _qObj = new InternalGroupObj(  
626 - this,  
627 - this._$_isUp,  
628 - undefined,  
629 - _bc2Obj  
630 - );  
631 - _bc2Obj.setGroup(_qObj);  
632 - this._$_groupBcArray[fromQ] = _qObj;  
633 -  
634 - bcArray.splice(0, 1);  
635 - fromQ ++;  
636 - }  
637 -  
638 - var qCount1 = Math.floor(bcArray.length / 2); // 需要添加多少圈  
639 - var qCount2 = bcArray.length % 2; // 最后是否有半圈  
640 -  
641 - while (fromQ < this._$_qCount) {  
642 - if (qCount1 > 0) {  
643 - _bc1Obj = bcArray.slice(0, 1)[0];  
644 - _bc2Obj = bcArray.slice(1, 2)[0];  
645 - _qObj = new InternalGroupObj(  
646 - this,  
647 - this._$_isUp,  
648 - _bc1Obj,  
649 - _bc2Obj  
650 - );  
651 - _bc1Obj.setGroup(_qObj);  
652 - _bc2Obj.setGroup(_qObj);  
653 - this._$_groupBcArray[fromQ] = _qObj;  
654 -  
655 - bcArray.splice(0, 2);  
656 - qCount1 --;  
657 - } else if (qCount2 > 0) {  
658 - // 加半圈,并加在bc1上  
659 - _bc1Obj = bcArray.slice(0, 1)[0];  
660 - _qObj = new InternalGroupObj(  
661 - this,  
662 - this._$_isUp,  
663 - _bc1Obj,  
664 - undefined  
665 - );  
666 - _bc1Obj.setGroup(_qObj);  
667 - this._$_groupBcArray[fromQ] = _qObj;  
668 -  
669 - bcArray.splice(0, 1);  
670 - qCount2 --;  
671 - } else {  
672 - break;  
673 - }  
674 -  
675 - fromQ ++;  
676 - }  
677 - }  
678 -};  
679 -  
680 -//-------------------------- 其他方法 ----------------------------//  
681 -  
682 -/**  
683 - * 从指定位置的班次开始,往后所有的班次修正发车时间  
684 - * @param groupIndex  
685 - * @param bcIndex  
686 - * @param time  
687 - */  
688 -InternalLpObj.prototype.fnAddMinuteToBcFcsj = function(groupIndex, bcIndex, time) {  
689 - var i;  
690 - var oCurBc;  
691 -  
692 - // 修正之前班次的停站时间  
693 - //oCurBc = this.getBc(  
694 - // bcIndex == 0 ? groupIndex - 1 : groupIndex,  
695 - // bcIndex == 1 ? 0 : 1  
696 - //);  
697 - //if (oCurBc) {  
698 - // oCurBc.setStopTime(oCurBc.getStopTime() + time);  
699 - //}  
700 -  
701 -  
702 - for (i = groupIndex; i < this._$_qCount; i++) {  
703 - if (bcIndex == 0) {  
704 - oCurBc = this.getBc(i, 0);  
705 - if (oCurBc) {  
706 - oCurBc.addMinuteToFcsj(time);  
707 - }  
708 - oCurBc = this.getBc(i, 1);  
709 - if (oCurBc) {  
710 - oCurBc.addMinuteToFcsj(time);  
711 - }  
712 -  
713 - } else {  
714 - oCurBc = this.getBc(i, 1);  
715 - if (oCurBc) {  
716 - oCurBc.addMinuteToFcsj(time);  
717 - }  
718 -  
719 - }  
720 -  
721 - bcIndex = 0;  
722 - }  
723 -};  
724 -  
725 -/**  
726 - * 在指定位置添加一个吃饭班次。  
727 - * 注1:吃饭班次不是普通班次,不记录进圈,记录进_$_other_bc_array  
728 - * 注2:添加吃饭班次时,会修改之前班次的停战时间,所以导致之后的班次的停战都会发生变化  
729 - * @param groupIndex  
730 - * @param bcIndex  
731 - * @param factory  
732 - * @param paramObj  
733 - * @returns int 相差时间(吃饭时间距离和停站时间相差值)  
734 - */  
735 -InternalLpObj.prototype.fnAddEatBc = function(groupIndex, bcIndex, factory, paramObj) {  
736 - var oPreBc;  
737 - var oEatBc;  
738 - var iBcModifyTime;  
739 - oPreBc = this.getBc( // 前一个邻接班次  
740 - bcIndex == 0 ? groupIndex - 1 : groupIndex,  
741 - bcIndex == 1 ? 0 : 1);  
742 - if (oPreBc) { // 存在前一个班次  
743 - oEatBc = factory.createBcObj(  
744 - this,  
745 - "cf",  
746 - !oPreBc.isUp(), // 和上一个班次方向相反  
747 - 1,  
748 - paramObj.addMinute(oPreBc.getArrTimeObj(), oPreBc.getStopTime()), // 使用上一个班次的到达时间作为开始时间  
749 - paramObj  
750 - );  
751 -  
752 - //iBcModifyTime = oEatBc.getBcTime() - oPreBc.getStopTime(); // 后续班次要调整的时间  
753 -  
754 - // 修正之后的班次发车时间  
755 - // 注意:之后那个班次发车时间就是吃饭班次的到达时间  
756 - iBcModifyTime = oEatBc.getArrTimeObj().diff(this.getBc(groupIndex, bcIndex).getFcTimeObj(), "m");  
757 - this.fnAddMinuteToBcFcsj(groupIndex, bcIndex, iBcModifyTime);  
758 -  
759 - oPreBc.setStopTime(0); // 不重置停站时间  
760 - oPreBc.fnSetEatTime(oEatBc.getBcTime());  
761 -  
762 - //this._$_other_bc_array.push(oEatBc);  
763 -  
764 - return iBcModifyTime;  
765 - } else {  
766 - return false;  
767 - }  
768 -  
769 -};  
770 -  
771 -/**  
772 - * 调整路牌的班次,通过调整停站时间,或者班次发车时间,不能让班次的到达时间和下一个班次的发车时间重叠。  
773 - * @param iPeakAverStopTime 高峰平均停站时间  
774 - * @param iTroughAverStopTime 低谷平均停站时间  
775 - * @param oParam 参数对象  
776 - */  
777 -InternalLpObj.prototype.fnAdjustBcInterval = function(iPeakAverStopTime, iTroughAverStopTime, oParam) {  
778 - // 获取车次链个数  
779 - var iBcChainCount = this.fnGetBcChainCount();  
780 -  
781 - var i;  
782 - var j;  
783 - var oBcIndex;  
784 - var iQIndex;  
785 - var iBcIndex;  
786 - var iBcCount;  
787 - var oBc;  
788 - var oNextBc;  
789 -  
790 - var iBcStopTime;  
791 -  
792 - for (i = 0; i < iBcChainCount; i++) {  
793 - oBcIndex = this.fnGetBcChainInfo(i);  
794 - iQIndex = oBcIndex["s_q"];  
795 - iBcIndex = oBcIndex["s_b"];  
796 - iBcCount = oBcIndex["bcount"];  
797 -  
798 - for (j = 0; j < iBcCount - 1; j++) {  
799 - oBc = this.getBc(iQIndex, iBcIndex);  
800 - oNextBc = this.getBc(  
801 - iBcIndex == 0 ? iQIndex : iQIndex + 1,  
802 - iBcIndex == 0 ? 1 : 0);  
803 -  
804 - if (oNextBc.fnIsFirstBc()) { // 如果同一路牌连续2个方向首站班次,都不做处理  
805 - continue;  
806 - }  
807 -  
808 - // 不改变当前班次的行驶时间,修正停站时间和下一个班次的发车时间  
809 - iBcStopTime = oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m");  
810 - if (iBcStopTime < 0) {  
811 - // 当前班次使用最小停站时间  
812 - oBc.setStopTime(oParam.fnCalcuFixedMinStopNumber(oBc.getArrTimeObj(), oBc.isUp()));  
813 - oNextBc.addMinuteToFcsj(oBc.getStopTime() + oBc.fnGetEatTime() - iBcStopTime);  
814 -  
815 - } else {  
816 - if (iBcStopTime == oBc.getStopTime() + oBc.fnGetEatTime()) {  
817 - // 停站时间一致,没有问题  
818 -  
819 -  
820 - } else {  
821 - // TODO:当前班次使用最小停站时间  
822 - oBc.setStopTime(oParam.fnCalcuFixedMinStopNumber(oBc.getArrTimeObj(), oBc.isUp()));  
823 - oNextBc.addMinuteToFcsj(oBc.getStopTime() + oBc.fnGetEatTime() - iBcStopTime);  
824 -  
825 - }  
826 - }  
827 -  
828 - iBcIndex = iBcIndex == 0 ? 1 : 0;  
829 - iQIndex = iBcIndex == 0 ? iQIndex + 1 : iQIndex;  
830 - }  
831 -  
832 - this.getBc(iQIndex, iBcIndex).setStopTime(0);  
833 - }  
834 -  
835 -  
836 -};  
837 -  
838 -  
839 -// TODO  
840 -  
841 -/**  
842 - *  
843 - *  
844 - */  
845 -InternalLpObj.prototype.calcuLpBx = function() {  
846 -  
847 -};  
848 -  
849 -  
850 -  
851 -  
852 -  
853 -  
854 - 1 +/**
  2 + * 内部路牌对象。
  3 + * @constructor
  4 + */
  5 +var InternalLpObj = function(
  6 + orilpObj, // 原始路牌对象
  7 + qCount, // 总共多少圈
  8 + isUp // 圈是以上行开始还是下行开始
  9 +) {
  10 + // TODO:原始路牌对象(这个路牌是对接外部gantt图像,以后有机会改了)
  11 + this._$$_orign_lp_obj = orilpObj;
  12 +
  13 + this._$_isUp = isUp;
  14 +
  15 + // 路牌的圈数,注意每个路牌的圈数都是一致的,
  16 + // 但并不是每一圈都有值
  17 + // 第1圈从上标线开始
  18 + // 第0圈表示中标线的第一个班次组成的半圈
  19 + // 有多少圈根据最终迭代的结果来看
  20 + this._$_qCount = qCount;
  21 + // 保存的是 InternalGroupBcObj 对象
  22 + this._$_groupBcArray = new Array(qCount);
  23 +
  24 + var i;
  25 + for (i = 0; i < this._$_qCount; i++) {
  26 + this._$_groupBcArray[i] = new InternalGroupObj(
  27 + this, this._$_isUp, undefined, undefined);
  28 + }
  29 +
  30 + // 距离上一个路牌的最小发车间隔时间
  31 + // 用于纵向添加班次的时候使用
  32 + // 默认第一个路牌为0
  33 + this._$_minVerticalIntervalTime = 0;
  34 +
  35 + // 详细记录每圈每个方向上的发车间隔时间
  36 + // 第一维度表示圈数,第二维度表示第一个方向,第二个方向
  37 + // 第一个方向是否上行由 _$_isUp 决定
  38 + // 这里的间隔表示下一个路牌上的班次距离本路牌的班次发车时间间隔
  39 + // 如果当前是最后一个路牌,表示第一个路牌的下一圈同方向班次距离本班次的间隔
  40 + this._$_aVerticalIntervalTime = new Array(this._$_qCount);
  41 + for (i = 0; i < this._$_aVerticalIntervalTime.length; i++) {
  42 + this._$_aVerticalIntervalTime[i] = new Array(2);
  43 + }
  44 +
  45 + // 班型的相关变量
  46 + this._$_bx_isLb = false; // 是否连班
  47 + this._$_bx_isfb = false; // 是否分班
  48 + this._$_bx_isfb_5_2 = false; // 是否5休2分班
  49 + this._$_bx_desc; // 班型描述(默认为路牌编号)
  50 +
  51 + // 其他班次(进出场,例包,吃饭等),TODO:以后再拆
  52 + this._$_other_bc_array = [];
  53 +
  54 + // TODO:
  55 +
  56 +};
  57 +
  58 +//------------------- get/set 方法 -------------------//
  59 +
  60 +InternalLpObj.prototype.getOtherBcArray = function() {
  61 + return this._$_other_bc_array;
  62 +};
  63 +InternalLpObj.prototype.addOtherBcArray = function(ba) {
  64 + this._$_other_bc_array = this._$_other_bc_array.concat(ba);
  65 +};
  66 +
  67 +/**
  68 + * 获取圈
  69 + * @param qIndex 圈index
  70 + */
  71 +InternalLpObj.prototype.getGroup = function(qIndex) {
  72 + return this._$_groupBcArray[qIndex];
  73 +};
  74 +
  75 +/**
  76 + * 获取路牌圈数。
  77 + * @returns {*}
  78 + */
  79 +InternalLpObj.prototype.fnGetGroupCount = function() {
  80 + return this._$_qCount;
  81 +};
  82 +
  83 +/**
  84 + * 是否上行。
  85 + * @returns boolean
  86 + */
  87 +InternalLpObj.prototype.isUp = function() {
  88 + return this._$_isUp;
  89 +};
  90 +
  91 +/**
  92 + * 获取班次。
  93 + * @param qIndex 第几圈
  94 + * @param bcIndex 第几个班次
  95 + */
  96 +InternalLpObj.prototype.getBc = function(qIndex, bcIndex) {
  97 + var group = this._$_groupBcArray[qIndex];
  98 + var bc;
  99 + if (bcIndex == 0) {
  100 + bc = group.getBc1();
  101 + } else if (bcIndex == 1) {
  102 + bc = group.getBc2();
  103 + }
  104 + return bc;
  105 +};
  106 +
  107 +/**
  108 + * 在具体位置设置班次。
  109 + * @param qIndex 第几圈
  110 + * @param bcIndex 第几个班次
  111 + * @param bc 班次对象
  112 + */
  113 +InternalLpObj.prototype.setBc = function(qIndex, bcIndex, bc) {
  114 + var group = this._$_groupBcArray[qIndex];
  115 + if (bcIndex == 0) {
  116 + group.setBc1(bc);
  117 + bc.setGroup(group);
  118 + } else if (bcIndex == 1) {
  119 + group.setBc2(bc);
  120 + bc.setGroup(group);
  121 + }
  122 +};
  123 +
  124 +/**
  125 + * 设置原始路牌对象。
  126 + * @param lpObj 原始路牌对象
  127 + */
  128 +InternalLpObj.prototype.setLp = function(lpObj) {
  129 + this._$$_orign_lp_obj = lpObj;
  130 + var i;
  131 + var group;
  132 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  133 + group = this._$_groupBcArray[i];
  134 + if (group) {
  135 + group.setLp(this); // 圈和班次保存都是 InternalLpObj 对象
  136 + }
  137 + }
  138 +};
  139 +
  140 +InternalLpObj.prototype.getLpNo = function() {
  141 + return this._$$_orign_lp_obj.lpNo;
  142 +};
  143 +InternalLpObj.prototype.getLpName = function() {
  144 + return this._$$_orign_lp_obj.lpName;
  145 +};
  146 +InternalLpObj.prototype.setBxFb5_2 = function(fb) {
  147 + this._$_bx_isfb_5_2 = fb;
  148 +};
  149 +InternalLpObj.prototype.isBxFb5_2 = function() {
  150 + return this._$_bx_isfb_5_2;
  151 +};
  152 +InternalLpObj.prototype.setBxLb = function(lb) {
  153 + this._$_bx_isLb = lb;
  154 +};
  155 +InternalLpObj.prototype.isBxLb = function() {
  156 + return this._$_bx_isLb;
  157 +};
  158 +
  159 +InternalLpObj.prototype.setBxFb = function(fb) {
  160 + this._$_bx_isfb = fb;
  161 +};
  162 +InternalLpObj.prototype.isBxFb = function() {
  163 + return this._$_bx_isfb;
  164 +};
  165 +
  166 +/**
  167 + * 设置路牌的班型描述(最终是设置班次的路牌名字)。
  168 + * @param desc 描述
  169 + */
  170 +InternalLpObj.prototype.setBxDesc = function(desc) {
  171 + // 最终原始路牌的名字
  172 + this._$$_orign_lp_obj.lpName = desc + "_" + this._$$_orign_lp_obj.lpNo;
  173 + // 内部对象的班型描述
  174 + this._$_bx_desc = desc;
  175 +};
  176 +/**
  177 + * 获取版型描述
  178 + * @returns string
  179 + */
  180 +InternalLpObj.prototype.getBxDesc = function() {
  181 + return this._$_bx_desc;
  182 +};
  183 +
  184 +/**
  185 + * 设置纵向最小发车间隔时间。
  186 + * @param v
  187 + */
  188 +InternalLpObj.prototype.setVerticalMinIntervalTime = function(v) {
  189 + // 第一个路牌,都为0
  190 + this._$_minVerticalIntervalTime = v;
  191 +};
  192 +/**
  193 + * 获取纵向最小发车间隔时间。
  194 + * @returns {number|*}
  195 + */
  196 +InternalLpObj.prototype.getVerticalMinIntervalTime = function() {
  197 + return this._$_minVerticalIntervalTime;
  198 +};
  199 +
  200 +/**
  201 + * 设置纵向发车间隔。
  202 + * @param iQindex 圈index
  203 + * @param iBindex 班次index
  204 + * @param iTime 间隔时间
  205 + */
  206 +InternalLpObj.prototype.fnSetVerticalIntervalTime = function(iQindex, iBindex, iTime) {
  207 + this._$_aVerticalIntervalTime[iQindex][iBindex] = iTime;
  208 +};
  209 +
  210 +/**
  211 + * 返回纵向发车间隔。
  212 + * @param iQindex 圈index
  213 + * @param iBindex 班次index
  214 + */
  215 +InternalLpObj.prototype.fnGetVerticalIntervalTime = function(iQindex, iBindex) {
  216 + return this._$_aVerticalIntervalTime[iQindex][iBindex];
  217 +};
  218 +
  219 +//-------------------- 班次操作方法(查询,统计,删除) -----------------------//
  220 +
  221 +/**
  222 + * 返回总共班次数。
  223 + */
  224 +InternalLpObj.prototype.getBcCount = function() {
  225 + var i;
  226 + var group;
  227 + var bccount = 0;
  228 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  229 + group = this._$_groupBcArray[i];
  230 + if (group) {
  231 + if (group.getBc1()) {
  232 + bccount += 1;
  233 + }
  234 + if (group.getBc2()) {
  235 + bccount += 1;
  236 + }
  237 + }
  238 + }
  239 +
  240 + return bccount;
  241 +};
  242 +
  243 +/**
  244 + * 返回班次列表,过滤空的班次,将所有存在的班次连成连续的对象数组返回。
  245 + * @returns arrays (InternalBcObj)
  246 + */
  247 +InternalLpObj.prototype.getBcArray = function() {
  248 + var bcArray = [];
  249 + var i;
  250 + var group;
  251 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  252 + group = this._$_groupBcArray[i];
  253 + if (group) {
  254 + group.getBc1() ? bcArray.push(group.getBc1()) : "";
  255 + group.getBc2() ? bcArray.push(group.getBc2()) : "";
  256 + }
  257 + }
  258 +
  259 + return bcArray;
  260 +};
  261 +
  262 +/**
  263 + * 获取最小(最早)班次对象。
  264 + * @returns [{圈index},{班次index}]
  265 + */
  266 +InternalLpObj.prototype.getMinBcObjPosition = function() {
  267 + var i;
  268 + var bIndex = [];
  269 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  270 + if (this._$_groupBcArray[i].getBc1()) {
  271 + bIndex.push(i);
  272 + bIndex.push(0);
  273 + break;
  274 + }
  275 + if (this._$_groupBcArray[i].getBc2()) {
  276 + bIndex.push(i);
  277 + bIndex.push(1);
  278 + break;
  279 + }
  280 + }
  281 + return bIndex;
  282 +};
  283 +
  284 +/**
  285 + * 获取最大(最晚)班次对象。
  286 + * @returns [{圈index},{班次index}]
  287 + */
  288 +InternalLpObj.prototype.getMaxBcObjPosition = function() {
  289 + var i;
  290 + var bIndex = [];
  291 + for (i = this._$_groupBcArray.length - 1; i >= 0; i--) {
  292 + if (this._$_groupBcArray[i].getBc2()) {
  293 + bIndex.push(i);
  294 + bIndex.push(1);
  295 + break;
  296 + }
  297 + if (this._$_groupBcArray[i].getBc1()) {
  298 + bIndex.push(i);
  299 + bIndex.push(0);
  300 + break;
  301 + }
  302 + }
  303 + return bIndex;
  304 +};
  305 +
  306 +InternalLpObj.prototype.getMinBcObj = function() {
  307 + var i;
  308 + var bcObj;
  309 + for (i = 0; i < this._$_groupBcArray.length; i++) {
  310 + bcObj = this._$_groupBcArray[i].getBc1();
  311 + if (bcObj) {
  312 + break;
  313 + }
  314 + bcObj = this._$_groupBcArray[i].getBc2();
  315 + if (bcObj) {
  316 + break;
  317 + }
  318 + }
  319 + return bcObj;
  320 +};
  321 +InternalLpObj.prototype.getMaxBcObj = function() {
  322 + var i;
  323 + var bcObj;
  324 + for (i = this._$_groupBcArray.length - 1; i >= 0; i--) {
  325 + bcObj = this._$_groupBcArray[i].getBc2();
  326 + if (bcObj) {
  327 + break;
  328 + }
  329 + bcObj = this._$_groupBcArray[i].getBc1();
  330 + if (bcObj) {
  331 + break;
  332 + }
  333 + }
  334 + return bcObj;
  335 +};
  336 +
  337 +/**
  338 + * 获取车次链信息。
  339 + * @param num 第几个车次链
  340 + * @returns object {s_q: {开始圈索引},s_b : {开始班次索引},e_q : {结束圈索引},e_b : {结束班次索引}, bcount : {班次数}}
  341 + */
  342 +InternalLpObj.prototype.fnGetBcChainInfo = function(num) {
  343 + // 计算总的车次链信息
  344 + var aChainInfo = [];
  345 + var oChainInfo;
  346 + var aBcIndex = this.getMinBcObjPosition();
  347 + var oBc;
  348 + var iQIndex;
  349 + var iBcIndex;
  350 + var i;
  351 + var bFlag;
  352 +
  353 + var iBcount = 0;
  354 +
  355 + if (aBcIndex.length == 2) {
  356 + iBcount = 1;
  357 + oChainInfo = {s_q : aBcIndex[0], s_b : aBcIndex[1], e_q : aBcIndex[0], e_b : aBcIndex[1], bcount: 1};
  358 + aChainInfo.push(oChainInfo);
  359 + bFlag = true;
  360 +
  361 + // 下一个班次的索引
  362 + iQIndex = aBcIndex[1] == 0 ? aBcIndex[0] : aBcIndex[0] + 1;
  363 + iBcIndex = aBcIndex[1] == 0 ? 1 : 0;
  364 +
  365 + for (i = iQIndex; i < this._$_qCount; i++) {
  366 + while (iBcIndex <= 1) {
  367 + oBc = this.getBc(i, iBcIndex);
  368 + if (!oBc) {
  369 + if (bFlag) {
  370 + // 车次链结尾是这个班次的前一个班次
  371 + oChainInfo.e_q = iBcIndex == 0 ? i - 1 : i;
  372 + oChainInfo.e_b = iBcIndex == 0 ? 1 : 0;
  373 + oChainInfo.bcount = iBcount;
  374 + }
  375 +
  376 + bFlag = false;
  377 + } else {
  378 + if (bFlag) {
  379 + iBcount ++;
  380 + oChainInfo.bcount = iBcount;
  381 + } else {
  382 + // 下一个车次链开始
  383 + iBcount = 1;
  384 + oChainInfo = {s_q : i, s_b : iBcIndex, e_q : i, e_b : iBcIndex, bcount: 1};
  385 + aChainInfo.push(oChainInfo);
  386 + bFlag = true;
  387 + }
  388 + }
  389 +
  390 +
  391 + iBcIndex ++;
  392 + }
  393 + iBcIndex = 0;
  394 + }
  395 +
  396 + }
  397 +
  398 + return aChainInfo[num];
  399 +};
  400 +
  401 +/**
  402 + * 获取车次链的个数。
  403 + * @returns int
  404 + */
  405 +InternalLpObj.prototype.fnGetBcChainCount = function() {
  406 + var iChainCount = 0;
  407 + var aBcIndex = this.getMinBcObjPosition();
  408 +
  409 + var oBc;
  410 + var iQIndex;
  411 + var iBcIndex;
  412 + var i;
  413 + var bFlag;
  414 +
  415 + if (aBcIndex.length == 2) {
  416 + iChainCount = 1;
  417 + bFlag = true;
  418 +
  419 + // 下一个班次的索引
  420 + iQIndex = aBcIndex[1] == 0 ? aBcIndex[0] : aBcIndex[0] + 1;
  421 + iBcIndex = aBcIndex[1] == 0 ? 1 : 0;
  422 +
  423 + for (i = iQIndex; i < this._$_qCount; i++) {
  424 + while (iBcIndex <= 1) {
  425 + oBc = this.getBc(i, iBcIndex);
  426 + if (!oBc) {
  427 + bFlag = false;
  428 + } else {
  429 + if (bFlag) {
  430 +
  431 + } else {
  432 + iChainCount ++;
  433 + bFlag = true;
  434 + }
  435 + }
  436 +
  437 +
  438 + iBcIndex ++;
  439 + }
  440 + iBcIndex = 0;
  441 + }
  442 +
  443 + }
  444 +
  445 +
  446 + return iChainCount;
  447 +};
  448 +
  449 +/**
  450 + * 在具体位置移除班次。
  451 + * @param qIndex 第几圈
  452 + * @param bcIndex 第几个班次
  453 + */
  454 +InternalLpObj.prototype.removeBc = function(qIndex, bcIndex) {
  455 + var group = this._$_groupBcArray[qIndex];
  456 + if (bcIndex == 0) {
  457 + group.removeBc1();
  458 + } else if (bcIndex == 1) {
  459 + group.removeBc2();
  460 + }
  461 +};
  462 +
  463 +/**
  464 + * 使用指定时间匹配返回离之最近的第几圈第几个班次,
  465 + * 使用时间差的绝度值,比较,取最小的
  466 + * 如果有两个一样的时间差,取比fctime大的时间
  467 + * @param fctime moment 比较用时间
  468 + * @param groupArray 圈数组
  469 + * @param hasUp boolean 计算上行班次
  470 + * @param hasDown boolean 计算下行班次
  471 + * @returns [{第几圈},{第几个班次}]
  472 + */
  473 +InternalLpObj.prototype.fnGetQBcIndexWithFcTimeFromGroupArray = function(
  474 + fctime, groupArray, hasUp, hasDown
  475 +) {
  476 + var i;
  477 + var timediff; // 时间差取绝对值
  478 + var qIndex;
  479 + var bcIndex;
  480 +
  481 + var group;
  482 + var bc1time;
  483 + var bc2time;
  484 +
  485 + var tempdiff;
  486 +
  487 + console.log("比较时间=" + fctime.format("HH:mm"));
  488 +
  489 + for (i = 0; i < this._$_qCount; i++) {
  490 + group = groupArray[i];
  491 + if (group) {
  492 + if (group.getBc1() && hasUp) {
  493 + bc1time = group.getBc1().getFcTimeObj();
  494 + console.log("bc1time=" + bc1time.format("HH:mm") + " tempdiff=" + tempdiff);
  495 + tempdiff = Math.abs(bc1time.diff(fctime));
  496 +
  497 + if (!timediff) {
  498 + timediff = Math.abs(tempdiff);
  499 + qIndex = i;
  500 + bcIndex = 0;
  501 + } else {
  502 + if (tempdiff < timediff) {
  503 + timediff = tempdiff;
  504 + qIndex = i;
  505 + bcIndex = 0;
  506 + } if (Math.abs(tempdiff) == timediff) {
  507 + if (bc1time.isAfter(fctime)) {
  508 + timediff = tempdiff;
  509 + qIndex = i;
  510 + bcIndex = 0;
  511 + }
  512 +
  513 + }
  514 + }
  515 + }
  516 +
  517 + if (group.getBc2() && hasDown) {
  518 + bc2time = group.getBc2().getFcTimeObj();
  519 + console.log("bc2time=" + bc2time.format("HH:mm") + " tempdiff=" + tempdiff);
  520 + tempdiff = Math.abs(bc2time.diff(fctime));
  521 +
  522 + if (!timediff) {
  523 + timediff = Math.abs(tempdiff);
  524 + qIndex = i;
  525 + bcIndex = 1;
  526 + } else {
  527 + if (tempdiff < timediff) {
  528 + timediff = tempdiff;
  529 + qIndex = i;
  530 + bcIndex = 1;
  531 + } if (Math.abs(tempdiff) == timediff) {
  532 + if (bc2time.isBefore(fctime)) {
  533 + timediff = tempdiff;
  534 + qIndex = i;
  535 + bcIndex = 1;
  536 + }
  537 +
  538 + }
  539 + }
  540 + }
  541 + }
  542 + }
  543 +
  544 + console.log("中标线对应数组索引=" + qIndex);
  545 +
  546 + var rst = [];
  547 + rst.push(qIndex);
  548 + rst.push(bcIndex);
  549 +
  550 + return rst;
  551 +};
  552 +
  553 +/**
  554 + * 使用指定时间匹配返回离之最近的第几圈第几个班次,
  555 + * 使用时间差的绝度值,比较,取最小的
  556 + * 如果有两个一样的时间差,取比fctime大的时间
  557 + * @param fctime moment 比较用时间
  558 + * @param hasUp boolean 计算上行班次
  559 + * @param hasDown boolean 计算下行班次
  560 + * @returns [{第几圈},{第几个班次}]
  561 + */
  562 +InternalLpObj.prototype.getQBcIndexWithFcTime = function(
  563 + fctime, hasUp, hasDown
  564 +) {
  565 + return this.fnGetQBcIndexWithFcTimeFromGroupArray(fctime, this._$_groupBcArray, hasUp, hasDown);
  566 +};
  567 +
  568 +//---------------------- 内部数据初始化方法(不同于构造函数)---------------------//
  569 +
  570 +/**
  571 + * 从指定开始时间到结束时间创建不间断班次(连班),并初始化路牌
  572 + * 注意,之前有班次会删除后再创建。
  573 + * @param startTime 开始时间
  574 + * @param endTime 结束时间
  575 + * @param isUp 第一个班次是上行还是下行
  576 + * @param fromQ 从第几圈开始加入
  577 + * @param paramObj 参数对象
  578 + * @param factory 工厂对象
  579 + */
  580 +InternalLpObj.prototype.initDataFromTimeToTime = function(
  581 + startTime,
  582 + endTime,
  583 + isUp,
  584 + fromQ,
  585 + paramObj,
  586 + factory) {
  587 +
  588 + var bcData = []; // 班次数组
  589 + var bcObj;
  590 + var kssj = startTime;
  591 + var fcno = 1; // 发车顺序号
  592 + var bcCount = 1; // 班次数
  593 + do {
  594 + bcObj = factory.createBcObj(
  595 + this, "normal", isUp, fcno, kssj, paramObj); // this就是所属路牌对象
  596 + bcData.push(bcObj);
  597 +
  598 + kssj = paramObj.addMinute(kssj, bcObj.getBcTime() + bcObj.getStopTime());
  599 + fcno ++;
  600 + bcCount ++;
  601 + isUp = !isUp;
  602 + } while(kssj.isBefore(endTime));
  603 + bcCount--;
  604 +
  605 + //console.log("last -1;" + bcData[bcCount -2].getFcTimeObj().format("HH:mm"));
  606 + //console.log("last;" + bcData[bcCount -1].getFcTimeObj().format("HH:mm"));
  607 + //console.log("endtime: " + endTime.format("HH:mm"));
  608 +
  609 + //if (bcCount > 0 && bcData[bcCount - 1].getArrTimeObj().isAfter(endTime)) {
  610 + // // 如果最后一个班次的到达时间超过结束时间,也要去除
  611 + // bcData.splice(bcCount - 1, 1);
  612 + //}
  613 +
  614 + this._initDataFromLbBcArray(bcData, fromQ);
  615 +
  616 +};
  617 +
  618 +/**
  619 + * 使用连班的班次数组初始化路牌(相应的圈会被覆盖)。
  620 + * @param bcArray 连班班次数组
  621 + * @param fromQ 从第几圈开始加入
  622 + */
  623 +InternalLpObj.prototype._initDataFromLbBcArray = function(
  624 + bcArray,
  625 + fromQ
  626 +) {
  627 + var _bc1Obj;
  628 + var _bc2Obj;
  629 + var _qObj;
  630 +
  631 + // 第一班次是上行还是下行
  632 + var isUp = bcArray[0].isUp();
  633 +
  634 + if (bcArray.length > 0 && fromQ < this._$_qCount) {
  635 + // 构造圈数
  636 + if (isUp != this._$_isUp) {
  637 + // 如果方向不一致,意味着第一个班次是半圈
  638 + // 加半圈,并加在bc2上
  639 + _bc2Obj = bcArray.slice(0, 1)[0];
  640 + _qObj = new InternalGroupObj(
  641 + this,
  642 + this._$_isUp,
  643 + undefined,
  644 + _bc2Obj
  645 + );
  646 + _bc2Obj.setGroup(_qObj);
  647 + this._$_groupBcArray[fromQ] = _qObj;
  648 +
  649 + bcArray.splice(0, 1);
  650 + fromQ ++;
  651 + }
  652 +
  653 + var qCount1 = Math.floor(bcArray.length / 2); // 需要添加多少圈
  654 + var qCount2 = bcArray.length % 2; // 最后是否有半圈
  655 +
  656 + while (fromQ < this._$_qCount) {
  657 + if (qCount1 > 0) {
  658 + _bc1Obj = bcArray.slice(0, 1)[0];
  659 + _bc2Obj = bcArray.slice(1, 2)[0];
  660 + _qObj = new InternalGroupObj(
  661 + this,
  662 + this._$_isUp,
  663 + _bc1Obj,
  664 + _bc2Obj
  665 + );
  666 + _bc1Obj.setGroup(_qObj);
  667 + _bc2Obj.setGroup(_qObj);
  668 + this._$_groupBcArray[fromQ] = _qObj;
  669 +
  670 + bcArray.splice(0, 2);
  671 + qCount1 --;
  672 + } else if (qCount2 > 0) {
  673 + // 加半圈,并加在bc1上
  674 + _bc1Obj = bcArray.slice(0, 1)[0];
  675 + _qObj = new InternalGroupObj(
  676 + this,
  677 + this._$_isUp,
  678 + _bc1Obj,
  679 + undefined
  680 + );
  681 + _bc1Obj.setGroup(_qObj);
  682 + this._$_groupBcArray[fromQ] = _qObj;
  683 +
  684 + bcArray.splice(0, 1);
  685 + qCount2 --;
  686 + } else {
  687 + break;
  688 + }
  689 +
  690 + fromQ ++;
  691 + }
  692 + }
  693 +};
  694 +
  695 +//-------------------------- 其他方法 ----------------------------//
  696 +
  697 +/**
  698 + * 从指定位置的班次开始,往后所有的班次修正发车时间
  699 + * @param groupIndex
  700 + * @param bcIndex
  701 + * @param time
  702 + */
  703 +InternalLpObj.prototype.fnAddMinuteToBcFcsj = function(groupIndex, bcIndex, time) {
  704 + var i;
  705 + var oCurBc;
  706 +
  707 + // 修正之前班次的停站时间
  708 + //oCurBc = this.getBc(
  709 + // bcIndex == 0 ? groupIndex - 1 : groupIndex,
  710 + // bcIndex == 1 ? 0 : 1
  711 + //);
  712 + //if (oCurBc) {
  713 + // oCurBc.setStopTime(oCurBc.getStopTime() + time);
  714 + //}
  715 +
  716 +
  717 + for (i = groupIndex; i < this._$_qCount; i++) {
  718 + if (bcIndex == 0) {
  719 + oCurBc = this.getBc(i, 0);
  720 + if (oCurBc) {
  721 + oCurBc.addMinuteToFcsj(time);
  722 + }
  723 + oCurBc = this.getBc(i, 1);
  724 + if (oCurBc) {
  725 + oCurBc.addMinuteToFcsj(time);
  726 + }
  727 +
  728 + } else {
  729 + oCurBc = this.getBc(i, 1);
  730 + if (oCurBc) {
  731 + oCurBc.addMinuteToFcsj(time);
  732 + }
  733 +
  734 + }
  735 +
  736 + bcIndex = 0;
  737 + }
  738 +};
  739 +
  740 +/**
  741 + * 在指定位置添加一个吃饭班次。
  742 + * 注1:吃饭班次不是普通班次,不记录进圈,记录进_$_other_bc_array
  743 + * 注2:添加吃饭班次时,会修改之前班次的停战时间,所以导致之后的班次的停战都会发生变化
  744 + * @param groupIndex
  745 + * @param bcIndex
  746 + * @param factory
  747 + * @param paramObj
  748 + * @returns int 相差时间(吃饭时间距离和停站时间相差值)
  749 + */
  750 +InternalLpObj.prototype.fnAddEatBc = function(groupIndex, bcIndex, factory, paramObj) {
  751 + var oPreBc;
  752 + var oEatBc;
  753 + var iBcModifyTime;
  754 + oPreBc = this.getBc( // 前一个邻接班次
  755 + bcIndex == 0 ? groupIndex - 1 : groupIndex,
  756 + bcIndex == 1 ? 0 : 1);
  757 + if (oPreBc) { // 存在前一个班次
  758 + oEatBc = factory.createBcObj(
  759 + this,
  760 + "cf",
  761 + !oPreBc.isUp(), // 和上一个班次方向相反
  762 + 1,
  763 + paramObj.addMinute(oPreBc.getArrTimeObj(), oPreBc.getStopTime()), // 使用上一个班次的到达时间作为开始时间
  764 + paramObj
  765 + );
  766 +
  767 + //iBcModifyTime = oEatBc.getBcTime() - oPreBc.getStopTime(); // 后续班次要调整的时间
  768 +
  769 + // 修正之后的班次发车时间
  770 + // 注意:之后那个班次发车时间就是吃饭班次的到达时间
  771 + iBcModifyTime = oEatBc.getArrTimeObj().diff(this.getBc(groupIndex, bcIndex).getFcTimeObj(), "m");
  772 + this.fnAddMinuteToBcFcsj(groupIndex, bcIndex, iBcModifyTime);
  773 +
  774 + oPreBc.setStopTime(0); // 不重置停站时间
  775 + oPreBc.fnSetEatTime(oEatBc.getBcTime());
  776 +
  777 + //this._$_other_bc_array.push(oEatBc);
  778 +
  779 + return iBcModifyTime;
  780 + } else {
  781 + return false;
  782 + }
  783 +
  784 +};
  785 +
  786 +/**
  787 + * 调整路牌的班次,通过调整停站时间,或者班次发车时间,不能让班次的到达时间和下一个班次的发车时间重叠。
  788 + * @param iPeakAverStopTime 高峰平均停站时间
  789 + * @param iTroughAverStopTime 低谷平均停站时间
  790 + * @param oParam 参数对象
  791 + */
  792 +InternalLpObj.prototype.fnAdjustBcInterval = function(iPeakAverStopTime, iTroughAverStopTime, oParam) {
  793 + // 获取车次链个数
  794 + var iBcChainCount = this.fnGetBcChainCount();
  795 +
  796 + var i;
  797 + var j;
  798 + var oBcIndex;
  799 + var iQIndex;
  800 + var iBcIndex;
  801 + var iBcCount;
  802 + var oBc;
  803 + var oNextBc;
  804 +
  805 + var iBcStopTime;
  806 +
  807 + for (i = 0; i < iBcChainCount; i++) {
  808 + oBcIndex = this.fnGetBcChainInfo(i);
  809 + iQIndex = oBcIndex["s_q"];
  810 + iBcIndex = oBcIndex["s_b"];
  811 + iBcCount = oBcIndex["bcount"];
  812 +
  813 + for (j = 0; j < iBcCount - 1; j++) {
  814 + oBc = this.getBc(iQIndex, iBcIndex);
  815 + oNextBc = this.getBc(
  816 + iBcIndex == 0 ? iQIndex : iQIndex + 1,
  817 + iBcIndex == 0 ? 1 : 0);
  818 +
  819 + if (oNextBc.fnIsFirstBc()) { // 如果同一路牌连续2个方向首站班次,都不做处理
  820 + continue;
  821 + }
  822 +
  823 + // 不改变当前班次的行驶时间,修正停站时间和下一个班次的发车时间
  824 + iBcStopTime = oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m");
  825 + if (iBcStopTime < 0) {
  826 + // 当前班次使用最小停站时间
  827 + oBc.setStopTime(oParam.fnCalcuFixedMinStopNumber(oBc.getArrTimeObj(), oBc.isUp()));
  828 + oNextBc.addMinuteToFcsj(oBc.getStopTime() + oBc.fnGetEatTime() - iBcStopTime);
  829 +
  830 + } else {
  831 + if (iBcStopTime == oBc.getStopTime() + oBc.fnGetEatTime()) {
  832 + // 停站时间一致,没有问题
  833 +
  834 +
  835 + } else {
  836 + // TODO:当前班次使用最小停站时间
  837 + oBc.setStopTime(oParam.fnCalcuFixedMinStopNumber(oBc.getArrTimeObj(), oBc.isUp()));
  838 + oNextBc.addMinuteToFcsj(oBc.getStopTime() + oBc.fnGetEatTime() - iBcStopTime);
  839 +
  840 + }
  841 + }
  842 +
  843 + iBcIndex = iBcIndex == 0 ? 1 : 0;
  844 + iQIndex = iBcIndex == 0 ? iQIndex + 1 : iQIndex;
  845 + }
  846 +
  847 + this.getBc(iQIndex, iBcIndex).setStopTime(0);
  848 + }
  849 +
  850 +
  851 +};
  852 +
  853 +
  854 +// TODO
  855 +
  856 +/**
  857 + *
  858 + *
  859 + */
  860 +InternalLpObj.prototype.calcuLpBx = function() {
  861 +
  862 +};
  863 +
  864 +
src/main/resources/static/pages/base/timesmodel/js/v2/core/InternalScheduleObj.js
1 -/**  
2 - * 内部行车计划对象。  
3 - * @constructor  
4 - */  
5 -var InternalScheduleObj = function(paramObj, lpArray, factory) {  
6 - // 参数对象  
7 - var _paramObj = paramObj;  
8 - // 外部的路牌数组  
9 - var _lpArray = lpArray;  
10 - // 工厂对象  
11 - var _factory = factory;  
12 -  
13 - //------------------ 初始化方法1,以及计算关联的内部变量 -----------------//  
14 - var _qIsUp; // 每一圈是上行开始还是下行开始  
15 - var _qCount = 0; // 总的圈数  
16 - var _internalLpArray = []; // 内部对象数组  
17 - var _aBxDesc = [ // 各种班型描述(班型名称,平均工时,平均需要的班次数,平均工时)  
18 - {'sType':'六工一休', 'fHoursV':6.66, 'fBcCount': 0, 'fAverTime': 0},  
19 - {'sType':'五工一休', 'fHoursV':6.85, 'fBcCount': 0, 'fAverTime': 0},  
20 - {'sType':'四工一休', 'fHoursV':7.14, 'fBcCount': 0, 'fAverTime': 0},  
21 - {'sType':'三工一休', 'fHoursV':7.61, 'fBcCount': 0, 'fAverTime': 0},  
22 - {'sType':'二工一休', 'fHoursV':8.57, 'fBcCount': 0, 'fAverTime': 0},  
23 - {'sType':'一工一休', 'fHoursV':11.42, 'fBcCount': 0, 'fAverTime': 0},  
24 - {'sType':'五工二休', 'fHoursV':7.99, 'fBcCount': 0, 'fAverTime': 0},  
25 - {'sType':'无工休', 'fHoursV':5.43, 'fBcCount': 0, 'fAverTime': 0}  
26 - ];  
27 -  
28 - var _fnInitFun1 = function() { // 初始化方法1  
29 - console.log("//---------------- 行车计划,初始化方法1 start ----------------//");  
30 -  
31 - //----------------------- 1、确定上标线的方向,圈的方向 -------------------//  
32 -  
33 - // 确定_qIsUp,哪个方向的首班车晚就用哪个  
34 - _qIsUp = _paramObj.getUpFirstDTimeObj().isBefore(  
35 - _paramObj.getDownFirstDTimeObj()) ? false : true;  
36 - // 上标线开始时间,就是方向的首班车时间  
37 - var st = _qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();  
38 - // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向  
39 - var et;  
40 - var et_IsUp;  
41 - if (_paramObj.getUpLastDtimeObj().isBefore(  
42 - _paramObj.getDownLastDTimeObj())) {  
43 - et = _paramObj.getDownLastDTimeObj();  
44 - et_IsUp = false;  
45 - } else {  
46 - et = _paramObj.getUpLastDtimeObj();  
47 - et_IsUp = true;  
48 - }  
49 -  
50 - //------------------------ 2、计算总共有多少圈 ------------------------//  
51 -  
52 - // 以开始时间,结束时间,构造上标线用连班班次发车时间  
53 - var bcFcsjArrays = []; // 班次发车时间对象数组  
54 - var bcArsjArrays = []; // 班次到达时间对象数组  
55 - var isUp = _qIsUp; // 方向  
56 - var bcCount = 1; // 班次数  
57 -  
58 - var _kssj = st; // 开始时间  
59 - var _bcsj = paramObj.calcuTravelTime(_kssj, isUp); // 班次历时  
60 - var _arrsj = paramObj.addMinute(_kssj, _bcsj); // 到达时间  
61 - var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, _bcsj); // 停站时间  
62 -  
63 - do {  
64 - bcFcsjArrays.push(_kssj);  
65 - bcArsjArrays.push(_arrsj);  
66 -  
67 - _kssj = paramObj.addMinute(_kssj, _bcsj + _stoptime);  
68 - _bcsj = paramObj.calcuTravelTime(_kssj, isUp);  
69 - _arrsj = paramObj.addMinute(_kssj, _bcsj);  
70 - _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, _bcsj);  
71 -  
72 - bcCount ++;  
73 - isUp = !isUp;  
74 - } while(_kssj.isBefore(et));  
75 - bcCount--; // 因为先做do,所以总的班次要减1  
76 - //if (bcCount > 0 && bcArsjArrays[bcCount - 1].isAfter(et)) {  
77 - // // 如果最后一个班次的到达时间超过结束时间,也要去除  
78 - // bcFcsjArrays.splice(bcCount - 1, 1);  
79 - // bcArsjArrays.splice(bcCount - 1, 1);  
80 - // bcCount--;  
81 - //}  
82 - var _qCount_p1 = Math.floor(bcCount / 2); // 2个班次一圈  
83 - var _qCount_p2 = bcCount % 2; // 余下的1个班次也算一圈  
84 -  
85 - // 利用连班数组计算圈数  
86 - _qCount = 1; // 前面加1圈,补中标线的班次  
87 - _qCount += _qCount_p1;  
88 - _qCount += _qCount_p2;  
89 -  
90 - // 计算最后是不是还要补一圈  
91 - if (_qCount > 1) { // 总的圈数就1圈,没必要加了(其实是不可能的,除非参数里问题)  
92 - if (_qCount_p2 == 0) { // 没有余下班次,整数圈数  
93 - // 最后一个班次的方向一定和开始的方向相反,如:上-下,上-下,上-下,一共三圈,最后一个班次为下行  
94 - // 判定最后一个班次的方向和上标线判定结束时间的班次方向是否一致  
95 - if (!_qIsUp == et_IsUp) {  
96 - // 一致不用加圈数  
97 - } else {  
98 - // 不一致需要加圈补最后一个结束时间班次  
99 - _qCount ++;  
100 - }  
101 - } else {  
102 - // 有余下的圈数,最后要不补的班次不管上行,下行都在这一圈里  
103 - // 不需要在补圈数了  
104 - }  
105 - }  
106 -  
107 - //------------------------ 3、根据路牌数,圈数创建路牌对象 ----------------------//  
108 -  
109 - // 创建内部的路牌数组,并把之前的连班路牌添加进上标线路牌中  
110 - var i;  
111 - for (i = 0; i < _lpArray.length; i++) {  
112 - _internalLpArray.push(new InternalLpObj(_lpArray[i], _qCount, _qIsUp));  
113 - }  
114 - // 初始化上标线,从第1圈开始  
115 - _internalLpArray[0].initDataFromTimeToTime(bcFcsjArrays[0], et, _qIsUp, 1, _paramObj, _factory);  
116 -  
117 - // 以上标线为基础,计算各种班型工时对应的圈数、班次数  
118 - var aBcArray = _internalLpArray[0].getBcArray();  
119 - aBcArray[0].fnSetIsFirstBc(true); // 设置首班班次标识  
120 -  
121 - if (aBcArray.length % 2 != 0) { // 不能整除2,去除一个班次计算  
122 - aBcArray.splice(aBcArray.length - 1, 1);  
123 - }  
124 -  
125 - // 午饭吃饭时间  
126 - var iLTime = _paramObj.fnGetLunchTime();  
127 - // 晚饭吃饭时间  
128 - var iDTime = _paramObj.fnGetDinnerTime();  
129 - // 出场时间  
130 - var iOutTime = _qIsUp ? _paramObj.getUpOutTime() : _paramObj.getDownOutTime();  
131 - // 进场时间  
132 - var iInTime = _qIsUp ? _paramObj.getDownInTime() : _paramObj.getUpInTime();  
133 - // 例保时间  
134 - var iBTime = _paramObj.getLbTime();  
135 -  
136 - var sum = 0; // 总班次时间  
137 - for (i = 0; i < aBcArray.length; i++) {  
138 - sum += aBcArray[i].getBcTime() + aBcArray[i].getStopTime();  
139 - }  
140 - sum += iLTime; // 加午饭时间  
141 - sum += iDTime; // 加晚饭时间  
142 - for (i = 0; i < _aBxDesc.length; i++) {  
143 - _aBxDesc[i].fAverTime = sum / (aBcArray.length / 2); // 平均周转时间不算进出场,例保时间  
144 -  
145 - // 计算5休2的班次数(双进出场,4个例保)  
146 - if (i == 6) {  
147 - _aBxDesc[i].fQCount =  
148 - (_aBxDesc[i].fHoursV * 60 - iOutTime * 2 - iInTime * 2 - iBTime * 4) /  
149 - _aBxDesc[i].fAverTime;  
150 - _aBxDesc[i].fBcCount = _aBxDesc[i].fQCount * 2;  
151 - } else { // 进出场,2个例保  
152 - _aBxDesc[i].fQCount =  
153 - (_aBxDesc[i].fHoursV * 60 - iOutTime - iInTime - iBTime * 2) /  
154 - _aBxDesc[i].fAverTime;  
155 - _aBxDesc[i].fBcCount = _aBxDesc[i].fQCount * 2;  
156 - }  
157 - }  
158 -  
159 -  
160 - // 在第一个班次之前再添加一个模拟班次,用于中标线的作用  
161 - // 那一圈必定是低谷,而且圈索引0,班次索引1,暂时标记,最后删除  
162 - var iFirstStopTime =  
163 - _paramObj.fnCalcuFixedStopNumber(  
164 - _paramObj.addMinute(aBcArray[0].getFcTimeObj(), -10),  
165 - _qIsUp  
166 - );  
167 - var iXXTime = _qIsUp ? _paramObj.getDownTroughTime() : _paramObj.getUpTroughTime();  
168 - var oFlagBc = _factory.createBcObj( // 标记班次  
169 - _internalLpArray[0],  
170 - "normal",  
171 - !_qIsUp,  
172 - 1,  
173 - _paramObj.addMinute(aBcArray[0].getFcTimeObj(), -(iFirstStopTime + iXXTime)),  
174 - _paramObj  
175 - );  
176 - oFlagBc.fnSetDelFlag(true); // 标记了删除记号  
177 -  
178 - _internalLpArray[0].setBc(0, 1, oFlagBc);  
179 -  
180 - // 在最后一圈也补上一个或者2个模拟班次,暂时标记,最后需要删除  
181 - var aMaxBcIndex = _internalLpArray[0].getMaxBcObjPosition();  
182 - if (aMaxBcIndex[0] == _qCount - 1) { // 可能加半圈  
183 - oFlagBc = _factory.createBcObj( // 标记班次  
184 - _internalLpArray[0],  
185 - "normal",  
186 - !_qIsUp,  
187 - 1,  
188 - _paramObj.addMinute(  
189 - _internalLpArray[0].getBc(_qCount - 1, 0).getArrTimeObj(),  
190 - _internalLpArray[0].getBc(_qCount - 1, 0).getStopTime()),  
191 - _paramObj  
192 - );  
193 - oFlagBc.fnSetDelFlag(true); // 标记了删除记号  
194 - _internalLpArray[0].setBc(_qCount - 1, 1, oFlagBc);  
195 -  
196 - } else { // 加完整的一圈  
197 - oFlagBc = _factory.createBcObj( // 标记班次  
198 - _internalLpArray[0],  
199 - "normal",  
200 - _qIsUp,  
201 - 1,  
202 - _paramObj.addMinute(  
203 - _internalLpArray[0].getBc(_qCount - 2, 1).getArrTimeObj(),  
204 - _internalLpArray[0].getBc(_qCount - 2, 1).getStopTime()),  
205 - _paramObj  
206 - );  
207 - oFlagBc.fnSetDelFlag(true); // 标记了删除记号  
208 - _internalLpArray[0].setBc(_qCount - 1, 0, oFlagBc);  
209 -  
210 - oFlagBc = _factory.createBcObj( // 标记班次  
211 - _internalLpArray[0],  
212 - "normal",  
213 - !_qIsUp,  
214 - 1,  
215 - _paramObj.addMinute(  
216 - _internalLpArray[0].getBc(_qCount - 1, 0).getArrTimeObj(),  
217 - _internalLpArray[0].getBc(_qCount - 1, 0).getStopTime()),  
218 - _paramObj  
219 - );  
220 - oFlagBc.fnSetDelFlag(true); // 标记了删除记号  
221 - _internalLpArray[0].setBc(_qCount - 1, 1, oFlagBc);  
222 -  
223 - }  
224 -  
225 - console.log("上行首班车时间:" + _paramObj.getUpFirstDTimeObj().format("HH:mm") +  
226 - "上行末班车时间:" + _paramObj.getUpLastDtimeObj().format("HH:mm"));  
227 - console.log("下行首班车时间:" + _paramObj.getDownFirstDTimeObj().format("HH:mm") +  
228 - "下行末班车时间:" + _paramObj.getDownLastDTimeObj().format("HH:mm"));  
229 - console.log("总共计算的圈数:" + _qCount);  
230 - console.log("圈的方向isUP:" + _qIsUp);  
231 - console.log("班型描述(以下):");  
232 - console.log(_aBxDesc);  
233 - console.log("所有路牌间隔描述(以下):");  
234 - for (i = 0; i < _internalLpArray.length; i++) {  
235 - console.log(_internalLpArray[i]._$_aVerticalIntervalTime);  
236 - }  
237 - console.log("//---------------- 行车计划,初始化方法1 end ----------------//");  
238 -  
239 - };  
240 -  
241 - //------------------ 初始化方法2,以及计算关联的内部变量 ----------------//  
242 - var _approximate_zgfQIndex; // 预估早高峰车辆从第几圈开始全部发出  
243 - var _approximate_zgfBIndex; // 预估早高峰车辆从第几圈第几个班次开始全部发出(上行或下行)  
244 - var _approximate_wgfQIndex; // 预估晚高峰车辆从第几圈开始全部发出  
245 - var _approximate_wgfBIndex; // 预估晚高峰车辆从第几圈第几个班次开始全部发出(上行或下行)  
246 -  
247 - var _fnInitFun2 = function() { // 初始化方法2  
248 - console.log("//---------------- 行车计划,初始化方法2 start ----------------//");  
249 -  
250 - //------------------------ 1、计算车辆总数 ------------------------//  
251 - // 是用高峰上行周转时间除以高峰平均间隔得到的  
252 - // 这样算还算合理,车辆不多不少,待以后有新的算法再修正  
253 - var iClCount = _paramObj.calcuClzx();  
254 -  
255 - //------------------------ 2、计算所有路牌的发车在各个圈中的间隔 --------------------//  
256 - var i;  
257 - var j;  
258 - var iBindex = 1;  
259 - var iZzsj;  
260 - var oLp;  
261 - var iC1;  
262 - var iC2;  
263 -  
264 - for (i = 0; i < _qCount - 1; i++) {  
265 - while (iBindex <= 1) {  
266 - // 每圈每个方向的周转时间不一致,以上标线为主  
267 - oLp = _internalLpArray[0];  
268 - iZzsj = oLp.getBc(i + 1, iBindex).getFcTimeObj().diff(  
269 - oLp.getBc(i, iBindex).getFcTimeObj(), "m"  
270 - );  
271 -  
272 - iC1 = Math.floor(iZzsj / iClCount);  
273 - iC2 = iZzsj % iClCount;  
274 -  
275 - for (j = 0; j < iClCount - iC2; j++) {  
276 - oLp = _internalLpArray[j];  
277 - oLp.fnSetVerticalIntervalTime(i, iBindex, iC1);  
278 - }  
279 -  
280 - for (j = 0; j < iC2; j++) {  
281 - oLp = _internalLpArray[iClCount - iC2 + j];  
282 - oLp.fnSetVerticalIntervalTime(i, iBindex, iC1 + 1);  
283 - }  
284 -  
285 - iBindex ++;  
286 -  
287 - }  
288 - iBindex = 0;  
289 - }  
290 - // 最后一圈没有下一圈的参照,周转时间没发获取,由于都是低谷,所以使用倒数第二圈的间隔最为最后一圈的间隔  
291 - for (i = 0; i < _internalLpArray.length; i++) {  
292 - oLp = _internalLpArray[i];  
293 - oLp.fnSetVerticalIntervalTime(_qCount - 1, 0, oLp.fnGetVerticalIntervalTime(_qCount - 2, 0));  
294 - oLp.fnSetVerticalIntervalTime(_qCount - 1, 1, oLp.fnGetVerticalIntervalTime(_qCount - 2, 1));  
295 - }  
296 -  
297 - //------------------------ 3、预估早高峰全部出车第几圈第几个班次全部出车,计算路牌之间的发车间隔 ------------------//  
298 -  
299 - // 以上标线为标准,查找离早高峰开始时间最近的班次作为早高峰开始班次  
300 - // 以这个班次为早高峰起点,全部出车策略  
301 - var qbcIndexArray = _internalLpArray[0].getQBcIndexWithFcTime(  
302 - _paramObj.getMPeakStartTimeObj(), true, true);  
303 - var qIndex = qbcIndexArray[0]; // 第几圈  
304 - var bIndex = qbcIndexArray[1]; // 第几个班次  
305 -  
306 - for (i = 1; i < _internalLpArray.length; i++) {  
307 - _fnGenerateBcAndSetBc(i, qIndex, bIndex);  
308 - }  
309 -  
310 - _approximate_zgfQIndex = qIndex;  
311 - _approximate_zgfBIndex = bIndex;  
312 -  
313 - //------------------------ 4、预估晚高峰全部出车第几圈第几个班次全部出车,计算路牌之间的发车间隔 ------------------//  
314 -  
315 - // 以上标线为标准,查找离晚高峰开始时间最近的班次作为晚高峰开始班次  
316 - // 以这个班次为早高峰起点,全部出车策略  
317 - qbcIndexArray = _internalLpArray[0].getQBcIndexWithFcTime(  
318 - _paramObj.getEPeakStartTimeObj(), true, true);  
319 - qIndex = qbcIndexArray[0]; // 第几圈  
320 - bIndex = qbcIndexArray[1]; // 第几个班次  
321 -  
322 - for (i = 1; i < _internalLpArray.length; i++) {  
323 - _fnGenerateBcAndSetBc(i, qIndex, bIndex);  
324 - }  
325 -  
326 - _approximate_wgfQIndex = qIndex;  
327 - _approximate_wgfBIndex = bIndex;  
328 -  
329 - console.log("早高峰周转时间(固定最大停战时间):" + _paramObj.calcuPeakZzsj() + "分钟");  
330 - console.log("早高峰发车时间范围:" + _paramObj.getMPeakMinFcjx() + "分钟 --- " + _paramObj.getMPeakMaxFcjx() + "分钟");  
331 - console.log("预估早高峰第" + _approximate_zgfQIndex + "(index)圈,第" + _approximate_zgfBIndex + "(index)班次车辆全部发出");  
332 - console.log("预估晚高峰第" + _approximate_wgfQIndex + "(index)圈,第" + _approximate_wgfBIndex + "(index)班次车辆全部发出");  
333 - console.log("//---------------- 行车计划,初始化方法2 end ----------------//");  
334 - };  
335 -  
336 - //----------------------- 初始化方法3,计算连班分班的路牌分布 ----------------//  
337 - var _iBx_lb_lpcount; // 连班路牌数  
338 - var _iBx_5_2_fb_lpcount; // 5休2分班路牌数  
339 - var _iBx_other_fb_lpcount; // 其他分班路牌数  
340 -  
341 - var _fnInitFun3 = function() { // 初始化方法3  
342 - console.log("//---------------- 行车计划,初始化方法3 start ----------------//");  
343 -  
344 - //--------------------- 1、计算分班连班班型车辆分布数 --------------------//  
345 - // 总共车辆数(高峰最大车辆数)  
346 - var iCls = _paramObj.calcuClzx();  
347 - // 低谷最少配车(连班车数量)  
348 - var iDgminpc = Math.round(_paramObj.calcuTroughZzsj() / _paramObj.getTroughMaxFcjx());  
349 - // 加班车路牌数(做5休2的路牌数)  
350 - var i_5_2_lpes = _paramObj.getJBLpes();  
351 -  
352 - // 做些简单的验证  
353 - if (iCls < iDgminpc) {  
354 - alert("总配车数小于低谷最小配车");  
355 - throw "总配车数小于低谷最小配车";  
356 - }  
357 - if (iDgminpc < 2) {  
358 - alert("连班路牌小于2,办不到啊");  
359 - throw "连班路牌小于2,办不到啊";  
360 - }  
361 - if (iCls - iDgminpc < i_5_2_lpes) {  
362 - alert("总分班路牌数小于加班路牌数");  
363 - throw "总分班路牌数小于加班路牌数";  
364 - }  
365 -  
366 - //// 修正连班路牌数,班次间隔大于20的,加1,直至班次间隔小于20  
367 - //while(_paramObj.calcuPeakZzsj() / iDgminpc > 20) {  
368 - // iDgminpc ++;  
369 - //}  
370 - _iBx_lb_lpcount = iDgminpc;  
371 -  
372 - _iBx_5_2_fb_lpcount = i_5_2_lpes;  
373 - _iBx_other_fb_lpcount = iCls - _iBx_lb_lpcount - i_5_2_lpes;  
374 -  
375 - //------------------------ 2、利用间隔法计算连班路牌分布 --------------------//  
376 - var i;  
377 - var j;  
378 - var iC1 = Math.floor(_internalLpArray.length / _iBx_lb_lpcount);  
379 - var iC2 = _internalLpArray.length % _iBx_lb_lpcount;  
380 - var iLpIndex;  
381 -  
382 - for (i = 0; i < _iBx_lb_lpcount - iC2; i++) {  
383 - iLpIndex = i * iC1;  
384 - _internalLpArray[iLpIndex].setBxLb(true);  
385 - _internalLpArray[iLpIndex].setBxDesc("连班");  
386 - }  
387 - for (j = 0; j < iC2; j++) {  
388 - iLpIndex = i * iC1 + j * (iC1 + 1);  
389 - _internalLpArray[iLpIndex].setBxLb(true);  
390 - _internalLpArray[iLpIndex].setBxDesc("连班");  
391 - }  
392 -  
393 - //------------------------ 3、利用间隔法计算分班班型路牌分布 --------------------//  
394 - // 获取分班路牌索引  
395 - var aNotLbIndexes = [];  
396 - for (i = 0; i < _internalLpArray.length; i++) {  
397 - if (!_internalLpArray[i].isBxLb()) {  
398 - aNotLbIndexes.push(i);  
399 - }  
400 - }  
401 - // 先5休2分班  
402 - iC1 = Math.floor(aNotLbIndexes.length / _iBx_5_2_fb_lpcount);  
403 - iC2 = aNotLbIndexes.length % _iBx_5_2_fb_lpcount;  
404 -  
405 - for (i = 0; i < _iBx_5_2_fb_lpcount - iC2; i++) {  
406 - iLpIndex = aNotLbIndexes[i * iC1];  
407 - _internalLpArray[iLpIndex].setBxLb(false);  
408 - _internalLpArray[iLpIndex].setBxFb(true);  
409 - _internalLpArray[iLpIndex].setBxFb5_2(true);  
410 - _internalLpArray[iLpIndex].setBxDesc("5休2分班");  
411 - }  
412 - for (i = 0; i < iC2; i++) {  
413 - iLpIndex = aNotLbIndexes[_iBx_5_2_fb_lpcount - iC2 + i * (iC1 + 1)];  
414 - _internalLpArray[iLpIndex].setBxLb(false);  
415 - _internalLpArray[iLpIndex].setBxFb(true);  
416 - _internalLpArray[iLpIndex].setBxFb5_2(true);  
417 - _internalLpArray[iLpIndex].setBxDesc("5休2分班");  
418 - }  
419 - // 其他分班  
420 - for (i = 0; i < aNotLbIndexes.length; i++) {  
421 - iLpIndex = aNotLbIndexes[i];  
422 - if (!_internalLpArray[iLpIndex].isBxFb5_2()) {  
423 - _internalLpArray[iLpIndex].setBxLb(false);  
424 - _internalLpArray[iLpIndex].setBxFb(true);  
425 - _internalLpArray[iLpIndex].setBxFb5_2(false);  
426 - _internalLpArray[iLpIndex].setBxDesc("其他分班");  
427 - }  
428 - }  
429 -  
430 - console.log("高峰周转时间:" + _paramObj.calcuPeakZzsj());  
431 - console.log("连班路牌数:" + _iBx_lb_lpcount);  
432 - console.log("5休2分班路牌数:" + _iBx_5_2_fb_lpcount);  
433 - console.log("其他分班路牌数:" + _iBx_other_fb_lpcount);  
434 - var aLbIndexes = [];  
435 - for (i = 0; i < _internalLpArray.length; i++) {  
436 - if (_internalLpArray[i].isBxLb()) {  
437 - aLbIndexes.push(i);  
438 - }  
439 - }  
440 - console.log("连班路牌indexes=" + aLbIndexes);  
441 - var a_5_2_fbIndexes = [];  
442 - for (i = 0; i < _internalLpArray.length; i++) {  
443 - if (_internalLpArray[i].isBxFb() && _internalLpArray[i].isBxFb5_2()) {  
444 - a_5_2_fbIndexes.push(i);  
445 - }  
446 - }  
447 - console.log("5休2分班路牌indexes=" + a_5_2_fbIndexes);  
448 - var a_other_fbIndexes = [];  
449 - for (i = 0; i < _internalLpArray.length; i++) {  
450 - if (_internalLpArray[i].isBxFb() && !_internalLpArray[i].isBxFb5_2()) {  
451 - a_other_fbIndexes.push(i);  
452 - }  
453 - }  
454 - console.log("其他分班路牌indexes=" + a_other_fbIndexes);  
455 -  
456 - console.log("//---------------- 行车计划,初始化方法3 end ----------------//");  
457 - };  
458 -  
459 - //----------------------- 初始化方法4,计算中标线位置 -------------------------//  
460 - var _iZbx_lpIndex; // 中标线对应第几个路牌  
461 -  
462 - var _fnInitFun4 = function() { // 初始化方法4  
463 - console.log("//---------------- 行车计划,初始化方法4 start ----------------//");  
464 -  
465 - //---------------------------- 1、模拟一个中标线,使用临时路牌 ----------------------//  
466 - // 构造中标线  
467 - // 中标线开始时间,就是方向的首班车时间  
468 - var oSt = !_qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();  
469 - // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向  
470 - // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向  
471 - var oEt;  
472 - if (_paramObj.getUpLastDtimeObj().isBefore(  
473 - _paramObj.getDownLastDTimeObj())) {  
474 - oEt = _paramObj.getDownLastDTimeObj();  
475 - } else {  
476 - oEt = _paramObj.getUpLastDtimeObj();  
477 - }  
478 -  
479 - var oTempLp = new InternalLpObj({lpNo: -999, lpName: "-999"}, _qCount, _qIsUp);  
480 - oTempLp.initDataFromTimeToTime(  
481 - oSt,  
482 - oEt,  
483 - !_qIsUp,  
484 - 0,  
485 - _paramObj,  
486 - _factory  
487 - );  
488 -  
489 - //------------------------ 2、找出中标线的早高峰班次,计算应该插在当前路牌数组的那个位置 ----------------//  
490 - // 找出中标线对应的早高峰的班次对象  
491 - var oZb_gf_bc = oTempLp.getBc(_approximate_zgfQIndex, _approximate_zgfBIndex);  
492 - //alert(oZb_gf_bc.getFcTimeObj().format("HH:mm"));  
493 -  
494 - // 把所有连班路牌高峰班次重新构造成一个一个的圈数组,计算对应中标线最近的是第几个路牌  
495 - // 中标线和上标线一样在连班路牌上  
496 - var aTempq = [];  
497 - var oTempq;  
498 - var oTempb;  
499 - var i;  
500 - var oLp;  
501 -  
502 - var aLbIndexes = []; // 连班的路牌索引  
503 - for (i = 0; i < _internalLpArray.length; i++) {  
504 - if (_internalLpArray[i].isBxLb()) {  
505 - aLbIndexes.push(i);  
506 - }  
507 - }  
508 -  
509 - for (i = 0; i < aLbIndexes.length; i++) {  
510 - oLp = _internalLpArray[aLbIndexes[i]];  
511 -  
512 - oTempb = oLp.getBc(_approximate_zgfQIndex, _approximate_zgfBIndex);  
513 - if (oTempb.isUp() == _qIsUp) {  
514 - oTempq = new InternalGroupObj(oLp, _qIsUp, oTempb, undefined);  
515 - } else {  
516 - oTempq = new InternalGroupObj(oLp, _qIsUp, undefined, oTempb);  
517 - }  
518 - aTempq.push(oTempq);  
519 -  
520 - }  
521 -  
522 - var aTtindex = oTempLp.fnGetQBcIndexWithFcTimeFromGroupArray( // 找出最接近中标线的路牌索引  
523 - oZb_gf_bc.getFcTimeObj(),  
524 - aTempq,  
525 - true,  
526 - true  
527 - );  
528 -  
529 - _iZbx_lpIndex = aLbIndexes[aTtindex[0]]; // 中标线放在第几个路牌  
530 -  
531 - oTempLp.getMinBcObj().fnSetIsFirstBc(true); // 设置首班班次标识  
532 -  
533 - if (_iZbx_lpIndex == 0) { // 如果中标线和上标线一致  
534 - var oFirstBcIndexes = oTempLp.getMinBcObjPosition();  
535 - var oFirstBc = oTempLp.getMinBcObj();  
536 - oFirstBc.setLp(_internalLpArray[_iZbx_lpIndex]);  
537 - oFirstBc.fnSetDelFlag(false);  
538 - _internalLpArray[_iZbx_lpIndex].setBc(oFirstBcIndexes[0], oFirstBcIndexes[1], oFirstBc);  
539 - } else {  
540 - oTempLp.setLp(_lpArray[_iZbx_lpIndex]); // 设置原始路牌对象  
541 - oTempLp._$_aVerticalIntervalTime = _internalLpArray[_iZbx_lpIndex]._$_aVerticalIntervalTime; // 设置纵向最小发车间隔  
542 - oTempLp.setBxLb(_internalLpArray[_iZbx_lpIndex].isBxLb());  
543 - oTempLp.setBxFb(_internalLpArray[_iZbx_lpIndex].isBxFb());  
544 - oTempLp.setBxFb5_2(_internalLpArray[_iZbx_lpIndex].isBxFb5_2());  
545 -  
546 - // 修正除了第一个班次外,其余其他班次  
547 - var iBcindex = 0;  
548 - for (i = 1; i < _qCount; i++) {  
549 - while (iBcindex <= 1) {  
550 - if (oTempLp.getBc(i, iBcindex)) { // 替换存在的班次  
551 - oTempLp.setBc(i, iBcindex, _fnGenerateBc(_iZbx_lpIndex, i, iBcindex));  
552 - }  
553 - iBcindex ++;  
554 - }  
555 - iBcindex = 0;  
556 - }  
557 -  
558 - _internalLpArray[_iZbx_lpIndex] = oTempLp;  
559 - }  
560 -  
561 - console.log("中标线对应第" + (_iZbx_lpIndex + 1) + "个路牌");  
562 -  
563 - console.log("//---------------- 行车计划,初始化方法4 end ----------------//");  
564 - };  
565 -  
566 - //-------------------- 重要的内部方法 -----------------------//  
567 - /**  
568 - * 核心方法,利用路牌间隔纵向生成班次。  
569 - * @param iLpindex 路牌索引  
570 - * @param iQindex 圈索引  
571 - * @param iBcindex 班次索引  
572 - * @returns object InternalBcObj,失败 false  
573 - */  
574 - var _fnGenerateBc = function(iLpindex, iQindex, iBcindex) {  
575 - // 以上标线为起始点,使用路牌在不同圈,班次索引的发车间隔,计算班次  
576 - // 注意,发车间隔是指下一个班次应该距离当前班次间隔,是从下往上的  
577 -  
578 - // 1、参数验证  
579 - if (iLpindex == 0) { // 上标线的班次不需要生成  
580 - return false;  
581 - }  
582 -  
583 - // 2、计算间隔  
584 - var i;  
585 - var oLp;  
586 - var iTime = 0;  
587 - for (i = 0; i < iLpindex; i++) {  
588 - oLp = _internalLpArray[i];  
589 - iTime += oLp.fnGetVerticalIntervalTime(iQindex, iBcindex);  
590 - }  
591 -  
592 - // 3、生成班次  
593 - var _oKsbc = _internalLpArray[0].getBc(iQindex, iBcindex);  
594 - if (!_oKsbc) {  
595 - return false;  
596 - }  
597 - var _oKssj = _paramObj.addMinute(_oKsbc.getFcTimeObj(), iTime);  
598 - var _oBc = _factory.createBcObj(  
599 - _internalLpArray[iLpindex],  
600 - "normal", _oKsbc.isUp(),  
601 - 1, _oKssj, _paramObj);  
602 -  
603 - return _oBc;  
604 -  
605 - };  
606 -  
607 - /**  
608 - * 核心方法,在指定位置生成班次并添加到路牌指定位置中。  
609 - * @param lpIndex 第几个路牌  
610 - * @param qIndex 第几圈  
611 - * @param bcIndex 第几个班次  
612 - */  
613 - var _fnGenerateBcAndSetBc = function(lpIndex, qIndex, bcIndex) {  
614 - var _bcObj = _fnGenerateBc(lpIndex, qIndex, bcIndex);  
615 - if (_bcObj) {  
616 - _internalLpArray[lpIndex].setBc(qIndex, bcIndex, _bcObj);  
617 - }  
618 - };  
619 -  
620 - /**  
621 - * 获取班次列表。  
622 - * @param oIsUp 是否上行  
623 - * @param oStartTime 开始时间对象  
624 - * @returns [(InternalBcObj)]  
625 - */  
626 - var _fnGetBcList2 = function(oIsUp, oStartTime) {  
627 - var i;  
628 - var j;  
629 - var oLp;  
630 - var oBc;  
631 - var aBc = [];  
632 -  
633 - for (j = 0; j < _qCount; j++) {  
634 - for (i = 0; i < _internalLpArray.length; i++) {  
635 - oLp = _internalLpArray[i];  
636 - oBc = oLp.getBc(  
637 - j,  
638 - _qIsUp == oIsUp ? 0 : 1  
639 - );  
640 - if (oBc && oBc.getFcTimeObj().isAfter(oStartTime)) {  
641 - aBc.push(oBc);  
642 - }  
643 - }  
644 - }  
645 -  
646 - var aBcFcTime = [];  
647 - for (i = 0; i < aBc.length; i++) {  
648 - oBc = aBc[i];  
649 - aBcFcTime.push(oBc.getFcTimeObj().format("HH:mm"));  
650 - }  
651 - console.log((oIsUp ? "上行班次列表:" : "下行班次列表:") + aBcFcTime.join(","));  
652 -  
653 - return aBc;  
654 - };  
655 -  
656 - /**  
657 - * 获取班次列表。  
658 - * @param isUp boolean 是否上行  
659 - * @returns [(InternalBcObj)]  
660 - */  
661 - var _fnGetBcList = function(isUp) {  
662 - var i;  
663 - var j;  
664 - var oLp;  
665 - var oBc;  
666 - var aBc = [];  
667 -  
668 - for (j = 0; j < _qCount; j++) {  
669 - for (i = 0; i < _internalLpArray.length; i++) {  
670 - oLp = _internalLpArray[i];  
671 - oBc = oLp.getBc(  
672 - j,  
673 - _qIsUp == isUp ? 0 : 1  
674 - );  
675 - if (oBc) {  
676 - aBc.push(oBc);  
677 - }  
678 - }  
679 - }  
680 -  
681 - var aBcFcTime = [];  
682 - for (i = 0; i < aBc.length; i++) {  
683 - oBc = aBc[i];  
684 - aBcFcTime.push(oBc.getFcTimeObj().format("HH:mm"));  
685 - }  
686 - console.log((isUp ? "上行班次列表:" : "下行班次列表:") + aBcFcTime.join(","));  
687 -  
688 - return aBc;  
689 - };  
690 -  
691 - /**  
692 - * 查找离指定时间最近的前面的班次索引信息  
693 - * @param timeObj 查找时间  
694 - * @param isUp 是否上行  
695 - * @returns [{路牌index},{圈index},{班次index}]  
696 - */  
697 - var _fnFindUpClosedBcIndexWithTime = function(timeObj, isUp) {  
698 -  
699 - var _lpObj;  
700 - var _groupObj;  
701 - var _bcObj;  
702 - var _i;  
703 - var _j;  
704 - var timediff; // 时间差取绝对值  
705 -  
706 - var _lpIndex;  
707 - var _up_qIndex;  
708 - var _up_bIndex;  
709 -  
710 - for (_i = 0; _i < _qCount; _i++) {  
711 - for (_j = 0; _j < _internalLpArray.length; _j++) {  
712 - _lpObj = _internalLpArray[_j];  
713 - _groupObj = _lpObj.getGroup(_i);  
714 - _bcObj = isUp == _qIsUp ? _groupObj.getBc1() : _groupObj.getBc2();  
715 - if (!_bcObj) { // 没有班次动态生成一个,可能生成不出的  
716 - _bcObj = _fnGenerateBc(_j, _i, isUp == _qIsUp ? 0 : 1);  
717 - }  
718 - if (_bcObj) {  
719 - if (timeObj.diff(_bcObj.getFcTimeObj()) >= 0) {  
720 - if (!timediff) {  
721 - timediff = timeObj.diff(_bcObj.getFcTimeObj());  
722 - _lpIndex = _j;  
723 - _up_qIndex = _i;  
724 - _up_bIndex = isUp == _qIsUp ? 0 : 1;  
725 - } else {  
726 - if (timeObj.diff(_bcObj.getFcTimeObj()) < timediff) {  
727 - timediff = timeObj.diff(_bcObj.getFcTimeObj());  
728 - _lpIndex = _j;  
729 - _up_qIndex = _i;  
730 - _up_bIndex = isUp == _qIsUp ? 0 : 1;  
731 - }  
732 - }  
733 - }  
734 - }  
735 - }  
736 - }  
737 -  
738 - if (_lpIndex == undefined) {  
739 - return false;  
740 - }  
741 -  
742 - var bcindex = [];  
743 - bcindex.push(_lpIndex);  
744 - bcindex.push(_up_qIndex);  
745 - bcindex.push(_up_bIndex);  
746 -  
747 - return bcindex;  
748 - };  
749 -  
750 - /**  
751 - * 查找离指定时间最近的后面的班次索引信息  
752 - * @param timeObj 查找时间  
753 - * @param isUp 是否上行  
754 - * @returns [{路牌index},{圈index},{班次index}]  
755 - */  
756 - var _fnFindDownClosedBcIndexWithTime = function(timeObj, isUp) {  
757 - var _lpObj;  
758 - var _groupObj;  
759 - var _bcObj;  
760 - var _i;  
761 - var _j;  
762 - var timediff; // 时间差取绝对值  
763 -  
764 - var _lpIndex;  
765 - var _down_qIndex;  
766 - var _down_bIndex;  
767 -  
768 - var flag;  
769 -  
770 - for (_i = 0; _i < _qCount; _i++) {  
771 - for (_j = 0; _j < _internalLpArray.length; _j++) {  
772 - _lpObj = _internalLpArray[_j];  
773 - _groupObj = _lpObj.getGroup(_i);  
774 - // TODO:bug  
775 - _bcObj = isUp == _qIsUp ? _groupObj.getBc1() : _groupObj.getBc2();  
776 - if (!_bcObj) { // 没有班次动态生成一个,可能生成不出的  
777 - _bcObj = _fnGenerateBc(_j, _i, isUp == _qIsUp ? 0 : 1);  
778 - }  
779 - if (_bcObj) {  
780 - //console.log("timeobj -> bcobj diff flag " +  
781 - // timeObj.format("HH:mm") + "->" +  
782 - // _bcObj.getFcTimeObj().format("HH:mm") +  
783 - // timeObj.diff(_bcObj.getFcTimeObj()) +  
784 - // (timeObj.diff(_bcObj.getFcTimeObj()) <= 0)  
785 - //);  
786 -  
787 - flag = (timeObj.diff(_bcObj.getFcTimeObj())) <= 0;  
788 -  
789 - if (flag) {  
790 - if (!timediff) {  
791 - timediff = timeObj.diff(_bcObj.getFcTimeObj());  
792 - _lpIndex = _j;  
793 - _down_qIndex = _i;  
794 - _down_bIndex = isUp == _qIsUp ? 0 : 1;  
795 - } else {  
796 - if ((timeObj.diff(_bcObj.getFcTimeObj())) > timediff) {  
797 - timediff = timeObj.diff(_bcObj.getFcTimeObj());  
798 - _lpIndex = _j;  
799 - _down_qIndex = _i;  
800 - _down_bIndex = isUp == _qIsUp ? 0 : 1;  
801 - }  
802 - }  
803 - }  
804 - }  
805 - }  
806 - }  
807 -  
808 - if (_lpIndex == undefined) {  
809 - return false;  
810 - }  
811 -  
812 - var bcindex = [];  
813 - bcindex.push(_lpIndex);  
814 - bcindex.push(_down_qIndex);  
815 - bcindex.push(_down_bIndex);  
816 -  
817 - return bcindex;  
818 - };  
819 -  
820 - /**  
821 - * 获取班次索引。  
822 - * @param oBc 班次对象  
823 - * @returns [{路牌索引},{圈索引},{班次索引}]  
824 - */  
825 - var _fnGetBcIndex = function(oBc) {  
826 - // 路牌索引  
827 - var i;  
828 - var iLpIndex;  
829 - for (i = 0; i < _internalLpArray.length; i++) {  
830 - if (_internalLpArray[i]._$$_orign_lp_obj == oBc._$$_internal_lp_obj._$$_orign_lp_obj) {  
831 - iLpIndex = i;  
832 - break;  
833 - }  
834 - }  
835 - // 圈索引  
836 - var j;  
837 - var iGroupIndex;  
838 - var bFlag = false;  
839 - for (i = 0; i < _internalLpArray.length; i++) {  
840 - if (bFlag) {  
841 - break;  
842 - }  
843 - for (j = 0; j < _qCount; j++) {  
844 - if (_internalLpArray[i]._$_groupBcArray[j] == oBc._$$_internal_group_obj) {  
845 - iGroupIndex = j;  
846 - bFlag = true;  
847 - break;  
848 - }  
849 - }  
850 - }  
851 - // 班次索引  
852 - var iBcIndex = _qIsUp == oBc.isUp() ? 0 : 1;  
853 -  
854 - if (iLpIndex == undefined) {  
855 - return null;  
856 - } else {  
857 - return [].concat(iLpIndex, iGroupIndex, iBcIndex);  
858 - }  
859 -  
860 - };  
861 -  
862 - return {  
863 - //------------- 布局初始化方法 ------------//  
864 - /**  
865 - * 初始化数据,使用标线初始化  
866 - */  
867 - fnInitDataWithBxLayout: function() {  
868 - // 初始化布局1,构造上标线,计算圈数,把上标线数据放入第一个路牌中  
869 - _fnInitFun1();  
870 - // 初始化布局2,从上标线的某个班次开始,构造所有路牌的早高峰班次,晚高峰班次,计算路牌在各个圈中的间隔  
871 - _fnInitFun2();  
872 - // 初始化布局3,计算连班分班路牌分布  
873 - _fnInitFun3();  
874 - // 初始化布局4,计算中标线位置  
875 - _fnInitFun4();  
876 -  
877 - },  
878 -  
879 - /**  
880 - * 调整高峰班次,  
881 - * 初始化生成早高峰,晚高峰班次并不准确,因为根据高峰时间段,并不在一个完整圈内,应该是在两个或多个圈之间  
882 - * 当初始化定好布局后(上标线,中标线),然后确定每个路牌的班型(连班,分班,5休2分班)后  
883 - * 然后重新计算框在高峰时间段内的班次索引,不足的添加,之前多加的删除(只删除分班路牌上的)  
884 - * @param isZgf 是否早高峰  
885 - * @param isUp 是否上行  
886 - */  
887 - fnAdjustGfbc : function(isZgf, isUp) {  
888 - var oStartTime; // 开始时间  
889 - var oEndTime; // 结束时间  
890 - var aStartBcIndex; // 开始班次索引  
891 - var aEndBcIndex; // 结束班次索引  
892 -  
893 - oStartTime = isZgf ? _paramObj.getMPeakStartTimeObj() : _paramObj.getEPeakStartTimeObj();  
894 - oEndTime = isZgf ? _paramObj.getMPeakEndTimeObj() : _paramObj.getEPeakEndTimeObj();  
895 -  
896 - aStartBcIndex = _fnFindUpClosedBcIndexWithTime(oStartTime, isUp);  
897 - aEndBcIndex = _fnFindDownClosedBcIndexWithTime(oEndTime, isUp);  
898 -  
899 - var iLpIndex;  
900 - var iQIndex;  
901 - var iBcIndex;  
902 - var iQInternelCount; // 高峰时间段中间包含的圈数  
903 - var i;  
904 - var j;  
905 -  
906 - var oLp;  
907 -  
908 - if (aStartBcIndex && aEndBcIndex) {  
909 - iLpIndex = aStartBcIndex[0];  
910 - iQIndex = aStartBcIndex[1];  
911 - iBcIndex = aStartBcIndex[2];  
912 -  
913 - // 处理头  
914 - // 删除头部多余班次  
915 - for (j = 0; j < iLpIndex; j++) {  
916 - oLp = _internalLpArray[j];  
917 - if (oLp.isBxFb() && oLp.getBc(iQIndex, iBcIndex)) {  
918 - oLp.removeBc(iQIndex, iBcIndex);  
919 - }  
920 - }  
921 -  
922 - for (j = iLpIndex; j < _internalLpArray.length; j++) {  
923 - oLp = _internalLpArray[j];  
924 - if (!oLp.getBc(iQIndex, iBcIndex)) {  
925 - _fnGenerateBcAndSetBc(j, iQIndex, iBcIndex);  
926 - }  
927 - }  
928 -  
929 - // 处理中间  
930 - iQInternelCount = aEndBcIndex[1] - aStartBcIndex[1] - 1;  
931 - for (i = 1; i <= iQInternelCount; i++) {  
932 - oLp = _internalLpArray[iQIndex + i];  
933 -  
934 - if (!oLp.getBc(iQIndex + i, iBcIndex)) {  
935 - _fnGenerateBcAndSetBc(i, iQIndex + i, iBcIndex);  
936 - }  
937 - }  
938 -  
939 - // 处理尾部  
940 - iLpIndex = aEndBcIndex[0];  
941 - iQIndex = aEndBcIndex[1];  
942 - iBcIndex = aEndBcIndex[2];  
943 -  
944 - // 删除尾部多余的班次  
945 - for (j = iLpIndex; j < _internalLpArray.length; j++) {  
946 - oLp = _internalLpArray[j];  
947 - if (oLp.isBxFb() && oLp.getBc(iQIndex, iBcIndex)) {  
948 - oLp.removeBc(iQIndex, iBcIndex);  
949 - }  
950 - }  
951 -  
952 - if (aStartBcIndex[1] != aEndBcIndex[1]) { // 指定时间范围跨圈  
953 - for (j = 0; j < iLpIndex; j++) {  
954 - oLp = _internalLpArray[j];  
955 - if (!oLp.getBc(iQIndex, iBcIndex)) {  
956 - _fnGenerateBcAndSetBc(j, iQIndex, iBcIndex);  
957 - }  
958 - }  
959 - } else {  
960 - // 不跨圈,不用处理,处理头的时候已经加了  
961 - }  
962 -  
963 - }  
964 -  
965 - },  
966 -  
967 - /**  
968 - * 按照营运时间要求补充班次,  
969 - * 早高峰7:45分以前出场运营,  
970 - * 晚高峰16:10分以前出场运营  
971 - */  
972 - fnCalcuLpBc_yy: function() {  
973 - // 补班次的时候,针对的是分班班型  
974 - var i;  
975 - var _oLp;  
976 - var _oBc;  
977 - var _aMinBcIndex;  
978 - var _aMaxBcIndex;  
979 -  
980 - var _qIndex;  
981 - var _bIndex;  
982 -  
983 - var _zgfCDate = _paramObj.toTimeObj("7:45");  
984 - var _wgfCDate = _paramObj.toTimeObj("16:10");  
985 - var _ccsj;  
986 -  
987 - for (i = 0; i < _internalLpArray.length; i++) {  
988 - _oLp = _internalLpArray[i];  
989 - if (_oLp.isBxFb()) { // 分班路牌  
990 - // 早高峰部分  
991 - _aMinBcIndex = _oLp.getMinBcObjPosition();  
992 - _qIndex = _aMinBcIndex[0];  
993 - _bIndex = _aMinBcIndex[1];  
994 - _oBc = _oLp.getBc(_qIndex, _bIndex);  
995 - if (_qIsUp) {  
996 - _ccsj = _bIndex == 0 ?  
997 - _paramObj.getUpOutTime() :  
998 - _paramObj.getDownOutTime();  
999 - } else {  
1000 - _ccsj = _bIndex == 0 ?  
1001 - _paramObj.getDownOutTime() :  
1002 - _paramObj.getUpOutTime();  
1003 - }  
1004 - if (_zgfCDate.isBefore(_paramObj.addMinute(_oBc.getFcTimeObj(), -_ccsj))) {  
1005 - _fnGenerateBcAndSetBc(  
1006 - i,  
1007 - _bIndex == 0 ? _qIndex - 1 : _qIndex,  
1008 - _bIndex == 0 ? 1 : 0  
1009 - )  
1010 - }  
1011 -  
1012 - // 晚高峰部分  
1013 - _aMaxBcIndex = _oLp.getMaxBcObjPosition();  
1014 - _qIndex = _aMaxBcIndex[0];  
1015 - _bIndex = _aMaxBcIndex[1];  
1016 - _oBc = _oLp.getBc(  
1017 - _bIndex == 0 ? _qIndex - 1 : _qIndex,  
1018 - _bIndex == 0 ? 1 : 0  
1019 - );  
1020 - if (!_oBc) { // 前一个班次不存在,再判定加不加  
1021 - _oBc = _oLp.getBc(_qIndex, _bIndex);  
1022 - if (_qIsUp) {  
1023 - _ccsj = _bIndex == 0 ?  
1024 - _paramObj.getUpOutTime() :  
1025 - _paramObj.getDownOutTime();  
1026 - } else {  
1027 - _ccsj = _bIndex == 0 ?  
1028 - _paramObj.getDownOutTime() :  
1029 - _paramObj.getUpOutTime();  
1030 - }  
1031 - if (_wgfCDate.isBefore(_paramObj.addMinute(_oBc.getFcTimeObj(), -_ccsj))) {  
1032 - _fnGenerateBcAndSetBc(  
1033 - i,  
1034 - _bIndex == 0 ? _qIndex - 1 : _qIndex,  
1035 - _bIndex == 0 ? 1 : 0  
1036 - )  
1037 - }  
1038 - }  
1039 - }  
1040 - }  
1041 - },  
1042 -  
1043 - /**  
1044 - * 补充做5休2的班型班次。  
1045 - * 1、确认5_2班型大致多少圈(小数点过.7进位)  
1046 - * 2、获取当前5_2两端车次链的信息,每段的班次数目,还差几个班次没加  
1047 - * 3、如果前面的车次链班次少,则从前面的车次链开始加  
1048 - * 4、如果车次链班次数一样,从从后面的车次链开始加  
1049 - * 5、加班次时都是往车次链前方加  
1050 - * 6、如果前面车次链不能再加班次了,从后面车次链加  
1051 - */  
1052 - fnCalcuLpBx_5_2: function() {  
1053 - // 计算做5休2班型所需的班次数  
1054 - var iBxBcount = _aBxDesc[6].fBcCount;  
1055 - if (iBxBcount - Math.floor(iBxBcount) > 0.7) {  
1056 - iBxBcount = Math.floor(iBxBcount) + 1;  
1057 - } else {  
1058 - iBxBcount = Math.floor(iBxBcount);  
1059 - }  
1060 -  
1061 - var i;  
1062 - var j;  
1063 - var oLp;  
1064 - var iAddBcCount;  
1065 - var oBcChain1;  
1066 - var oBcChain2;  
1067 - var iQindex;  
1068 - var iBindex;  
1069 -  
1070 - for (i = 0; i < _internalLpArray.length; i++) {  
1071 - oLp = _internalLpArray[i];  
1072 - if (oLp.isBxFb5_2()) {  
1073 - iAddBcCount = iBxBcount - oLp.getBcArray().length; // 需要添加的班次数  
1074 - for (j = 1; j <= iAddBcCount; j++) {  
1075 - oBcChain1 = oLp.fnGetBcChainInfo(0);  
1076 - oBcChain2 = oLp.fnGetBcChainInfo(1);  
1077 -  
1078 - if (oBcChain1.bcount < oBcChain2.bcount) {  
1079 - iQindex = oBcChain1.s_b == 0 ? oBcChain1.s_q - 1 : oBcChain1.s_q;  
1080 - iBindex = oBcChain1.s_b == 0 ? 1 : 0;  
1081 - // 往车次链往前不能加,就往后加  
1082 - if (_fnGenerateBc(i, iQindex, iBindex)) {  
1083 - _fnGenerateBcAndSetBc(i, iQindex, iBindex);  
1084 - } else {  
1085 - iQindex = oBcChain1.e_b == 0 ? oBcChain1.e_q : oBcChain1.e_q + 1;  
1086 - iBindex = oBcChain1.e_b == 0 ? 1 : 0;  
1087 - _fnGenerateBcAndSetBc(i, iQindex, iBindex);  
1088 - }  
1089 -  
1090 - } else if (oBcChain1.bcount > oBcChain2.bcount) {  
1091 - iQindex = oBcChain2.s_b == 0 ? oBcChain2.s_q - 1 : oBcChain2.s_q;  
1092 - iBindex = oBcChain2.s_b == 0 ? 1 : 0;  
1093 - _fnGenerateBcAndSetBc(i, iQindex, iBindex);  
1094 - } else {  
1095 - iQindex = oBcChain2.s_b == 0 ? oBcChain2.s_q - 1 : oBcChain2.s_q;  
1096 - iBindex = oBcChain2.s_b == 0 ? 1 : 0;  
1097 - _fnGenerateBcAndSetBc(i, iQindex, iBindex);  
1098 - }  
1099 - }  
1100 - }  
1101 - }  
1102 -  
1103 - },  
1104 -  
1105 - /**  
1106 - * 补其他分班班型班次。  
1107 - * 从车次链的后面开始加  
1108 - */  
1109 - fnCalcuLpBx_other: function() {  
1110 - // TODO:根据上标线的首班时间确定班型,小于05:59的做一休一,否则做二休一  
1111 - var oSt = _qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();  
1112 - var iBxIndex = 4;  
1113 - if (oSt.isBefore(_paramObj.toTimeObj("05:59"))) {  
1114 - iBxIndex = 5;  
1115 - }  
1116 - // 计算做5休2班型所需的班次数  
1117 - var iQBcount = _aBxDesc[iBxIndex].fQCount;  
1118 - var iBxBcount = Math.round(iQBcount) * 2;  
1119 -  
1120 - var i;  
1121 - var j;  
1122 - var oLp;  
1123 - var iAddBcCount;  
1124 - var oBcChain1;  
1125 - var oBcChain2;  
1126 - var iQindex;  
1127 - var iBindex;  
1128 -  
1129 - for (i = 0; i < _internalLpArray.length; i++) {  
1130 - oLp = _internalLpArray[i];  
1131 - if (oLp.isBxFb() && !oLp.isBxFb5_2()) {  
1132 - iAddBcCount = iBxBcount - oLp.getBcArray().length; // 需要添加的班次数  
1133 - for (j = 1; j <= iAddBcCount; j++) {  
1134 - oBcChain1 = oLp.fnGetBcChainInfo(0);  
1135 - oBcChain2 = oLp.fnGetBcChainInfo(1);  
1136 -  
1137 - if (oBcChain1.bcount < oBcChain2.bcount) {  
1138 - iQindex = oBcChain1.e_b == 0 ? oBcChain1.e_q : oBcChain1.e_q + 1;  
1139 - iBindex = oBcChain1.e_b == 0 ? 1 : 0;  
1140 - _fnGenerateBcAndSetBc(i, iQindex, iBindex);  
1141 - } else if (oBcChain1.bcount > oBcChain2.bcount) {  
1142 - iQindex = oBcChain2.e_b == 0 ? oBcChain2.e_q : oBcChain2.e_q + 1;  
1143 - iBindex = oBcChain2.e_b == 0 ? 1 : 0;  
1144 - _fnGenerateBcAndSetBc(i, iQindex, iBindex);  
1145 - } else {  
1146 - iQindex = oBcChain2.e_b == 0 ? oBcChain2.e_q : oBcChain2.e_q + 1;  
1147 - iBindex = oBcChain2.e_b == 0 ? 1 : 0;  
1148 - _fnGenerateBcAndSetBc(i, iQindex, iBindex);  
1149 - }  
1150 - }  
1151 - }  
1152 - }  
1153 -  
1154 - },  
1155 -  
1156 - /**  
1157 - * 补充连班路牌班次。  
1158 - * 1、上标线,中标线中间的连班路牌班次从早高峰班次一直拉到底,从早高峰班次向上标线起始班次靠拢  
1159 - * 2、中标线以下的连班路牌班次从早高峰班次一直拉到底,从早高峰班次向中标线起始班次靠拢  
1160 - */  
1161 - fnCalcuLpBx_lb: function() {  
1162 - // 补充连班的班次,参照上标线,中标线补充不足的班次  
1163 -  
1164 - var aLbLpindexes = []; // 除上标线,中标线的连班路牌索引  
1165 - var i;  
1166 - for (i = 0; i < _internalLpArray.length; i++) {  
1167 - if (_internalLpArray[i].isBxLb() && i != 0 && i != _iZbx_lpIndex) {  
1168 - aLbLpindexes.push(i);  
1169 - }  
1170 - }  
1171 -  
1172 - var oEndsj = // 结束时间  
1173 - _paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj()) ?  
1174 - _paramObj.getDownLastDTimeObj() :  
1175 - _paramObj.getUpLastDtimeObj();  
1176 -  
1177 - var oLp;  
1178 - var aMinbcPos;  
1179 - var oBc;  
1180 - var j;  
1181 - var iTempBcIndex;  
1182 -  
1183 - // 1、从最小班次开始,往后补充班次  
1184 - for (i = 0; i < aLbLpindexes.length; i++) {  
1185 - oLp = _internalLpArray[aLbLpindexes[i]];  
1186 -  
1187 - // 最小班次索引  
1188 - aMinbcPos = oLp.getMinBcObjPosition();  
1189 - // 使用纵向分隔补充班次,从最小班次向后补  
1190 - iTempBcIndex = aMinbcPos[1] == 0 ? 1 : 0;  
1191 - j = iTempBcIndex == 0 ? aMinbcPos[0] + 1 : aMinbcPos[0];  
1192 -  
1193 - while (j < _qCount) {  
1194 - while (iTempBcIndex <= 1) {  
1195 - oBc = _fnGenerateBc(aLbLpindexes[i], j, iTempBcIndex);  
1196 - if (oBc &&  
1197 - oBc.getFcTimeObj().isBefore(oEndsj) ) {  
1198 - oLp.setBc(j, iTempBcIndex, oBc);  
1199 - }  
1200 - iTempBcIndex++;  
1201 - }  
1202 - iTempBcIndex = 0;  
1203 - j++;  
1204 - }  
1205 -  
1206 - }  
1207 -  
1208 - // 2、上标线中标线之间的路牌,从最小的班次往前补充班次  
1209 -  
1210 - // 还要补充缺失的班次,差上标线几个班次要往前补上  
1211 - var iBccount;  
1212 - var iQindex;  
1213 - var iBindex;  
1214 - // 补上标线到中标线之间的连班路牌的班次  
1215 - for (i = 0; i < aLbLpindexes.length; i++) {  
1216 - if (aLbLpindexes[i] > 0 && aLbLpindexes[i] < _iZbx_lpIndex) {  
1217 - oLp = _internalLpArray[aLbLpindexes[i]];  
1218 - aMinbcPos = oLp.getMinBcObjPosition();  
1219 - iQindex = aMinbcPos[0];  
1220 - iBindex = aMinbcPos[1];  
1221 - iBccount = (iQindex - 1) * 2 + iBindex; // 距离上标线起始站点差几个班次  
1222 - for (j = 0; j < iBccount; j++) {  
1223 - if (iBindex == 0) {  
1224 - iQindex --;  
1225 - iBindex = 1;  
1226 - _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);  
1227 - } else if (iBindex == 1) {  
1228 - iBindex --;  
1229 - _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);  
1230 - }  
1231 - }  
1232 -  
1233 - }  
1234 -  
1235 - }  
1236 -  
1237 - // 3、中标线之后的路牌,从最小的班次往前补充班次  
1238 -  
1239 - // 补中标线以下的连班路牌的班次  
1240 - for (i = 0; i < aLbLpindexes.length; i++) {  
1241 - if (aLbLpindexes[i] > _iZbx_lpIndex) {  
1242 - oLp = _internalLpArray[aLbLpindexes[i]];  
1243 - aMinbcPos = oLp.getMinBcObjPosition();  
1244 - iQindex = aMinbcPos[0];  
1245 - iBindex = aMinbcPos[1];  
1246 - iBccount = (iQindex - 0) * 2 + iBindex - 1; // 距离上标线起始站点差几个班次  
1247 - for (j = 0; j < iBccount; j++) {  
1248 - if (iBindex == 0) {  
1249 - iQindex --;  
1250 - iBindex = 1;  
1251 - _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);  
1252 - } else if (iBindex == 1) {  
1253 - iBindex --;  
1254 - _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);  
1255 - }  
1256 - }  
1257 - }  
1258 - }  
1259 -  
1260 - },  
1261 -  
1262 - /**  
1263 - * 计算末班车。  
1264 - * 1、将上下行拉成上下行两个班次列表(包括标记班次)  
1265 - * 2、分别找出离末班车发车时间最近的班次,并替换时间  
1266 - * 3、删除之后的班次  
1267 - */  
1268 - fnCalcuLastBc: function() {  
1269 - var i;  
1270 - var iTimeDiff;  
1271 - var iTempTime;  
1272 - var aBc;  
1273 - var oLastBcTime;  
1274 - var oLastBcIsUp;  
1275 - var iModifyIndex;  
1276 -  
1277 - // 查找末班车早的末班车时间和方向  
1278 - if (_paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj())) {  
1279 - oLastBcTime = _paramObj.getUpLastDtimeObj();  
1280 - oLastBcIsUp = true;  
1281 - } else {  
1282 - oLastBcTime = _paramObj.getDownLastDTimeObj();  
1283 - oLastBcIsUp = false;  
1284 - }  
1285 -  
1286 - // 确定早的末班车时间  
1287 - aBc = _fnGetBcList(oLastBcIsUp);  
1288 - for (i = 0; i < aBc.length; i++) {  
1289 - iTempTime = oLastBcTime.diff(aBc[i].getFcTimeObj(), "m");  
1290 - if (iTimeDiff == undefined) {  
1291 - iTimeDiff = iTempTime;  
1292 - iModifyIndex = i;  
1293 - } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff)) {  
1294 - iTimeDiff = iTempTime;  
1295 - iModifyIndex = i;  
1296 - }  
1297 - }  
1298 - aBc[iModifyIndex].addMinuteToFcsj(iTimeDiff); // 替换成末班车时间  
1299 - aBc[iModifyIndex].fnSetDelFlag(false);  
1300 - aBc[iModifyIndex].fnSetIsLastBc(true);  
1301 - for (i = iModifyIndex + 1; i < aBc.length; i++) { // 删除多余班次  
1302 - _qIsUp == oLastBcIsUp ?  
1303 - aBc[i]._$$_internal_group_obj.setBc1(undefined) :  
1304 - aBc[i]._$$_internal_group_obj.setBc2(undefined);  
1305 - }  
1306 -  
1307 - // 查找末班车晚的末班车时间和方向  
1308 - if (_paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj())) {  
1309 - oLastBcTime = _paramObj.getDownLastDTimeObj();  
1310 - oLastBcIsUp = false;  
1311 - } else {  
1312 - oLastBcTime = _paramObj.getUpLastDtimeObj();  
1313 - oLastBcIsUp = true;  
1314 - }  
1315 - // 确定晚的末班车时间  
1316 - aBc = _fnGetBcList(oLastBcIsUp);  
1317 - var oBc;  
1318 - var aBcIndex;  
1319 - var iLpIndex;  
1320 - var iQIndex;  
1321 - var iBcIndex;  
1322 -  
1323 - iTimeDiff = undefined;  
1324 - for (i = 0; i < aBc.length; i++) {  
1325 - oBc = aBc[i];  
1326 - aBcIndex = _fnGetBcIndex(oBc);  
1327 -  
1328 - iLpIndex = aBcIndex[0];  
1329 - iQIndex = aBcIndex[2] == 0 ? aBcIndex[1] -1 : aBcIndex[1];  
1330 - iBcIndex = aBcIndex[2] == 0 ? 1 : 0;  
1331 -  
1332 - if (!_internalLpArray[iLpIndex].getBc(iQIndex, iBcIndex)) {  
1333 - continue;  
1334 - }  
1335 -  
1336 - iTempTime = oLastBcTime.diff(aBc[i].getFcTimeObj(), "m");  
1337 - if (iTimeDiff == undefined) {  
1338 - iTimeDiff = iTempTime;  
1339 - iModifyIndex = i;  
1340 - } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff)) {  
1341 - iTimeDiff = iTempTime;  
1342 - iModifyIndex = i;  
1343 - }  
1344 - }  
1345 - aBc[iModifyIndex].addMinuteToFcsj(iTimeDiff); // 替换成末班车时间  
1346 - aBc[iModifyIndex].fnSetDelFlag(false);  
1347 - aBc[iModifyIndex].fnSetIsLastBc(true);  
1348 - for (i = iModifyIndex + 1; i < aBc.length; i++) { // 删除多余班次  
1349 - _qIsUp == oLastBcIsUp ?  
1350 - aBc[i]._$$_internal_group_obj.setBc1(undefined) :  
1351 - aBc[i]._$$_internal_group_obj.setBc2(undefined);  
1352 - }  
1353 -  
1354 - },  
1355 -  
1356 - /**  
1357 - * 添加吃饭班次。  
1358 - */  
1359 - fnCalcuEatBc: function() {  
1360 - // 吃午饭时间范围,10:15 到 12:15  
1361 - // 吃晚饭时间范围,18:00 到 19:00  
1362 -  
1363 - if (!_paramObj.fnIsEat()) {  
1364 - return;  
1365 - }  
1366 -  
1367 - // 午饭index  
1368 - var aLEIndex;  
1369 - // 晚饭index  
1370 - var aDEIndex;  
1371 -  
1372 - // 所有吃饭都默认在一个方向,两个方向暂时不考虑  
1373 - if (_paramObj.fnIsUpEat()) {  
1374 - aLEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("10:15"), true, false);  
1375 - aDEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("18:00"), true, false);  
1376 - } else {  
1377 - aLEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("10:15"), false, true);  
1378 - aDEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("18:00"), false, true);  
1379 - }  
1380 -  
1381 - // 午饭第几圈,第几个班次  
1382 - var iLEQIndex = aLEIndex[0];  
1383 - var iLEBIndex = aLEIndex[1];  
1384 - // 晚饭第几圈,第几个班次  
1385 - var iDEQIndex = aDEIndex[0];  
1386 - var iDEBIndex = aDEIndex[1];  
1387 -  
1388 - // 注意,本模型只有连班才有吃饭  
1389 -  
1390 - var i;  
1391 - var oLp;  
1392 - var aLbIndex = []; // 连班班型的路牌索引  
1393 - for (i = 0; i < _internalLpArray.length; i++) {  
1394 - oLp = _internalLpArray[i];  
1395 - if (oLp.isBxLb()) {  
1396 - aLbIndex.push(i);  
1397 - }  
1398 - }  
1399 -  
1400 - var iLTime;  
1401 - var iDtime;  
1402 - var j;  
1403 - for (i = 0; i < aLbIndex.length; i++) {  
1404 - oLp = _internalLpArray[aLbIndex[i]];  
1405 -  
1406 - // 午饭  
1407 - iLTime = oLp.fnAddEatBc(iLEQIndex, iLEBIndex, _factory, _paramObj);  
1408 - // 晚饭  
1409 - iDtime = oLp.fnAddEatBc(iDEQIndex, iDEBIndex, _factory, _paramObj);  
1410 -  
1411 - if (i == aLbIndex.length - 1) {  
1412 - for (j = aLbIndex[i]; j < _internalLpArray.length; j++) {  
1413 - oLp = _internalLpArray[j];  
1414 - if (oLp.isBxFb()) { // 5休2班型不调整  
1415 - // 修正午饭之后路牌班次的发车时间  
1416 - oLp.fnAddMinuteToBcFcsj(iLEQIndex, iLEBIndex, iLTime);  
1417 - oLp.fnAddMinuteToBcFcsj(iDEQIndex, iDEBIndex, iDtime);  
1418 - }  
1419 - }  
1420 - } else {  
1421 - for (j = aLbIndex[i]; j < aLbIndex[i + 1]; j++) {  
1422 - oLp = _internalLpArray[j];  
1423 - if (oLp.isBxFb()) {  
1424 - // 修正午饭之后路牌班次的发车时间  
1425 - oLp.fnAddMinuteToBcFcsj(iLEQIndex, iLEBIndex, iLTime);  
1426 - oLp.fnAddMinuteToBcFcsj(iDEQIndex, iDEBIndex, iDtime);  
1427 - }  
1428 - }  
1429 - }  
1430 - }  
1431 -  
1432 - },  
1433 -  
1434 - /**  
1435 - * 补每个路牌的其他班次(进出场,例保班次)。  
1436 - */  
1437 - fnCalcuOtherBc_: function() {  
1438 - var i;  
1439 - var _lpObj;  
1440 - var _minBcIndex;  
1441 - var _maxBcIndex;  
1442 - var _minBc;  
1443 - var _maxBc;  
1444 - var _otherbc = [];  
1445 - var _oFbbc;  
1446 -  
1447 - for (i = 0; i < _internalLpArray.length; i++) {  
1448 - _lpObj = _internalLpArray[i];  
1449 - _minBcIndex = _lpObj.getMinBcObjPosition();  
1450 - _maxBcIndex = _lpObj.getMaxBcObjPosition();  
1451 - _minBc = _lpObj.getBc(_minBcIndex[0], _minBcIndex[1]);  
1452 - _maxBc = _lpObj.getBc(_maxBcIndex[0], _maxBcIndex[1]);  
1453 -  
1454 - _otherbc = [];  
1455 - _otherbc.push(_factory.createBcObj(  
1456 - _lpObj, "bd", true, 1,  
1457 - _minBc.getFcTimeObj(),  
1458 - _paramObj  
1459 - ));  
1460 - _otherbc.push(_factory.createBcObj(  
1461 - _lpObj, "out", true, 1,  
1462 - _minBc.getFcTimeObj(),  
1463 - _paramObj  
1464 - ));  
1465 -  
1466 - _maxBc.setArrTimeObj(_paramObj.addMinute(_maxBc.getFcTimeObj(), _maxBc.getBcTime()));  
1467 - _maxBc.setStopTime(0);  
1468 - _otherbc.push(_factory.createBcObj(  
1469 - _lpObj, "in", true, 1,  
1470 - _maxBc.getArrTimeObj(),  
1471 - _paramObj  
1472 - ));  
1473 - _otherbc.push(_factory.createBcObj(  
1474 - _lpObj, "lc", true, 1,  
1475 - _maxBc.getArrTimeObj(),  
1476 - _paramObj  
1477 - ));  
1478 -  
1479 - // 5休2分班出场例保班次  
1480 - if (_lpObj.isBxFb5_2()) {  
1481 - _oFbbc = _lpObj.getBc(  
1482 - _lpObj.fnGetBcChainInfo(1)["s_q"],  
1483 - _lpObj.fnGetBcChainInfo(1)["s_b"]  
1484 - );  
1485 -  
1486 - _otherbc.push(_factory.createBcObj(  
1487 - _lpObj, "bd", true, 1,  
1488 - _oFbbc.getFcTimeObj(),  
1489 - _paramObj  
1490 - ));  
1491 - _otherbc.push(_factory.createBcObj(  
1492 - _lpObj, "out", true, 1,  
1493 - _oFbbc.getFcTimeObj(),  
1494 - _paramObj  
1495 - ));  
1496 - }  
1497 -  
1498 - _lpObj.addOtherBcArray(_otherbc);  
1499 - }  
1500 -  
1501 - },  
1502 -  
1503 - /**  
1504 - * 补每个路牌的其他班次(进出场,例保班次)  
1505 - * 所有的车次链前后都加进出场、报道班次  
1506 - */  
1507 - fnCalcuOtherBc: function() {  
1508 - var i;  
1509 - var j;  
1510 - var iBcChainCount;  
1511 - var oLp;  
1512 - var aOtherBc;  
1513 - var oStartBc;  
1514 - var oEndBc;  
1515 -  
1516 - for (i = 0; i < _internalLpArray.length; i++) {  
1517 - aOtherBc = [];  
1518 - oLp = _internalLpArray[i];  
1519 - iBcChainCount = oLp.fnGetBcChainCount();  
1520 -  
1521 - if (iBcChainCount == 1) { // 只有一个车次链,是连班班型  
1522 - // 头部要添加出场,例保班次  
1523 - oStartBc = oLp.getBc(  
1524 - oLp.fnGetBcChainInfo(0)["s_q"],  
1525 - oLp.fnGetBcChainInfo(0)["s_b"]  
1526 - );  
1527 - aOtherBc.push(_factory.createBcObj(  
1528 - oLp, "bd", true, 1,  
1529 - oStartBc.getFcTimeObj(),  
1530 - _paramObj  
1531 - ));  
1532 - aOtherBc.push(_factory.createBcObj(  
1533 - oLp, "out", true, 1,  
1534 - oStartBc.getFcTimeObj(),  
1535 - _paramObj  
1536 - ));  
1537 -  
1538 - // 尾部需添加进场,例保班次  
1539 - oEndBc = oLp.getBc(  
1540 - oLp.fnGetBcChainInfo(0)["e_q"],  
1541 - oLp.fnGetBcChainInfo(0)["e_b"]  
1542 - );  
1543 - aOtherBc.push(_factory.createBcObj(  
1544 - oLp, "in", true, 1,  
1545 - oEndBc.getArrTimeObj(),  
1546 - _paramObj  
1547 - ));  
1548 - aOtherBc.push(_factory.createBcObj(  
1549 - oLp, "lc", true, 1,  
1550 - oEndBc.getArrTimeObj(),  
1551 - _paramObj  
1552 - ));  
1553 - } else if (iBcChainCount == 2) { // 两个车次链,是分班班型  
1554 - // 第一个车次链开头有出场,报到班次,车次链结尾只有进场班次  
1555 - oStartBc = oLp.getBc(  
1556 - oLp.fnGetBcChainInfo(0)["s_q"],  
1557 - oLp.fnGetBcChainInfo(0)["s_b"]  
1558 - );  
1559 - aOtherBc.push(_factory.createBcObj(  
1560 - oLp, "bd", true, 1,  
1561 - oStartBc.getFcTimeObj(),  
1562 - _paramObj  
1563 - ));  
1564 - aOtherBc.push(_factory.createBcObj(  
1565 - oLp, "out", true, 1,  
1566 - oStartBc.getFcTimeObj(),  
1567 - _paramObj  
1568 - ));  
1569 -  
1570 - oEndBc = oLp.getBc(  
1571 - oLp.fnGetBcChainInfo(0)["e_q"],  
1572 - oLp.fnGetBcChainInfo(0)["e_b"]  
1573 - );  
1574 - aOtherBc.push(_factory.createBcObj(  
1575 - oLp, "in", true, 1,  
1576 - oEndBc.getArrTimeObj(),  
1577 - _paramObj  
1578 - ));  
1579 -  
1580 - // 第二个车次链开头只有出场班次,车次链结尾有进场,报到班次  
1581 - oStartBc = oLp.getBc(  
1582 - oLp.fnGetBcChainInfo(1)["s_q"],  
1583 - oLp.fnGetBcChainInfo(1)["s_b"]  
1584 - );  
1585 - aOtherBc.push(_factory.createBcObj(  
1586 - oLp, "out", true, 1,  
1587 - oStartBc.getFcTimeObj(),  
1588 - _paramObj  
1589 - ));  
1590 -  
1591 - oEndBc = oLp.getBc(  
1592 - oLp.fnGetBcChainInfo(1)["e_q"],  
1593 - oLp.fnGetBcChainInfo(1)["e_b"]  
1594 - );  
1595 - aOtherBc.push(_factory.createBcObj(  
1596 - oLp, "in", true, 1,  
1597 - oEndBc.getArrTimeObj(),  
1598 - _paramObj  
1599 - ));  
1600 - aOtherBc.push(_factory.createBcObj(  
1601 - oLp, "lc", true, 1,  
1602 - oEndBc.getArrTimeObj(),  
1603 - _paramObj  
1604 - ));  
1605 -  
1606 -  
1607 - } else {  
1608 - // 2个车次链以上,暂时没有此班型  
1609 - }  
1610 -  
1611 - oLp.addOtherBcArray(aOtherBc);  
1612 - }  
1613 - },  
1614 -  
1615 - /**  
1616 - * 祛除上标线开头的删除标记的班次。  
1617 - */  
1618 - fnRemoveDelFirstFlagBc: function() {  
1619 - var oLp = _internalLpArray[0];  
1620 - var aMinBcIndex = oLp.getMinBcObjPosition();  
1621 - if (oLp.getBc(aMinBcIndex[0], aMinBcIndex[1]).fnIsDelFlag()) {  
1622 - oLp.removeBc(aMinBcIndex[0], aMinBcIndex[1]);  
1623 - }  
1624 - },  
1625 - /**  
1626 - * 祛除上标线结尾的删除标记的班次。  
1627 - */  
1628 - fnRemoveDelLastFlagBc: function() {  
1629 - var oLp = _internalLpArray[0];  
1630 - var aMaxBcIndex = oLp.getMaxBcObjPosition();  
1631 - if (oLp.getBc(aMaxBcIndex[0], aMaxBcIndex[1]).fnIsDelFlag()) {  
1632 - oLp.removeBc(aMaxBcIndex[0], aMaxBcIndex[1]);  
1633 - }  
1634 - },  
1635 -  
1636 - /**  
1637 - * 调整路牌班次间隔(核准周转时间,停站时间)。  
1638 - * @param iFre int 迭代次数  
1639 - */  
1640 - fnAdjustLpBcInterval: function(iFre) {  
1641 - if (iFre > 0) {  
1642 - for (var i = 0; i < _internalLpArray.length; i++) {  
1643 - _internalLpArray[i].fnAdjustBcInterval(  
1644 - this.fnCalcuAverPeakStopTime(),  
1645 - this.fnCalcuAverTroughStopTime(),  
1646 - _paramObj);  
1647 - }  
1648 -  
1649 - this.fnAdjustLpBcInterval(iFre - 1);  
1650 - }  
1651 - },  
1652 -  
1653 - /**  
1654 - * 调整班次间隔。  
1655 - * @param bIsUp 是否上行  
1656 - * @param oStartTime 开始时间对象  
1657 - * @param iFre 迭代次数  
1658 - */  
1659 - fnAdjustBcInterval2_: function(bIsUp, oStartTime, iFre) {  
1660 - if (iFre > 0) {  
1661 - var aBc = _fnGetBcList2(bIsUp, oStartTime); // 指定方向的班次列表  
1662 - aBc.sort(function(o1, o2) {  
1663 - if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {  
1664 - return -1;  
1665 - } else {  
1666 - return 1;  
1667 - }  
1668 - });  
1669 - var i;  
1670 - var j;  
1671 -  
1672 - var iBcCountOfGroup = 3; // 3个班次取一次计算  
1673 - var aBcOfGroup; // 3个班次列表  
1674 - var aBcIntervalOfGroup; // 班次间隔列表,如:3个班次,2个间隔  
1675 -  
1676 - for (i = 0; i <= aBc.length - iBcCountOfGroup; i++) {  
1677 - aBcOfGroup = [];  
1678 - aBcIntervalOfGroup = [];  
1679 - for (j = i; j < i + iBcCountOfGroup; j++) {  
1680 - aBcOfGroup.push(aBc[j]);  
1681 - }  
1682 -  
1683 - for (j = 0; j < aBcOfGroup.length; j++) {  
1684 - if (j < aBcOfGroup.length - 1) {  
1685 - aBcIntervalOfGroup.push(aBcOfGroup[j + 1].getFcTimeObj().diff(  
1686 - aBcOfGroup[j].getFcTimeObj(), "m"));  
1687 - }  
1688 - }  
1689 -  
1690 - if (aBcIntervalOfGroup[0] < 19) {  
1691 - aBcOfGroup[1].addMinuteToFcsj(1);  
1692 - } else if (aBcIntervalOfGroup[0] > 20) {  
1693 - aBcOfGroup[1].addMinuteToFcsj(-1);  
1694 - } else {  
1695 - if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {  
1696 - //continue;  
1697 - } else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {  
1698 - aBcOfGroup[1].addMinuteToFcsj(-1);  
1699 - } else {  
1700 - aBcOfGroup[1].addMinuteToFcsj(1);  
1701 - }  
1702 - }  
1703 -  
1704 - }  
1705 -  
1706 - this.fnAdjustBcInterval2(bIsUp, oStartTime, iFre - 1);  
1707 - }  
1708 - },  
1709 -  
1710 - /**  
1711 - * 调整班次间隔。  
1712 - * @param boolean isUp 是否上行  
1713 - * @param oStartTime 开始时间对象  
1714 - * @param fre int 迭代次数  
1715 - */  
1716 - fnAdjustBcInterval: function(isUp, oStartTime, fre) {  
1717 - if (fre > 0) {  
1718 - var aBc = !oStartTime ? _fnGetBcList(isUp) : _fnGetBcList2(isUp, oStartTime); // 指定方向的班次列表  
1719 -  
1720 - aBc.sort(function(o1, o2) {  
1721 - if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {  
1722 - return -1;  
1723 - } else {  
1724 - return 1;  
1725 - }  
1726 - });  
1727 -  
1728 - var i;  
1729 - var j;  
1730 -  
1731 - var iBcCountOfGroup = 3; // 3个班次取一次计算  
1732 - var aBcOfGroup; // 3个班次列表  
1733 - var aBcIntervalOfGroup; // 班次间隔列表,如:3个班次,2个间隔  
1734 - var oBcFcTime; // 班次发车时间  
1735 -  
1736 - for (i = 0; i <= aBc.length - iBcCountOfGroup; i++) {  
1737 - aBcOfGroup = [];  
1738 - aBcIntervalOfGroup = [];  
1739 - for (j = i; j < i + iBcCountOfGroup; j++) {  
1740 - aBcOfGroup.push(aBc[j]);  
1741 - }  
1742 -  
1743 - for (j = 0; j < aBcOfGroup.length; j++) {  
1744 - if (j < aBcOfGroup.length - 1) {  
1745 - aBcIntervalOfGroup.push(aBcOfGroup[j + 1].getFcTimeObj().diff(  
1746 - aBcOfGroup[j].getFcTimeObj(), "m"));  
1747 - }  
1748 - }  
1749 -  
1750 - // 判定规则  
1751 - oBcFcTime = aBcOfGroup[1].getFcTimeObj();  
1752 -  
1753 - // 第一个班次发车时间不动,根据间隔,调整中间一个班次  
1754 - // 如果3个班次2个间隔时间差1分钟,不调整  
1755 - // 如果第一个间隔大,调整第二个班次往前1分钟  
1756 - // 如果第二个间隔大,调整第二个班次往后1分钟  
1757 -  
1758 - if (_paramObj.isTroughBc(oBcFcTime) &&  
1759 - aBcIntervalOfGroup[0] > _paramObj.getTroughMaxFcjx()) {  
1760 - aBcOfGroup[1].addMinuteToFcsj(-1);  
1761 - }  
1762 -  
1763 - //else if (_paramObj.isMPeakBc(oBcFcTime) &&  
1764 - // aBcIntervalOfGroup[0] < _paramObj.getMPeakMinFcjx()) {  
1765 - // aBcOfGroup[1].addMinuteToFcsj(1);  
1766 - //} else if (_paramObj.isMPeakBc(oBcFcTime) &&  
1767 - // aBcIntervalOfGroup[0] > _paramObj.getMPeakMaxFcjx()) {  
1768 - // aBcOfGroup[1].addMinuteToFcsj(-1);  
1769 - //} else if (_paramObj.isEPeakBc(oBcFcTime) &&  
1770 - // aBcIntervalOfGroup[0] < _paramObj.getEPeakMinFcjx()) {  
1771 - // aBcOfGroup[1].addMinuteToFcsj(1);  
1772 - //} else if (_paramObj.isEPeakBc(oBcFcTime) &&  
1773 - // aBcIntervalOfGroup[0] > _paramObj.getEPeakMaxFcjx()) {  
1774 - // aBcOfGroup[1].addMinuteToFcsj(-1);  
1775 - //}  
1776 -  
1777 -  
1778 - else {  
1779 - if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {  
1780 - //continue;  
1781 - } else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {  
1782 - aBcOfGroup[1].addMinuteToFcsj(-1);  
1783 - } else {  
1784 - aBcOfGroup[1].addMinuteToFcsj(1);  
1785 - }  
1786 - }  
1787 -  
1788 - //if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {  
1789 - // //continue;  
1790 - //} else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {  
1791 - // aBcOfGroup[1].addMinuteToFcsj(-1);  
1792 - //} else {  
1793 - // aBcOfGroup[1].addMinuteToFcsj(1);  
1794 - //}  
1795 -  
1796 -  
1797 - }  
1798 -  
1799 - this.fnAdjustBcInterval(isUp, oStartTime, fre - 1);  
1800 - }  
1801 -  
1802 - },  
1803 -  
1804 - /**  
1805 - * 调整班次间隔(平均间隔)。  
1806 - * @param bIsUp 是否上行  
1807 - * @param oStartTime 开始时间对象  
1808 - */  
1809 - fnAdjustBcInterval2_avg: function(bIsUp, oStartTime) {  
1810 - var aBc = !oStartTime ? _fnGetBcList(bIsUp) : _fnGetBcList2(bIsUp, oStartTime); // 指定方向的班次列表  
1811 - aBc.sort(function(o1, o2) {  
1812 - if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {  
1813 - return -1;  
1814 - } else {  
1815 - return 1;  
1816 - }  
1817 - });  
1818 -  
1819 - var j;  
1820 - var iCount = aBc.length - 1;  
1821 - var iC1 = Math.floor(aBc[aBc.length - 1].getFcTimeObj().diff(aBc[0].getFcTimeObj(), "m") / iCount);  
1822 - var iC2 = aBc[aBc.length - 1].getFcTimeObj().diff(aBc[0].getFcTimeObj(), "m") % iCount;  
1823 - var iTempTime;  
1824 -  
1825 - for (j = 0; j < iCount - iC2; j++) {  
1826 - iTempTime = aBc[j + 1].getFcTimeObj().diff(aBc[j].getFcTimeObj(), "m");  
1827 - aBc[j + 1].addMinuteToFcsj(iC1 - iTempTime);  
1828 - }  
1829 - for (j = 0; j < iC2; j++) {  
1830 - iTempTime = aBc[iCount - iC2 + j + 1].getFcTimeObj().diff(aBc[iCount - iC2 + j].getFcTimeObj(), "m");  
1831 - aBc[iCount - iC2 + j + 1].addMinuteToFcsj(iC1 + 1 - iTempTime);  
1832 - }  
1833 -  
1834 - },  
1835 -  
1836 - /**  
1837 - * 计算高峰平均停站时间。  
1838 - */  
1839 - fnCalcuAverPeakStopTime: function() {  
1840 - var i;  
1841 - var j;  
1842 - var aBc;  
1843 - var iBcCount = 0;  
1844 - var iSum = 0;  
1845 - for (i = 0; i < _internalLpArray.length; i++) {  
1846 - aBc = _internalLpArray[i].getBcArray();  
1847 -  
1848 - for (j = 0; j < aBc.length; j++) {  
1849 - if (!_paramObj.isTroughBc(aBc[j].getArrTimeObj())) {  
1850 - iBcCount ++;  
1851 - iSum += aBc[j].getStopTime();  
1852 - }  
1853 - }  
1854 - }  
1855 -  
1856 - return Math.floor(iSum / iBcCount);  
1857 - },  
1858 -  
1859 - /**  
1860 - * 计算低谷平均停站时间。  
1861 - */  
1862 - fnCalcuAverTroughStopTime: function() {  
1863 - var i;  
1864 - var j;  
1865 - var aBc;  
1866 - var iBcCount = 0;  
1867 - var iSum = 0;  
1868 - for (i = 0; i < _internalLpArray.length; i++) {  
1869 - aBc = _internalLpArray[i].getBcArray();  
1870 - for (j = 0; j < aBc.length; j++) {  
1871 - if (_paramObj.isTroughBc(aBc[j].getArrTimeObj())) {  
1872 - iBcCount ++;  
1873 - iSum += aBc[j].getStopTime();  
1874 - }  
1875 - }  
1876 - }  
1877 -  
1878 - return Math.floor(iSum / iBcCount);  
1879 - },  
1880 -  
1881 - //------------- 其他方法 -------------//  
1882 - /**  
1883 - * 内部数据转化成显示用的班次数组。  
1884 - */  
1885 - fnToGanttBcArray: function() {  
1886 - var aAllBc = [];  
1887 - var aLpBc = [];  
1888 - var aEatBc = [];  
1889 - var oLp;  
1890 - var i;  
1891 - var j;  
1892 -  
1893 - for (i = 0; i < _internalLpArray.length; i++) {  
1894 - oLp = _internalLpArray[i];  
1895 - aLpBc = [];  
1896 - aLpBc = aLpBc.concat(oLp.getOtherBcArray(), oLp.getBcArray());  
1897 -  
1898 - aEatBc = [];  
1899 - // 根据班次的吃饭时间添加吃饭班次  
1900 - for (j = 0; j < aLpBc.length; j++) {  
1901 - if (aLpBc[j].fnGetEatTime() > 0) {  
1902 - aEatBc.push(_factory.createBcObj(  
1903 - oLp,  
1904 - "cf",  
1905 - !aLpBc[j].isUp(), // 和上一个班次方向相反  
1906 - 1,  
1907 - _paramObj.addMinute(aLpBc[j].getArrTimeObj(), aLpBc[j].getStopTime()), // 使用上一个班次的到达时间作为开始时间  
1908 - _paramObj  
1909 - ));  
1910 - }  
1911 - }  
1912 - aLpBc = aLpBc.concat(aEatBc);  
1913 -  
1914 - // 按照发车时间排序  
1915 - aLpBc.sort(function(o1, o2) {  
1916 - if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {  
1917 - return -1;  
1918 - } else {  
1919 - return 1;  
1920 - }  
1921 - });  
1922 -  
1923 - // 重新赋值fcno  
1924 - for (j = 0; j < aLpBc.length; j++) {  
1925 - aLpBc[j].fnSetFcno(j + 1);  
1926 - }  
1927 -  
1928 - aAllBc = aAllBc.concat(aLpBc);  
1929 - }  
1930 -  
1931 - var aGanttBc = [];  
1932 - for (i = 0; i < aAllBc.length; i++) {  
1933 - aGanttBc.push(aAllBc[i].toGanttBcObj());  
1934 - }  
1935 -  
1936 - return aGanttBc;  
1937 - }  
1938 -  
1939 - }; 1 +/**
  2 + * 内部行车计划对象。
  3 + * @constructor
  4 + */
  5 +var InternalScheduleObj = function(paramObj, lpArray, factory) {
  6 + // 参数对象
  7 + var _paramObj = paramObj;
  8 + // 外部的路牌数组
  9 + var _lpArray = lpArray;
  10 + // 工厂对象
  11 + var _factory = factory;
  12 +
  13 + //------------------ 初始化方法1,以及计算关联的内部变量 -----------------//
  14 + var _qIsUp; // 每一圈是上行开始还是下行开始
  15 + var _qCount = 0; // 总的圈数
  16 + var _internalLpArray = []; // 内部对象数组
  17 + var _aBxDesc = [ // 各种班型描述(班型名称,平均工时,平均需要的班次数,平均工时)
  18 + {'sType':'六工一休', 'fHoursV':6.66, 'fBcCount': 0, 'fAverTime': 0},
  19 + {'sType':'五工一休', 'fHoursV':6.85, 'fBcCount': 0, 'fAverTime': 0},
  20 + {'sType':'四工一休', 'fHoursV':7.14, 'fBcCount': 0, 'fAverTime': 0},
  21 + {'sType':'三工一休', 'fHoursV':7.61, 'fBcCount': 0, 'fAverTime': 0},
  22 + {'sType':'二工一休', 'fHoursV':8.57, 'fBcCount': 0, 'fAverTime': 0},
  23 + {'sType':'一工一休', 'fHoursV':11.42, 'fBcCount': 0, 'fAverTime': 0},
  24 + {'sType':'五工二休', 'fHoursV':7.99, 'fBcCount': 0, 'fAverTime': 0},
  25 + {'sType':'无工休', 'fHoursV':5.43, 'fBcCount': 0, 'fAverTime': 0}
  26 + ];
  27 +
  28 + var _fnInitFun1 = function() { // 初始化方法1
  29 + console.log("//---------------- 行车计划,初始化方法1 start ----------------//");
  30 +
  31 + //----------------------- 1、确定上标线的方向,圈的方向 -------------------//
  32 +
  33 + // 确定_qIsUp,哪个方向的首班车晚就用哪个
  34 + _qIsUp = _paramObj.getUpFirstDTimeObj().isBefore(
  35 + _paramObj.getDownFirstDTimeObj()) ? false : true;
  36 + // 上标线开始时间,就是方向的首班车时间
  37 + var st = _qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();
  38 + // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向
  39 + var et;
  40 + var et_IsUp;
  41 + if (_paramObj.getUpLastDtimeObj().isBefore(
  42 + _paramObj.getDownLastDTimeObj())) {
  43 + et = _paramObj.getDownLastDTimeObj();
  44 + et_IsUp = false;
  45 + } else {
  46 + et = _paramObj.getUpLastDtimeObj();
  47 + et_IsUp = true;
  48 + }
  49 +
  50 + //------------------------ 2、计算总共有多少圈 ------------------------//
  51 +
  52 + // 以开始时间,结束时间,构造上标线用连班班次发车时间
  53 + var bcFcsjArrays = []; // 班次发车时间对象数组
  54 + var bcArsjArrays = []; // 班次到达时间对象数组
  55 + var isUp = _qIsUp; // 方向
  56 + var bcCount = 1; // 班次数
  57 +
  58 + var _kssj = st; // 开始时间
  59 + var _bcsj = paramObj.calcuTravelTime(_kssj, isUp); // 班次历时
  60 + var _arrsj = paramObj.addMinute(_kssj, _bcsj); // 到达时间
  61 + var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, _bcsj); // 停站时间
  62 +
  63 + do {
  64 + bcFcsjArrays.push(_kssj);
  65 + bcArsjArrays.push(_arrsj);
  66 +
  67 + _kssj = paramObj.addMinute(_kssj, _bcsj + _stoptime);
  68 + _bcsj = paramObj.calcuTravelTime(_kssj, isUp);
  69 + _arrsj = paramObj.addMinute(_kssj, _bcsj);
  70 + _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, _bcsj);
  71 +
  72 + bcCount ++;
  73 + isUp = !isUp;
  74 + } while(_kssj.isBefore(et));
  75 + bcCount--; // 因为先做do,所以总的班次要减1
  76 + //if (bcCount > 0 && bcArsjArrays[bcCount - 1].isAfter(et)) {
  77 + // // 如果最后一个班次的到达时间超过结束时间,也要去除
  78 + // bcFcsjArrays.splice(bcCount - 1, 1);
  79 + // bcArsjArrays.splice(bcCount - 1, 1);
  80 + // bcCount--;
  81 + //}
  82 + var _qCount_p1 = Math.floor(bcCount / 2); // 2个班次一圈
  83 + var _qCount_p2 = bcCount % 2; // 余下的1个班次也算一圈
  84 +
  85 + // 利用连班数组计算圈数
  86 + _qCount = 1; // 前面加1圈,补中标线的班次
  87 + _qCount += _qCount_p1;
  88 + _qCount += _qCount_p2;
  89 +
  90 + // 计算最后是不是还要补一圈
  91 + if (_qCount > 1) { // 总的圈数就1圈,没必要加了(其实是不可能的,除非参数里问题)
  92 + if (_qCount_p2 == 0) { // 没有余下班次,整数圈数
  93 + // 最后一个班次的方向一定和开始的方向相反,如:上-下,上-下,上-下,一共三圈,最后一个班次为下行
  94 + // 判定最后一个班次的方向和上标线判定结束时间的班次方向是否一致
  95 + if (!_qIsUp == et_IsUp) {
  96 + // 一致不用加圈数
  97 + } else {
  98 + // 不一致需要加圈补最后一个结束时间班次
  99 + _qCount ++;
  100 + }
  101 + } else {
  102 + // 有余下的圈数,最后要不补的班次不管上行,下行都在这一圈里
  103 + // 不需要在补圈数了
  104 + }
  105 + }
  106 +
  107 + //------------------------ 3、根据路牌数,圈数创建路牌对象 ----------------------//
  108 +
  109 + // 创建内部的路牌数组,并把之前的连班路牌添加进上标线路牌中
  110 + var i;
  111 + for (i = 0; i < _lpArray.length; i++) {
  112 + _internalLpArray.push(new InternalLpObj(_lpArray[i], _qCount, _qIsUp));
  113 + }
  114 + // 初始化上标线,从第1圈开始
  115 + _internalLpArray[0].initDataFromTimeToTime(bcFcsjArrays[0], et, _qIsUp, 1, _paramObj, _factory);
  116 +
  117 + // 以上标线为基础,计算各种班型工时对应的圈数、班次数
  118 + var aBcArray = _internalLpArray[0].getBcArray();
  119 + aBcArray[0].fnSetIsFirstBc(true); // 设置首班班次标识
  120 +
  121 + if (aBcArray.length % 2 != 0) { // 不能整除2,去除一个班次计算
  122 + aBcArray.splice(aBcArray.length - 1, 1);
  123 + }
  124 +
  125 + // 午饭吃饭时间
  126 + var iLTime = _paramObj.fnGetLunchTime();
  127 + // 晚饭吃饭时间
  128 + var iDTime = _paramObj.fnGetDinnerTime();
  129 + // 出场时间
  130 + var iOutTime = _qIsUp ? _paramObj.getUpOutTime() : _paramObj.getDownOutTime();
  131 + // 进场时间
  132 + var iInTime = _qIsUp ? _paramObj.getDownInTime() : _paramObj.getUpInTime();
  133 + // 例保时间
  134 + var iBTime = _paramObj.getLbTime();
  135 +
  136 + var sum = 0; // 总班次时间
  137 + for (i = 0; i < aBcArray.length; i++) {
  138 + sum += aBcArray[i].getBcTime() + aBcArray[i].getStopTime();
  139 + }
  140 + sum += iLTime; // 加午饭时间
  141 + sum += iDTime; // 加晚饭时间
  142 + for (i = 0; i < _aBxDesc.length; i++) {
  143 + _aBxDesc[i].fAverTime = sum / (aBcArray.length / 2); // 平均周转时间不算进出场,例保时间
  144 +
  145 + // 计算5休2的班次数(双进出场,4个例保)
  146 + if (i == 6) {
  147 + _aBxDesc[i].fQCount =
  148 + (_aBxDesc[i].fHoursV * 60 - iOutTime * 2 - iInTime * 2 - iBTime * 4) /
  149 + _aBxDesc[i].fAverTime;
  150 + _aBxDesc[i].fBcCount = _aBxDesc[i].fQCount * 2;
  151 + } else { // 进出场,2个例保
  152 + _aBxDesc[i].fQCount =
  153 + (_aBxDesc[i].fHoursV * 60 - iOutTime - iInTime - iBTime * 2) /
  154 + _aBxDesc[i].fAverTime;
  155 + _aBxDesc[i].fBcCount = _aBxDesc[i].fQCount * 2;
  156 + }
  157 + }
  158 +
  159 +
  160 + // 在第一个班次之前再添加一个模拟班次,用于中标线的作用
  161 + // 那一圈必定是低谷,而且圈索引0,班次索引1,暂时标记,最后删除
  162 + var iFirstStopTime =
  163 + _paramObj.fnCalcuFixedStopNumber(
  164 + _paramObj.addMinute(aBcArray[0].getFcTimeObj(), -10),
  165 + _qIsUp
  166 + );
  167 + var iXXTime = _qIsUp ? _paramObj.getDownTroughTime() : _paramObj.getUpTroughTime();
  168 + var oFlagBc = _factory.createBcObj( // 标记班次
  169 + _internalLpArray[0],
  170 + "normal",
  171 + !_qIsUp,
  172 + 1,
  173 + _paramObj.addMinute(aBcArray[0].getFcTimeObj(), -(iFirstStopTime + iXXTime)),
  174 + _paramObj
  175 + );
  176 + oFlagBc.fnSetDelFlag(true); // 标记了删除记号
  177 +
  178 + _internalLpArray[0].setBc(0, 1, oFlagBc);
  179 +
  180 + // 在最后一圈也补上一个或者2个模拟班次,暂时标记,最后需要删除
  181 + var aMaxBcIndex = _internalLpArray[0].getMaxBcObjPosition();
  182 + if (aMaxBcIndex[0] == _qCount - 1) { // 可能加半圈
  183 + oFlagBc = _factory.createBcObj( // 标记班次
  184 + _internalLpArray[0],
  185 + "normal",
  186 + !_qIsUp,
  187 + 1,
  188 + _paramObj.addMinute(
  189 + _internalLpArray[0].getBc(_qCount - 1, 0).getArrTimeObj(),
  190 + _internalLpArray[0].getBc(_qCount - 1, 0).getStopTime()),
  191 + _paramObj
  192 + );
  193 + oFlagBc.fnSetDelFlag(true); // 标记了删除记号
  194 + _internalLpArray[0].setBc(_qCount - 1, 1, oFlagBc);
  195 +
  196 + } else { // 加完整的一圈
  197 + oFlagBc = _factory.createBcObj( // 标记班次
  198 + _internalLpArray[0],
  199 + "normal",
  200 + _qIsUp,
  201 + 1,
  202 + _paramObj.addMinute(
  203 + _internalLpArray[0].getBc(_qCount - 2, 1).getArrTimeObj(),
  204 + _internalLpArray[0].getBc(_qCount - 2, 1).getStopTime()),
  205 + _paramObj
  206 + );
  207 + oFlagBc.fnSetDelFlag(true); // 标记了删除记号
  208 + _internalLpArray[0].setBc(_qCount - 1, 0, oFlagBc);
  209 +
  210 + oFlagBc = _factory.createBcObj( // 标记班次
  211 + _internalLpArray[0],
  212 + "normal",
  213 + !_qIsUp,
  214 + 1,
  215 + _paramObj.addMinute(
  216 + _internalLpArray[0].getBc(_qCount - 1, 0).getArrTimeObj(),
  217 + _internalLpArray[0].getBc(_qCount - 1, 0).getStopTime()),
  218 + _paramObj
  219 + );
  220 + oFlagBc.fnSetDelFlag(true); // 标记了删除记号
  221 + _internalLpArray[0].setBc(_qCount - 1, 1, oFlagBc);
  222 +
  223 + }
  224 +
  225 + console.log("上行首班车时间:" + _paramObj.getUpFirstDTimeObj().format("HH:mm") +
  226 + "上行末班车时间:" + _paramObj.getUpLastDtimeObj().format("HH:mm"));
  227 + console.log("下行首班车时间:" + _paramObj.getDownFirstDTimeObj().format("HH:mm") +
  228 + "下行末班车时间:" + _paramObj.getDownLastDTimeObj().format("HH:mm"));
  229 + console.log("总共计算的圈数:" + _qCount);
  230 + console.log("圈的方向isUP:" + _qIsUp);
  231 + console.log("班型描述(以下):");
  232 + console.log(_aBxDesc);
  233 + console.log("所有路牌间隔描述(以下):");
  234 + for (i = 0; i < _internalLpArray.length; i++) {
  235 + console.log(_internalLpArray[i]._$_aVerticalIntervalTime);
  236 + }
  237 + console.log("//---------------- 行车计划,初始化方法1 end ----------------//");
  238 +
  239 + };
  240 +
  241 + //------------------ 初始化方法2,以及计算关联的内部变量 ----------------//
  242 + var _approximate_zgfQIndex; // 预估早高峰车辆从第几圈开始全部发出
  243 + var _approximate_zgfBIndex; // 预估早高峰车辆从第几圈第几个班次开始全部发出(上行或下行)
  244 + var _approximate_wgfQIndex; // 预估晚高峰车辆从第几圈开始全部发出
  245 + var _approximate_wgfBIndex; // 预估晚高峰车辆从第几圈第几个班次开始全部发出(上行或下行)
  246 +
  247 + var _fnInitFun2 = function() { // 初始化方法2
  248 + console.log("//---------------- 行车计划,初始化方法2 start ----------------//");
  249 +
  250 + //------------------------ 1、计算车辆总数 ------------------------//
  251 + // 是用高峰上行周转时间除以高峰平均间隔得到的
  252 + // 这样算还算合理,车辆不多不少,待以后有新的算法再修正
  253 + var iClCount = _paramObj.calcuClzx();
  254 +
  255 + //------------------------ 2、计算所有路牌的发车在各个圈中的间隔 --------------------//
  256 + var i;
  257 + var j;
  258 + var iBindex = 1;
  259 + var iZzsj;
  260 + var oLp;
  261 + var iC1;
  262 + var iC2;
  263 +
  264 + for (i = 0; i < _qCount - 1; i++) {
  265 + while (iBindex <= 1) {
  266 + // 每圈每个方向的周转时间不一致,以上标线为主
  267 + oLp = _internalLpArray[0];
  268 + iZzsj = oLp.getBc(i + 1, iBindex).getFcTimeObj().diff(
  269 + oLp.getBc(i, iBindex).getFcTimeObj(), "m"
  270 + );
  271 +
  272 + iC1 = Math.floor(iZzsj / iClCount);
  273 + iC2 = iZzsj % iClCount;
  274 +
  275 + for (j = 0; j < iClCount - iC2; j++) {
  276 + oLp = _internalLpArray[j];
  277 + oLp.fnSetVerticalIntervalTime(i, iBindex, iC1);
  278 + }
  279 +
  280 + for (j = 0; j < iC2; j++) {
  281 + oLp = _internalLpArray[iClCount - iC2 + j];
  282 + oLp.fnSetVerticalIntervalTime(i, iBindex, iC1 + 1);
  283 + }
  284 +
  285 + iBindex ++;
  286 +
  287 + }
  288 + iBindex = 0;
  289 + }
  290 + // 最后一圈没有下一圈的参照,周转时间没发获取,由于都是低谷,所以使用倒数第二圈的间隔最为最后一圈的间隔
  291 + for (i = 0; i < _internalLpArray.length; i++) {
  292 + oLp = _internalLpArray[i];
  293 + oLp.fnSetVerticalIntervalTime(_qCount - 1, 0, oLp.fnGetVerticalIntervalTime(_qCount - 2, 0));
  294 + oLp.fnSetVerticalIntervalTime(_qCount - 1, 1, oLp.fnGetVerticalIntervalTime(_qCount - 2, 1));
  295 + }
  296 +
  297 + //------------------------ 3、预估早高峰全部出车第几圈第几个班次全部出车,计算路牌之间的发车间隔 ------------------//
  298 +
  299 + // 以上标线为标准,查找离早高峰开始时间最近的班次作为早高峰开始班次
  300 + // 以这个班次为早高峰起点,全部出车策略
  301 + var qbcIndexArray = _internalLpArray[0].getQBcIndexWithFcTime(
  302 + _paramObj.getMPeakStartTimeObj(), true, true);
  303 + var qIndex = qbcIndexArray[0]; // 第几圈
  304 + var bIndex = qbcIndexArray[1]; // 第几个班次
  305 +
  306 + for (i = 1; i < _internalLpArray.length; i++) {
  307 + _fnGenerateBcAndSetBc(i, qIndex, bIndex);
  308 + }
  309 +
  310 + _approximate_zgfQIndex = qIndex;
  311 + _approximate_zgfBIndex = bIndex;
  312 +
  313 + //------------------------ 4、预估晚高峰全部出车第几圈第几个班次全部出车,计算路牌之间的发车间隔 ------------------//
  314 +
  315 + // 以上标线为标准,查找离晚高峰开始时间最近的班次作为晚高峰开始班次
  316 + // 以这个班次为早高峰起点,全部出车策略
  317 + qbcIndexArray = _internalLpArray[0].getQBcIndexWithFcTime(
  318 + _paramObj.getEPeakStartTimeObj(), true, true);
  319 + qIndex = qbcIndexArray[0]; // 第几圈
  320 + bIndex = qbcIndexArray[1]; // 第几个班次
  321 +
  322 + for (i = 1; i < _internalLpArray.length; i++) {
  323 + _fnGenerateBcAndSetBc(i, qIndex, bIndex);
  324 + }
  325 +
  326 + _approximate_wgfQIndex = qIndex;
  327 + _approximate_wgfBIndex = bIndex;
  328 +
  329 + console.log("早高峰周转时间(固定最大停战时间):" + _paramObj.calcuPeakZzsj() + "分钟");
  330 + console.log("早高峰发车时间范围:" + _paramObj.getMPeakMinFcjx() + "分钟 --- " + _paramObj.getMPeakMaxFcjx() + "分钟");
  331 + console.log("预估早高峰第" + _approximate_zgfQIndex + "(index)圈,第" + _approximate_zgfBIndex + "(index)班次车辆全部发出");
  332 + console.log("预估晚高峰第" + _approximate_wgfQIndex + "(index)圈,第" + _approximate_wgfBIndex + "(index)班次车辆全部发出");
  333 + console.log("//---------------- 行车计划,初始化方法2 end ----------------//");
  334 + };
  335 +
  336 + //----------------------- 初始化方法3,计算连班分班的路牌分布 ----------------//
  337 + var _iBx_lb_lpcount; // 连班路牌数
  338 + var _iBx_5_2_fb_lpcount; // 5休2分班路牌数
  339 + var _iBx_other_fb_lpcount; // 其他分班路牌数
  340 +
  341 + var _fnInitFun3 = function() { // 初始化方法3
  342 + console.log("//---------------- 行车计划,初始化方法3 start ----------------//");
  343 +
  344 + //--------------------- 1、计算分班连班班型车辆分布数 --------------------//
  345 + // 总共车辆数(高峰最大车辆数)
  346 + var iCls = _paramObj.calcuClzx();
  347 + // 低谷最少配车(连班车数量)
  348 + var iDgminpc = Math.round(_paramObj.calcuTroughZzsj() / _paramObj.getTroughMaxFcjx());
  349 + // 加班车路牌数(做5休2的路牌数)
  350 + var i_5_2_lpes = _paramObj.getJBLpes();
  351 +
  352 + // 做些简单的验证
  353 + if (iCls < iDgminpc) {
  354 + alert("总配车数小于低谷最小配车");
  355 + throw "总配车数小于低谷最小配车";
  356 + }
  357 + if (iDgminpc < 2) {
  358 + alert("连班路牌小于2,办不到啊");
  359 + throw "连班路牌小于2,办不到啊";
  360 + }
  361 + if (iCls - iDgminpc < i_5_2_lpes) {
  362 + alert("总分班路牌数小于加班路牌数");
  363 + throw "总分班路牌数小于加班路牌数";
  364 + }
  365 +
  366 + //// 修正连班路牌数,班次间隔大于20的,加1,直至班次间隔小于20
  367 + //while(_paramObj.calcuPeakZzsj() / iDgminpc > 20) {
  368 + // iDgminpc ++;
  369 + //}
  370 + _iBx_lb_lpcount = iDgminpc;
  371 +
  372 + _iBx_5_2_fb_lpcount = i_5_2_lpes;
  373 + _iBx_other_fb_lpcount = iCls - _iBx_lb_lpcount - i_5_2_lpes;
  374 +
  375 + //------------------------ 2、利用间隔法计算连班路牌分布 --------------------//
  376 + var i;
  377 + var j;
  378 + var iC1 = Math.floor(_internalLpArray.length / _iBx_lb_lpcount);
  379 + var iC2 = _internalLpArray.length % _iBx_lb_lpcount;
  380 + var iLpIndex;
  381 +
  382 + for (i = 0; i < _iBx_lb_lpcount - iC2; i++) {
  383 + iLpIndex = i * iC1;
  384 + _internalLpArray[iLpIndex].setBxLb(true);
  385 + _internalLpArray[iLpIndex].setBxDesc("连班");
  386 + }
  387 + for (j = 0; j < iC2; j++) {
  388 + iLpIndex = i * iC1 + j * (iC1 + 1);
  389 + _internalLpArray[iLpIndex].setBxLb(true);
  390 + _internalLpArray[iLpIndex].setBxDesc("连班");
  391 + }
  392 +
  393 + //------------------------ 3、利用间隔法计算分班班型路牌分布 --------------------//
  394 + // 获取分班路牌索引
  395 + var aNotLbIndexes = [];
  396 + for (i = 0; i < _internalLpArray.length; i++) {
  397 + if (!_internalLpArray[i].isBxLb()) {
  398 + aNotLbIndexes.push(i);
  399 + }
  400 + }
  401 + // 先5休2分班
  402 + iC1 = Math.floor(aNotLbIndexes.length / _iBx_5_2_fb_lpcount);
  403 + iC2 = aNotLbIndexes.length % _iBx_5_2_fb_lpcount;
  404 +
  405 + for (i = 0; i < _iBx_5_2_fb_lpcount - iC2; i++) {
  406 + iLpIndex = aNotLbIndexes[i * iC1];
  407 + _internalLpArray[iLpIndex].setBxLb(false);
  408 + _internalLpArray[iLpIndex].setBxFb(true);
  409 + _internalLpArray[iLpIndex].setBxFb5_2(true);
  410 + _internalLpArray[iLpIndex].setBxDesc("5休2分班");
  411 + }
  412 + for (i = 0; i < iC2; i++) {
  413 + iLpIndex = aNotLbIndexes[_iBx_5_2_fb_lpcount - iC2 + i * (iC1 + 1)];
  414 + _internalLpArray[iLpIndex].setBxLb(false);
  415 + _internalLpArray[iLpIndex].setBxFb(true);
  416 + _internalLpArray[iLpIndex].setBxFb5_2(true);
  417 + _internalLpArray[iLpIndex].setBxDesc("5休2分班");
  418 + }
  419 + // 其他分班
  420 + for (i = 0; i < aNotLbIndexes.length; i++) {
  421 + iLpIndex = aNotLbIndexes[i];
  422 + if (!_internalLpArray[iLpIndex].isBxFb5_2()) {
  423 + _internalLpArray[iLpIndex].setBxLb(false);
  424 + _internalLpArray[iLpIndex].setBxFb(true);
  425 + _internalLpArray[iLpIndex].setBxFb5_2(false);
  426 + _internalLpArray[iLpIndex].setBxDesc("其他分班");
  427 + }
  428 + }
  429 +
  430 + console.log("高峰周转时间:" + _paramObj.calcuPeakZzsj());
  431 + console.log("连班路牌数:" + _iBx_lb_lpcount);
  432 + console.log("5休2分班路牌数:" + _iBx_5_2_fb_lpcount);
  433 + console.log("其他分班路牌数:" + _iBx_other_fb_lpcount);
  434 + var aLbIndexes = [];
  435 + for (i = 0; i < _internalLpArray.length; i++) {
  436 + if (_internalLpArray[i].isBxLb()) {
  437 + aLbIndexes.push(i);
  438 + }
  439 + }
  440 + console.log("连班路牌indexes=" + aLbIndexes);
  441 + var a_5_2_fbIndexes = [];
  442 + for (i = 0; i < _internalLpArray.length; i++) {
  443 + if (_internalLpArray[i].isBxFb() && _internalLpArray[i].isBxFb5_2()) {
  444 + a_5_2_fbIndexes.push(i);
  445 + }
  446 + }
  447 + console.log("5休2分班路牌indexes=" + a_5_2_fbIndexes);
  448 + var a_other_fbIndexes = [];
  449 + for (i = 0; i < _internalLpArray.length; i++) {
  450 + if (_internalLpArray[i].isBxFb() && !_internalLpArray[i].isBxFb5_2()) {
  451 + a_other_fbIndexes.push(i);
  452 + }
  453 + }
  454 + console.log("其他分班路牌indexes=" + a_other_fbIndexes);
  455 +
  456 + console.log("//---------------- 行车计划,初始化方法3 end ----------------//");
  457 + };
  458 +
  459 + //----------------------- 初始化方法4,计算中标线位置 -------------------------//
  460 + var _iZbx_lpIndex; // 中标线对应第几个路牌
  461 +
  462 + var _fnInitFun4 = function() { // 初始化方法4
  463 + console.log("//---------------- 行车计划,初始化方法4 start ----------------//");
  464 +
  465 + //---------------------------- 1、模拟一个中标线,使用临时路牌 ----------------------//
  466 + // 构造中标线
  467 + // 中标线开始时间,就是方向的首班车时间
  468 + var oSt = !_qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();
  469 + // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向
  470 + // 上标线结束时间,使用最晚的末班车时间,结束时间的班次方向
  471 + var oEt;
  472 + if (_paramObj.getUpLastDtimeObj().isBefore(
  473 + _paramObj.getDownLastDTimeObj())) {
  474 + oEt = _paramObj.getDownLastDTimeObj();
  475 + } else {
  476 + oEt = _paramObj.getUpLastDtimeObj();
  477 + }
  478 +
  479 + var oTempLp = new InternalLpObj({lpNo: -999, lpName: "-999"}, _qCount, _qIsUp);
  480 + oTempLp.initDataFromTimeToTime(
  481 + oSt,
  482 + oEt,
  483 + !_qIsUp,
  484 + 0,
  485 + _paramObj,
  486 + _factory
  487 + );
  488 +
  489 + //------------------------ 2、找出中标线的早高峰班次,计算应该插在当前路牌数组的那个位置 ----------------//
  490 + // 找出中标线对应的早高峰的班次对象
  491 + var oZb_gf_bc = oTempLp.getBc(_approximate_zgfQIndex, _approximate_zgfBIndex);
  492 + //alert(oZb_gf_bc.getFcTimeObj().format("HH:mm"));
  493 +
  494 + // 把所有连班路牌高峰班次重新构造成一个一个的圈数组,计算对应中标线最近的是第几个路牌
  495 + // 中标线和上标线一样在连班路牌上
  496 + var aTempq = [];
  497 + var oTempq;
  498 + var oTempb;
  499 + var i;
  500 + var oLp;
  501 +
  502 + var aLbIndexes = []; // 连班的路牌索引
  503 + for (i = 0; i < _internalLpArray.length; i++) {
  504 + if (_internalLpArray[i].isBxLb()) {
  505 + aLbIndexes.push(i);
  506 + }
  507 + }
  508 +
  509 + for (i = 0; i < aLbIndexes.length; i++) {
  510 + oLp = _internalLpArray[aLbIndexes[i]];
  511 +
  512 + oTempb = oLp.getBc(_approximate_zgfQIndex, _approximate_zgfBIndex);
  513 + if (oTempb.isUp() == _qIsUp) {
  514 + oTempq = new InternalGroupObj(oLp, _qIsUp, oTempb, undefined);
  515 + } else {
  516 + oTempq = new InternalGroupObj(oLp, _qIsUp, undefined, oTempb);
  517 + }
  518 + aTempq.push(oTempq);
  519 +
  520 + }
  521 +
  522 + var aTtindex = oTempLp.fnGetQBcIndexWithFcTimeFromGroupArray( // 找出最接近中标线的路牌索引
  523 + oZb_gf_bc.getFcTimeObj(),
  524 + aTempq,
  525 + true,
  526 + true
  527 + );
  528 +
  529 + _iZbx_lpIndex = aLbIndexes[aTtindex[0]]; // 中标线放在第几个路牌
  530 +
  531 + oTempLp.getMinBcObj().fnSetIsFirstBc(true); // 设置首班班次标识
  532 +
  533 + if (_iZbx_lpIndex == 0) { // 如果中标线和上标线一致
  534 + var oFirstBcIndexes = oTempLp.getMinBcObjPosition();
  535 + var oFirstBc = oTempLp.getMinBcObj();
  536 + oFirstBc.setLp(_internalLpArray[_iZbx_lpIndex]);
  537 + oFirstBc.fnSetDelFlag(false);
  538 + _internalLpArray[_iZbx_lpIndex].setBc(oFirstBcIndexes[0], oFirstBcIndexes[1], oFirstBc);
  539 + } else {
  540 + oTempLp.setLp(_lpArray[_iZbx_lpIndex]); // 设置原始路牌对象
  541 + oTempLp._$_aVerticalIntervalTime = _internalLpArray[_iZbx_lpIndex]._$_aVerticalIntervalTime; // 设置纵向最小发车间隔
  542 + oTempLp.setBxLb(_internalLpArray[_iZbx_lpIndex].isBxLb());
  543 + oTempLp.setBxFb(_internalLpArray[_iZbx_lpIndex].isBxFb());
  544 + oTempLp.setBxFb5_2(_internalLpArray[_iZbx_lpIndex].isBxFb5_2());
  545 +
  546 + // 修正除了第一个班次外,其余其他班次
  547 + var iBcindex = 0;
  548 + for (i = 1; i < _qCount; i++) {
  549 + while (iBcindex <= 1) {
  550 + if (oTempLp.getBc(i, iBcindex)) { // 替换存在的班次
  551 + oTempLp.setBc(i, iBcindex, _fnGenerateBc(_iZbx_lpIndex, i, iBcindex));
  552 + }
  553 + iBcindex ++;
  554 + }
  555 + iBcindex = 0;
  556 + }
  557 +
  558 + _internalLpArray[_iZbx_lpIndex] = oTempLp;
  559 + }
  560 +
  561 + console.log("中标线对应第" + (_iZbx_lpIndex + 1) + "个路牌");
  562 +
  563 + console.log("//---------------- 行车计划,初始化方法4 end ----------------//");
  564 + };
  565 +
  566 + //-------------------- 重要的内部方法 -----------------------//
  567 + /**
  568 + * 核心方法,利用路牌间隔纵向生成班次。
  569 + * @param iLpindex 路牌索引
  570 + * @param iQindex 圈索引
  571 + * @param iBcindex 班次索引
  572 + * @returns object InternalBcObj,失败 false
  573 + */
  574 + var _fnGenerateBc = function(iLpindex, iQindex, iBcindex) {
  575 + // 以上标线为起始点,使用路牌在不同圈,班次索引的发车间隔,计算班次
  576 + // 注意,发车间隔是指下一个班次应该距离当前班次间隔,是从下往上的
  577 +
  578 + // 1、参数验证
  579 + if (iLpindex == 0) { // 上标线的班次不需要生成
  580 + return false;
  581 + }
  582 +
  583 + // 2、计算间隔
  584 + var i;
  585 + var oLp;
  586 + var iTime = 0;
  587 + for (i = 0; i < iLpindex; i++) {
  588 + oLp = _internalLpArray[i];
  589 + iTime += oLp.fnGetVerticalIntervalTime(iQindex, iBcindex);
  590 + }
  591 +
  592 + // 3、生成班次
  593 + var _oKsbc = _internalLpArray[0].getBc(iQindex, iBcindex);
  594 + if (!_oKsbc) {
  595 + return false;
  596 + }
  597 + var _oKssj = _paramObj.addMinute(_oKsbc.getFcTimeObj(), iTime);
  598 + var _oBc = _factory.createBcObj(
  599 + _internalLpArray[iLpindex],
  600 + "normal", _oKsbc.isUp(),
  601 + 1, _oKssj, _paramObj);
  602 +
  603 + return _oBc;
  604 +
  605 + };
  606 +
  607 + /**
  608 + * 核心方法,在指定位置生成班次并添加到路牌指定位置中。
  609 + * @param lpIndex 第几个路牌
  610 + * @param qIndex 第几圈
  611 + * @param bcIndex 第几个班次
  612 + */
  613 + var _fnGenerateBcAndSetBc = function(lpIndex, qIndex, bcIndex) {
  614 + var _bcObj = _fnGenerateBc(lpIndex, qIndex, bcIndex);
  615 + if (_bcObj) {
  616 + _internalLpArray[lpIndex].setBc(qIndex, bcIndex, _bcObj);
  617 + }
  618 + };
  619 +
  620 + /**
  621 + * 获取班次列表。
  622 + * @param oIsUp 是否上行
  623 + * @param oStartTime 开始时间对象
  624 + * @returns [(InternalBcObj)]
  625 + */
  626 + var _fnGetBcList2 = function(oIsUp, oStartTime) {
  627 + var i;
  628 + var j;
  629 + var oLp;
  630 + var oBc;
  631 + var aBc = [];
  632 +
  633 + for (j = 0; j < _qCount; j++) {
  634 + for (i = 0; i < _internalLpArray.length; i++) {
  635 + oLp = _internalLpArray[i];
  636 + oBc = oLp.getBc(
  637 + j,
  638 + _qIsUp == oIsUp ? 0 : 1
  639 + );
  640 + if (oBc && oBc.getFcTimeObj().isAfter(oStartTime)) {
  641 + aBc.push(oBc);
  642 + }
  643 + }
  644 + }
  645 +
  646 + var aBcFcTime = [];
  647 + for (i = 0; i < aBc.length; i++) {
  648 + oBc = aBc[i];
  649 + aBcFcTime.push(oBc.getFcTimeObj().format("HH:mm"));
  650 + }
  651 + console.log((oIsUp ? "上行班次列表:" : "下行班次列表:") + aBcFcTime.join(","));
  652 +
  653 + return aBc;
  654 + };
  655 +
  656 + /**
  657 + * 获取班次列表。
  658 + * @param isUp boolean 是否上行
  659 + * @returns [(InternalBcObj)]
  660 + */
  661 + var _fnGetBcList = function(isUp) {
  662 + var i;
  663 + var j;
  664 + var oLp;
  665 + var oBc;
  666 + var aBc = [];
  667 +
  668 + for (j = 0; j < _qCount; j++) {
  669 + for (i = 0; i < _internalLpArray.length; i++) {
  670 + oLp = _internalLpArray[i];
  671 + oBc = oLp.getBc(
  672 + j,
  673 + _qIsUp == isUp ? 0 : 1
  674 + );
  675 + if (oBc) {
  676 + aBc.push(oBc);
  677 + }
  678 + }
  679 + }
  680 +
  681 + var aBcFcTime = [];
  682 + for (i = 0; i < aBc.length; i++) {
  683 + oBc = aBc[i];
  684 + aBcFcTime.push(oBc.getFcTimeObj().format("HH:mm"));
  685 + }
  686 + console.log((isUp ? "上行班次列表:" : "下行班次列表:") + aBcFcTime.join(","));
  687 +
  688 + return aBc;
  689 + };
  690 +
  691 + /**
  692 + * 查找离指定时间最近的前面的班次索引信息
  693 + * @param timeObj 查找时间
  694 + * @param isUp 是否上行
  695 + * @returns [{路牌index},{圈index},{班次index}]
  696 + */
  697 + var _fnFindUpClosedBcIndexWithTime = function(timeObj, isUp) {
  698 +
  699 + var _lpObj;
  700 + var _groupObj;
  701 + var _bcObj;
  702 + var _i;
  703 + var _j;
  704 + var timediff; // 时间差取绝对值
  705 +
  706 + var _lpIndex;
  707 + var _up_qIndex;
  708 + var _up_bIndex;
  709 +
  710 + for (_i = 0; _i < _qCount; _i++) {
  711 + for (_j = 0; _j < _internalLpArray.length; _j++) {
  712 + _lpObj = _internalLpArray[_j];
  713 + _groupObj = _lpObj.getGroup(_i);
  714 + _bcObj = isUp == _qIsUp ? _groupObj.getBc1() : _groupObj.getBc2();
  715 + if (!_bcObj) { // 没有班次动态生成一个,可能生成不出的
  716 + _bcObj = _fnGenerateBc(_j, _i, isUp == _qIsUp ? 0 : 1);
  717 + }
  718 + if (_bcObj) {
  719 + if (timeObj.diff(_bcObj.getFcTimeObj()) >= 0) {
  720 + if (!timediff) {
  721 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  722 + _lpIndex = _j;
  723 + _up_qIndex = _i;
  724 + _up_bIndex = isUp == _qIsUp ? 0 : 1;
  725 + } else {
  726 + if (timeObj.diff(_bcObj.getFcTimeObj()) < timediff) {
  727 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  728 + _lpIndex = _j;
  729 + _up_qIndex = _i;
  730 + _up_bIndex = isUp == _qIsUp ? 0 : 1;
  731 + }
  732 + }
  733 + }
  734 + }
  735 + }
  736 + }
  737 +
  738 + if (_lpIndex == undefined) {
  739 + return false;
  740 + }
  741 +
  742 + var bcindex = [];
  743 + bcindex.push(_lpIndex);
  744 + bcindex.push(_up_qIndex);
  745 + bcindex.push(_up_bIndex);
  746 +
  747 + return bcindex;
  748 + };
  749 +
  750 + /**
  751 + * 查找离指定时间最近的后面的班次索引信息
  752 + * @param timeObj 查找时间
  753 + * @param isUp 是否上行
  754 + * @returns [{路牌index},{圈index},{班次index}]
  755 + */
  756 + var _fnFindDownClosedBcIndexWithTime = function(timeObj, isUp) {
  757 + var _lpObj;
  758 + var _groupObj;
  759 + var _bcObj;
  760 + var _i;
  761 + var _j;
  762 + var timediff; // 时间差取绝对值
  763 +
  764 + var _lpIndex;
  765 + var _down_qIndex;
  766 + var _down_bIndex;
  767 +
  768 + var flag;
  769 +
  770 + for (_i = 0; _i < _qCount; _i++) {
  771 + for (_j = 0; _j < _internalLpArray.length; _j++) {
  772 + _lpObj = _internalLpArray[_j];
  773 + _groupObj = _lpObj.getGroup(_i);
  774 + // TODO:bug
  775 + _bcObj = isUp == _qIsUp ? _groupObj.getBc1() : _groupObj.getBc2();
  776 + if (!_bcObj) { // 没有班次动态生成一个,可能生成不出的
  777 + _bcObj = _fnGenerateBc(_j, _i, isUp == _qIsUp ? 0 : 1);
  778 + }
  779 + if (_bcObj) {
  780 + //console.log("timeobj -> bcobj diff flag " +
  781 + // timeObj.format("HH:mm") + "->" +
  782 + // _bcObj.getFcTimeObj().format("HH:mm") +
  783 + // timeObj.diff(_bcObj.getFcTimeObj()) +
  784 + // (timeObj.diff(_bcObj.getFcTimeObj()) <= 0)
  785 + //);
  786 +
  787 + flag = (timeObj.diff(_bcObj.getFcTimeObj())) <= 0;
  788 +
  789 + if (flag) {
  790 + if (!timediff) {
  791 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  792 + _lpIndex = _j;
  793 + _down_qIndex = _i;
  794 + _down_bIndex = isUp == _qIsUp ? 0 : 1;
  795 + } else {
  796 + if ((timeObj.diff(_bcObj.getFcTimeObj())) > timediff) {
  797 + timediff = timeObj.diff(_bcObj.getFcTimeObj());
  798 + _lpIndex = _j;
  799 + _down_qIndex = _i;
  800 + _down_bIndex = isUp == _qIsUp ? 0 : 1;
  801 + }
  802 + }
  803 + }
  804 + }
  805 + }
  806 + }
  807 +
  808 + if (_lpIndex == undefined) {
  809 + return false;
  810 + }
  811 +
  812 + var bcindex = [];
  813 + bcindex.push(_lpIndex);
  814 + bcindex.push(_down_qIndex);
  815 + bcindex.push(_down_bIndex);
  816 +
  817 + return bcindex;
  818 + };
  819 +
  820 + /**
  821 + * 获取班次索引。
  822 + * @param oBc 班次对象
  823 + * @returns [{路牌索引},{圈索引},{班次索引}]
  824 + */
  825 + var _fnGetBcIndex = function(oBc) {
  826 + // 路牌索引
  827 + var i;
  828 + var iLpIndex;
  829 + for (i = 0; i < _internalLpArray.length; i++) {
  830 + if (_internalLpArray[i]._$$_orign_lp_obj == oBc._$$_internal_lp_obj._$$_orign_lp_obj) {
  831 + iLpIndex = i;
  832 + break;
  833 + }
  834 + }
  835 + // 圈索引
  836 + var j;
  837 + var iGroupIndex;
  838 + var bFlag = false;
  839 + for (i = 0; i < _internalLpArray.length; i++) {
  840 + if (bFlag) {
  841 + break;
  842 + }
  843 + for (j = 0; j < _qCount; j++) {
  844 + if (_internalLpArray[i]._$_groupBcArray[j] == oBc._$$_internal_group_obj) {
  845 + iGroupIndex = j;
  846 + bFlag = true;
  847 + break;
  848 + }
  849 + }
  850 + }
  851 + // 班次索引
  852 + var iBcIndex = _qIsUp == oBc.isUp() ? 0 : 1;
  853 +
  854 + if (iLpIndex == undefined) {
  855 + return null;
  856 + } else {
  857 + return [].concat(iLpIndex, iGroupIndex, iBcIndex);
  858 + }
  859 +
  860 + };
  861 +
  862 + return {
  863 + //------------- 布局初始化方法 ------------//
  864 + /**
  865 + * 初始化数据,使用标线初始化
  866 + */
  867 + fnInitDataWithBxLayout: function() {
  868 + // 初始化布局1,构造上标线,计算圈数,把上标线数据放入第一个路牌中
  869 + _fnInitFun1();
  870 + // 初始化布局2,从上标线的某个班次开始,构造所有路牌的早高峰班次,晚高峰班次,计算路牌在各个圈中的间隔
  871 + _fnInitFun2();
  872 + // 初始化布局3,计算连班分班路牌分布
  873 + _fnInitFun3();
  874 + // 初始化布局4,计算中标线位置
  875 + _fnInitFun4();
  876 +
  877 + },
  878 +
  879 + /**
  880 + * 调整高峰班次,
  881 + * 初始化生成早高峰,晚高峰班次并不准确,因为根据高峰时间段,并不在一个完整圈内,应该是在两个或多个圈之间
  882 + * 当初始化定好布局后(上标线,中标线),然后确定每个路牌的班型(连班,分班,5休2分班)后
  883 + * 然后重新计算框在高峰时间段内的班次索引,不足的添加,之前多加的删除(只删除分班路牌上的)
  884 + * @param isZgf 是否早高峰
  885 + * @param isUp 是否上行
  886 + */
  887 + fnAdjustGfbc : function(isZgf, isUp) {
  888 + var oStartTime; // 开始时间
  889 + var oEndTime; // 结束时间
  890 + var aStartBcIndex; // 开始班次索引
  891 + var aEndBcIndex; // 结束班次索引
  892 +
  893 + oStartTime = isZgf ? _paramObj.getMPeakStartTimeObj() : _paramObj.getEPeakStartTimeObj();
  894 + oEndTime = isZgf ? _paramObj.getMPeakEndTimeObj() : _paramObj.getEPeakEndTimeObj();
  895 +
  896 + aStartBcIndex = _fnFindUpClosedBcIndexWithTime(oStartTime, isUp);
  897 + aEndBcIndex = _fnFindDownClosedBcIndexWithTime(oEndTime, isUp);
  898 +
  899 + var iLpIndex;
  900 + var iQIndex;
  901 + var iBcIndex;
  902 + var iQInternelCount; // 高峰时间段中间包含的圈数
  903 + var i;
  904 + var j;
  905 +
  906 + var oLp;
  907 +
  908 + if (aStartBcIndex && aEndBcIndex) {
  909 + iLpIndex = aStartBcIndex[0];
  910 + iQIndex = aStartBcIndex[1];
  911 + iBcIndex = aStartBcIndex[2];
  912 +
  913 + // 处理头
  914 + // 删除头部多余班次
  915 + for (j = 0; j < iLpIndex; j++) {
  916 + oLp = _internalLpArray[j];
  917 + if (oLp.isBxFb() && oLp.getBc(iQIndex, iBcIndex)) {
  918 + oLp.removeBc(iQIndex, iBcIndex);
  919 + }
  920 + }
  921 +
  922 + for (j = iLpIndex; j < _internalLpArray.length; j++) {
  923 + oLp = _internalLpArray[j];
  924 + if (!oLp.getBc(iQIndex, iBcIndex)) {
  925 + _fnGenerateBcAndSetBc(j, iQIndex, iBcIndex);
  926 + }
  927 + }
  928 +
  929 + // 处理中间
  930 + iQInternelCount = aEndBcIndex[1] - aStartBcIndex[1] - 1;
  931 + for (i = 1; i <= iQInternelCount; i++) {
  932 + oLp = _internalLpArray[iQIndex + i];
  933 +
  934 + if (!oLp.getBc(iQIndex + i, iBcIndex)) {
  935 + _fnGenerateBcAndSetBc(i, iQIndex + i, iBcIndex);
  936 + }
  937 + }
  938 +
  939 + // 处理尾部
  940 + iLpIndex = aEndBcIndex[0];
  941 + iQIndex = aEndBcIndex[1];
  942 + iBcIndex = aEndBcIndex[2];
  943 +
  944 + // 删除尾部多余的班次
  945 + for (j = iLpIndex; j < _internalLpArray.length; j++) {
  946 + oLp = _internalLpArray[j];
  947 + if (oLp.isBxFb() && oLp.getBc(iQIndex, iBcIndex)) {
  948 + oLp.removeBc(iQIndex, iBcIndex);
  949 + }
  950 + }
  951 +
  952 + if (aStartBcIndex[1] != aEndBcIndex[1]) { // 指定时间范围跨圈
  953 + for (j = 0; j < iLpIndex; j++) {
  954 + oLp = _internalLpArray[j];
  955 + if (!oLp.getBc(iQIndex, iBcIndex)) {
  956 + _fnGenerateBcAndSetBc(j, iQIndex, iBcIndex);
  957 + }
  958 + }
  959 + } else {
  960 + // 不跨圈,不用处理,处理头的时候已经加了
  961 + }
  962 +
  963 + }
  964 +
  965 + },
  966 +
  967 + /**
  968 + * 按照营运时间要求补充班次,
  969 + * 早高峰7:45分以前出场运营,
  970 + * 晚高峰16:10分以前出场运营
  971 + */
  972 + fnCalcuLpBc_yy: function() {
  973 + // 补班次的时候,针对的是分班班型
  974 + var i;
  975 + var _oLp;
  976 + var _oBc;
  977 + var _aMinBcIndex;
  978 + var _aMaxBcIndex;
  979 +
  980 + var _qIndex;
  981 + var _bIndex;
  982 +
  983 + var _zgfCDate = _paramObj.toTimeObj("7:45");
  984 + var _wgfCDate = _paramObj.toTimeObj("16:10");
  985 + var _ccsj;
  986 +
  987 + for (i = 0; i < _internalLpArray.length; i++) {
  988 + _oLp = _internalLpArray[i];
  989 + if (_oLp.isBxFb()) { // 分班路牌
  990 + // 早高峰部分
  991 + _aMinBcIndex = _oLp.getMinBcObjPosition();
  992 + _qIndex = _aMinBcIndex[0];
  993 + _bIndex = _aMinBcIndex[1];
  994 + _oBc = _oLp.getBc(_qIndex, _bIndex);
  995 + if (_qIsUp) {
  996 + _ccsj = _bIndex == 0 ?
  997 + _paramObj.getUpOutTime() :
  998 + _paramObj.getDownOutTime();
  999 + } else {
  1000 + _ccsj = _bIndex == 0 ?
  1001 + _paramObj.getDownOutTime() :
  1002 + _paramObj.getUpOutTime();
  1003 + }
  1004 + if (_zgfCDate.isBefore(_paramObj.addMinute(_oBc.getFcTimeObj(), -_ccsj))) {
  1005 + _fnGenerateBcAndSetBc(
  1006 + i,
  1007 + _bIndex == 0 ? _qIndex - 1 : _qIndex,
  1008 + _bIndex == 0 ? 1 : 0
  1009 + )
  1010 + }
  1011 +
  1012 + // 晚高峰部分
  1013 + _aMaxBcIndex = _oLp.getMaxBcObjPosition();
  1014 + _qIndex = _aMaxBcIndex[0];
  1015 + _bIndex = _aMaxBcIndex[1];
  1016 + _oBc = _oLp.getBc(
  1017 + _bIndex == 0 ? _qIndex - 1 : _qIndex,
  1018 + _bIndex == 0 ? 1 : 0
  1019 + );
  1020 + if (!_oBc) { // 前一个班次不存在,再判定加不加
  1021 + _oBc = _oLp.getBc(_qIndex, _bIndex);
  1022 + if (_qIsUp) {
  1023 + _ccsj = _bIndex == 0 ?
  1024 + _paramObj.getUpOutTime() :
  1025 + _paramObj.getDownOutTime();
  1026 + } else {
  1027 + _ccsj = _bIndex == 0 ?
  1028 + _paramObj.getDownOutTime() :
  1029 + _paramObj.getUpOutTime();
  1030 + }
  1031 + if (_wgfCDate.isBefore(_paramObj.addMinute(_oBc.getFcTimeObj(), -_ccsj))) {
  1032 + _fnGenerateBcAndSetBc(
  1033 + i,
  1034 + _bIndex == 0 ? _qIndex - 1 : _qIndex,
  1035 + _bIndex == 0 ? 1 : 0
  1036 + )
  1037 + }
  1038 + }
  1039 + }
  1040 + }
  1041 + },
  1042 +
  1043 + /**
  1044 + * 补充做5休2的班型班次。
  1045 + * 1、确认5_2班型大致多少圈(小数点过.7进位)
  1046 + * 2、获取当前5_2两端车次链的信息,每段的班次数目,还差几个班次没加
  1047 + * 3、如果前面的车次链班次少,则从前面的车次链开始加
  1048 + * 4、如果车次链班次数一样,从从后面的车次链开始加
  1049 + * 5、加班次时都是往车次链前方加
  1050 + * 6、如果前面车次链不能再加班次了,从后面车次链加
  1051 + */
  1052 + fnCalcuLpBx_5_2: function() {
  1053 + // 计算做5休2班型所需的班次数
  1054 + var iBxBcount = _aBxDesc[6].fBcCount;
  1055 + if (iBxBcount - Math.floor(iBxBcount) > 0.7) {
  1056 + iBxBcount = Math.floor(iBxBcount) + 1;
  1057 + } else {
  1058 + iBxBcount = Math.floor(iBxBcount);
  1059 + }
  1060 +
  1061 + var i;
  1062 + var j;
  1063 + var oLp;
  1064 + var iAddBcCount;
  1065 + var oBcChain1;
  1066 + var oBcChain2;
  1067 + var iQindex;
  1068 + var iBindex;
  1069 +
  1070 + for (i = 0; i < _internalLpArray.length; i++) {
  1071 + oLp = _internalLpArray[i];
  1072 + if (oLp.isBxFb5_2()) {
  1073 + iAddBcCount = iBxBcount - oLp.getBcArray().length; // 需要添加的班次数
  1074 + for (j = 1; j <= iAddBcCount; j++) {
  1075 + oBcChain1 = oLp.fnGetBcChainInfo(0);
  1076 + oBcChain2 = oLp.fnGetBcChainInfo(1);
  1077 +
  1078 + if (oBcChain1.bcount < oBcChain2.bcount) {
  1079 + iQindex = oBcChain1.s_b == 0 ? oBcChain1.s_q - 1 : oBcChain1.s_q;
  1080 + iBindex = oBcChain1.s_b == 0 ? 1 : 0;
  1081 + // 往车次链往前不能加,就往后加
  1082 + if (_fnGenerateBc(i, iQindex, iBindex)) {
  1083 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1084 + } else {
  1085 + iQindex = oBcChain1.e_b == 0 ? oBcChain1.e_q : oBcChain1.e_q + 1;
  1086 + iBindex = oBcChain1.e_b == 0 ? 1 : 0;
  1087 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1088 + }
  1089 +
  1090 + } else if (oBcChain1.bcount > oBcChain2.bcount) {
  1091 + iQindex = oBcChain2.s_b == 0 ? oBcChain2.s_q - 1 : oBcChain2.s_q;
  1092 + iBindex = oBcChain2.s_b == 0 ? 1 : 0;
  1093 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1094 + } else {
  1095 + iQindex = oBcChain2.s_b == 0 ? oBcChain2.s_q - 1 : oBcChain2.s_q;
  1096 + iBindex = oBcChain2.s_b == 0 ? 1 : 0;
  1097 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1098 + }
  1099 + }
  1100 + }
  1101 + }
  1102 +
  1103 + },
  1104 +
  1105 + /**
  1106 + * 补其他分班班型班次。
  1107 + * 从车次链的后面开始加
  1108 + */
  1109 + fnCalcuLpBx_other: function() {
  1110 + // TODO:根据上标线的首班时间确定班型,小于05:59的做一休一,否则做二休一
  1111 + var oSt = _qIsUp ? _paramObj.getUpFirstDTimeObj() : _paramObj.getDownFirstDTimeObj();
  1112 + var iBxIndex = 4;
  1113 + if (oSt.isBefore(_paramObj.toTimeObj("05:59"))) {
  1114 + iBxIndex = 5;
  1115 + }
  1116 + // 计算做5休2班型所需的班次数
  1117 + var iQBcount = _aBxDesc[iBxIndex].fQCount;
  1118 + var iBxBcount = Math.round(iQBcount) * 2;
  1119 +
  1120 + var i;
  1121 + var j;
  1122 + var oLp;
  1123 + var iAddBcCount;
  1124 + var oBcChain1;
  1125 + var oBcChain2;
  1126 + var iQindex;
  1127 + var iBindex;
  1128 +
  1129 + for (i = 0; i < _internalLpArray.length; i++) {
  1130 + oLp = _internalLpArray[i];
  1131 + if (oLp.isBxFb() && !oLp.isBxFb5_2()) {
  1132 + iAddBcCount = iBxBcount - oLp.getBcArray().length; // 需要添加的班次数
  1133 + for (j = 1; j <= iAddBcCount; j++) {
  1134 + oBcChain1 = oLp.fnGetBcChainInfo(0);
  1135 + oBcChain2 = oLp.fnGetBcChainInfo(1);
  1136 +
  1137 + if (oBcChain1.bcount < oBcChain2.bcount) {
  1138 + iQindex = oBcChain1.e_b == 0 ? oBcChain1.e_q : oBcChain1.e_q + 1;
  1139 + iBindex = oBcChain1.e_b == 0 ? 1 : 0;
  1140 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1141 + } else if (oBcChain1.bcount > oBcChain2.bcount) {
  1142 + iQindex = oBcChain2.e_b == 0 ? oBcChain2.e_q : oBcChain2.e_q + 1;
  1143 + iBindex = oBcChain2.e_b == 0 ? 1 : 0;
  1144 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1145 + } else {
  1146 + iQindex = oBcChain2.e_b == 0 ? oBcChain2.e_q : oBcChain2.e_q + 1;
  1147 + iBindex = oBcChain2.e_b == 0 ? 1 : 0;
  1148 + _fnGenerateBcAndSetBc(i, iQindex, iBindex);
  1149 + }
  1150 + }
  1151 + }
  1152 + }
  1153 +
  1154 + },
  1155 +
  1156 + /**
  1157 + * 补充连班路牌班次。
  1158 + * 1、上标线,中标线中间的连班路牌班次从早高峰班次一直拉到底,从早高峰班次向上标线起始班次靠拢
  1159 + * 2、中标线以下的连班路牌班次从早高峰班次一直拉到底,从早高峰班次向中标线起始班次靠拢
  1160 + */
  1161 + fnCalcuLpBx_lb: function() {
  1162 + // 补充连班的班次,参照上标线,中标线补充不足的班次
  1163 +
  1164 + var aLbLpindexes = []; // 除上标线,中标线的连班路牌索引
  1165 + var i;
  1166 + for (i = 0; i < _internalLpArray.length; i++) {
  1167 + if (_internalLpArray[i].isBxLb() && i != 0 && i != _iZbx_lpIndex) {
  1168 + aLbLpindexes.push(i);
  1169 + }
  1170 + }
  1171 +
  1172 + var oEndsj = // 结束时间
  1173 + _paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj()) ?
  1174 + _paramObj.getDownLastDTimeObj() :
  1175 + _paramObj.getUpLastDtimeObj();
  1176 +
  1177 + var oLp;
  1178 + var aMinbcPos;
  1179 + var oBc;
  1180 + var j;
  1181 + var iTempBcIndex;
  1182 +
  1183 + // 1、从最小班次开始,往后补充班次
  1184 + for (i = 0; i < aLbLpindexes.length; i++) {
  1185 + oLp = _internalLpArray[aLbLpindexes[i]];
  1186 +
  1187 + // 最小班次索引
  1188 + aMinbcPos = oLp.getMinBcObjPosition();
  1189 + // 使用纵向分隔补充班次,从最小班次向后补
  1190 + iTempBcIndex = aMinbcPos[1] == 0 ? 1 : 0;
  1191 + j = iTempBcIndex == 0 ? aMinbcPos[0] + 1 : aMinbcPos[0];
  1192 +
  1193 + while (j < _qCount) {
  1194 + while (iTempBcIndex <= 1) {
  1195 + oBc = _fnGenerateBc(aLbLpindexes[i], j, iTempBcIndex);
  1196 + if (oBc &&
  1197 + oBc.getFcTimeObj().isBefore(oEndsj) ) {
  1198 + oLp.setBc(j, iTempBcIndex, oBc);
  1199 + }
  1200 + iTempBcIndex++;
  1201 + }
  1202 + iTempBcIndex = 0;
  1203 + j++;
  1204 + }
  1205 +
  1206 + }
  1207 +
  1208 + // 2、上标线中标线之间的路牌,从最小的班次往前补充班次
  1209 +
  1210 + // 还要补充缺失的班次,差上标线几个班次要往前补上
  1211 + var iBccount;
  1212 + var iQindex;
  1213 + var iBindex;
  1214 + // 补上标线到中标线之间的连班路牌的班次
  1215 + for (i = 0; i < aLbLpindexes.length; i++) {
  1216 + if (aLbLpindexes[i] > 0 && aLbLpindexes[i] < _iZbx_lpIndex) {
  1217 + oLp = _internalLpArray[aLbLpindexes[i]];
  1218 + aMinbcPos = oLp.getMinBcObjPosition();
  1219 + iQindex = aMinbcPos[0];
  1220 + iBindex = aMinbcPos[1];
  1221 + iBccount = (iQindex - 1) * 2 + iBindex; // 距离上标线起始站点差几个班次
  1222 + for (j = 0; j < iBccount; j++) {
  1223 + if (iBindex == 0) {
  1224 + iQindex --;
  1225 + iBindex = 1;
  1226 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1227 + } else if (iBindex == 1) {
  1228 + iBindex --;
  1229 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1230 + }
  1231 + }
  1232 +
  1233 + }
  1234 +
  1235 + }
  1236 +
  1237 + // 3、中标线之后的路牌,从最小的班次往前补充班次
  1238 +
  1239 + // 补中标线以下的连班路牌的班次
  1240 + for (i = 0; i < aLbLpindexes.length; i++) {
  1241 + if (aLbLpindexes[i] > _iZbx_lpIndex) {
  1242 + oLp = _internalLpArray[aLbLpindexes[i]];
  1243 + aMinbcPos = oLp.getMinBcObjPosition();
  1244 + iQindex = aMinbcPos[0];
  1245 + iBindex = aMinbcPos[1];
  1246 + iBccount = (iQindex - 0) * 2 + iBindex - 1; // 距离上标线起始站点差几个班次
  1247 + for (j = 0; j < iBccount; j++) {
  1248 + if (iBindex == 0) {
  1249 + iQindex --;
  1250 + iBindex = 1;
  1251 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1252 + } else if (iBindex == 1) {
  1253 + iBindex --;
  1254 + _fnGenerateBcAndSetBc(aLbLpindexes[i], iQindex, iBindex);
  1255 + }
  1256 + }
  1257 + }
  1258 + }
  1259 +
  1260 + },
  1261 +
  1262 + /**
  1263 + * 计算末班车。
  1264 + * 1、将上下行拉成上下行两个班次列表(包括标记班次)
  1265 + * 2、分别找出离末班车发车时间最近的班次,并替换时间
  1266 + * 3、删除之后的班次
  1267 + */
  1268 + fnCalcuLastBc: function() {
  1269 + var i;
  1270 + var iTimeDiff;
  1271 + var iTempTime;
  1272 + var aBc;
  1273 + var oLastBcTime;
  1274 + var oLastBcIsUp;
  1275 + var iModifyIndex;
  1276 +
  1277 + // 查找末班车早的末班车时间和方向
  1278 + if (_paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj())) {
  1279 + oLastBcTime = _paramObj.getUpLastDtimeObj();
  1280 + oLastBcIsUp = true;
  1281 + } else {
  1282 + oLastBcTime = _paramObj.getDownLastDTimeObj();
  1283 + oLastBcIsUp = false;
  1284 + }
  1285 +
  1286 + // 确定早的末班车时间
  1287 + aBc = _fnGetBcList(oLastBcIsUp);
  1288 + for (i = 0; i < aBc.length; i++) {
  1289 + iTempTime = oLastBcTime.diff(aBc[i].getFcTimeObj(), "m");
  1290 + if (iTimeDiff == undefined) {
  1291 + iTimeDiff = iTempTime;
  1292 + iModifyIndex = i;
  1293 + } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff)) {
  1294 + iTimeDiff = iTempTime;
  1295 + iModifyIndex = i;
  1296 + }
  1297 + }
  1298 + aBc[iModifyIndex].addMinuteToFcsj(iTimeDiff); // 替换成末班车时间
  1299 + aBc[iModifyIndex].fnSetDelFlag(false);
  1300 + aBc[iModifyIndex].fnSetIsLastBc(true);
  1301 + for (i = iModifyIndex + 1; i < aBc.length; i++) { // 删除多余班次
  1302 + _qIsUp == oLastBcIsUp ?
  1303 + aBc[i]._$$_internal_group_obj.setBc1(undefined) :
  1304 + aBc[i]._$$_internal_group_obj.setBc2(undefined);
  1305 + }
  1306 +
  1307 + // 查找末班车晚的末班车时间和方向
  1308 + if (_paramObj.getUpLastDtimeObj().isBefore(_paramObj.getDownLastDTimeObj())) {
  1309 + oLastBcTime = _paramObj.getDownLastDTimeObj();
  1310 + oLastBcIsUp = false;
  1311 + } else {
  1312 + oLastBcTime = _paramObj.getUpLastDtimeObj();
  1313 + oLastBcIsUp = true;
  1314 + }
  1315 + // 确定晚的末班车时间
  1316 + aBc = _fnGetBcList(oLastBcIsUp);
  1317 + var oBc;
  1318 + var aBcIndex;
  1319 + var iLpIndex;
  1320 + var iQIndex;
  1321 + var iBcIndex;
  1322 +
  1323 + iTimeDiff = undefined;
  1324 + for (i = 0; i < aBc.length; i++) {
  1325 + oBc = aBc[i];
  1326 + aBcIndex = _fnGetBcIndex(oBc);
  1327 +
  1328 + iLpIndex = aBcIndex[0];
  1329 + iQIndex = aBcIndex[2] == 0 ? aBcIndex[1] -1 : aBcIndex[1];
  1330 + iBcIndex = aBcIndex[2] == 0 ? 1 : 0;
  1331 +
  1332 + if (!_internalLpArray[iLpIndex].getBc(iQIndex, iBcIndex)) {
  1333 + continue;
  1334 + }
  1335 +
  1336 + iTempTime = oLastBcTime.diff(aBc[i].getFcTimeObj(), "m");
  1337 + if (iTimeDiff == undefined) {
  1338 + iTimeDiff = iTempTime;
  1339 + iModifyIndex = i;
  1340 + } else if (Math.abs(iTempTime) <= Math.abs(iTimeDiff)) {
  1341 + iTimeDiff = iTempTime;
  1342 + iModifyIndex = i;
  1343 + }
  1344 + }
  1345 + aBc[iModifyIndex].addMinuteToFcsj(iTimeDiff); // 替换成末班车时间
  1346 + aBc[iModifyIndex].fnSetDelFlag(false);
  1347 + aBc[iModifyIndex].fnSetIsLastBc(true);
  1348 + for (i = iModifyIndex + 1; i < aBc.length; i++) { // 删除多余班次
  1349 + _qIsUp == oLastBcIsUp ?
  1350 + aBc[i]._$$_internal_group_obj.setBc1(undefined) :
  1351 + aBc[i]._$$_internal_group_obj.setBc2(undefined);
  1352 + }
  1353 +
  1354 + },
  1355 +
  1356 + /**
  1357 + * 添加吃饭班次。
  1358 + */
  1359 + fnCalcuEatBc: function() {
  1360 + // 吃午饭时间范围,10:15 到 12:15
  1361 + // 吃晚饭时间范围,18:00 到 19:00
  1362 +
  1363 + if (!_paramObj.fnIsEat()) {
  1364 + return;
  1365 + }
  1366 +
  1367 + // 午饭index
  1368 + var aLEIndex;
  1369 + // 晚饭index
  1370 + var aDEIndex;
  1371 +
  1372 + // 所有吃饭都默认在一个方向,两个方向暂时不考虑
  1373 + if (_paramObj.fnIsUpEat()) {
  1374 + aLEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("10:15"), true, false);
  1375 + aDEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("18:00"), true, false);
  1376 + } else {
  1377 + aLEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("10:15"), false, true);
  1378 + aDEIndex = _internalLpArray[0].getQBcIndexWithFcTime(_paramObj.toTimeObj("18:00"), false, true);
  1379 + }
  1380 +
  1381 + // 午饭第几圈,第几个班次
  1382 + var iLEQIndex = aLEIndex[0];
  1383 + var iLEBIndex = aLEIndex[1];
  1384 + // 晚饭第几圈,第几个班次
  1385 + var iDEQIndex = aDEIndex[0];
  1386 + var iDEBIndex = aDEIndex[1];
  1387 +
  1388 + // 注意,本模型只有连班才有吃饭
  1389 +
  1390 + var i;
  1391 + var oLp;
  1392 + var aLbIndex = []; // 连班班型的路牌索引
  1393 + for (i = 0; i < _internalLpArray.length; i++) {
  1394 + oLp = _internalLpArray[i];
  1395 + if (oLp.isBxLb()) {
  1396 + aLbIndex.push(i);
  1397 + }
  1398 + }
  1399 +
  1400 + var iLTime;
  1401 + var iDtime;
  1402 + var j;
  1403 + for (i = 0; i < aLbIndex.length; i++) {
  1404 + oLp = _internalLpArray[aLbIndex[i]];
  1405 +
  1406 + // 午饭
  1407 + iLTime = oLp.fnAddEatBc(iLEQIndex, iLEBIndex, _factory, _paramObj);
  1408 + // 晚饭
  1409 + iDtime = oLp.fnAddEatBc(iDEQIndex, iDEBIndex, _factory, _paramObj);
  1410 +
  1411 + if (i == aLbIndex.length - 1) {
  1412 + for (j = aLbIndex[i]; j < _internalLpArray.length; j++) {
  1413 + oLp = _internalLpArray[j];
  1414 + if (oLp.isBxFb()) { // 5休2班型不调整
  1415 + // 修正午饭之后路牌班次的发车时间
  1416 + oLp.fnAddMinuteToBcFcsj(iLEQIndex, iLEBIndex, iLTime);
  1417 + oLp.fnAddMinuteToBcFcsj(iDEQIndex, iDEBIndex, iDtime);
  1418 + }
  1419 + }
  1420 + } else {
  1421 + for (j = aLbIndex[i]; j < aLbIndex[i + 1]; j++) {
  1422 + oLp = _internalLpArray[j];
  1423 + if (oLp.isBxFb()) {
  1424 + // 修正午饭之后路牌班次的发车时间
  1425 + oLp.fnAddMinuteToBcFcsj(iLEQIndex, iLEBIndex, iLTime);
  1426 + oLp.fnAddMinuteToBcFcsj(iDEQIndex, iDEBIndex, iDtime);
  1427 + }
  1428 + }
  1429 + }
  1430 + }
  1431 +
  1432 + },
  1433 +
  1434 + /**
  1435 + * 补每个路牌的其他班次(进出场,例保班次)。
  1436 + */
  1437 + fnCalcuOtherBc_: function() {
  1438 + var i;
  1439 + var _lpObj;
  1440 + var _minBcIndex;
  1441 + var _maxBcIndex;
  1442 + var _minBc;
  1443 + var _maxBc;
  1444 + var _otherbc = [];
  1445 + var _oFbbc;
  1446 +
  1447 + for (i = 0; i < _internalLpArray.length; i++) {
  1448 + _lpObj = _internalLpArray[i];
  1449 + _minBcIndex = _lpObj.getMinBcObjPosition();
  1450 + _maxBcIndex = _lpObj.getMaxBcObjPosition();
  1451 + _minBc = _lpObj.getBc(_minBcIndex[0], _minBcIndex[1]);
  1452 + _maxBc = _lpObj.getBc(_maxBcIndex[0], _maxBcIndex[1]);
  1453 +
  1454 + _otherbc = [];
  1455 + _otherbc.push(_factory.createBcObj(
  1456 + _lpObj, "bd", true, 1,
  1457 + _minBc.getFcTimeObj(),
  1458 + _paramObj
  1459 + ));
  1460 + _otherbc.push(_factory.createBcObj(
  1461 + _lpObj, "out", true, 1,
  1462 + _minBc.getFcTimeObj(),
  1463 + _paramObj
  1464 + ));
  1465 +
  1466 + _maxBc.setArrTimeObj(_paramObj.addMinute(_maxBc.getFcTimeObj(), _maxBc.getBcTime()));
  1467 + _maxBc.setStopTime(0);
  1468 + _otherbc.push(_factory.createBcObj(
  1469 + _lpObj, "in", true, 1,
  1470 + _maxBc.getArrTimeObj(),
  1471 + _paramObj
  1472 + ));
  1473 + _otherbc.push(_factory.createBcObj(
  1474 + _lpObj, "lc", true, 1,
  1475 + _maxBc.getArrTimeObj(),
  1476 + _paramObj
  1477 + ));
  1478 +
  1479 + // 5休2分班出场例保班次
  1480 + if (_lpObj.isBxFb5_2()) {
  1481 + _oFbbc = _lpObj.getBc(
  1482 + _lpObj.fnGetBcChainInfo(1)["s_q"],
  1483 + _lpObj.fnGetBcChainInfo(1)["s_b"]
  1484 + );
  1485 +
  1486 + _otherbc.push(_factory.createBcObj(
  1487 + _lpObj, "bd", true, 1,
  1488 + _oFbbc.getFcTimeObj(),
  1489 + _paramObj
  1490 + ));
  1491 + _otherbc.push(_factory.createBcObj(
  1492 + _lpObj, "out", true, 1,
  1493 + _oFbbc.getFcTimeObj(),
  1494 + _paramObj
  1495 + ));
  1496 + }
  1497 +
  1498 + _lpObj.addOtherBcArray(_otherbc);
  1499 + }
  1500 +
  1501 + },
  1502 +
  1503 + /**
  1504 + * 补每个路牌的其他班次(进出场,例保班次)
  1505 + * 所有的车次链前后都加进出场、报道班次
  1506 + */
  1507 + fnCalcuOtherBc: function() {
  1508 + var i;
  1509 + var j;
  1510 + var iBcChainCount;
  1511 + var oLp;
  1512 + var aOtherBc;
  1513 + var oStartBc;
  1514 + var oEndBc;
  1515 +
  1516 + for (i = 0; i < _internalLpArray.length; i++) {
  1517 + aOtherBc = [];
  1518 + oLp = _internalLpArray[i];
  1519 + iBcChainCount = oLp.fnGetBcChainCount();
  1520 +
  1521 + if (iBcChainCount == 1) { // 只有一个车次链,是连班班型
  1522 + // 头部要添加出场,例保班次
  1523 + oStartBc = oLp.getBc(
  1524 + oLp.fnGetBcChainInfo(0)["s_q"],
  1525 + oLp.fnGetBcChainInfo(0)["s_b"]
  1526 + );
  1527 + aOtherBc.push(_factory.createBcObj(
  1528 + oLp, "bd", true, 1,
  1529 + oStartBc.getFcTimeObj(),
  1530 + _paramObj
  1531 + ));
  1532 + aOtherBc.push(_factory.createBcObj(
  1533 + oLp, "out", true, 1,
  1534 + oStartBc.getFcTimeObj(),
  1535 + _paramObj
  1536 + ));
  1537 +
  1538 + // 尾部需添加进场,例保班次
  1539 + oEndBc = oLp.getBc(
  1540 + oLp.fnGetBcChainInfo(0)["e_q"],
  1541 + oLp.fnGetBcChainInfo(0)["e_b"]
  1542 + );
  1543 + aOtherBc.push(_factory.createBcObj(
  1544 + oLp, "in", true, 1,
  1545 + oEndBc.getArrTimeObj(),
  1546 + _paramObj
  1547 + ));
  1548 + aOtherBc.push(_factory.createBcObj(
  1549 + oLp, "lc", true, 1,
  1550 + oEndBc.getArrTimeObj(),
  1551 + _paramObj
  1552 + ));
  1553 + } else if (iBcChainCount == 2) { // 两个车次链,是分班班型
  1554 + // 第一个车次链开头有出场,报到班次,车次链结尾只有进场班次
  1555 + oStartBc = oLp.getBc(
  1556 + oLp.fnGetBcChainInfo(0)["s_q"],
  1557 + oLp.fnGetBcChainInfo(0)["s_b"]
  1558 + );
  1559 + aOtherBc.push(_factory.createBcObj(
  1560 + oLp, "bd", true, 1,
  1561 + oStartBc.getFcTimeObj(),
  1562 + _paramObj
  1563 + ));
  1564 + aOtherBc.push(_factory.createBcObj(
  1565 + oLp, "out", true, 1,
  1566 + oStartBc.getFcTimeObj(),
  1567 + _paramObj
  1568 + ));
  1569 +
  1570 + oEndBc = oLp.getBc(
  1571 + oLp.fnGetBcChainInfo(0)["e_q"],
  1572 + oLp.fnGetBcChainInfo(0)["e_b"]
  1573 + );
  1574 + aOtherBc.push(_factory.createBcObj(
  1575 + oLp, "in", true, 1,
  1576 + oEndBc.getArrTimeObj(),
  1577 + _paramObj
  1578 + ));
  1579 +
  1580 + // 第二个车次链开头只有出场班次,车次链结尾有进场,报到班次
  1581 + oStartBc = oLp.getBc(
  1582 + oLp.fnGetBcChainInfo(1)["s_q"],
  1583 + oLp.fnGetBcChainInfo(1)["s_b"]
  1584 + );
  1585 + aOtherBc.push(_factory.createBcObj(
  1586 + oLp, "out", true, 1,
  1587 + oStartBc.getFcTimeObj(),
  1588 + _paramObj
  1589 + ));
  1590 +
  1591 + oEndBc = oLp.getBc(
  1592 + oLp.fnGetBcChainInfo(1)["e_q"],
  1593 + oLp.fnGetBcChainInfo(1)["e_b"]
  1594 + );
  1595 + aOtherBc.push(_factory.createBcObj(
  1596 + oLp, "in", true, 1,
  1597 + oEndBc.getArrTimeObj(),
  1598 + _paramObj
  1599 + ));
  1600 + aOtherBc.push(_factory.createBcObj(
  1601 + oLp, "lc", true, 1,
  1602 + oEndBc.getArrTimeObj(),
  1603 + _paramObj
  1604 + ));
  1605 +
  1606 +
  1607 + } else {
  1608 + // 2个车次链以上,暂时没有此班型
  1609 + }
  1610 +
  1611 + oLp.addOtherBcArray(aOtherBc);
  1612 + }
  1613 + },
  1614 +
  1615 + /**
  1616 + * 祛除上标线开头的删除标记的班次。
  1617 + */
  1618 + fnRemoveDelFirstFlagBc: function() {
  1619 + var oLp = _internalLpArray[0];
  1620 + var aMinBcIndex = oLp.getMinBcObjPosition();
  1621 + if (oLp.getBc(aMinBcIndex[0], aMinBcIndex[1]).fnIsDelFlag()) {
  1622 + oLp.removeBc(aMinBcIndex[0], aMinBcIndex[1]);
  1623 + }
  1624 + },
  1625 + /**
  1626 + * 祛除上标线结尾的删除标记的班次。
  1627 + */
  1628 + fnRemoveDelLastFlagBc: function() {
  1629 + var oLp = _internalLpArray[0];
  1630 + var aMaxBcIndex = oLp.getMaxBcObjPosition();
  1631 + if (oLp.getBc(aMaxBcIndex[0], aMaxBcIndex[1]).fnIsDelFlag()) {
  1632 + oLp.removeBc(aMaxBcIndex[0], aMaxBcIndex[1]);
  1633 + }
  1634 + },
  1635 +
  1636 + /**
  1637 + * 调整路牌班次间隔(核准周转时间,停站时间)。
  1638 + * @param iFre int 迭代次数
  1639 + */
  1640 + fnAdjustLpBcInterval: function(iFre) {
  1641 + if (iFre > 0) {
  1642 + for (var i = 0; i < _internalLpArray.length; i++) {
  1643 + _internalLpArray[i].fnAdjustBcInterval(
  1644 + this.fnCalcuAverPeakStopTime(),
  1645 + this.fnCalcuAverTroughStopTime(),
  1646 + _paramObj);
  1647 + }
  1648 +
  1649 + this.fnAdjustLpBcInterval(iFre - 1);
  1650 + }
  1651 + },
  1652 +
  1653 + /**
  1654 + * 调整班次间隔。
  1655 + * @param bIsUp 是否上行
  1656 + * @param oStartTime 开始时间对象
  1657 + * @param iFre 迭代次数
  1658 + */
  1659 + fnAdjustBcInterval2_: function(bIsUp, oStartTime, iFre) {
  1660 + if (iFre > 0) {
  1661 + var aBc = _fnGetBcList2(bIsUp, oStartTime); // 指定方向的班次列表
  1662 + aBc.sort(function(o1, o2) {
  1663 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1664 + return -1;
  1665 + } else {
  1666 + return 1;
  1667 + }
  1668 + });
  1669 + var i;
  1670 + var j;
  1671 +
  1672 + var iBcCountOfGroup = 3; // 3个班次取一次计算
  1673 + var aBcOfGroup; // 3个班次列表
  1674 + var aBcIntervalOfGroup; // 班次间隔列表,如:3个班次,2个间隔
  1675 +
  1676 + for (i = 0; i <= aBc.length - iBcCountOfGroup; i++) {
  1677 + aBcOfGroup = [];
  1678 + aBcIntervalOfGroup = [];
  1679 + for (j = i; j < i + iBcCountOfGroup; j++) {
  1680 + aBcOfGroup.push(aBc[j]);
  1681 + }
  1682 +
  1683 + for (j = 0; j < aBcOfGroup.length; j++) {
  1684 + if (j < aBcOfGroup.length - 1) {
  1685 + aBcIntervalOfGroup.push(aBcOfGroup[j + 1].getFcTimeObj().diff(
  1686 + aBcOfGroup[j].getFcTimeObj(), "m"));
  1687 + }
  1688 + }
  1689 +
  1690 + if (aBcIntervalOfGroup[0] < 19) {
  1691 + aBcOfGroup[1].addMinuteToFcsj(1);
  1692 + } else if (aBcIntervalOfGroup[0] > 20) {
  1693 + aBcOfGroup[1].addMinuteToFcsj(-1);
  1694 + } else {
  1695 + if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {
  1696 + //continue;
  1697 + } else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {
  1698 + aBcOfGroup[1].addMinuteToFcsj(-1);
  1699 + } else {
  1700 + aBcOfGroup[1].addMinuteToFcsj(1);
  1701 + }
  1702 + }
  1703 +
  1704 + }
  1705 +
  1706 + this.fnAdjustBcInterval2(bIsUp, oStartTime, iFre - 1);
  1707 + }
  1708 + },
  1709 +
  1710 + /**
  1711 + * 调整班次间隔。
  1712 + * @param boolean isUp 是否上行
  1713 + * @param oStartTime 开始时间对象
  1714 + * @param fre int 迭代次数
  1715 + */
  1716 + fnAdjustBcInterval: function(isUp, oStartTime, fre) {
  1717 + if (fre > 0) {
  1718 + var aBc = !oStartTime ? _fnGetBcList(isUp) : _fnGetBcList2(isUp, oStartTime); // 指定方向的班次列表
  1719 +
  1720 + aBc.sort(function(o1, o2) {
  1721 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1722 + return -1;
  1723 + } else {
  1724 + return 1;
  1725 + }
  1726 + });
  1727 +
  1728 + var i;
  1729 + var j;
  1730 +
  1731 + var iBcCountOfGroup = 3; // 3个班次取一次计算
  1732 + var aBcOfGroup; // 3个班次列表
  1733 + var aBcIntervalOfGroup; // 班次间隔列表,如:3个班次,2个间隔
  1734 + var oBcFcTime; // 班次发车时间
  1735 +
  1736 + for (i = 0; i <= aBc.length - iBcCountOfGroup; i++) {
  1737 + aBcOfGroup = [];
  1738 + aBcIntervalOfGroup = [];
  1739 + for (j = i; j < i + iBcCountOfGroup; j++) {
  1740 + aBcOfGroup.push(aBc[j]);
  1741 + }
  1742 +
  1743 + for (j = 0; j < aBcOfGroup.length; j++) {
  1744 + if (j < aBcOfGroup.length - 1) {
  1745 + aBcIntervalOfGroup.push(aBcOfGroup[j + 1].getFcTimeObj().diff(
  1746 + aBcOfGroup[j].getFcTimeObj(), "m"));
  1747 + }
  1748 + }
  1749 +
  1750 + // 判定规则
  1751 + oBcFcTime = aBcOfGroup[1].getFcTimeObj();
  1752 +
  1753 + // 第一个班次发车时间不动,根据间隔,调整中间一个班次
  1754 + // 如果3个班次2个间隔时间差1分钟,不调整
  1755 + // 如果第一个间隔大,调整第二个班次往前1分钟
  1756 + // 如果第二个间隔大,调整第二个班次往后1分钟
  1757 +
  1758 + if (_paramObj.isTroughBc(oBcFcTime) &&
  1759 + aBcIntervalOfGroup[0] > _paramObj.getTroughMaxFcjx()) {
  1760 + aBcOfGroup[1].addMinuteToFcsj(-1);
  1761 + }
  1762 +
  1763 + //else if (_paramObj.isMPeakBc(oBcFcTime) &&
  1764 + // aBcIntervalOfGroup[0] < _paramObj.getMPeakMinFcjx()) {
  1765 + // aBcOfGroup[1].addMinuteToFcsj(1);
  1766 + //} else if (_paramObj.isMPeakBc(oBcFcTime) &&
  1767 + // aBcIntervalOfGroup[0] > _paramObj.getMPeakMaxFcjx()) {
  1768 + // aBcOfGroup[1].addMinuteToFcsj(-1);
  1769 + //} else if (_paramObj.isEPeakBc(oBcFcTime) &&
  1770 + // aBcIntervalOfGroup[0] < _paramObj.getEPeakMinFcjx()) {
  1771 + // aBcOfGroup[1].addMinuteToFcsj(1);
  1772 + //} else if (_paramObj.isEPeakBc(oBcFcTime) &&
  1773 + // aBcIntervalOfGroup[0] > _paramObj.getEPeakMaxFcjx()) {
  1774 + // aBcOfGroup[1].addMinuteToFcsj(-1);
  1775 + //}
  1776 +
  1777 +
  1778 + else {
  1779 + if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {
  1780 + //continue;
  1781 + } else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {
  1782 + aBcOfGroup[1].addMinuteToFcsj(-1);
  1783 + } else {
  1784 + aBcOfGroup[1].addMinuteToFcsj(1);
  1785 + }
  1786 + }
  1787 +
  1788 + //if (Math.abs(aBcIntervalOfGroup[0] - aBcIntervalOfGroup[1]) <= 1) {
  1789 + // //continue;
  1790 + //} else if (aBcIntervalOfGroup[0] > aBcIntervalOfGroup[1]) {
  1791 + // aBcOfGroup[1].addMinuteToFcsj(-1);
  1792 + //} else {
  1793 + // aBcOfGroup[1].addMinuteToFcsj(1);
  1794 + //}
  1795 +
  1796 +
  1797 + }
  1798 +
  1799 + this.fnAdjustBcInterval(isUp, oStartTime, fre - 1);
  1800 + }
  1801 +
  1802 + },
  1803 +
  1804 + /**
  1805 + * 调整班次间隔(平均间隔)。
  1806 + * @param bIsUp 是否上行
  1807 + * @param oStartTime 开始时间对象
  1808 + */
  1809 + fnAdjustBcInterval2_avg: function(bIsUp, oStartTime) {
  1810 + var aBc = !oStartTime ? _fnGetBcList(bIsUp) : _fnGetBcList2(bIsUp, oStartTime); // 指定方向的班次列表
  1811 + aBc.sort(function(o1, o2) {
  1812 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1813 + return -1;
  1814 + } else {
  1815 + return 1;
  1816 + }
  1817 + });
  1818 +
  1819 + var j;
  1820 + var iCount = aBc.length - 1;
  1821 + var iC1 = Math.floor(aBc[aBc.length - 1].getFcTimeObj().diff(aBc[0].getFcTimeObj(), "m") / iCount);
  1822 + var iC2 = aBc[aBc.length - 1].getFcTimeObj().diff(aBc[0].getFcTimeObj(), "m") % iCount;
  1823 + var iTempTime;
  1824 +
  1825 + for (j = 0; j < iCount - iC2; j++) {
  1826 + iTempTime = aBc[j + 1].getFcTimeObj().diff(aBc[j].getFcTimeObj(), "m");
  1827 + aBc[j + 1].addMinuteToFcsj(iC1 - iTempTime);
  1828 + }
  1829 + for (j = 0; j < iC2; j++) {
  1830 + iTempTime = aBc[iCount - iC2 + j + 1].getFcTimeObj().diff(aBc[iCount - iC2 + j].getFcTimeObj(), "m");
  1831 + aBc[iCount - iC2 + j + 1].addMinuteToFcsj(iC1 + 1 - iTempTime);
  1832 + }
  1833 +
  1834 + },
  1835 +
  1836 + /**
  1837 + * 计算高峰平均停站时间。
  1838 + */
  1839 + fnCalcuAverPeakStopTime: function() {
  1840 + var i;
  1841 + var j;
  1842 + var aBc;
  1843 + var iBcCount = 0;
  1844 + var iSum = 0;
  1845 + for (i = 0; i < _internalLpArray.length; i++) {
  1846 + aBc = _internalLpArray[i].getBcArray();
  1847 +
  1848 + for (j = 0; j < aBc.length; j++) {
  1849 + if (!_paramObj.isTroughBc(aBc[j].getArrTimeObj())) {
  1850 + iBcCount ++;
  1851 + iSum += aBc[j].getStopTime();
  1852 + }
  1853 + }
  1854 + }
  1855 +
  1856 + return Math.floor(iSum / iBcCount);
  1857 + },
  1858 +
  1859 + /**
  1860 + * 计算低谷平均停站时间。
  1861 + */
  1862 + fnCalcuAverTroughStopTime: function() {
  1863 + var i;
  1864 + var j;
  1865 + var aBc;
  1866 + var iBcCount = 0;
  1867 + var iSum = 0;
  1868 + for (i = 0; i < _internalLpArray.length; i++) {
  1869 + aBc = _internalLpArray[i].getBcArray();
  1870 + for (j = 0; j < aBc.length; j++) {
  1871 + if (_paramObj.isTroughBc(aBc[j].getArrTimeObj())) {
  1872 + iBcCount ++;
  1873 + iSum += aBc[j].getStopTime();
  1874 + }
  1875 + }
  1876 + }
  1877 +
  1878 + return Math.floor(iSum / iBcCount);
  1879 + },
  1880 +
  1881 + //------------- 其他方法 -------------//
  1882 + /**
  1883 + * 返回内部路牌数据列表。
  1884 + * @returns {Array}
  1885 + */
  1886 + fnGetLpArray: function() {
  1887 + return _internalLpArray;
  1888 + },
  1889 +
  1890 + /**
  1891 + * 内部数据转化成显示用的班次数组。
  1892 + */
  1893 + fnToGanttBcArray: function() {
  1894 + var aAllBc = [];
  1895 + var aLpBc = [];
  1896 + var aEatBc = [];
  1897 + var oLp;
  1898 + var i;
  1899 + var j;
  1900 +
  1901 + for (i = 0; i < _internalLpArray.length; i++) {
  1902 + oLp = _internalLpArray[i];
  1903 + aLpBc = [];
  1904 + aLpBc = aLpBc.concat(oLp.getOtherBcArray(), oLp.getBcArray());
  1905 +
  1906 + aEatBc = [];
  1907 + // 根据班次的吃饭时间添加吃饭班次
  1908 + for (j = 0; j < aLpBc.length; j++) {
  1909 + if (aLpBc[j].fnGetEatTime() > 0) {
  1910 + aEatBc.push(_factory.createBcObj(
  1911 + oLp,
  1912 + "cf",
  1913 + !aLpBc[j].isUp(), // 和上一个班次方向相反
  1914 + 1,
  1915 + _paramObj.addMinute(aLpBc[j].getArrTimeObj(), aLpBc[j].getStopTime()), // 使用上一个班次的到达时间作为开始时间
  1916 + _paramObj
  1917 + ));
  1918 + }
  1919 + }
  1920 + aLpBc = aLpBc.concat(aEatBc);
  1921 +
  1922 + // 按照发车时间排序
  1923 + aLpBc.sort(function(o1, o2) {
  1924 + if (o1.getFcTimeObj().isBefore(o2.getFcTimeObj())) {
  1925 + return -1;
  1926 + } else {
  1927 + return 1;
  1928 + }
  1929 + });
  1930 +
  1931 + // 重新赋值fcno
  1932 + for (j = 0; j < aLpBc.length; j++) {
  1933 + aLpBc[j].fnSetFcno(j + 1);
  1934 + }
  1935 +
  1936 + aAllBc = aAllBc.concat(aLpBc);
  1937 + }
  1938 +
  1939 + var aGanttBc = [];
  1940 + for (i = 0; i < aAllBc.length; i++) {
  1941 + aGanttBc.push(aAllBc[i].toGanttBcObj());
  1942 + }
  1943 +
  1944 + return aGanttBc;
  1945 + }
  1946 +
  1947 + };
  1948 +
1940 }; 1949 };
1941 \ No newline at end of file 1950 \ No newline at end of file
src/main/resources/static/pages/base/timesmodel/js/v2/main_v2.js
1 -/**  
2 - * 主类。  
3 - */  
4 -var Main_v2 = function() {  
5 -  
6 - // 内部工厂类  
7 - var _factoryFun = function() {  
8 - return {  
9 - // 创建参数  
10 - createParameterObj: function(formMap, dataMap) {  
11 - var paramObj = ParameterObj();  
12 - paramObj.wrap(formMap, dataMap);  
13 - return paramObj;  
14 - },  
15 - // 创建班次对象  
16 - createBcObj: function(lpObj, bcType, isUp, fcno, fcTimeObj, paramObj) {  
17 - var _bclc = paramObj.calcuTravelLcNumber(isUp, bcType);  
18 - var _fcsj = fcTimeObj;  
19 - var _bcsj = paramObj.calcuTravelTime(_fcsj, isUp);  
20 - var _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
21 - //var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, _bcsj);  
22 - var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, undefined);  
23 - var _tccid = paramObj.getTTinfoId();  
24 - var _ttinfoid = paramObj.getTTinfoId();  
25 - var _xl = paramObj.getXlId();  
26 - var _qdz = isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;  
27 - var _zdz = isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;  
28 -  
29 - if (bcType == "bd") { // 早例保,传过来的发车时间是第一个班次的发车时间  
30 - if (isUp) { // 上行  
31 - _fcsj = paramObj.addMinute(  
32 - _fcsj,  
33 - -(paramObj.getUpOutTime() + paramObj.getLbTime()));  
34 - _bcsj = paramObj.getLbTime();  
35 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
36 - _stoptime = 0;  
37 - } else { // 下行  
38 - _fcsj = paramObj.addMinute(  
39 - _fcsj,  
40 - -(paramObj.getDownOutTime() + paramObj.getLbTime()));  
41 - _bcsj = paramObj.getLbTime();  
42 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
43 - _stoptime = 0;  
44 - }  
45 - } else if (bcType == "lc") { // 晚例保,传过来的发车时间是最后一个班次的到达时间  
46 - if (isUp) { // 上行  
47 - _fcsj = paramObj.addMinute(  
48 - _fcsj,  
49 - paramObj.getUpInTime());  
50 - _bcsj = paramObj.getLbTime();  
51 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
52 - _stoptime = 0;  
53 - } else { // 下行  
54 - _fcsj = paramObj.addMinute(  
55 - _fcsj,  
56 - paramObj.getDownInTime());  
57 - _bcsj = paramObj.getLbTime();  
58 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
59 - _stoptime = 0;  
60 - }  
61 - } else if (bcType == "out") { // 出场,传过来的发车时间是第一个班次的发车时间  
62 - if (isUp) { // 上行  
63 - _fcsj = paramObj.addMinute(  
64 - _fcsj,  
65 - -paramObj.getUpOutTime());  
66 - _bcsj = paramObj.getUpOutTime();  
67 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
68 - _stoptime = 0;  
69 - } else { // 下行  
70 - _fcsj = paramObj.addMinute(  
71 - _fcsj,  
72 - -paramObj.getDownOutTime());  
73 - _bcsj = paramObj.getDownOutTime();  
74 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
75 - _stoptime = 0;  
76 - }  
77 - } else if (bcType == "in") { // 进场,传过来的发车时间是最后一个班次的到达时间  
78 - if (isUp) { // 上行  
79 - _bcsj = paramObj.getUpInTime();  
80 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
81 - _stoptime = 0;  
82 - } else { // 下行  
83 - _bcsj = paramObj.getDownInTime();  
84 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
85 - _stoptime = 0;  
86 - }  
87 - } else if (bcType == "cf") { // 吃饭班次  
88 - // 以13:00为分界,之前的为午饭,之后的为晚饭  
89 - if (fcTimeObj.isBefore(paramObj.toTimeObj("13:00"))) {  
90 - _bcsj = paramObj.fnGetLunchTime();  
91 - } else {  
92 - _bcsj = paramObj.fnGetDinnerTime();  
93 - }  
94 - _arrsj = paramObj.addMinute(_fcsj, _bcsj);  
95 - _stoptime = 0;  
96 - }  
97 -  
98 - var bcParamObj = {};  
99 - bcParamObj.bcType = bcType; // 班次类型(normal,in_,out, bd, lc, cf等)  
100 - bcParamObj.isUp = isUp; // boolean是否上下行  
101 - bcParamObj.fcno = fcno; // 发车顺序号  
102 - bcParamObj.fcTimeObj = _fcsj; // 发车时间对象  
103 - bcParamObj.bclc = _bclc; // 班次里程  
104 - bcParamObj.bcsj = _bcsj; // 班次历时  
105 - bcParamObj.arrtime = _arrsj; // 到达时间对象  
106 - bcParamObj.stoptime = _stoptime; // 停站时间  
107 - bcParamObj.tccid = _tccid; // 停车场id  
108 - bcParamObj.ttinfoid = _ttinfoid; // 时刻表id  
109 - bcParamObj.xl = _xl; // 线路id  
110 - bcParamObj.qdzid = _qdz; // 起点站id  
111 - bcParamObj.zdzid = _zdz; // 终点站id  
112 -  
113 - return new InternalBcObj(lpObj, bcParamObj);  
114 - }  
115 - };  
116 - };  
117 - var _factory = _factoryFun();  
118 -  
119 - // 所有的时间使用moment.js计算  
120 -  
121 - var _paramObj; // 参数对象  
122 -  
123 - var _bxDesc = [ // 班型描述  
124 - {'type':'六工一休','hoursV':6.66, 'minueV':'6:40', 'qcount': 0, 'avertime': 0},  
125 - {'type':'五工一休','hoursV':6.85, 'minueV':'6:51', 'qcount': 0, 'avertime': 0},  
126 - {'type':'四工一休','hoursV':7.14, 'minueV':'7:08', 'qcount': 0, 'avertime': 0},  
127 - {'type':'三工一休','hoursV':7.61, 'minueV':'7:37', 'qcount': 0, 'avertime': 0},  
128 - {'type':'二工一休','hoursV':8.57, 'minueV':'8:34', 'qcount': 0, 'avertime': 0},  
129 - {'type':'一工一休','hoursV':11.42, 'minueV':'11:25', 'qcount': 0, 'avertime': 0},  
130 - {'type':'五工二休','hoursV':7.99, 'minueV':'8:00', 'qcount': 0, 'avertime': 0},  
131 - {'type':'无工休', 'hoursV':5.43, 'minueV':'5:43', 'qcount': 0, 'avertime': 0}  
132 - ];  
133 -  
134 - return {  
135 - /**  
136 - * 工厂对象,创建不同的对象。  
137 - * @returns {{createParameterObj, createBcObj}}  
138 - */  
139 - getFactory: function() {  
140 - return _factory;  
141 - },  
142 -  
143 - /**  
144 - * 使用发车间隔策略生成时刻表。  
145 - * @param paramObj 参数对象  
146 - * @param lpArray 路牌数组  
147 - * @constructor  
148 - */  
149 - BXPplaceClassesTime03 : function(paramObj, lpArray) {  
150 - // 参数对象  
151 - _paramObj = paramObj;  
152 -  
153 - // 1、初始化行车计划  
154 - var schedule = new InternalScheduleObj(_paramObj, lpArray, _factory);  
155 - schedule.fnInitDataWithBxLayout();  
156 - // 2、将连班路牌的班次补足  
157 - schedule.fnCalcuLpBx_lb();  
158 -  
159 - // 3、修正针对初始化时生成的高峰班次,之前不足的补上,多余的删除  
160 - schedule.fnAdjustGfbc(true, true); // 修正上行早高峰  
161 - schedule.fnAdjustGfbc(true, false); // 修正下行早高峰  
162 - schedule.fnAdjustGfbc(false, true); // 修正上行晚高峰  
163 - schedule.fnAdjustGfbc(false, false); // 修正下行晚高峰  
164 -  
165 - // 6、补吃饭班次  
166 - schedule.fnCalcuEatBc();  
167 -  
168 - // 4、按照车辆投入运营要求补充班次  
169 - schedule.fnCalcuLpBc_yy();  
170 -  
171 - // 5、根据班型补充所有的不足班次  
172 - schedule.fnCalcuLpBx_5_2();  
173 - schedule.fnCalcuLpBx_other();  
174 -  
175 - // 7、祛除上标线开头有删除标记的班次  
176 - schedule.fnRemoveDelFirstFlagBc();  
177 -  
178 - // TODO:8、调整路牌班次间隔  
179 - schedule.fnAdjustLpBcInterval(1);  
180 -  
181 - // TODO:9、调整纵向班次间隔  
182 - schedule.fnAdjustBcInterval(true, false, 10);  
183 - schedule.fnAdjustBcInterval(false, false, 10);  
184 -  
185 - // 10、确定末班车  
186 - schedule.fnCalcuLastBc();  
187 -  
188 - // 11、祛除上标线结尾有删除标记的班次  
189 - schedule.fnRemoveDelLastFlagBc();  
190 -  
191 - // TODO:12、平均化指定时间后的班次列表间隔  
192 - schedule.fnAdjustBcInterval2_avg(true, _paramObj.toTimeObj("19:50"));  
193 - schedule.fnAdjustBcInterval2_avg(false, _paramObj.toTimeObj("19:50"));  
194 -  
195 - // 10、补进出场例保班次  
196 - schedule.fnCalcuOtherBc();  
197 -  
198 - //-------------------- 输出ganut图上的班次,班型描述 ----------------------//  
199 - var gBcData = schedule.fnToGanttBcArray();  
200 - // TODO:班型再议  
201 - return {'json':gBcData,'bxrcgs':null};  
202 -  
203 - }  
204 -  
205 - };  
206 -  
207 -}();  
208 \ No newline at end of file 1 \ No newline at end of file
  2 +/**
  3 + * 主类。
  4 + */
  5 +var Main_v2 = function() {
  6 +
  7 + // 内部工厂类
  8 + var _factoryFun = function() {
  9 + return {
  10 + // 创建参数
  11 + createParameterObj: function(formMap, dataMap) {
  12 + var paramObj = ParameterObj();
  13 + paramObj.wrap(formMap, dataMap);
  14 + return paramObj;
  15 + },
  16 + // 创建班次对象
  17 + createBcObj: function(lpObj, bcType, isUp, fcno, fcTimeObj, paramObj) {
  18 + var _bclc = paramObj.calcuTravelLcNumber(isUp, bcType);
  19 + var _fcsj = fcTimeObj;
  20 + var _bcsj = paramObj.calcuTravelTime(_fcsj, isUp);
  21 + var _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  22 + //var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, _bcsj);
  23 + var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, undefined);
  24 + var _tccid = paramObj.getTTinfoId();
  25 + var _ttinfoid = paramObj.getTTinfoId();
  26 + var _xl = paramObj.getXlId();
  27 + var _qdz = isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;
  28 + var _zdz = isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;
  29 +
  30 + if (bcType == "bd") { // 早例保,传过来的发车时间是第一个班次的发车时间
  31 + if (isUp) { // 上行
  32 + _fcsj = paramObj.addMinute(
  33 + _fcsj,
  34 + -(paramObj.getUpOutTime() + paramObj.getLbTime()));
  35 + _bcsj = paramObj.getLbTime();
  36 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  37 + _stoptime = 0;
  38 + } else { // 下行
  39 + _fcsj = paramObj.addMinute(
  40 + _fcsj,
  41 + -(paramObj.getDownOutTime() + paramObj.getLbTime()));
  42 + _bcsj = paramObj.getLbTime();
  43 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  44 + _stoptime = 0;
  45 + }
  46 + } else if (bcType == "lc") { // 晚例保,传过来的发车时间是最后一个班次的到达时间
  47 + if (isUp) { // 上行
  48 + _fcsj = paramObj.addMinute(
  49 + _fcsj,
  50 + paramObj.getUpInTime());
  51 + _bcsj = paramObj.getLbTime();
  52 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  53 + _stoptime = 0;
  54 + } else { // 下行
  55 + _fcsj = paramObj.addMinute(
  56 + _fcsj,
  57 + paramObj.getDownInTime());
  58 + _bcsj = paramObj.getLbTime();
  59 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  60 + _stoptime = 0;
  61 + }
  62 + } else if (bcType == "out") { // 出场,传过来的发车时间是第一个班次的发车时间
  63 + if (isUp) { // 上行
  64 + _fcsj = paramObj.addMinute(
  65 + _fcsj,
  66 + -paramObj.getUpOutTime());
  67 + _bcsj = paramObj.getUpOutTime();
  68 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  69 + _stoptime = 0;
  70 + } else { // 下行
  71 + _fcsj = paramObj.addMinute(
  72 + _fcsj,
  73 + -paramObj.getDownOutTime());
  74 + _bcsj = paramObj.getDownOutTime();
  75 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  76 + _stoptime = 0;
  77 + }
  78 + } else if (bcType == "in") { // 进场,传过来的发车时间是最后一个班次的到达时间
  79 + if (isUp) { // 上行
  80 + _bcsj = paramObj.getUpInTime();
  81 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  82 + _stoptime = 0;
  83 + } else { // 下行
  84 + _bcsj = paramObj.getDownInTime();
  85 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  86 + _stoptime = 0;
  87 + }
  88 + } else if (bcType == "cf") { // 吃饭班次
  89 + // 以13:00为分界,之前的为午饭,之后的为晚饭
  90 + if (fcTimeObj.isBefore(paramObj.toTimeObj("13:00"))) {
  91 + _bcsj = paramObj.fnGetLunchTime();
  92 + } else {
  93 + _bcsj = paramObj.fnGetDinnerTime();
  94 + }
  95 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  96 + _stoptime = 0;
  97 + }
  98 +
  99 + var bcParamObj = {};
  100 + bcParamObj.bcType = bcType; // 班次类型(normal,in_,out, bd, lc, cf等)
  101 + bcParamObj.isUp = isUp; // boolean是否上下行
  102 + bcParamObj.fcno = fcno; // 发车顺序号
  103 + bcParamObj.fcTimeObj = _fcsj; // 发车时间对象
  104 + bcParamObj.bclc = _bclc; // 班次里程
  105 + bcParamObj.bcsj = _bcsj; // 班次历时
  106 + bcParamObj.arrtime = _arrsj; // 到达时间对象
  107 + bcParamObj.stoptime = _stoptime; // 停站时间
  108 + bcParamObj.tccid = _tccid; // 停车场id
  109 + bcParamObj.ttinfoid = _ttinfoid; // 时刻表id
  110 + bcParamObj.xl = _xl; // 线路id
  111 + bcParamObj.qdzid = _qdz; // 起点站id
  112 + bcParamObj.zdzid = _zdz; // 终点站id
  113 +
  114 + return new InternalBcObj(lpObj, bcParamObj);
  115 + }
  116 + };
  117 + };
  118 + var _factory = _factoryFun();
  119 +
  120 + // 所有的时间使用moment.js计算
  121 +
  122 + var _paramObj; // 参数对象
  123 +
  124 + var _bxDesc = [ // 班型描述
  125 + {'type':'六工一休','hoursV':6.66, 'minueV':'6:40', 'qcount': 0, 'avertime': 0},
  126 + {'type':'五工一休','hoursV':6.85, 'minueV':'6:51', 'qcount': 0, 'avertime': 0},
  127 + {'type':'四工一休','hoursV':7.14, 'minueV':'7:08', 'qcount': 0, 'avertime': 0},
  128 + {'type':'三工一休','hoursV':7.61, 'minueV':'7:37', 'qcount': 0, 'avertime': 0},
  129 + {'type':'二工一休','hoursV':8.57, 'minueV':'8:34', 'qcount': 0, 'avertime': 0},
  130 + {'type':'一工一休','hoursV':11.42, 'minueV':'11:25', 'qcount': 0, 'avertime': 0},
  131 + {'type':'五工二休','hoursV':7.99, 'minueV':'8:00', 'qcount': 0, 'avertime': 0},
  132 + {'type':'无工休', 'hoursV':5.43, 'minueV':'5:43', 'qcount': 0, 'avertime': 0}
  133 + ];
  134 +
  135 + var _funCalcuExportData_lpObjList = function(aInternalLpObj) {
  136 + // 构造路牌对象
  137 + var aLpObj = [];
  138 + var i;
  139 + var j;
  140 + var z;
  141 + var oInternalLp;
  142 + var oInternalBc;
  143 + var oLp;
  144 + var iZbc;
  145 + var iZgs;
  146 + for (i = 0; i < aInternalLpObj.length; i++) {
  147 + oInternalLp = aInternalLpObj[i];
  148 + iZbc = 0;
  149 + iZgs = 0;
  150 + oLp = {
  151 + "lpname": oInternalLp.getLpName(), // 路牌名字
  152 + "isUp": oInternalLp.isUp(), // 每圈的第一个班次是否上行
  153 + "bcObjList": [], // 班次列表
  154 + "groupCount": oInternalLp.fnGetGroupCount(), // 总圈数
  155 + "zgs": 0, // 总工时
  156 + "zbc": 0, // 总班次
  157 + "stationRouteId1": 0, // 第一个班次起点站路由id
  158 + "stationRouteId2": 0 // 第二个班次起点站路由id
  159 + };
  160 + for (j = 0; j < oInternalLp.fnGetGroupCount(); j++) {
  161 + for (z = 0; z < 2; z++) {
  162 + oInternalBc = oInternalLp.getBc(j, z);
  163 + if (oInternalBc) {
  164 + oLp.bcObjList.push({
  165 + "bcsj": oInternalBc.getBcTime(), // 班次时间
  166 + "ssj": oInternalBc.getStopTime(), // 停站时间
  167 + "eatsj": oInternalBc.fnGetEatTime(), // 吃饭时间
  168 +
  169 + "tccid": oInternalBc._$_tccid, // 停车场id
  170 + "qdzid": oInternalBc._$_qdzid, // 起点站id
  171 + "zdzid": oInternalBc._$_zdzid, // 终点站id
  172 +
  173 + "isUp": oInternalBc._$_isUp, // 是否上行
  174 +
  175 + "bcType": oInternalBc._$_bcType, // 班次类型
  176 + "fcsj": oInternalBc._$_fcsjObj.format("HH:mm"), // 发车时间
  177 +
  178 + "groupNo": j, // 第几圈
  179 + "groupBcNo": z // 圈里第几个班次
  180 +
  181 + });
  182 +
  183 + iZgs = iZgs +
  184 + oInternalBc.getBcTime() + // 班次时间
  185 + oInternalBc.getStopTime() + // 停站时间
  186 + oInternalBc.fnGetEatTime(); // 吃饭时间
  187 + iZbc = iZbc + 1;
  188 +
  189 + // 设置圈站点路由id
  190 + if (oInternalBc.isUp() == oInternalLp.isUp()) { // 第一个班次
  191 + if (oLp.stationRouteId1 == 0) {
  192 + oLp.stationRouteId1 = oInternalBc._$_qdzid;
  193 + }
  194 + } else { // 第二个班次
  195 + if (oLp.stationRouteId2 == 0) {
  196 + oLp.stationRouteId2 = oInternalBc._$_qdzid;
  197 + }
  198 + }
  199 +
  200 + }
  201 + }
  202 +
  203 + }
  204 +
  205 + for (z = 0; z < oInternalLp.getOtherBcArray().length; z++) {
  206 + oInternalBc = oInternalLp.getOtherBcArray()[z];
  207 + iZgs = iZgs +
  208 + oInternalBc.getBcTime() + // 班次时间
  209 + oInternalBc.getStopTime(); // 停站时间
  210 + if (oInternalBc._$_bcType != "bd" &&
  211 + oInternalBc._$_bcType != "lc" &&
  212 + oInternalBc._$_bcType != "cf") {
  213 + iZbc = iZbc + 1;
  214 + }
  215 + }
  216 +
  217 +
  218 +
  219 + oLp.zgs = iZgs;
  220 + oLp.zbc = iZbc;
  221 + aLpObj.push(oLp);
  222 + }
  223 +
  224 + return aLpObj;
  225 + };
  226 +
  227 + var _funCalcuExportData_statInfoList = function(aInternalLpObj) {
  228 + var countBc = 0, // 总班次
  229 + serviceBc = 0, // 营运班次
  230 + jcbc = 0, // 进场总班次.
  231 + ccbc = 0, // 出场总班次.
  232 + cfbc = 0, // 吃饭总班次.
  233 + zwlbbc = 0, // 早晚例保总班次.
  234 + countGs = 0.0, // 总工时
  235 + servicesj = 0, // 营运班次总时间
  236 + jcsj = 0.0, // 进场总时间.
  237 + ccsj = 0.0, // 出场总时间.
  238 + cfsj = 0.0, // 吃饭总时间.
  239 + zwlbsj = 0.0, // 早晚例保总时间.
  240 + ksBc = 0, // 空驶班次
  241 + serviceLc = 0.0, // 营运里程
  242 + ksLc = 0.0, // 空驶里程
  243 + avgTzjx = 0.0, // 平均停站间隙
  244 + gfServiceBc = 0, // 高峰营运班次
  245 + dgServiceBc = 0, // 低谷营运班次
  246 + gfAvgTzjx = 0.0, // 高峰平均停站间隙
  247 + dgAvgTzjx = 0.0; // 低谷平均停站间隙
  248 +
  249 + var aAllBc = [];
  250 + var oLp;
  251 + var oBc;
  252 + var i;
  253 + var j;
  254 +
  255 + for (i = 0; i < aInternalLpObj.length; i++) {
  256 + oLp = aInternalLpObj[i];
  257 + for (j = 0; j < oLp.getBcArray().length; j++) {
  258 + aAllBc.push(oLp.getBcArray()[j]);
  259 + }
  260 + for (j = 0; j < oLp.getOtherBcArray().length; j++) {
  261 + aAllBc.push(oLp.getOtherBcArray()[j]);
  262 + }
  263 + }
  264 +
  265 + for (i = 0; i < aAllBc.length; i++) {
  266 + oBc = aAllBc[i];
  267 +
  268 + if (oBc.getBcTime() > 0) {
  269 + countBc = countBc + 1;
  270 + countGs = countGs + oBc.getStopTime() + oBc.getBcTime();
  271 + if (_paramObj.isTroughBc(oBc.getFcTimeObj())) {
  272 + if (oBc._$_bcType == "normal") {
  273 + dgServiceBc = dgServiceBc + 1;
  274 + dgAvgTzjx = dgAvgTzjx + oBc.getStopTime();
  275 + }
  276 + } else {
  277 + if (oBc._$_bcType == "normal") {
  278 + gfServiceBc = gfServiceBc + 1;
  279 + gfAvgTzjx = gfAvgTzjx + oBc.getStopTime();
  280 + }
  281 + }
  282 +
  283 + if (oBc._$_bcType == "normal") {
  284 + serviceBc = serviceBc + 1;
  285 + serviceLc = serviceLc + oBc._$_bclc;
  286 + servicesj = servicesj + oBc.getBcTime();
  287 + avgTzjx = avgTzjx + oBc.getStopTime();
  288 +
  289 + if (oBc.fnGetEatTime() > 0) {
  290 + cfbc = cfbc + 1;
  291 + cfsj = cfsj + oBc.fnGetEatTime();
  292 + }
  293 + } else if (oBc._$_bcType == "in") {
  294 + jcbc = jcbc + 1;
  295 + jcsj = jcsj + oBc.getBcTime();
  296 + } else if (oBc._$_bcType == "out") {
  297 + ccbc = ccbc + 1;
  298 + ccsj = ccsj + oBc.getBcTime();
  299 + } else if (oBc._$_bcType == "bd") {
  300 + zwlbbc = zwlbbc + 1;
  301 + zwlbsj = zwlbsj + oBc.getBcTime();
  302 + } else if (oBc._$_bcType == "lc") {
  303 + zwlbbc = zwlbbc + 1;
  304 + zwlbsj = zwlbsj + oBc.getBcTime();
  305 + }
  306 + }
  307 + }
  308 +
  309 + dgAvgTzjx = dgAvgTzjx / dgServiceBc;
  310 + gfAvgTzjx = gfAvgTzjx / gfServiceBc;
  311 + avgTzjx = avgTzjx / dgServiceBc;
  312 +
  313 + return [
  314 + {'statItem': '总班次(包括进出场、吃饭时间、早晚例保、营运且班次时间大于零的班次)', 'statValue': countBc},
  315 + {'statItem': '进场总班次(包括进场且班次时间大于零的班次)', 'statValue': jcbc},
  316 + {'statItem': '出场总班次(包括进场且班次时间大于零的班次)', 'statValue': ccbc},
  317 + {'statItem': '吃饭总班次(包括吃饭且班次时间大于零的班次)', 'statValue': cfbc},
  318 + {'statItem': '早晚例保总班次(包括早晚例保且时间大于零的班次)', 'statValue': zwlbbc},
  319 + {'statItem': '营运总班次(包括正常、区间、放大站且班次时间大于零班次)','statValue': serviceBc},
  320 + {'statItem': '进场总时间(包括进场班次且班次时间大于零)', 'statValue': jcsj/60},
  321 + {'statItem': '出场总时间(包括进场班次且班次时间大于零)', 'statValue': ccsj/60},
  322 + {'statItem': '吃饭总时间(包括吃饭班次且班次时间大于零)', 'statValue': cfsj/60},
  323 + {'statItem': '早晚例保总时间(包括早晚例保班次且时间大于零的)', 'statValue': zwlbsj/60},
  324 + {'statItem': '营运班次总时间(包括正常、区间、放大站且班次时间大于零)', 'statValue': servicesj/60},
  325 + {'statItem': '总工时(包括进出场、吃饭时间、早晚例保、营运班次时间)', 'statValue': countGs/60},
  326 + {'statItem': '空驶班次(包括直放班次)', 'statValue': ksBc},
  327 + {'statItem': '营运里程(包括正常、区间、放大站里程)', 'statValue': serviceLc},
  328 + {'statItem': '空驶里程(包括直放里程)', 'statValue': ksLc},
  329 + {'statItem': '平均停站时间(营运班次停站时间总和/营运总班次)', 'statValue': avgTzjx},
  330 + {'statItem': '高峰营运班次(包括早晚高峰时段的正常、区间、放大站班次)', 'statValue': gfServiceBc},
  331 + {'statItem': '低谷营运班次(包括低谷时段的正常、区间、放大站班次)', 'statValue': dgServiceBc},
  332 + {'statItem': '高峰平均停站间隙(高峰营运班次停站时间总和/高峰营运班次总和)', 'statValue': gfAvgTzjx},
  333 + {'statItem': '低谷平均停站间隙(低谷营运班次停站时间总和/低谷营运班次总和)', 'statValue': dgAvgTzjx},
  334 + {'statItem': '综合评估', 'statValue': 3}
  335 + ];
  336 +
  337 + };
  338 +
  339 + return {
  340 + /**
  341 + * 工厂对象,创建不同的对象。
  342 + * @returns {{createParameterObj, createBcObj}}
  343 + */
  344 + getFactory: function() {
  345 + return _factory;
  346 + },
  347 +
  348 + /**
  349 + * 使用发车间隔策略生成时刻表。
  350 + * @param paramObj 参数对象
  351 + * @param lpArray 路牌数组
  352 + * @constructor
  353 + */
  354 + BXPplaceClassesTime03 : function(paramObj, lpArray) {
  355 + // 参数对象
  356 + _paramObj = paramObj;
  357 +
  358 + // 1、初始化行车计划
  359 + var schedule = new InternalScheduleObj(_paramObj, lpArray, _factory);
  360 + schedule.fnInitDataWithBxLayout();
  361 + // 2、将连班路牌的班次补足
  362 + schedule.fnCalcuLpBx_lb();
  363 +
  364 + // 3、修正针对初始化时生成的高峰班次,之前不足的补上,多余的删除
  365 + schedule.fnAdjustGfbc(true, true); // 修正上行早高峰
  366 + schedule.fnAdjustGfbc(true, false); // 修正下行早高峰
  367 + schedule.fnAdjustGfbc(false, true); // 修正上行晚高峰
  368 + schedule.fnAdjustGfbc(false, false); // 修正下行晚高峰
  369 +
  370 + // 6、补吃饭班次
  371 + schedule.fnCalcuEatBc();
  372 +
  373 + // 4、按照车辆投入运营要求补充班次
  374 + schedule.fnCalcuLpBc_yy();
  375 +
  376 + // 5、根据班型补充所有的不足班次
  377 + schedule.fnCalcuLpBx_5_2();
  378 + schedule.fnCalcuLpBx_other();
  379 +
  380 + // 7、祛除上标线开头有删除标记的班次
  381 + schedule.fnRemoveDelFirstFlagBc();
  382 +
  383 + // TODO:8、调整路牌班次间隔
  384 + schedule.fnAdjustLpBcInterval(1);
  385 +
  386 + // TODO:9、调整纵向班次间隔
  387 + schedule.fnAdjustBcInterval(true, false, 10);
  388 + schedule.fnAdjustBcInterval(false, false, 10);
  389 +
  390 + // 10、确定末班车
  391 + schedule.fnCalcuLastBc();
  392 +
  393 + // 11、祛除上标线结尾有删除标记的班次
  394 + schedule.fnRemoveDelLastFlagBc();
  395 +
  396 + // TODO:12、平均化指定时间后的班次列表间隔
  397 + schedule.fnAdjustBcInterval2_avg(true, _paramObj.toTimeObj("19:50"));
  398 + schedule.fnAdjustBcInterval2_avg(false, _paramObj.toTimeObj("19:50"));
  399 +
  400 + // 10、补进出场例保班次
  401 + schedule.fnCalcuOtherBc();
  402 +
  403 + //-------------------- 输出ganut图上的班次,班型描述 ----------------------//
  404 + // TODO:班型再议
  405 + return {
  406 + 'json':schedule.fnToGanttBcArray(),'bxrcgs':null,
  407 + 'aInternalLpObj': schedule.fnGetLpArray()
  408 + };
  409 +
  410 + },
  411 + /**
  412 + * 导出时刻表配置。
  413 + * @param aInternalLpObj 内部路牌对象列表
  414 + */
  415 + exportDataConfig: function(aInternalLpObj) {
  416 + $('.exportAdd').on('click',function() {
  417 + var aInfos = {
  418 + "lpObjList": _funCalcuExportData_lpObjList(aInternalLpObj), // 路牌班次信息列表
  419 + "statInfoList": _funCalcuExportData_statInfoList(aInternalLpObj) // 统计项目列表
  420 + };
  421 +
  422 + console.log(aInfos);
  423 +
  424 + // 提交
  425 + $.ajax({
  426 + type: 'POST',
  427 + url: "/tidc/exportDTDFile",
  428 + dataType: 'binary',
  429 + contentType: "application/json",
  430 + data: JSON.stringify(aInfos),
  431 + success: function(data){
  432 + Main_v2.downloadFile(data, "application/octet-stream", "时刻表信息.xls");
  433 + },
  434 + error: function(xhr, type){
  435 + alert('错误:TODO');
  436 + }
  437 + });
  438 +
  439 + });
  440 + },
  441 +
  442 + downloadFile: function (data, mimeType, fileName) {
  443 + var success = false;
  444 + var blob = new Blob([data], { type: mimeType });
  445 + try {
  446 + if (navigator.msSaveBlob)
  447 + navigator.msSaveBlob(blob, fileName);
  448 + else {
  449 + // Try using other saveBlob implementations, if available
  450 + var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;
  451 + if (saveBlob === undefined) throw "Not supported";
  452 + saveBlob(blob, fileName);
  453 + }
  454 + success = true;
  455 + } catch (ex) {
  456 + console.log("saveBlob method failed with the following exception:");
  457 + console.log(ex);
  458 + }
  459 +
  460 + if (!success) {
  461 + // Get the blob url creator
  462 + var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
  463 + if (urlCreator) {
  464 + // Try to use a download link
  465 + var link = document.createElement('a');
  466 + if ('download' in link) {
  467 + // Try to simulate a click
  468 + try {
  469 + // Prepare a blob URL
  470 + var url = urlCreator.createObjectURL(blob);
  471 + link.setAttribute('href', url);
  472 +
  473 + // Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
  474 + link.setAttribute("download", fileName);
  475 +
  476 + // Simulate clicking the download link
  477 + var event = document.createEvent('MouseEvents');
  478 + event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
  479 + link.dispatchEvent(event);
  480 + success = true;
  481 +
  482 + } catch (ex) {
  483 + console.log("Download link method with simulated click failed with the following exception:");
  484 + console.log(ex);
  485 + }
  486 + }
  487 +
  488 + if (!success) {
  489 + // Fallback to window.location method
  490 + try {
  491 + // Prepare a blob URL
  492 + // Use application/octet-stream when using window.location to force download
  493 + var url = urlCreator.createObjectURL(blob);
  494 + window.location = url;
  495 + console.log("Download link method with window.location succeeded");
  496 + success = true;
  497 + } catch (ex) {
  498 + console.log("Download link method with window.location failed with the following exception:");
  499 + console.log(ex);
  500 + }
  501 + }
  502 + }
  503 + }
  504 +
  505 + if (!success) {
  506 + // Fallback to window.open method
  507 + console.log("No methods worked for saving the arraybuffer, using last resort window.open");
  508 + window.open("", '_blank', '');
  509 + }
  510 + }
  511 +
  512 + };
  513 +
  514 +}();
src/main/resources/static/pages/scheduleApp/module/common/main.js
@@ -343,4 +343,48 @@ ScheduleApp.controller(&#39;ScheduleAppController&#39;, [ @@ -343,4 +343,48 @@ ScheduleApp.controller(&#39;ScheduleAppController&#39;, [
343 DataStore.getData("cl"); 343 DataStore.getData("cl");
344 DataStore.getData("ry"); 344 DataStore.getData("ry");
345 } 345 }
346 -]);  
347 \ No newline at end of file 346 \ No newline at end of file
  347 +]);
  348 +
  349 +// JQuery插件,使$ajax支持resposetype=arraybuffer,二进制输出,html5的特性
  350 +// use this transport for "binary" data type
  351 +$.ajaxTransport("+binary", function(options, originalOptions, jqXHR){
  352 + // check for conditions and support for blob / arraybuffer response type
  353 + if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob)))))
  354 + {
  355 + return {
  356 + // create new XMLHttpRequest
  357 + send: function(headers, callback){
  358 + // setup all variables
  359 + var xhr = new XMLHttpRequest(),
  360 + url = options.url,
  361 + type = options.type,
  362 + async = options.async || true,
  363 + // blob or arraybuffer. Default is blob
  364 + dataType = options.responseType || "blob",
  365 + data = options.data || null,
  366 + username = options.username || null,
  367 + password = options.password || null;
  368 +
  369 + xhr.addEventListener('load', function(){
  370 + var data = {};
  371 + data[options.dataType] = xhr.response;
  372 + // make callback and send data
  373 + callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
  374 + });
  375 +
  376 + xhr.open(type, url, async, username, password);
  377 +
  378 + // setup custom headers
  379 + for (var i in headers ) {
  380 + xhr.setRequestHeader(i, headers[i] );
  381 + }
  382 +
  383 + xhr.responseType = dataType;
  384 + xhr.send(data);
  385 + },
  386 + abort: function(){
  387 + jqXHR.abort();
  388 + }
  389 + };
  390 + }
  391 +});
348 \ No newline at end of file 392 \ No newline at end of file