Commit 2cd83ddbdb0ae951746985705537cb22a9c93f4b

Authored by 徐烜
2 parents e437b28b 07ae3e61

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

Too many changes to show.

To preserve performance only 10 of 13 files are displayed.

src/main/java/com/bsth/data/gpsdata_v2/DataHandleProcess.java
1   -package com.bsth.data.gpsdata_v2;
2   -
3   -import com.bsth.data.gpsdata_v2.cache.GpsCacheData;
4   -import com.bsth.data.gpsdata_v2.entity.GpsEntity;
5   -import com.bsth.data.gpsdata_v2.handlers.*;
6   -import com.google.common.collect.ArrayListMultimap;
7   -import org.slf4j.Logger;
8   -import org.slf4j.LoggerFactory;
9   -import org.springframework.beans.factory.annotation.Autowired;
10   -import org.springframework.stereotype.Component;
11   -
12   -import java.util.ArrayList;
13   -import java.util.List;
14   -import java.util.Set;
15   -import java.util.concurrent.CountDownLatch;
16   -import java.util.concurrent.ExecutorService;
17   -import java.util.concurrent.Executors;
18   -import java.util.concurrent.ThreadFactory;
19   -
20   -/**
21   - * 实时信号数据处理
22   - * Created by panzhao on 2017/11/15.
23   - */
24   -@Component
25   -public class DataHandleProcess {
26   -
27   - static Logger logger = LoggerFactory.getLogger(DataHandleProcess.class);
28   - final static int POOL_SIZE = 25;
29   -
30   - static ExecutorService threadPool = Executors.newFixedThreadPool(POOL_SIZE + 1, new HandlerThreadFactory());
31   - public static CountDownLatch count;
32   -
33   - @Autowired
34   - GpsStateProcess gpsStateProcess;
35   - @Autowired
36   - StationInsideProcess stationInsideProcess;
37   - @Autowired
38   - AbnormalStateProcess abnormalStateProcess;
39   - @Autowired
40   - InStationProcess inStationProcess;
41   - @Autowired
42   - OutStationProcess outStationProcess;
43   - @Autowired
44   - ReverseRouteProcess reverseRouteProcess;
45   -
46   - @Autowired
47   - GpsRealData gpsRealData;
48   -
49   - public void handle(List<GpsEntity> list) {
50   - try {
51   - //按设备号分组数据(一个设备的多条数据,必须在一个线程里跑)
52   - ArrayListMultimap multimap = ArrayListMultimap.create();
53   - for (GpsEntity gps : list) {
54   - multimap.put(gps.getDeviceId(), gps);
55   - }
56   - List<String> deviceList = new ArrayList<>(multimap.keySet());
57   -
58   - //数据均分给线程
59   - ArrayListMultimap dataListMap = ArrayListMultimap.create();
60   - int size = deviceList.size(), threadIndex = 0, threadSize = size / POOL_SIZE;
61   - for (int i = 0; i < size; i++) {
62   - if (i % threadSize == 0)
63   - threadIndex++;
64   - dataListMap.putAll(threadIndex, multimap.get(deviceList.get(i)));
65   - }
66   - Set<Integer> ks = dataListMap.keySet();
67   - logger.info("analyse gps size: " + list.size() + ", ks: " + ks.size());
68   - count = new CountDownLatch(ks.size());
69   -
70   - for (Integer index : ks) {
71   - threadPool.execute(new SignalHandleThread(dataListMap.get(index), count));
72   - }
73   -
74   - //等待子线程结束
75   - count.await();
76   -
77   - //加入实时gps对照
78   - for (GpsEntity gps : list)
79   - gpsRealData.put(gps);
80   - } catch (Exception e) {
81   - logger.error("", e);
82   - }
83   - }
84   -
85   - public class SignalHandleThread implements Runnable {
86   -
87   - List<GpsEntity> list;
88   - CountDownLatch count;
89   -
90   - SignalHandleThread(List<GpsEntity> gpsList, CountDownLatch count) {
91   - this.list = gpsList;
92   - this.count = count;
93   - }
94   -
95   - @Override
96   - public void run() {
97   - try {
98   - for (GpsEntity gps : list) {
99   - try{
100   - if(Math.abs(gps.getTimestamp() - gps.getServerTimestamp()) > 1000 * 60 * 20)
101   - continue;
102   -
103   - gpsStateProcess.process(gps);//状态处理
104   - stationInsideProcess.process(gps);//场站内外判定
105   - reverseRouteProcess.process(gps);//反向路由处理
106   - abnormalStateProcess.process(gps);//超速越界
107   -
108   - inStationProcess.process(gps);//进站
109   - outStationProcess.process(gps);//出站
110   -
111   - GpsCacheData.putGps(gps);//历史gps缓存
112   - }catch (Exception e){
113   - logger.error("", e);
114   - }
115   - }
116   - } finally {
117   - if (count != null)
118   - count.countDown();
119   - }
120   - }
121   - }
122   -
123   - static class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
124   - @Override
125   - public void uncaughtException(Thread t, Throwable e) {
126   - logger.error("caught " , e);
127   - }
128   - }
129   -
130   - static class HandlerThreadFactory implements ThreadFactory {
131   - @Override
132   - public Thread newThread(Runnable r) {
133   - Thread t = new Thread(r);
134   - t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
135   - return t;
136   - }
137   - }
  1 +package com.bsth.data.gpsdata_v2;
  2 +
  3 +import com.bsth.data.gpsdata_v2.cache.GpsCacheData;
  4 +import com.bsth.data.gpsdata_v2.entity.GpsEntity;
  5 +import com.bsth.data.gpsdata_v2.handlers.*;
  6 +import com.google.common.collect.ArrayListMultimap;
  7 +import org.slf4j.Logger;
  8 +import org.slf4j.LoggerFactory;
  9 +import org.springframework.beans.factory.annotation.Autowired;
  10 +import org.springframework.stereotype.Component;
  11 +
  12 +import java.util.ArrayList;
  13 +import java.util.List;
  14 +import java.util.Set;
  15 +import java.util.concurrent.CountDownLatch;
  16 +import java.util.concurrent.ExecutorService;
  17 +import java.util.concurrent.Executors;
  18 +import java.util.concurrent.ThreadFactory;
  19 +
  20 +/**
  21 + * 实时信号数据处理
  22 + * Created by panzhao on 2017/11/15.
  23 + */
  24 +@Component
  25 +public class DataHandleProcess {
  26 +
  27 + static Logger logger = LoggerFactory.getLogger(DataHandleProcess.class);
  28 + final static int POOL_SIZE = 25;
  29 +
  30 + static ExecutorService threadPool = Executors.newFixedThreadPool(POOL_SIZE + 1, new HandlerThreadFactory());
  31 + public static CountDownLatch count;
  32 +
  33 + @Autowired
  34 + GpsStateProcess gpsStateProcess;
  35 + @Autowired
  36 + StationInsideProcess stationInsideProcess;
  37 + @Autowired
  38 + AbnormalStateProcess abnormalStateProcess;
  39 + @Autowired
  40 + InStationProcess inStationProcess;
  41 + @Autowired
  42 + OutStationProcess outStationProcess;
  43 + @Autowired
  44 + ReverseRouteProcess reverseRouteProcess;
  45 +
  46 + @Autowired
  47 + GpsRealData gpsRealData;
  48 +
  49 + public void handle(List<GpsEntity> list) {
  50 + try {
  51 + //按设备号分组数据(一个设备的多条数据,必须在一个线程里跑)
  52 + ArrayListMultimap multimap = ArrayListMultimap.create();
  53 + for (GpsEntity gps : list) {
  54 + multimap.put(gps.getDeviceId(), gps);
  55 + }
  56 + List<String> deviceList = new ArrayList<>(multimap.keySet());
  57 +
  58 + //数据均分给线程
  59 + ArrayListMultimap dataListMap = ArrayListMultimap.create();
  60 + int size = deviceList.size(), threadIndex = 0, threadSize = size / POOL_SIZE;
  61 + for (int i = 0; i < size; i++) {
  62 + if (i % threadSize == 0)
  63 + threadIndex++;
  64 + dataListMap.putAll(threadIndex, multimap.get(deviceList.get(i)));
  65 + }
  66 + Set<Integer> ks = dataListMap.keySet();
  67 + logger.info("analyse gps size: " + list.size() + ", ks: " + ks.size());
  68 + count = new CountDownLatch(ks.size());
  69 +
  70 + for (Integer index : ks) {
  71 + threadPool.execute(new SignalHandleThread(dataListMap.get(index), count));
  72 + }
  73 +
  74 + //等待子线程结束
  75 + count.await();
  76 +
  77 + //加入实时gps对照
  78 + for (GpsEntity gps : list)
  79 + gpsRealData.put(gps);
  80 + } catch (Exception e) {
  81 + logger.error("", e);
  82 + }
  83 + }
  84 +
  85 + public class SignalHandleThread implements Runnable {
  86 +
  87 + List<GpsEntity> list;
  88 + CountDownLatch count;
  89 +
  90 + SignalHandleThread(List<GpsEntity> gpsList, CountDownLatch count) {
  91 + this.list = gpsList;
  92 + this.count = count;
  93 + }
  94 +
  95 + @Override
  96 + public void run() {
  97 + try {
  98 + for (GpsEntity gps : list) {
  99 + try{
  100 + if(Math.abs(gps.getTimestamp() - gps.getServerTimestamp()) > 1000 * 60 * 20)
  101 + continue;
  102 +
  103 + gpsStateProcess.process(gps);//状态处理
  104 + stationInsideProcess.process(gps);//场站内外判定
  105 + reverseRouteProcess.process(gps);//反向路由处理
  106 + abnormalStateProcess.process(gps);//超速越界
  107 +
  108 + inStationProcess.process(gps);//进站
  109 + outStationProcess.process(gps);//出站
  110 +
  111 + GpsCacheData.putGps(gps);//历史gps缓存
  112 + }catch (Exception e){
  113 + logger.error("", e);
  114 + }
  115 + }
  116 + } finally {
  117 + if (count != null)
  118 + count.countDown();
  119 + }
  120 + }
  121 + }
  122 +
  123 + static class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
  124 + @Override
  125 + public void uncaughtException(Thread t, Throwable e) {
  126 + logger.error("caught " , e);
  127 + }
  128 + }
  129 +
  130 + static class HandlerThreadFactory implements ThreadFactory {
  131 + @Override
  132 + public Thread newThread(Runnable r) {
  133 + Thread t = new Thread(r);
  134 + t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
  135 + return t;
  136 + }
  137 + }
138 138 }
139 139 \ No newline at end of file
... ...
src/main/java/com/bsth/data/gpsdata_v2/cache/GeoCacheData.java
1   -package com.bsth.data.gpsdata_v2.cache;
2   -
3   -import com.bsth.data.gpsdata_v2.entity.CtLineString;
4   -import com.bsth.data.gpsdata_v2.entity.GpsEntity;
5   -import com.bsth.data.gpsdata_v2.entity.PreconditionGeo;
6   -import com.bsth.data.gpsdata_v2.entity.StationRoute;
7   -import com.bsth.data.gpsdata_v2.utils.StationRouteComp;
8   -import com.bsth.util.Geo.Point;
9   -import com.bsth.util.Geo.Polygon;
10   -import com.google.common.base.Splitter;
11   -import com.google.common.collect.ArrayListMultimap;
12   -import org.apache.commons.lang3.StringUtils;
13   -import org.slf4j.Logger;
14   -import org.slf4j.LoggerFactory;
15   -import org.springframework.beans.factory.annotation.Autowired;
16   -import org.springframework.jdbc.core.BeanPropertyRowMapper;
17   -import org.springframework.jdbc.core.JdbcTemplate;
18   -import org.springframework.jdbc.core.RowMapper;
19   -import org.springframework.stereotype.Component;
20   -
21   -import java.sql.ResultSet;
22   -import java.sql.SQLException;
23   -import java.util.*;
24   -
25   -/**
26   - * 空间数据缓存
27   - * Created by panzhao on 2017/11/15.
28   - */
29   -@Component
30   -public class GeoCacheData {
31   -
32   - static Logger logger = LoggerFactory.getLogger(GeoCacheData.class);
33   -
34   - /**
35   - * 线路路段走向
36   - */
37   - private static ArrayListMultimap<String, CtLineString> sectionCacheMap;
38   - /**
39   - * 路段编码和名称对照
40   - */
41   - private static Map<String, String> sectionCode2Name;
42   - /**
43   - * 线路站点路由
44   - */
45   - private static ArrayListMultimap<String, StationRoute> stationCacheMap;
46   - /**
47   - * 线路前置进站围栏
48   - */
49   - public static ArrayListMultimap<String, PreconditionGeo> premiseGeoMap;
50   - /**
51   - * 线路_上下行_站点编码 ——> 站点
52   - */
53   - private static Map<String, StationRoute> routeCodeMap;
54   - /**
55   - * 停车场
56   - */
57   - public static Map<String, Polygon> tccMap;
58   - /**
59   - * 线路限速信息
60   - */
61   - private static Map<String, Double> speedLimitMap;
62   -
63   - @Autowired
64   - JdbcTemplate jdbcTemplate;
65   -
66   - public void loadData() {
67   - loadStationRoutesData();
68   - loadTccMapData();
69   - loadSpeedLimit();
70   -
71   - //加载路段信息
72   - loadRoadsData();
73   -
74   - //加载前置进站围栏
75   - loadPremiseGeoData();
76   - }
77   -
78   - public static List<StationRoute> getStationRoute(String lineCode, int directions) {
79   - return stationCacheMap.get(lineCode + "_" + directions);
80   - }
81   -
82   - public static StationRoute getRouteCode(GpsEntity gps) {
83   - return routeCodeMap.get(gps.getLineId() + "_" + gps.getUpDown() + "_" + gps.getStopNo());
84   - }
85   -
86   - public static Double speedLimit(String lineCode){
87   - return speedLimitMap.get(lineCode);
88   - }
89   -
90   - public static List<CtLineString> getLineStringList(GpsEntity gps){
91   - return sectionCacheMap.get(gps.getLineId() + "_" + gps.getUpDown());
92   - }
93   -
94   - private void loadStationRoutesData(){
95   - String sql = "select r.LINE_CODE,r.DIRECTIONS,r.STATION_CODE,r.STATION_MARK,s.SHAPES_TYPE,s.G_LONX,s.G_LATY,ST_AsText(s.G_POLYGON_GRID) as G_POLYGON_GRID,s.RADIUS, r.STATION_ROUTE_CODE,s.STATION_NAME from bsth_c_stationroute r left join bsth_c_station s on r.station=s.id where r.destroy=0 order by r.station_route_code";
96   - List<StationRoute> routeList = jdbcTemplate.query(sql, new RowMapper<StationRoute>() {
97   -
98   - @Override
99   - public StationRoute mapRow(ResultSet rs, int rowNum) throws SQLException {
100   - StationRoute sRoute = new StationRoute();
101   - sRoute.setCode(rs.getString("STATION_CODE"));
102   - sRoute.setLineCode(rs.getString("LINE_CODE"));
103   - sRoute.setDirections(rs.getInt("DIRECTIONS"));
104   - sRoute.setPoint(new Point(rs.getFloat("G_LONX"), rs.getFloat("G_LATY")));
105   - sRoute.setRadius(rs.getFloat("RADIUS"));
106   - sRoute.setRouteSort(rs.getInt("STATION_ROUTE_CODE"));
107   - sRoute.setMark(rs.getString("STATION_MARK"));
108   - sRoute.setName(rs.getString("STATION_NAME"));
109   -
110   - String shapesType = rs.getString("SHAPES_TYPE");
111   - //多边形电子围栏
112   - if (StringUtils.isNotEmpty(shapesType) && shapesType.equals("d"))
113   - sRoute.setPolygon(parsePolygon(rs.getString("G_POLYGON_GRID")));
114   - return sRoute;
115   - }
116   - });
117   -
118   - //按线路和走向分组
119   - if (routeList.size() > 0) {
120   - ArrayListMultimap<String, StationRoute> tempMap = ArrayListMultimap.create();
121   - Map<String, StationRoute> codeMap = new HashMap<>(routeList.size());
122   - for (StationRoute sr : routeList) {
123   - tempMap.put(sr.getLineCode() + "_" + sr.getDirections(), sr);
124   - //站点编码 ——> 和路由顺序对照
125   - codeMap.put(sr.getLineCode() + "_" + sr.getDirections() + "_" + sr.getCode(), sr);
126   - }
127   -
128   - StationRouteComp srCom = new StationRouteComp();
129   - //连接路由
130   - Set<String> set = tempMap.keySet();
131   - for (String key : set) {
132   - Collections.sort(tempMap.get(key), srCom);
133   - connectStationRoute(tempMap.get(key));
134   - }
135   - stationCacheMap = tempMap;
136   - routeCodeMap = codeMap;
137   - }
138   - }
139   -
140   - private void loadTccMapData(){
141   - //加载停车场数据
142   - String sql = "select PARK_CODE, ST_AsText(G_PARK_POINT) as G_PARK_POINT from bsth_c_car_park where park_code is not null and b_park_point is not null";
143   - List<Map<String, Object>> tccList = jdbcTemplate.queryForList(sql);
144   - Map<String, Polygon> tccTempMap = new HashMap<>();
145   -
146   - Polygon polygon;
147   - for (Map<String, Object> tMap : tccList) {
148   -
149   - try {
150   - polygon = parsePolygon(tMap.get("G_PARK_POINT").toString());
151   - tccTempMap.put(tMap.get("PARK_CODE").toString()
152   - , polygon);
153   - } catch (Exception e) {
154   - logger.error("停车场:" + tMap.get("PARK_CODE"), e);
155   - }
156   - }
157   - if (tccTempMap.size() > 0){
158   - tccMap = tccTempMap;
159   - }
160   - }
161   -
162   - private void loadSpeedLimit(){
163   - //加载线路限速信息
164   - String sql = "select l.LINE_CODE,i.SPEEDING from bsth_c_line_information i left join bsth_c_line l on i.line=l.id where i.speed_limit is not null";
165   - List<Map<String, Object>> speedMap = jdbcTemplate.queryForList(sql);
166   - Map<String, Double> speedTempMap = new HashMap<>();
167   - for (Map<String, Object> tMap : speedMap) {
168   - try {
169   - speedTempMap.put(tMap.get("LINE_CODE").toString(), Double.parseDouble(tMap.get("SPEEDING").toString()));
170   - } catch (NumberFormatException e) {
171   - logger.error("speeding is null...");
172   - }
173   - }
174   - speedLimitMap = speedTempMap;
175   - }
176   -
177   - private void loadRoadsData() {
178   - //加载线路下路段空间数据
179   - String sql = "select r.LINE_CODE,r.SECTION_CODE,r.SECTIONROUTE_CODE,s.SECTION_NAME,ST_AsText(s.GSECTION_VECTOR) as GSECTION_VECTOR, r.DIRECTIONS, s.CROSES_ROAD from bsth_c_sectionroute r INNER JOIN bsth_c_section s on r.section=s.id where r.destroy=0 and GSECTION_VECTOR is not null order by line_code,directions,sectionroute_code";
180   - List<Map<String, Object>> secList = jdbcTemplate.queryForList(sql);
181   -
182   - String polygonStr, key;
183   - String[] coords;
184   - int i, len;
185   - ArrayListMultimap<String, CtLineString> sectionCacheTempMap = ArrayListMultimap.create();
186   - String[] temps1, temps2;
187   - CtLineString lineString;
188   - for (Map<String, Object> tMap : secList) {
189   - //空间数据映射
190   - polygonStr = tMap.get("GSECTION_VECTOR").toString();
191   - key = tMap.get("LINE_CODE") + "_" + tMap.get("DIRECTIONS");
192   -
193   - coords = polygonStr.substring(11, polygonStr.length() - 1).split(",");
194   - len = coords.length - 1;
195   - //每2个点连一条线
196   - for(i = 0; i < len; i ++){
197   - temps1 = coords[i].split(" ");
198   - temps2 = coords[i + 1].split(" ");
199   -
200   - lineString = new CtLineString();
201   - lineString.setS(new Point(Float.parseFloat(temps1[0]), Float.parseFloat(temps1[1])));
202   - lineString.setE(new Point(Float.parseFloat(temps2[0]), Float.parseFloat(temps2[1])));
203   -
204   - sectionCacheTempMap.put(key, lineString);
205   - }
206   - }
207   -
208   - if(sectionCacheTempMap.size() > 0)
209   - sectionCacheMap = sectionCacheTempMap;
210   -
211   - Map<String, String> sectionCode2NameTemp = new HashMap<>();
212   -
213   - //加载全量路段编码和名称对照
214   - sql = "select SECTION_CODE,SECTION_NAME,CROSES_ROAD from bsth_c_section";
215   - secList = jdbcTemplate.queryForList(sql);
216   - String name = null, code;
217   - for (Map<String, Object> tMap : secList) {
218   - if(tMap.get("CROSES_ROAD") != null && StringUtils.isNotEmpty(tMap.get("CROSES_ROAD").toString()))
219   - name = tMap.get("CROSES_ROAD").toString();
220   - else if(tMap.get("SECTION_NAME") != null && StringUtils.isNotEmpty(tMap.get("SECTION_NAME").toString()))
221   - name = tMap.get("SECTION_NAME").toString();
222   -
223   - code = tMap.get("SECTION_CODE").toString();
224   - sectionCode2NameTemp.put(code, name);
225   - }
226   - if(sectionCode2NameTemp.size() > 0)
227   - sectionCode2Name = sectionCode2NameTemp;
228   - }
229   -
230   - private void loadPremiseGeoData() {
231   - ArrayListMultimap<String, PreconditionGeo> premiseGeoMapCopy = ArrayListMultimap.create();
232   -
233   - String sql = "select * from bsth_f_geo_premise";
234   - List<PreconditionGeo> list = jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(PreconditionGeo.class));
235   -
236   - List<String> coordList;
237   - String[] cs;
238   - Point point;
239   - List<Point> ps;
240   - StationRoute sr;
241   - for(PreconditionGeo p : list){
242   - try{
243   - sr = routeCodeMap.get(p.getLineCode()+"_"+p.getUpDown()+"_"+p.getStationCode());
244   - p.setOrder(sr.getRouteSort());
245   - //polygon
246   - ps = new ArrayList<>();
247   - coordList = Splitter.on(",").trimResults().splitToList(p.getCoords());
248   - for(String c : coordList){
249   - cs = c.split(" ");
250   - point = new Point(Double.parseDouble(cs[0]), Double.parseDouble(cs[1]));
251   - ps.add(point);
252   - }
253   -
254   - p.setPolygon(new Polygon(ps));
255   -
256   - sr.setPremise(true);
257   - //按线路,走向分组
258   - premiseGeoMapCopy.put(p.getLineCode()+"_"+p.getUpDown(), p);
259   - }catch (Exception e){
260   - logger.error("", e);
261   - }
262   - }
263   -
264   - //排序
265   - Set<String> ks = premiseGeoMapCopy.keySet();
266   - PreconditionGeoComp comp = new PreconditionGeoComp();
267   - for(String k : ks){
268   - Collections.sort(premiseGeoMapCopy.get(k), comp);
269   - }
270   -
271   - premiseGeoMap = premiseGeoMapCopy;
272   - }
273   -
274   - public Polygon parsePolygon(String polygonStr) {
275   - String[] coords = polygonStr.substring(9, polygonStr.length() - 2).split(","), temps;
276   -
277   - List<Point> cds = new ArrayList<>(coords.length);
278   - int len = coords.length;
279   - for (int i = 0; i < len; i++) {
280   - temps = coords[i].split(" ");
281   - cds.add(new Point(Float.parseFloat(temps[0]), Float.parseFloat(temps[1])));
282   - }
283   - return new Polygon(cds);
284   - }
285   -
286   - private void connectStationRoute(List<StationRoute> list) {
287   - int size = list.size();
288   - StationRoute sr = null;
289   - for (int i = 0; i < size; i++) {
290   - sr = list.get(i);
291   - //上一个
292   - if (i > 0)
293   - sr.setPrve(list.get(i - 1));
294   - //下一个
295   - if (i < size - 1)
296   - sr.setNext(list.get(i + 1));
297   - }
298   - }
299   -
300   - /**
301   - * 是否是环线
302   - * @param lineId
303   - * @return
304   - */
305   - public static boolean isLoopLine(String lineId) {
306   - List<StationRoute> srs = getStationRoute(lineId , 0);
307   - if(srs.get(0).getName().equals(srs.get(srs.size()- 1).getName())
308   - && getStationRoute(lineId , 1).size()==2)
309   - return true;
310   - return false;
311   - }
312   -
313   - private static class PreconditionGeoComp implements Comparator<PreconditionGeo>{
314   -
315   - @Override
316   - public int compare(PreconditionGeo p1, PreconditionGeo p2) {
317   - return p1.getOrder() - p2.getOrder();
318   - }
319   - }
320   -
321   - public static Map<String, String> sectionCode2NameMap(){
322   - return sectionCode2Name;
323   - }
  1 +package com.bsth.data.gpsdata_v2.cache;
  2 +
  3 +import com.bsth.data.gpsdata_v2.entity.CtLineString;
  4 +import com.bsth.data.gpsdata_v2.entity.GpsEntity;
  5 +import com.bsth.data.gpsdata_v2.entity.PreconditionGeo;
  6 +import com.bsth.data.gpsdata_v2.entity.StationRoute;
  7 +import com.bsth.data.gpsdata_v2.utils.StationRouteComp;
  8 +import com.bsth.util.Geo.Point;
  9 +import com.bsth.util.Geo.Polygon;
  10 +import com.google.common.base.Splitter;
  11 +import com.google.common.collect.ArrayListMultimap;
  12 +import org.apache.commons.lang3.StringUtils;
  13 +import org.slf4j.Logger;
  14 +import org.slf4j.LoggerFactory;
  15 +import org.springframework.beans.factory.annotation.Autowired;
  16 +import org.springframework.jdbc.core.BeanPropertyRowMapper;
  17 +import org.springframework.jdbc.core.JdbcTemplate;
  18 +import org.springframework.jdbc.core.RowMapper;
  19 +import org.springframework.stereotype.Component;
  20 +
  21 +import java.sql.ResultSet;
  22 +import java.sql.SQLException;
  23 +import java.util.*;
  24 +
  25 +/**
  26 + * 空间数据缓存
  27 + * Created by panzhao on 2017/11/15.
  28 + */
  29 +@Component
  30 +public class GeoCacheData {
  31 +
  32 + static Logger logger = LoggerFactory.getLogger(GeoCacheData.class);
  33 +
  34 + /**
  35 + * 线路路段走向
  36 + */
  37 + private static ArrayListMultimap<String, CtLineString> sectionCacheMap;
  38 + /**
  39 + * 路段编码和名称对照
  40 + */
  41 + private static Map<String, String> sectionCode2Name;
  42 + /**
  43 + * 线路站点路由
  44 + */
  45 + private static ArrayListMultimap<String, StationRoute> stationCacheMap;
  46 + /**
  47 + * 线路前置进站围栏
  48 + */
  49 + public static ArrayListMultimap<String, PreconditionGeo> premiseGeoMap;
  50 + /**
  51 + * 线路_上下行_站点编码 ——> 站点
  52 + */
  53 + private static Map<String, StationRoute> routeCodeMap;
  54 + /**
  55 + * 停车场
  56 + */
  57 + public static Map<String, Polygon> tccMap;
  58 + /**
  59 + * 线路限速信息
  60 + */
  61 + private static Map<String, Double> speedLimitMap;
  62 +
  63 + @Autowired
  64 + JdbcTemplate jdbcTemplate;
  65 +
  66 + public void loadData() {
  67 + loadStationRoutesData();
  68 + loadTccMapData();
  69 + loadSpeedLimit();
  70 +
  71 + //加载路段信息
  72 + loadRoadsData();
  73 +
  74 + //加载前置进站围栏
  75 + loadPremiseGeoData();
  76 + }
  77 +
  78 + public static List<StationRoute> getStationRoute(String lineCode, int directions) {
  79 + return stationCacheMap.get(lineCode + "_" + directions);
  80 + }
  81 +
  82 + public static StationRoute getRouteCode(GpsEntity gps) {
  83 + return routeCodeMap.get(gps.getLineId() + "_" + gps.getUpDown() + "_" + gps.getStopNo());
  84 + }
  85 +
  86 + public static Double speedLimit(String lineCode){
  87 + return speedLimitMap.get(lineCode);
  88 + }
  89 +
  90 + public static List<CtLineString> getLineStringList(GpsEntity gps){
  91 + return sectionCacheMap.get(gps.getLineId() + "_" + gps.getUpDown());
  92 + }
  93 +
  94 + private void loadStationRoutesData(){
  95 + String sql = "select r.LINE_CODE,r.DIRECTIONS,r.STATION_CODE,r.STATION_MARK,s.SHAPES_TYPE,s.G_LONX,s.G_LATY,ST_AsText(s.G_POLYGON_GRID) as G_POLYGON_GRID,s.RADIUS, r.STATION_ROUTE_CODE,s.STATION_NAME from bsth_c_stationroute r left join bsth_c_station s on r.station=s.id where r.destroy=0 order by r.station_route_code";
  96 + List<StationRoute> routeList = jdbcTemplate.query(sql, new RowMapper<StationRoute>() {
  97 +
  98 + @Override
  99 + public StationRoute mapRow(ResultSet rs, int rowNum) throws SQLException {
  100 + StationRoute sRoute = new StationRoute();
  101 + sRoute.setCode(rs.getString("STATION_CODE"));
  102 + sRoute.setLineCode(rs.getString("LINE_CODE"));
  103 + sRoute.setDirections(rs.getInt("DIRECTIONS"));
  104 + sRoute.setPoint(new Point(rs.getFloat("G_LONX"), rs.getFloat("G_LATY")));
  105 + sRoute.setRadius(rs.getFloat("RADIUS"));
  106 + sRoute.setRouteSort(rs.getInt("STATION_ROUTE_CODE"));
  107 + sRoute.setMark(rs.getString("STATION_MARK"));
  108 + sRoute.setName(rs.getString("STATION_NAME"));
  109 +
  110 + String shapesType = rs.getString("SHAPES_TYPE");
  111 + //多边形电子围栏
  112 + if (StringUtils.isNotEmpty(shapesType) && shapesType.equals("d"))
  113 + sRoute.setPolygon(parsePolygon(rs.getString("G_POLYGON_GRID")));
  114 + return sRoute;
  115 + }
  116 + });
  117 +
  118 + //按线路和走向分组
  119 + if (routeList.size() > 0) {
  120 + ArrayListMultimap<String, StationRoute> tempMap = ArrayListMultimap.create();
  121 + Map<String, StationRoute> codeMap = new HashMap<>(routeList.size());
  122 + for (StationRoute sr : routeList) {
  123 + tempMap.put(sr.getLineCode() + "_" + sr.getDirections(), sr);
  124 + //站点编码 ——> 和路由顺序对照
  125 + codeMap.put(sr.getLineCode() + "_" + sr.getDirections() + "_" + sr.getCode(), sr);
  126 + }
  127 +
  128 + StationRouteComp srCom = new StationRouteComp();
  129 + //连接路由
  130 + Set<String> set = tempMap.keySet();
  131 + for (String key : set) {
  132 + Collections.sort(tempMap.get(key), srCom);
  133 + connectStationRoute(tempMap.get(key));
  134 + }
  135 + stationCacheMap = tempMap;
  136 + routeCodeMap = codeMap;
  137 + }
  138 + }
  139 +
  140 + private void loadTccMapData(){
  141 + //加载停车场数据
  142 + String sql = "select PARK_CODE, ST_AsText(G_PARK_POINT) as G_PARK_POINT from bsth_c_car_park where park_code is not null and b_park_point is not null";
  143 + List<Map<String, Object>> tccList = jdbcTemplate.queryForList(sql);
  144 + Map<String, Polygon> tccTempMap = new HashMap<>();
  145 +
  146 + Polygon polygon;
  147 + for (Map<String, Object> tMap : tccList) {
  148 +
  149 + try {
  150 + polygon = parsePolygon(tMap.get("G_PARK_POINT").toString());
  151 + tccTempMap.put(tMap.get("PARK_CODE").toString()
  152 + , polygon);
  153 + } catch (Exception e) {
  154 + logger.error("停车场:" + tMap.get("PARK_CODE"), e);
  155 + }
  156 + }
  157 + if (tccTempMap.size() > 0){
  158 + tccMap = tccTempMap;
  159 + }
  160 + }
  161 +
  162 + private void loadSpeedLimit(){
  163 + //加载线路限速信息
  164 + String sql = "select l.LINE_CODE,i.SPEEDING from bsth_c_line_information i left join bsth_c_line l on i.line=l.id where i.speed_limit is not null";
  165 + List<Map<String, Object>> speedMap = jdbcTemplate.queryForList(sql);
  166 + Map<String, Double> speedTempMap = new HashMap<>();
  167 + for (Map<String, Object> tMap : speedMap) {
  168 + try {
  169 + speedTempMap.put(tMap.get("LINE_CODE").toString(), Double.parseDouble(tMap.get("SPEEDING").toString()));
  170 + } catch (NumberFormatException e) {
  171 + logger.error("speeding is null...");
  172 + }
  173 + }
  174 + speedLimitMap = speedTempMap;
  175 + }
  176 +
  177 + private void loadRoadsData() {
  178 + //加载线路下路段空间数据
  179 + String sql = "select r.LINE_CODE,r.SECTION_CODE,r.SECTIONROUTE_CODE,s.SECTION_NAME,ST_AsText(s.GSECTION_VECTOR) as GSECTION_VECTOR, r.DIRECTIONS, s.CROSES_ROAD from bsth_c_sectionroute r INNER JOIN bsth_c_section s on r.section=s.id where r.destroy=0 and GSECTION_VECTOR is not null order by line_code,directions,sectionroute_code";
  180 + List<Map<String, Object>> secList = jdbcTemplate.queryForList(sql);
  181 +
  182 + String polygonStr, key;
  183 + String[] coords;
  184 + int i, len;
  185 + ArrayListMultimap<String, CtLineString> sectionCacheTempMap = ArrayListMultimap.create();
  186 + String[] temps1, temps2;
  187 + CtLineString lineString;
  188 + for (Map<String, Object> tMap : secList) {
  189 + //空间数据映射
  190 + polygonStr = tMap.get("GSECTION_VECTOR").toString();
  191 + key = tMap.get("LINE_CODE") + "_" + tMap.get("DIRECTIONS");
  192 +
  193 + coords = polygonStr.substring(11, polygonStr.length() - 1).split(",");
  194 + len = coords.length - 1;
  195 + //每2个点连一条线
  196 + for(i = 0; i < len; i ++){
  197 + temps1 = coords[i].split(" ");
  198 + temps2 = coords[i + 1].split(" ");
  199 +
  200 + lineString = new CtLineString();
  201 + lineString.setS(new Point(Float.parseFloat(temps1[0]), Float.parseFloat(temps1[1])));
  202 + lineString.setE(new Point(Float.parseFloat(temps2[0]), Float.parseFloat(temps2[1])));
  203 +
  204 + sectionCacheTempMap.put(key, lineString);
  205 + }
  206 + }
  207 +
  208 + if(sectionCacheTempMap.size() > 0)
  209 + sectionCacheMap = sectionCacheTempMap;
  210 +
  211 + Map<String, String> sectionCode2NameTemp = new HashMap<>();
  212 +
  213 + //加载全量路段编码和名称对照
  214 + sql = "select SECTION_CODE,SECTION_NAME,CROSES_ROAD from bsth_c_section";
  215 + secList = jdbcTemplate.queryForList(sql);
  216 + String name = null, code;
  217 + for (Map<String, Object> tMap : secList) {
  218 + if(tMap.get("CROSES_ROAD") != null && StringUtils.isNotEmpty(tMap.get("CROSES_ROAD").toString()))
  219 + name = tMap.get("CROSES_ROAD").toString();
  220 + else if(tMap.get("SECTION_NAME") != null && StringUtils.isNotEmpty(tMap.get("SECTION_NAME").toString()))
  221 + name = tMap.get("SECTION_NAME").toString();
  222 +
  223 + code = tMap.get("SECTION_CODE").toString();
  224 + sectionCode2NameTemp.put(code, name);
  225 + }
  226 + if(sectionCode2NameTemp.size() > 0)
  227 + sectionCode2Name = sectionCode2NameTemp;
  228 + }
  229 +
  230 + private void loadPremiseGeoData() {
  231 + ArrayListMultimap<String, PreconditionGeo> premiseGeoMapCopy = ArrayListMultimap.create();
  232 +
  233 + String sql = "select * from bsth_f_geo_premise";
  234 + List<PreconditionGeo> list = jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(PreconditionGeo.class));
  235 +
  236 + List<String> coordList;
  237 + String[] cs;
  238 + Point point;
  239 + List<Point> ps;
  240 + StationRoute sr;
  241 + for(PreconditionGeo p : list){
  242 + try{
  243 + sr = routeCodeMap.get(p.getLineCode()+"_"+p.getUpDown()+"_"+p.getStationCode());
  244 + p.setOrder(sr.getRouteSort());
  245 + //polygon
  246 + ps = new ArrayList<>();
  247 + coordList = Splitter.on(",").trimResults().splitToList(p.getCoords());
  248 + for(String c : coordList){
  249 + cs = c.split(" ");
  250 + point = new Point(Double.parseDouble(cs[0]), Double.parseDouble(cs[1]));
  251 + ps.add(point);
  252 + }
  253 +
  254 + p.setPolygon(new Polygon(ps));
  255 +
  256 + sr.setPremise(true);
  257 + //按线路,走向分组
  258 + premiseGeoMapCopy.put(p.getLineCode()+"_"+p.getUpDown(), p);
  259 + }catch (Exception e){
  260 + logger.error("", e);
  261 + }
  262 + }
  263 +
  264 + //排序
  265 + Set<String> ks = premiseGeoMapCopy.keySet();
  266 + PreconditionGeoComp comp = new PreconditionGeoComp();
  267 + for(String k : ks){
  268 + Collections.sort(premiseGeoMapCopy.get(k), comp);
  269 + }
  270 +
  271 + premiseGeoMap = premiseGeoMapCopy;
  272 + }
  273 +
  274 + public Polygon parsePolygon(String polygonStr) {
  275 + String[] coords = polygonStr.substring(9, polygonStr.length() - 2).split(","), temps;
  276 +
  277 + List<Point> cds = new ArrayList<>(coords.length);
  278 + int len = coords.length;
  279 + for (int i = 0; i < len; i++) {
  280 + temps = coords[i].split(" ");
  281 + cds.add(new Point(Float.parseFloat(temps[0]), Float.parseFloat(temps[1])));
  282 + }
  283 + return new Polygon(cds);
  284 + }
  285 +
  286 + private void connectStationRoute(List<StationRoute> list) {
  287 + int size = list.size();
  288 + StationRoute sr = null;
  289 + for (int i = 0; i < size; i++) {
  290 + sr = list.get(i);
  291 + //上一个
  292 + if (i > 0)
  293 + sr.setPrve(list.get(i - 1));
  294 + //下一个
  295 + if (i < size - 1)
  296 + sr.setNext(list.get(i + 1));
  297 + }
  298 + }
  299 +
  300 + /**
  301 + * 是否是环线
  302 + * @param lineId
  303 + * @return
  304 + */
  305 + public static boolean isLoopLine(String lineId) {
  306 + List<StationRoute> srs = getStationRoute(lineId , 0);
  307 + if(srs.get(0).getName().equals(srs.get(srs.size()- 1).getName())
  308 + && getStationRoute(lineId , 1).size()==2)
  309 + return true;
  310 + return false;
  311 + }
  312 +
  313 + private static class PreconditionGeoComp implements Comparator<PreconditionGeo>{
  314 +
  315 + @Override
  316 + public int compare(PreconditionGeo p1, PreconditionGeo p2) {
  317 + return p1.getOrder() - p2.getOrder();
  318 + }
  319 + }
  320 +
  321 + public static Map<String, String> sectionCode2NameMap(){
  322 + return sectionCode2Name;
  323 + }
324 324 }
325 325 \ No newline at end of file
... ...
src/main/java/com/bsth/data/gpsdata_v2/handlers/InStationProcess.java
1   -package com.bsth.data.gpsdata_v2.handlers;
2   -
3   -import com.bsth.data.LineConfigData;
4   -import com.bsth.data.gpsdata_v2.cache.GeoCacheData;
5   -import com.bsth.data.gpsdata_v2.cache.GpsCacheData;
6   -import com.bsth.data.gpsdata_v2.entity.GpsEntity;
7   -import com.bsth.data.gpsdata_v2.entity.StationRoute;
8   -import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;
9   -import com.bsth.data.gpsdata_v2.utils.GeoUtils;
10   -import com.bsth.data.msg_queue.DirectivePushQueue;
11   -import com.bsth.data.schedule.DayOfSchedule;
12   -import com.bsth.data.schedule.late_adjust.LateAdjustHandle;
13   -import com.bsth.entity.realcontrol.LineConfig;
14   -import com.bsth.entity.realcontrol.ScheduleRealInfo;
15   -import com.bsth.websocket.handler.SendUtils;
16   -import org.apache.commons.lang3.StringUtils;
17   -import org.slf4j.Logger;
18   -import org.slf4j.LoggerFactory;
19   -import org.springframework.beans.factory.annotation.Autowired;
20   -import org.springframework.stereotype.Component;
21   -
22   -import java.util.List;
23   -
24   -/**
25   - * 车辆到站处理程序
26   - * Created by panzhao on 2017/11/16.
27   - */
28   -@Component
29   -public class InStationProcess {
30   -
31   - @Autowired
32   - DayOfSchedule dayOfSchedule;
33   -
34   - @Autowired
35   - LineConfigData lineConfigData;
36   -
37   - @Autowired
38   - SendUtils sendUtils;
39   -
40   - @Autowired
41   - GpsStatusManager gpsStatusManager;
42   -
43   - Logger logger = LoggerFactory.getLogger(this.getClass());
44   -
45   - public void process(GpsEntity gps) {
46   - GpsEntity prev = GpsCacheData.getPrev(gps);
47   -
48   - if(null == prev)
49   - return;
50   -
51   - //从站外到站内
52   - if(prev.getInstation() == 0 && gps.getInstation() > 0){
53   - inStation(gps, prev);
54   - }
55   -
56   - //从站内到另一个站内
57   - if(prev.getInstation() == 1 && gps.getInstation() == 1
58   - && !prev.getStopNo().equals(gps.getStopNo())
59   - && !prev.getStation().getName().equals(gps.getStation().getName()))
60   - inStation(gps, prev);
61   -
62   - //从场内到站内
63   - if(prev.getInstation() == 2 && gps.getInstation() == 1){
64   - inStation(gps, prev);
65   - }
66   -
67   - //被起点站覆盖的情况下进场
68   - if(isInPark(gps, prev))
69   - inStation(gps, prev);
70   - }
71   -
72   - /**
73   - * 进站
74   - *
75   - * @param gps
76   - * @param prev
77   - */
78   - private void inStation(GpsEntity gps, GpsEntity prev) {
79   - ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm());
80   - boolean flow = true;
81   - //要经过2个中途站才能进
82   - int count = GpsCacheData.lastInTrailsSize(gps);
83   - List<StationRoute> routes = GeoCacheData.getStationRoute(gps.getLineId(), gps.getUpDown());
84   - if (isNotInOut(sch) && gps.getInstation() == 1 && routes.size() > 4
85   - && count < 2) {
86   - logger.info("没有进中途站,拒绝进站... -" + gps.getNbbm() + " -time:" + gps.getTimestamp());
87   - flow = false;
88   - }
89   -
90   - boolean isEnd = false;
91   -
92   - //进终点
93   - if (flow && null != sch && sch.getZdzCode().equals(gps.getStopNo())) {
94   - inEndStation(sch, gps);
95   - isEnd = true;
96   - }
97   -
98   - GpsCacheData.in(gps, isEnd);
99   - }
100   -
101   - private boolean isNotInOut(ScheduleRealInfo sch) {
102   - return !sch.getBcType().equals("in") && !sch.getBcType().equals("out");
103   - }
104   -
105   - /**
106   - * 进班次终点
107   - *
108   - * @param gps
109   - */
110   - private void inEndStation(ScheduleRealInfo sch, GpsEntity gps) {
111   - String nbbm = sch.getClZbh();
112   - //校验进站前置约束
113   - if (!validInPremise(gps))
114   - return;
115   -
116   - //实达时间不覆盖
117   - if (StringUtils.isNotEmpty(sch.getZdsjActual()))
118   - return;
119   -
120   - //应用到离站缓冲区设置参数
121   - long rsT = lineConfigData.applyIn(sch, gps.getTimestamp());
122   -
123   - sch.setZdsjActualAll(rsT);
124   - sch.setSiginCompate(2);
125   - //通知误点停靠程序,有车辆到站
126   - LateAdjustHandle.carArrive(gps);
127   -
128   - //持久化
129   - dayOfSchedule.save(sch);
130   -
131   - //车辆的下一个班次
132   - ScheduleRealInfo next = dayOfSchedule.next(sch);
133   - if (next != null) {
134   - dayOfSchedule.addExecPlan(next);
135   - inStationAndInPark(sch, next);//进站既进场
136   - }
137   -
138   - //路牌的下一个班次,页面显示起点实际到达时间
139   - ScheduleRealInfo lpNext = dayOfSchedule.nextByLp(sch);
140   - if (lpNext != null) {
141   - lpNext.setQdzArrDatesj(sch.getZdsjActual());
142   - }
143   -
144   - //已完成班次数
145   - int doneSum = dayOfSchedule.doneSum(nbbm);
146   - //webSocket
147   - sendUtils.sendZdsj(sch, lpNext, doneSum);
148   -
149   - logger.info("车辆:" + nbbm + " 班次:" + sch.getDfsj() + "到终点, 时间:" + sch.getZdsjActual());
150   -
151   - //清除车辆误点调整监听
152   - LateAdjustHandle.remove(nbbm);
153   -
154   - //将gps转换成下一个班次走向的站内信号(应对只有一个站内信号 即 发出时)
155   - transformUpDown(gps, next);
156   -
157   - //下发调度指令
158   - DirectivePushQueue.put6002(next, doneSum, "到站@系统");
159   -
160   - //套跑 -下发线路切换指令
161   - if (null != next && !next.getXlBm().equals(sch.getXlBm())) {
162   - gpsStatusManager.changeLine(next.getClZbh(), next.getXlBm(), "套跑@系统");
163   - }
164   -
165   -
166   - if (null == next && gps.isService())
167   - nonService(sch, "结束@系统");//班次结束
168   - else if (null != next && dayOfSchedule.emptyService(next))
169   - nonService(sch, "空驶@系统");//下一班非营运
170   - }
171   -
172   - /**
173   - * 校验进站前置约束
174   - *
175   - * @param gps
176   - * @return
177   - */
178   - private boolean validInPremise(GpsEntity gps) {
179   - StationRoute sr = gps.getStation();
180   - if (null == sr || !sr.isPremise())
181   - return true;
182   -
183   - String premiseCode = gps.getPremiseCode();
184   -
185   - if (StringUtils.isNotEmpty(premiseCode) && premiseCode.equals(gps.getStopNo())) {
186   - logger.info("满足前置进站约束 " + premiseCode);
187   - return true;
188   - } else {
189   - logger.info(gps.getNbbm() + " not premiseCode 不满足前置进站约束 " + premiseCode);
190   - }
191   - return false;
192   - }
193   -
194   - /**
195   - * 进站既进场
196   - *
197   - * @param sch
198   - */
199   - private void inStationAndInPark(ScheduleRealInfo sch, ScheduleRealInfo next) {
200   - LineConfig config = lineConfigData.get(sch.getXlBm());
201   - //限定出站既出场的停车场
202   - String park = config.getTwinsPark();
203   - boolean limitPark = StringUtils.isNotEmpty(park);
204   -
205   -
206   - if (next.getBcType().equals("in") && config.getOutConfig() == 2 && isEmptyMileage(next)
207   - && (!limitPark || park.equals(next.getZdzCode()))) {
208   -
209   - endSch(next, sch.getZdsjActualTime());
210   -
211   - sendUtils.refreshSch(next);
212   - dayOfSchedule.save(next);
213   -
214   - //分班的时候,需要再跳过1个班次
215   - next = dayOfSchedule.next(next);
216   - if (next != null)
217   - dayOfSchedule.addExecPlan(next);
218   -
219   - //进场,切换成非营运状态
220   - nonService(sch, "进场@系统");
221   - }
222   - }
223   -
224   -
225   - private boolean isEmptyMileage(ScheduleRealInfo sch) {
226   - return sch.getBcsj() == 0 || sch.getJhlcOrig().intValue() == 0;
227   - }
228   -
229   -
230   - /**
231   - * 切换为非营运状态
232   - *
233   - * @param sch
234   - * @param sender
235   - */
236   - private void nonService(ScheduleRealInfo sch, String sender) {
237   - gpsStatusManager.changeServiceState(sch.getClZbh(), sch.getXlDir(), 1, sender);
238   - }
239   -
240   - private void endSch(ScheduleRealInfo sch, Long t) {
241   - sch.setFcsjActualAll(t);
242   - sch.setZdsjActualAll(t);
243   - }
244   -
245   - private void transformUpDown(GpsEntity gps, ScheduleRealInfo sch) {
246   - if (null == sch)
247   - return;
248   - byte upDown = Byte.parseByte(sch.getXlDir());
249   - //gps 切换走向
250   - gps.setUpDown(upDown);
251   - gps.setPremiseCode(null);
252   -
253   - List<StationRoute> srs = GeoCacheData.getStationRoute(sch.getXlBm(), upDown);
254   - StationRoute station = GeoUtils.gpsInStation(gps, srs);
255   - if (station != null) {
256   - gps.setStopNo(station.getCode());
257   - }
258   - }
259   -
260   - private boolean isInPark(GpsEntity gps, GpsEntity prve){
261   - if(StringUtils.isNotEmpty(gps.getCarparkNo()) && StringUtils.isEmpty(prve.getCarparkNo()))
262   - return true;
263   - return false;
264   - }
  1 +package com.bsth.data.gpsdata_v2.handlers;
  2 +
  3 +import com.bsth.data.LineConfigData;
  4 +import com.bsth.data.gpsdata_v2.cache.GeoCacheData;
  5 +import com.bsth.data.gpsdata_v2.cache.GpsCacheData;
  6 +import com.bsth.data.gpsdata_v2.entity.GpsEntity;
  7 +import com.bsth.data.gpsdata_v2.entity.StationRoute;
  8 +import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;
  9 +import com.bsth.data.gpsdata_v2.utils.GeoUtils;
  10 +import com.bsth.data.msg_queue.DirectivePushQueue;
  11 +import com.bsth.data.schedule.DayOfSchedule;
  12 +import com.bsth.data.schedule.late_adjust.LateAdjustHandle;
  13 +import com.bsth.entity.realcontrol.LineConfig;
  14 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  15 +import com.bsth.websocket.handler.SendUtils;
  16 +import org.apache.commons.lang3.StringUtils;
  17 +import org.slf4j.Logger;
  18 +import org.slf4j.LoggerFactory;
  19 +import org.springframework.beans.factory.annotation.Autowired;
  20 +import org.springframework.stereotype.Component;
  21 +
  22 +import java.util.List;
  23 +
  24 +/**
  25 + * 车辆到站处理程序
  26 + * Created by panzhao on 2017/11/16.
  27 + */
  28 +@Component
  29 +public class InStationProcess {
  30 +
  31 + @Autowired
  32 + DayOfSchedule dayOfSchedule;
  33 +
  34 + @Autowired
  35 + LineConfigData lineConfigData;
  36 +
  37 + @Autowired
  38 + SendUtils sendUtils;
  39 +
  40 + @Autowired
  41 + GpsStatusManager gpsStatusManager;
  42 +
  43 + Logger logger = LoggerFactory.getLogger(this.getClass());
  44 +
  45 + public void process(GpsEntity gps) {
  46 + GpsEntity prev = GpsCacheData.getPrev(gps);
  47 +
  48 + if(null == prev)
  49 + return;
  50 +
  51 + //从站外到站内
  52 + if(prev.getInstation() == 0 && gps.getInstation() > 0){
  53 + inStation(gps, prev);
  54 + }
  55 +
  56 + //从站内到另一个站内
  57 + if(prev.getInstation() == 1 && gps.getInstation() == 1
  58 + && !prev.getStopNo().equals(gps.getStopNo())
  59 + && !prev.getStation().getName().equals(gps.getStation().getName()))
  60 + inStation(gps, prev);
  61 +
  62 + //从场内到站内
  63 + if(prev.getInstation() == 2 && gps.getInstation() == 1){
  64 + inStation(gps, prev);
  65 + }
  66 +
  67 + //被起点站覆盖的情况下进场
  68 + if(isInPark(gps, prev))
  69 + inStation(gps, prev);
  70 + }
  71 +
  72 + /**
  73 + * 进站
  74 + *
  75 + * @param gps
  76 + * @param prev
  77 + */
  78 + private void inStation(GpsEntity gps, GpsEntity prev) {
  79 + ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm());
  80 + boolean flow = true;
  81 + //要经过2个中途站才能进
  82 + int count = GpsCacheData.lastInTrailsSize(gps);
  83 + List<StationRoute> routes = GeoCacheData.getStationRoute(gps.getLineId(), gps.getUpDown());
  84 + if (isNotInOut(sch) && gps.getInstation() == 1 && routes.size() > 4
  85 + && count < 2) {
  86 + logger.info("没有进中途站,拒绝进站... -" + gps.getNbbm() + " -time:" + gps.getTimestamp());
  87 + flow = false;
  88 + }
  89 +
  90 + boolean isEnd = false;
  91 +
  92 + //进终点
  93 + if (flow && null != sch && sch.getZdzCode().equals(gps.getStopNo())) {
  94 + inEndStation(sch, gps);
  95 + isEnd = true;
  96 + }
  97 +
  98 + GpsCacheData.in(gps, isEnd);
  99 + }
  100 +
  101 + private boolean isNotInOut(ScheduleRealInfo sch) {
  102 + return !sch.getBcType().equals("in") && !sch.getBcType().equals("out");
  103 + }
  104 +
  105 + /**
  106 + * 进班次终点
  107 + *
  108 + * @param gps
  109 + */
  110 + private void inEndStation(ScheduleRealInfo sch, GpsEntity gps) {
  111 + String nbbm = sch.getClZbh();
  112 + //校验进站前置约束
  113 + if (!validInPremise(gps))
  114 + return;
  115 +
  116 + //实达时间不覆盖
  117 + if (StringUtils.isNotEmpty(sch.getZdsjActual()))
  118 + return;
  119 +
  120 + //应用到离站缓冲区设置参数
  121 + long rsT = lineConfigData.applyIn(sch, gps.getTimestamp());
  122 +
  123 + sch.setZdsjActualAll(rsT);
  124 + sch.setSiginCompate(2);
  125 + //通知误点停靠程序,有车辆到站
  126 + LateAdjustHandle.carArrive(gps);
  127 +
  128 + //持久化
  129 + dayOfSchedule.save(sch);
  130 +
  131 + //车辆的下一个班次
  132 + ScheduleRealInfo next = dayOfSchedule.next(sch);
  133 + if (next != null) {
  134 + dayOfSchedule.addExecPlan(next);
  135 + inStationAndInPark(sch, next);//进站既进场
  136 + }
  137 +
  138 + //路牌的下一个班次,页面显示起点实际到达时间
  139 + ScheduleRealInfo lpNext = dayOfSchedule.nextByLp(sch);
  140 + if (lpNext != null) {
  141 + lpNext.setQdzArrDatesj(sch.getZdsjActual());
  142 + }
  143 +
  144 + //已完成班次数
  145 + int doneSum = dayOfSchedule.doneSum(nbbm);
  146 + //webSocket
  147 + sendUtils.sendZdsj(sch, lpNext, doneSum);
  148 +
  149 + logger.info("车辆:" + nbbm + " 班次:" + sch.getDfsj() + "到终点, 时间:" + sch.getZdsjActual());
  150 +
  151 + //清除车辆误点调整监听
  152 + LateAdjustHandle.remove(nbbm);
  153 +
  154 + //将gps转换成下一个班次走向的站内信号(应对只有一个站内信号 即 发出时)
  155 + transformUpDown(gps, next);
  156 +
  157 + //下发调度指令
  158 + DirectivePushQueue.put6002(next, doneSum, "到站@系统");
  159 +
  160 + //套跑 -下发线路切换指令
  161 + if (null != next && !next.getXlBm().equals(sch.getXlBm())) {
  162 + gpsStatusManager.changeLine(next.getClZbh(), next.getXlBm(), "套跑@系统");
  163 + }
  164 +
  165 +
  166 + if (null == next && gps.isService())
  167 + nonService(sch, "结束@系统");//班次结束
  168 + else if (null != next && dayOfSchedule.emptyService(next))
  169 + nonService(sch, "空驶@系统");//下一班非营运
  170 + }
  171 +
  172 + /**
  173 + * 校验进站前置约束
  174 + *
  175 + * @param gps
  176 + * @return
  177 + */
  178 + private boolean validInPremise(GpsEntity gps) {
  179 + StationRoute sr = gps.getStation();
  180 + if (null == sr || !sr.isPremise())
  181 + return true;
  182 +
  183 + String premiseCode = gps.getPremiseCode();
  184 +
  185 + if (StringUtils.isNotEmpty(premiseCode) && premiseCode.equals(gps.getStopNo())) {
  186 + logger.info("满足前置进站约束 " + premiseCode);
  187 + return true;
  188 + } else {
  189 + logger.info(gps.getNbbm() + " not premiseCode 不满足前置进站约束 " + premiseCode);
  190 + }
  191 + return false;
  192 + }
  193 +
  194 + /**
  195 + * 进站既进场
  196 + *
  197 + * @param sch
  198 + */
  199 + private void inStationAndInPark(ScheduleRealInfo sch, ScheduleRealInfo next) {
  200 + LineConfig config = lineConfigData.get(sch.getXlBm());
  201 + //限定出站既出场的停车场
  202 + String park = config.getTwinsPark();
  203 + boolean limitPark = StringUtils.isNotEmpty(park);
  204 +
  205 +
  206 + if (next.getBcType().equals("in") && config.getOutConfig() == 2 && isEmptyMileage(next)
  207 + && (!limitPark || park.equals(next.getZdzCode()))) {
  208 +
  209 + endSch(next, sch.getZdsjActualTime());
  210 +
  211 + sendUtils.refreshSch(next);
  212 + dayOfSchedule.save(next);
  213 +
  214 + //分班的时候,需要再跳过1个班次
  215 + next = dayOfSchedule.next(next);
  216 + if (next != null)
  217 + dayOfSchedule.addExecPlan(next);
  218 +
  219 + //进场,切换成非营运状态
  220 + nonService(sch, "进场@系统");
  221 + }
  222 + }
  223 +
  224 +
  225 + private boolean isEmptyMileage(ScheduleRealInfo sch) {
  226 + return sch.getBcsj() == 0 || sch.getJhlcOrig().intValue() == 0;
  227 + }
  228 +
  229 +
  230 + /**
  231 + * 切换为非营运状态
  232 + *
  233 + * @param sch
  234 + * @param sender
  235 + */
  236 + private void nonService(ScheduleRealInfo sch, String sender) {
  237 + gpsStatusManager.changeServiceState(sch.getClZbh(), sch.getXlDir(), 1, sender);
  238 + }
  239 +
  240 + private void endSch(ScheduleRealInfo sch, Long t) {
  241 + sch.setFcsjActualAll(t);
  242 + sch.setZdsjActualAll(t);
  243 + }
  244 +
  245 + private void transformUpDown(GpsEntity gps, ScheduleRealInfo sch) {
  246 + if (null == sch)
  247 + return;
  248 + byte upDown = Byte.parseByte(sch.getXlDir());
  249 + //gps 切换走向
  250 + gps.setUpDown(upDown);
  251 + gps.setPremiseCode(null);
  252 +
  253 + List<StationRoute> srs = GeoCacheData.getStationRoute(sch.getXlBm(), upDown);
  254 + StationRoute station = GeoUtils.gpsInStation(gps, srs);
  255 + if (station != null) {
  256 + gps.setStopNo(station.getCode());
  257 + }
  258 + }
  259 +
  260 + private boolean isInPark(GpsEntity gps, GpsEntity prve){
  261 + if(StringUtils.isNotEmpty(gps.getCarparkNo()) && StringUtils.isEmpty(prve.getCarparkNo()))
  262 + return true;
  263 + return false;
  264 + }
265 265 }
266 266 \ No newline at end of file
... ...
src/main/java/com/bsth/data/gpsdata_v2/handlers/OutStationProcess.java
1   -package com.bsth.data.gpsdata_v2.handlers;
2   -
3   -import com.bsth.data.LineConfigData;
4   -import com.bsth.data.gpsdata_v2.cache.GpsCacheData;
5   -import com.bsth.data.gpsdata_v2.entity.GpsEntity;
6   -import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;
7   -import com.bsth.data.gpsdata_v2.utils.SignalSchPlanMatcher;
8   -import com.bsth.data.schedule.DayOfSchedule;
9   -import com.bsth.data.schedule.late_adjust.LateAdjustHandle;
10   -import com.bsth.entity.realcontrol.LineConfig;
11   -import com.bsth.entity.realcontrol.ScheduleRealInfo;
12   -import com.bsth.websocket.handler.SendUtils;
13   -import org.apache.commons.lang3.StringUtils;
14   -import org.slf4j.Logger;
15   -import org.slf4j.LoggerFactory;
16   -import org.springframework.beans.factory.annotation.Autowired;
17   -import org.springframework.stereotype.Component;
18   -
19   -/**
20   - * 车辆出站处理程序
21   - * Created by panzhao on 2017/11/16.
22   - */
23   -@Component
24   -public class OutStationProcess {
25   -
26   - @Autowired
27   - DayOfSchedule dayOfSchedule;
28   -
29   - Logger logger = LoggerFactory.getLogger(this.getClass());
30   -
31   - @Autowired
32   - LineConfigData lineConfigData;
33   -
34   - @Autowired
35   - SendUtils sendUtils;
36   -
37   - @Autowired
38   - SignalSchPlanMatcher signalSchPlanMatcher;
39   -
40   - @Autowired
41   - GpsStatusManager gpsStatusManager;
42   - private final static int MAX_BEFORE_TIME = 1000 * 60 * 120;
43   -
44   - public void process(GpsEntity gps){
45   - GpsEntity prev = GpsCacheData.getPrev(gps);
46   -
47   - if(null == prev)
48   - return;
49   -
50   - //从站内到站外
51   - if(prev.getInstation() > 0 && gps.getInstation() == 0)
52   - outStation(gps, prev);
53   -
54   - //从站内到另一个站内
55   - if(prev.getInstation() > 0 && gps.getInstation() > 0
56   - && !prev.getStopNo().equals(gps.getStopNo()))
57   - outStation(gps, prev);
58   -
59   - //在被起点站覆盖的情况下出场
60   - if(isOutPark(gps, prev))
61   - outStation(gps, prev);
62   - }
63   -
64   - /**
65   - * 出站
66   - * @param gps
67   - */
68   - private void outStation(GpsEntity gps, GpsEntity prev) {
69   - ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm());
70   -
71   - //起点发车
72   - if (null != sch &&
73   - (sch.getQdzCode().equals(prev.getStopNo()) || sch.getQdzCode().equals(prev.getCarparkNo()))){
74   - //发车班次匹配
75   - if(!signalSchPlanMatcher.outMatch(gps, sch)){
76   - outStation(gps, prev);
77   - return;
78   - }
79   -
80   - int diff = (int) (sch.getDfsjT() - gps.getTimestamp());
81   - //首班出场最多提前2小时
82   - if((dayOfSchedule.isFirstOut(sch) && diff > MAX_BEFORE_TIME) || diff > MAX_BEFORE_TIME / 2)
83   - return;
84   -
85   - gps.setPremiseCode(null);//清除前置围栏标记
86   -
87   - if(StringUtils.isNotEmpty(sch.getFcsjActual())
88   - && !outManyFit(gps, sch)){
89   - return;//班次已经实发
90   - }
91   -
92   - //应用到离站缓冲区设置参数
93   - long rsT = lineConfigData.applyOut(sch, gps.getTimestamp());
94   - //实发时间
95   - sch.setFcsjActualAll(rsT);
96   - sch.setSiginCompate(1);
97   -
98   - //出站既出场
99   - outStationAndOutPark(sch);
100   -
101   - //webSocket
102   - sendUtils.sendFcsj(sch);
103   -
104   - //持久化
105   - dayOfSchedule.save(sch);
106   -
107   - //清理应发未发标记
108   - LateAdjustHandle.remove(sch.getClZbh());
109   -
110   - //发车的时候,同步一下状态
111   - if(!gps.isService() && !dayOfSchedule.emptyService(sch))
112   - gpsStatusManager.changeServiceState(sch.getClZbh(), sch.getXlDir(), 0, "发车@系统");
113   -
114   - logger.info("车辆:" + sch.getClZbh() + " 班次:" + sch.getDfsj() + "发车, 时间:" + sch.getFcsjActual());
115   - }
116   -
117   - GpsCacheData.out(gps);
118   - }
119   -
120   - /**
121   - * 是否是一个更合适的发车信号
122   - * @param gps
123   - * @param sch
124   - * @return
125   - */
126   - private boolean outManyFit(GpsEntity gps, ScheduleRealInfo sch) {
127   - LineConfig conf = lineConfigData.get(sch.getXlBm());
128   - if(null != conf && conf.isLockFirstOutTime())
129   - return false;
130   -
131   - if(StringUtils.isNotEmpty(sch.getZdsjActual()))
132   - return false;
133   -
134   - long t1 = sch.getFcsjActualTime();
135   - long t2 = gps.getTimestamp();
136   - long c = sch.getDfsjT();
137   -
138   - int threshold = 1000 * 60 * 5;
139   - if(Math.abs(t2 - c) < threshold && c - t1 > threshold){
140   - return true;
141   - }
142   -
143   - if(c - t1 > 1000 * 60 * 60 * 2 && Math.abs(t2 - c) < c - t1){
144   - return true;
145   - }
146   - return false;
147   - }
148   -
149   - private void outStationAndOutPark(ScheduleRealInfo sch){
150   - try{
151   - LineConfig config = lineConfigData.get(sch.getXlBm());
152   - //限定出站既出场的停车场
153   - String park = config.getTwinsPark();
154   - boolean limitPark = StringUtils.isNotEmpty(park);
155   -
156   - if (config != null && config.getOutConfig() == 2) {
157   - //出站既出场
158   - ScheduleRealInfo schPrev = dayOfSchedule.prev(sch);
159   - if (isOut(schPrev) && isEmptyMileage(schPrev)
160   - && (!limitPark || park.equals(schPrev.getQdzCode()))) {
161   -
162   - endSch(schPrev, sch.getFcsjActualTime());
163   -
164   - //起点实到
165   - sch.setQdzArrDatesj(schPrev.getZdsjActual());
166   -
167   - sendUtils.refreshSch(schPrev);
168   - dayOfSchedule.save(schPrev);
169   - }
170   - }
171   - }catch (Exception e){
172   - logger.error("", e);
173   - }
174   - }
175   -
176   - private boolean isEmptyMileage(ScheduleRealInfo sch){
177   - return sch.getBcsj()==0 || sch.getJhlcOrig().intValue()==0;
178   - }
179   -
180   - private boolean isOut(ScheduleRealInfo sch){
181   - return sch != null && sch.getBcType().equals("out");
182   - }
183   -
184   - private void endSch(ScheduleRealInfo sch, Long t){
185   - sch.setFcsjActualAll(t);
186   - sch.setZdsjActualAll(t);
187   - }
188   -
189   - private boolean isOutPark(GpsEntity gps, GpsEntity prve){
190   - if(StringUtils.isNotEmpty(prve.getCarparkNo()) && StringUtils.isEmpty(gps.getCarparkNo()))
191   - return true;
192   - return false;
193   - }
  1 +package com.bsth.data.gpsdata_v2.handlers;
  2 +
  3 +import com.bsth.data.LineConfigData;
  4 +import com.bsth.data.gpsdata_v2.cache.GpsCacheData;
  5 +import com.bsth.data.gpsdata_v2.entity.GpsEntity;
  6 +import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;
  7 +import com.bsth.data.gpsdata_v2.utils.SignalSchPlanMatcher;
  8 +import com.bsth.data.schedule.DayOfSchedule;
  9 +import com.bsth.data.schedule.late_adjust.LateAdjustHandle;
  10 +import com.bsth.entity.realcontrol.LineConfig;
  11 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  12 +import com.bsth.websocket.handler.SendUtils;
  13 +import org.apache.commons.lang3.StringUtils;
  14 +import org.slf4j.Logger;
  15 +import org.slf4j.LoggerFactory;
  16 +import org.springframework.beans.factory.annotation.Autowired;
  17 +import org.springframework.stereotype.Component;
  18 +
  19 +/**
  20 + * 车辆出站处理程序
  21 + * Created by panzhao on 2017/11/16.
  22 + */
  23 +@Component
  24 +public class OutStationProcess {
  25 +
  26 + @Autowired
  27 + DayOfSchedule dayOfSchedule;
  28 +
  29 + Logger logger = LoggerFactory.getLogger(this.getClass());
  30 +
  31 + @Autowired
  32 + LineConfigData lineConfigData;
  33 +
  34 + @Autowired
  35 + SendUtils sendUtils;
  36 +
  37 + @Autowired
  38 + SignalSchPlanMatcher signalSchPlanMatcher;
  39 +
  40 + @Autowired
  41 + GpsStatusManager gpsStatusManager;
  42 + private final static int MAX_BEFORE_TIME = 1000 * 60 * 120;
  43 +
  44 + public void process(GpsEntity gps){
  45 + GpsEntity prev = GpsCacheData.getPrev(gps);
  46 +
  47 + if(null == prev)
  48 + return;
  49 +
  50 + //从站内到站外
  51 + if(prev.getInstation() > 0 && gps.getInstation() == 0)
  52 + outStation(gps, prev);
  53 +
  54 + //从站内到另一个站内
  55 + if(prev.getInstation() > 0 && gps.getInstation() > 0
  56 + && !prev.getStopNo().equals(gps.getStopNo()))
  57 + outStation(gps, prev);
  58 +
  59 + //在被起点站覆盖的情况下出场
  60 + if(isOutPark(gps, prev))
  61 + outStation(gps, prev);
  62 + }
  63 +
  64 + /**
  65 + * 出站
  66 + * @param gps
  67 + */
  68 + private void outStation(GpsEntity gps, GpsEntity prev) {
  69 + ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm());
  70 +
  71 + //起点发车
  72 + if (null != sch &&
  73 + (sch.getQdzCode().equals(prev.getStopNo()) || sch.getQdzCode().equals(prev.getCarparkNo()))){
  74 + //发车班次匹配
  75 + if(!signalSchPlanMatcher.outMatch(gps, sch)){
  76 + outStation(gps, prev);
  77 + return;
  78 + }
  79 +
  80 + int diff = (int) (sch.getDfsjT() - gps.getTimestamp());
  81 + //首班出场最多提前2小时
  82 + if((dayOfSchedule.isFirstOut(sch) && diff > MAX_BEFORE_TIME) || diff > MAX_BEFORE_TIME / 2)
  83 + return;
  84 +
  85 + gps.setPremiseCode(null);//清除前置围栏标记
  86 +
  87 + if(StringUtils.isNotEmpty(sch.getFcsjActual())
  88 + && !outManyFit(gps, sch)){
  89 + return;//班次已经实发
  90 + }
  91 +
  92 + //应用到离站缓冲区设置参数
  93 + long rsT = lineConfigData.applyOut(sch, gps.getTimestamp());
  94 + //实发时间
  95 + sch.setFcsjActualAll(rsT);
  96 + sch.setSiginCompate(1);
  97 +
  98 + //出站既出场
  99 + outStationAndOutPark(sch);
  100 +
  101 + //webSocket
  102 + sendUtils.sendFcsj(sch);
  103 +
  104 + //持久化
  105 + dayOfSchedule.save(sch);
  106 +
  107 + //清理应发未发标记
  108 + LateAdjustHandle.remove(sch.getClZbh());
  109 +
  110 + //发车的时候,同步一下状态
  111 + if(!gps.isService() && !dayOfSchedule.emptyService(sch))
  112 + gpsStatusManager.changeServiceState(sch.getClZbh(), sch.getXlDir(), 0, "发车@系统");
  113 +
  114 + logger.info("车辆:" + sch.getClZbh() + " 班次:" + sch.getDfsj() + "发车, 时间:" + sch.getFcsjActual());
  115 + }
  116 +
  117 + GpsCacheData.out(gps);
  118 + }
  119 +
  120 + /**
  121 + * 是否是一个更合适的发车信号
  122 + * @param gps
  123 + * @param sch
  124 + * @return
  125 + */
  126 + private boolean outManyFit(GpsEntity gps, ScheduleRealInfo sch) {
  127 + LineConfig conf = lineConfigData.get(sch.getXlBm());
  128 + if(null != conf && conf.isLockFirstOutTime())
  129 + return false;
  130 +
  131 + if(StringUtils.isNotEmpty(sch.getZdsjActual()))
  132 + return false;
  133 +
  134 + long t1 = sch.getFcsjActualTime();
  135 + long t2 = gps.getTimestamp();
  136 + long c = sch.getDfsjT();
  137 +
  138 + int threshold = 1000 * 60 * 5;
  139 + if(Math.abs(t2 - c) < threshold && c - t1 > threshold){
  140 + return true;
  141 + }
  142 +
  143 + if(c - t1 > 1000 * 60 * 60 * 2 && Math.abs(t2 - c) < c - t1){
  144 + return true;
  145 + }
  146 + return false;
  147 + }
  148 +
  149 + private void outStationAndOutPark(ScheduleRealInfo sch){
  150 + try{
  151 + LineConfig config = lineConfigData.get(sch.getXlBm());
  152 + //限定出站既出场的停车场
  153 + String park = config.getTwinsPark();
  154 + boolean limitPark = StringUtils.isNotEmpty(park);
  155 +
  156 + if (config != null && config.getOutConfig() == 2) {
  157 + //出站既出场
  158 + ScheduleRealInfo schPrev = dayOfSchedule.prev(sch);
  159 + if (isOut(schPrev) && isEmptyMileage(schPrev)
  160 + && (!limitPark || park.equals(schPrev.getQdzCode()))) {
  161 +
  162 + endSch(schPrev, sch.getFcsjActualTime());
  163 +
  164 + //起点实到
  165 + sch.setQdzArrDatesj(schPrev.getZdsjActual());
  166 +
  167 + sendUtils.refreshSch(schPrev);
  168 + dayOfSchedule.save(schPrev);
  169 + }
  170 + }
  171 + }catch (Exception e){
  172 + logger.error("", e);
  173 + }
  174 + }
  175 +
  176 + private boolean isEmptyMileage(ScheduleRealInfo sch){
  177 + return sch.getBcsj()==0 || sch.getJhlcOrig().intValue()==0;
  178 + }
  179 +
  180 + private boolean isOut(ScheduleRealInfo sch){
  181 + return sch != null && sch.getBcType().equals("out");
  182 + }
  183 +
  184 + private void endSch(ScheduleRealInfo sch, Long t){
  185 + sch.setFcsjActualAll(t);
  186 + sch.setZdsjActualAll(t);
  187 + }
  188 +
  189 + private boolean isOutPark(GpsEntity gps, GpsEntity prve){
  190 + if(StringUtils.isNotEmpty(prve.getCarparkNo()) && StringUtils.isEmpty(gps.getCarparkNo()))
  191 + return true;
  192 + return false;
  193 + }
194 194 }
195 195 \ No newline at end of file
... ...
src/main/java/com/bsth/data/gpsdata_v2/rfid/UploadRfidDataService.java
1   -package com.bsth.data.gpsdata_v2.rfid;
2   -
3   -import com.alibaba.fastjson.JSON;
4   -import com.bsth.data.gpsdata_v2.rfid.entity.RfidInoutStation;
5   -import com.bsth.data.gpsdata_v2.rfid.handle.RfidSignalHandle;
6   -import org.slf4j.Logger;
7   -import org.slf4j.LoggerFactory;
8   -import org.springframework.beans.factory.annotation.Autowired;
9   -import org.springframework.web.bind.annotation.RequestBody;
10   -import org.springframework.web.bind.annotation.RequestMapping;
11   -import org.springframework.web.bind.annotation.RequestMethod;
12   -import org.springframework.web.bind.annotation.RestController;
13   -
14   -import java.util.List;
15   -
16   -/**
17   - * RFID 数据上传入口
18   - * Created by panzhao on 2017/11/22.
19   - */
20   -@RestController
21   -@RequestMapping("/rfid")
22   -public class UploadRfidDataService {
23   -
24   - @Autowired
25   - RfidSignalHandle rfidSignalHandle;
26   -
27   - Logger logger = LoggerFactory.getLogger(this.getClass());
28   -
29   - @RequestMapping(value = "inside", method = RequestMethod.POST)
30   - public void inside(@RequestBody List<RfidInoutStation> list) {
31   - logger.info("up rfid: " + JSON.toJSONString(list));
32   - rfidSignalHandle.handle(list);
33   - }
34   -
35   - @RequestMapping(value = "test")
36   - public int test() {
37   - return 1;
38   - }
  1 +package com.bsth.data.gpsdata_v2.rfid;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.bsth.data.gpsdata_v2.rfid.entity.RfidInoutStation;
  5 +import com.bsth.data.gpsdata_v2.rfid.handle.RfidSignalHandle;
  6 +import org.slf4j.Logger;
  7 +import org.slf4j.LoggerFactory;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.web.bind.annotation.RequestBody;
  10 +import org.springframework.web.bind.annotation.RequestMapping;
  11 +import org.springframework.web.bind.annotation.RequestMethod;
  12 +import org.springframework.web.bind.annotation.RestController;
  13 +
  14 +import java.util.List;
  15 +
  16 +/**
  17 + * RFID 数据上传入口
  18 + * Created by panzhao on 2017/11/22.
  19 + */
  20 +@RestController
  21 +@RequestMapping("/rfid")
  22 +public class UploadRfidDataService {
  23 +
  24 + @Autowired
  25 + RfidSignalHandle rfidSignalHandle;
  26 +
  27 + Logger logger = LoggerFactory.getLogger(this.getClass());
  28 +
  29 + @RequestMapping(value = "inside", method = RequestMethod.POST)
  30 + public void inside(@RequestBody List<RfidInoutStation> list) {
  31 + logger.info("up rfid: " + JSON.toJSONString(list));
  32 + rfidSignalHandle.handle(list);
  33 + }
  34 +
  35 + @RequestMapping(value = "test")
  36 + public int test() {
  37 + return 1;
  38 + }
39 39 }
40 40 \ No newline at end of file
... ...
src/main/java/com/bsth/data/gpsdata_v2/rfid/handle/RfidSignalHandle.java
1   -package com.bsth.data.gpsdata_v2.rfid.handle;
2   -
3   -import com.bsth.data.gpsdata_v2.rfid.entity.RfidInoutStation;
4   -import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;
5   -import com.bsth.data.msg_queue.DirectivePushQueue;
6   -import com.bsth.data.schedule.DayOfSchedule;
7   -import com.bsth.entity.realcontrol.ScheduleRealInfo;
8   -import com.bsth.websocket.handler.SendUtils;
9   -import org.apache.commons.lang3.StringUtils;
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 java.util.List;
16   -
17   -/**
18   - * RFID信号处理
19   - * Created by panzhao on 2017/11/22.
20   - */
21   -@Component
22   -public class RfidSignalHandle {
23   -
24   - @Autowired
25   - DayOfSchedule dayOfSchedule;
26   -
27   - @Autowired
28   - SendUtils sendUtils;
29   -
30   - @Autowired
31   - GpsStatusManager gpsStatusManager;
32   -
33   - private final static int MAX_TIME_DIFF = 1000 * 60 * 60 * 2;
34   -
35   - Logger logger = LoggerFactory.getLogger(this.getClass());
36   -
37   - public void handle(List<RfidInoutStation> list){
38   - for(RfidInoutStation signal : list){
39   - if(signal.getType()==2)
40   - in(signal);
41   - else if(signal.getType()==4)
42   - out(signal);
43   - }
44   - }
45   -
46   - /**
47   - * 出
48   - * @param signal
49   - */
50   - private void out(RfidInoutStation signal) {
51   - try{
52   - String nbbm = signal.getNbbm();
53   - ScheduleRealInfo sch = dayOfSchedule.executeCurr(nbbm);
54   -
55   - if(null == sch)
56   - return;
57   -
58   - //最大时间差
59   - if(Math.abs(sch.getDfsjT() - signal.getT()) > MAX_TIME_DIFF)
60   - return;
61   -
62   - if(sch.getQdzCode().equals(signal.getStation())
63   - && StringUtils.isEmpty(sch.getFcsjActual())){
64   -
65   - //班次发车
66   - sch.setFcsjActualAll(signal.getT());
67   -
68   - //webSocket
69   - sendUtils.sendFcsj(sch);
70   -
71   - //持久化
72   - dayOfSchedule.save(sch);
73   -
74   - logger.info("RFID; 车辆:" + sch.getClZbh() + " 班次:" + sch.getDfsj() + "发车, 时间:" + sch.getFcsjActual());
75   - }
76   - }catch (Exception e){
77   - logger.error("", e);
78   - }
79   - }
80   -
81   - /**
82   - * 进
83   - * @param signal
84   - */
85   - private void in(RfidInoutStation signal) {
86   - try{
87   - String nbbm = signal.getNbbm();
88   - ScheduleRealInfo sch = dayOfSchedule.executeCurr(nbbm);
89   -
90   - if(null == sch)
91   - return;
92   -
93   - //最大时间差
94   - if(Math.abs(sch.getDfsjT() - signal.getT()) > MAX_TIME_DIFF)
95   - return;
96   -
97   - if(sch.getZdzCode().equals(signal.getStation())
98   - && StringUtils.isEmpty(sch.getZdsjActual())){
99   -
100   - sch.setZdsjActualAll(signal.getT());
101   -
102   - //持久化
103   - dayOfSchedule.save(sch);
104   -
105   - //车辆的下一个班次
106   - ScheduleRealInfo next = dayOfSchedule.next(sch);
107   - if(next != null){
108   - dayOfSchedule.addExecPlan(next);
109   - }
110   -
111   - //路牌的下一个班次,页面显示起点实际到达时间
112   - ScheduleRealInfo lpNext = dayOfSchedule.nextByLp(sch);
113   - if(lpNext != null){
114   - lpNext.setQdzArrDatesj(sch.getZdsjActual());
115   - }
116   -
117   - //已完成班次数
118   - int doneSum = dayOfSchedule.doneSum(nbbm);
119   -
120   - //webSocket
121   - sendUtils.sendZdsj(sch, lpNext, doneSum);
122   -
123   - logger.info("RFID; 车辆:" + nbbm + " 班次:" + sch.getDfsj() + "到终点, 时间:" + sch.getZdsjActual());
124   -
125   - //下发调度指令
126   - DirectivePushQueue.put6002(next, doneSum, "rfid@系统");
127   -
128   - //套跑 -下发线路切换指令
129   - if(null != next && !next.getXlBm().equals(sch.getXlBm())){
130   - gpsStatusManager.changeLine(next.getClZbh(), next.getXlBm(), "rfid@系统");
131   - }
132   -
133   - if(null == next)
134   - nonService(sch, "rfid1@系统");//班次结束
135   - else if(null != next && dayOfSchedule.emptyService(next))
136   - nonService(sch, "rfid2@系统");//下一班非营运
137   - }
138   - }catch (Exception e){
139   - logger.error("", e);
140   - }
141   - }
142   -
143   - /**
144   - * 将车载设备切换为非营运状态
145   - * @param sch
146   - * @param sender
147   - */
148   - private void nonService(ScheduleRealInfo sch, String sender){
149   - gpsStatusManager.changeServiceState(sch.getClZbh(), sch.getXlDir(), 1, sender);
150   - }
  1 +package com.bsth.data.gpsdata_v2.rfid.handle;
  2 +
  3 +import com.bsth.data.gpsdata_v2.rfid.entity.RfidInoutStation;
  4 +import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;
  5 +import com.bsth.data.msg_queue.DirectivePushQueue;
  6 +import com.bsth.data.schedule.DayOfSchedule;
  7 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  8 +import com.bsth.websocket.handler.SendUtils;
  9 +import org.apache.commons.lang3.StringUtils;
  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 java.util.List;
  16 +
  17 +/**
  18 + * RFID信号处理
  19 + * Created by panzhao on 2017/11/22.
  20 + */
  21 +@Component
  22 +public class RfidSignalHandle {
  23 +
  24 + @Autowired
  25 + DayOfSchedule dayOfSchedule;
  26 +
  27 + @Autowired
  28 + SendUtils sendUtils;
  29 +
  30 + @Autowired
  31 + GpsStatusManager gpsStatusManager;
  32 +
  33 + private final static int MAX_TIME_DIFF = 1000 * 60 * 60 * 2;
  34 +
  35 + Logger logger = LoggerFactory.getLogger(this.getClass());
  36 +
  37 + public void handle(List<RfidInoutStation> list){
  38 + for(RfidInoutStation signal : list){
  39 + if(signal.getType()==2)
  40 + in(signal);
  41 + else if(signal.getType()==4)
  42 + out(signal);
  43 + }
  44 + }
  45 +
  46 + /**
  47 + * 出
  48 + * @param signal
  49 + */
  50 + private void out(RfidInoutStation signal) {
  51 + try{
  52 + String nbbm = signal.getNbbm();
  53 + ScheduleRealInfo sch = dayOfSchedule.executeCurr(nbbm);
  54 +
  55 + if(null == sch)
  56 + return;
  57 +
  58 + //最大时间差
  59 + if(Math.abs(sch.getDfsjT() - signal.getT()) > MAX_TIME_DIFF)
  60 + return;
  61 +
  62 + if(sch.getQdzCode().equals(signal.getStation())
  63 + && StringUtils.isEmpty(sch.getFcsjActual())){
  64 +
  65 + //班次发车
  66 + sch.setFcsjActualAll(signal.getT());
  67 +
  68 + //webSocket
  69 + sendUtils.sendFcsj(sch);
  70 +
  71 + //持久化
  72 + dayOfSchedule.save(sch);
  73 +
  74 + logger.info("RFID; 车辆:" + sch.getClZbh() + " 班次:" + sch.getDfsj() + "发车, 时间:" + sch.getFcsjActual());
  75 + }
  76 + }catch (Exception e){
  77 + logger.error("", e);
  78 + }
  79 + }
  80 +
  81 + /**
  82 + * 进
  83 + * @param signal
  84 + */
  85 + private void in(RfidInoutStation signal) {
  86 + try{
  87 + String nbbm = signal.getNbbm();
  88 + ScheduleRealInfo sch = dayOfSchedule.executeCurr(nbbm);
  89 +
  90 + if(null == sch)
  91 + return;
  92 +
  93 + //最大时间差
  94 + if(Math.abs(sch.getDfsjT() - signal.getT()) > MAX_TIME_DIFF)
  95 + return;
  96 +
  97 + if(sch.getZdzCode().equals(signal.getStation())
  98 + && StringUtils.isEmpty(sch.getZdsjActual())){
  99 +
  100 + sch.setZdsjActualAll(signal.getT());
  101 +
  102 + //持久化
  103 + dayOfSchedule.save(sch);
  104 +
  105 + //车辆的下一个班次
  106 + ScheduleRealInfo next = dayOfSchedule.next(sch);
  107 + if(next != null){
  108 + dayOfSchedule.addExecPlan(next);
  109 + }
  110 +
  111 + //路牌的下一个班次,页面显示起点实际到达时间
  112 + ScheduleRealInfo lpNext = dayOfSchedule.nextByLp(sch);
  113 + if(lpNext != null){
  114 + lpNext.setQdzArrDatesj(sch.getZdsjActual());
  115 + }
  116 +
  117 + //已完成班次数
  118 + int doneSum = dayOfSchedule.doneSum(nbbm);
  119 +
  120 + //webSocket
  121 + sendUtils.sendZdsj(sch, lpNext, doneSum);
  122 +
  123 + logger.info("RFID; 车辆:" + nbbm + " 班次:" + sch.getDfsj() + "到终点, 时间:" + sch.getZdsjActual());
  124 +
  125 + //下发调度指令
  126 + DirectivePushQueue.put6002(next, doneSum, "rfid@系统");
  127 +
  128 + //套跑 -下发线路切换指令
  129 + if(null != next && !next.getXlBm().equals(sch.getXlBm())){
  130 + gpsStatusManager.changeLine(next.getClZbh(), next.getXlBm(), "rfid@系统");
  131 + }
  132 +
  133 + if(null == next)
  134 + nonService(sch, "rfid1@系统");//班次结束
  135 + else if(null != next && dayOfSchedule.emptyService(next))
  136 + nonService(sch, "rfid2@系统");//下一班非营运
  137 + }
  138 + }catch (Exception e){
  139 + logger.error("", e);
  140 + }
  141 + }
  142 +
  143 + /**
  144 + * 将车载设备切换为非营运状态
  145 + * @param sch
  146 + * @param sender
  147 + */
  148 + private void nonService(ScheduleRealInfo sch, String sender){
  149 + gpsStatusManager.changeServiceState(sch.getClZbh(), sch.getXlDir(), 1, sender);
  150 + }
151 151 }
152 152 \ No newline at end of file
... ...
src/main/java/com/bsth/data/gpsdata_v2/thread/OfflineMonitorThread.java
1   -package com.bsth.data.gpsdata_v2.thread;
2   -
3   -import com.bsth.data.gpsdata_v2.GpsRealData;
4   -import com.bsth.data.gpsdata_v2.entity.GpsEntity;
5   -import com.bsth.websocket.handler.SendUtils;
6   -import org.slf4j.Logger;
7   -import org.slf4j.LoggerFactory;
8   -import org.springframework.beans.factory.annotation.Autowired;
9   -import org.springframework.stereotype.Component;
10   -
11   -import java.util.Collection;
12   -
13   -/**
14   - * GPS掉离线监控
15   - * Created by panzhao on 2017/1/11.
16   - */
17   -@Component
18   -public class OfflineMonitorThread extends Thread{
19   -
20   - @Autowired
21   - GpsRealData gpsRealData;
22   -
23   - //掉线阈值
24   - private final static int LOSE_TIME = 1000 * 60 * 10;
25   -
26   - Logger logger = LoggerFactory.getLogger(this.getClass());
27   -
28   - @Autowired
29   - SendUtils sendUtils;
30   -
31   - //无任务时 离线阈值
32   - //private final static int OFFLINE_TIME = 1000 * 60 * 10;
33   -
34   - @Override
35   - public void run() {
36   - try{
37   - long t = System.currentTimeMillis();
38   - Collection<GpsEntity> list = gpsRealData.all();
39   -
40   - String state;
41   - for(GpsEntity gps : list){
42   - state = gps.getAbnormalStatus();
43   -
44   - if(state != null && state.equals("offline"))
45   - continue;
46   -
47   - if (t - gps.getTimestamp() > LOSE_TIME){
48   - gps.offline();
49   -
50   - //通知页面有设备掉线
51   - sendUtils.deviceOffline(gps);
52   - }
53   - }
54   - }catch (Exception e){
55   - logger.error("", e);
56   - }
57   - }
58   -}
  1 +package com.bsth.data.gpsdata_v2.thread;
  2 +
  3 +import com.bsth.data.gpsdata_v2.GpsRealData;
  4 +import com.bsth.data.gpsdata_v2.entity.GpsEntity;
  5 +import com.bsth.websocket.handler.SendUtils;
  6 +import org.slf4j.Logger;
  7 +import org.slf4j.LoggerFactory;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.stereotype.Component;
  10 +
  11 +import java.util.Collection;
  12 +
  13 +/**
  14 + * GPS掉离线监控
  15 + * Created by panzhao on 2017/1/11.
  16 + */
  17 +@Component
  18 +public class OfflineMonitorThread extends Thread{
  19 +
  20 + @Autowired
  21 + GpsRealData gpsRealData;
  22 +
  23 + //掉线阈值
  24 + private final static int LOSE_TIME = 1000 * 60 * 10;
  25 +
  26 + Logger logger = LoggerFactory.getLogger(this.getClass());
  27 +
  28 + @Autowired
  29 + SendUtils sendUtils;
  30 +
  31 + //无任务时 离线阈值
  32 + //private final static int OFFLINE_TIME = 1000 * 60 * 10;
  33 +
  34 + @Override
  35 + public void run() {
  36 + try{
  37 + long t = System.currentTimeMillis();
  38 + Collection<GpsEntity> list = gpsRealData.all();
  39 +
  40 + String state;
  41 + for(GpsEntity gps : list){
  42 + state = gps.getAbnormalStatus();
  43 +
  44 + if(state != null && state.equals("offline"))
  45 + continue;
  46 +
  47 + if (t - gps.getTimestamp() > LOSE_TIME){
  48 + gps.offline();
  49 +
  50 + //通知页面有设备掉线
  51 + sendUtils.deviceOffline(gps);
  52 + }
  53 + }
  54 + }catch (Exception e){
  55 + logger.error("", e);
  56 + }
  57 + }
  58 +}
... ...
src/main/java/com/bsth/data/gpsdata_v2/utils/GpsDataRecovery.java
1   -package com.bsth.data.gpsdata_v2.utils;
2   -
3   -import com.bsth.data.BasicData;
4   -import com.bsth.data.gpsdata_v2.cache.GpsCacheData;
5   -import com.bsth.data.gpsdata_v2.entity.GpsEntity;
6   -import com.bsth.data.gpsdata_v2.handlers.*;
7   -import com.bsth.util.db.DBUtils_MS;
8   -import com.google.common.collect.ArrayListMultimap;
9   -import org.slf4j.Logger;
10   -import org.slf4j.LoggerFactory;
11   -import org.springframework.beans.BeansException;
12   -import org.springframework.context.ApplicationContext;
13   -import org.springframework.context.ApplicationContextAware;
14   -import org.springframework.jdbc.core.JdbcTemplate;
15   -import org.springframework.jdbc.core.RowMapper;
16   -import org.springframework.stereotype.Component;
17   -
18   -import java.sql.ResultSet;
19   -import java.sql.SQLException;
20   -import java.util.*;
21   -import java.util.concurrent.CountDownLatch;
22   -import java.util.concurrent.ExecutorService;
23   -import java.util.concurrent.Executors;
24   -
25   -/**
26   - * gps数据恢复
27   - * Created by panzhao on 2016/12/24.
28   - */
29   -@Component
30   -public class GpsDataRecovery implements ApplicationContextAware {
31   -
32   - static Logger logger = LoggerFactory.getLogger(GpsDataRecovery.class);
33   -
34   - public static boolean run;
35   -
36   - static ExecutorService threadPool = Executors.newFixedThreadPool(10);
37   -
38   - static GpsStateProcess gpsStateProcess;
39   - static StationInsideProcess stationInsideProcess;
40   - static InStationProcess inStationProcess;
41   - static OutStationProcess outStationProcess;
42   - static AbnormalStateProcess abnormalStateProcess;
43   - static ReverseRouteProcess reverseRouteProcess;
44   -
45   - public void recovery() {
46   - List<GpsEntity> list = loadData();
47   -
48   - //按线路分组数据
49   - ArrayListMultimap<String, GpsEntity> listMap = ArrayListMultimap.create();
50   - for (GpsEntity gps : list) {
51   - if (gps.getNbbm() != null)
52   - listMap.put(gps.getNbbm(), gps);
53   - }
54   -
55   -
56   - Set<String> keys = listMap.keySet();
57   -
58   - CountDownLatch count = new CountDownLatch(keys.size());
59   - GpsComp comp = new GpsComp();
60   - for (String nbbm : keys) {
61   - Collections.sort(listMap.get(nbbm), comp);
62   - threadPool.submit(new RecoveryThread(listMap.get(nbbm), count));
63   - /*if(nbbm.equals("W7C-035"))
64   - new RecoveryThread(listMap.get(nbbm), count).run();*/
65   - /*if(lineId.equals("60028"))
66   - new RecoveryThread(listMap.get(lineId), count).run();*/
67   - }
68   -
69   - try {
70   - count.await();
71   - run = false;
72   - logger.info("数据恢复完成....");
73   - } catch (InterruptedException e) {
74   - logger.error("", e);
75   - }
76   - }
77   -
78   - /**
79   - * 加载当天的gps数据
80   - *
81   - * @return
82   - */
83   - public List<GpsEntity> loadData() {
84   - Calendar calendar = Calendar.getInstance();
85   - int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
86   -
87   - String sql = "select DEVICE_ID,LAT,LON,TS,SPEED_GPS,LINE_ID,SERVICE_STATE,SERVER_TS from bsth_c_gps_info where days_year=327"; //+ dayOfYear;
88   - JdbcTemplate jdbcTemplate = new JdbcTemplate(DBUtils_MS.getDataSource());
89   -
90   - List<GpsEntity> list =
91   - jdbcTemplate.query(sql, new RowMapper<GpsEntity>() {
92   - @Override
93   - public GpsEntity mapRow(ResultSet rs, int rowNum) throws SQLException {
94   - GpsEntity gps = new GpsEntity();
95   -
96   - gps.setDeviceId(rs.getString("DEVICE_ID"));
97   - gps.setNbbm(BasicData.deviceId2NbbmMap.get(gps.getDeviceId()));
98   - gps.setSpeed(rs.getFloat("SPEED_GPS"));
99   - gps.setLat(rs.getFloat("LAT"));
100   - gps.setLon(rs.getFloat("LON"));
101   - gps.setLineId(rs.getString("LINE_ID"));
102   - gps.setTimestamp(rs.getLong("TS"));
103   - gps.setUpDown((byte) getUpOrDown(rs.getLong("SERVICE_STATE")));
104   - gps.setServerTimestamp(rs.getLong("SERVER_TS"));
105   - return gps;
106   - }
107   - });
108   - return list;
109   - }
110   -
111   - /**
112   - * 王通 2016/6/29 9:23:24 获取车辆线路上下行
113   - *
114   - * @return -1无效 0上行 1下行
115   - */
116   - public static int getUpOrDown(long serviceState) {
117   - if ((serviceState & 0x00020000) == 0x00020000 || (serviceState & 0x80000000) == 0x80000000
118   - || (serviceState & 0x01000000) == 0x01000000 || (serviceState & 0x08000000) == 0x08000000)
119   - return -1;
120   - return (((serviceState & 0x10000000) == 0x10000000) ? 1 : 0);
121   - }
122   -
123   - @Override
124   - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
125   - gpsStateProcess = applicationContext.getBean(GpsStateProcess.class);
126   - stationInsideProcess = applicationContext.getBean(StationInsideProcess.class);
127   - inStationProcess = applicationContext.getBean(InStationProcess.class);
128   - outStationProcess = applicationContext.getBean(OutStationProcess.class);
129   - abnormalStateProcess = applicationContext.getBean(AbnormalStateProcess.class);
130   - reverseRouteProcess = applicationContext.getBean(ReverseRouteProcess.class);
131   - }
132   -
133   - public static class GpsComp implements Comparator<GpsEntity> {
134   -
135   - @Override
136   - public int compare(GpsEntity g1, GpsEntity g2) {
137   - return g1.getTimestamp().compareTo(g2.getTimestamp());
138   - }
139   - }
140   -
141   - public static class RecoveryThread implements Runnable {
142   - List<GpsEntity> list;
143   - CountDownLatch count;
144   -
145   - RecoveryThread(List<GpsEntity> list, CountDownLatch count) {
146   - this.list = list;
147   - this.count = count;
148   - }
149   -
150   - @Override
151   - public void run() {
152   - try {
153   - //循环gps恢复数据
154   - for (GpsEntity gps : list) {
155   - try {
156   -
157   - /*if(gps.getTimestamp() >= 1511396220000L)
158   - System.out.println("aaa");*/
159   -
160   - if(Math.abs(gps.getTimestamp() - gps.getServerTimestamp()) > 1000 * 60 * 20)
161   - continue;
162   -
163   - gpsStateProcess.process(gps);//状态处理
164   - stationInsideProcess.process(gps);//场站内外判定
165   - reverseRouteProcess.process(gps);//反向路由处理
166   -
167   - abnormalStateProcess.process(gps);//超速越界
168   -
169   - inStationProcess.process(gps);//进站
170   - outStationProcess.process(gps);//出站
171   -
172   - GpsCacheData.putGps(gps);//历史gps缓存
173   - } catch (Exception e) {
174   - logger.error("", e);
175   - }
176   - }
177   - } finally {
178   - count.countDown();
179   - }
180   - }
181   - }
  1 +package com.bsth.data.gpsdata_v2.utils;
  2 +
  3 +import com.bsth.data.BasicData;
  4 +import com.bsth.data.gpsdata_v2.cache.GpsCacheData;
  5 +import com.bsth.data.gpsdata_v2.entity.GpsEntity;
  6 +import com.bsth.data.gpsdata_v2.handlers.*;
  7 +import com.bsth.util.db.DBUtils_MS;
  8 +import com.google.common.collect.ArrayListMultimap;
  9 +import org.slf4j.Logger;
  10 +import org.slf4j.LoggerFactory;
  11 +import org.springframework.beans.BeansException;
  12 +import org.springframework.context.ApplicationContext;
  13 +import org.springframework.context.ApplicationContextAware;
  14 +import org.springframework.jdbc.core.JdbcTemplate;
  15 +import org.springframework.jdbc.core.RowMapper;
  16 +import org.springframework.stereotype.Component;
  17 +
  18 +import java.sql.ResultSet;
  19 +import java.sql.SQLException;
  20 +import java.util.*;
  21 +import java.util.concurrent.CountDownLatch;
  22 +import java.util.concurrent.ExecutorService;
  23 +import java.util.concurrent.Executors;
  24 +
  25 +/**
  26 + * gps数据恢复
  27 + * Created by panzhao on 2016/12/24.
  28 + */
  29 +@Component
  30 +public class GpsDataRecovery implements ApplicationContextAware {
  31 +
  32 + static Logger logger = LoggerFactory.getLogger(GpsDataRecovery.class);
  33 +
  34 + public static boolean run;
  35 +
  36 + static ExecutorService threadPool = Executors.newFixedThreadPool(10);
  37 +
  38 + static GpsStateProcess gpsStateProcess;
  39 + static StationInsideProcess stationInsideProcess;
  40 + static InStationProcess inStationProcess;
  41 + static OutStationProcess outStationProcess;
  42 + static AbnormalStateProcess abnormalStateProcess;
  43 + static ReverseRouteProcess reverseRouteProcess;
  44 +
  45 + public void recovery() {
  46 + List<GpsEntity> list = loadData();
  47 +
  48 + //按线路分组数据
  49 + ArrayListMultimap<String, GpsEntity> listMap = ArrayListMultimap.create();
  50 + for (GpsEntity gps : list) {
  51 + if (gps.getNbbm() != null)
  52 + listMap.put(gps.getNbbm(), gps);
  53 + }
  54 +
  55 +
  56 + Set<String> keys = listMap.keySet();
  57 +
  58 + CountDownLatch count = new CountDownLatch(keys.size());
  59 + GpsComp comp = new GpsComp();
  60 + for (String nbbm : keys) {
  61 + Collections.sort(listMap.get(nbbm), comp);
  62 + threadPool.submit(new RecoveryThread(listMap.get(nbbm), count));
  63 + /*if(nbbm.equals("W7C-035"))
  64 + new RecoveryThread(listMap.get(nbbm), count).run();*/
  65 + /*if(lineId.equals("60028"))
  66 + new RecoveryThread(listMap.get(lineId), count).run();*/
  67 + }
  68 +
  69 + try {
  70 + count.await();
  71 + run = false;
  72 + logger.info("数据恢复完成....");
  73 + } catch (InterruptedException e) {
  74 + logger.error("", e);
  75 + }
  76 + }
  77 +
  78 + /**
  79 + * 加载当天的gps数据
  80 + *
  81 + * @return
  82 + */
  83 + public List<GpsEntity> loadData() {
  84 + Calendar calendar = Calendar.getInstance();
  85 + int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
  86 +
  87 + String sql = "select DEVICE_ID,LAT,LON,TS,SPEED_GPS,LINE_ID,SERVICE_STATE,SERVER_TS from bsth_c_gps_info where days_year=327"; //+ dayOfYear;
  88 + JdbcTemplate jdbcTemplate = new JdbcTemplate(DBUtils_MS.getDataSource());
  89 +
  90 + List<GpsEntity> list =
  91 + jdbcTemplate.query(sql, new RowMapper<GpsEntity>() {
  92 + @Override
  93 + public GpsEntity mapRow(ResultSet rs, int rowNum) throws SQLException {
  94 + GpsEntity gps = new GpsEntity();
  95 +
  96 + gps.setDeviceId(rs.getString("DEVICE_ID"));
  97 + gps.setNbbm(BasicData.deviceId2NbbmMap.get(gps.getDeviceId()));
  98 + gps.setSpeed(rs.getFloat("SPEED_GPS"));
  99 + gps.setLat(rs.getFloat("LAT"));
  100 + gps.setLon(rs.getFloat("LON"));
  101 + gps.setLineId(rs.getString("LINE_ID"));
  102 + gps.setTimestamp(rs.getLong("TS"));
  103 + gps.setUpDown((byte) getUpOrDown(rs.getLong("SERVICE_STATE")));
  104 + gps.setServerTimestamp(rs.getLong("SERVER_TS"));
  105 + return gps;
  106 + }
  107 + });
  108 + return list;
  109 + }
  110 +
  111 + /**
  112 + * 王通 2016/6/29 9:23:24 获取车辆线路上下行
  113 + *
  114 + * @return -1无效 0上行 1下行
  115 + */
  116 + public static int getUpOrDown(long serviceState) {
  117 + if ((serviceState & 0x00020000) == 0x00020000 || (serviceState & 0x80000000) == 0x80000000
  118 + || (serviceState & 0x01000000) == 0x01000000 || (serviceState & 0x08000000) == 0x08000000)
  119 + return -1;
  120 + return (((serviceState & 0x10000000) == 0x10000000) ? 1 : 0);
  121 + }
  122 +
  123 + @Override
  124 + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  125 + gpsStateProcess = applicationContext.getBean(GpsStateProcess.class);
  126 + stationInsideProcess = applicationContext.getBean(StationInsideProcess.class);
  127 + inStationProcess = applicationContext.getBean(InStationProcess.class);
  128 + outStationProcess = applicationContext.getBean(OutStationProcess.class);
  129 + abnormalStateProcess = applicationContext.getBean(AbnormalStateProcess.class);
  130 + reverseRouteProcess = applicationContext.getBean(ReverseRouteProcess.class);
  131 + }
  132 +
  133 + public static class GpsComp implements Comparator<GpsEntity> {
  134 +
  135 + @Override
  136 + public int compare(GpsEntity g1, GpsEntity g2) {
  137 + return g1.getTimestamp().compareTo(g2.getTimestamp());
  138 + }
  139 + }
  140 +
  141 + public static class RecoveryThread implements Runnable {
  142 + List<GpsEntity> list;
  143 + CountDownLatch count;
  144 +
  145 + RecoveryThread(List<GpsEntity> list, CountDownLatch count) {
  146 + this.list = list;
  147 + this.count = count;
  148 + }
  149 +
  150 + @Override
  151 + public void run() {
  152 + try {
  153 + //循环gps恢复数据
  154 + for (GpsEntity gps : list) {
  155 + try {
  156 +
  157 + /*if(gps.getTimestamp() >= 1511396220000L)
  158 + System.out.println("aaa");*/
  159 +
  160 + if(Math.abs(gps.getTimestamp() - gps.getServerTimestamp()) > 1000 * 60 * 20)
  161 + continue;
  162 +
  163 + gpsStateProcess.process(gps);//状态处理
  164 + stationInsideProcess.process(gps);//场站内外判定
  165 + reverseRouteProcess.process(gps);//反向路由处理
  166 +
  167 + abnormalStateProcess.process(gps);//超速越界
  168 +
  169 + inStationProcess.process(gps);//进站
  170 + outStationProcess.process(gps);//出站
  171 +
  172 + GpsCacheData.putGps(gps);//历史gps缓存
  173 + } catch (Exception e) {
  174 + logger.error("", e);
  175 + }
  176 + }
  177 + } finally {
  178 + count.countDown();
  179 + }
  180 + }
  181 + }
182 182 }
183 183 \ No newline at end of file
... ...
src/main/java/com/bsth/data/gpsdata_v2/utils/SignalSchPlanMatcher.java
1   -package com.bsth.data.gpsdata_v2.utils;
2   -
3   -import com.bsth.data.gpsdata_v2.entity.GpsEntity;
4   -import com.bsth.data.schedule.DayOfSchedule;
5   -import com.bsth.data.schedule.ScheduleComparator;
6   -import com.bsth.entity.realcontrol.ScheduleRealInfo;
7   -import org.apache.commons.lang3.StringUtils;
8   -import org.slf4j.Logger;
9   -import org.slf4j.LoggerFactory;
10   -import org.springframework.beans.factory.annotation.Autowired;
11   -import org.springframework.stereotype.Component;
12   -
13   -import java.util.Collections;
14   -import java.util.List;
15   -
16   -/**
17   - * 班次匹配器
18   - * Created by panzhao on 2016/12/31.
19   - */
20   -@Component
21   -public class SignalSchPlanMatcher {
22   -
23   - @Autowired
24   - DayOfSchedule dayOfSchedule;
25   -
26   - static ScheduleComparator.DFSJ schComp = new ScheduleComparator.DFSJ();
27   -
28   - Logger log = LoggerFactory.getLogger(this.getClass());
29   -
30   - /**
31   - * 发车信号匹配
32   - * @param gps
33   - * @param sch
34   - * @return
35   - */
36   - public boolean outMatch(GpsEntity gps, ScheduleRealInfo sch){
37   - long t = gps.getTimestamp();
38   - if(t < sch.getDfsjT())
39   - return true;
40   -
41   - try{
42   - //晚于待发时间 10 分钟 ,匹配一下最佳的班次
43   - if(t - sch.getDfsjT() > 1000 * 60 * 10){
44   - ScheduleRealInfo near = searchNearOut(gps);
45   -
46   - if(null != near && !near.getId().equals(sch.getId())){
47   - dayOfSchedule.addExecPlan(near);
48   - return false;
49   - }
50   - }
51   -
52   - }catch (Exception e){
53   - log.error("", e);
54   - }
55   - return true;
56   - /*try{
57   - //会不会是分班没有完成
58   - if(sch.getBcType().equals("in") && t - sch.getDfsjT() > 1000 * 60 * 20){
59   - ScheduleRealInfo fbFirst = dayOfSchedule.nextByBcType(sch, "normal");
60   -
61   - if(fbFirst == null || !fbFirst.getQdzCode().equals(gps.getStopNo()))
62   - return;
63   -
64   - long dt = fbFirst.getDfsjT();
65   - //晚于待发前4分钟 -执行分班的首个营运
66   - if(dt - t < 1000 * 60 * 4){
67   - dayOfSchedule.addExecPlan(fbFirst);
68   - return;
69   - }
70   - }
71   -
72   - //线路编码不匹配
73   - if("out".equals(sch.getBcType()) && !sch.getXlBm().equals(gps.getLineId())){
74   - ScheduleRealInfo nextOut = dayOfSchedule.nextByBcType(sch, "out");
75   - if(nextOut != null && nextOut.getXlBm().equals(gps.getLineId())
76   - && fcSpace(sch, gps) > fcSpace(nextOut, gps)){
77   - dayOfSchedule.addExecPlan(nextOut);
78   - return;
79   - }
80   - }
81   - }catch (Exception e){
82   - log.error("", e);
83   - }
84   -
85   - //下一个相同走向的班次
86   - ScheduleRealInfo next = dayOfSchedule.nextSame(sch);
87   - if(next == null || !next.getQdzCode().equals(sch.getQdzCode()))
88   - return;
89   -
90   - //晚于班次间隔百分之70,跳下一个班次
91   - double s = (int) (next.getDfsjT() - sch.getDfsjT());
92   - double r = (int) (t - sch.getDfsjT());
93   - if(r / s > 0.7){
94   - if(dayOfSchedule.addExecPlan(next))
95   - outMatch(gps, next);
96   - }*/
97   - }
98   -
99   - /**
100   - * 搜索一个离发车信号最近的班次
101   - * @param gps
102   - * @return
103   - */
104   - private ScheduleRealInfo searchNearOut(GpsEntity gps) {
105   - List<ScheduleRealInfo> list = dayOfSchedule.findByNbbm(gps.getNbbm());
106   - //排序
107   - Collections.sort(list, schComp);
108   -
109   - ScheduleRealInfo near = null;
110   - int diff, minDiff=-1;
111   - for(ScheduleRealInfo sch : list){
112   -
113   - if(StringUtils.isNotEmpty(sch.getFcsjActual()))
114   - continue;
115   -
116   - if(StringUtils.isNotEmpty(sch.getZdsjActual()))
117   - continue;
118   -
119   - diff = (int) Math.abs(gps.getTimestamp() - sch.getDfsjT());
120   - if(null == near || diff < minDiff){
121   - near = sch;
122   - minDiff = diff;
123   - }
124   - }
125   - return near;
126   - }
127   -}
  1 +package com.bsth.data.gpsdata_v2.utils;
  2 +
  3 +import com.bsth.data.gpsdata_v2.entity.GpsEntity;
  4 +import com.bsth.data.schedule.DayOfSchedule;
  5 +import com.bsth.data.schedule.ScheduleComparator;
  6 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  7 +import org.apache.commons.lang3.StringUtils;
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +import org.springframework.beans.factory.annotation.Autowired;
  11 +import org.springframework.stereotype.Component;
  12 +
  13 +import java.util.Collections;
  14 +import java.util.List;
  15 +
  16 +/**
  17 + * 班次匹配器
  18 + * Created by panzhao on 2016/12/31.
  19 + */
  20 +@Component
  21 +public class SignalSchPlanMatcher {
  22 +
  23 + @Autowired
  24 + DayOfSchedule dayOfSchedule;
  25 +
  26 + static ScheduleComparator.DFSJ schComp = new ScheduleComparator.DFSJ();
  27 +
  28 + Logger log = LoggerFactory.getLogger(this.getClass());
  29 +
  30 + /**
  31 + * 发车信号匹配
  32 + * @param gps
  33 + * @param sch
  34 + * @return
  35 + */
  36 + public boolean outMatch(GpsEntity gps, ScheduleRealInfo sch){
  37 + long t = gps.getTimestamp();
  38 + if(t < sch.getDfsjT())
  39 + return true;
  40 +
  41 + try{
  42 + //晚于待发时间 10 分钟 ,匹配一下最佳的班次
  43 + if(t - sch.getDfsjT() > 1000 * 60 * 10){
  44 + ScheduleRealInfo near = searchNearOut(gps);
  45 +
  46 + if(null != near && !near.getId().equals(sch.getId())){
  47 + dayOfSchedule.addExecPlan(near);
  48 + return false;
  49 + }
  50 + }
  51 +
  52 + }catch (Exception e){
  53 + log.error("", e);
  54 + }
  55 + return true;
  56 + /*try{
  57 + //会不会是分班没有完成
  58 + if(sch.getBcType().equals("in") && t - sch.getDfsjT() > 1000 * 60 * 20){
  59 + ScheduleRealInfo fbFirst = dayOfSchedule.nextByBcType(sch, "normal");
  60 +
  61 + if(fbFirst == null || !fbFirst.getQdzCode().equals(gps.getStopNo()))
  62 + return;
  63 +
  64 + long dt = fbFirst.getDfsjT();
  65 + //晚于待发前4分钟 -执行分班的首个营运
  66 + if(dt - t < 1000 * 60 * 4){
  67 + dayOfSchedule.addExecPlan(fbFirst);
  68 + return;
  69 + }
  70 + }
  71 +
  72 + //线路编码不匹配
  73 + if("out".equals(sch.getBcType()) && !sch.getXlBm().equals(gps.getLineId())){
  74 + ScheduleRealInfo nextOut = dayOfSchedule.nextByBcType(sch, "out");
  75 + if(nextOut != null && nextOut.getXlBm().equals(gps.getLineId())
  76 + && fcSpace(sch, gps) > fcSpace(nextOut, gps)){
  77 + dayOfSchedule.addExecPlan(nextOut);
  78 + return;
  79 + }
  80 + }
  81 + }catch (Exception e){
  82 + log.error("", e);
  83 + }
  84 +
  85 + //下一个相同走向的班次
  86 + ScheduleRealInfo next = dayOfSchedule.nextSame(sch);
  87 + if(next == null || !next.getQdzCode().equals(sch.getQdzCode()))
  88 + return;
  89 +
  90 + //晚于班次间隔百分之70,跳下一个班次
  91 + double s = (int) (next.getDfsjT() - sch.getDfsjT());
  92 + double r = (int) (t - sch.getDfsjT());
  93 + if(r / s > 0.7){
  94 + if(dayOfSchedule.addExecPlan(next))
  95 + outMatch(gps, next);
  96 + }*/
  97 + }
  98 +
  99 + /**
  100 + * 搜索一个离发车信号最近的班次
  101 + * @param gps
  102 + * @return
  103 + */
  104 + private ScheduleRealInfo searchNearOut(GpsEntity gps) {
  105 + List<ScheduleRealInfo> list = dayOfSchedule.findByNbbm(gps.getNbbm());
  106 + //排序
  107 + Collections.sort(list, schComp);
  108 +
  109 + ScheduleRealInfo near = null;
  110 + int diff, minDiff=-1;
  111 + for(ScheduleRealInfo sch : list){
  112 +
  113 + if(StringUtils.isNotEmpty(sch.getFcsjActual()))
  114 + continue;
  115 +
  116 + if(StringUtils.isNotEmpty(sch.getZdsjActual()))
  117 + continue;
  118 +
  119 + diff = (int) Math.abs(gps.getTimestamp() - sch.getDfsjT());
  120 + if(null == near || diff < minDiff){
  121 + near = sch;
  122 + minDiff = diff;
  123 + }
  124 + }
  125 + return near;
  126 + }
  127 +}
... ...
src/main/java/com/bsth/service/oil/impl/YlbServiceImpl.java
... ... @@ -404,7 +404,7 @@ public class YlbServiceImpl extends BaseServiceImpl&lt;Ylb,Integer&gt; implements YlbS
404 404 Ylxxb ylxxb = ylxxList.get(i);
405 405 if (map.get("clZbh").toString().equals(ylxxb.getNbbm())
406 406 && map.get("jGh").toString().equals(ylxxb.getJsy())
407   - && ylxxb.getJylx()>0) {
  407 + && ylxxb.getJylx()==1) {
408 408 if(ylxxb.getJzl()>0){
409 409 fage2=true;
410 410 }
... ... @@ -418,7 +418,7 @@ public class YlbServiceImpl extends BaseServiceImpl&lt;Ylb,Integer&gt; implements YlbS
418 418 Ylxxb ylxxb = ylxxList.get(j);
419 419 if (map.get("clZbh").toString().equals(ylxxb.getNbbm())
420 420 && map.get("jGh").toString().equals(ylxxb.getJsy())
421   - && ylxxb.getJylx()>0) {
  421 + && ylxxb.getJylx()==1) {
422 422 jzl =Arith.add(jzl, ylxxb.getJzl());
423 423 }
424 424 }
... ... @@ -765,7 +765,7 @@ public class YlbServiceImpl extends BaseServiceImpl&lt;Ylb,Integer&gt; implements YlbS
765 765 for (int i = 0; i < ylxxbList.size(); i++) {
766 766 Boolean fage=false;
767 767 Ylxxb y1=ylxxbList.get(i);
768   - if(m.get(y1.getNbbm())!=null){
  768 + if(m.get(y1.getNbbm())==null){
769 769 Line line=BasicData.nbbm2LineMap.get(y1.getNbbm());
770 770 if(null !=line){
771 771 if(!xlbm.equals("")){
... ... @@ -808,7 +808,6 @@ public class YlbServiceImpl extends BaseServiceImpl&lt;Ylb,Integer&gt; implements YlbS
808 808 if(status){
809 809 t.setCzyl(0.0);
810 810 }
811   -// double jzyl=Arith.add(t.getJzl(), t.getCzyl());
812 811 t.setJzyl(Arith.add(t.getJzl(), t.getCzyl()));
813 812 t.setYh(0.0);
814 813 if(!(t.getSsgsdm().equals("") || t.getFgsdm().equals(""))){
... ...