Commit 0734f5ef73e25f508a9c80815a28a34c00628719

Authored by mcy123
2 parents 9310b8a5 112c42c9

mcy

Showing 38 changed files with 1974 additions and 1007 deletions
src/main/java/com/bsth/controller/realcontrol/SignalStateController.java 0 → 100644
  1 +package com.bsth.controller.realcontrol;
  2 +
  3 +import com.bsth.data.gpsdata.SignalStateData;
  4 +import com.bsth.data.gpsdata.arrival.entity.SignalState;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.web.bind.annotation.RequestMapping;
  7 +import org.springframework.web.bind.annotation.RequestParam;
  8 +import org.springframework.web.bind.annotation.RestController;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * Created by panzhao on 2016/12/30.
  14 + */
  15 +@RestController
  16 +@RequestMapping("signalState")
  17 +public class SignalStateController {
  18 +
  19 + @Autowired
  20 + SignalStateData signalStateData;
  21 +
  22 + @RequestMapping("/multi")
  23 + public List<SignalState> findByMultiLine(@RequestParam String idx){
  24 + return signalStateData.get(idx);
  25 + }
  26 +}
src/main/java/com/bsth/data/BasicData.java
@@ -13,6 +13,7 @@ import org.slf4j.Logger; @@ -13,6 +13,7 @@ import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory; 13 import org.slf4j.LoggerFactory;
14 import org.springframework.beans.factory.annotation.Autowired; 14 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.boot.CommandLineRunner; 15 import org.springframework.boot.CommandLineRunner;
  16 +import org.springframework.core.annotation.Order;
16 import org.springframework.stereotype.Component; 17 import org.springframework.stereotype.Component;
17 18
18 import java.util.*; 19 import java.util.*;
@@ -25,13 +26,14 @@ import java.util.concurrent.TimeUnit; @@ -25,13 +26,14 @@ import java.util.concurrent.TimeUnit;
25 * @date 2016年8月10日 下午3:27:45 26 * @date 2016年8月10日 下午3:27:45
26 */ 27 */
27 @Component 28 @Component
  29 +@Order(value = 1)
28 public class BasicData implements CommandLineRunner { 30 public class BasicData implements CommandLineRunner {
29 -  
30 - //公司代码和公司名对照(K: 公司编码,V:公司名)  
31 - public static Map<String, String> businessCodeNameMap;  
32 -  
33 - //分公司公司代码和分公司公司名对照(K: 公司编码+分公司编码,V:分公司公司名)  
34 - public static Map<String, String> businessFgsCodeNameMap; 31 +
  32 + //公司代码和公司名对照(K: 公司编码,V:公司名)
  33 + public static Map<String, String> businessCodeNameMap;
  34 +
  35 + //分公司公司代码和分公司公司名对照(K: 公司编码+分公司编码,V:分公司公司名)
  36 + public static Map<String, String> businessFgsCodeNameMap;
35 37
36 //设备号和车辆自编号 (K: 设备编码 ,V:车辆自编号) 38 //设备号和车辆自编号 (K: 设备编码 ,V:车辆自编号)
37 public static BiMap<String, String> deviceId2NbbmMap; 39 public static BiMap<String, String> deviceId2NbbmMap;
@@ -39,27 +41,21 @@ public class BasicData implements CommandLineRunner { @@ -39,27 +41,21 @@ public class BasicData implements CommandLineRunner {
39 //车辆自编号和公司代码对照 (K: 车辆自编号 ,V:公司代码) 41 //车辆自编号和公司代码对照 (K: 车辆自编号 ,V:公司代码)
40 public static Map<String, String> nbbm2CompanyCodeMap; 42 public static Map<String, String> nbbm2CompanyCodeMap;
41 43
42 - //站点编码和名称对照,包括停车场 (K: 站点编码 ,V:站点名称) 44 + //站点编码和名称对照,包括停车场 (K: lineCode_updown_stationCode ,V:站点名称)
43 public static Map<String, String> stationCode2NameMap; 45 public static Map<String, String> stationCode2NameMap;
44 46
45 //线路起终点对照(线路编码_上下行_起终点) 1024_0_B (1024上行起点) 47 //线路起终点对照(线路编码_上下行_起终点) 1024_0_B (1024上行起点)
46 - public static Map<String, String> lineSEPointMap; 48 + //public static Map<String, String> lineSEPointMap;
47 49
48 //车辆和线路对照 50 //车辆和线路对照
49 public static Map<String, Line> nbbm2LineMap; 51 public static Map<String, Line> nbbm2LineMap;
50 52
51 - //线路和用户对照 用于webSocket定向推送消息(用户进入线调时写入数据)  
52 - //public static TreeMultimap<String, String> lineCode2SocketUserMap = TreeMultimap.create();  
53 -  
54 //线路ID和code 对照 53 //线路ID和code 对照
55 public static BiMap<Integer, String> lineId2CodeMap; 54 public static BiMap<Integer, String> lineId2CodeMap;
56 55
57 //线路编码和名称对照 56 //线路编码和名称对照
58 public static Map<String, String> lineCode2NameMap; 57 public static Map<String, String> lineCode2NameMap;
59 58
60 - //线路编码_站点编码 == 0|1 上下行  
61 - //public static Map<String, Integer> lineStationUpDownMap;  
62 -  
63 //停车场 59 //停车场
64 public static List<String> parkCodeList; 60 public static List<String> parkCodeList;
65 61
@@ -77,7 +73,7 @@ public class BasicData implements CommandLineRunner { @@ -77,7 +73,7 @@ public class BasicData implements CommandLineRunner {
77 public static Map<String, String> allPerson; 73 public static Map<String, String> allPerson;
78 74
79 //站点名和运管处编号 对照 75 //站点名和运管处编号 对照
80 - public static Map<String,Integer> stationName2YgcNumber; 76 + public static Map<String, Integer> stationName2YgcNumber;
81 77
82 78
83 static Logger logger = LoggerFactory.getLogger(BasicData.class); 79 static Logger logger = LoggerFactory.getLogger(BasicData.class);
@@ -87,7 +83,7 @@ public class BasicData implements CommandLineRunner { @@ -87,7 +83,7 @@ public class BasicData implements CommandLineRunner {
87 83
88 @Override 84 @Override
89 public void run(String... arg0) throws Exception { 85 public void run(String... arg0) throws Exception {
90 - Application.mainServices.scheduleWithFixedDelay(dataLoader, 2, 2, TimeUnit.HOURS); 86 + Application.mainServices.scheduleWithFixedDelay(dataLoader, 0, 2, TimeUnit.HOURS);
91 } 87 }
92 88
93 89
@@ -114,7 +110,7 @@ public class BasicData implements CommandLineRunner { @@ -114,7 +110,7 @@ public class BasicData implements CommandLineRunner {
114 110
115 @Autowired 111 @Autowired
116 PersonnelRepository personnelRepository; 112 PersonnelRepository personnelRepository;
117 - 113 +
118 @Autowired 114 @Autowired
119 BusinessRepository businessRepository; 115 BusinessRepository businessRepository;
120 116
@@ -156,47 +152,24 @@ public class BasicData implements CommandLineRunner { @@ -156,47 +152,24 @@ public class BasicData implements CommandLineRunner {
156 return 0; 152 return 0;
157 } 153 }
158 154
159 -  
160 -/* private void loadStationRouteInfo() {  
161 - Iterator<StationRoute> iterator = stationRouteRepository.findAllEffective().iterator();  
162 -  
163 - Map<String, String> sePointMap = new HashMap<>();  
164 - //lineSEPointMap  
165 - Map<String, Integer> map = new HashMap<>();  
166 -  
167 - StationRoute route;  
168 - while (iterator.hasNext()) {  
169 - route = iterator.next();  
170 - map.put(route.getLineCode() + "_" + route.getStationCode(), route.getDirections());  
171 -  
172 - if (route.getStationMark() != null &&  
173 - (route.getStationMark().equals("B") || route.getStationMark().equals("E"))) {  
174 - sePointMap.put(route.getLineCode() + "_"  
175 - + route.getDirections()  
176 - + "_" + route.getStationMark(), route.getStationCode());  
177 - }  
178 - }  
179 - lineStationUpDownMap = map;  
180 - lineSEPointMap = sePointMap;  
181 - }*/  
182 -  
183 /** 155 /**
184 * loadBusinessInfo 156 * loadBusinessInfo
185 * (公司代码公司名对照) 157 * (公司代码公司名对照)
186 */ 158 */
187 - public void loadBusinessInfo(){  
188 - Map<String, String> businessMap=new HashMap<String,String>();  
189 - Map<String, String> businessFgsMap=new HashMap<String,String>();  
190 - Iterator<Business> busIter=businessRepository.findAll().iterator();  
191 - Business t;  
192 - while(busIter.hasNext()){  
193 - t=busIter.next();  
194 - businessMap.put(t.getBusinessCode(), t.getBusinessName());  
195 - businessFgsMap.put(t.getBusinessCode()+"_"+t.getUpCode(), t.getBusinessName());  
196 - }  
197 - businessCodeNameMap=businessMap;  
198 - businessFgsCodeNameMap=businessFgsMap; 159 + public void loadBusinessInfo() {
  160 + Map<String, String> businessMap = new HashMap<String, String>();
  161 + Map<String, String> businessFgsMap = new HashMap<String, String>();
  162 + Iterator<Business> busIter = businessRepository.findAll().iterator();
  163 + Business t;
  164 + while (busIter.hasNext()) {
  165 + t = busIter.next();
  166 + businessMap.put(t.getBusinessCode(), t.getBusinessName());
  167 + businessFgsMap.put(t.getBusinessCode() + "_" + t.getUpCode(), t.getBusinessName());
  168 + }
  169 + businessCodeNameMap = businessMap;
  170 + businessFgsCodeNameMap = businessFgsMap;
199 } 171 }
  172 +
200 /** 173 /**
201 * @Title: loadDeviceInfo 174 * @Title: loadDeviceInfo
202 * @Description: TODO(加载设备相关信息) 175 * @Description: TODO(加载设备相关信息)
@@ -223,13 +196,13 @@ public class BasicData implements CommandLineRunner { @@ -223,13 +196,13 @@ public class BasicData implements CommandLineRunner {
223 */ 196 */
224 public void loadStationInfo() { 197 public void loadStationInfo() {
225 Map<String, String> stationCode2Name = new HashMap<>(); 198 Map<String, String> stationCode2Name = new HashMap<>();
226 - Iterator<Station> iterator = stationRepository.findAll().iterator();  
227 - //站点  
228 - Station station; 199 + Iterator<StationRoute> iterator = stationRouteRepository.findAll().iterator();
  200 + StationRoute sroute;
229 while (iterator.hasNext()) { 201 while (iterator.hasNext()) {
230 - station = iterator.next();  
231 - stationCode2Name.put(station.getStationCod(), station.getStationName()); 202 + sroute = iterator.next();
  203 + stationCode2Name.put(sroute.getLineCode() + "_" + sroute.getDirections() + "_" + sroute.getStationCode(), sroute.getStationName());
232 } 204 }
  205 +
233 //停车场 206 //停车场
234 Iterator<CarPark> iterator2 = carParkRepository.findAll().iterator(); 207 Iterator<CarPark> iterator2 = carParkRepository.findAll().iterator();
235 208
@@ -266,7 +239,7 @@ public class BasicData implements CommandLineRunner { @@ -266,7 +239,7 @@ public class BasicData implements CommandLineRunner {
266 * @Title: loadLineInfo 239 * @Title: loadLineInfo
267 * @Description: TODO(加载线路相关信息) 240 * @Description: TODO(加载线路相关信息)
268 */ 241 */
269 - public void loadLineInfo(){ 242 + public void loadLineInfo() {
270 Iterator<Line> iterator = lineRepository.findAll().iterator(); 243 Iterator<Line> iterator = lineRepository.findAll().iterator();
271 244
272 Line line; 245 Line line;
@@ -276,36 +249,36 @@ public class BasicData implements CommandLineRunner { @@ -276,36 +249,36 @@ public class BasicData implements CommandLineRunner {
276 Map<String, String> code2SHcode = new HashMap<String, String>(); 249 Map<String, String> code2SHcode = new HashMap<String, String>();
277 Map<String, Integer> tempStationName2YgcNumber = new HashMap<String, Integer>(); 250 Map<String, Integer> tempStationName2YgcNumber = new HashMap<String, Integer>();
278 251
279 - while(iterator.hasNext()){ 252 + while (iterator.hasNext()) {
280 line = iterator.next(); 253 line = iterator.next();
281 biMap.put(line.getId(), line.getLineCode()); 254 biMap.put(line.getId(), line.getLineCode());
282 code2name.put(line.getLineCode(), line.getName()); 255 code2name.put(line.getLineCode(), line.getName());
283 - id2SHcode.put(line.getId(),line.getShanghaiLinecode()); 256 + id2SHcode.put(line.getId(), line.getShanghaiLinecode());
284 code2SHcode.put(line.getLineCode(), line.getShanghaiLinecode()); 257 code2SHcode.put(line.getLineCode(), line.getShanghaiLinecode());
285 258
286 /** 259 /**
287 * 加载运管处的站点及序号 260 * 加载运管处的站点及序号
288 * 上行从1开始,下行顺序续编 261 * 上行从1开始,下行顺序续编
289 262
290 - List<Object[]> ygcLines = stationRouteRepository.findAllLineWithYgc();  
291 - if(ygcLines != null && ygcLines.size() > 0){  
292 - int size = ygcLines.size();  
293 - Object[] tempArray ;  
294 - int num = 1;  
295 - String key;  
296 - String lineCode = "";  
297 - for (int i = 0; i < size; i ++){  
298 - tempArray = ygcLines.get(i);  
299 - if(lineCode.equals("")){  
300 - lineCode = tempArray[0]+"";  
301 - }else if(!lineCode.equals(tempArray[0]+"")){  
302 - num = 1;  
303 - lineCode = tempArray[0]+"";  
304 - }  
305 - key = tempArray[0] + "_"+tempArray[1] + "_"+tempArray[2];  
306 - tempStationName2YgcNumber.put(key,num++);  
307 - }  
308 - }*/ 263 + List<Object[]> ygcLines = stationRouteRepository.findAllLineWithYgc();
  264 + if(ygcLines != null && ygcLines.size() > 0){
  265 + int size = ygcLines.size();
  266 + Object[] tempArray ;
  267 + int num = 1;
  268 + String key;
  269 + String lineCode = "";
  270 + for (int i = 0; i < size; i ++){
  271 + tempArray = ygcLines.get(i);
  272 + if(lineCode.equals("")){
  273 + lineCode = tempArray[0]+"";
  274 + }else if(!lineCode.equals(tempArray[0]+"")){
  275 + num = 1;
  276 + lineCode = tempArray[0]+"";
  277 + }
  278 + key = tempArray[0] + "_"+tempArray[1] + "_"+tempArray[2];
  279 + tempStationName2YgcNumber.put(key,num++);
  280 + }
  281 + }*/
309 } 282 }
310 283
311 lineId2CodeMap = biMap; 284 lineId2CodeMap = biMap;
src/main/java/com/bsth/data/LineConfigData.java
@@ -10,6 +10,7 @@ import org.slf4j.Logger; @@ -10,6 +10,7 @@ import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory; 10 import org.slf4j.LoggerFactory;
11 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.beans.factory.annotation.Autowired;
12 import org.springframework.boot.CommandLineRunner; 12 import org.springframework.boot.CommandLineRunner;
  13 +import org.springframework.core.annotation.Order;
13 import org.springframework.stereotype.Component; 14 import org.springframework.stereotype.Component;
14 15
15 import java.util.*; 16 import java.util.*;
@@ -23,6 +24,7 @@ import java.util.*; @@ -23,6 +24,7 @@ import java.util.*;
23 * 24 *
24 */ 25 */
25 @Component 26 @Component
  27 +@Order(value = 2)
26 public class LineConfigData implements CommandLineRunner { 28 public class LineConfigData implements CommandLineRunner {
27 29
28 Logger logger = LoggerFactory.getLogger(this.getClass()); 30 Logger logger = LoggerFactory.getLogger(this.getClass());
src/main/java/com/bsth/data/gpsdata/GpsEntity.java
@@ -86,7 +86,7 @@ public class GpsEntity { @@ -86,7 +86,7 @@ public class GpsEntity {
86 private StationRoute station; 86 private StationRoute station;
87 87
88 /** 状态 */ 88 /** 状态 */
89 - private String signalState; 89 + private String signalState = "normal";
90 90
91 public Integer getCompanyCode() { 91 public Integer getCompanyCode() {
92 return companyCode; 92 return companyCode;
src/main/java/com/bsth/data/gpsdata/GpsRealData.java
@@ -2,7 +2,6 @@ package com.bsth.data.gpsdata; @@ -2,7 +2,6 @@ package com.bsth.data.gpsdata;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
5 -import com.bsth.Application;  
6 import com.bsth.data.BasicData; 5 import com.bsth.data.BasicData;
7 import com.bsth.data.forecast.ForecastRealServer; 6 import com.bsth.data.forecast.ForecastRealServer;
8 import com.bsth.data.gpsdata.arrival.GpsRealAnalyse; 7 import com.bsth.data.gpsdata.arrival.GpsRealAnalyse;
@@ -26,7 +25,6 @@ import org.springframework.stereotype.Component; @@ -26,7 +25,6 @@ import org.springframework.stereotype.Component;
26 import java.io.BufferedReader; 25 import java.io.BufferedReader;
27 import java.io.InputStreamReader; 26 import java.io.InputStreamReader;
28 import java.util.*; 27 import java.util.*;
29 -import java.util.concurrent.TimeUnit;  
30 28
31 /** 29 /**
32 * @author PanZhao 30 * @author PanZhao
@@ -67,12 +65,23 @@ public class GpsRealData implements CommandLineRunner { @@ -67,12 +65,23 @@ public class GpsRealData implements CommandLineRunner {
67 65
68 @Override 66 @Override
69 public void run(String... arg0) throws Exception { 67 public void run(String... arg0) throws Exception {
70 - logger.info("gpsDataLoader,40,6");  
71 - Application.mainServices.scheduleWithFixedDelay(gpsDataLoader, 40, 6, TimeUnit.SECONDS); 68 + logger.info("gpsDataLoader,20,5");
  69 + //Application.mainServices.scheduleWithFixedDelay(gpsDataLoader, 20, 6, TimeUnit.SECONDS);
72 } 70 }
73 71
74 public void put(GpsEntity gps) { 72 public void put(GpsEntity gps) {
75 - gpsMap.put(gps.getDeviceId(), gps); 73 + String device = gps.getDeviceId();
  74 + gpsMap.put(device, gps);
  75 +
  76 + if (StringUtils.isNotBlank(gps.getLineId())){
  77 + //站点名称
  78 + gps.setStationName(getStationName(gps));
  79 + lineCode2Devices.put(gps.getLineId(), device);
  80 + }
  81 + }
  82 +
  83 + public String getStationName(GpsEntity gps){
  84 + return BasicData.stationCode2NameMap.get(gps.getLineId() + "_" + gps.getUpDown() + gps.getStopNo());
76 } 85 }
77 86
78 /** 87 /**
@@ -197,6 +206,8 @@ public class GpsRealData implements CommandLineRunner { @@ -197,6 +206,8 @@ public class GpsRealData implements CommandLineRunner {
197 gps.setNbbm(nbbm); 206 gps.setNbbm(nbbm);
198 //有更新的点位 207 //有更新的点位
199 updateList.add(gps); 208 updateList.add(gps);
  209 + //实时GPS数据集
  210 + gpsRealData.put(gps);
200 } 211 }
201 //分析数据 212 //分析数据
202 gpsRealAnalyse.analyse(updateList); 213 gpsRealAnalyse.analyse(updateList);
src/main/java/com/bsth/data/gpsdata/SignalStateData.java 0 → 100644
  1 +package com.bsth.data.gpsdata;
  2 +
  3 +import com.bsth.data.gpsdata.arrival.entity.SignalState;
  4 +import com.bsth.websocket.handler.SendUtils;
  5 +import com.google.common.base.Splitter;
  6 +import com.google.common.collect.ArrayListMultimap;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.stereotype.Component;
  9 +
  10 +import java.util.ArrayList;
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * 信号状态数据
  15 + * Created by panzhao on 2016/12/30.
  16 + */
  17 +@Component
  18 +public class SignalStateData {
  19 +
  20 + @Autowired
  21 + SendUtils sendUtils;
  22 +
  23 + private static ArrayListMultimap<String, SignalState> listMultimap = ArrayListMultimap.create();
  24 +
  25 + public void put(SignalState state){
  26 + listMultimap.put(state.getLineCode(), state);
  27 + //推送到客户端
  28 + sendUtils.sendSignalState(state);
  29 + }
  30 +
  31 + public List<SignalState> get(String idx){
  32 + List<SignalState> rs = new ArrayList<>();
  33 + List<String> ids = Splitter.on(",").splitToList(idx);
  34 +
  35 + for(String lineCode : ids){
  36 + rs.addAll(listMultimap.get(lineCode));
  37 + }
  38 + return rs;
  39 + }
  40 +}
src/main/java/com/bsth/data/gpsdata/arrival/GeoCacheData.java
@@ -29,8 +29,8 @@ public class GeoCacheData { @@ -29,8 +29,8 @@ public class GeoCacheData {
29 29
30 static Logger logger = LoggerFactory.getLogger(GeoCacheData.class); 30 static Logger logger = LoggerFactory.getLogger(GeoCacheData.class);
31 31
32 - //每辆车缓存最后500条gps  
33 - private static final int CACHE_SIZE = 500; 32 + //每辆车缓存最后1000条gps
  33 + private static final int CACHE_SIZE = 1000;
34 private static Map<String, CircleQueue<GpsEntity>> gpsCacheMap = new HashMap<>(); 34 private static Map<String, CircleQueue<GpsEntity>> gpsCacheMap = new HashMap<>();
35 35
36 //线路路段走向 36 //线路路段走向
@@ -75,7 +75,7 @@ public class GeoCacheData { @@ -75,7 +75,7 @@ public class GeoCacheData {
75 } 75 }
76 } 76 }
77 77
78 - public static StationRoute getRouteCode(GpsEntity gps){ 78 + public static StationRoute getRouteCode(GpsEntity gps) {
79 return routeCodeMap.get(gps.getLineId() + "_" + gps.getUpDown() + "_" + gps.getStopNo()); 79 return routeCodeMap.get(gps.getLineId() + "_" + gps.getUpDown() + "_" + gps.getStopNo());
80 } 80 }
81 81
@@ -94,6 +94,21 @@ public class GeoCacheData { @@ -94,6 +94,21 @@ public class GeoCacheData {
94 return null; 94 return null;
95 } 95 }
96 96
  97 + public static List<StationRoute> midwayStation(String lineCode, int directions, String sCode, String eCode) {
  98 + List<StationRoute> list = getStationRoute(lineCode, directions), rs = new ArrayList<>();
  99 +
  100 + boolean flag = false;
  101 + for (StationRoute sr : list) {
  102 + if (flag)
  103 + rs.add(sr);
  104 + if (sr.getCode().equals(sCode))
  105 + flag = true;
  106 + else if (sr.getCode().equals(eCode))
  107 + break;
  108 + }
  109 + return rs;
  110 + }
  111 +
97 public static Polygon getTccPolygon(String code) { 112 public static Polygon getTccPolygon(String code) {
98 return tccMap.get(code); 113 return tccMap.get(code);
99 } 114 }
@@ -191,4 +206,16 @@ public class GeoCacheData { @@ -191,4 +206,16 @@ public class GeoCacheData {
191 } 206 }
192 return cds; 207 return cds;
193 } 208 }
  209 +
  210 + /**
  211 + * 是不是终点站
  212 + * @param lineId
  213 + * @param upDown
  214 + * @param stationCode
  215 + * @return
  216 + */
  217 + public static boolean isEndStation(String lineId, Integer upDown, String stationCode) {
  218 + StationRoute station = routeCodeMap.get(lineId + "_" + upDown + "_" + stationCode);
  219 + return station != null && station.getMark().equals("E");
  220 + }
194 } 221 }
195 \ No newline at end of file 222 \ No newline at end of file
src/main/java/com/bsth/data/gpsdata/arrival/SignalHandle.java
1 package com.bsth.data.gpsdata.arrival; 1 package com.bsth.data.gpsdata.arrival;
2 2
3 import com.bsth.data.gpsdata.GpsEntity; 3 import com.bsth.data.gpsdata.GpsEntity;
  4 +import com.bsth.data.gpsdata.arrival.entity.StationRoute;
4 import com.bsth.data.gpsdata.arrival.utils.CircleQueue; 5 import com.bsth.data.gpsdata.arrival.utils.CircleQueue;
  6 +import com.bsth.data.gpsdata.arrival.utils.GeoUtils;
  7 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  8 +
  9 +import java.util.List;
5 10
6 /** 11 /**
7 * Created by panzhao on 2016/12/27. 12 * Created by panzhao on 2016/12/27.
@@ -14,64 +19,71 @@ public abstract class SignalHandle { @@ -14,64 +19,71 @@ public abstract class SignalHandle {
14 return prevs != null && prevs.size() > 0 && prevs.getTail() != null; 19 return prevs != null && prevs.size() > 0 && prevs.getTail() != null;
15 } 20 }
16 21
  22 + protected boolean isDriftSignal(GpsEntity gps) {
  23 + return gps.getLat() == 0 || gps.getLon() == 0;
  24 + }
  25 +
17 /** 26 /**
18 * 是不是异常信号 27 * 是不是异常信号
19 * 28 *
20 * @param gps 29 * @param gps
21 - * @return  
22 - */  
23 - protected boolean isAbnormal(GpsEntity gps) {  
24 - return gps.getLat() == 0 || gps.getLon() == 0;  
25 - } 30 + * @return protected boolean isAbnormal(GpsEntity gps) {
  31 + return gps.getLat() == 0 || gps.getLon() == 0;
  32 + }*/
26 33
27 /** 34 /**
28 * 连续异常信号个数统计 35 * 连续异常信号个数统计
29 * 36 *
30 * @param prevs 37 * @param prevs
31 - * @return 38 + * @return protected int abnormalCount(CircleQueue<GpsEntity> prevs) {
  39 + * int count = 0;
  40 + * <p>
  41 + * if (!isNotEmpty(prevs))
  42 + * return count;
  43 + * <p>
  44 + * GpsEntity[] array = (GpsEntity[]) prevs.getQueue();
  45 + * GpsEntity gps;
  46 + * for (int i = array.length - 1; i > 0; i--) {
  47 + * gps = array[i];
  48 + * <p>
  49 + * if (isAbnormal(gps))
  50 + * count++;
  51 + * else
  52 + * break;
  53 + * }
  54 + * <p>
  55 + * return count;
  56 + * }
32 */ 57 */
33 - protected int abnormalCount(CircleQueue<GpsEntity> prevs) {  
34 - int count = 0;  
35 58
36 - if (!isNotEmpty(prevs))  
37 - return count;  
38 -  
39 - GpsEntity[] array = (GpsEntity[]) prevs.getQueue();  
40 - GpsEntity gps;  
41 - for (int i = array.length - 1; i > 0; i--) {  
42 - gps = array[i];  
43 -  
44 - if (isAbnormal(gps))  
45 - count++;  
46 - else  
47 - break; 59 + protected void transformUpdown(GpsEntity gps, ScheduleRealInfo sch) {
  60 + int updown = Integer.parseInt(sch.getXlDir());
  61 + List<StationRoute> srs = GeoCacheData.getStationRoute(sch.getXlBm(), updown);
  62 + StationRoute station = GeoUtils.gpsInStation(gps, srs);
  63 + if (station != null) {
  64 + gps.setUpDown(updown);
  65 + gps.setStopNo(station.getCode());
48 } 66 }
49 -  
50 - return count;  
51 } 67 }
52 68
53 /** 69 /**
54 - * 车辆运行轨迹(最近20分钟)  
55 - * 0:上行 1:下行 -1:未知 70 + * 是否是从异常状态恢复的第一个信号
56 * 71 *
57 * @param gps 72 * @param gps
  73 + * @param prevs
58 * @return 74 * @return
59 */ 75 */
60 - protected int runTrack(GpsEntity gps, CircleQueue<GpsEntity> prevs) {  
61 - int rs = -1, count = 0;  
62 -  
63 - long et = gps.getTimestamp() - (1000 * 60 * 20);  
64 - Object[] array = prevs.getQueue();  
65 - GpsEntity prev;  
66 - for(Object obj : array){  
67 - prev = (GpsEntity) obj;  
68 - if(prev.getTimestamp() < et)  
69 - break;  
70 - 76 + protected boolean abnormalRecovery(GpsEntity gps, CircleQueue<GpsEntity> prevs) {
  77 + if (prevs == null || prevs.size() == 0)
  78 + return false;
71 79
  80 + GpsEntity prev = prevs.getTail();
  81 + //从漂移状态恢复
  82 + if (isDriftSignal(prev)
  83 + && !isDriftSignal(gps)) {
  84 + return true;
72 } 85 }
73 - //for()  
74 - return 0;  
75 - }  
76 86
77 -} 87 + return false;
  88 + }
  89 +}
78 \ No newline at end of file 90 \ No newline at end of file
src/main/java/com/bsth/data/gpsdata/arrival/entity/RouteReverse.java
@@ -5,6 +5,7 @@ package com.bsth.data.gpsdata.arrival.entity; @@ -5,6 +5,7 @@ package com.bsth.data.gpsdata.arrival.entity;
5 */ 5 */
6 public class RouteReverse { 6 public class RouteReverse {
7 7
  8 + private String nbbm;
8 //反转个数 9 //反转个数
9 private int count; 10 private int count;
10 11
@@ -14,18 +15,18 @@ public class RouteReverse { @@ -14,18 +15,18 @@ public class RouteReverse {
14 //掉头站点 15 //掉头站点
15 private String turned; 16 private String turned;
16 17
17 - //开始时间  
18 - private long st;  
19 -  
20 //掉头时间 18 //掉头时间
21 private long zt; 19 private long zt;
22 20
23 - //结束时间  
24 - private long et; 21 + //检测时间
  22 + private long ct;
25 23
26 //是否闭合 24 //是否闭合
27 private boolean close; 25 private boolean close;
28 26
  27 + //信号不明确
  28 + private boolean vague;
  29 +
29 public int getCount() { 30 public int getCount() {
30 return count; 31 return count;
31 } 32 }
@@ -50,22 +51,6 @@ public class RouteReverse { @@ -50,22 +51,6 @@ public class RouteReverse {
50 this.turned = turned; 51 this.turned = turned;
51 } 52 }
52 53
53 - public long getSt() {  
54 - return st;  
55 - }  
56 -  
57 - public void setSt(long st) {  
58 - this.st = st;  
59 - }  
60 -  
61 - public long getEt() {  
62 - return et;  
63 - }  
64 -  
65 - public void setEt(long et) {  
66 - this.et = et;  
67 - }  
68 -  
69 public boolean isClose() { 54 public boolean isClose() {
70 return close; 55 return close;
71 } 56 }
@@ -81,4 +66,28 @@ public class RouteReverse { @@ -81,4 +66,28 @@ public class RouteReverse {
81 public void setZt(long zt) { 66 public void setZt(long zt) {
82 this.zt = zt; 67 this.zt = zt;
83 } 68 }
84 -} 69 +
  70 + public long getCt() {
  71 + return ct;
  72 + }
  73 +
  74 + public void setCt(long ct) {
  75 + this.ct = ct;
  76 + }
  77 +
  78 + public String getNbbm() {
  79 + return nbbm;
  80 + }
  81 +
  82 + public void setNbbm(String nbbm) {
  83 + this.nbbm = nbbm;
  84 + }
  85 +
  86 + public boolean isVague() {
  87 + return vague;
  88 + }
  89 +
  90 + public void setVague(boolean vague) {
  91 + this.vague = vague;
  92 + }
  93 +}
85 \ No newline at end of file 94 \ No newline at end of file
src/main/java/com/bsth/data/gpsdata/arrival/entity/SignalAbnormal.java 0 → 100644
  1 +package com.bsth.data.gpsdata.arrival.entity;
  2 +
  3 +/**
  4 + * 班次信号异常(漂移 或 断线)
  5 + * Created by panzhao on 2016/12/31.
  6 + */
  7 +public class SignalAbnormal {
  8 +
  9 + private Long et;
  10 +
  11 + /** drift or reconnection */
  12 + private String abnormalType;
  13 +
  14 + private Long st;
  15 +
  16 + private String nearPoint;
  17 +
  18 + private String destCode;
  19 +
  20 + private Long ct;
  21 +
  22 + //0: 发车 1:到站
  23 + private int outOrIn;
  24 +
  25 + public Long getEt() {
  26 + return et;
  27 + }
  28 +
  29 + public void setEt(Long et) {
  30 + this.et = et;
  31 + }
  32 +
  33 + public String getAbnormalType() {
  34 + return abnormalType;
  35 + }
  36 +
  37 + public void setAbnormalType(String abnormalType) {
  38 + this.abnormalType = abnormalType;
  39 + }
  40 +
  41 + public Long getSt() {
  42 + return st;
  43 + }
  44 +
  45 + public void setSt(Long st) {
  46 + this.st = st;
  47 + }
  48 +
  49 + public String getNearPoint() {
  50 + return nearPoint;
  51 + }
  52 +
  53 + public void setNearPoint(String nearPoint) {
  54 + this.nearPoint = nearPoint;
  55 + }
  56 +
  57 + public Long getCt() {
  58 + return ct;
  59 + }
  60 +
  61 + public void setCt(Long ct) {
  62 + this.ct = ct;
  63 + }
  64 +
  65 + public int getOutOrIn() {
  66 + return outOrIn;
  67 + }
  68 +
  69 + public void setOutOrIn(int outOrIn) {
  70 + this.outOrIn = outOrIn;
  71 + }
  72 +
  73 + public String getDestCode() {
  74 + return destCode;
  75 + }
  76 +
  77 + public void setDestCode(String destCode) {
  78 + this.destCode = destCode;
  79 + }
  80 +}
src/main/java/com/bsth/data/gpsdata/arrival/entity/SignalState.java 0 → 100644
  1 +package com.bsth.data.gpsdata.arrival.entity;
  2 +
  3 +import com.bsth.data.BasicData;
  4 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  5 +import org.joda.time.format.DateTimeFormat;
  6 +import org.joda.time.format.DateTimeFormatter;
  7 +
  8 +/**
  9 + * 信号状态
  10 + * Created by panzhao on 2016/12/30.
  11 + */
  12 +public class SignalState {
  13 +
  14 + private String type;
  15 +
  16 + private Long st;
  17 +
  18 + //private Long checkTime;
  19 +
  20 + private Long schId;
  21 +
  22 + private String lineCode;
  23 +
  24 + private String text;
  25 +
  26 + private RouteReverse reverse;
  27 +
  28 + private SignalAbnormal signalAbnormal;
  29 +
  30 + private static DateTimeFormatter fmtHHmm = DateTimeFormat.forPattern("HH:mm");
  31 +
  32 + /**
  33 + * 记录区间调头
  34 + *
  35 + * @param sch
  36 + * @param reverse
  37 + * @return
  38 + */
  39 + public static SignalState reverseSignalSTate(ScheduleRealInfo sch, RouteReverse reverse) {
  40 + if(reverse.isVague())
  41 + return null;
  42 +
  43 + SignalState state = new SignalState();
  44 + state.setSchId(sch.getId());
  45 + state.setType("route_reverse");
  46 + //state.setCheckTime(System.currentTimeMillis());
  47 +
  48 + String stationName = BasicData.stationCode2NameMap.get(sch.getXlBm() + "_" + sch.getXlDir() + "_" + reverse.getTurned());
  49 + state.setText(fmtHHmm.print(reverse.getZt()) + " 从 " + stationName + " 站掉头");
  50 + state.setSt(sch.getFcsjActualTime());
  51 + state.setLineCode(sch.getXlBm());
  52 + state.setReverse(reverse);
  53 + return state;
  54 + }
  55 +
  56 + public static SignalState abnormalSignalSTate(ScheduleRealInfo sch, SignalAbnormal signalAbnormal) {
  57 + SignalState state = new SignalState();
  58 + state.setSchId(sch.getId());
  59 + state.setType("abnormal_signal");
  60 + //state.setCheckTime(signalAbnormal.getCt());
  61 + state.setLineCode(sch.getXlBm());
  62 +
  63 + String text = (fmtHHmm.print(signalAbnormal.getSt()) + " ~ " + fmtHHmm.print(signalAbnormal.getEt()));
  64 + String abnormType = signalAbnormal.getAbnormalType();
  65 + if (abnormType.equals("drift"))
  66 + text += "(GPS无效)";
  67 + else if (abnormType.equals("reconnection"))
  68 + text += "(信号丢失)";
  69 +
  70 + state.setText(text);
  71 + state.setSignalAbnormal(signalAbnormal);
  72 + return state;
  73 + }
  74 +
  75 + public String getType() {
  76 + return type;
  77 + }
  78 +
  79 + public void setType(String type) {
  80 + this.type = type;
  81 + }
  82 +
  83 + public long getSchId() {
  84 + return schId;
  85 + }
  86 +
  87 + public void setSchId(long schId) {
  88 + this.schId = schId;
  89 + }
  90 +
  91 + public String getLineCode() {
  92 + return lineCode;
  93 + }
  94 +
  95 + public void setLineCode(String lineCode) {
  96 + this.lineCode = lineCode;
  97 + }
  98 +
  99 + public Long getSt() {
  100 + return st;
  101 + }
  102 +
  103 + public void setSt(Long st) {
  104 + this.st = st;
  105 + }
  106 +
  107 + public String getText() {
  108 + return text;
  109 + }
  110 +
  111 + public void setText(String text) {
  112 + this.text = text;
  113 + }
  114 +
  115 + public RouteReverse getReverse() {
  116 + return reverse;
  117 + }
  118 +
  119 + public void setReverse(RouteReverse reverse) {
  120 + this.reverse = reverse;
  121 + }
  122 +
  123 + public SignalAbnormal getSignalAbnormal() {
  124 + return signalAbnormal;
  125 + }
  126 +
  127 + public void setSignalAbnormal(SignalAbnormal signalAbnormal) {
  128 + this.signalAbnormal = signalAbnormal;
  129 + }
  130 +}
src/main/java/com/bsth/data/gpsdata/arrival/handlers/InOutStationSignalHandle.java
@@ -2,23 +2,21 @@ package com.bsth.data.gpsdata.arrival.handlers; @@ -2,23 +2,21 @@ package com.bsth.data.gpsdata.arrival.handlers;
2 2
3 import com.bsth.data.LineConfigData; 3 import com.bsth.data.LineConfigData;
4 import com.bsth.data.gpsdata.GpsEntity; 4 import com.bsth.data.gpsdata.GpsEntity;
5 -import com.bsth.data.gpsdata.arrival.GeoCacheData;  
6 import com.bsth.data.gpsdata.arrival.SignalHandle; 5 import com.bsth.data.gpsdata.arrival.SignalHandle;
7 -import com.bsth.data.gpsdata.arrival.entity.StationRoute;  
8 import com.bsth.data.gpsdata.arrival.utils.CircleQueue; 6 import com.bsth.data.gpsdata.arrival.utils.CircleQueue;
9 -import com.bsth.data.gpsdata.arrival.utils.GeoUtils; 7 +import com.bsth.data.gpsdata.arrival.utils.ScheduleSignalState;
  8 +import com.bsth.data.gpsdata.arrival.utils.SignalSchPlanMatcher;
10 import com.bsth.data.schedule.DayOfSchedule; 9 import com.bsth.data.schedule.DayOfSchedule;
11 import com.bsth.entity.realcontrol.LineConfig; 10 import com.bsth.entity.realcontrol.LineConfig;
12 import com.bsth.entity.realcontrol.ScheduleRealInfo; 11 import com.bsth.entity.realcontrol.ScheduleRealInfo;
13 import com.bsth.service.directive.DirectiveService; 12 import com.bsth.service.directive.DirectiveService;
14 import com.bsth.websocket.handler.SendUtils; 13 import com.bsth.websocket.handler.SendUtils;
  14 +import org.apache.commons.lang3.StringUtils;
15 import org.slf4j.Logger; 15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory; 16 import org.slf4j.LoggerFactory;
17 import org.springframework.beans.factory.annotation.Autowired; 17 import org.springframework.beans.factory.annotation.Autowired;
18 import org.springframework.stereotype.Component; 18 import org.springframework.stereotype.Component;
19 19
20 -import java.util.List;  
21 -  
22 /** 20 /**
23 * 进出站动作处理 21 * 进出站动作处理
24 * Created by panzhao on 2016/12/27. 22 * Created by panzhao on 2016/12/27.
@@ -40,8 +38,25 @@ public class InOutStationSignalHandle extends SignalHandle{ @@ -40,8 +38,25 @@ public class InOutStationSignalHandle extends SignalHandle{
40 @Autowired 38 @Autowired
41 DirectiveService directiveService; 39 DirectiveService directiveService;
42 40
  41 + @Autowired
  42 + ScheduleSignalState scheduleSignalState;
  43 +
  44 + @Autowired
  45 + SignalSchPlanMatcher signalSchPlanMatcher;
  46 +
  47 + private final static int MAX_BEFORE_TIME = 1000 * 60 * 72;
  48 +
43 @Override 49 @Override
44 public boolean handle(GpsEntity gps, CircleQueue<GpsEntity> prevs) { 50 public boolean handle(GpsEntity gps, CircleQueue<GpsEntity> prevs) {
  51 + //忽略漂移信号
  52 + if(isDriftSignal(gps))
  53 + return false;
  54 +
  55 + //从异常状态恢复的第一个信号
  56 + if(abnormalRecovery(gps, prevs)){
  57 + //回溯一下之前的轨迹
  58 + scheduleSignalState.signalRetrospect(gps);
  59 + }
45 60
46 if(isNotEmpty(prevs)){ 61 if(isNotEmpty(prevs)){
47 GpsEntity prev = prevs.getTail(); 62 GpsEntity prev = prevs.getTail();
@@ -91,13 +106,23 @@ public class InOutStationSignalHandle extends SignalHandle{ @@ -91,13 +106,23 @@ public class InOutStationSignalHandle extends SignalHandle{
91 ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm()); 106 ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm());
92 String qdzCode = sch.getQdzCode(); 107 String qdzCode = sch.getQdzCode();
93 108
94 -  
95 - //if(sch.getFcsjActual() != ) 109 + //首班出场最多提前1.2小时
  110 + if(dayOfSchedule.isFirstOut(sch) && sch.getDfsjT() - gps.getTimestamp() > MAX_BEFORE_TIME)
  111 + return;
96 112
97 //起点发车 113 //起点发车
98 if(qdzCode != null && prev.getStopNo().equals(qdzCode) 114 if(qdzCode != null && prev.getStopNo().equals(qdzCode)
99 && !willDepart(gps, prev, sch)){ 115 && !willDepart(gps, prev, sch)){
100 116
  117 + //发车班次匹配
  118 + signalSchPlanMatcher.outMatch(gps, sch);
  119 + sch = dayOfSchedule.executeCurr(gps.getNbbm());
  120 +
  121 + //实发时间不覆盖
  122 + if(StringUtils.isNotEmpty(sch.getFcsjActual()))
  123 + return;
  124 +
  125 + //实发时间
101 sch.setFcsjActualAll(gps.getTimestamp()); 126 sch.setFcsjActualAll(gps.getTimestamp());
102 //通知客户端 127 //通知客户端
103 sendUtils.sendFcsj(sch); 128 sendUtils.sendFcsj(sch);
@@ -108,16 +133,27 @@ public class InOutStationSignalHandle extends SignalHandle{ @@ -108,16 +133,27 @@ public class InOutStationSignalHandle extends SignalHandle{
108 outStationAndOutPark(sch); 133 outStationAndOutPark(sch);
109 logger.info("班次:" + sch.getDfsj() + "发车, 时间:" + sch.getFcsjActual()); 134 logger.info("班次:" + sch.getDfsj() + "发车, 时间:" + sch.getFcsjActual());
110 } 135 }
  136 + else if(sch.getBcType().equals("out")){
  137 + ScheduleRealInfo next = dayOfSchedule.nextSame(sch);
  138 + if(prev.getStopNo().equals(next.getQdzCode())){
  139 + //发下一个班次
  140 + dayOfSchedule.addExecPlan(next);
  141 + outStation(gps, prev);
  142 + }
  143 + }
111 } 144 }
112 145
  146 +
113 private void outStationAndOutPark(ScheduleRealInfo sch){ 147 private void outStationAndOutPark(ScheduleRealInfo sch){
114 LineConfig config = lineConfigData.get(sch.getXlBm()); 148 LineConfig config = lineConfigData.get(sch.getXlBm());
115 if (config != null && config.getOutConfig() == 2) { 149 if (config != null && config.getOutConfig() == 2) {
116 //出站既出场 150 //出站既出场
117 ScheduleRealInfo schPrev = dayOfSchedule.prev(sch); 151 ScheduleRealInfo schPrev = dayOfSchedule.prev(sch);
118 if (schPrev != null && schPrev.getBcType().equals("out")) { 152 if (schPrev != null && schPrev.getBcType().equals("out")) {
119 - schPrev.setFcsjActualAll(sch.getFcsjActual());  
120 - schPrev.setZdsjActualAll(sch.getFcsjActual()); 153 + schPrev.setFcsjActualAll(sch.getFcsjActualTime());
  154 + schPrev.setZdsjActualAll(sch.getFcsjActualTime());
  155 +
  156 + sendUtils.refreshSch(schPrev);
121 } 157 }
122 } 158 }
123 } 159 }
@@ -129,9 +165,12 @@ public class InOutStationSignalHandle extends SignalHandle{ @@ -129,9 +165,12 @@ public class InOutStationSignalHandle extends SignalHandle{
129 */ 165 */
130 private void inStation(GpsEntity gps, GpsEntity prev){ 166 private void inStation(GpsEntity gps, GpsEntity prev){
131 ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm()); 167 ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm());
132 - String zdzCode = sch.getZdzCode();  
133 168
134 - if(zdzCode != null && gps.getStopNo().equals(zdzCode)){ 169 + if(gps.getStopNo().equals(sch.getZdzCode())){
  170 +
  171 + //实达时间不覆盖
  172 + if(StringUtils.isNotEmpty(sch.getZdsjActual()))
  173 + return;
135 174
136 sch.setZdsjActualAll(gps.getTimestamp()); 175 sch.setZdsjActualAll(gps.getTimestamp());
137 //已完成班次数 176 //已完成班次数
@@ -142,33 +181,22 @@ public class InOutStationSignalHandle extends SignalHandle{ @@ -142,33 +181,22 @@ public class InOutStationSignalHandle extends SignalHandle{
142 //持久化 181 //持久化
143 dayOfSchedule.save(sch); 182 dayOfSchedule.save(sch);
144 //下发调度指令 183 //下发调度指令
145 - //directiveService.send60Dispatch(next, doneSum, "到站@系统"); 184 + directiveService.send60Dispatch(next, doneSum, "到站@系统");
146 185
147 //准备执行下一个班次 186 //准备执行下一个班次
148 if (next != null) { 187 if (next != null) {
149 next.setQdzArrDatesj(sch.getZdsjActual()); 188 next.setQdzArrDatesj(sch.getZdsjActual());
150 dayOfSchedule.addExecPlan(next); 189 dayOfSchedule.addExecPlan(next);
151 -  
152 //进站既进场 190 //进站既进场
153 inStationAndInPark(sch, next); 191 inStationAndInPark(sch, next);
154 -  
155 //将gps转换为下一个班次走向的站内信号 192 //将gps转换为下一个班次走向的站内信号
156 - int updown = Integer.parseInt(next.getXlDir());  
157 - List<StationRoute> srs = GeoCacheData.getStationRoute(next.getXlBm(), updown);  
158 - StationRoute station = GeoUtils.gpsInStation(gps, srs);  
159 - if (station != null) {  
160 - gps.setUpDown(updown);  
161 - gps.setStopNo(station.getCode());  
162 - } 193 + transformUpdown(gps, sch);
163 } 194 }
164 } 195 }
165 - /* //如果出场班次计划终点时间5分钟后还未完成,检查一下车辆轨迹,是否已经在执行线路上班次  
166 - else if(sch.getBcType().equals("out")  
167 - && sch.getZdsj() != null  
168 - && gps.getTimestamp() - sch.getZdsjT() >= 1000 * 60 * 5){  
169 - logger.info("出场班次计划终点时间5分钟后还未完成");  
170 -  
171 - }*/ 196 + else if(sch.getFcsjActual() == null){
  197 + //有进站,但班次没有实发,向前追溯一下信号
  198 + scheduleSignalState.signalRetrospect(gps, sch);
  199 + }
172 } 200 }
173 201
174 /** 202 /**
@@ -179,8 +207,10 @@ public class InOutStationSignalHandle extends SignalHandle{ @@ -179,8 +207,10 @@ public class InOutStationSignalHandle extends SignalHandle{
179 LineConfig config = lineConfigData.get(sch.getXlBm()); 207 LineConfig config = lineConfigData.get(sch.getXlBm());
180 if (next.getBcType().equals("in") && 208 if (next.getBcType().equals("in") &&
181 config != null && config.getOutConfig() == 2) { 209 config != null && config.getOutConfig() == 2) {
182 - next.setFcsjActualAll(sch.getZdsjActual());  
183 - next.setZdsjActualAll(sch.getZdsjActual()); 210 + next.setFcsjActualAll(sch.getZdsjActualTime());
  211 + next.setZdsjActualAll(sch.getZdsjActualTime());
  212 +
  213 + sendUtils.refreshSch(next);
184 } 214 }
185 } 215 }
186 216
@@ -193,7 +223,7 @@ public class InOutStationSignalHandle extends SignalHandle{ @@ -193,7 +223,7 @@ public class InOutStationSignalHandle extends SignalHandle{
193 */ 223 */
194 private boolean willDepart(GpsEntity gps, GpsEntity prev, Object task){ 224 private boolean willDepart(GpsEntity gps, GpsEntity prev, Object task){
195 225
196 -/* ScheduleRealInfo sch = (ScheduleRealInfo) task; 226 + /*ScheduleRealInfo sch = (ScheduleRealInfo) task;
197 ScheduleRealInfo prevTask = dayOfSchedule.prev(sch); 227 ScheduleRealInfo prevTask = dayOfSchedule.prev(sch);
198 if(prevTask == null || prevTask.getBcType().equals("out")) 228 if(prevTask == null || prevTask.getBcType().equals("out"))
199 return false; 229 return false;
src/main/java/com/bsth/data/gpsdata/arrival/handlers/OfflineSignalHandle.java
@@ -13,16 +13,17 @@ import org.springframework.stereotype.Component; @@ -13,16 +13,17 @@ import org.springframework.stereotype.Component;
13 @Component 13 @Component
14 public class OfflineSignalHandle extends SignalHandle{ 14 public class OfflineSignalHandle extends SignalHandle{
15 15
16 - //断开3分钟,标记为重连信号  
17 - private final static int OFFLINE_TIME = 1000 * 60 * 3; 16 + //断开2分钟,标记为重连信号
  17 + private final static int OFFLINE_TIME = 1000 * 60 * 2;
18 18
19 //断开70分钟,之前的信号不再有参考价值 19 //断开70分钟,之前的信号不再有参考价值
20 private final static int CLEAR_TIME = 1000 * 60 * 70; 20 private final static int CLEAR_TIME = 1000 * 60 * 70;
21 21
22 @Override 22 @Override
23 public boolean handle(GpsEntity gps, CircleQueue<GpsEntity> prevs) { 23 public boolean handle(GpsEntity gps, CircleQueue<GpsEntity> prevs) {
24 - //异常信号不管  
25 - if(isAbnormal(gps)){ 24 + //漂移信号不管
  25 + if(isDriftSignal(gps)){
  26 + gps.setSignalState("drift");
26 return true; 27 return true;
27 } 28 }
28 29
@@ -39,4 +40,4 @@ public class OfflineSignalHandle extends SignalHandle{ @@ -39,4 +40,4 @@ public class OfflineSignalHandle extends SignalHandle{
39 } 40 }
40 return true; 41 return true;
41 } 42 }
42 -} 43 +}
43 \ No newline at end of file 44 \ No newline at end of file
src/main/java/com/bsth/data/gpsdata/arrival/handlers/ReverseSignalHandle.java
1 package com.bsth.data.gpsdata.arrival.handlers; 1 package com.bsth.data.gpsdata.arrival.handlers;
2 2
3 -import com.alibaba.fastjson.JSON;  
4 import com.bsth.data.gpsdata.GpsEntity; 3 import com.bsth.data.gpsdata.GpsEntity;
5 import com.bsth.data.gpsdata.arrival.GeoCacheData; 4 import com.bsth.data.gpsdata.arrival.GeoCacheData;
6 import com.bsth.data.gpsdata.arrival.SignalHandle; 5 import com.bsth.data.gpsdata.arrival.SignalHandle;
7 import com.bsth.data.gpsdata.arrival.entity.RouteReverse; 6 import com.bsth.data.gpsdata.arrival.entity.RouteReverse;
8 import com.bsth.data.gpsdata.arrival.entity.StationRoute; 7 import com.bsth.data.gpsdata.arrival.entity.StationRoute;
9 import com.bsth.data.gpsdata.arrival.utils.CircleQueue; 8 import com.bsth.data.gpsdata.arrival.utils.CircleQueue;
  9 +import com.bsth.data.gpsdata.arrival.utils.ScheduleSignalState;
10 import com.bsth.data.schedule.DayOfSchedule; 10 import com.bsth.data.schedule.DayOfSchedule;
11 -import com.bsth.entity.realcontrol.ScheduleRealInfo;  
12 import org.slf4j.Logger; 11 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory; 12 import org.slf4j.LoggerFactory;
14 import org.springframework.beans.factory.annotation.Autowired; 13 import org.springframework.beans.factory.annotation.Autowired;
@@ -26,6 +25,9 @@ public class ReverseSignalHandle extends SignalHandle { @@ -26,6 +25,9 @@ public class ReverseSignalHandle extends SignalHandle {
26 @Autowired 25 @Autowired
27 DayOfSchedule dayOfSchedule; 26 DayOfSchedule dayOfSchedule;
28 27
  28 + @Autowired
  29 + ScheduleSignalState scheduleSignalState;
  30 +
29 @Override 31 @Override
30 public boolean handle(GpsEntity gps, CircleQueue<GpsEntity> prevs) { 32 public boolean handle(GpsEntity gps, CircleQueue<GpsEntity> prevs) {
31 if (!isNotEmpty(prevs)) 33 if (!isNotEmpty(prevs))
@@ -36,17 +38,10 @@ public class ReverseSignalHandle extends SignalHandle { @@ -36,17 +38,10 @@ public class ReverseSignalHandle extends SignalHandle {
36 if (isReverse(gps, prev)) { 38 if (isReverse(gps, prev)) {
37 RouteReverse reverse = reverseSearch(prevs, gps); 39 RouteReverse reverse = reverseSearch(prevs, gps);
38 40
39 - if (reverse.getCount() >= 2) {  
40 - //切换到下一个班次  
41 - ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm());  
42 - if (sch.getBcType().equals("out") && sch.getZdsjT() != null && sch.getZdsjT() > gps.getTimestamp()) {  
43 - return false;  
44 - }  
45 - dayOfSchedule.addExecPlan(dayOfSchedule.next(sch));  
46 -  
47 - if (reverse.isClose()) {  
48 - logger.info("区间掉头,车辆:" + gps.getNbbm() + " -" + JSON.toJSONString(reverse));  
49 - } 41 + if (reverse.getCount() >= 4
  42 + && reverse.isClose()
  43 + && !GeoCacheData.isEndStation(gps.getLineId(), gps.getUpDown(), reverse.getTurned())) {
  44 + scheduleSignalState.reverseAnalyse(reverse);
50 } 45 }
51 } 46 }
52 return false; 47 return false;
@@ -63,7 +58,8 @@ public class ReverseSignalHandle extends SignalHandle { @@ -63,7 +58,8 @@ public class ReverseSignalHandle extends SignalHandle {
63 RouteReverse routeReverse = new RouteReverse(); 58 RouteReverse routeReverse = new RouteReverse();
64 int count = 0; 59 int count = 0;
65 String path = ""; 60 String path = "";
66 - String turned = null; 61 + long zt = 0L;
  62 + boolean half = false;
67 63
68 //当前站点 64 //当前站点
69 StationRoute curr = GeoCacheData.getRouteCode(gps), sr; 65 StationRoute curr = GeoCacheData.getRouteCode(gps), sr;
@@ -72,22 +68,29 @@ public class ReverseSignalHandle extends SignalHandle { @@ -72,22 +68,29 @@ public class ReverseSignalHandle extends SignalHandle {
72 for (int i = array.length - 1; i > 0; i--) { 68 for (int i = array.length - 1; i > 0; i--) {
73 prev = (GpsEntity) array[i]; 69 prev = (GpsEntity) array[i];
74 70
75 - if(!prev.getUpDown().equals(gps.getUpDown())) 71 + if (!prev.getUpDown().equals(gps.getUpDown())
  72 + || prev.getSignalState().equals("reconnection"))
76 break; 73 break;
77 74
78 if (prev.getInstation() == 1) { 75 if (prev.getInstation() == 1) {
79 sr = GeoCacheData.getRouteCode(prev); 76 sr = GeoCacheData.getRouteCode(prev);
80 77
81 if (sr.getRouteSort() > curr.getRouteSort()) { 78 if (sr.getRouteSort() > curr.getRouteSort()) {
  79 + if(half){
  80 + routeReverse.setVague(true);
  81 + }
  82 +
82 path += (curr.getCode() + ","); 83 path += (curr.getCode() + ",");
83 count++; 84 count++;
  85 + zt = prev.getTimestamp();
84 } else if (sr.getRouteSort() < curr.getRouteSort()) { 86 } else if (sr.getRouteSort() < curr.getRouteSort()) {
85 - path += (curr.getCode() + ",");  
86 - //掉头点  
87 - if (turned == null)  
88 - turned = prev.getStopNo(); 87 + if (routeReverse.getTurned() == null) {
  88 + routeReverse.setTurned(curr.getCode());
  89 + half = true;
  90 + }
89 91
90 - //路径闭合 92 + path += (curr.getCode() + ",");
  93 + //掉头前当前站
91 if (sr.getCode().equals(gps.getStopNo())) { 94 if (sr.getCode().equals(gps.getStopNo())) {
92 routeReverse.setClose(true); 95 routeReverse.setClose(true);
93 path += sr.getCode(); 96 path += sr.getCode();
@@ -99,9 +102,11 @@ public class ReverseSignalHandle extends SignalHandle { @@ -99,9 +102,11 @@ public class ReverseSignalHandle extends SignalHandle {
99 } 102 }
100 } 103 }
101 104
  105 + routeReverse.setZt(zt);
102 routeReverse.setCount(count); 106 routeReverse.setCount(count);
103 routeReverse.setDetail(path); 107 routeReverse.setDetail(path);
104 - routeReverse.setTurned(turned); 108 + routeReverse.setCt(gps.getTimestamp());
  109 + routeReverse.setNbbm(gps.getNbbm());
105 return routeReverse; 110 return routeReverse;
106 } 111 }
107 112
@@ -129,4 +134,4 @@ public class ReverseSignalHandle extends SignalHandle { @@ -129,4 +134,4 @@ public class ReverseSignalHandle extends SignalHandle {
129 } 134 }
130 return false; 135 return false;
131 } 136 }
132 -} 137 +}
133 \ No newline at end of file 138 \ No newline at end of file
src/main/java/com/bsth/data/gpsdata/arrival/utils/CircleQueue.java
@@ -105,8 +105,8 @@ public class CircleQueue&lt;T&gt; { @@ -105,8 +105,8 @@ public class CircleQueue&lt;T&gt; {
105 } 105 }
106 } 106 }
107 } else { 107 } else {
108 - elementDataSort = new Object[tail];  
109 - for (int i = 0; i < tail; i++) { 108 + elementDataSort = new Object[tail + 1];
  109 + for (int i = 0; i <= tail; i++) {
110 elementDataSort[i] = elementDataCopy[i]; 110 elementDataSort[i] = elementDataCopy[i];
111 } 111 }
112 } 112 }
src/main/java/com/bsth/data/gpsdata/arrival/utils/ScheduleSignalState.java 0 → 100644
  1 +package com.bsth.data.gpsdata.arrival.utils;
  2 +
  3 +import com.bsth.data.LineConfigData;
  4 +import com.bsth.data.gpsdata.GpsEntity;
  5 +import com.bsth.data.gpsdata.SignalStateData;
  6 +import com.bsth.data.gpsdata.arrival.GeoCacheData;
  7 +import com.bsth.data.gpsdata.arrival.entity.RouteReverse;
  8 +import com.bsth.data.gpsdata.arrival.entity.SignalAbnormal;
  9 +import com.bsth.data.gpsdata.arrival.entity.SignalState;
  10 +import com.bsth.data.schedule.DayOfSchedule;
  11 +import com.bsth.entity.realcontrol.LineConfig;
  12 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  13 +import org.slf4j.Logger;
  14 +import org.slf4j.LoggerFactory;
  15 +import org.springframework.beans.factory.annotation.Autowired;
  16 +import org.springframework.stereotype.Component;
  17 +
  18 +/**
  19 + * 班次信号状态分析
  20 + * Created by panzhao on 2016/12/29.
  21 + */
  22 +@Component
  23 +public class ScheduleSignalState {
  24 +
  25 + @Autowired
  26 + DayOfSchedule dayOfSchedule;
  27 +
  28 + Logger logger = LoggerFactory.getLogger(this.getClass());
  29 +
  30 + @Autowired
  31 + LineConfigData lineConfigData;
  32 +
  33 + @Autowired
  34 + SignalStateData signalStateData;
  35 +
  36 + /**
  37 + * 路由反向分析
  38 + */
  39 + public void reverseAnalyse(RouteReverse reverse) {
  40 + ScheduleRealInfo sch = dayOfSchedule.executeCurr(reverse.getNbbm());
  41 +
  42 + String bcType = sch.getBcType();
  43 +
  44 + switch (bcType) {
  45 + case "out":
  46 + outReverseAnalyse(sch, reverse);
  47 + break;
  48 + case "normal":
  49 + normalReverseAnalyse(sch, reverse);
  50 + break;
  51 + }
  52 + }
  53 +
  54 + /**
  55 + * 出场班次路由反向分析
  56 + *
  57 + * @param sch
  58 + */
  59 + private void outReverseAnalyse(ScheduleRealInfo sch, RouteReverse reverse) {
  60 + long t = reverse.getCt();
  61 + //出场班次终点时间前,允许反向轨迹
  62 + if (sch.getZdsjT() != null && sch.getZdsjT() > t) {
  63 + return;
  64 + }
  65 +
  66 + int rt;
  67 + //从实发 到 当前时间 < 计划运送时间 * 0.9
  68 + if (sch.getFcsjActual() != null && sch.getBcsj() != null) {
  69 + rt = (int) (t - sch.getFcsjActualTime());
  70 + if (rt < sch.getBcsj() * 0.9)
  71 + return;
  72 + }
  73 +
  74 + ScheduleRealInfo next = dayOfSchedule.next(sch);
  75 + if (next.getXlDir().equals(sch.getXlDir()))
  76 + return;
  77 +
  78 + //时间足够下一个班次待发时间运行到当前站
  79 + int runTime = reverse.getCount() * 1500 * 60;
  80 + if (next.getDfsjT() + runTime < t) {
  81 + //跳到下一个班次
  82 + dayOfSchedule.addExecPlan(next);
  83 + }
  84 + }
  85 +
  86 + /**
  87 + * 正常班次路由反向分析
  88 + *
  89 + * @param sch
  90 + * @param reverse
  91 + */
  92 + private void normalReverseAnalyse(ScheduleRealInfo sch, RouteReverse reverse) {
  93 + LineConfig conf = lineConfigData.get(sch.getXlBm());
  94 +
  95 + if (conf.isReadReverse()) {
  96 + //跳下一个班次
  97 + ScheduleRealInfo next = dayOfSchedule.next(sch);
  98 + if (next != null)
  99 + dayOfSchedule.addExecPlan(next);
  100 +
  101 + //记录信号状态
  102 + SignalState signalState = SignalState.reverseSignalSTate(sch, reverse);
  103 + signalStateData.put(signalState);
  104 + }
  105 + }
  106 +
  107 + public void signalRetrospect(GpsEntity gps) {
  108 + signalRetrospect(gps, dayOfSchedule.executeCurr(gps.getNbbm()));
  109 + }
  110 +
  111 + /**
  112 + * 信号追溯
  113 + *
  114 + * @param gps
  115 + * @param sch
  116 + */
  117 + public void signalRetrospect(GpsEntity gps, ScheduleRealInfo sch) {
  118 + //回放数据,是否有掉线或者漂移
  119 + CircleQueue<GpsEntity> queue = GeoCacheData.getGps(gps.getNbbm());
  120 + if (queue == null || queue.size() == 0 /*|| gps.getInstation() == 0*/)
  121 + return;
  122 +
  123 + //起始时间点
  124 + long st = 0;
  125 + ScheduleRealInfo prev = dayOfSchedule.prev(sch);
  126 +
  127 + if (prev != null) {
  128 + if (prev.getZdsjActual() != null)
  129 + st = prev.getZdsjActualTime();
  130 + else
  131 + st = (GeoCacheData.midwayStation(gps.getLineId(), gps.getUpDown(), sch.getQdzCode(), gps.getStopNo()).size() + 1) * (1000 * 60 * 5);
  132 + }
  133 +
  134 + Object[] tempArray = queue.getQueue();
  135 + int len = tempArray.length;
  136 +
  137 + Object[] array = new Object[len + 1];
  138 + System.arraycopy(tempArray, 0, array, 0, len);
  139 + array[len] = gps;
  140 +
  141 + String gpsState = "";
  142 + GpsEntity tempGps, nearGps = null;
  143 + int i = len - 1;
  144 + for (; i >= 0; i--) {
  145 + tempGps = (GpsEntity) array[i];
  146 +
  147 + gpsState = tempGps.getSignalState();
  148 + if (gpsState.equals("truncation"))
  149 + break;
  150 + else if (gpsState.equals("drift")) {
  151 + nearGps = (GpsEntity) array[i + 1];
  152 + break;
  153 + } else if (gpsState.equals("reconnection")) {
  154 + nearGps = tempGps;
  155 + break;
  156 + }
  157 +
  158 + if (tempGps.getTimestamp() < st)
  159 + break;
  160 + }
  161 +
  162 + if (nearGps != null && i > 0) {
  163 + createSignalAbnormal(gpsState, nearGps, i, array, sch);
  164 + }
  165 + }
  166 +
  167 + private void createSignalAbnormal(String gpsState, GpsEntity nearGps, int i, Object[] array, ScheduleRealInfo sch) {
  168 + switch (gpsState) {
  169 + case "drift":
  170 + driftSignalAbnormal(nearGps, i, array, sch);
  171 + break;
  172 + case "reconnection":
  173 + offlineSignalAbnormal(nearGps, ((GpsEntity) array[i - 1]), sch);
  174 + break;
  175 + }
  176 + }
  177 +
  178 + /**
  179 + * 掉线异常状态记录
  180 + *
  181 + * @param e
  182 + * @param s
  183 + */
  184 + private void offlineSignalAbnormal(GpsEntity e, GpsEntity s, ScheduleRealInfo sch) {
  185 + long st = s.getTimestamp(), et = e.getTimestamp();
  186 +
  187 + //掉线超过10分钟才记录
  188 + if (et - st < (1000 * 60 * 10))
  189 + return;
  190 +
  191 + SignalAbnormal signalAbnormal = new SignalAbnormal();
  192 + signalAbnormal.setSt(st);
  193 + signalAbnormal.setEt(et);
  194 + signalAbnormal.setAbnormalType("reconnection");
  195 + signalAbnormal.setDestCode(sch.getQdzCode());
  196 + signalAbnormal.setOutOrIn(0);
  197 +
  198 + //截断GPS
  199 + e.setSignalState("truncation");
  200 +
  201 + //记录信号状态
  202 + SignalState signalState = SignalState.abnormalSignalSTate(sch, signalAbnormal);
  203 + signalStateData.put(signalState);
  204 + }
  205 +
  206 + /**
  207 + * 漂移异常状态记录
  208 + *
  209 + * @param nearGps
  210 + * @param i
  211 + * @param array
  212 + */
  213 + private void driftSignalAbnormal(GpsEntity nearGps, int i, Object[] array, ScheduleRealInfo sch) {
  214 + GpsEntity gps, s = null;
  215 + //找到漂移开始时间
  216 + for (; i >= 0; i--) {
  217 + gps = (GpsEntity) array[i];
  218 +
  219 + if (!gps.getSignalState().equals("drift") || i == 0
  220 + || gps.getSignalState().equals("truncation")) {
  221 + s = gps;
  222 + break;
  223 + }
  224 + }
  225 +
  226 + long st = s.getTimestamp(), et = nearGps.getTimestamp();
  227 + if (et - st < (1000 * 60 * 3))
  228 + return;
  229 + /*if (s != null){
  230 + st = s.getTimestamp();
  231 + //漂移小于3分钟
  232 + if(et - st < (1000 * 60 * 3))
  233 + return;
  234 + }*/
  235 +
  236 +
  237 + SignalAbnormal signalAbnormal = new SignalAbnormal();
  238 + signalAbnormal.setSt(st);
  239 + signalAbnormal.setEt(et);
  240 + signalAbnormal.setAbnormalType("drift");
  241 + signalAbnormal.setDestCode(sch.getQdzCode());
  242 + signalAbnormal.setOutOrIn(0);
  243 +
  244 + //截断GPS
  245 + nearGps.setSignalState("truncation");
  246 +
  247 + //记录信号状态
  248 + SignalState signalState = SignalState.abnormalSignalSTate(sch, signalAbnormal);
  249 + signalStateData.put(signalState);
  250 + }
  251 +}
src/main/java/com/bsth/data/gpsdata/arrival/utils/SignalSchPlanMatcher.java 0 → 100644
  1 +package com.bsth.data.gpsdata.arrival.utils;
  2 +
  3 +import com.bsth.data.gpsdata.GpsEntity;
  4 +import com.bsth.data.schedule.DayOfSchedule;
  5 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.stereotype.Component;
  8 +
  9 +/**
  10 + * 班次匹配器
  11 + * Created by panzhao on 2016/12/31.
  12 + */
  13 +@Component
  14 +public class SignalSchPlanMatcher {
  15 +
  16 + @Autowired
  17 + DayOfSchedule dayOfSchedule;
  18 +
  19 + /**
  20 + * 发车信号匹配
  21 + * @param outSigal
  22 + * @param sch
  23 + * @return
  24 + */
  25 + public void outMatch(GpsEntity outSigal, ScheduleRealInfo sch){
  26 + long t = outSigal.getTimestamp();
  27 + if(t < sch.getDfsjT())
  28 + return;
  29 +
  30 + //下一个相同走向的班次
  31 + ScheduleRealInfo next = dayOfSchedule.nextSame(sch);
  32 + if(next == null || !next.getQdzCode().equals(sch.getQdzCode()))
  33 + return;
  34 +
  35 + //晚于班次间隔百分之70,跳下一个班次
  36 + double s = (int) (next.getDfsjT() - sch.getDfsjT());
  37 + double r = (int) (t - sch.getDfsjT());
  38 + if(r / s > 0.7){
  39 + dayOfSchedule.addExecPlan(next);
  40 + outMatch(outSigal, next);
  41 + }
  42 + }
  43 +}
src/main/java/com/bsth/data/gpsdata/recovery/GpsDataRecovery.java
@@ -28,7 +28,7 @@ import java.util.concurrent.Executors; @@ -28,7 +28,7 @@ import java.util.concurrent.Executors;
28 * Created by panzhao on 2016/12/24. 28 * Created by panzhao on 2016/12/24.
29 */ 29 */
30 @Component 30 @Component
31 -public class GpsDataRecovery implements ApplicationContextAware{ 31 +public class GpsDataRecovery implements ApplicationContextAware {
32 32
33 static Logger logger = LoggerFactory.getLogger(GpsDataRecovery.class); 33 static Logger logger = LoggerFactory.getLogger(GpsDataRecovery.class);
34 34
@@ -48,7 +48,7 @@ public class GpsDataRecovery implements ApplicationContextAware{ @@ -48,7 +48,7 @@ public class GpsDataRecovery implements ApplicationContextAware{
48 //按车辆分组数据 48 //按车辆分组数据
49 ArrayListMultimap<String, GpsEntity> listMap = ArrayListMultimap.create(); 49 ArrayListMultimap<String, GpsEntity> listMap = ArrayListMultimap.create();
50 for (GpsEntity gps : list) { 50 for (GpsEntity gps : list) {
51 - if(gps.getNbbm() != null) 51 + if (gps.getNbbm() != null)
52 listMap.put(gps.getNbbm(), gps); 52 listMap.put(gps.getNbbm(), gps);
53 } 53 }
54 54
@@ -60,6 +60,8 @@ public class GpsDataRecovery implements ApplicationContextAware{ @@ -60,6 +60,8 @@ public class GpsDataRecovery implements ApplicationContextAware{
60 for (String nbbm : keys) { 60 for (String nbbm : keys) {
61 Collections.sort(listMap.get(nbbm), comp); 61 Collections.sort(listMap.get(nbbm), comp);
62 threadPool.execute(new RecoveryThread(listMap.get(nbbm), count)); 62 threadPool.execute(new RecoveryThread(listMap.get(nbbm), count));
  63 + /*if(nbbm.equals("YT-CD008"))
  64 + new RecoveryThread(listMap.get(nbbm), count).run();*/
63 } 65 }
64 66
65 try { 67 try {
@@ -124,7 +126,7 @@ public class GpsDataRecovery implements ApplicationContextAware{ @@ -124,7 +126,7 @@ public class GpsDataRecovery implements ApplicationContextAware{
124 reverseSignalHandle = applicationContext.getBean(ReverseSignalHandle.class); 126 reverseSignalHandle = applicationContext.getBean(ReverseSignalHandle.class);
125 } 127 }
126 128
127 - public static class GpsComp implements Comparator<GpsEntity>{ 129 + public static class GpsComp implements Comparator<GpsEntity> {
128 130
129 @Override 131 @Override
130 public int compare(GpsEntity g1, GpsEntity g2) { 132 public int compare(GpsEntity g1, GpsEntity g2) {
@@ -132,26 +134,28 @@ public class GpsDataRecovery implements ApplicationContextAware{ @@ -132,26 +134,28 @@ public class GpsDataRecovery implements ApplicationContextAware{
132 } 134 }
133 } 135 }
134 136
135 - public static class RecoveryThread implements Runnable{ 137 + public static class RecoveryThread implements Runnable {
136 List<GpsEntity> list; 138 List<GpsEntity> list;
137 CountDownLatch count; 139 CountDownLatch count;
138 140
139 - RecoveryThread(List<GpsEntity> list, CountDownLatch count){ 141 + RecoveryThread(List<GpsEntity> list, CountDownLatch count) {
140 this.list = list; 142 this.list = list;
141 this.count = count; 143 this.count = count;
142 } 144 }
  145 +
143 @Override 146 @Override
144 public void run() { 147 public void run() {
145 try { 148 try {
146 //循环gps恢复数据 149 //循环gps恢复数据
147 CircleQueue<GpsEntity> prevs; 150 CircleQueue<GpsEntity> prevs;
148 151
149 - for(GpsEntity gps : list){ 152 + for (GpsEntity gps : list) {
  153 +
150 prevs = GeoCacheData.getGps(gps.getNbbm()); 154 prevs = GeoCacheData.getGps(gps.getNbbm());
151 //掉线处理 155 //掉线处理
152 offlineSignalHandle.handle(gps, prevs); 156 offlineSignalHandle.handle(gps, prevs);
153 //状态处理 157 //状态处理
154 - if(!correctSignalHandle.handle(gps, prevs)) 158 + if (!correctSignalHandle.handle(gps, prevs))
155 continue; 159 continue;
156 //场,站内外判断 160 //场,站内外判断
157 stationInsideHandle.handle(gps, prevs); 161 stationInsideHandle.handle(gps, prevs);
@@ -160,11 +164,12 @@ public class GpsDataRecovery implements ApplicationContextAware{ @@ -160,11 +164,12 @@ public class GpsDataRecovery implements ApplicationContextAware{
160 //进出站动作处理 164 //进出站动作处理
161 inOutStationSignalHandle.handle(gps, prevs); 165 inOutStationSignalHandle.handle(gps, prevs);
162 GeoCacheData.putGps(gps); 166 GeoCacheData.putGps(gps);
  167 +
  168 + //Thread.sleep(50);
163 } 169 }
164 - }catch (Exception e){ 170 + } catch (Exception e) {
165 logger.error("", e); 171 logger.error("", e);
166 - }  
167 - finally { 172 + } finally {
168 count.countDown(); 173 count.countDown();
169 } 174 }
170 } 175 }
src/main/java/com/bsth/data/schedule/DayOfSchedule.java
@@ -2,8 +2,6 @@ package com.bsth.data.schedule; @@ -2,8 +2,6 @@ package com.bsth.data.schedule;
2 2
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONArray; 4 import com.alibaba.fastjson.JSONArray;
5 -import com.bsth.Application;  
6 -import com.bsth.data.BasicData;  
7 import com.bsth.data.LineConfigData; 5 import com.bsth.data.LineConfigData;
8 import com.bsth.data.directive.FirstScheduleCheckThread; 6 import com.bsth.data.directive.FirstScheduleCheckThread;
9 import com.bsth.data.gpsdata.GpsRealData; 7 import com.bsth.data.gpsdata.GpsRealData;
@@ -29,12 +27,12 @@ import org.slf4j.Logger; @@ -29,12 +27,12 @@ import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory; 27 import org.slf4j.LoggerFactory;
30 import org.springframework.beans.factory.annotation.Autowired; 28 import org.springframework.beans.factory.annotation.Autowired;
31 import org.springframework.boot.CommandLineRunner; 29 import org.springframework.boot.CommandLineRunner;
  30 +import org.springframework.core.annotation.Order;
32 import org.springframework.stereotype.Component; 31 import org.springframework.stereotype.Component;
33 32
34 import java.text.ParseException; 33 import java.text.ParseException;
35 import java.text.SimpleDateFormat; 34 import java.text.SimpleDateFormat;
36 import java.util.*; 35 import java.util.*;
37 -import java.util.concurrent.TimeUnit;  
38 36
39 /** 37 /**
40 * @author PanZhao 38 * @author PanZhao
@@ -43,443 +41,568 @@ import java.util.concurrent.TimeUnit; @@ -43,443 +41,568 @@ import java.util.concurrent.TimeUnit;
43 * @date 2016年8月15日 上午10:16:12 41 * @date 2016年8月15日 上午10:16:12
44 */ 42 */
45 @Component 43 @Component
  44 +@Order(value = 3)
46 public class DayOfSchedule implements CommandLineRunner { 45 public class DayOfSchedule implements CommandLineRunner {
47 46
48 - Logger logger = LoggerFactory.getLogger(this.getClass());  
49 -  
50 - // 按车辆分组的班次数据  
51 - private static ArrayListMultimap<String, ScheduleRealInfo> nbbmScheduleMap;  
52 -  
53 - // 班次主键映射  
54 - private static Map<Long, ScheduleRealInfo> id2SchedulMap;  
55 -  
56 - // 车辆和排班起终点站对照(包括进出的停车场,区间起终点)  
57 - private static TreeMultimap<String, String> nbbm2SEStationMap;  
58 -  
59 - //车辆 ——> 当前执行班次  
60 - private static Map<String, ScheduleRealInfo> carExecutePlanMap;  
61 -  
62 - // 持久化缓冲区  
63 - public static LinkedList<ScheduleRealInfo> pstBuffer;  
64 -  
65 - // 排序器  
66 - private static ScheduleComparator.FCSJ schFCSJComparator;  
67 -  
68 - @Autowired  
69 - LineConfigData lineConfigData;  
70 -  
71 - @Autowired  
72 - ScheduleRealInfoRepository schRepository;  
73 -  
74 - @Autowired  
75 - SchedulePlanInfoService schPlanService;  
76 -  
77 - @Autowired  
78 - SchAttrCalculator schAttrCalculator;  
79 -  
80 - @Autowired  
81 - SendUtils sendUtils;  
82 -  
83 - @Autowired  
84 - GpsRealData gpsRealData;  
85 -  
86 - /** 线路当前使用的排班的日期 */  
87 - public static Map<String, String> currSchDateMap;  
88 -  
89 - static {  
90 - nbbmScheduleMap = ArrayListMultimap.create();  
91 - id2SchedulMap = new HashMap<>();  
92 - pstBuffer = new LinkedList<>();  
93 - schFCSJComparator = new ScheduleComparator.FCSJ();  
94 - currSchDateMap = new HashMap<>();  
95 - nbbm2SEStationMap = TreeMultimap.create();  
96 - carExecutePlanMap = new HashMap<>();  
97 - }  
98 -  
99 - @Autowired  
100 - ScheduleRefreshThread scheduleRefreshThread;  
101 -  
102 - @Autowired  
103 - SchedulePstThread schedulePstThread;  
104 -  
105 - @Autowired  
106 - FirstScheduleCheckThread firstScheduleCheckThread;  
107 -  
108 - @Autowired  
109 - ScheduleLateThread scheduleLateThread;  
110 -  
111 - private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd")  
112 - ,fmtHHmm = DateTimeFormat.forPattern("HH:mm");  
113 -  
114 - @Override  
115 - public void run(String... arg0) throws Exception {  
116 - //翻班线程  
117 - Application.mainServices.scheduleWithFixedDelay(scheduleRefreshThread, 15, 240, TimeUnit.SECONDS);  
118 - //入库  
119 - Application.mainServices.scheduleWithFixedDelay(schedulePstThread, 60, 60, TimeUnit.SECONDS);  
120 - //首班出场指令补发器  
121 - Application.mainServices.scheduleWithFixedDelay(firstScheduleCheckThread, 30, 240, TimeUnit.SECONDS);  
122 - //班次误点扫描  
123 - //Application.mainServices.scheduleWithFixedDelay(scheduleLateThread, 60, 60, TimeUnit.SECONDS);  
124 - }  
125 -  
126 - public Map<String, String> getCurrSchDate() {  
127 - return currSchDateMap;  
128 - }  
129 -  
130 - /**  
131 - *  
132 - * @Title: calcSchDateB  
133 - * @Description: TODO(计算线路当前应该使用的排班日期)  
134 - */  
135 - public String calcSchDate(String lineCode) {  
136 - LineConfig conf = lineConfigData.get(lineCode);  
137 - long ct = System.currentTimeMillis();  
138 -  
139 - String schDate = fmtyyyyMMdd.print(ct);  
140 - // 小于当天起始运营时间,则取前一天的排班  
141 - if (ct < conf.getCurrStartTime())  
142 - schDate = DateUtils.subtractDay(schDate, 1);  
143 -  
144 - return schDate;  
145 - }  
146 -  
147 - /**  
148 - * @Title: reloadSch  
149 - * @Title: reloadSch  
150 - * @Description: TODO(重新载入排班)  
151 - * @param @param  
152 - * lineCode 线路编码  
153 - * @param @param  
154 - * schDate 班次日期 yyyy-MM-dd  
155 - * @param @param  
156 - * forcePlan 强制从计划调度重新抓取  
157 - */  
158 - public int reloadSch(String lineCode, String schDate, boolean forcePlan) {  
159 - try {  
160 - List<ScheduleRealInfo> list;  
161 -  
162 - if (forcePlan)  
163 - removeRealSch(lineCode, schDate);  
164 - else  
165 - clearRAMData(lineCode);  
166 -  
167 - if (existRealSch(lineCode, schDate))  
168 - list = loadRealSch(lineCode, schDate);// 从实际排班表加载  
169 - else {  
170 - list = loadPlanSch(lineCode, schDate);// 从计划排班表加载  
171 - // 写入数据库  
172 - batchSave(list);  
173 - }  
174 -  
175 - //更新线路和班次日期对照  
176 - currSchDateMap.put(lineCode, schDate);  
177 - //添加到缓存  
178 - putAll(list);  
179 -  
180 - Set<String> cars = searchAllCars(list);  
181 - //计算“起点站应到”时间  
182 - for(String nbbm : cars)  
183 - schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm));  
184 -  
185 - //是否是出站即出场  
186 - LineConfig conf = lineConfigData.get(lineCode);  
187 - if(conf.getOutConfig() == 2){  
188 - for(String nbbm : cars)  
189 - schAttrCalculator.connectOutSchedule(nbbmScheduleMap.get(nbbm));  
190 - }  
191 -  
192 - // 页面 翻班通知  
193 - sendUtils.shiftSchedule(lineCode);  
194 - } catch (Exception e) {  
195 - logger.error("", e);  
196 - return -1;  
197 - } 47 + Logger logger = LoggerFactory.getLogger(this.getClass());
198 48
199 - return 0;  
200 - }  
201 -  
202 - /**  
203 - *  
204 - * @Title: searchAllCars  
205 - * @Description: TODO(搜索班次集合中的车辆)  
206 - */  
207 - private Set<String> searchAllCars(List<ScheduleRealInfo> list) {  
208 - Set<String> cars = new HashSet<>();  
209 - for(ScheduleRealInfo sch : list)  
210 - cars.add(sch.getClZbh());  
211 -  
212 - return cars;  
213 - }  
214 -  
215 - private void putAll(List<ScheduleRealInfo> list) {  
216 - for (ScheduleRealInfo sch : list)  
217 - put(sch);  
218 - }  
219 -  
220 - /**  
221 - * @Title: removeRealSch  
222 - * @Description: TODO(清除实际排班,包括数据库和内存数据)  
223 - * @param @param  
224 - * lineCode 线路编码  
225 - * @param @param  
226 - * schDate 班次日期 yyyy-MM-dd  
227 - */  
228 - public void removeRealSch(String lineCode, String schDate) throws Exception {  
229 - try {  
230 - // 清理数据库数据  
231 - schRepository.deleteByLineCodeAndDate(lineCode + "", schDate);  
232 -  
233 - // 清理内存数据  
234 - clearRAMData(lineCode + "");  
235 - } catch (Exception e) {  
236 - logger.error("removeRealSch error, " + lineCode + " -" + schDate, e);  
237 - throw e;  
238 - }  
239 - }  
240 -  
241 - /**  
242 - *  
243 - * @Title: clearRAMData  
244 - * @Description: TODO(清理内存数据)  
245 - */  
246 - public void clearRAMData(String lineCode) {  
247 - int count = 0;  
248 - List<ScheduleRealInfo> remList = new ArrayList<>();  
249 - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();  
250 - for (ScheduleRealInfo sch : schs) {  
251 - if (sch.getXlBm().equals(lineCode))  
252 - remList.add(sch);  
253 - }  
254 -  
255 - for(ScheduleRealInfo sch : remList){  
256 - if(null != sch){  
257 - nbbmScheduleMap.remove(sch.getClZbh(), sch);  
258 - id2SchedulMap.remove(sch.getId());  
259 - count ++;  
260 - }  
261 - }  
262 -  
263 - logger.info(lineCode + "排班清理 " + count);  
264 - }  
265 -  
266 - /**  
267 - * @Title: existRealSch  
268 - * @Description: TODO(实际排班是否已存在)  
269 - */  
270 - public boolean existRealSch(String lineCode, String schDate) {  
271 - int count = schRepository.countByLineCodeAndDate(lineCode, schDate);  
272 - return count > 0;  
273 - }  
274 -  
275 - /**  
276 - * @Title: loadRealSch  
277 - * @Description: TODO(从实际排班表加载数据)  
278 - */  
279 - public List<ScheduleRealInfo> loadRealSch(String lineCode, String schDate) {  
280 - return schRepository.findByLineCodeAndDate(lineCode, schDate);  
281 - }  
282 -  
283 - /**  
284 - * @Title: loadPlanSch  
285 - * @Description: TODO(从计划排班表加载数据)  
286 - */  
287 - public List<ScheduleRealInfo> loadPlanSch(String lineCode, String schDate) {  
288 - logger.info("从计划排班表恢复排班,lineCode: " + lineCode + ", schDate: " + schDate);  
289 - List<ScheduleRealInfo> realList = new ArrayList<>();  
290 -  
291 - try {  
292 - Map<String, Object> data = new HashMap<>();  
293 -  
294 - data.put("scheduleDate_eq", fmtyyyyMMdd.parseDateTime(schDate).toDate());  
295 - data.put("xlBm_eq", lineCode);  
296 -  
297 - // 查询计划排班  
298 - List<SchedulePlanInfo> planItr = cleanSchPlanItr(schPlanService.list(data).iterator());  
299 -  
300 - // 转换为实际排班  
301 - realList = JSONArray.parseArray(JSON.toJSONString(planItr), ScheduleRealInfo.class);  
302 -  
303 - for (ScheduleRealInfo sch : realList) {  
304 - sch.setScheduleDateStr(fmtyyyyMMdd.print(sch.getScheduleDate().getTime()));  
305 - sch.setRealExecDate(sch.getScheduleDateStr());  
306 - // 计划终点时间  
307 - if (sch.getBcsj() != null) {  
308 - sch.setZdsj(fmtHHmm.print(fmtHHmm.parseMillis(sch.getFcsj()) + (sch.getBcsj() * 60 * 1000)));  
309 - sch.setLate(false);  
310 - }  
311 - //计划里程为0,设置NULL  
312 - if(sch.getJhlc() != null && sch.getJhlc() == 0)  
313 - sch.setJhlc(null);  
314 - }  
315 - } catch (Exception e) {  
316 - logger.error("", e);  
317 - }  
318 - return realList;  
319 - }  
320 -  
321 - /**  
322 - * @Title: batchSave  
323 - * @Description: TODO(批量入库)  
324 - */  
325 - private void batchSave(List<ScheduleRealInfo> list) {  
326 - // 查询数据库最大ID  
327 - Long id = schRepository.getMaxId();  
328 - if (null == id)  
329 - id = 0L;  
330 - id++;  
331 -  
332 - SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");  
333 - for (ScheduleRealInfo item : list) {  
334 - item.setSpId(item.getId());// 保留原始的计划ID  
335 - item.setId(id++);// 设置ID  
336 - item.setScheduleDateStr(sdfyyyyMMdd.format(item.getScheduleDate()));  
337 - } 49 + // 按车辆分组的班次数据
  50 + private static ArrayListMultimap<String, ScheduleRealInfo> nbbmScheduleMap;
338 51
339 - // 入库  
340 - new BatchSaveUtils<ScheduleRealInfo>().saveList(list, ScheduleRealInfo.class);  
341 - } 52 + // 班次主键映射
  53 + private static Map<Long, ScheduleRealInfo> id2SchedulMap;
342 54
343 - private List<SchedulePlanInfo> cleanSchPlanItr(Iterator<SchedulePlanInfo> itrab) {  
344 - List<SchedulePlanInfo> list = new ArrayList<>(); 55 + // 车辆和排班起终点站对照(包括进出的停车场,区间起终点)
  56 + private static TreeMultimap<String, String> nbbm2SEStationMap;
345 57
346 - SchedulePlanInfo sp;  
347 - while (itrab.hasNext()) {  
348 - sp = itrab.next();  
349 - sp.setSchedulePlan(null);  
350 - list.add(sp);  
351 - }  
352 - return list;  
353 - }  
354 -  
355 - /**  
356 - *  
357 - * @Title: findByLineCode  
358 - * @Description: TODO(lineCode 获取班次)  
359 - */  
360 - public List<ScheduleRealInfo> findByLineCode(String lineCode) {  
361 - List<ScheduleRealInfo> rs = new ArrayList<>(); 58 + //车辆 ——> 当前执行班次
  59 + private static Map<String, ScheduleRealInfo> carExecutePlanMap;
362 60
363 - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();  
364 - for (ScheduleRealInfo sch : schs) {  
365 - if (sch.getXlBm().equals(lineCode))  
366 - rs.add(sch);  
367 - }  
368 - return rs;  
369 - }  
370 -  
371 - /**  
372 - *  
373 - * @Title: findCarByLineCode  
374 - * @Description: TODO(线路下运营的车辆)  
375 - */  
376 - public Set<String> findCarByLineCode(String lineCode){  
377 - Set<String> rs = new HashSet<>();  
378 -  
379 - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();  
380 - for (ScheduleRealInfo sch : schs) {  
381 - if (sch.getXlBm().equals(lineCode))  
382 - rs.add(sch.getClZbh());  
383 - }  
384 -  
385 - return rs;  
386 - }  
387 -  
388 - public List<ScheduleRealInfo> findByNbbm(String nbbm) {  
389 - return nbbmScheduleMap.get(nbbm);  
390 - }  
391 -  
392 - /**  
393 - *  
394 - * @Title: findByLineAndUpDown  
395 - * @Description: TODO(lineCode 和走向获取班次)  
396 - */  
397 - public List<ScheduleRealInfo> findByLineAndUpDown(String lineCode, Integer upDown) {  
398 - List<ScheduleRealInfo> list = findByLineCode(lineCode), rs = new ArrayList<>();  
399 -  
400 - for (ScheduleRealInfo sch : list) {  
401 - if (sch.getXlDir().equals(upDown + ""))  
402 - rs.add(sch);  
403 - }  
404 - return rs;  
405 - } 61 + // 持久化缓冲区
  62 + public static LinkedList<ScheduleRealInfo> pstBuffer;
406 63
407 - public ScheduleRealInfo get(long id) {  
408 - return id2SchedulMap.get(id);  
409 - } 64 + // 排序器
  65 + private static ScheduleComparator.FCSJ schFCSJComparator;
410 66
411 - public Set<String> getSEStationList(String nbbm) {  
412 - return nbbm2SEStationMap.get(nbbm);  
413 - } 67 + @Autowired
  68 + LineConfigData lineConfigData;
414 69
415 - /**  
416 - *  
417 - * @Title: next  
418 - * @Description: TODO(下一个班次)  
419 - */  
420 - public ScheduleRealInfo next(ScheduleRealInfo sch) { 70 + @Autowired
  71 + ScheduleRealInfoRepository schRepository;
421 72
422 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());  
423 -  
424 - boolean flag = false;  
425 - ScheduleRealInfo next = null;  
426 - for(ScheduleRealInfo temp : list){  
427 - if(temp.getId() == sch.getId()){  
428 - flag = true;  
429 - continue;  
430 - }  
431 - //忽略烂班  
432 - if(temp.isDestroy())  
433 - continue;  
434 -  
435 - if(flag){  
436 - next = temp;  
437 - break;  
438 - }  
439 - }  
440 - return next;  
441 - } 73 + @Autowired
  74 + SchedulePlanInfoService schPlanService;
442 75
443 - public void put(ScheduleRealInfo sch) { 76 + @Autowired
  77 + SchAttrCalculator schAttrCalculator;
444 78
445 - schAttrCalculator  
446 - .calcRealDate(sch)  
447 - .calcAllTimeByFcsj(sch); 79 + @Autowired
  80 + SendUtils sendUtils;
  81 +
  82 + @Autowired
  83 + GpsRealData gpsRealData;
  84 +
  85 + /**
  86 + * 线路当前使用的排班的日期
  87 + */
  88 + public static Map<String, String> currSchDateMap;
  89 +
  90 + static {
  91 + nbbmScheduleMap = ArrayListMultimap.create();
  92 + id2SchedulMap = new HashMap<>();
  93 + pstBuffer = new LinkedList<>();
  94 + schFCSJComparator = new ScheduleComparator.FCSJ();
  95 + currSchDateMap = new HashMap<>();
  96 + nbbm2SEStationMap = TreeMultimap.create();
  97 + carExecutePlanMap = new HashMap<>();
  98 + }
  99 +
  100 + @Autowired
  101 + ScheduleRefreshThread scheduleRefreshThread;
  102 +
  103 + @Autowired
  104 + SchedulePstThread schedulePstThread;
  105 +
  106 + @Autowired
  107 + FirstScheduleCheckThread firstScheduleCheckThread;
  108 +
  109 + @Autowired
  110 + ScheduleLateThread scheduleLateThread;
  111 +
  112 + @Autowired
  113 + SubmitToTrafficManage submitToTrafficManage;
  114 +
  115 + @Autowired
  116 + LineConfigData lineConfigs;
  117 +
  118 + @Autowired
  119 + GpsDataRecovery gpsDataRecovery;
  120 +
  121 + private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd"), fmtHHmm = DateTimeFormat.forPattern("HH:mm");
  122 +
  123 + @Override
  124 + public void run(String... arg0) throws Exception {
  125 + //从数据库恢复排班
  126 + //dataRecovery();
  127 +
  128 + //翻班线程
  129 +// Application.mainServices.scheduleWithFixedDelay(scheduleRefreshThread, 15, 240, TimeUnit.SECONDS);
  130 + //入库
  131 +// Application.mainServices.scheduleWithFixedDelay(schedulePstThread, 60, 60, TimeUnit.SECONDS);
  132 + //首班出场指令补发器
  133 +// Application.mainServices.scheduleWithFixedDelay(firstScheduleCheckThread, 30, 240, TimeUnit.SECONDS);
  134 + //班次误点扫描
  135 +// Application.mainServices.scheduleWithFixedDelay(scheduleLateThread, 60, 60, TimeUnit.SECONDS);
  136 +
  137 + //每天凌晨2点20提交数据到运管处
  138 + long diff = (DateUtils.getTimestamp() + 1000 * 60 * 140) - System.currentTimeMillis();
  139 + if (diff < 0)
  140 + diff += (1000 * 60 * 60 * 24);
  141 +
  142 + logger.info(diff / 1000 / 60 + "分钟之后提交到运管处");
  143 + //Application.mainServices.scheduleWithFixedDelay(submitToTrafficManage, diff / 1000, 60 * 60 * 24, TimeUnit.SECONDS);
  144 + }
  145 +
  146 + //数据恢复
  147 + private void dataRecovery() {
  148 + GpsDataRecovery.run = true;
  149 +
  150 + Collection<LineConfig> confs = lineConfigs.getAll();
  151 + String lineCode, currSchDate;
  152 + for (LineConfig conf : confs) {
  153 + lineCode = conf.getLine().getLineCode();
  154 + currSchDate = calcSchDate(lineCode);
  155 + //加载班次数据
  156 + reloadSch(lineCode, currSchDate, false);
  157 + }
  158 +
  159 + //恢复gps数据
  160 + gpsDataRecovery.recovery();
  161 + }
  162 +
  163 + public Map<String, String> getCurrSchDate() {
  164 + return currSchDateMap;
  165 + }
  166 +
  167 + /**
  168 + * @Title: calcSchDateB
  169 + * @Description: TODO(计算线路当前应该使用的排班日期)
  170 + */
  171 + public String calcSchDate(String lineCode) {
  172 + LineConfig conf = lineConfigData.get(lineCode);
  173 + long ct = System.currentTimeMillis();
  174 +
  175 + String schDate = fmtyyyyMMdd.print(ct);
  176 + // 小于当天起始运营时间,则取前一天的排班
  177 + if (ct < conf.getCurrStartTime())
  178 + schDate = DateUtils.subtractDay(schDate, 1);
  179 +
  180 + return schDate;
  181 + }
  182 +
  183 + /**
  184 + * @param @param lineCode 线路编码
  185 + * @param @param schDate 班次日期 yyyy-MM-dd
  186 + * @param @param forcePlan 强制从计划调度重新抓取
  187 + * @Title: reloadSch
  188 + * @Title: reloadSch
  189 + * @Description: TODO(重新载入排班)
  190 + */
  191 + public int reloadSch(String lineCode, String schDate, boolean forcePlan) {
  192 + try {
  193 + List<ScheduleRealInfo> list;
  194 +
  195 + if (forcePlan)
  196 + removeRealSch(lineCode, schDate);
  197 + else
  198 + clearRAMData(lineCode);
  199 +
  200 + if (existRealSch(lineCode, schDate))
  201 + list = loadRealSch(lineCode, schDate);// 从实际排班表加载
  202 + else {
  203 + list = loadPlanSch(lineCode, schDate);// 从计划排班表加载
  204 + // 写入数据库
  205 + batchSave(list);
  206 + }
  207 +
  208 + //更新线路和班次日期对照
  209 + currSchDateMap.put(lineCode, schDate);
  210 + //添加到缓存
  211 + putAll(list);
  212 +
  213 + Set<String> cars = searchAllCars(list);
  214 + for (String nbbm : cars) {
  215 + //计算“起点站应到”时间
  216 + schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm));
  217 + //车辆 ——> 要执行的班次对照
  218 + reCalcExecPlan(nbbm);
  219 + }
  220 +
  221 + // 页面 翻班通知
  222 + //sendUtils.shiftSchedule(lineCode);
  223 + } catch (Exception e) {
  224 + logger.error("", e);
  225 + return -1;
  226 + }
  227 +
  228 + return 0;
  229 + }
  230 +
  231 + /**
  232 + * @Title: searchAllCars
  233 + * @Description: TODO(搜索班次集合中的车辆)
  234 + */
  235 + private Set<String> searchAllCars(List<ScheduleRealInfo> list) {
  236 + Set<String> cars = new HashSet<>();
  237 + for (ScheduleRealInfo sch : list)
  238 + cars.add(sch.getClZbh());
  239 +
  240 + return cars;
  241 + }
  242 +
  243 + private void putAll(List<ScheduleRealInfo> list) {
  244 + for (ScheduleRealInfo sch : list)
  245 + put(sch);
  246 + }
  247 +
  248 + /**
  249 + * @param @param lineCode 线路编码
  250 + * @param @param schDate 班次日期 yyyy-MM-dd
  251 + * @Title: removeRealSch
  252 + * @Description: TODO(清除实际排班,包括数据库和内存数据)
  253 + */
  254 + public void removeRealSch(String lineCode, String schDate) throws Exception {
  255 + try {
  256 + // 清理数据库数据
  257 + schRepository.deleteByLineCodeAndDate(lineCode + "", schDate);
  258 +
  259 + // 清理内存数据
  260 + clearRAMData(lineCode + "");
  261 + } catch (Exception e) {
  262 + logger.error("removeRealSch error, " + lineCode + " -" + schDate, e);
  263 + throw e;
  264 + }
  265 + }
  266 +
  267 + /**
  268 + * @Title: clearRAMData
  269 + * @Description: TODO(清理内存数据)
  270 + */
  271 + public void clearRAMData(String lineCode) {
  272 + int count = 0;
  273 + List<ScheduleRealInfo> remList = new ArrayList<>();
  274 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  275 + for (ScheduleRealInfo sch : schs) {
  276 + if (sch.getXlBm().equals(lineCode))
  277 + remList.add(sch);
  278 + }
  279 +
  280 + for (ScheduleRealInfo sch : remList) {
  281 + if (null != sch) {
  282 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  283 + id2SchedulMap.remove(sch.getId());
  284 + count++;
  285 + }
  286 + }
  287 +
  288 + logger.info(lineCode + "排班清理 " + count);
  289 + }
  290 +
  291 + /**
  292 + * @Title: existRealSch
  293 + * @Description: TODO(实际排班是否已存在)
  294 + */
  295 + public boolean existRealSch(String lineCode, String schDate) {
  296 + int count = schRepository.countByLineCodeAndDate(lineCode, schDate);
  297 + return count > 0;
  298 + }
  299 +
  300 + /**
  301 + * @Title: loadRealSch
  302 + * @Description: TODO(从实际排班表加载数据)
  303 + */
  304 + public List<ScheduleRealInfo> loadRealSch(String lineCode, String schDate) {
  305 + return schRepository.findByLineCodeAndDate(lineCode, schDate);
  306 + }
  307 +
  308 + /**
  309 + * @Title: loadPlanSch
  310 + * @Description: TODO(从计划排班表加载数据)
  311 + */
  312 + public List<ScheduleRealInfo> loadPlanSch(String lineCode, String schDate) {
  313 + logger.info("从计划排班表恢复排班,lineCode: " + lineCode + ", schDate: " + schDate);
  314 + List<ScheduleRealInfo> realList = new ArrayList<>();
  315 +
  316 + try {
  317 + Map<String, Object> data = new HashMap<>();
  318 +
  319 + data.put("scheduleDate_eq", fmtyyyyMMdd.parseDateTime(schDate).toDate());
  320 + data.put("xlBm_eq", lineCode);
  321 +
  322 + // 查询计划排班
  323 + List<SchedulePlanInfo> planItr = cleanSchPlanItr(schPlanService.list(data).iterator());
  324 +
  325 + // 转换为实际排班
  326 + realList = JSONArray.parseArray(JSON.toJSONString(planItr), ScheduleRealInfo.class);
  327 +
  328 + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
  329 + String fcsj;
  330 + for (ScheduleRealInfo sch : realList) {
  331 + sch.setScheduleDateStr(fmtyyyyMMdd.print(sch.getScheduleDate().getTime()));
  332 + sch.setRealExecDate(sch.getScheduleDateStr());
  333 +
  334 + if (StringUtils.isEmpty(sch.getFcsj()))
  335 + sch.setFcsj("00:00");
  336 +
  337 + fcsj = sch.getFcsj().trim();
  338 + //处理一下发车时间格式没有:号的问题
  339 + if (fcsj.indexOf(":") == -1 && fcsj.length() >= 4) {
  340 + sch.setFcsj(fcsj.substring(0, 2) + ":" + fcsj.substring(2, 4));
  341 + }
  342 +
  343 + try {
  344 + sdf.parse(sch.getFcsj());
  345 + } catch (ParseException e) {
  346 + //发车时间仍然校验不过的,直接写成00:00
  347 + sch.setFcsj("00:00");
  348 + }
  349 + sch.setDfsj(sch.getFcsj());
  350 +
  351 + // 计划终点时间
  352 + if (sch.getBcsj() != null) {
  353 + sch.setZdsj(fmtHHmm.print(fmtHHmm.parseMillis(sch.getFcsj()) + (sch.getBcsj() * 60 * 1000)));
  354 + sch.setLate(false);
  355 + }
  356 + //计划里程为0,设置NULL
  357 + if (sch.getJhlc() != null && sch.getJhlc() == 0)
  358 + sch.setJhlc(null);
  359 + }
  360 + } catch (Exception e) {
  361 + logger.error("", e);
  362 + }
  363 + return realList;
  364 + }
  365 +
  366 + /**
  367 + * @Title: batchSave
  368 + * @Description: TODO(批量入库)
  369 + */
  370 + private void batchSave(List<ScheduleRealInfo> list) {
  371 + // 查询数据库最大ID
  372 + Long id = schRepository.getMaxId();
  373 + if (null == id)
  374 + id = 0L;
  375 + id++;
  376 +
  377 + SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
  378 + for (ScheduleRealInfo item : list) {
  379 + item.setSpId(item.getId());// 保留原始的计划ID
  380 + item.setId(id++);// 设置ID
  381 + item.setScheduleDateStr(sdfyyyyMMdd.format(item.getScheduleDate()));
  382 + }
  383 +
  384 + // 入库
  385 + new BatchSaveUtils<ScheduleRealInfo>().saveList(list, ScheduleRealInfo.class);
  386 + }
  387 +
  388 + private List<SchedulePlanInfo> cleanSchPlanItr(Iterator<SchedulePlanInfo> itrab) {
  389 + List<SchedulePlanInfo> list = new ArrayList<>();
  390 +
  391 + SchedulePlanInfo sp;
  392 + while (itrab.hasNext()) {
  393 + sp = itrab.next();
  394 + sp.setSchedulePlan(null);
  395 + list.add(sp);
  396 + }
  397 + return list;
  398 + }
  399 +
  400 + /**
  401 + * @Title: findByLineCode
  402 + * @Description: TODO(lineCode 获取班次)
  403 + */
  404 + public List<ScheduleRealInfo> findByLineCode(String lineCode) {
  405 + List<ScheduleRealInfo> rs = new ArrayList<>();
  406 +
  407 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  408 + for (ScheduleRealInfo sch : schs) {
  409 + if (sch.getXlBm().equals(lineCode))
  410 + rs.add(sch);
  411 + }
  412 + return rs;
  413 + }
  414 +
  415 + /**
  416 + * @Title: findCarByLineCode
  417 + * @Description: TODO(线路下运营的车辆)
  418 + */
  419 + public Set<String> findCarByLineCode(String lineCode) {
  420 + Set<String> rs = new HashSet<>();
  421 +
  422 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  423 + for (ScheduleRealInfo sch : schs) {
  424 + if (sch.getXlBm().equals(lineCode))
  425 + rs.add(sch.getClZbh());
  426 + }
  427 +
  428 + return rs;
  429 + }
  430 +
  431 + public List<ScheduleRealInfo> findByNbbm(String nbbm) {
  432 + return nbbmScheduleMap.get(nbbm);
  433 + }
  434 +
  435 + /**
  436 + * @Title: findByLineAndUpDown
  437 + * @Description: TODO(lineCode 和走向获取班次)
  438 + */
  439 + public List<ScheduleRealInfo> findByLineAndUpDown(String lineCode, Integer upDown) {
  440 + List<ScheduleRealInfo> list = findByLineCode(lineCode), rs = new ArrayList<>();
  441 +
  442 + for (ScheduleRealInfo sch : list) {
  443 + if (sch.getXlDir().equals(upDown + ""))
  444 + rs.add(sch);
  445 + }
  446 + return rs;
  447 + }
  448 +
  449 + public ScheduleRealInfo get(long id) {
  450 + return id2SchedulMap.get(id);
  451 + }
  452 +
  453 + public Set<String> getSEStationList(String nbbm) {
  454 + return nbbm2SEStationMap.get(nbbm);
  455 + }
  456 +
  457 + /**
  458 + * @Title: next
  459 + * @Description: TODO(下一个班次)
  460 + */
  461 + public ScheduleRealInfo next(ScheduleRealInfo sch) {
  462 +
  463 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  464 + int outConfig = -1;
  465 + LineConfig config = lineConfigData.get(sch.getXlBm());
  466 + if (config != null)
  467 + outConfig = config.getOutConfig();
  468 +
  469 + boolean flag = false;
  470 + ScheduleRealInfo next = null;
  471 + for (ScheduleRealInfo temp : list) {
  472 + if (temp.getId() == sch.getId()) {
  473 + flag = true;
  474 + continue;
  475 + }
  476 + //忽略烂班
  477 + if (temp.isDestroy())
  478 + continue;
  479 +
  480 + //出站既出场,忽略出场班次
  481 + if (outConfig == 2 && temp.getBcType().equals("out"))
  482 + continue;
  483 +
  484 + if (flag) {
  485 + next = temp;
  486 + break;
  487 + }
  488 + }
  489 + return next;
  490 + }
  491 +
  492 + /**
  493 + * 下一个相同走向的班次
  494 + * @param sch
  495 + * @return
  496 + */
  497 + public ScheduleRealInfo nextSame(ScheduleRealInfo sch){
  498 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  499 + int outConfig = -1;
  500 + LineConfig config = lineConfigData.get(sch.getXlBm());
  501 + if (config != null)
  502 + outConfig = config.getOutConfig();
  503 +
  504 + boolean flag = false;
  505 + ScheduleRealInfo next = null;
  506 + for (ScheduleRealInfo temp : list) {
  507 + if (temp.getId() == sch.getId()) {
  508 + flag = true;
  509 + continue;
  510 + }
  511 + //忽略烂班
  512 + if (temp.isDestroy())
  513 + continue;
  514 +
  515 + //出站既出场,忽略出场班次
  516 + if (outConfig == 2 && temp.getBcType().equals("out"))
  517 + continue;
  518 +
  519 + if (flag && temp.getXlDir().equals(sch.getXlDir())) {
  520 + next = temp;
  521 + break;
  522 + }
  523 + }
  524 + return next;
  525 + }
  526 +
  527 + /**
  528 + * 上一个班次
  529 + *
  530 + * @param sch
  531 + * @return
  532 + */
  533 + public ScheduleRealInfo prev(ScheduleRealInfo sch) {
  534 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  535 +
  536 + //boolean flag = false;
  537 + ScheduleRealInfo prev = null;
  538 + int size = list.size();
  539 +
  540 + for (int i = 0; i < size; i++) {
  541 + if (list.get(i).isDestroy())
  542 + continue;
  543 +
  544 + if (list.get(i).getId().equals(sch.getId())) {
  545 + return prev;
  546 + }
  547 + prev = list.get(i);
  548 + }
  549 + return prev;
  550 + }
  551 +
  552 + /**
  553 + * 是否是首班出场
  554 + * @param sch
  555 + * @return
  556 + */
  557 + public boolean isFirstOut(ScheduleRealInfo sch){
  558 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  559 + if(list.get(0).equals(sch) && sch.getBcType().equals("out"))
  560 + return true;
  561 + return false;
  562 + }
  563 +
  564 + public void put(ScheduleRealInfo sch) {
  565 + schAttrCalculator
  566 + .calcRealDate(sch)
  567 + .calcAllTimeByFcsj(sch);
  568 +
  569 + String nbbm = sch.getClZbh();
  570 + nbbmScheduleMap.put(nbbm, sch);
  571 + nbbm2SEStationMap.put(nbbm, sch.getQdzCode());
  572 + nbbm2SEStationMap.put(nbbm, sch.getZdzCode());
  573 +
  574 + //主键索引
  575 + id2SchedulMap.put(sch.getId(), sch);
  576 + //跨24点的,再save一次
  577 + if (!sch.getRealExecDate().equals(sch.getScheduleDateStr()))
  578 + save(sch);
  579 + }
  580 +
  581 + public void delete(ScheduleRealInfo sch) {
  582 + //ScheduleRealInfo sch = id2SchedulMap.get(id);
  583 + if (!sch.isSflj())
  584 + return;
  585 +
  586 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  587 + id2SchedulMap.remove(sch.getId());
  588 + //return sch;
  589 + }
448 590
449 - String nbbm = sch.getClZbh();  
450 - nbbmScheduleMap.put(nbbm, sch);  
451 - nbbm2SEStationMap.put(nbbm, sch.getQdzCode());  
452 - nbbm2SEStationMap.put(nbbm, sch.getZdzCode());  
453 -  
454 - //主键索引  
455 - id2SchedulMap.put(sch.getId(), sch);  
456 - }  
457 -  
458 - public void delete(ScheduleRealInfo sch) {  
459 - //ScheduleRealInfo sch = id2SchedulMap.get(id);  
460 - if(!sch.isSflj())  
461 - return;  
462 -  
463 - nbbmScheduleMap.remove(sch.getClZbh(), sch);  
464 - id2SchedulMap.remove(sch.getId());  
465 - //return sch;  
466 - }  
467 -  
468 // public void calcQdzTimePlan(String nbbm){ 591 // public void calcQdzTimePlan(String nbbm){
469 // schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm)); 592 // schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm));
470 // } 593 // }
471 -  
472 - public List<ScheduleRealInfo> updateQdzTimePlan(String nbbm){  
473 - return schAttrCalculator.updateQdzTimePlan(nbbmScheduleMap.get(nbbm));  
474 - }  
475 -  
476 - /**  
477 - *  
478 - * @Title: nextAll  
479 - * @Description: TODO(之后的所有班次)  
480 - */ 594 +
  595 + public List<ScheduleRealInfo> updateQdzTimePlan(String nbbm) {
  596 + return schAttrCalculator.updateQdzTimePlan(nbbmScheduleMap.get(nbbm));
  597 + }
  598 +
  599 + /**
  600 + *
  601 + * @Title: nextAll
  602 + * @Description: TODO(之后的所有班次)
  603 + */
481 /* public List<ScheduleRealInfo> nextAll(ScheduleRealInfo sch) { 604 /* public List<ScheduleRealInfo> nextAll(ScheduleRealInfo sch) {
482 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh()); 605 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
483 // 排序 606 // 排序
484 Collections.sort(list, schFCSJComparator); 607 Collections.sort(list, schFCSJComparator);
485 608
@@ -494,181 +617,229 @@ public class DayOfSchedule implements CommandLineRunner { @@ -494,181 +617,229 @@ public class DayOfSchedule implements CommandLineRunner {
494 return rs; 617 return rs;
495 }*/ 618 }*/
496 619
497 - /**  
498 - *  
499 - * @Title: doneSum  
500 - * @Description: TODO(已完成班次总数)  
501 - */  
502 - public int doneSum(String clZbh) {  
503 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(clZbh);  
504 - int rs = 0;  
505 -  
506 - for(ScheduleRealInfo sch : list){  
507 - if(sch.getStatus() == 2 && !sch.isDestroy())  
508 - rs ++;  
509 - }  
510 - return rs;  
511 - }  
512 -  
513 - /**  
514 - *  
515 - * @Title: prveNotExecNum  
516 - * @Description: TODO(班次之前未执行班次数量)  
517 - */  
518 - public int prveNotExecNum(ScheduleRealInfo sch){  
519 - int n = 0;  
520 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());  
521 - for(ScheduleRealInfo s : list){  
522 - if(s.getFcsjActual() == null && !s.isDestroy())  
523 - n ++;  
524 -  
525 - if(s.getId().equals(sch.getId()))  
526 - break;  
527 - }  
528 - return n;  
529 - }  
530 -  
531 - /**  
532 - *  
533 - * @Title: validEndTime  
534 - * @Description: TODO(是否是有效的到达时间)  
535 - */  
536 - public boolean validEndTime(ScheduleRealInfo sch, Long ts) {  
537 - if(sch.getFcsjActualTime() != null && sch.getFcsjActualTime() > ts)  
538 - return false;  
539 -  
540 - return validTime(sch, ts);  
541 - }  
542 -  
543 - /**  
544 - *  
545 - * @Title: validStartTime  
546 - * @Description: TODO(是否是合适的发车时间)  
547 - */  
548 - public boolean validStartTime(ScheduleRealInfo sch, Long ts) {  
549 - if(sch.getZdsjActualTime() != null && sch.getZdsjActualTime() < ts)  
550 - return false;  
551 -  
552 - return validTime(sch, ts);  
553 - }  
554 -  
555 - public boolean validTime(ScheduleRealInfo sch, Long ts){  
556 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());  
557 - int ci = list.indexOf(sch);  
558 - ScheduleRealInfo prve, next;  
559 - if(ci > 0){  
560 - //之前班次实际时间不能大于该时间  
561 - for(int i = ci - 1; i >= 0; i --){  
562 - prve = list.get(i);  
563 - if(prve.getZdsjActualTime() != null && prve.getZdsjActualTime() > ts )  
564 - return false;  
565 -  
566 - if(prve.getFcsjActualTime() != null && prve.getFcsjActualTime() > ts)  
567 - return false;  
568 - }  
569 - }  
570 -  
571 - if(ci < list.size() - 1){  
572 - //之后班次实际时间不能小于该时间  
573 - for(int i = ci + 1; i < list.size(); i ++){  
574 - next = list.get(i);  
575 - if(next.getFcsjActualTime() != null && next.getFcsjActualTime() < ts)  
576 - return false;  
577 -  
578 - if(next.getZdsjActualTime() != null && next.getZdsjActualTime() < ts)  
579 - return false;  
580 - }  
581 - }  
582 - return true;  
583 - }  
584 -  
585 - public void save(ScheduleRealInfo sch){  
586 - //schRepository.save(sch);  
587 - pstBuffer.add(sch);  
588 - }  
589 -  
590 -  
591 - /**  
592 - *  
593 - * @Title: nextByBcType  
594 - * @Description: TODO(获取下一个指定班次类型的班次)  
595 - */  
596 - public ScheduleRealInfo nextByBcType(String nbbm, String bcType){  
597 - List<ScheduleRealInfo> list = findByBcType(nbbm, bcType);  
598 -  
599 - Collections.sort(list, schFCSJComparator);  
600 - ScheduleRealInfo sch = null;  
601 - for(ScheduleRealInfo temp : list){  
602 - if(temp.getFcsjActual() == null)  
603 - sch = temp;  
604 - }  
605 -  
606 - return sch;  
607 - }  
608 -  
609 - public List<ScheduleRealInfo> findByBcType(String nbbm, String bcType){  
610 - List<ScheduleRealInfo> all = nbbmScheduleMap.get(nbbm)  
611 - ,outList = new ArrayList<>();  
612 -  
613 - for(ScheduleRealInfo sch : all){  
614 - if(sch.getBcType().equals(bcType))  
615 - outList.add(sch);  
616 - }  
617 - return outList;  
618 - }  
619 -  
620 - public Set<String> allCar(){  
621 - return nbbmScheduleMap.keySet();  
622 - }  
623 -  
624 - public Collection<ScheduleRealInfo> findAll(){  
625 - return nbbmScheduleMap.values();  
626 - }  
627 -  
628 - public void addExecPlan(ScheduleRealInfo sch){  
629 - carExecutePlanMap.put(sch.getClZbh(), sch);  
630 - }  
631 -  
632 - public void removeExecPlan(String clzbh){  
633 - carExecutePlanMap.remove(clzbh);  
634 - }  
635 -  
636 - public Map<String, ScheduleRealInfo> execPlamMap(){  
637 - return carExecutePlanMap;  
638 - }  
639 -  
640 - /**  
641 - * @Title: changeCar  
642 - * @Description: TODO(班次换车) 返回有更新的班次  
643 - * @param @param sch  
644 - * @param @param newClZbh 新的车辆自编号  
645 - */  
646 - public List<ScheduleRealInfo> changeCar(ScheduleRealInfo sch , String newClZbh){  
647 - List<ScheduleRealInfo> ups = new ArrayList<>();  
648 - String oldClzbh = sch.getClZbh();  
649 - if(oldClzbh.equals(newClZbh))  
650 - return ups;  
651 -  
652 -  
653 - //变更相关映射信息  
654 - nbbmScheduleMap.remove(sch.getClZbh(), sch);  
655 -  
656 - sch.setClZbh(newClZbh);  
657 - nbbmScheduleMap.put(newClZbh, sch);  
658 - nbbm2SEStationMap.put(newClZbh, sch.getQdzCode());  
659 - nbbm2SEStationMap.put(newClZbh, sch.getZdzCode());  
660 -  
661 - //重新计算班次应到时间  
662 - ups.addAll(updateQdzTimePlan(oldClzbh));  
663 - ups.addAll(updateQdzTimePlan(newClZbh));  
664 - return ups;  
665 - }  
666 -  
667 - /**  
668 - *  
669 - * @Title: linkToSchPlan  
670 - * @Description: TODO(车辆关联到班次)  
671 - */ 620 + /**
  621 + * @Title: doneSum
  622 + * @Description: TODO(已完成班次总数)
  623 + */
  624 + public int doneSum(String clZbh) {
  625 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(clZbh);
  626 + int rs = 0;
  627 +
  628 + for (ScheduleRealInfo sch : list) {
  629 + if (sch.getStatus() == 2 && !sch.isDestroy())
  630 + rs++;
  631 + }
  632 + return rs;
  633 + }
  634 +
  635 + /**
  636 + * @Title: prveNotExecNum
  637 + * @Description: TODO(班次之前未执行班次数量)
  638 + */
  639 + public int prveNotExecNum(ScheduleRealInfo sch) {
  640 + int n = 0;
  641 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  642 + for (ScheduleRealInfo s : list) {
  643 + if (s.getFcsjActual() == null && !s.isDestroy())
  644 + n++;
  645 +
  646 + if (s.getId().equals(sch.getId()))
  647 + break;
  648 + }
  649 + return n;
  650 + }
  651 +
  652 + /**
  653 + * @Title: validEndTime
  654 + * @Description: TODO(是否是有效的到达时间)
  655 + */
  656 + public boolean validEndTime(ScheduleRealInfo sch, Long ts) {
  657 + if (sch.getFcsjActualTime() != null && sch.getFcsjActualTime() > ts)
  658 + return false;
  659 +
  660 + return validTime(sch, ts);
  661 + }
  662 +
  663 + /**
  664 + * @Title: validStartTime
  665 + * @Description: TODO(是否是合适的发车时间)
  666 + */
  667 + public boolean validStartTime(ScheduleRealInfo sch, Long ts) {
  668 + if (sch.getZdsjActualTime() != null && sch.getZdsjActualTime() < ts)
  669 + return false;
  670 +
  671 + return validTime(sch, ts);
  672 + }
  673 +
  674 + public boolean validTime(ScheduleRealInfo sch, Long ts) {
  675 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  676 + int ci = list.indexOf(sch);
  677 + ScheduleRealInfo prve, next;
  678 + if (ci > 0) {
  679 + //之前班次实际时间不能大于该时间
  680 + for (int i = ci - 1; i >= 0; i--) {
  681 + prve = list.get(i);
  682 + if (prve.getZdsjActualTime() != null && prve.getZdsjActualTime() > ts)
  683 + return false;
  684 +
  685 + if (prve.getFcsjActualTime() != null && prve.getFcsjActualTime() > ts)
  686 + return false;
  687 + }
  688 + }
  689 +
  690 + if (ci < list.size() - 1) {
  691 + //之后班次实际时间不能小于该时间
  692 + for (int i = ci + 1; i < list.size(); i++) {
  693 + next = list.get(i);
  694 + if (next.getFcsjActualTime() != null && next.getFcsjActualTime() < ts)
  695 + return false;
  696 +
  697 + if (next.getZdsjActualTime() != null && next.getZdsjActualTime() < ts)
  698 + return false;
  699 + }
  700 + }
  701 + return true;
  702 + }
  703 +
  704 + public void save(ScheduleRealInfo sch) {
  705 + //schRepository.save(sch);
  706 + pstBuffer.add(sch);
  707 + }
  708 +
  709 +
  710 + /**
  711 + * @Title: nextByBcType
  712 + * @Description: TODO(获取下一个指定班次类型的班次)
  713 + */
  714 + public ScheduleRealInfo nextByBcType(String nbbm, String bcType) {
  715 + List<ScheduleRealInfo> list = findByBcType(nbbm, bcType);
  716 +
  717 + Collections.sort(list, schFCSJComparator);
  718 + ScheduleRealInfo sch = null;
  719 + for (ScheduleRealInfo temp : list) {
  720 + if (temp.getFcsjActual() == null)
  721 + sch = temp;
  722 + }
  723 +
  724 + return sch;
  725 + }
  726 +
  727 + public List<ScheduleRealInfo> findByBcType(String nbbm, String bcType) {
  728 + List<ScheduleRealInfo> all = nbbmScheduleMap.get(nbbm), outList = new ArrayList<>();
  729 +
  730 + for (ScheduleRealInfo sch : all) {
  731 + if (sch.getBcType().equals(bcType))
  732 + outList.add(sch);
  733 + }
  734 + return outList;
  735 + }
  736 +
  737 + public Set<String> allCar() {
  738 + return nbbmScheduleMap.keySet();
  739 + }
  740 +
  741 + public Collection<ScheduleRealInfo> findAll() {
  742 + return nbbmScheduleMap.values();
  743 + }
  744 +
  745 + public void addExecPlan(ScheduleRealInfo sch) {
  746 + if(sch != null)
  747 + carExecutePlanMap.put(sch.getClZbh(), sch);
  748 + }
  749 +
  750 + public void removeExecPlan(String clzbh) {
  751 + carExecutePlanMap.remove(clzbh);
  752 + }
  753 +
  754 + public Map<String, ScheduleRealInfo> execPlanMap() {
  755 + return carExecutePlanMap;
  756 + }
  757 +
  758 + /**
  759 + * 车辆当前执行的班次
  760 + *
  761 + * @param nbbm
  762 + * @return
  763 + */
  764 + public ScheduleRealInfo executeCurr(String nbbm) {
  765 + return carExecutePlanMap.get(nbbm);
  766 + }
  767 +
  768 + /**
  769 + * @param @param sch
  770 + * @param @param newClZbh 新的车辆自编号
  771 + * @Title: changeCar
  772 + * @Description: TODO(班次换车) 返回有更新的班次
  773 + */
  774 + public List<ScheduleRealInfo> changeCar(ScheduleRealInfo sch, String newClZbh) {
  775 + List<ScheduleRealInfo> ups = new ArrayList<>();
  776 + String oldClzbh = sch.getClZbh();
  777 + if (oldClzbh.equals(newClZbh))
  778 + return ups;
  779 +
  780 +
  781 + //变更相关映射信息
  782 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  783 +
  784 + sch.setClZbh(newClZbh);
  785 + nbbmScheduleMap.put(newClZbh, sch);
  786 + nbbm2SEStationMap.put(newClZbh, sch.getQdzCode());
  787 + nbbm2SEStationMap.put(newClZbh, sch.getZdzCode());
  788 +
  789 + //重新计算班次应到时间
  790 + ups.addAll(updateQdzTimePlan(oldClzbh));
  791 + ups.addAll(updateQdzTimePlan(newClZbh));
  792 +
  793 + //重新计算车辆当前执行班次
  794 + reCalcExecPlan(newClZbh);
  795 + reCalcExecPlan(sch.getClZbh());
  796 + return ups;
  797 + }
  798 +
  799 + public void reCalcExecPlan(String nbbm){
  800 + carExecutePlanMap.put(nbbm, schAttrCalculator.calcCurrentExecSch(nbbmScheduleMap.get(nbbm)));
  801 + }
  802 +
  803 + /**
  804 + * 是否在执行首班出场
  805 + * @param nbbm
  806 + * @return
  807 + */
  808 + public boolean isExecFirstOut(String nbbm, long time){
  809 + try {
  810 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(nbbm);
  811 + ScheduleRealInfo second = list.get(2),
  812 + first = executeCurr(nbbm);
  813 +
  814 + if(first.getBcType().equals("out")
  815 + && first.getDfsjT() < second.getDfsjT()
  816 + && doneSum(nbbm) == 0 && second.getDfsjT() > time)
  817 + return true;
  818 + } catch (Exception e) {
  819 + logger.error("", e);
  820 + }
  821 +
  822 + return false;
  823 + }
  824 +
  825 + /**
  826 + * 获取班次的计划停站时间
  827 + * @param sch
  828 + * @return
  829 +
  830 + public int stopTimePlan(Object task) {
  831 +
  832 + ScheduleRealInfo sch = prev((ScheduleRealInfo) task);
  833 +
  834 + sch.getzdsj
  835 + return -1;
  836 + }*/
  837 +
  838 + /**
  839 + *
  840 + * @Title: linkToSchPlan
  841 + * @Description: TODO(车辆关联到班次)
  842 + */
672 /* public void linkToSchPlan(String nbbm) { 843 /* public void linkToSchPlan(String nbbm) {
673 //当前GPS状态 844 //当前GPS状态
674 GpsEntity gps = gpsRealData.get(BasicData.deviceId2NbbmMap.inverse().get(nbbm)); 845 GpsEntity gps = gpsRealData.get(BasicData.deviceId2NbbmMap.inverse().get(nbbm));
src/main/java/com/bsth/data/schedule/SchAttrCalculator.java
@@ -62,13 +62,13 @@ public class SchAttrCalculator { @@ -62,13 +62,13 @@ public class SchAttrCalculator {
62 sch.setDfsjAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr()+sch.getDfsj())); 62 sch.setDfsjAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr()+sch.getDfsj()));
63 63
64 //實發時間 64 //實發時間
65 - if(sch.getFcsjActual() != null && 65 + if(StringUtils.isNotEmpty(sch.getFcsjActual()) &&
66 sch.getFcsjActual().compareTo(conf.getStartOpt()) < 0){ 66 sch.getFcsjActual().compareTo(conf.getStartOpt()) < 0){
67 sch.setFcsjActualAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr()+sch.getFcsjActual()) + DAY_TIME); 67 sch.setFcsjActualAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr()+sch.getFcsjActual()) + DAY_TIME);
68 } 68 }
69 69
70 //實際終點時間 70 //實際終點時間
71 - if(sch.getZdsjActual() != null && 71 + if(StringUtils.isNotEmpty(sch.getZdsjActual()) &&
72 sch.getZdsjActual().compareTo(conf.getStartOpt()) < 0){ 72 sch.getZdsjActual().compareTo(conf.getStartOpt()) < 0){
73 sch.setZdsjActualAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr()+sch.getZdsjActual()) + DAY_TIME); 73 sch.setZdsjActualAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr()+sch.getZdsjActual()) + DAY_TIME);
74 } 74 }
@@ -162,34 +162,6 @@ public class SchAttrCalculator { @@ -162,34 +162,6 @@ public class SchAttrCalculator {
162 162
163 return updateList; 163 return updateList;
164 } 164 }
165 -  
166 - /**  
167 - *  
168 - * @Title: connectOutSchedule  
169 - * @Description: TODO(关联出场班次)  
170 - */  
171 - public void connectOutSchedule(List<ScheduleRealInfo> list){  
172 - Collections.sort(list, new ScheduleComparator.FCSJ());  
173 -  
174 - int len = list.size();  
175 - if(len == 0)  
176 - return;  
177 -  
178 - ScheduleRealInfo prve = list.get(0), curr;  
179 - for(int i = 1; i < len; i ++){  
180 - curr = list.get(i);  
181 -  
182 - //出站即出场关联  
183 - if(prve.getBcType().equals("out") && prve.getJhlc() == null)  
184 - curr.setTwinsSch(prve);  
185 -  
186 - //进站即进场关联  
187 - if(curr.getBcType().equals("in") && curr.getJhlc() == null)  
188 - prve.setTwinsSch(curr);  
189 -  
190 - prve = curr;  
191 - }  
192 - }  
193 165
194 public SchAttrCalculator calcFcsjTime(ScheduleRealInfo sch) throws ParseException { 166 public SchAttrCalculator calcFcsjTime(ScheduleRealInfo sch) throws ParseException {
195 sch.setFcsjT(fmtyyyyMMddHHmm.parseMillis(sch.getRealExecDate() + sch.getFcsj())); 167 sch.setFcsjT(fmtyyyyMMddHHmm.parseMillis(sch.getRealExecDate() + sch.getFcsj()));
src/main/java/com/bsth/entity/realcontrol/LineConfig.java
@@ -53,6 +53,9 @@ public class LineConfig { @@ -53,6 +53,9 @@ public class LineConfig {
53 /** 调度指令模板 */ 53 /** 调度指令模板 */
54 private String schDirectiveTemp; 54 private String schDirectiveTemp;
55 55
  56 + /** 识别区间调头 */
  57 + private boolean readReverse;
  58 +
56 @OneToMany(cascade = CascadeType.ALL) 59 @OneToMany(cascade = CascadeType.ALL)
57 private Set<D80ReplyTemp> d80Temps = new HashSet<>(); 60 private Set<D80ReplyTemp> d80Temps = new HashSet<>();
58 61
@@ -140,4 +143,12 @@ public class LineConfig { @@ -140,4 +143,12 @@ public class LineConfig {
140 public void setD80Temps(Set<D80ReplyTemp> d80Temps) { 143 public void setD80Temps(Set<D80ReplyTemp> d80Temps) {
141 this.d80Temps = d80Temps; 144 this.d80Temps = d80Temps;
142 } 145 }
  146 +
  147 + public boolean isReadReverse() {
  148 + return readReverse;
  149 + }
  150 +
  151 + public void setReadReverse(boolean readReverse) {
  152 + this.readReverse = readReverse;
  153 + }
143 } 154 }
src/main/java/com/bsth/entity/realcontrol/ScheduleRealInfo.java
@@ -94,11 +94,6 @@ public class ScheduleRealInfo { @@ -94,11 +94,6 @@ public class ScheduleRealInfo {
94 * 班次类型 TODO:正常班次、出场、进场、加油、区间班次、放空班次、放大站班次、两点间空驶 94 * 班次类型 TODO:正常班次、出场、进场、加油、区间班次、放空班次、放大站班次、两点间空驶
95 */ 95 */
96 private String bcType; 96 private String bcType;
97 -  
98 - /** 出站即出场 , 关联的进出场班次 */  
99 - @JsonIgnore  
100 - @Transient  
101 - private ScheduleRealInfo twinsSch;  
102 97
103 /** 创建人 */ 98 /** 创建人 */
104 @JsonIgnore 99 @JsonIgnore
@@ -258,21 +253,6 @@ public class ScheduleRealInfo { @@ -258,21 +253,6 @@ public class ScheduleRealInfo {
258 this.ccno = ccno; 253 this.ccno = ccno;
259 } 254 }
260 255
261 - public static DateTimeFormatter getFmtHHmm() {  
262 - return fmtHHmm;  
263 - }  
264 -  
265 - public static void setFmtHHmm(DateTimeFormatter fmtHHmm) {  
266 - ScheduleRealInfo.fmtHHmm = fmtHHmm;  
267 - }  
268 -  
269 - public static DateTimeFormatter getFmtyyyyMMddHHmm() {  
270 - return fmtyyyyMMddHHmm;  
271 - }  
272 -  
273 - public static void setFmtyyyyMMddHHmm(DateTimeFormatter fmtyyyyMMddHHmm) {  
274 - ScheduleRealInfo.fmtyyyyMMddHHmm = fmtyyyyMMddHHmm;  
275 - }  
276 256
277 /** ---------------- 257 /** ----------------
278 @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 258 @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@@ -804,13 +784,13 @@ public class ScheduleRealInfo { @@ -804,13 +784,13 @@ public class ScheduleRealInfo {
804 this.opDirectiveState = opDirectiveState; 784 this.opDirectiveState = opDirectiveState;
805 } 785 }
806 786
807 - public ScheduleRealInfo getTwinsSch() { 787 +/* public ScheduleRealInfo getTwinsSch() {
808 return twinsSch; 788 return twinsSch;
809 } 789 }
810 790
811 public void setTwinsSch(ScheduleRealInfo twinsSch) { 791 public void setTwinsSch(ScheduleRealInfo twinsSch) {
812 this.twinsSch = twinsSch; 792 this.twinsSch = twinsSch;
813 - } 793 + }*/
814 794
815 public boolean isLate() { 795 public boolean isLate() {
816 return late; 796 return late;
src/main/java/com/bsth/repository/realcontrol/ScheduleRealInfoRepository.java
@@ -32,7 +32,7 @@ public interface ScheduleRealInfoRepository extends BaseRepository&lt;ScheduleRealI @@ -32,7 +32,7 @@ public interface ScheduleRealInfoRepository extends BaseRepository&lt;ScheduleRealI
32 32
33 //把sum(addMileage) 替换为0 数据表去掉了 add_mileage 字段 33 //把sum(addMileage) 替换为0 数据表去掉了 add_mileage 字段
34 @Query(value="select new map(clZbh as clZbh,jGh as jGh,jName as jName,sum(jhlc) as zgl," 34 @Query(value="select new map(clZbh as clZbh,jGh as jGh,jName as jName,sum(jhlc) as zgl,"
35 - + " 0 as ksgl,count(jName) as bcs) from ScheduleRealInfo s where" 35 + + "0 as ksgl,count(jName) as bcs) from ScheduleRealInfo s where"
36 + " s.xlBm = ?1 and DATE_FORMAT(s.scheduleDate,'%Y-%m-%d') = ?2 group by clZbh,jGh,jName") 36 + " s.xlBm = ?1 and DATE_FORMAT(s.scheduleDate,'%Y-%m-%d') = ?2 group by clZbh,jGh,jName")
37 List<Map<String, Object>> dailyInfo(String line,String date); 37 List<Map<String, Object>> dailyInfo(String line,String date);
38 38
@@ -71,7 +71,7 @@ public interface ScheduleRealInfoRepository extends BaseRepository&lt;ScheduleRealI @@ -71,7 +71,7 @@ public interface ScheduleRealInfoRepository extends BaseRepository&lt;ScheduleRealI
71 @Query(value="select count(jName) from ScheduleRealInfo s where s.jName = ?1 and s.clZbh = ?2 and s.lpName = ?3 and sflj != 0") 71 @Query(value="select count(jName) from ScheduleRealInfo s where s.jName = ?1 and s.clZbh = ?2 and s.lpName = ?3 and sflj != 0")
72 int findLjbc(String jName,String clZbh,String lpName); 72 int findLjbc(String jName,String clZbh,String lpName);
73 73
74 - @Query(value="SELECT c.company,r.request_code,FROM_UNIXTIME(r.timestamp/1000,'%Y-%m-%d %T'),c.inside_code FROM bsth_v_report_80 r LEFT JOIN bsth_c_cars c ON c.equipment_code = r.device_id where FROM_UNIXTIME(r.timestamp/1000,'%Y-%m-%d') = ?2 and r.line_id like %?1% and c.inside_code like %?3%",nativeQuery=true) 74 + @Query(value="SELECT c.company,r.request_code,FROM_UNIXTIME(r.timestamp/1000,'%Y-%m-%d %T') FROM bsth_v_report_80 r LEFT JOIN bsth_c_cars c ON c.equipment_code = r.device_id where FROM_UNIXTIME(r.timestamp/1000,'%Y-%m-%d') = ?2 and r.line_id = ?1 and c.inside_code = ?3",nativeQuery=true)
75 List<Object[]> account(String line,String date,String code); 75 List<Object[]> account(String line,String date,String code);
76 76
77 @Query(value="select s from ScheduleRealInfo s where s.xlBm = ?1 and s.scheduleDate >= str_to_date(?2,'%Y-%m-%d') " 77 @Query(value="select s from ScheduleRealInfo s where s.xlBm = ?1 and s.scheduleDate >= str_to_date(?2,'%Y-%m-%d') "
@@ -125,4 +125,4 @@ public interface ScheduleRealInfoRepository extends BaseRepository&lt;ScheduleRealI @@ -125,4 +125,4 @@ public interface ScheduleRealInfoRepository extends BaseRepository&lt;ScheduleRealI
125 @Query(value="select new map(xlBm as xlBm) from ScheduleRealInfo s where DATE_FORMAT(s.scheduleDate,'%Y-%m-%d') = ?1 GROUP BY xlBm ORDER BY xlBm") 125 @Query(value="select new map(xlBm as xlBm) from ScheduleRealInfo s where DATE_FORMAT(s.scheduleDate,'%Y-%m-%d') = ?1 GROUP BY xlBm ORDER BY xlBm")
126 List<Map<String,Object>> setDDRBGroup(String date); 126 List<Map<String,Object>> setDDRBGroup(String date);
127 127
128 -}  
129 \ No newline at end of file 128 \ No newline at end of file
  129 +}
src/main/java/com/bsth/websocket/handler/SendUtils.java
1 package com.bsth.websocket.handler; 1 package com.bsth.websocket.handler;
2 2
3 -import java.text.SimpleDateFormat;  
4 -import java.util.ArrayList;  
5 -import java.util.Date;  
6 -import java.util.HashMap;  
7 -import java.util.List;  
8 -import java.util.Map;  
9 -  
10 -import org.slf4j.Logger;  
11 -import org.slf4j.LoggerFactory;  
12 -import org.springframework.beans.factory.annotation.Autowired;  
13 -import org.springframework.stereotype.Component;  
14 -  
15 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
16 import com.bsth.data.BasicData; 4 import com.bsth.data.BasicData;
17 import com.bsth.data.LineConfigData; 5 import com.bsth.data.LineConfigData;
18 -import com.bsth.data.schedule.DayOfSchedule; 6 +import com.bsth.data.gpsdata.arrival.entity.SignalState;
19 import com.bsth.entity.directive.D80; 7 import com.bsth.entity.directive.D80;
20 import com.bsth.entity.realcontrol.ScheduleRealInfo; 8 import com.bsth.entity.realcontrol.ScheduleRealInfo;
21 import com.fasterxml.jackson.core.JsonProcessingException; 9 import com.fasterxml.jackson.core.JsonProcessingException;
22 import com.fasterxml.jackson.databind.ObjectMapper; 10 import com.fasterxml.jackson.databind.ObjectMapper;
  11 +import org.slf4j.Logger;
  12 +import org.slf4j.LoggerFactory;
  13 +import org.springframework.beans.factory.annotation.Autowired;
  14 +import org.springframework.stereotype.Component;
  15 +
  16 +import java.text.SimpleDateFormat;
  17 +import java.util.*;
23 18
24 @Component 19 @Component
25 public class SendUtils{ 20 public class SendUtils{
@@ -40,7 +35,7 @@ public class SendUtils{ @@ -40,7 +35,7 @@ public class SendUtils{
40 */ 35 */
41 public void sendFcsj(ScheduleRealInfo sch) { 36 public void sendFcsj(ScheduleRealInfo sch) {
42 //处理出站即出场的班次 37 //处理出站即出场的班次
43 - connectOutSchTime(sch); 38 + //connectOutSchTime(sch);
44 39
45 Map<String, Object> map = new HashMap<>(); 40 Map<String, Object> map = new HashMap<>();
46 map.put("fn", "faChe"); 41 map.put("fn", "faChe");
@@ -86,7 +81,7 @@ public class SendUtils{ @@ -86,7 +81,7 @@ public class SendUtils{
86 */ 81 */
87 public void sendZdsj(ScheduleRealInfo sch, ScheduleRealInfo nextSch, int finish) { 82 public void sendZdsj(ScheduleRealInfo sch, ScheduleRealInfo nextSch, int finish) {
88 //处理进站即进场的班次 83 //处理进站即进场的班次
89 - connectInSchTime(sch); 84 + //connectInSchTime(sch);
90 85
91 Map<String, Object> map = new HashMap<>(); 86 Map<String, Object> map = new HashMap<>();
92 map.put("fn", "zhongDian"); 87 map.put("fn", "zhongDian");
@@ -103,12 +98,30 @@ public class SendUtils{ @@ -103,12 +98,30 @@ public class SendUtils{
103 logger.error("", e); 98 logger.error("", e);
104 } 99 }
105 } 100 }
  101 +
  102 + /**
  103 + * 推送班次信号状态
  104 + * @param state
  105 + */
  106 + public void sendSignalState(SignalState state){
  107 + Map<String, Object> map = new HashMap<>();
  108 + map.put("fn", "signal_state");
  109 + map.put("data", state);
  110 +
  111 + ObjectMapper mapper = new ObjectMapper();
  112 +
  113 + try {
  114 + socketHandler.sendMessageToLine(state.getLineCode(), mapper.writeValueAsString(map));
  115 + } catch (Exception e) {
  116 + logger.error("", e);
  117 + }
  118 + }
106 119
107 /** 120 /**
108 * 121 *
109 * @Title: shiftSchedule 122 * @Title: shiftSchedule
110 * @Description: TODO(线路翻班通知) 123 * @Description: TODO(线路翻班通知)
111 - */ 124 +
112 public void shiftSchedule(String lineCode){ 125 public void shiftSchedule(String lineCode){
113 Map<String, Object> map = new HashMap<>(); 126 Map<String, Object> map = new HashMap<>();
114 map.put("fn", "systemNotice"); 127 map.put("fn", "systemNotice");
@@ -124,7 +137,7 @@ public class SendUtils{ @@ -124,7 +137,7 @@ public class SendUtils{
124 logger.error("", e); 137 logger.error("", e);
125 } 138 }
126 } 139 }
127 - 140 + */
128 /** 141 /**
129 * 142 *
130 * @Title: sendDirectiveToPage 143 * @Title: sendDirectiveToPage
@@ -157,39 +170,4 @@ public class SendUtils{ @@ -157,39 +170,4 @@ public class SendUtils{
157 list.add(sch); 170 list.add(sch);
158 refreshSch(list); 171 refreshSch(list);
159 } 172 }
160 -  
161 -  
162 - //出站即出场  
163 - public void connectOutSchTime(ScheduleRealInfo sch){  
164 - try{  
165 - ScheduleRealInfo twins = sch.getTwinsSch();  
166 - if(twins != null  
167 - && lineConfigData.get(sch.getXlBm()).getOutConfig() == 2  
168 - && twins.getBcType().equals("out")){  
169 -  
170 - twins.setFcsjActualAll(sch.getFcsjActualTime());  
171 - //刷新关联的出场班次  
172 - //refreshSch(twins);  
173 - }  
174 - }catch(Exception e){  
175 - logger.error("", e);  
176 - }  
177 - }  
178 -  
179 - //进站即出场  
180 - public void connectInSchTime(ScheduleRealInfo sch){  
181 - try{  
182 - ScheduleRealInfo twins = sch.getTwinsSch();  
183 - if(twins != null  
184 - && lineConfigData.get(sch.getXlBm()).getOutConfig() == 2  
185 - && twins.getBcType().equals("in")){  
186 -  
187 - twins.setZdsjActualAll(sch.getZdsjActualTime());  
188 - //刷新关联的出场班次  
189 - //refreshSch(twins);  
190 - }  
191 - }catch(Exception e){  
192 - logger.error("", e);  
193 - }  
194 - }  
195 } 173 }
src/main/resources/application-dev.properties
@@ -7,13 +7,13 @@ spring.jpa.hibernate.naming_strategy= org.hibernate.cfg.ImprovedNamingStrategy @@ -7,13 +7,13 @@ spring.jpa.hibernate.naming_strategy= org.hibernate.cfg.ImprovedNamingStrategy
7 #DATABASE 7 #DATABASE
8 spring.jpa.database= MYSQL 8 spring.jpa.database= MYSQL
9 spring.jpa.show-sql= true 9 spring.jpa.show-sql= true
10 -spring.datasource.driver-class-name= com.mysql.jdbc.Driver  
11 -spring.datasource.url= jdbc:mysql://127.0.0.1/qp_control?useUnicode=true&characterEncoding=utf-8&useSSL=false  
12 -spring.datasource.username= root  
13 -spring.datasource.password=  
14 -#spring.datasource.url= jdbc:mysql://192.168.168.117/pd_control?useUnicode=true&characterEncoding=utf-8&useSSL=false 10 +#spring.datasource.driver-class-name= com.mysql.jdbc.Driver
  11 +#spring.datasource.url= jdbc:mysql://192.168.168.201/mh_control?useUnicode=true&characterEncoding=utf-8&useSSL=false
15 #spring.datasource.username= root 12 #spring.datasource.username= root
16 -#spring.datasource.password= root 13 +#spring.datasource.password= 123456
  14 +spring.datasource.url= jdbc:mysql://localhost/mh_control?useUnicode=true&characterEncoding=utf-8&useSSL=false
  15 +spring.datasource.username= root
  16 +spring.datasource.password= root
17 #DATASOURCE 17 #DATASOURCE
18 spring.datasource.max-active=100 18 spring.datasource.max-active=100
19 spring.datasource.max-idle=8 19 spring.datasource.max-idle=8
src/main/resources/ms-jdbc.properties
@@ -4,6 +4,6 @@ @@ -4,6 +4,6 @@
4 #ms.mysql.password= 123456 4 #ms.mysql.password= 123456
5 5
6 ms.mysql.driver= com.mysql.jdbc.Driver 6 ms.mysql.driver= com.mysql.jdbc.Driver
7 -ms.mysql.url= jdbc:mysql://192.168.168.171:3306/ms?useUnicode=true&characterEncoding=utf-8 7 +ms.mysql.url= jdbc:mysql://192.168.168.117:3306/ms?useUnicode=true&characterEncoding=utf-8
8 ms.mysql.username= root 8 ms.mysql.username= root
9 -ms.mysql.password= root2jsp  
10 \ No newline at end of file 9 \ No newline at end of file
  10 +ms.mysql.password= root
11 \ No newline at end of file 11 \ No newline at end of file
src/main/resources/static/real_control_v2/css/line_schedule.css
@@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
55 padding: 0; 55 padding: 0;
56 } 56 }
57 57
58 -.line_schedule .schedule-wrap i.uk-icon-question-circle{ 58 +.line_schedule .schedule-wrap .header-title i.uk-icon-question-circle{
59 cursor: pointer; 59 cursor: pointer;
60 font-size: 14px; 60 font-size: 14px;
61 color: #cccaca; 61 color: #cccaca;
@@ -528,6 +528,7 @@ div.drop-rail[data-type=&quot;car&quot;]:before { @@ -528,6 +528,7 @@ div.drop-rail[data-type=&quot;car&quot;]:before {
528 528
529 dl.relevance-active dd:nth-child(n+2) { 529 dl.relevance-active dd:nth-child(n+2) {
530 background: #f1efef !important; 530 background: #f1efef !important;
  531 + color: #333;
531 } 532 }
532 533
533 dl.relevance-active.intimity dd:nth-child(n+2) { 534 dl.relevance-active.intimity dd:nth-child(n+2) {
@@ -1022,4 +1023,27 @@ dd.fcsjActualCell div.last-sch-sunken span._badge{ @@ -1022,4 +1023,27 @@ dd.fcsjActualCell div.last-sch-sunken span._badge{
1022 .ct_table>.ct_table_body dl.dl-last-sch:hover div.last-sch-sunken, 1023 .ct_table>.ct_table_body dl.dl-last-sch:hover div.last-sch-sunken,
1023 .ct_table>.ct_table_body dl.dl-last-sch.context-menu-active div.last-sch-sunken{ 1024 .ct_table>.ct_table_body dl.dl-last-sch.context-menu-active div.last-sch-sunken{
1024 background: #f5fbff; 1025 background: #f5fbff;
  1026 +}
  1027 +
  1028 +dd.fcsjActualCell{
  1029 + position: relative;
  1030 +}
  1031 +
  1032 +i.signal_state_icon{
  1033 + position: absolute;
  1034 + right: 5px;
  1035 + top: 7px;
  1036 + box-shadow: 0px 0px 11px 0 rgba(0, 0, 0, 0.2), -1px 3px 8px 0 rgba(0, 0, 0, 0.19);
  1037 + text-indent: 0;
  1038 + border-radius: 15px;
  1039 + cursor: pointer;
  1040 +}
  1041 +
  1042 +i.signal_state_icon.uk-icon-question-circle{
  1043 + color: #e85252 !important;
  1044 +}
  1045 +
  1046 +i.signal_state_icon.uk-icon-reply{
  1047 + color: #4134e3 !important;
  1048 + box-shadow: none;
1025 } 1049 }
1026 \ No newline at end of file 1050 \ No newline at end of file
src/main/resources/static/real_control_v2/fragments/line_schedule/sch_table.html
@@ -83,7 +83,7 @@ @@ -83,7 +83,7 @@
83 <dd data-sort-val={{sch.dfsjT}} dbclick dbclick-type="dfsj" dbclick-val="{{sch.dfsj}}"> 83 <dd data-sort-val={{sch.dfsjT}} dbclick dbclick-type="dfsj" dbclick-val="{{sch.dfsj}}">
84 {{sch.dfsj}} 84 {{sch.dfsj}}
85 </dd> 85 </dd>
86 - <dd class=" 86 + <dd data-uk-observe class="
87 {{if sch.status==-1}} 87 {{if sch.status==-1}}
88 tl-qrlb 88 tl-qrlb
89 {{else if sch.status==2}} 89 {{else if sch.status==2}}
@@ -130,7 +130,7 @@ @@ -130,7 +130,7 @@
130 </script> 130 </script>
131 131
132 <script id="line-schedule-sfsj-temp" type="text/html"> 132 <script id="line-schedule-sfsj-temp" type="text/html">
133 - <dd class=" 133 + <dd data-uk-observe class="
134 {{if status==-1}} 134 {{if status==-1}}
135 tl-qrlb 135 tl-qrlb
136 {{else if status==2}} 136 {{else if status==2}}
src/main/resources/static/real_control_v2/fragments/north/nav/signal_state_config.html 0 → 100644
  1 +<div class="uk-modal ct-form-modal" id="signal_state_config-modal">
  2 + <div class="uk-modal-dialog" style="width: 530px;">
  3 + <a href="" class="uk-modal-close uk-close"></a>
  4 + <div class="uk-modal-header">
  5 + <h2>信号标记设置</h2></div>
  6 +
  7 + <p style="border-bottom: 1px solid #efefef;color: grey;padding-bottom: 9px;">
  8 + <small>
  9 + <i class="uk-icon-question-circle"> </i>
  10 + 设置项将会保存在本地客户端,清理缓存和更换电脑会重置.</small>
  11 + </p>
  12 + <form class="uk-form uk-form-horizontal">
  13 + <div class="uk-grid">
  14 + <div class="uk-width-2-3 uk-container-center">
  15 + <div class="uk-form-row">
  16 + <label class="uk-form-label">是否启用</label>
  17 + <div class="uk-form-controls">
  18 + <select name="enable">
  19 + <option value="1">启用</option>
  20 + <option value="0">禁用</option>
  21 + </select>
  22 + </div>
  23 + </div>
  24 + </div>
  25 + </div>
  26 +
  27 + <div class="uk-modal-footer uk-text-right" style="margin-bottom: -20px;">
  28 + <button type="button" class="uk-button uk-modal-close">取消</button>
  29 + <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-check"></i> &nbsp;保存</button>
  30 + </div>
  31 + </form>
  32 + </div>
  33 +
  34 + <script>
  35 + (function() {
  36 + var modal = '#signal_state_config-modal';
  37 + var f = $('form', modal);
  38 +
  39 + $(modal).on('init', function(e, data) {
  40 + var val = gb_signal_state.isEnable()?1:0;
  41 + $('[name=enable]', f).val(val);
  42 + });
  43 +
  44 + f.formValidation(gb_form_validation_opts);
  45 + f.on('success.form.fv', function(e) {
  46 + e.preventDefault();
  47 + var data = $(this).serializeJSON();
  48 +
  49 + if(data.enable=='1')
  50 + gb_signal_state.enable();
  51 + else
  52 + gb_signal_state.disable();
  53 +
  54 + UIkit.modal(modal).hide();
  55 + });
  56 +
  57 + })();
  58 + </script>
  59 +</div>
0 \ No newline at end of file 60 \ No newline at end of file
src/main/resources/static/real_control_v2/js/data/json/north_toolbar.json
@@ -93,6 +93,11 @@ @@ -93,6 +93,11 @@
93 "id": 3.1, 93 "id": 3.1,
94 "text": "TTS", 94 "text": "TTS",
95 "event": "tts_config" 95 "event": "tts_config"
  96 + },
  97 + {
  98 + "id": 3.2,
  99 + "text": "信号标记",
  100 + "event": "signal_state"
96 } 101 }
97 ] 102 ]
98 } 103 }
src/main/resources/static/real_control_v2/js/line_schedule/layout.js
@@ -22,7 +22,7 @@ var gb_line_layout = (function() { @@ -22,7 +22,7 @@ var gb_line_layout = (function() {
22 }; 22 };
23 23
24 //图例icon tootip 24 //图例icon tootip
25 - $(document).on('mouseenter', '.schedule-wrap i.uk-icon-question-circle', function() { 25 + $(document).on('mouseenter', '.schedule-wrap .header-title i.uk-icon-question-circle', function() {
26 $(this).qtip({ 26 $(this).qtip({
27 show: { 27 show: {
28 ready: true, 28 ready: true,
src/main/resources/static/real_control_v2/js/line_schedule/sch_table.js
@@ -236,6 +236,8 @@ var gb_schedule_table = (function () { @@ -236,6 +236,8 @@ var gb_schedule_table = (function () {
236 else 236 else
237 $(dds[8]).html(''); 237 $(dds[8]).html('');
238 238
  239 + //信号状态标记
  240 + gb_signal_state.marker_sch(sch);
239 //班次是车辆的最后一班 241 //班次是车辆的最后一班
240 if(dl.hasClass('dl-last-sch')) 242 if(dl.hasClass('dl-last-sch'))
241 markerLastSch([sch]); 243 markerLastSch([sch]);
@@ -446,6 +448,7 @@ var gb_schedule_table = (function () { @@ -446,6 +448,7 @@ var gb_schedule_table = (function () {
446 return car_yfwf_map[lineCode]; 448 return car_yfwf_map[lineCode];
447 }, 449 },
448 scroToDl: scroToDl, 450 scroToDl: scroToDl,
449 - reset_drag_active_all: reset_drag_active_all 451 + reset_drag_active_all: reset_drag_active_all,
  452 + getDl: getDl
450 }; 453 };
451 })(); 454 })();
src/main/resources/static/real_control_v2/js/main.js
1 //主调和监控模式 1 //主调和监控模式
2 var operationMode = window.localStorage.getItem('operationMode'); 2 var operationMode = window.localStorage.getItem('operationMode');
3 -if(operationMode == 0){ 3 +if (operationMode == 0) {
4 $('body>.north').addClass('monitor'); 4 $('body>.north').addClass('monitor');
5 $(document).on('ajaxSend', interceptPOST); 5 $(document).on('ajaxSend', interceptPOST);
6 } 6 }
@@ -8,8 +8,8 @@ else @@ -8,8 +8,8 @@ else
8 $('body>.north').addClass('main'); 8 $('body>.north').addClass('main');
9 9
10 //拦截POST请求 10 //拦截POST请求
11 -function interceptPOST(e, xhr, t){  
12 - if(t && (t.method == 'POST' || t.type == 'POST')){ 11 +function interceptPOST(e, xhr, t) {
  12 + if (t && (t.method == 'POST' || t.type == 'POST')) {
13 console.log(e, xhr, t); 13 console.log(e, xhr, t);
14 xhr.abort(); 14 xhr.abort();
15 notify_err('监控模式!'); 15 notify_err('监控模式!');
@@ -18,54 +18,56 @@ function interceptPOST(e, xhr, t){ @@ -18,54 +18,56 @@ function interceptPOST(e, xhr, t){
18 18
19 /* main js */ 19 /* main js */
20 var gb_main_ep = new EventProxy(), 20 var gb_main_ep = new EventProxy(),
21 - res_load_ep = EventProxy.create('load_data_basic', 'load_tab', 'load_home_layout', 'load_home_line_panel', function() { 21 + res_load_ep = EventProxy.create('load_data_basic', 'load_tab', 'load_home_layout', 'load_home_line_panel', function () {
22 var eq = gb_main_ep; 22 var eq = gb_main_ep;
23 // basic data end 23 // basic data end
24 eq.once('data-basic', g_emit('tab')); 24 eq.once('data-basic', g_emit('tab'));
25 // tabs 25 // tabs
26 - eq.once('tab', function() { 26 + eq.once('tab', function () {
27 gb_tabs.init( 27 gb_tabs.init(
28 g_emit('home-layout') 28 g_emit('home-layout')
29 ); 29 );
30 }); 30 });
31 //home layout 31 //home layout
32 - eq.once('home-layout', function() { 32 + eq.once('home-layout', function () {
33 gb_home_layout.layout( 33 gb_home_layout.layout(
34 g_emit('home-line-panel') 34 g_emit('home-line-panel')
35 ); 35 );
36 }); 36 });
37 //home line panel 37 //home line panel
38 - eq.once('home-line-panel', function() { 38 + eq.once('home-line-panel', function () {
39 gb_home_line_panel.init(g_emit('gps-time-refresh')); 39 gb_home_line_panel.init(g_emit('gps-time-refresh'));
40 }); 40 });
41 41
42 //start fixed time refresh gps 42 //start fixed time refresh gps
43 - eq.once('gps-time-refresh', function() { 43 + eq.once('gps-time-refresh', function () {
44 gb_data_gps.fixedTimeRefresh(); 44 gb_data_gps.fixedTimeRefresh();
45 g_emit('line-schedule-layout')(); 45 g_emit('line-schedule-layout')();
46 }); 46 });
47 47
48 //line schedule layout 48 //line schedule layout
49 - eq.once('line-schedule-layout', function() { 49 + eq.once('line-schedule-layout', function () {
50 gb_line_layout.layout(g_emit('render-sch-table')); 50 gb_line_layout.layout(g_emit('render-sch-table'));
51 }); 51 });
52 52
53 //render schedule table 53 //render schedule table
54 - eq.once('render-sch-table', function() {  
55 - gb_schedule_table.show(function(){  
56 - //搜索框  
57 - gb_sch_search.init(); 54 + eq.once('render-sch-table', function () {
  55 + gb_schedule_table.show(function () {
  56 + //搜索框
  57 + gb_sch_search.init();
  58 + //加载信号状态
  59 + gb_signal_state.init();
58 }); 60 });
59 61
60 //嵌入地图页面 62 //嵌入地图页面
61 - $('li.map-panel','#main-tab-content').load('/real_control_v2/mapmonitor/real.html');  
62 - 63 + $('li.map-panel', '#main-tab-content').load('/real_control_v2/mapmonitor/real.html');
  64 + //弹出更新说明
63 showUpdateDescription(); 65 showUpdateDescription();
64 }); 66 });
65 67
66 function g_emit(id) { 68 function g_emit(id) {
67 console.log('g_emit [' + id + ']'); 69 console.log('g_emit [' + id + ']');
68 - return function() { 70 + return function () {
69 console.log('eq.emitLater(' + id + ')'); 71 console.log('eq.emitLater(' + id + ')');
70 return eq.emitLater(id); 72 return eq.emitLater(id);
71 }; 73 };
@@ -73,17 +75,17 @@ var gb_main_ep = new EventProxy(), @@ -73,17 +75,17 @@ var gb_main_ep = new EventProxy(),
73 }); 75 });
74 76
75 //modal hide remove dom 77 //modal hide remove dom
76 -$(document).on('hide.uk.modal', '.uk-modal', function() { 78 +$(document).on('hide.uk.modal', '.uk-modal', function () {
77 $(this).remove(); 79 $(this).remove();
78 }); 80 });
79 81
80 $(document).on('click', '.ct-bottom-drawer-close', function () { 82 $(document).on('click', '.ct-bottom-drawer-close', function () {
81 - $(this).parents('.ct-bottom-drawer').removeClass('open'); 83 + $(this).parents('.ct-bottom-drawer').removeClass('open');
82 }); 84 });
83 85
84 function connectArr(arr, separator, transFun) { 86 function connectArr(arr, separator, transFun) {
85 var rs = ''; 87 var rs = '';
86 - $.each(arr, function(i, item) { 88 + $.each(arr, function (i, item) {
87 if (transFun) 89 if (transFun)
88 item = transFun(item); 90 item = transFun(item);
89 rs += (separator + item); 91 rs += (separator + item);
@@ -102,26 +104,26 @@ var gb_form_validation_opts = { @@ -102,26 +104,26 @@ var gb_form_validation_opts = {
102 }; 104 };
103 105
104 106
105 -var notify_wait = function(t) { 107 +var notify_wait = function (t) {
106 UIkit.notify("<i class='uk-icon-spinner uk-icon-spin'></i> " + t, { 108 UIkit.notify("<i class='uk-icon-spinner uk-icon-spin'></i> " + t, {
107 status: 'info' 109 status: 'info'
108 }); 110 });
109 }; 111 };
110 112
111 -var notify_succ = function(t) { 113 +var notify_succ = function (t) {
112 UIkit.notify("<i class='uk-icon-check'></i> " + t, { 114 UIkit.notify("<i class='uk-icon-check'></i> " + t, {
113 status: 'success' 115 status: 'success'
114 }); 116 });
115 }; 117 };
116 118
117 -var notify_err = function(t) { 119 +var notify_err = function (t) {
118 UIkit.notify("<i class='uk-icon-times'></i> " + t, { 120 UIkit.notify("<i class='uk-icon-times'></i> " + t, {
119 status: 'danger' 121 status: 'danger'
120 }); 122 });
121 }; 123 };
122 124
123 -var alt_confirm = function(content, succ, okBtn) {  
124 - var modalEl = UIkit.modal.confirm(content, function() { 125 +var alt_confirm = function (content, succ, okBtn) {
  126 + var modalEl = UIkit.modal.confirm(content, function () {
125 succ && succ(); 127 succ && succ();
126 modalEl.hide(); 128 modalEl.hide();
127 }, { 129 }, {
@@ -129,15 +131,15 @@ var alt_confirm = function(content, succ, okBtn) { @@ -129,15 +131,15 @@ var alt_confirm = function(content, succ, okBtn) {
129 Ok: okBtn, 131 Ok: okBtn,
130 Cancel: '取消' 132 Cancel: '取消'
131 } 133 }
132 - ,center: true 134 + , center: true
133 }); 135 });
134 }; 136 };
135 137
136 -var isArray = function(obj) { 138 +var isArray = function (obj) {
137 return Object.prototype.toString.call(obj) === '[object Array]'; 139 return Object.prototype.toString.call(obj) === '[object Array]';
138 }; 140 };
139 141
140 -var notify_err_form = function(t, form) { 142 +var notify_err_form = function (t, form) {
141 $('.uk-alert-danger', form).remove(); 143 $('.uk-alert-danger', form).remove();
142 $('.uk-modal-footer', form).before('<div class="uk-alert uk-alert-danger" data-uk-alert="">' + 144 $('.uk-modal-footer', form).before('<div class="uk-alert uk-alert-danger" data-uk-alert="">' +
143 '<a href="" class="uk-alert-close uk-close"></a>' + 145 '<a href="" class="uk-alert-close uk-close"></a>' +
@@ -147,29 +149,29 @@ var notify_err_form = function(t, form) { @@ -147,29 +149,29 @@ var notify_err_form = function(t, form) {
147 enable_submit_btn(form); 149 enable_submit_btn(form);
148 }; 150 };
149 151
150 -var enable_submit_btn = function(form) { 152 +var enable_submit_btn = function (form) {
151 var subBtn = $('button[type=submit]', form); 153 var subBtn = $('button[type=submit]', form);
152 if (subBtn) { 154 if (subBtn) {
153 subBtn.removeClass('disabled').removeAttr('disabled'); 155 subBtn.removeClass('disabled').removeAttr('disabled');
154 } 156 }
155 } 157 }
156 158
157 -var disabled_submit_btn = function(form) { 159 +var disabled_submit_btn = function (form) {
158 var subBtn = $('button[type=submit]', form); 160 var subBtn = $('button[type=submit]', form);
159 if (subBtn) { 161 if (subBtn) {
160 - subBtn.addClass('disabled').attr('disabled','disabled'); 162 + subBtn.addClass('disabled').attr('disabled', 'disabled');
161 } 163 }
162 }; 164 };
163 165
164 -var show_modal = function(id, dom) { 166 +var show_modal = function (id, dom) {
165 $(document.body).append(dom); 167 $(document.body).append(dom);
166 return UIkit.modal(id, { 168 return UIkit.modal(id, {
167 bgclose: false 169 bgclose: false
168 }).show(); 170 }).show();
169 }; 171 };
170 172
171 -var open_modal = function(pageUrl, data, opt) {  
172 - $.get(pageUrl, function(dom) { 173 +var open_modal = function (pageUrl, data, opt) {
  174 + $.get(pageUrl, function (dom) {
173 if (!$(dom).hasClass('uk-modal')) { 175 if (!$(dom).hasClass('uk-modal')) {
174 alert('无效的dom片段!'); 176 alert('无效的dom片段!');
175 return; 177 return;
@@ -188,20 +190,20 @@ var open_modal = function(pageUrl, data, opt) { @@ -188,20 +190,20 @@ var open_modal = function(pageUrl, data, opt) {
188 190
189 function showUpdateDescription() { 191 function showUpdateDescription() {
190 //更新说明 192 //更新说明
191 - var updateDescription={ 193 + var updateDescription = {
192 date: '2016-12-20', 194 date: '2016-12-20',
193 text: '<h5>1、回场子任务开放使用。</h5>' 195 text: '<h5>1、回场子任务开放使用。</h5>'
194 }; 196 };
195 197
196 var storage = window.localStorage 198 var storage = window.localStorage
197 - ,key = 'update_' + updateDescription.date; 199 + , key = 'update_' + updateDescription.date;
198 var text = storage.getItem(key); 200 var text = storage.getItem(key);
199 - if(!text){  
200 - var modal = '<div class="uk-modal" id="update-description-modal">'+  
201 - ' <div class="uk-modal-dialog">'+  
202 - ' <a class="uk-modal-close uk-close"></a>'+  
203 - ' <div class="uk-modal-header">'+  
204 - ' <h2>'+updateDescription.date+' 更新说明</h2></div>'+updateDescription.text+ 201 + if (!text) {
  202 + var modal = '<div class="uk-modal" id="update-description-modal">' +
  203 + ' <div class="uk-modal-dialog">' +
  204 + ' <a class="uk-modal-close uk-close"></a>' +
  205 + ' <div class="uk-modal-header">' +
  206 + ' <h2>' + updateDescription.date + ' 更新说明</h2></div>' + updateDescription.text +
205 ' </div>'; 207 ' </div>';
206 208
207 show_modal('#update-description-modal', modal); 209 show_modal('#update-description-modal', modal);
src/main/resources/static/real_control_v2/js/north/toolbar.js
@@ -71,6 +71,9 @@ var gb_northToolbar = (function() { @@ -71,6 +71,9 @@ var gb_northToolbar = (function() {
71 }, 71 },
72 gps_play_back: function () { 72 gps_play_back: function () {
73 gb_map_play_back.initParams(); 73 gb_map_play_back.initParams();
  74 + },
  75 + signal_state: function () {
  76 + open_modal('/real_control_v2/fragments/north/nav/signal_state_config.html', {}, modal_opts);
74 } 77 }
75 } 78 }
76 })(); 79 })();
src/main/resources/static/real_control_v2/js/signal_state/signal_state.js 0 → 100644
  1 +/**
  2 + * GPS信号状态
  3 + * @type {{}}
  4 + */
  5 +var gb_signal_state = (function () {
  6 + var storage = window.localStorage;
  7 +
  8 + $(document).on('click', 'i.signal_state_icon', function (e) {
  9 + e.stopPropagation();
  10 + });
  11 +
  12 + var signal_state_data = {};
  13 + var enable = true;
  14 + //读取本地状态
  15 + var locStatus = storage.getItem("signal_state_enable");
  16 + if (locStatus && locStatus=='0')
  17 + enable = false;
  18 +
  19 + var init = function () {
  20 + $.get('/signalState/multi', {idx: gb_data_basic.line_idx}, function (rs) {
  21 + //按班次ID分组
  22 + signal_state_data = gb_common.groupBy(rs, 'schId');
  23 +
  24 + for (var schId in signal_state_data) {
  25 + multi_render(signal_state_data[schId]);
  26 + }
  27 + });
  28 + };
  29 +
  30 + var multi_render = function (list) {
  31 + if (!enable)
  32 + return;
  33 +
  34 + if (!list || list.length == 0)
  35 + return;
  36 + var line = list[0].lineCode
  37 + , schId = list[0].schId;
  38 +
  39 + var sch = gb_schedule_table.findScheduleByLine(line)[schId];
  40 + var dl = gb_schedule_table.getDl(sch);
  41 + var icon = 'question-circle';
  42 + var t = '';
  43 + $.each(list, function () {
  44 + t += (this.text + '<br>');
  45 + });
  46 +
  47 + if (list.length == 1 && list[0].type == 'route_reverse')
  48 + icon = 'reply';
  49 +
  50 + var dd = $('dd.fcsjActualCell', dl);
  51 + var se = $('i.signal_state_icon', dd);
  52 + if (se && se.length > 0)
  53 + se.remove();
  54 +
  55 + dd.append('<i data-uk-tooltip title="' + t + '" class="uk-icon-' + icon + ' signal_state_icon"></i>');
  56 + };
  57 +
  58 + var put = function (obj) {
  59 + if (!signal_state_data[obj.schId]) {
  60 + signal_state_data[obj.schId] = [];
  61 + }
  62 +
  63 + signal_state_data[obj.schId].push(obj);
  64 + multi_render(signal_state_data[obj.schId]);
  65 + };
  66 +
  67 + var marker_sch = function (sch) {
  68 + var list = signal_state_data[sch.id];
  69 + if (list) {
  70 + multi_render(list);
  71 + }
  72 + };
  73 +
  74 + var clearAll = function () {
  75 + $('.signal_state_icon').remove();
  76 + };
  77 +
  78 + return {
  79 + init: init,
  80 + put: put,
  81 + marker_sch: marker_sch,
  82 + isEnable: function () {
  83 + return enable;
  84 + },
  85 + disable: function () {
  86 + enable = false;
  87 + storage.setItem("signal_state_enable", 0);
  88 +
  89 + clearAll();
  90 + },
  91 + enable: function () {
  92 + enable = true;
  93 + storage.setItem("signal_state_enable", 1);
  94 + for (var schId in signal_state_data) {
  95 + multi_render(signal_state_data[schId]);
  96 + }
  97 + }
  98 + };
  99 +})();
0 \ No newline at end of file 100 \ No newline at end of file
src/main/resources/static/real_control_v2/js/websocket/sch_websocket.js
@@ -26,7 +26,7 @@ var gb_sch_websocket = (function () { @@ -26,7 +26,7 @@ var gb_sch_websocket = (function () {
26 var data = { 26 var data = {
27 operCode: 'register_line', 27 operCode: 'register_line',
28 idx: gb_data_basic.line_idx 28 idx: gb_data_basic.line_idx
29 - } 29 + };
30 schSock.send(JSON.stringify(data)); 30 schSock.send(JSON.stringify(data));
31 console.log('regListen....', data); 31 console.log('regListen....', data);
32 } 32 }
@@ -45,21 +45,21 @@ var gb_sch_websocket = (function () { @@ -45,21 +45,21 @@ var gb_sch_websocket = (function () {
45 var calcUntreated = function (lineCode) { 45 var calcUntreated = function (lineCode) {
46 var size = $('li.line_schedule[data-id=' + lineCode + '] .sys-mailbox .sys-mail-item').length; 46 var size = $('li.line_schedule[data-id=' + lineCode + '] .sys-mailbox .sys-mail-item').length;
47 $('#badge_untreated_num_' + lineCode).text(size); 47 $('#badge_untreated_num_' + lineCode).text(size);
48 - } 48 + };
49 49
50 var calcUntreatedAll = function () { 50 var calcUntreatedAll = function () {
51 $('#main-tab-content li.line_schedule').each(function () { 51 $('#main-tab-content li.line_schedule').each(function () {
52 calcUntreated($(this).data('id')); 52 calcUntreated($(this).data('id'));
53 }); 53 });
54 - } 54 + };
55 55
56 56
57 //80协议上报 57 //80协议上报
58 var report80 = function (msg) { 58 var report80 = function (msg) {
59 msg.dateStr = moment(msg.timestamp).format('HH:mm'); 59 msg.dateStr = moment(msg.timestamp).format('HH:mm');
60 msg.text = gb_common.reqCode80[msg.data.requestCode]; 60 msg.text = gb_common.reqCode80[msg.data.requestCode];
61 - if(!msg.text)  
62 - msg.text='(未知的请求码 '+msg.data.requestCode+')'; 61 + if (!msg.text)
  62 + msg.text = '(未知的请求码 ' + msg.data.requestCode + ')';
63 63
64 var $item = $(temps['sys-note-80-temp'](msg)); 64 var $item = $(temps['sys-note-80-temp'](msg));
65 findMailBox(msg.data.lineId).prepend($item); 65 findMailBox(msg.data.lineId).prepend($item);
@@ -68,7 +68,7 @@ var gb_sch_websocket = (function () { @@ -68,7 +68,7 @@ var gb_sch_websocket = (function () {
68 gb_tts.speak(ttsMsg, msg.data.lineId); 68 gb_tts.speak(ttsMsg, msg.data.lineId);
69 69
70 calcUntreated(msg.data.lineId); 70 calcUntreated(msg.data.lineId);
71 - } 71 + };
72 72
73 var waitRemoves = []; 73 var waitRemoves = [];
74 //车辆发出 74 //车辆发出
@@ -89,7 +89,7 @@ var gb_sch_websocket = (function () { @@ -89,7 +89,7 @@ var gb_sch_websocket = (function () {
89 gb_schedule_table.calc_yfwf_num(msg.t.xlBm); 89 gb_schedule_table.calc_yfwf_num(msg.t.xlBm);
90 90
91 calcUntreated(msg.t.xlBm); 91 calcUntreated(msg.t.xlBm);
92 - } 92 + };
93 93
94 //到达终点 94 //到达终点
95 var zhongDian = function (msg) { 95 var zhongDian = function (msg) {
@@ -107,20 +107,20 @@ var gb_sch_websocket = (function () { @@ -107,20 +107,20 @@ var gb_sch_websocket = (function () {
107 gb_tts.speak(ttsMsg, msg.t.xlBm); 107 gb_tts.speak(ttsMsg, msg.t.xlBm);
108 108
109 calcUntreated(msg.t.xlBm); 109 calcUntreated(msg.t.xlBm);
110 - } 110 + };
111 111
112 //服务器通知刷新班次 112 //服务器通知刷新班次
113 var refreshSch = function (msg) { 113 var refreshSch = function (msg) {
114 gb_schedule_table.updateSchedule(msg.ts); 114 gb_schedule_table.updateSchedule(msg.ts);
115 /*//重新计算应发未发 115 /*//重新计算应发未发
116 - var idx={};  
117 - $.each(msg.ts, function(i, t){  
118 - if(idx[t.xlBm])  
119 - return true;  
120 - gb_schedule_table.calc_yfwf_num(t.xlBm);  
121 - idx[t.xlBm]=1;  
122 - });*/  
123 - } 116 + var idx={};
  117 + $.each(msg.ts, function(i, t){
  118 + if(idx[t.xlBm])
  119 + return true;
  120 + gb_schedule_table.calc_yfwf_num(t.xlBm);
  121 + idx[t.xlBm]=1;
  122 + });*/
  123 + };
124 124
125 //80消息确认 125 //80消息确认
126 var d80Confirm = function (msg) { 126 var d80Confirm = function (msg) {
@@ -129,12 +129,17 @@ var gb_sch_websocket = (function () { @@ -129,12 +129,17 @@ var gb_sch_websocket = (function () {
129 calcUntreated(msg.lineId); 129 calcUntreated(msg.lineId);
130 //重新计算应发未发 130 //重新计算应发未发
131 gb_schedule_table.calc_yfwf_num(msg.lineId); 131 gb_schedule_table.calc_yfwf_num(msg.lineId);
132 - } 132 + };
133 133
134 //指令状态改变 134 //指令状态改变
135 - var directiveStatus = function(msg){ 135 + var directiveStatus = function (msg) {
136 gb_schedule_table.updateSchedule(msg.t); 136 gb_schedule_table.updateSchedule(msg.t);
137 - } 137 + };
  138 +
  139 + //班次信号状态
  140 + var signalState = function (msg) {
  141 + gb_signal_state.put(msg.data);
  142 + };
138 143
139 var msgHandle = { 144 var msgHandle = {
140 report80: report80, 145 report80: report80,
@@ -142,8 +147,9 @@ var gb_sch_websocket = (function () { @@ -142,8 +147,9 @@ var gb_sch_websocket = (function () {
142 zhongDian: zhongDian, 147 zhongDian: zhongDian,
143 refreshSch: refreshSch, 148 refreshSch: refreshSch,
144 d80Confirm: d80Confirm, 149 d80Confirm: d80Confirm,
145 - directive: directiveStatus  
146 - } 150 + directive: directiveStatus,
  151 + signal_state: signalState
  152 + };
147 153
148 function currentSecond() { 154 function currentSecond() {
149 return Date.parse(new Date()) / 1000; 155 return Date.parse(new Date()) / 1000;
@@ -167,15 +173,15 @@ var gb_sch_websocket = (function () { @@ -167,15 +173,15 @@ var gb_sch_websocket = (function () {
167 $(this).parents('.sys-note-42').remove(); 173 $(this).parents('.sys-note-42').remove();
168 174
169 var size = $(this).parents('.sys-mailbox').find('.sys-mail-item').length 175 var size = $(this).parents('.sys-mailbox').find('.sys-mail-item').length
170 - ,lineCode = $(this).parents('li.line_schedule').data('id'); 176 + , lineCode = $(this).parents('li.line_schedule').data('id');
171 177
172 $('#badge_untreated_num_' + lineCode).text(size); 178 $('#badge_untreated_num_' + lineCode).text(size);
173 }); 179 });
174 180
175 //42消息点击 181 //42消息点击
176 $(document).on('click', '.sys-mailbox .sys-note-42', function () { 182 $(document).on('click', '.sys-mailbox .sys-note-42', function () {
177 - var lineCode=$(this).parents('li.line_schedule').data('id')  
178 - ,id=$(this).data('id'); 183 + var lineCode = $(this).parents('li.line_schedule').data('id')
  184 + , id = $(this).data('id');
179 var sch = gb_schedule_table.findScheduleByLine(lineCode)[id]; 185 var sch = gb_schedule_table.findScheduleByLine(lineCode)[id];
180 var dl = gb_schedule_table.scroToDl(sch); 186 var dl = gb_schedule_table.scroToDl(sch);
181 //高亮 187 //高亮
@@ -205,7 +211,7 @@ var gb_sch_websocket = (function () { @@ -205,7 +211,7 @@ var gb_sch_websocket = (function () {
205 notify_succ(rs.msg); 211 notify_succ(rs.msg);
206 cb && cb(); 212 cb && cb();
207 }); 213 });
208 - } 214 + };
209 215
210 216
211 //定时到离站信使清理掉 217 //定时到离站信使清理掉
src/main/resources/static/real_control_v2/main.html
@@ -142,6 +142,8 @@ @@ -142,6 +142,8 @@
142 <script src="/real_control_v2/assets/echarts-3/echarts.js"></script> 142 <script src="/real_control_v2/assets/echarts-3/echarts.js"></script>
143 <!-- Geolib --> 143 <!-- Geolib -->
144 <script src="/real_control_v2/geolib/geolib.js"></script> 144 <script src="/real_control_v2/geolib/geolib.js"></script>
  145 +
  146 + <script src="/real_control_v2/js/signal_state/signal_state.js"></script>
145 </body> 147 </body>
146 148
147 </html> 149 </html>
src/main/resources/static/real_control_v2/mapmonitor/fragments/playback/run.html
@@ -148,10 +148,14 @@ @@ -148,10 +148,14 @@
148 var logs = []; 148 var logs = [];
149 for (var i = 0; i <= ei; i++) { 149 for (var i = 0; i <= ei; i++) {
150 trailArray.push(new BMap.Point(gpsArray[i].bd_lon, gpsArray[i].bd_lat)); 150 trailArray.push(new BMap.Point(gpsArray[i].bd_lon, gpsArray[i].bd_lat));
151 - if(i > 0 && logs[logs.length - 1].road.ROAD_CODE == gpsArray[i].road.ROAD_CODE)  
152 - logs.pop();  
153 -  
154 - logs.push(gpsArray[i]); 151 + try {
  152 + if(i > 0 && logs[logs.length - 1].road.ROAD_CODE == gpsArray[i].road.ROAD_CODE)
  153 + logs.pop();
  154 + }
  155 + catch (e){}
  156 +
  157 + if(gpsArray[i].road)
  158 + logs.push(gpsArray[i]);
155 } 159 }
156 trailPolyline.setPath(trailArray); 160 trailPolyline.setPath(trailArray);
157 161
@@ -302,6 +306,9 @@ @@ -302,6 +306,9 @@
302 gb_ct_table.fixedHead(logWrap); 306 gb_ct_table.fixedHead(logWrap);
303 307
304 function logWrite(gps, prve) { 308 function logWrite(gps, prve) {
  309 + if(!gps.road || !gps.road.ROAD_CODE)
  310 + return;
  311 +
305 var code = gps.road.ROAD_CODE; 312 var code = gps.road.ROAD_CODE;
306 if (!prve || code != prve.road.ROAD_CODE) { 313 if (!prve || code != prve.road.ROAD_CODE) {
307 logPanel.append('<dl data-code="' + code + '" ><dd>' + gps.timeStr + '</dd><dd>' + gps.speed + '</dd><dd>' + gps.road.ROAD_NAME + '</dd><dd>正常</dd></dl>'); 314 logPanel.append('<dl data-code="' + code + '" ><dd>' + gps.timeStr + '</dd><dd>' + gps.speed + '</dd><dd>' + gps.road.ROAD_NAME + '</dd><dd>正常</dd></dl>');