Commit f134136e051411f37ea2b86704bf470c792e6273

Authored by 潘钊
1 parent 612f7eea

update

Showing 29 changed files with 771 additions and 342 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 13 import org.slf4j.LoggerFactory;
14 14 import org.springframework.beans.factory.annotation.Autowired;
15 15 import org.springframework.boot.CommandLineRunner;
  16 +import org.springframework.core.annotation.Order;
16 17 import org.springframework.stereotype.Component;
17 18  
18 19 import java.util.*;
... ... @@ -25,13 +26,14 @@ import java.util.concurrent.TimeUnit;
25 26 * @date 2016年8月10日 下午3:27:45
26 27 */
27 28 @Component
  29 +@Order(value = 1)
28 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 38 //设备号和车辆自编号 (K: 设备编码 ,V:车辆自编号)
37 39 public static BiMap<String, String> deviceId2NbbmMap;
... ... @@ -39,7 +41,7 @@ public class BasicData implements CommandLineRunner {
39 41 //车辆自编号和公司代码对照 (K: 车辆自编号 ,V:公司代码)
40 42 public static Map<String, String> nbbm2CompanyCodeMap;
41 43  
42   - //站点编码和名称对照,包括停车场 (K: 站点编码 ,V:站点名称)
  44 + //站点编码和名称对照,包括停车场 (K: lineCode_updown_stationCode ,V:站点名称)
43 45 public static Map<String, String> stationCode2NameMap;
44 46  
45 47 //线路起终点对照(线路编码_上下行_起终点) 1024_0_B (1024上行起点)
... ... @@ -48,18 +50,12 @@ public class BasicData implements CommandLineRunner {
48 50 //车辆和线路对照
49 51 public static Map<String, Line> nbbm2LineMap;
50 52  
51   - //线路和用户对照 用于webSocket定向推送消息(用户进入线调时写入数据)
52   - //public static TreeMultimap<String, String> lineCode2SocketUserMap = TreeMultimap.create();
53   -
54 53 //线路ID和code 对照
55 54 public static BiMap<Integer, String> lineId2CodeMap;
56 55  
57 56 //线路编码和名称对照
58 57 public static Map<String, String> lineCode2NameMap;
59 58  
60   - //线路编码_站点编码 == 0|1 上下行
61   - //public static Map<String, Integer> lineStationUpDownMap;
62   -
63 59 //停车场
64 60 public static List<String> parkCodeList;
65 61  
... ... @@ -77,7 +73,7 @@ public class BasicData implements CommandLineRunner {
77 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 79 static Logger logger = LoggerFactory.getLogger(BasicData.class);
... ... @@ -114,7 +110,7 @@ public class BasicData implements CommandLineRunner {
114 110  
115 111 @Autowired
116 112 PersonnelRepository personnelRepository;
117   -
  113 +
118 114 @Autowired
119 115 BusinessRepository businessRepository;
120 116  
... ... @@ -156,47 +152,24 @@ public class BasicData implements CommandLineRunner {
156 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 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 174 * @Title: loadDeviceInfo
202 175 * @Description: TODO(加载设备相关信息)
... ... @@ -223,13 +196,13 @@ public class BasicData implements CommandLineRunner {
223 196 */
224 197 public void loadStationInfo() {
225 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 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 207 Iterator<CarPark> iterator2 = carParkRepository.findAll().iterator();
235 208  
... ... @@ -266,7 +239,7 @@ public class BasicData implements CommandLineRunner {
266 239 * @Title: loadLineInfo
267 240 * @Description: TODO(加载线路相关信息)
268 241 */
269   - public void loadLineInfo(){
  242 + public void loadLineInfo() {
270 243 Iterator<Line> iterator = lineRepository.findAll().iterator();
271 244  
272 245 Line line;
... ... @@ -276,36 +249,36 @@ public class BasicData implements CommandLineRunner {
276 249 Map<String, String> code2SHcode = new HashMap<String, String>();
277 250 Map<String, Integer> tempStationName2YgcNumber = new HashMap<String, Integer>();
278 251  
279   - while(iterator.hasNext()){
  252 + while (iterator.hasNext()) {
280 253 line = iterator.next();
281 254 biMap.put(line.getId(), line.getLineCode());
282 255 code2name.put(line.getLineCode(), line.getName());
283   - id2SHcode.put(line.getId(),line.getShanghaiLinecode());
  256 + id2SHcode.put(line.getId(), line.getShanghaiLinecode());
284 257 code2SHcode.put(line.getLineCode(), line.getShanghaiLinecode());
285 258  
286 259 /**
287 260 * 加载运管处的站点及序号
288 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 284 lineId2CodeMap = biMap;
... ...
src/main/java/com/bsth/data/LineConfigData.java
... ... @@ -10,6 +10,7 @@ import org.slf4j.Logger;
10 10 import org.slf4j.LoggerFactory;
11 11 import org.springframework.beans.factory.annotation.Autowired;
12 12 import org.springframework.boot.CommandLineRunner;
  13 +import org.springframework.core.annotation.Order;
13 14 import org.springframework.stereotype.Component;
14 15  
15 16 import java.util.*;
... ... @@ -23,6 +24,7 @@ import java.util.*;
23 24 *
24 25 */
25 26 @Component
  27 +@Order(value = 2)
26 28 public class LineConfigData implements CommandLineRunner {
27 29  
28 30 Logger logger = LoggerFactory.getLogger(this.getClass());
... ...
src/main/java/com/bsth/data/gpsdata/GpsEntity.java
... ... @@ -86,7 +86,7 @@ public class GpsEntity {
86 86 private StationRoute station;
87 87  
88 88 /** 状态 */
89   - private String signalState;
  89 + private String signalState = "normal";
90 90  
91 91 public Integer getCompanyCode() {
92 92 return companyCode;
... ...
src/main/java/com/bsth/data/gpsdata/GpsRealData.java
... ... @@ -2,7 +2,6 @@ package com.bsth.data.gpsdata;
2 2  
3 3 import com.alibaba.fastjson.JSON;
4 4 import com.alibaba.fastjson.JSONObject;
5   -import com.bsth.Application;
6 5 import com.bsth.data.BasicData;
7 6 import com.bsth.data.forecast.ForecastRealServer;
8 7 import com.bsth.data.gpsdata.arrival.GpsRealAnalyse;
... ... @@ -26,7 +25,6 @@ import org.springframework.stereotype.Component;
26 25 import java.io.BufferedReader;
27 26 import java.io.InputStreamReader;
28 27 import java.util.*;
29   -import java.util.concurrent.TimeUnit;
30 28  
31 29 /**
32 30 * @author PanZhao
... ... @@ -67,12 +65,23 @@ public class GpsRealData implements CommandLineRunner {
67 65  
68 66 @Override
69 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, 5, TimeUnit.SECONDS);
72 70 }
73 71  
74 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 206 gps.setNbbm(nbbm);
198 207 //有更新的点位
199 208 updateList.add(gps);
  209 + //实时GPS数据集
  210 + gpsRealData.put(gps);
200 211 }
201 212 //分析数据
202 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.google.common.base.Splitter;
  5 +import com.google.common.collect.ArrayListMultimap;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +import java.util.ArrayList;
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * 信号状态数据
  13 + * Created by panzhao on 2016/12/30.
  14 + */
  15 +@Component
  16 +public class SignalStateData {
  17 +
  18 + private static ArrayListMultimap<String, SignalState> listMultimap = ArrayListMultimap.create();
  19 +
  20 + public void put(SignalState state){
  21 + listMultimap.put(state.getLineCode(), state);
  22 + //推送到客户端
  23 + }
  24 +
  25 + public List<SignalState> get(String idx){
  26 + List<SignalState> rs = new ArrayList<>();
  27 + List<String> ids = Splitter.on(",").splitToList(idx);
  28 +
  29 + for(String lineCode : ids){
  30 + rs.addAll(listMultimap.get(lineCode));
  31 + }
  32 + return rs;
  33 + }
  34 +}
... ...
src/main/java/com/bsth/data/gpsdata/arrival/GeoCacheData.java
... ... @@ -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 79 return routeCodeMap.get(gps.getLineId() + "_" + gps.getUpDown() + "_" + gps.getStopNo());
80 80 }
81 81  
... ... @@ -94,6 +94,21 @@ public class GeoCacheData {
94 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 112 public static Polygon getTccPolygon(String code) {
98 113 return tccMap.get(code);
99 114 }
... ...
src/main/java/com/bsth/data/gpsdata/arrival/SignalHandle.java
1 1 package com.bsth.data.gpsdata.arrival;
2 2  
3 3 import com.bsth.data.gpsdata.GpsEntity;
  4 +import com.bsth.data.gpsdata.arrival.entity.StationRoute;
4 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 12 * Created by panzhao on 2016/12/27.
... ... @@ -50,28 +55,13 @@ public abstract class SignalHandle {
50 55 return count;
51 56 }
52 57  
53   - /**
54   - * 车辆运行轨迹(最近20分钟)
55   - * 0:上行 1:下行 -1:未知
56   - *
57   - * @param gps
58   - * @return
59   - */
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   -
71   -
  58 + protected void transformUpdown(GpsEntity gps, ScheduleRealInfo sch){
  59 + int updown = Integer.parseInt(sch.getXlDir());
  60 + List<StationRoute> srs = GeoCacheData.getStationRoute(sch.getXlBm(), updown);
  61 + StationRoute station = GeoUtils.gpsInStation(gps, srs);
  62 + if (station != null) {
  63 + gps.setUpDown(updown);
  64 + gps.setStopNo(station.getCode());
72 65 }
73   - //for()
74   - return 0;
75 66 }
76   -
77 67 }
... ...
src/main/java/com/bsth/data/gpsdata/arrival/entity/RouteReverse.java
... ... @@ -5,6 +5,7 @@ package com.bsth.data.gpsdata.arrival.entity;
5 5 */
6 6 public class RouteReverse {
7 7  
  8 + private String nbbm;
8 9 //反转个数
9 10 private int count;
10 11  
... ... @@ -14,14 +15,11 @@ public class RouteReverse {
14 15 //掉头站点
15 16 private String turned;
16 17  
17   - //开始时间
18   - private long st;
19   -
20 18 //掉头时间
21 19 private long zt;
22 20  
23   - //结束时间
24   - private long et;
  21 + //检测时间
  22 + private long ct;
25 23  
26 24 //是否闭合
27 25 private boolean close;
... ... @@ -50,22 +48,6 @@ public class RouteReverse {
50 48 this.turned = turned;
51 49 }
52 50  
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 51 public boolean isClose() {
70 52 return close;
71 53 }
... ... @@ -81,4 +63,20 @@ public class RouteReverse {
81 63 public void setZt(long zt) {
82 64 this.zt = zt;
83 65 }
  66 +
  67 + public long getCt() {
  68 + return ct;
  69 + }
  70 +
  71 + public void setCt(long ct) {
  72 + this.ct = ct;
  73 + }
  74 +
  75 + public String getNbbm() {
  76 + return nbbm;
  77 + }
  78 +
  79 + public void setNbbm(String nbbm) {
  80 + this.nbbm = nbbm;
  81 + }
84 82 }
... ...
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 + SignalState state = new SignalState();
  41 + state.setSchId(sch.getId());
  42 + state.setType("route_reverse");
  43 + state.setCheckTime(System.currentTimeMillis());
  44 +
  45 + String stationName = BasicData.stationCode2NameMap.get(sch.getXlBm() + "_" + sch.getXlDir() + "_" + reverse.getTurned());
  46 + state.setText(fmtHHmm.print(reverse.getZt()) + " 从 " + stationName + " 站掉头");
  47 + state.setSt(sch.getFcsjActualTime());
  48 + state.setLineCode(sch.getXlBm());
  49 + state.setReverse(reverse);
  50 + return state;
  51 + }
  52 +
  53 + public static SignalState abnormalSignalSTate(ScheduleRealInfo sch, SignalAbnormal signalAbnormal){
  54 + SignalState state = new SignalState();
  55 + state.setSchId(sch.getId());
  56 + state.setType("abnormal_signal");
  57 + state.setCheckTime(signalAbnormal.getCt());
  58 + state.setLineCode(sch.getXlBm());
  59 +
  60 + String text = "信号";
  61 + String abnormType = signalAbnormal.getAbnormalType();
  62 + if(abnormType.equals("drift"))
  63 + text += "漂移";
  64 + else if(abnormType.equals("reconnection"))
  65 + text += "掉线";
  66 +
  67 + text += ("至" + fmtHHmm.print(signalAbnormal.getEt()) + "恢复正常");
  68 +
  69 + if(signalAbnormal.getOutOrIn() == 0)
  70 + text += "约在 00:00 分左右发车";
  71 + else if(signalAbnormal.getOutOrIn() == 1)
  72 + text += "约在 00:00 分左右到达终点";
  73 +
  74 + state.setText(text);
  75 + state.setSignalAbnormal(signalAbnormal);
  76 + return state;
  77 + }
  78 +
  79 + public String getType() {
  80 + return type;
  81 + }
  82 +
  83 + public void setType(String type) {
  84 + this.type = type;
  85 + }
  86 +
  87 + public long getCheckTime() {
  88 + return checkTime;
  89 + }
  90 +
  91 + public void setCheckTime(long checkTime) {
  92 + this.checkTime = checkTime;
  93 + }
  94 +
  95 +
  96 + public long getSchId() {
  97 + return schId;
  98 + }
  99 +
  100 + public void setSchId(long schId) {
  101 + this.schId = schId;
  102 + }
  103 +
  104 + public String getLineCode() {
  105 + return lineCode;
  106 + }
  107 +
  108 + public void setLineCode(String lineCode) {
  109 + this.lineCode = lineCode;
  110 + }
  111 +
  112 + public Long getSt() {
  113 + return st;
  114 + }
  115 +
  116 + public void setSt(Long st) {
  117 + this.st = st;
  118 + }
  119 +
  120 + public String getText() {
  121 + return text;
  122 + }
  123 +
  124 + public void setText(String text) {
  125 + this.text = text;
  126 + }
  127 +
  128 + public RouteReverse getReverse() {
  129 + return reverse;
  130 + }
  131 +
  132 + public void setReverse(RouteReverse reverse) {
  133 + this.reverse = reverse;
  134 + }
  135 +
  136 + public SignalAbnormal getSignalAbnormal() {
  137 + return signalAbnormal;
  138 + }
  139 +
  140 + public void setSignalAbnormal(SignalAbnormal signalAbnormal) {
  141 + this.signalAbnormal = signalAbnormal;
  142 + }
  143 +}
... ...
src/main/java/com/bsth/data/gpsdata/arrival/handlers/InOutStationSignalHandle.java
... ... @@ -2,11 +2,9 @@ package com.bsth.data.gpsdata.arrival.handlers;
2 2  
3 3 import com.bsth.data.LineConfigData;
4 4 import com.bsth.data.gpsdata.GpsEntity;
5   -import com.bsth.data.gpsdata.arrival.GeoCacheData;
6 5 import com.bsth.data.gpsdata.arrival.SignalHandle;
7   -import com.bsth.data.gpsdata.arrival.entity.StationRoute;
8 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;
10 8 import com.bsth.data.schedule.DayOfSchedule;
11 9 import com.bsth.entity.realcontrol.LineConfig;
12 10 import com.bsth.entity.realcontrol.ScheduleRealInfo;
... ... @@ -17,8 +15,6 @@ import org.slf4j.LoggerFactory;
17 15 import org.springframework.beans.factory.annotation.Autowired;
18 16 import org.springframework.stereotype.Component;
19 17  
20   -import java.util.List;
21   -
22 18 /**
23 19 * 进出站动作处理
24 20 * Created by panzhao on 2016/12/27.
... ... @@ -40,6 +36,9 @@ public class InOutStationSignalHandle extends SignalHandle{
40 36 @Autowired
41 37 DirectiveService directiveService;
42 38  
  39 + @Autowired
  40 + ScheduleSignalState scheduleSignalState;
  41 +
43 42 @Override
44 43 public boolean handle(GpsEntity gps, CircleQueue<GpsEntity> prevs) {
45 44  
... ... @@ -92,8 +91,6 @@ public class InOutStationSignalHandle extends SignalHandle{
92 91 String qdzCode = sch.getQdzCode();
93 92  
94 93  
95   - //if(sch.getFcsjActual() != )
96   -
97 94 //起点发车
98 95 if(qdzCode != null && prev.getStopNo().equals(qdzCode)
99 96 && !willDepart(gps, prev, sch)){
... ... @@ -108,6 +105,14 @@ public class InOutStationSignalHandle extends SignalHandle{
108 105 outStationAndOutPark(sch);
109 106 logger.info("班次:" + sch.getDfsj() + "发车, 时间:" + sch.getFcsjActual());
110 107 }
  108 + else if(sch.getBcType().equals("out")){
  109 + ScheduleRealInfo next = dayOfSchedule.next(sch);
  110 + if(prev.getStopNo().equals(next.getQdzCode())){
  111 + //发下一个班次
  112 + dayOfSchedule.addExecPlan(next);
  113 + outStation(gps, prev);
  114 + }
  115 + }
111 116 }
112 117  
113 118 private void outStationAndOutPark(ScheduleRealInfo sch){
... ... @@ -118,6 +123,8 @@ public class InOutStationSignalHandle extends SignalHandle{
118 123 if (schPrev != null && schPrev.getBcType().equals("out")) {
119 124 schPrev.setFcsjActualAll(sch.getFcsjActual());
120 125 schPrev.setZdsjActualAll(sch.getFcsjActual());
  126 +
  127 + sendUtils.refreshSch(schPrev);
121 128 }
122 129 }
123 130 }
... ... @@ -129,9 +136,8 @@ public class InOutStationSignalHandle extends SignalHandle{
129 136 */
130 137 private void inStation(GpsEntity gps, GpsEntity prev){
131 138 ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm());
132   - String zdzCode = sch.getZdzCode();
133 139  
134   - if(zdzCode != null && gps.getStopNo().equals(zdzCode)){
  140 + if(gps.getStopNo().equals(sch.getZdzCode())){
135 141  
136 142 sch.setZdsjActualAll(gps.getTimestamp());
137 143 //已完成班次数
... ... @@ -148,27 +154,16 @@ public class InOutStationSignalHandle extends SignalHandle{
148 154 if (next != null) {
149 155 next.setQdzArrDatesj(sch.getZdsjActual());
150 156 dayOfSchedule.addExecPlan(next);
151   -
152 157 //进站既进场
153 158 inStationAndInPark(sch, next);
154   -
155 159 //将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   - }
  160 + transformUpdown(gps, sch);
163 161 }
164 162 }
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   - }*/
  163 + else if(sch.getFcsjActual() == null){
  164 + //有进站,但班次没有实发,向前追溯一下信号
  165 + scheduleSignalState.signalRetrospect(gps, sch);
  166 + }
172 167 }
173 168  
174 169 /**
... ... @@ -181,6 +176,8 @@ public class InOutStationSignalHandle extends SignalHandle{
181 176 config != null && config.getOutConfig() == 2) {
182 177 next.setFcsjActualAll(sch.getZdsjActual());
183 178 next.setZdsjActualAll(sch.getZdsjActual());
  179 +
  180 + sendUtils.refreshSch(next);
184 181 }
185 182 }
186 183  
... ... @@ -193,7 +190,7 @@ public class InOutStationSignalHandle extends SignalHandle{
193 190 */
194 191 private boolean willDepart(GpsEntity gps, GpsEntity prev, Object task){
195 192  
196   -/* ScheduleRealInfo sch = (ScheduleRealInfo) task;
  193 + /*ScheduleRealInfo sch = (ScheduleRealInfo) task;
197 194 ScheduleRealInfo prevTask = dayOfSchedule.prev(sch);
198 195 if(prevTask == null || prevTask.getBcType().equals("out"))
199 196 return false;
... ...
src/main/java/com/bsth/data/gpsdata/arrival/handlers/OfflineSignalHandle.java
... ... @@ -13,16 +13,17 @@ import org.springframework.stereotype.Component;
13 13 @Component
14 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 19 //断开70分钟,之前的信号不再有参考价值
20 20 private final static int CLEAR_TIME = 1000 * 60 * 70;
21 21  
22 22 @Override
23 23 public boolean handle(GpsEntity gps, CircleQueue<GpsEntity> prevs) {
24   - //异常信号不管
25   - if(isAbnormal(gps)){
  24 + //漂移信号不管
  25 + if(gps.getLat() == 0 || gps.getLon() == 0){
  26 + gps.setSignalState("drift");
26 27 return true;
27 28 }
28 29  
... ...
src/main/java/com/bsth/data/gpsdata/arrival/handlers/ReverseSignalHandle.java
1 1 package com.bsth.data.gpsdata.arrival.handlers;
2 2  
3   -import com.alibaba.fastjson.JSON;
4 3 import com.bsth.data.gpsdata.GpsEntity;
5 4 import com.bsth.data.gpsdata.arrival.GeoCacheData;
6 5 import com.bsth.data.gpsdata.arrival.SignalHandle;
7 6 import com.bsth.data.gpsdata.arrival.entity.RouteReverse;
8 7 import com.bsth.data.gpsdata.arrival.entity.StationRoute;
9 8 import com.bsth.data.gpsdata.arrival.utils.CircleQueue;
  9 +import com.bsth.data.gpsdata.arrival.utils.ScheduleSignalState;
10 10 import com.bsth.data.schedule.DayOfSchedule;
11   -import com.bsth.entity.realcontrol.ScheduleRealInfo;
12 11 import org.slf4j.Logger;
13 12 import org.slf4j.LoggerFactory;
14 13 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -26,6 +25,9 @@ public class ReverseSignalHandle extends SignalHandle {
26 25 @Autowired
27 26 DayOfSchedule dayOfSchedule;
28 27  
  28 + @Autowired
  29 + ScheduleSignalState scheduleSignalState;
  30 +
29 31 @Override
30 32 public boolean handle(GpsEntity gps, CircleQueue<GpsEntity> prevs) {
31 33 if (!isNotEmpty(prevs))
... ... @@ -36,17 +38,8 @@ public class ReverseSignalHandle extends SignalHandle {
36 38 if (isReverse(gps, prev)) {
37 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 + scheduleSignalState.reverseAnalyse(reverse);
50 43 }
51 44 }
52 45 return false;
... ... @@ -63,7 +56,7 @@ public class ReverseSignalHandle extends SignalHandle {
63 56 RouteReverse routeReverse = new RouteReverse();
64 57 int count = 0;
65 58 String path = "";
66   - String turned = null;
  59 + long zt = 0L;
67 60  
68 61 //当前站点
69 62 StationRoute curr = GeoCacheData.getRouteCode(gps), sr;
... ... @@ -72,7 +65,8 @@ public class ReverseSignalHandle extends SignalHandle {
72 65 for (int i = array.length - 1; i > 0; i--) {
73 66 prev = (GpsEntity) array[i];
74 67  
75   - if(!prev.getUpDown().equals(gps.getUpDown()))
  68 + if (!prev.getUpDown().equals(gps.getUpDown())
  69 + || prev.getSignalState().equals("reconnection"))
76 70 break;
77 71  
78 72 if (prev.getInstation() == 1) {
... ... @@ -81,13 +75,15 @@ public class ReverseSignalHandle extends SignalHandle {
81 75 if (sr.getRouteSort() > curr.getRouteSort()) {
82 76 path += (curr.getCode() + ",");
83 77 count++;
84   - } else if (sr.getRouteSort() < curr.getRouteSort()) {
85   - path += (curr.getCode() + ",");
86   - //掉头点
87   - if (turned == null)
88   - turned = prev.getStopNo();
  78 + zt = prev.getTimestamp();
  79 + }
  80 + else if (sr.getRouteSort() < curr.getRouteSort()) {
  81 + if(routeReverse.getTurned() == null){
  82 + routeReverse.setTurned(curr.getCode());
  83 + }
89 84  
90   - //路径闭合
  85 + path += (curr.getCode() + ",");
  86 + //掉头前当前站
91 87 if (sr.getCode().equals(gps.getStopNo())) {
92 88 routeReverse.setClose(true);
93 89 path += sr.getCode();
... ... @@ -99,9 +95,11 @@ public class ReverseSignalHandle extends SignalHandle {
99 95 }
100 96 }
101 97  
  98 + routeReverse.setZt(zt);
102 99 routeReverse.setCount(count);
103 100 routeReverse.setDetail(path);
104   - routeReverse.setTurned(turned);
  101 + routeReverse.setCt(gps.getTimestamp());
  102 + routeReverse.setNbbm(gps.getNbbm());
105 103 return routeReverse;
106 104 }
107 105  
... ...
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 + /**
  108 + * 有到离站无发车时信号追溯
  109 + *
  110 + * @param gps
  111 + * @param sch
  112 + */
  113 + public void signalRetrospect(GpsEntity gps, ScheduleRealInfo sch) {
  114 + //回放数据,是否有掉线或者漂移
  115 + CircleQueue<GpsEntity> queue = GeoCacheData.getGps(gps.getNbbm());
  116 + if (queue == null || queue.size() == 0 || gps.getInstation() == 0)
  117 + return;
  118 +
  119 + //起始时间点
  120 + long st = 0;
  121 + ScheduleRealInfo prev = dayOfSchedule.prev(sch);
  122 +
  123 + if(prev != null){
  124 + if(prev.getZdsjActual() != null)
  125 + st = prev.getZdsjActualTime();
  126 + else
  127 + st = (GeoCacheData.midwayStation(gps.getLineId(), gps.getUpDown(), sch.getQdzCode(), gps.getStopNo()).size() + 1) * (1000 * 60 * 5);
  128 + }
  129 +
  130 + Object[] tempArray = queue.getQueue();
  131 + int len = tempArray.length;
  132 +
  133 + Object[] array = new Object[len + 1];
  134 + System.arraycopy(tempArray, 0, array, 0, len);
  135 + array[len] = gps;
  136 +
  137 + String gpsState = "";
  138 + GpsEntity tempGps, nearGps = null;
  139 + for (int i = len - 1; i > 0; i--) {
  140 + tempGps = (GpsEntity) array[i];
  141 +
  142 + gpsState = tempGps.getSignalState();
  143 + if(gpsState.equals("drift")){
  144 + nearGps = (GpsEntity) array[i + 1];
  145 + break;
  146 + }
  147 + else if(gpsState.equals("reconnection")){
  148 + nearGps = tempGps;
  149 + break;
  150 + }
  151 +
  152 + if(tempGps.getTimestamp() < st)
  153 + break;
  154 + }
  155 +
  156 + if(nearGps != null){
  157 + SignalAbnormal signalAbnormal = new SignalAbnormal();
  158 + signalAbnormal.setCt(gps.getTimestamp());
  159 + signalAbnormal.setEt(nearGps.getTimestamp());
  160 + signalAbnormal.setAbnormalType(gpsState);
  161 + signalAbnormal.setDestCode(sch.getQdzCode());
  162 + signalAbnormal.setOutOrIn(0);
  163 +
  164 + //记录信号状态
  165 + SignalState signalState = SignalState.abnormalSignalSTate(sch, signalAbnormal);
  166 + signalStateData.put(signalState);
  167 + }
  168 + }
  169 +}
... ...
src/main/java/com/bsth/data/gpsdata/recovery/GpsDataRecovery.java
... ... @@ -60,6 +60,8 @@ public class GpsDataRecovery implements ApplicationContextAware{
60 60 for (String nbbm : keys) {
61 61 Collections.sort(listMap.get(nbbm), comp);
62 62 threadPool.execute(new RecoveryThread(listMap.get(nbbm), count));
  63 + /*if(nbbm.equals("SXC-YD009"))
  64 + new RecoveryThread(listMap.get(nbbm), count).run();*/
63 65 }
64 66  
65 67 try {
... ... @@ -147,6 +149,9 @@ public class GpsDataRecovery implements ApplicationContextAware{
147 149 CircleQueue<GpsEntity> prevs;
148 150  
149 151 for(GpsEntity gps : list){
  152 + /* if(gps.getTimestamp() == 1483081260000L)
  153 + System.out.println("aaa");*/
  154 +
150 155 prevs = GeoCacheData.getGps(gps.getNbbm());
151 156 //掉线处理
152 157 offlineSignalHandle.handle(gps, prevs);
... ...
src/main/java/com/bsth/data/schedule/DayOfSchedule.java
... ... @@ -3,7 +3,6 @@ package com.bsth.data.schedule;
3 3 import com.alibaba.fastjson.JSON;
4 4 import com.alibaba.fastjson.JSONArray;
5 5 import com.bsth.Application;
6   -import com.bsth.data.BasicData;
7 6 import com.bsth.data.LineConfigData;
8 7 import com.bsth.data.directive.FirstScheduleCheckThread;
9 8 import com.bsth.data.gpsdata.GpsRealData;
... ... @@ -29,6 +28,7 @@ import org.slf4j.Logger;
29 28 import org.slf4j.LoggerFactory;
30 29 import org.springframework.beans.factory.annotation.Autowired;
31 30 import org.springframework.boot.CommandLineRunner;
  31 +import org.springframework.core.annotation.Order;
32 32 import org.springframework.stereotype.Component;
33 33  
34 34 import java.text.ParseException;
... ... @@ -43,6 +43,7 @@ import java.util.concurrent.TimeUnit;
43 43 * @date 2016年8月15日 上午10:16:12
44 44 */
45 45 @Component
  46 +@Order(value = 3)
46 47 public class DayOfSchedule implements CommandLineRunner {
47 48  
48 49 Logger logger = LoggerFactory.getLogger(this.getClass());
... ... @@ -117,19 +118,14 @@ public class DayOfSchedule implements CommandLineRunner {
117 118 LineConfigData lineConfigs;
118 119  
119 120 @Autowired
120   - BasicData.BasicDataLoader dataLoader;
121   -
122   - @Autowired
123 121 GpsDataRecovery gpsDataRecovery;
124 122  
125 123 private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd"), fmtHHmm = DateTimeFormat.forPattern("HH:mm");
126 124  
127 125 @Override
128 126 public void run(String... arg0) throws Exception {
129   - //加载基础数据
130   - dataLoader.loadAllData();
131 127 //从数据库恢复排班
132   - dataRecovery();
  128 + //dataRecovery();
133 129  
134 130 //翻班线程
135 131 // Application.mainServices.scheduleWithFixedDelay(scheduleRefreshThread, 15, 240, TimeUnit.SECONDS);
... ... @@ -224,13 +220,6 @@ public class DayOfSchedule implements CommandLineRunner {
224 220 reCalcExecPlan(nbbm);
225 221 }
226 222  
227   - //是否是出站即出场
228   - LineConfig conf = lineConfigData.get(lineCode);
229   - if (conf.getOutConfig() == 2) {
230   - for (String nbbm : cars)
231   - schAttrCalculator.connectOutSchedule(nbbmScheduleMap.get(nbbm));
232   - }
233   -
234 223 // 页面 翻班通知
235 224 sendUtils.shiftSchedule(lineCode);
236 225 } catch (Exception e) {
... ...
src/main/java/com/bsth/data/schedule/SchAttrCalculator.java
... ... @@ -162,34 +162,6 @@ public class SchAttrCalculator {
162 162  
163 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 166 public SchAttrCalculator calcFcsjTime(ScheduleRealInfo sch) throws ParseException {
195 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 53 /** 调度指令模板 */
54 54 private String schDirectiveTemp;
55 55  
  56 + /** 识别区间调头 */
  57 + private boolean readReverse;
  58 +
56 59 @OneToMany(cascade = CascadeType.ALL)
57 60 private Set<D80ReplyTemp> d80Temps = new HashSet<>();
58 61  
... ... @@ -140,4 +143,12 @@ public class LineConfig {
140 143 public void setD80Temps(Set<D80ReplyTemp> d80Temps) {
141 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 94 * 班次类型 TODO:正常班次、出场、进场、加油、区间班次、放空班次、放大站班次、两点间空驶
95 95 */
96 96 private String bcType;
97   -
98   - /** 出站即出场 , 关联的进出场班次 */
99   - @JsonIgnore
100   - @Transient
101   - private ScheduleRealInfo twinsSch;
102 97  
103 98 /** 创建人 */
104 99 @JsonIgnore
... ... @@ -258,21 +253,6 @@ public class ScheduleRealInfo {
258 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 258 @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
... ... @@ -804,13 +784,13 @@ public class ScheduleRealInfo {
804 784 this.opDirectiveState = opDirectiveState;
805 785 }
806 786  
807   - public ScheduleRealInfo getTwinsSch() {
  787 +/* public ScheduleRealInfo getTwinsSch() {
808 788 return twinsSch;
809 789 }
810 790  
811 791 public void setTwinsSch(ScheduleRealInfo twinsSch) {
812 792 this.twinsSch = twinsSch;
813   - }
  793 + }*/
814 794  
815 795 public boolean isLate() {
816 796 return late;
... ...
src/main/java/com/bsth/websocket/handler/SendUtils.java
1 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 3 import com.alibaba.fastjson.JSONObject;
16 4 import com.bsth.data.BasicData;
17 5 import com.bsth.data.LineConfigData;
... ... @@ -20,6 +8,13 @@ import com.bsth.entity.directive.D80;
20 8 import com.bsth.entity.realcontrol.ScheduleRealInfo;
21 9 import com.fasterxml.jackson.core.JsonProcessingException;
22 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 19 @Component
25 20 public class SendUtils{
... ... @@ -40,7 +35,7 @@ public class SendUtils{
40 35 */
41 36 public void sendFcsj(ScheduleRealInfo sch) {
42 37 //处理出站即出场的班次
43   - connectOutSchTime(sch);
  38 + //connectOutSchTime(sch);
44 39  
45 40 Map<String, Object> map = new HashMap<>();
46 41 map.put("fn", "faChe");
... ... @@ -86,7 +81,7 @@ public class SendUtils{
86 81 */
87 82 public void sendZdsj(ScheduleRealInfo sch, ScheduleRealInfo nextSch, int finish) {
88 83 //处理进站即进场的班次
89   - connectInSchTime(sch);
  84 + //connectInSchTime(sch);
90 85  
91 86 Map<String, Object> map = new HashMap<>();
92 87 map.put("fn", "zhongDian");
... ... @@ -157,39 +152,4 @@ public class SendUtils{
157 152 list.add(sch);
158 153 refreshSch(list);
159 154 }
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 155 }
... ...
src/main/resources/static/real_control_v2/css/line_schedule.css
... ... @@ -55,7 +55,7 @@
55 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 59 cursor: pointer;
60 60 font-size: 14px;
61 61 color: #cccaca;
... ... @@ -1022,4 +1022,24 @@ dd.fcsjActualCell div.last-sch-sunken span._badge{
1022 1022 .ct_table>.ct_table_body dl.dl-last-sch:hover div.last-sch-sunken,
1023 1023 .ct_table>.ct_table_body dl.dl-last-sch.context-menu-active div.last-sch-sunken{
1024 1024 background: #f5fbff;
  1025 +}
  1026 +
  1027 +dd.fcsjActualCell{
  1028 + position: relative;
  1029 +}
  1030 +
  1031 +i.signal_state_icon{
  1032 + position: absolute;
  1033 + right: 5px;
  1034 + top: 7px;
  1035 + color: #e85252 !important;
  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-reply{
  1043 + color: #4134e3;
  1044 + box-shadow: none;
1025 1045 }
1026 1046 \ No newline at end of file
... ...
src/main/resources/static/real_control_v2/fragments/line_schedule/sch_table.html
... ... @@ -83,7 +83,7 @@
83 83 <dd data-sort-val={{sch.dfsjT}} dbclick dbclick-type="dfsj" dbclick-val="{{sch.dfsj}}">
84 84 {{sch.dfsj}}
85 85 </dd>
86   - <dd class="
  86 + <dd data-uk-observe class="
87 87 {{if sch.status==-1}}
88 88 tl-qrlb
89 89 {{else if sch.status==2}}
... ...
src/main/resources/static/real_control_v2/js/line_schedule/layout.js
... ... @@ -22,7 +22,7 @@ var gb_line_layout = (function() {
22 22 };
23 23  
24 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 26 $(this).qtip({
27 27 show: {
28 28 ready: true,
... ...
src/main/resources/static/real_control_v2/js/line_schedule/sch_table.js
... ... @@ -446,6 +446,7 @@ var gb_schedule_table = (function () {
446 446 return car_yfwf_map[lineCode];
447 447 },
448 448 scroToDl: scroToDl,
449   - reset_drag_active_all: reset_drag_active_all
  449 + reset_drag_active_all: reset_drag_active_all,
  450 + getDl: getDl
450 451 };
451 452 })();
... ...
src/main/resources/static/real_control_v2/js/main.js
1 1 //主调和监控模式
2 2 var operationMode = window.localStorage.getItem('operationMode');
3   -if(operationMode == 0){
  3 +if (operationMode == 0) {
4 4 $('body>.north').addClass('monitor');
5 5 $(document).on('ajaxSend', interceptPOST);
6 6 }
... ... @@ -8,8 +8,8 @@ else
8 8 $('body>.north').addClass('main');
9 9  
10 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 13 console.log(e, xhr, t);
14 14 xhr.abort();
15 15 notify_err('监控模式!');
... ... @@ -18,54 +18,56 @@ function interceptPOST(e, xhr, t){
18 18  
19 19 /* main js */
20 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 22 var eq = gb_main_ep;
23 23 // basic data end
24 24 eq.once('data-basic', g_emit('tab'));
25 25 // tabs
26   - eq.once('tab', function() {
  26 + eq.once('tab', function () {
27 27 gb_tabs.init(
28 28 g_emit('home-layout')
29 29 );
30 30 });
31 31 //home layout
32   - eq.once('home-layout', function() {
  32 + eq.once('home-layout', function () {
33 33 gb_home_layout.layout(
34 34 g_emit('home-line-panel')
35 35 );
36 36 });
37 37 //home line panel
38   - eq.once('home-line-panel', function() {
  38 + eq.once('home-line-panel', function () {
39 39 gb_home_line_panel.init(g_emit('gps-time-refresh'));
40 40 });
41 41  
42 42 //start fixed time refresh gps
43   - eq.once('gps-time-refresh', function() {
  43 + eq.once('gps-time-refresh', function () {
44 44 gb_data_gps.fixedTimeRefresh();
45 45 g_emit('line-schedule-layout')();
46 46 });
47 47  
48 48 //line schedule layout
49   - eq.once('line-schedule-layout', function() {
  49 + eq.once('line-schedule-layout', function () {
50 50 gb_line_layout.layout(g_emit('render-sch-table'));
51 51 });
52 52  
53 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 65 showUpdateDescription();
64 66 });
65 67  
66 68 function g_emit(id) {
67 69 console.log('g_emit [' + id + ']');
68   - return function() {
  70 + return function () {
69 71 console.log('eq.emitLater(' + id + ')');
70 72 return eq.emitLater(id);
71 73 };
... ... @@ -73,17 +75,17 @@ var gb_main_ep = new EventProxy(),
73 75 });
74 76  
75 77 //modal hide remove dom
76   -$(document).on('hide.uk.modal', '.uk-modal', function() {
  78 +$(document).on('hide.uk.modal', '.uk-modal', function () {
77 79 $(this).remove();
78 80 });
79 81  
80 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 86 function connectArr(arr, separator, transFun) {
85 87 var rs = '';
86   - $.each(arr, function(i, item) {
  88 + $.each(arr, function (i, item) {
87 89 if (transFun)
88 90 item = transFun(item);
89 91 rs += (separator + item);
... ... @@ -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 108 UIkit.notify("<i class='uk-icon-spinner uk-icon-spin'></i> " + t, {
107 109 status: 'info'
108 110 });
109 111 };
110 112  
111   -var notify_succ = function(t) {
  113 +var notify_succ = function (t) {
112 114 UIkit.notify("<i class='uk-icon-check'></i> " + t, {
113 115 status: 'success'
114 116 });
115 117 };
116 118  
117   -var notify_err = function(t) {
  119 +var notify_err = function (t) {
118 120 UIkit.notify("<i class='uk-icon-times'></i> " + t, {
119 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 127 succ && succ();
126 128 modalEl.hide();
127 129 }, {
... ... @@ -129,15 +131,15 @@ var alt_confirm = function(content, succ, okBtn) {
129 131 Ok: okBtn,
130 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 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 143 $('.uk-alert-danger', form).remove();
142 144 $('.uk-modal-footer', form).before('<div class="uk-alert uk-alert-danger" data-uk-alert="">' +
143 145 '<a href="" class="uk-alert-close uk-close"></a>' +
... ... @@ -147,29 +149,29 @@ var notify_err_form = function(t, form) {
147 149 enable_submit_btn(form);
148 150 };
149 151  
150   -var enable_submit_btn = function(form) {
  152 +var enable_submit_btn = function (form) {
151 153 var subBtn = $('button[type=submit]', form);
152 154 if (subBtn) {
153 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 160 var subBtn = $('button[type=submit]', form);
159 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 167 $(document.body).append(dom);
166 168 return UIkit.modal(id, {
167 169 bgclose: false
168 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 175 if (!$(dom).hasClass('uk-modal')) {
174 176 alert('无效的dom片段!');
175 177 return;
... ... @@ -188,20 +190,20 @@ var open_modal = function(pageUrl, data, opt) {
188 190  
189 191 function showUpdateDescription() {
190 192 //更新说明
191   - var updateDescription={
  193 + var updateDescription = {
192 194 date: '2016-12-20',
193 195 text: '<h5>1、回场子任务开放使用。</h5>'
194 196 };
195 197  
196 198 var storage = window.localStorage
197   - ,key = 'update_' + updateDescription.date;
  199 + , key = 'update_' + updateDescription.date;
198 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 207 ' </div>';
206 208  
207 209 show_modal('#update-description-modal', modal);
... ...
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 +
  7 + $(document).on('click', 'i.signal_state_icon', function (e) {
  8 + e.stopPropagation();
  9 + });
  10 +
  11 + var signal_state_data = {};
  12 +
  13 + var init = function () {
  14 + $.get('/signalState/multi', {idx: gb_data_basic.line_idx}, function (rs) {
  15 + //按班次ID分组
  16 + signal_state_data = gb_common.groupBy(rs, 'schId');
  17 + console.log('信号数据', signal_state_data);
  18 +
  19 + $.each(rs, function () {
  20 + renderIcon(this);
  21 + });
  22 + //for(var schId)
  23 + });
  24 + };
  25 +
  26 + var renderIcon = function (sState) {
  27 + var sch = gb_schedule_table.findScheduleByLine(sState.lineCode)[sState.schId];
  28 + var dl = gb_schedule_table.getDl(sch);
  29 +
  30 + var dd = $('dd.fcsjActualCell', dl);
  31 + $('i.signal_state_icon', dd).remove();
  32 + var icon='question-circle';
  33 +
  34 + if(sState.type=='route_reverse')
  35 + icon = 'reply';
  36 +
  37 + dd.append('<i data-uk-tooltip title="'+sState.text+'" class="uk-icon-'+icon+' signal_state_icon"></i>');
  38 + };
  39 +
  40 + return {
  41 + init: init
  42 + };
  43 +})();
0 44 \ No newline at end of file
... ...
src/main/resources/static/real_control_v2/main.html
... ... @@ -142,6 +142,8 @@
142 142 <script src="/real_control_v2/assets/echarts-3/echarts.js"></script>
143 143 <!-- Geolib -->
144 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 147 </body>
146 148  
147 149 </html>
... ...
src/main/resources/static/real_control_v2/mapmonitor/fragments/playback/run.html
... ... @@ -148,10 +148,14 @@
148 148 var logs = [];
149 149 for (var i = 0; i <= ei; i++) {
150 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 160 trailPolyline.setPath(trailArray);
157 161  
... ... @@ -302,6 +306,9 @@
302 306 gb_ct_table.fixedHead(logWrap);
303 307  
304 308 function logWrite(gps, prve) {
  309 + if(!gps.road || !gps.road.ROAD_CODE)
  310 + return;
  311 +
305 312 var code = gps.road.ROAD_CODE;
306 313 if (!prve || code != prve.road.ROAD_CODE) {
307 314 logPanel.append('<dl data-code="' + code + '" ><dd>' + gps.timeStr + '</dd><dd>' + gps.speed + '</dd><dd>' + gps.road.ROAD_NAME + '</dd><dd>正常</dd></dl>');
... ...