Commit 93905332d9283f59f8e6bbdf40124a9634aa3fcb

Authored by 潘钊
1 parent 1786ccee

重写到离站匹配模块

Showing 24 changed files with 1146 additions and 145 deletions
src/main/java/com/bsth/data/BasicData.java
1 package com.bsth.data; 1 package com.bsth.data;
2 2
3 import com.bsth.Application; 3 import com.bsth.Application;
  4 +import com.bsth.data.gpsdata.analyse.GeoCacheData;
4 import com.bsth.entity.*; 5 import com.bsth.entity.*;
5 import com.bsth.entity.schedule.CarConfigInfo; 6 import com.bsth.entity.schedule.CarConfigInfo;
6 import com.bsth.repository.*; 7 import com.bsth.repository.*;
@@ -57,7 +58,7 @@ public class BasicData implements CommandLineRunner { @@ -57,7 +58,7 @@ public class BasicData implements CommandLineRunner {
57 public static Map<String, String> lineCode2NameMap; 58 public static Map<String, String> lineCode2NameMap;
58 59
59 //线路编码_站点编码 == 0|1 上下行 60 //线路编码_站点编码 == 0|1 上下行
60 - public static Map<String, Integer> lineStationUpDownMap; 61 + //public static Map<String, Integer> lineStationUpDownMap;
61 62
62 //停车场 63 //停车场
63 public static List<String> parkCodeList; 64 public static List<String> parkCodeList;
@@ -86,7 +87,7 @@ public class BasicData implements CommandLineRunner { @@ -86,7 +87,7 @@ public class BasicData implements CommandLineRunner {
86 87
87 @Override 88 @Override
88 public void run(String... arg0) throws Exception { 89 public void run(String... arg0) throws Exception {
89 - Application.mainServices.scheduleWithFixedDelay(dataLoader, 0, 1, TimeUnit.HOURS); 90 + Application.mainServices.scheduleWithFixedDelay(dataLoader, 2, 2, TimeUnit.HOURS);
90 } 91 }
91 92
92 93
@@ -117,6 +118,9 @@ public class BasicData implements CommandLineRunner { @@ -117,6 +118,9 @@ public class BasicData implements CommandLineRunner {
117 @Autowired 118 @Autowired
118 BusinessRepository businessRepository; 119 BusinessRepository businessRepository;
119 120
  121 + @Autowired
  122 + GeoCacheData geoCacheData;
  123 +
120 124
121 @Override 125 @Override
122 public void run() { 126 public void run() {
@@ -138,11 +142,13 @@ public class BasicData implements CommandLineRunner { @@ -138,11 +142,13 @@ public class BasicData implements CommandLineRunner {
138 //车辆和线路映射信息 142 //车辆和线路映射信息
139 loadNbbm2LineInfo(); 143 loadNbbm2LineInfo();
140 //站点路由信息 144 //站点路由信息
141 - loadStationRouteInfo(); 145 + //loadStationRouteInfo();
142 //人员信息 146 //人员信息
143 loadPersonnelInfo(); 147 loadPersonnelInfo();
144 //公司信息 148 //公司信息
145 loadBusinessInfo(); 149 loadBusinessInfo();
  150 +
  151 + geoCacheData.loadData();
146 logger.info("加载基础数据成功!,"); 152 logger.info("加载基础数据成功!,");
147 } catch (Exception e) { 153 } catch (Exception e) {
148 logger.error("加载基础数据时出现异常,", e); 154 logger.error("加载基础数据时出现异常,", e);
@@ -151,7 +157,7 @@ public class BasicData implements CommandLineRunner { @@ -151,7 +157,7 @@ public class BasicData implements CommandLineRunner {
151 } 157 }
152 158
153 159
154 - private void loadStationRouteInfo() { 160 +/* private void loadStationRouteInfo() {
155 Iterator<StationRoute> iterator = stationRouteRepository.findAllEffective().iterator(); 161 Iterator<StationRoute> iterator = stationRouteRepository.findAllEffective().iterator();
156 162
157 Map<String, String> sePointMap = new HashMap<>(); 163 Map<String, String> sePointMap = new HashMap<>();
@@ -172,7 +178,7 @@ public class BasicData implements CommandLineRunner { @@ -172,7 +178,7 @@ public class BasicData implements CommandLineRunner {
172 } 178 }
173 lineStationUpDownMap = map; 179 lineStationUpDownMap = map;
174 lineSEPointMap = sePointMap; 180 lineSEPointMap = sePointMap;
175 - } 181 + }*/
176 182
177 /** 183 /**
178 * loadBusinessInfo 184 * loadBusinessInfo
@@ -280,7 +286,7 @@ public class BasicData implements CommandLineRunner { @@ -280,7 +286,7 @@ public class BasicData implements CommandLineRunner {
280 /** 286 /**
281 * 加载运管处的站点及序号 287 * 加载运管处的站点及序号
282 * 上行从1开始,下行顺序续编 288 * 上行从1开始,下行顺序续编
283 - */ 289 +
284 List<Object[]> ygcLines = stationRouteRepository.findAllLineWithYgc(); 290 List<Object[]> ygcLines = stationRouteRepository.findAllLineWithYgc();
285 if(ygcLines != null && ygcLines.size() > 0){ 291 if(ygcLines != null && ygcLines.size() > 0){
286 int size = ygcLines.size(); 292 int size = ygcLines.size();
@@ -299,7 +305,7 @@ public class BasicData implements CommandLineRunner { @@ -299,7 +305,7 @@ public class BasicData implements CommandLineRunner {
299 key = tempArray[0] + "_"+tempArray[1] + "_"+tempArray[2]; 305 key = tempArray[0] + "_"+tempArray[1] + "_"+tempArray[2];
300 tempStationName2YgcNumber.put(key,num++); 306 tempStationName2YgcNumber.put(key,num++);
301 } 307 }
302 - } 308 + }*/
303 } 309 }
304 310
305 lineId2CodeMap = biMap; 311 lineId2CodeMap = biMap;
src/main/java/com/bsth/data/arrival/AnalyseData.java
1 package com.bsth.data.arrival; 1 package com.bsth.data.arrival;
2 2
3 -import java.util.ArrayList;  
4 -import java.util.Collections;  
5 -import java.util.List;  
6 -import java.util.Set;  
7 -  
8 import org.slf4j.Logger; 3 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory; 4 import org.slf4j.LoggerFactory;
10 import org.springframework.stereotype.Component; 5 import org.springframework.stereotype.Component;
11 6
12 -import com.bsth.data.BasicData; 7 +import java.util.ArrayList;
  8 +import java.util.Collections;
  9 +import java.util.List;
  10 +import java.util.Set;
13 11
14 /** 12 /**
15 * 13 *
@@ -98,14 +96,15 @@ public class AnalyseData { @@ -98,14 +96,15 @@ public class AnalyseData {
98 } 96 }
99 97
100 private boolean effective(ArrivalEntity arr){ 98 private boolean effective(ArrivalEntity arr){
101 - //停车场 99 + /*//停车场
102 if(BasicData.parkCodeList.contains(arr.getStopNo())){ 100 if(BasicData.parkCodeList.contains(arr.getStopNo())){
103 arr.setTcc(true); 101 arr.setTcc(true);
104 return true; 102 return true;
105 } 103 }
106 - 104 +
107 Integer upDown = BasicData.lineStationUpDownMap.get(arr.getLineCode() + "_" + arr.getStopNo()); 105 Integer upDown = BasicData.lineStationUpDownMap.get(arr.getLineCode() + "_" + arr.getStopNo());
108 -  
109 - return arr.getUpDown() == upDown || BasicData.parkCodeList.contains(arr.getStopNo()); 106 +
  107 + return arr.getUpDown() == upDown || BasicData.parkCodeList.contains(arr.getStopNo());*/
  108 + return false;
110 } 109 }
111 } 110 }
src/main/java/com/bsth/data/forecast/ForecastRealServer.java
@@ -70,7 +70,7 @@ public class ForecastRealServer implements CommandLineRunner { @@ -70,7 +70,7 @@ public class ForecastRealServer implements CommandLineRunner {
70 /* public void forecast(String nbbm){ 70 /* public void forecast(String nbbm){
71 logger.info("预测," + nbbm); 71 logger.info("预测," + nbbm);
72 //当前执行班次 72 //当前执行班次
73 - ScheduleRealInfo sch = dayOfSchedule.execPlamMap().get(nbbm); 73 + ScheduleRealInfo sch = dayOfSchedule.execPlanMap().get(nbbm);
74 if(null == sch) 74 if(null == sch)
75 return; 75 return;
76 76
@@ -86,7 +86,7 @@ public class ForecastRealServer implements CommandLineRunner { @@ -86,7 +86,7 @@ public class ForecastRealServer implements CommandLineRunner {
86 //终点站 86 //终点站
87 String eStation = null; 87 String eStation = null;
88 //当前执行班次 88 //当前执行班次
89 - ScheduleRealInfo sch = dayOfSchedule.execPlamMap().get(nbbm); 89 + ScheduleRealInfo sch = dayOfSchedule.execPlanMap().get(nbbm);
90 if(null != sch) 90 if(null != sch)
91 eStation = sch.getZdzCode(); 91 eStation = sch.getZdzCode();
92 92
src/main/java/com/bsth/data/gpsdata/GpsEntity.java
1 package com.bsth.data.gpsdata; 1 package com.bsth.data.gpsdata;
2 2
  3 +import com.bsth.data.gpsdata.analyse.StationRoute;
  4 +import com.fasterxml.jackson.annotation.JsonIgnore;
  5 +
3 /** 6 /**
4 * 7 *
5 * @ClassName: GpsRealData 8 * @ClassName: GpsRealData
@@ -58,25 +61,33 @@ public class GpsEntity { @@ -58,25 +61,33 @@ public class GpsEntity {
58 /** 预计到达终点时间 */ 61 /** 预计到达终点时间 */
59 private Float expectStopTime; 62 private Float expectStopTime;
60 63
61 - /** 设备是否在线 */ 64 + /** 设备是否在线
62 private boolean online; 65 private boolean online;
63 - 66 + */
64 /** 当前执行班次ID */ 67 /** 当前执行班次ID */
65 private Long schId; 68 private Long schId;
66 69
67 /** 是否异常数据 */ 70 /** 是否异常数据 */
68 private boolean abnormal; 71 private boolean abnormal;
69 -  
70 - private int valid; 72 +/*
  73 + private int valid;*/
71 74
72 private int version; 75 private int version;
73 76
74 - /** 是否起终点站 */ 77 + /** 是否起终点站
75 private boolean sEPoint; 78 private boolean sEPoint;
  79 + */
76 80
77 /** 站内 */ 81 /** 站内 */
78 private boolean instation; 82 private boolean instation;
79 83
  84 + /** 站点信息,站内时有值 */
  85 + @JsonIgnore
  86 + private StationRoute station;
  87 +
  88 + /** 状态 */
  89 + private String state2;
  90 +
80 public Integer getCompanyCode() { 91 public Integer getCompanyCode() {
81 return companyCode; 92 return companyCode;
82 } 93 }
@@ -181,14 +192,6 @@ public class GpsEntity { @@ -181,14 +192,6 @@ public class GpsEntity {
181 this.stationName = stationName; 192 this.stationName = stationName;
182 } 193 }
183 194
184 - public boolean isOnline() {  
185 - return online;  
186 - }  
187 -  
188 - public void setOnline(boolean online) {  
189 - this.online = online;  
190 - }  
191 -  
192 public long getArrTime() { 195 public long getArrTime() {
193 return arrTime; 196 return arrTime;
194 } 197 }
@@ -221,43 +224,44 @@ public class GpsEntity { @@ -221,43 +224,44 @@ public class GpsEntity {
221 this.schId = schId; 224 this.schId = schId;
222 } 225 }
223 226
224 - public boolean isAbnormal() {  
225 - return abnormal; 227 +
  228 + public int getVersion() {
  229 + return version;
226 } 230 }
227 231
228 - public void setAbnormal(boolean abnormal) {  
229 - this.abnormal = abnormal; 232 + public void setVersion(int version) {
  233 + this.version = version;
230 } 234 }
231 235
232 - public int getValid() {  
233 - return valid; 236 + public boolean isInstation() {
  237 + return instation;
234 } 238 }
235 239
236 - public void setValid(int valid) {  
237 - this.valid = valid; 240 + public void setInstation(boolean instation) {
  241 + this.instation = instation;
238 } 242 }
239 243
240 - public int getVersion() {  
241 - return version; 244 + public StationRoute getStation() {
  245 + return station;
242 } 246 }
243 247
244 - public void setVersion(int version) {  
245 - this.version = version; 248 + public void setStation(StationRoute station) {
  249 + this.station = station;
246 } 250 }
247 251
248 - public boolean issEPoint() {  
249 - return sEPoint; 252 + public boolean isAbnormal() {
  253 + return abnormal;
250 } 254 }
251 255
252 - public void setsEPoint(boolean sEPoint) {  
253 - this.sEPoint = sEPoint; 256 + public void setAbnormal(boolean abnormal) {
  257 + this.abnormal = abnormal;
254 } 258 }
255 259
256 - public boolean isInstation() {  
257 - return instation; 260 + public String getState2() {
  261 + return state2;
258 } 262 }
259 263
260 - public void setInstation(boolean instation) {  
261 - this.instation = instation; 264 + public void setState2(String state2) {
  265 + this.state2 = state2;
262 } 266 }
263 } 267 }
src/main/java/com/bsth/data/gpsdata/GpsRealData.java
@@ -5,6 +5,8 @@ import com.alibaba.fastjson.JSONObject; @@ -5,6 +5,8 @@ import com.alibaba.fastjson.JSONObject;
5 import com.bsth.Application; 5 import com.bsth.Application;
6 import com.bsth.data.BasicData; 6 import com.bsth.data.BasicData;
7 import com.bsth.data.forecast.ForecastRealServer; 7 import com.bsth.data.forecast.ForecastRealServer;
  8 +import com.bsth.data.gpsdata.analyse.GpsAnalyse;
  9 +import com.bsth.data.gpsdata.recovery.GpsDataRecovery;
8 import com.bsth.data.schedule.DayOfSchedule; 10 import com.bsth.data.schedule.DayOfSchedule;
9 import com.bsth.entity.realcontrol.ScheduleRealInfo; 11 import com.bsth.entity.realcontrol.ScheduleRealInfo;
10 import com.bsth.util.ConfigUtil; 12 import com.bsth.util.ConfigUtil;
@@ -55,6 +57,9 @@ public class GpsRealData implements CommandLineRunner{ @@ -55,6 +57,9 @@ public class GpsRealData implements CommandLineRunner{
55 57
56 @Autowired 58 @Autowired
57 ForecastRealServer forecastRealServer; 59 ForecastRealServer forecastRealServer;
  60 +
  61 +
  62 +
58 /** 63 /**
59 * 构造函数 64 * 构造函数
60 */ 65 */
@@ -67,13 +72,17 @@ public class GpsRealData implements CommandLineRunner{ @@ -67,13 +72,17 @@ public class GpsRealData implements CommandLineRunner{
67 @Override 72 @Override
68 public void run(String... arg0) throws Exception { 73 public void run(String... arg0) throws Exception {
69 logger.info("gpsDataLoader,20,6"); 74 logger.info("gpsDataLoader,20,6");
70 - Application.mainServices.scheduleWithFixedDelay(gpsDataLoader, 20, 15, TimeUnit.SECONDS); 75 + Application.mainServices.scheduleWithFixedDelay(gpsDataLoader, 40, 20, TimeUnit.SECONDS);
71 } 76 }
72 77
73 public GpsEntity add(GpsEntity gps) { 78 public GpsEntity add(GpsEntity gps) {
74 String device = gps.getDeviceId(); 79 String device = gps.getDeviceId();
75 GpsEntity old = gpsMap.get(device); 80 GpsEntity old = gpsMap.get(device);
76 81
  82 + //分析gps
  83 + if(isAvailable(gps) && (old == null || old.getTimestamp() != gps.getTimestamp()))
  84 + GpsAnalyse.start(gps);
  85 +
77 if(!StringUtils.isEmpty(gps.getStopNo())){ 86 if(!StringUtils.isEmpty(gps.getStopNo())){
78 //定时定距数据附带站点编码改变 87 //定时定距数据附带站点编码改变
79 if(null == old || !gps.getStopNo().equals(old.getStopNo())){ 88 if(null == old || !gps.getStopNo().equals(old.getStopNo())){
@@ -94,6 +103,11 @@ public class GpsRealData implements CommandLineRunner{ @@ -94,6 +103,11 @@ public class GpsRealData implements CommandLineRunner{
94 return gps; 103 return gps;
95 } 104 }
96 105
  106 + public boolean isAvailable(GpsEntity gps){
  107 + return StringUtils.isNotEmpty(gps.getLineId()) &&
  108 + dayOfSchedule.getCurrSchDate().containsKey(gps.getLineId());
  109 + }
  110 +
97 /** 111 /**
98 * 112 *
99 * @Title: get @Description: TODO(设备号获取GPS) 113 * @Title: get @Description: TODO(设备号获取GPS)
@@ -118,7 +132,7 @@ public class GpsRealData implements CommandLineRunner{ @@ -118,7 +132,7 @@ public class GpsRealData implements CommandLineRunner{
118 if(gps.isAbnormal()) 132 if(gps.isAbnormal())
119 continue; 133 continue;
120 134
121 - sch = dayOfSchedule.execPlamMap().get(gps.getNbbm()); 135 + sch = dayOfSchedule.execPlanMap().get(gps.getNbbm());
122 if(null != sch) 136 if(null != sch)
123 gps.setSchId(sch.getId()); 137 gps.setSchId(sch.getId());
124 rs.add(gps); 138 rs.add(gps);
@@ -161,6 +175,11 @@ public class GpsRealData implements CommandLineRunner{ @@ -161,6 +175,11 @@ public class GpsRealData implements CommandLineRunner{
161 @Override 175 @Override
162 public void run() { 176 public void run() {
163 try{ 177 try{
  178 + //如果正在恢复数据
  179 + if(GpsDataRecovery.run){
  180 + return;
  181 + }
  182 +
164 load(); 183 load();
165 }catch(Exception e){ 184 }catch(Exception e){
166 logger.error("", e); 185 logger.error("", e);
@@ -207,7 +226,7 @@ public class GpsRealData implements CommandLineRunner{ @@ -207,7 +226,7 @@ public class GpsRealData implements CommandLineRunner{
207 gpsRealData.add(gps); 226 gpsRealData.add(gps);
208 227
209 //纠正走向 228 //纠正走向
210 - correctUpdown(gps); 229 + //correctUpdown(gps);
211 } 230 }
212 } else 231 } else
213 logger.error("result is null"); 232 logger.error("result is null");
@@ -226,7 +245,7 @@ public class GpsRealData implements CommandLineRunner{ @@ -226,7 +245,7 @@ public class GpsRealData implements CommandLineRunner{
226 * 是否是起终点 245 * 是否是起终点
227 * @param gps 246 * @param gps
228 * @return 247 * @return
229 - */ 248 +
230 public boolean isSEPoint(GpsEntity gps){ 249 public boolean isSEPoint(GpsEntity gps){
231 String key = gps.getLineId()+"_"+gps.getUpDown()+"_" 250 String key = gps.getLineId()+"_"+gps.getUpDown()+"_"
232 ,stationCode; 251 ,stationCode;
@@ -247,12 +266,12 @@ public class GpsRealData implements CommandLineRunner{ @@ -247,12 +266,12 @@ public class GpsRealData implements CommandLineRunner{
247 } 266 }
248 } 267 }
249 return false; 268 return false;
250 - } 269 + }*/
251 270
252 /** 271 /**
253 * 纠正上下行 272 * 纠正上下行
254 * @param gps 273 * @param gps
255 - */ 274 +
256 public void correctUpdown(GpsEntity gps){ 275 public void correctUpdown(GpsEntity gps){
257 Integer updown=BasicData.lineStationUpDownMap.get(gps.getLineId()+"_"+gps.getStopNo()); 276 Integer updown=BasicData.lineStationUpDownMap.get(gps.getLineId()+"_"+gps.getStopNo());
258 if(updown != null && !updown.equals(gps.getUpDown())) 277 if(updown != null && !updown.equals(gps.getUpDown()))
@@ -260,6 +279,6 @@ public class GpsRealData implements CommandLineRunner{ @@ -260,6 +279,6 @@ public class GpsRealData implements CommandLineRunner{
260 279
261 if(isSEPoint(gps)) 280 if(isSEPoint(gps))
262 return; 281 return;
263 - } 282 + }*/
264 } 283 }
265 } 284 }
src/main/java/com/bsth/data/gpsdata/analyse/CircleQueue.java
@@ -109,4 +109,8 @@ public class CircleQueue&lt;T&gt; { @@ -109,4 +109,8 @@ public class CircleQueue&lt;T&gt; {
109 } 109 }
110 return elementDataSort; 110 return elementDataSort;
111 } 111 }
  112 +
  113 + public T getTail(){
  114 + return elementData[tail] == null?null:(T)elementData[tail];
  115 + }
112 } 116 }
src/main/java/com/bsth/data/gpsdata/analyse/GeoCacheData.java
@@ -5,7 +5,10 @@ import com.google.common.collect.ArrayListMultimap; @@ -5,7 +5,10 @@ import com.google.common.collect.ArrayListMultimap;
5 import com.vividsolutions.jts.geom.Coordinate; 5 import com.vividsolutions.jts.geom.Coordinate;
6 import com.vividsolutions.jts.geom.GeometryFactory; 6 import com.vividsolutions.jts.geom.GeometryFactory;
7 import com.vividsolutions.jts.geom.LineString; 7 import com.vividsolutions.jts.geom.LineString;
  8 +import com.vividsolutions.jts.geom.Polygon;
8 import org.apache.commons.lang3.StringUtils; 9 import org.apache.commons.lang3.StringUtils;
  10 +import org.slf4j.Logger;
  11 +import org.slf4j.LoggerFactory;
9 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.jdbc.core.JdbcTemplate; 13 import org.springframework.jdbc.core.JdbcTemplate;
11 import org.springframework.jdbc.core.RowMapper; 14 import org.springframework.jdbc.core.RowMapper;
@@ -13,9 +16,7 @@ import org.springframework.stereotype.Component; @@ -13,9 +16,7 @@ import org.springframework.stereotype.Component;
13 16
14 import java.sql.ResultSet; 17 import java.sql.ResultSet;
15 import java.sql.SQLException; 18 import java.sql.SQLException;
16 -import java.util.HashMap;  
17 -import java.util.List;  
18 -import java.util.Map; 19 +import java.util.*;
19 20
20 /** 21 /**
21 * Created by panzhao on 2016/12/23. 22 * Created by panzhao on 2016/12/23.
@@ -23,8 +24,10 @@ import java.util.Map; @@ -23,8 +24,10 @@ import java.util.Map;
23 @Component 24 @Component
24 public class GeoCacheData { 25 public class GeoCacheData {
25 26
26 - //每辆车缓存最后50条gps  
27 - private static final int CACHE_SIZE = 50; 27 + static Logger logger = LoggerFactory.getLogger(GeoCacheData.class);
  28 +
  29 + //每辆车缓存最后200条gps
  30 + private static final int CACHE_SIZE = 200;
28 private static Map<String, CircleQueue<GpsEntity>> gpsCacheMap = new HashMap<>(); 31 private static Map<String, CircleQueue<GpsEntity>> gpsCacheMap = new HashMap<>();
29 32
30 //线路路段走向 33 //线路路段走向
@@ -33,13 +36,52 @@ public class GeoCacheData { @@ -33,13 +36,52 @@ public class GeoCacheData {
33 //线路站点路由 36 //线路站点路由
34 private static ArrayListMultimap<String, StationRoute> stationCacheMap; 37 private static ArrayListMultimap<String, StationRoute> stationCacheMap;
35 38
  39 + //停车场
  40 + public static Map<String, Polygon> tccMap;
  41 +
36 @Autowired 42 @Autowired
37 JdbcTemplate jdbcTemplate; 43 JdbcTemplate jdbcTemplate;
38 44
39 - public void loadData(){ 45 + public static CircleQueue<GpsEntity> getGps(String nbbm) {
  46 + return gpsCacheMap.get(nbbm);
  47 + }
  48 +
  49 + public static void putGps(GpsEntity gps) {
  50 + CircleQueue<GpsEntity> queue = gpsCacheMap.get(gps.getNbbm());
  51 + if (queue == null) {
  52 + //第一个点从站内开始
  53 + if(!gps.isInstation())
  54 + return;
  55 +
  56 + queue = new CircleQueue<>(CACHE_SIZE);
  57 + gpsCacheMap.put(gps.getNbbm(), queue);
  58 + }
  59 + queue.add(gps);
  60 + }
  61 +
  62 + public static List<StationRoute> getStationRoute(String lineCode, int directions) {
  63 + return stationCacheMap.get(lineCode + "_" + directions);
  64 + }
  65 +
  66 + public static StationRoute getStation(String lineCode, int directions, String code) {
  67 + List<StationRoute> list = getStationRoute(lineCode, directions);
  68 +
  69 + for (StationRoute sr : list) {
  70 + if (sr.getCode().equals(code)) {
  71 + return sr;
  72 + }
  73 + }
  74 + return null;
  75 + }
  76 +
  77 + public static Polygon getTccPolygon(String code){
  78 + return tccMap.get(code);
  79 + }
  80 +
  81 + public void loadData() {
40 final GeometryFactory geometryFactory = new GeometryFactory(); 82 final GeometryFactory geometryFactory = new GeometryFactory();
41 //加载站点路由 83 //加载站点路由
42 - 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 from bsth_c_stationroute r left join bsth_c_station s on r.station=s.id"; 84 + 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 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";
43 List<StationRoute> routeList = jdbcTemplate.query(sql, new RowMapper<StationRoute>() { 85 List<StationRoute> routeList = jdbcTemplate.query(sql, new RowMapper<StationRoute>() {
44 @Override 86 @Override
45 public StationRoute mapRow(ResultSet rs, int rowNum) throws SQLException { 87 public StationRoute mapRow(ResultSet rs, int rowNum) throws SQLException {
@@ -47,39 +89,82 @@ public class GeoCacheData { @@ -47,39 +89,82 @@ public class GeoCacheData {
47 sRoute.setCode(rs.getString("STATION_CODE")); 89 sRoute.setCode(rs.getString("STATION_CODE"));
48 sRoute.setLineCode(rs.getString("LINE_CODE")); 90 sRoute.setLineCode(rs.getString("LINE_CODE"));
49 sRoute.setDirections(rs.getInt("DIRECTIONS")); 91 sRoute.setDirections(rs.getInt("DIRECTIONS"));
50 - sRoute.setPoint(geometryFactory.createPoint(new Coordinate(rs.getFloat("G_LONX"), rs.getFloat("G_LATY")))); 92 + sRoute.setPoint(geometryFactory.createPoint(new Coordinate(rs.getFloat("G_LATY"), rs.getFloat("G_LONX"))));
51 sRoute.setRadius(rs.getFloat("RADIUS")); 93 sRoute.setRadius(rs.getFloat("RADIUS"));
  94 + sRoute.setRouteSort(rs.getInt("STATION_ROUTE_CODE"));
  95 + sRoute.setMark(rs.getString("STATION_MARK"));
52 96
53 String shapesType = rs.getString("SHAPES_TYPE"); 97 String shapesType = rs.getString("SHAPES_TYPE");
54 //多边形电子围栏 98 //多边形电子围栏
55 - if(StringUtils.isNotEmpty(shapesType) && shapesType.equals("d")){ 99 + if (StringUtils.isNotEmpty(shapesType) && shapesType.equals("d")) {
56 geometryFactory.createPolygon(parsePolygon(rs.getString("G_POLYGON_GRID"))); 100 geometryFactory.createPolygon(parsePolygon(rs.getString("G_POLYGON_GRID")));
57 } 101 }
58 return sRoute; 102 return sRoute;
59 } 103 }
60 }); 104 });
61 //按线路和走向分组 105 //按线路和走向分组
62 - if(routeList.size() > 0){ 106 + if (routeList.size() > 0) {
63 ArrayListMultimap<String, StationRoute> tempMap = ArrayListMultimap.create(); 107 ArrayListMultimap<String, StationRoute> tempMap = ArrayListMultimap.create();
64 - for(StationRoute sr : routeList){ 108 + for (StationRoute sr : routeList) {
65 tempMap.put(sr.getLineCode() + "_" + sr.getDirections(), sr); 109 tempMap.put(sr.getLineCode() + "_" + sr.getDirections(), sr);
66 } 110 }
  111 +
  112 + StationRouteComp srCom = new StationRouteComp();
  113 + //连接路由
  114 + Set<String> set = tempMap.keySet();
  115 + for (String key : set) {
  116 + Collections.sort(tempMap.get(key), srCom);
  117 + connectStationRoute(tempMap.get(key));
  118 + }
  119 +
67 stationCacheMap = tempMap; 120 stationCacheMap = tempMap;
68 } 121 }
69 122
70 - System.out.println(stationCacheMap); 123 + //加载停车场数据
  124 + 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";
  125 + List<Map<String, Object>> tccList = jdbcTemplate.queryForList(sql);
  126 + Map<String, Polygon> tccTempMap = new HashMap<>();
  127 +
  128 + Polygon polygon;
  129 + for (Map<String, Object> tMap : tccList) {
  130 +
  131 + try {
  132 + polygon = geometryFactory.createPolygon(parsePolygon(tMap.get("G_PARK_POINT").toString()));
  133 + tccTempMap.put(tMap.get("PARK_CODE").toString()
  134 + , polygon);
  135 + } catch (Exception e) {
  136 + logger.error("停车场:" + tMap.get("PARK_CODE") , e);
  137 + }
  138 + }
  139 +
  140 + if(tccTempMap.size() > 0)
  141 + tccMap = tccTempMap;
71 } 142 }
72 143
73 - public Coordinate[] parsePolygon(String polygonStr){  
74 - String[] coords = polygonStr.substring(11, polygonStr.length() - 2).split(",")  
75 - ,temps; 144 + private void connectStationRoute(List<StationRoute> list) {
  145 + int size = list.size();
  146 + StationRoute sr = null;
  147 + for (int i = 0; i < size; i++) {
  148 + sr = list.get(i);
  149 + //上一个
  150 + if (i > 0)
  151 + sr.setPrve(list.get(i - 1));
  152 + //下一个
  153 + if (i < size - 1)
  154 + sr.setNext(list.get(i + 1));
  155 + }
  156 + }
  157 +
  158 + public Coordinate[] parsePolygon(String polygonStr) {
  159 + String[] coords = polygonStr.substring(9, polygonStr.length() - 2).split(","), temps;
76 160
77 Coordinate[] cds = new Coordinate[coords.length]; 161 Coordinate[] cds = new Coordinate[coords.length];
78 int len = coords.length; 162 int len = coords.length;
79 - for(int i = 0; i < len; i++){ 163 + for (int i = 0; i < len; i++) {
80 temps = coords[i].split(" "); 164 temps = coords[i].split(" ");
81 - cds[i] = new Coordinate(Float.parseFloat(temps[0]), Float.parseFloat(temps[1])); 165 + cds[i] = new Coordinate(Float.parseFloat(temps[1]), Float.parseFloat(temps[0]));
82 } 166 }
83 return cds; 167 return cds;
84 } 168 }
  169 +
85 } 170 }
src/main/java/com/bsth/data/gpsdata/analyse/GpsAnalyse.java
1 package com.bsth.data.gpsdata.analyse; 1 package com.bsth.data.gpsdata.analyse;
2 2
3 import com.bsth.data.gpsdata.GpsEntity; 3 import com.bsth.data.gpsdata.GpsEntity;
4 -import com.vividsolutions.jts.geom.GeometryFactory; 4 +import com.bsth.data.gpsdata.analyse.components.GpsArrival;
  5 +import org.slf4j.Logger;
  6 +import org.slf4j.LoggerFactory;
5 7
6 import java.util.concurrent.ExecutorService; 8 import java.util.concurrent.ExecutorService;
7 import java.util.concurrent.Executors; 9 import java.util.concurrent.Executors;
@@ -12,35 +14,26 @@ import java.util.concurrent.Executors; @@ -12,35 +14,26 @@ import java.util.concurrent.Executors;
12 */ 14 */
13 public class GpsAnalyse { 15 public class GpsAnalyse {
14 16
15 - //线程池  
16 - ExecutorService threadPool = Executors.newFixedThreadPool(50); 17 + static Logger logger = LoggerFactory.getLogger(GpsAnalyse.class);
17 18
18 - private static GeometryFactory geometryFactory = new GeometryFactory(); 19 + //线程池
  20 + static ExecutorService threadPool = Executors.newFixedThreadPool(50);
19 21
20 - public void start(GpsEntity gps){ 22 + public static void start(GpsEntity gps) {
21 threadPool.execute(new ArrivalMatchThread(gps)); 23 threadPool.execute(new ArrivalMatchThread(gps));
22 } 24 }
23 25
24 - public class ArrivalMatchThread implements Runnable{ 26 + public static class ArrivalMatchThread implements Runnable {
25 27
26 private GpsEntity gps; 28 private GpsEntity gps;
27 29
28 - public ArrivalMatchThread(GpsEntity gps){ 30 + public ArrivalMatchThread(GpsEntity gps) {
29 this.gps = gps; 31 this.gps = gps;
30 } 32 }
31 33
32 @Override 34 @Override
33 public void run() { 35 public void run() {
34 - //CircleQueue<GpsEntity> queue = gpsCacheMap.get(gps.getNbbm());  
35 -  
36 - //站内还是站外  
37 - //Point p = geometryFactory.createPoint(new Coordinate(gps.getLat(), gps.getLon()));  
38 -  
39 - /*if(queue == null){  
40 - //首个GPS点  
41 - queue = new CircleQueue<>(CACHE_SIZE);  
42 - queue.add(gps);  
43 - }*/ 36 + GpsArrival.arrival(gps);
44 } 37 }
45 } 38 }
46 } 39 }
src/main/java/com/bsth/data/gpsdata/analyse/StationRoute.java
@@ -30,6 +30,15 @@ public class StationRoute { @@ -30,6 +30,15 @@ public class StationRoute {
30 /** 多边形电子围栏 */ 30 /** 多边形电子围栏 */
31 private Polygon polygon; 31 private Polygon polygon;
32 32
  33 + /** 站点标记 */
  34 + private String mark;
  35 +
  36 + /** 下一站 */
  37 + private StationRoute next;
  38 +
  39 + /** 上一站 */
  40 + private StationRoute prve;
  41 +
33 public String getCode() { 42 public String getCode() {
34 return code; 43 return code;
35 } 44 }
@@ -85,4 +94,28 @@ public class StationRoute { @@ -85,4 +94,28 @@ public class StationRoute {
85 public void setDirections(int directions) { 94 public void setDirections(int directions) {
86 this.directions = directions; 95 this.directions = directions;
87 } 96 }
  97 +
  98 + public StationRoute getNext() {
  99 + return next;
  100 + }
  101 +
  102 + public void setNext(StationRoute next) {
  103 + this.next = next;
  104 + }
  105 +
  106 + public StationRoute getPrve() {
  107 + return prve;
  108 + }
  109 +
  110 + public void setPrve(StationRoute prve) {
  111 + this.prve = prve;
  112 + }
  113 +
  114 + public String getMark() {
  115 + return mark;
  116 + }
  117 +
  118 + public void setMark(String mark) {
  119 + this.mark = mark;
  120 + }
88 } 121 }
src/main/java/com/bsth/data/gpsdata/analyse/StationRouteComp.java 0 → 100644
  1 +package com.bsth.data.gpsdata.analyse;
  2 +
  3 +import java.util.Comparator;
  4 +
  5 +/**
  6 + * Created by panzhao on 2016/12/24.
  7 + */
  8 +public class StationRouteComp implements Comparator<StationRoute>{
  9 + @Override
  10 + public int compare(StationRoute s1, StationRoute s2) {
  11 + return s1.getRouteSort() - s2.getRouteSort();
  12 + }
  13 +}
src/main/java/com/bsth/data/gpsdata/analyse/components/GpsArrival.java 0 → 100644
  1 +package com.bsth.data.gpsdata.analyse.components;
  2 +
  3 +import com.bsth.data.LineConfigData;
  4 +import com.bsth.data.gpsdata.GpsEntity;
  5 +import com.bsth.data.gpsdata.analyse.CircleQueue;
  6 +import com.bsth.data.gpsdata.analyse.GeoCacheData;
  7 +import com.bsth.data.gpsdata.analyse.StationRoute;
  8 +import com.bsth.data.gpsdata.analyse.util.GeoUtils;
  9 +import com.bsth.data.schedule.DayOfSchedule;
  10 +import com.bsth.entity.realcontrol.LineConfig;
  11 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  12 +import org.slf4j.Logger;
  13 +import org.slf4j.LoggerFactory;
  14 +import org.springframework.beans.BeansException;
  15 +import org.springframework.context.ApplicationContext;
  16 +import org.springframework.context.ApplicationContextAware;
  17 +import org.springframework.stereotype.Component;
  18 +
  19 +import java.util.List;
  20 +
  21 +/**
  22 + * gps 到离站判断
  23 + * Created by panzhao on 2016/12/24.
  24 + */
  25 +@Component
  26 +public class GpsArrival implements ApplicationContextAware {
  27 +
  28 + static Logger logger = LoggerFactory.getLogger(GpsArrival.class);
  29 +
  30 + static DayOfSchedule dayOfSchedule;
  31 +
  32 + static LineConfigData lineConfigData;
  33 +
  34 + public static void arrival(GpsEntity gps) {
  35 +
  36 + if (gps.getLat() == 0 || gps.getLon() == 0) {
  37 + //logger.error("无效的gps");
  38 + return;
  39 + }
  40 +
  41 + Object task = DayOfSchedule.executeCurr(gps.getNbbm());
  42 + if (task == null)
  43 + return;
  44 + if (task.getClass().isAssignableFrom(ScheduleRealInfo.class)) {
  45 + ScheduleRealInfo sch = (ScheduleRealInfo) task;
  46 + //和班次同步走向
  47 + gps.setUpDown(Integer.parseInt(sch.getXlDir()));
  48 +
  49 + //出场
  50 + if (sch.getBcType().equals("out")) {
  51 + outCarpark(gps, sch);
  52 + }
  53 + else if (sch.getBcType().equals("normal"))
  54 + normalInOut(gps, sch);
  55 + else if(sch.getBcType().equals("in")){
  56 + inCarpark(gps, sch);
  57 + }
  58 + }
  59 +
  60 + GeoCacheData.putGps(gps);
  61 + }
  62 +
  63 + /**
  64 + * 正常班次
  65 + *
  66 + * @param gps
  67 + * @param sch
  68 + */
  69 + private static void normalInOut(GpsEntity gps, ScheduleRealInfo sch) {
  70 + CircleQueue<GpsEntity> queue = GeoCacheData.getGps(gps.getNbbm());
  71 + GpsEntity prev = null;
  72 + if (queue != null)
  73 + prev = queue.getTail();
  74 +
  75 + List<StationRoute> srs = GeoCacheData.getStationRoute(sch.getXlBm(), gps.getUpDown());
  76 + StationRoute station = GeoUtils.gpsInStation(gps, srs);
  77 +
  78 + if (station != null) {
  79 + //站内
  80 + gps.setStopNo(station.getCode());
  81 + gps.setInstation(true);
  82 + stationInside(gps, prev, sch);
  83 + } else {
  84 + //站外
  85 + stationOutside(gps, prev, sch);
  86 + }
  87 + }
  88 +
  89 + /**
  90 + * GPS在站点内
  91 + *
  92 + * @param gps
  93 + * @param prev
  94 + * @param sch
  95 + */
  96 + private static void stationInside(GpsEntity gps, GpsEntity prev, ScheduleRealInfo sch) {
  97 + if(prev == null)
  98 + return;
  99 +
  100 + if (gps.getStopNo().equals(sch.getZdzCode()) && sch.getZdsjActual() == null) {
  101 + //到终点站
  102 + arriveEnd(sch, gps);
  103 + return;
  104 + }
  105 +
  106 + //上一个点在站外
  107 + if(!prev.isInstation())
  108 + return;
  109 + //超过 (待发时间 + 90%的单程运送时间),还在起点站。默认烂一圈
  110 + if (prev.getStopNo().equals(gps.getStopNo())){
  111 + if(gps.getStopNo().equals(sch.getQdzCode())
  112 + && gps.getTimestamp() > sch.getDfsjT() + (sch.getBcsj() * 60 * 1000 * 0.9)){
  113 +
  114 + ScheduleRealInfo next = dayOfSchedule.next(dayOfSchedule.next(sch));
  115 + dayOfSchedule.addExecPlan(next);
  116 + }
  117 + return;
  118 + }
  119 +
  120 + //发车
  121 + if (prev.getStopNo().equals(sch.getQdzCode())) {
  122 + busWillDepart(sch, gps);
  123 + return;
  124 + }
  125 +
  126 + //中途站
  127 + StationRoute prevStation = GeoCacheData.getStation(prev.getLineId(), prev.getUpDown(), prev.getStopNo());
  128 + StationRoute currStation = GeoCacheData.getStation(gps.getLineId(), gps.getUpDown(), gps.getStopNo());
  129 + if (currStation.getRouteSort() < prevStation.getRouteSort()) {
  130 + //开始下一个班次
  131 + finishPlan(sch);
  132 +
  133 + logger.info("路由反向。。。。。。:" + gps.getTimestamp());
  134 + //为班次补上实际时间
  135 +
  136 + }
  137 + }
  138 +
  139 + /**
  140 + * GPS在站点外
  141 + *
  142 + * @param gps
  143 + * @param prev
  144 + * @param sch
  145 + */
  146 + private static void stationOutside(GpsEntity gps, GpsEntity prev, ScheduleRealInfo sch) {
  147 + if(prev == null)
  148 + return;
  149 +
  150 + gps.setStopNo(prev.getStopNo());
  151 + if (prev.isInstation() && prev.getStopNo().equals(sch.getQdzCode())) {
  152 + //发车
  153 + busWillDepart(sch, gps);
  154 + return;
  155 + }
  156 + }
  157 +
  158 + /**
  159 + * 公交车起点发出
  160 + */
  161 + final static long DRIFT_VAL_TIME = 1000 * 60 * 10;
  162 + //班次最大差值1小时
  163 + final static long MAX_DIFF = 1000 * 60 * 60;
  164 + private static void busWillDepart(ScheduleRealInfo sch, GpsEntity gps) {
  165 + //实发时间不覆盖
  166 + if (sch.getFcsjActual() == null && Math.abs(gps.getTimestamp() - sch.getDfsjT()) < MAX_DIFF) {
  167 +
  168 + //提前10分钟以上发出,判断一下是否是漂移
  169 + if(sch.getDfsjT() - gps.getTimestamp() > DRIFT_VAL_TIME){
  170 + ScheduleRealInfo schPrev = dayOfSchedule.prev(sch);
  171 + if(schPrev != null && schPrev.getZdsjActual() != null){
  172 + //计划停站时间
  173 + long stopTimeJH = sch.getDfsjT() - schPrev.getZdsjT();
  174 + //实际停站时间
  175 + long actualStopTime = gps.getTimestamp() - schPrev.getZdsjActualTime();
  176 + /*
  177 + 没停够计划百分之60的,算漂移
  178 + (这里出现的误判,由程序在车辆到中途站的时候进行补偿)
  179 + */
  180 + if(stopTimeJH * 0.6 < actualStopTime){
  181 + logger.info("漂移.... 车辆:" + gps.getNbbm() + " ts: " + gps.getTimestamp());
  182 + return;
  183 + }
  184 + }
  185 + }
  186 +
  187 + LineConfig config = lineConfigData.get(sch.getXlBm());
  188 + if(config != null && config.getOutConfig() == 2){
  189 + //出站既出场
  190 + ScheduleRealInfo schPrev = dayOfSchedule.prev(sch);
  191 + if(schPrev.getBcType().equals("out")){
  192 + schPrev.setFcsjActualAll(schPrev.getDfsjT());
  193 + schPrev.setZdsjActualAll(schPrev.getZdsjT());
  194 + }
  195 + }
  196 +
  197 + sch.setFcsjActualAll(gps.getTimestamp());
  198 + logger.info("(站外)班次:" + sch.getDfsj() + "发车, 时间:" + sch.getFcsjActual());
  199 + }
  200 + }
  201 +
  202 + /**
  203 + * 公交车到达终点
  204 + *
  205 + * @param sch
  206 + * @param gps
  207 + */
  208 + private static void arriveEnd(ScheduleRealInfo sch, GpsEntity gps) {
  209 + sch.setZdsjActualAll(gps.getTimestamp());
  210 + ScheduleRealInfo next = finishPlan(sch);
  211 + logger.info("班次:" + sch.getDfsj() + "到达终点, 时间:" + sch.getZdsjActual());
  212 +
  213 + if (next == null)
  214 + return;
  215 +
  216 + //将gps转换为下一个班次走向的站内信号
  217 + int updown = Integer.parseInt(next.getXlDir());
  218 + List<StationRoute> srs = GeoCacheData.getStationRoute(next.getXlBm(), updown);
  219 + StationRoute station = GeoUtils.gpsInStation(gps, srs);
  220 + if (station != null) {
  221 + gps.setUpDown(updown);
  222 + gps.setStopNo(station.getCode());
  223 + }
  224 + }
  225 +
  226 + /**
  227 + * 出场班次
  228 + *
  229 + * @param gps
  230 + * @param sch
  231 + */
  232 + private static void outCarpark(GpsEntity gps, ScheduleRealInfo sch) {
  233 + String carpark = GeoUtils.gpsInCarpark(gps);
  234 + if (carpark != null) {
  235 + gps.setInstation(true);
  236 + gps.setStopNo(carpark);
  237 + return; // 还在场内
  238 + }
  239 +
  240 + CircleQueue<GpsEntity> queue = GeoCacheData.getGps(gps.getNbbm());
  241 + if (queue == null)
  242 + return;
  243 + //上一个gps
  244 + GpsEntity prev = queue.getTail();
  245 +
  246 + if (carpark == null && prev.isInstation() && prev.getStopNo().equals(sch.getQdzCode())) {
  247 + gps.setStopNo(prev.getStopNo());
  248 + //停车场发出
  249 + busWillDepart(sch, gps);
  250 + return;
  251 + }
  252 +
  253 + List<StationRoute> srs = GeoCacheData.getStationRoute(sch.getXlBm(), gps.getUpDown());
  254 + StationRoute station = GeoUtils.gpsInStation(gps, srs);
  255 +
  256 + if (station != null && station.getCode().equals(sch.getZdzCode())) {
  257 + gps.setStopNo(station.getCode());
  258 + //到达终点
  259 + arriveEnd(sch, gps);
  260 + }
  261 + }
  262 +
  263 +
  264 + /**
  265 + * 进场班次
  266 + * @param gps
  267 + * @param sch
  268 + */
  269 + private static void inCarpark(GpsEntity gps, ScheduleRealInfo sch) {
  270 + String carpark = GeoUtils.gpsInCarpark(gps);
  271 + if (carpark != null && carpark.equals(sch.getZdzCode())) {
  272 + //进场班次取第一个实际进场时间
  273 + if(sch.getZdsjActual() != null)
  274 + return;
  275 +
  276 + //进场
  277 + arriveEnd(sch, gps);
  278 + return;
  279 + }
  280 +
  281 + CircleQueue<GpsEntity> queue = GeoCacheData.getGps(gps.getNbbm());
  282 + if (queue == null)
  283 + return;
  284 + //上一个gps
  285 + GpsEntity prev = queue.getTail();
  286 +
  287 + if (carpark == null && prev.isInstation() && prev.getStopNo().equals(sch.getQdzCode())) {
  288 + gps.setStopNo(prev.getStopNo());
  289 + //进场班次发出
  290 + busWillDepart(sch, gps);
  291 + return;
  292 + }
  293 + }
  294 +
  295 + /**
  296 + * 完成班次 -返回下一个班次
  297 + *
  298 + * @param sch
  299 + */
  300 + private static ScheduleRealInfo finishPlan(ScheduleRealInfo sch) {
  301 + ScheduleRealInfo next = dayOfSchedule.next(sch);
  302 + if (next != null) {
  303 + next.setQdzArrDatesj(sch.getZdsjActual());
  304 + dayOfSchedule.addExecPlan(next);
  305 + }
  306 + return next;
  307 + }
  308 +
  309 + @Override
  310 + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  311 + dayOfSchedule = applicationContext.getBean(DayOfSchedule.class);
  312 + lineConfigData = applicationContext.getBean(LineConfigData.class);
  313 + }
  314 +}
src/main/java/com/bsth/data/gpsdata/analyse/components/GpsStateCorrective.java 0 → 100644
  1 +package com.bsth.data.gpsdata.analyse.components;
  2 +
  3 +import com.bsth.data.gpsdata.GpsEntity;
  4 +import com.bsth.data.schedule.DayOfSchedule;
  5 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  6 +import com.vividsolutions.jts.geom.GeometryFactory;
  7 +import org.joda.time.format.DateTimeFormat;
  8 +import org.joda.time.format.DateTimeFormatter;
  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.stereotype.Component;
  15 +
  16 +/**
  17 + * GPS状态纠正
  18 + * Created by panzhao on 2016/12/23.
  19 + */
  20 +@Component
  21 +public class GpsStateCorrective implements ApplicationContextAware {
  22 +
  23 + static Logger logger = LoggerFactory.getLogger(GpsStateCorrective.class);
  24 +
  25 + static DayOfSchedule dayOfSchedule;
  26 +
  27 + private static GeometryFactory geometryFactory = new GeometryFactory();
  28 +
  29 + public static void correct(GpsEntity gps, ScheduleRealInfo sch){
  30 +/* int upDown = Integer.parseInt(sch.getXlDir());
  31 + gps.setUpDown(upDown);
  32 + List<StationRoute> srs = GeoCacheData.getStationRoute(sch.getXlBm(), upDown);
  33 +
  34 + Point point = geometryFactory.createPoint(new Coordinate(gps.getLat(), gps.getLon()));
  35 +
  36 + //之前的点位
  37 + CircleQueue<GpsEntity> queue = GeoCacheData.getGps(gps.getNbbm());
  38 + GpsEntity prev = null;
  39 + if(queue != null)
  40 + prev = queue.getTail();
  41 +
  42 + //线路上,站点间
  43 + StationRoute station = GeoUtils.pointInStation(point, srs);
  44 + //在站内
  45 + if(station != null){
  46 + gps.setStopNo(station.getCode());
  47 + gps.setInstation(true);
  48 + gps.setStation(station);
  49 +
  50 + if(prev != null && prev.getUpDown() == upDown){
  51 + StationRoute prevStation = GeoCacheData.getStation(prev.getLineId(), upDown, prev.getStopNo());
  52 +
  53 + //倒着开??
  54 + if(prevStation.getRouteSort() > station.getRouteSort()){
  55 + reversalHandle(gps, prev, sch);
  56 + }
  57 + }
  58 + }
  59 + else{
  60 + if(prev != null)
  61 + gps.setStopNo(prev.getStopNo());
  62 + }
  63 +
  64 + //是否在停车场内
  65 + Map<String, Polygon> carparkMap = GeoCacheData.tccMap;
  66 + Set<String> codes = carparkMap.keySet();
  67 + Polygon p;
  68 + for(String code : codes){
  69 + p = carparkMap.get(code);
  70 + //场内
  71 + if(p.contains(point)){
  72 + gps.setCarparkNo(code);
  73 + if(sch.getBcType().equals("out")){
  74 + gps.setInstation(true);
  75 + gps.setStopNo(code);
  76 + }
  77 + }
  78 + }*/
  79 + }
  80 +
  81 + private static DateTimeFormatter fmt = DateTimeFormat.forPattern("HH:mm");
  82 +
  83 + private static void reversalHandle(GpsEntity gps, GpsEntity prev, ScheduleRealInfo sch){
  84 + /*if(sch.getBcType().equals("out") && gps.getTimestamp() < sch.getZdsjT())
  85 + return;
  86 +
  87 + //先假设没到终点,直接开始了下一个班次
  88 + ScheduleRealInfo next = dayOfSchedule.next(sch);
  89 + String log = "倒着开??? nbbm: " + gps.getNbbm() + " 当前:" + gps.getStopNo() + " 上一站:" + prev.getStopNo() + " 当前班次:" + sch.getDfsj();
  90 + if(next != null){
  91 + dayOfSchedule.addExecPlan(next);
  92 +
  93 + log += (" 下一个班次:" + next.getDfsj());
  94 + }
  95 +
  96 + log += (" GPS时间:" + fmt.print(gps.getTimestamp()));
  97 +
  98 + logger.info(log);*/
  99 + }
  100 +
  101 + @Override
  102 + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  103 + dayOfSchedule = applicationContext.getBean(DayOfSchedule.class);
  104 + }
  105 +}
src/main/java/com/bsth/data/gpsdata/analyse/util/GeoUtils.java 0 → 100644
  1 +package com.bsth.data.gpsdata.analyse.util;
  2 +
  3 +import com.bsth.data.gpsdata.GpsEntity;
  4 +import com.bsth.data.gpsdata.analyse.GeoCacheData;
  5 +import com.bsth.data.gpsdata.analyse.StationRoute;
  6 +import com.vividsolutions.jts.geom.Coordinate;
  7 +import com.vividsolutions.jts.geom.GeometryFactory;
  8 +import com.vividsolutions.jts.geom.Point;
  9 +import com.vividsolutions.jts.geom.Polygon;
  10 +
  11 +import java.util.List;
  12 +import java.util.Map;
  13 +import java.util.Set;
  14 +
  15 +/**
  16 + * Created by panzhao on 2016/12/23.
  17 + */
  18 +public class GeoUtils {
  19 +
  20 + private final static double EARTHRADIUS = 6378137;
  21 +
  22 + private static GeometryFactory geometryFactory = new GeometryFactory();
  23 + /**
  24 + * gps是否在路由上的某个站内
  25 + *
  26 + * @param gps
  27 + * @param srs
  28 + * @return
  29 + */
  30 + public static StationRoute gpsInStation(GpsEntity gps, List<StationRoute> srs) {
  31 + Point point = geometryFactory.createPoint(new Coordinate(gps.getLat(), gps.getLon()));
  32 + double min = -1, distance, distance2;
  33 + StationRoute stationRoute = null;
  34 +
  35 + for (StationRoute sr : srs) {
  36 + if (sr.getPolygon() == null) {
  37 + //圆形
  38 + distance = getDistance(sr.getPoint(), point);//sr.getPoint().distance(point);
  39 +
  40 + if (distance > sr.getRadius())
  41 + continue;
  42 +
  43 + if (min > distance || min == -1) {
  44 + min = distance;
  45 + stationRoute = sr;
  46 + }
  47 + } else {
  48 + //多边形
  49 + if (sr.getPolygon().contains(point)) {
  50 + stationRoute = sr;
  51 + break;
  52 + }
  53 + }
  54 + }
  55 + return stationRoute;
  56 + }
  57 +
  58 + public static double getDistance(Point p1, Point p2) {
  59 + double lng1 = getLoop(p1.getY(), -180, 180), lat1 = getRange(
  60 + p1.getX(), -74, 74);
  61 + double lng2 = getLoop(p2.getY(), -180, 180), lat2 = getRange(
  62 + p2.getX(), -74, 74);
  63 +
  64 + double x1, x2, y1, y2;
  65 + x1 = degreeToRad(lng1);
  66 + y1 = degreeToRad(lat1);
  67 + x2 = degreeToRad(lng2);
  68 + y2 = degreeToRad(lat2);
  69 + return EARTHRADIUS
  70 + * Math.acos((Math.sin(y1) * Math.sin(y2) + Math.cos(y1)
  71 + * Math.cos(y2) * Math.cos(x2 - x1)));
  72 + }
  73 +
  74 + private static double getLoop(double v, double a, double b) {
  75 + while (v > b) {
  76 + v -= b - a;
  77 + }
  78 + while (v < a) {
  79 + v += b - a;
  80 + }
  81 + return v;
  82 + }
  83 +
  84 + private static double getRange(double v, double a, double b) {
  85 + v = Math.min(Math.max(v, a), b);
  86 + return v;
  87 + }
  88 +
  89 + private static double degreeToRad(double degree) {
  90 + return Math.PI * degree / 180;
  91 + }
  92 +
  93 +
  94 + /**
  95 + * gps 是否在某个停车场内
  96 + * @param gps
  97 + * @return
  98 + */
  99 + public static String gpsInCarpark(GpsEntity gps){
  100 + Point point = geometryFactory.createPoint(new Coordinate(gps.getLat(), gps.getLon()));
  101 +
  102 + Map<String, Polygon> carparkMap = GeoCacheData.tccMap;
  103 + Set<String> codes = carparkMap.keySet();
  104 + Polygon polygon;
  105 + for(String code : codes){
  106 + polygon = carparkMap.get(code);
  107 + if(point.within(polygon)){
  108 + return code;
  109 + }
  110 + }
  111 + return null;
  112 + }
  113 +
  114 + /**
  115 + * 是否是有效的连续点
  116 + * @param prevGps
  117 + * @param gps
  118 + * @return
  119 + */
  120 + public static boolean overdue(GpsEntity prevGps, GpsEntity gps) {
  121 + return gps.getTimestamp() - prevGps.getTimestamp() < 120000;
  122 + }
  123 +}
src/main/java/com/bsth/data/gpsdata/recovery/GpsDataRecovery.java 0 → 100644
  1 +package com.bsth.data.gpsdata.recovery;
  2 +
  3 +import com.bsth.data.BasicData;
  4 +import com.bsth.data.gpsdata.GpsEntity;
  5 +import com.bsth.data.gpsdata.analyse.components.GpsArrival;
  6 +import com.bsth.util.db.DBUtils_MS;
  7 +import com.google.common.collect.ArrayListMultimap;
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +import org.springframework.jdbc.core.JdbcTemplate;
  11 +import org.springframework.jdbc.core.RowMapper;
  12 +
  13 +import java.sql.ResultSet;
  14 +import java.sql.SQLException;
  15 +import java.util.*;
  16 +import java.util.concurrent.CountDownLatch;
  17 +import java.util.concurrent.ExecutorService;
  18 +import java.util.concurrent.Executors;
  19 +
  20 +/**
  21 + * 数据恢复
  22 + * Created by panzhao on 2016/12/24.
  23 + */
  24 +public class GpsDataRecovery {
  25 +
  26 + static Logger logger = LoggerFactory.getLogger(GpsDataRecovery.class);
  27 +
  28 + public static boolean run;
  29 +
  30 + static ExecutorService threadPool = Executors.newFixedThreadPool(50);
  31 +
  32 + private static CountDownLatch count;
  33 +
  34 + public static void recovery() {
  35 + List<GpsEntity> list = loadData();
  36 +
  37 + //按车辆分组数据
  38 + ArrayListMultimap<String, GpsEntity> listMap = ArrayListMultimap.create();
  39 + for (GpsEntity gps : list) {
  40 + if(gps.getNbbm() != null)
  41 + listMap.put(gps.getNbbm(), gps);
  42 + }
  43 +
  44 + count = new CountDownLatch(listMap.keySet().size());
  45 +
  46 + Set<String> keys = listMap.keySet();
  47 + for (String nbbm : keys) {
  48 + threadPool.execute(new RecoveryDataThread(listMap.get(nbbm), count));
  49 + /*if(nbbm.equals("W9A-250"))
  50 + new RecoveryDataThread(listMap.get(nbbm), count).run();*/
  51 + }
  52 + try {
  53 + //等待子线程结束
  54 + count.await();
  55 + logger.info("GPS 数据恢复完成....");
  56 + } catch (InterruptedException e) {
  57 + logger.error("", e);
  58 + }
  59 + }
  60 +
  61 + /**
  62 + * 加载当天的gps数据
  63 + *
  64 + * @return
  65 + */
  66 + public static List<GpsEntity> loadData() {
  67 + Calendar calendar = Calendar.getInstance();
  68 + int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
  69 +
  70 + String sql = "select DEVICE_ID,LAT,LON,TS,SPEED_GPS,LINE_ID,SERVICE_STATE from BSTH_C_GPS_INFO where days_year=" + dayOfYear;
  71 + JdbcTemplate jdbcTemplate = new JdbcTemplate(DBUtils_MS.getDataSource());
  72 +
  73 + List<GpsEntity> list =
  74 + jdbcTemplate.query(sql, new RowMapper<GpsEntity>() {
  75 + @Override
  76 + public GpsEntity mapRow(ResultSet rs, int rowNum) throws SQLException {
  77 + GpsEntity gps = new GpsEntity();
  78 +
  79 + gps.setDeviceId(rs.getString("DEVICE_ID"));
  80 + gps.setNbbm(BasicData.deviceId2NbbmMap.get(gps.getDeviceId()));
  81 + gps.setSpeed(rs.getFloat("SPEED_GPS"));
  82 + gps.setLat(rs.getFloat("LAT"));
  83 + gps.setLon(rs.getFloat("LON"));
  84 + gps.setLineId(rs.getString("LINE_ID"));
  85 + gps.setTimestamp(rs.getLong("TS"));
  86 + gps.setUpDown(getUpOrDown(rs.getLong("SERVICE_STATE")));
  87 + return gps;
  88 + }
  89 + });
  90 + return list;
  91 + }
  92 +
  93 + /**
  94 + * 王通 2016/6/29 9:23:24 获取车辆线路上下行
  95 + *
  96 + * @return -1无效 0上行 1下行
  97 + */
  98 + public static int getUpOrDown(long serviceState) {
  99 + if ((serviceState & 0x00020000) == 0x00020000 || (serviceState & 0x80000000) == 0x80000000
  100 + || (serviceState & 0x01000000) == 0x01000000 || (serviceState & 0x08000000) == 0x08000000)
  101 + return -1;
  102 + return (((serviceState & 0x10000000) == 0x10000000) ? 1 : 0);
  103 + }
  104 +
  105 + public static class RecoveryDataThread implements Runnable {
  106 +
  107 + List<GpsEntity> list;
  108 + CountDownLatch count;
  109 +
  110 + public RecoveryDataThread(List<GpsEntity> list, CountDownLatch count) {
  111 + this.list = list;
  112 + this.count = count;
  113 + }
  114 +
  115 + @Override
  116 + public void run() {
  117 + try {
  118 + //排序
  119 + Collections.sort(list, new GpsComp());
  120 + //依次跑完gps
  121 + //int i = 0;
  122 + for(GpsEntity gps : list){
  123 + /* i++;
  124 + if(i == 383){
  125 + System.out.println("aaa");
  126 + }*/
  127 + GpsArrival.arrival(gps);
  128 + }
  129 + } catch (Exception e) {
  130 + logger.error("", e);
  131 + } finally {
  132 + count.countDown();
  133 + }
  134 + }
  135 + }
  136 +
  137 + public static class GpsComp implements Comparator<GpsEntity>{
  138 +
  139 + @Override
  140 + public int compare(GpsEntity g1, GpsEntity g2) {
  141 + return (int) (g1.getTimestamp() - g2.getTimestamp());
  142 + }
  143 + }
  144 +}
src/main/java/com/bsth/data/schedule/DayOfSchedule.java
@@ -3,9 +3,11 @@ package com.bsth.data.schedule; @@ -3,9 +3,11 @@ package com.bsth.data.schedule;
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONArray; 4 import com.alibaba.fastjson.JSONArray;
5 import com.bsth.Application; 5 import com.bsth.Application;
  6 +import com.bsth.data.BasicData;
6 import com.bsth.data.LineConfigData; 7 import com.bsth.data.LineConfigData;
7 import com.bsth.data.directive.FirstScheduleCheckThread; 8 import com.bsth.data.directive.FirstScheduleCheckThread;
8 import com.bsth.data.gpsdata.GpsRealData; 9 import com.bsth.data.gpsdata.GpsRealData;
  10 +import com.bsth.data.gpsdata.recovery.GpsDataRecovery;
9 import com.bsth.data.schedule.thread.ScheduleLateThread; 11 import com.bsth.data.schedule.thread.ScheduleLateThread;
10 import com.bsth.data.schedule.thread.SchedulePstThread; 12 import com.bsth.data.schedule.thread.SchedulePstThread;
11 import com.bsth.data.schedule.thread.ScheduleRefreshThread; 13 import com.bsth.data.schedule.thread.ScheduleRefreshThread;
@@ -111,19 +113,30 @@ public class DayOfSchedule implements CommandLineRunner { @@ -111,19 +113,30 @@ public class DayOfSchedule implements CommandLineRunner {
111 @Autowired 113 @Autowired
112 SubmitToTrafficManage submitToTrafficManage; 114 SubmitToTrafficManage submitToTrafficManage;
113 115
  116 + @Autowired
  117 + LineConfigData lineConfigs;
  118 +
  119 + @Autowired
  120 + BasicData.BasicDataLoader dataLoader;
  121 +
114 private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd") 122 private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd")
115 ,fmtHHmm = DateTimeFormat.forPattern("HH:mm"); 123 ,fmtHHmm = DateTimeFormat.forPattern("HH:mm");
116 124
117 @Override 125 @Override
118 public void run(String... arg0) throws Exception { 126 public void run(String... arg0) throws Exception {
  127 + //加载基础数据
  128 + dataLoader.loadAllData();
  129 + //从数据库恢复排班
  130 + //dataRecovery();
  131 +
119 //翻班线程 132 //翻班线程
120 Application.mainServices.scheduleWithFixedDelay(scheduleRefreshThread, 15, 240, TimeUnit.SECONDS); 133 Application.mainServices.scheduleWithFixedDelay(scheduleRefreshThread, 15, 240, TimeUnit.SECONDS);
121 //入库 134 //入库
122 -// Application.mainServices.scheduleWithFixedDelay(schedulePstThread, 60, 60, TimeUnit.SECONDS); 135 + Application.mainServices.scheduleWithFixedDelay(schedulePstThread, 60, 60, TimeUnit.SECONDS);
123 //首班出场指令补发器 136 //首班出场指令补发器
124 // Application.mainServices.scheduleWithFixedDelay(firstScheduleCheckThread, 30, 240, TimeUnit.SECONDS); 137 // Application.mainServices.scheduleWithFixedDelay(firstScheduleCheckThread, 30, 240, TimeUnit.SECONDS);
125 //班次误点扫描 138 //班次误点扫描
126 -// Application.mainServices.scheduleWithFixedDelay(scheduleLateThread, 60, 60, TimeUnit.SECONDS); 139 + Application.mainServices.scheduleWithFixedDelay(scheduleLateThread, 60, 60, TimeUnit.SECONDS);
127 140
128 //每天凌晨2点20提交数据到运管处 141 //每天凌晨2点20提交数据到运管处
129 long diff = (DateUtils.getTimestamp() + 1000*60*140) - System.currentTimeMillis(); 142 long diff = (DateUtils.getTimestamp() + 1000*60*140) - System.currentTimeMillis();
@@ -134,6 +147,23 @@ public class DayOfSchedule implements CommandLineRunner { @@ -134,6 +147,23 @@ public class DayOfSchedule implements CommandLineRunner {
134 //Application.mainServices.scheduleWithFixedDelay(submitToTrafficManage, diff / 1000, 60 * 60 * 24, TimeUnit.SECONDS); 147 //Application.mainServices.scheduleWithFixedDelay(submitToTrafficManage, diff / 1000, 60 * 60 * 24, TimeUnit.SECONDS);
135 } 148 }
136 149
  150 + //数据恢复
  151 + private void dataRecovery() {
  152 + GpsDataRecovery.run = true;
  153 +
  154 + Collection<LineConfig> confs = lineConfigs.getAll();
  155 + String lineCode, currSchDate;
  156 + for(LineConfig conf : confs){
  157 + lineCode = conf.getLine().getLineCode();
  158 + currSchDate = calcSchDate(lineCode);
  159 + //加载班次数据
  160 + reloadSch(lineCode, currSchDate, false);
  161 + }
  162 +
  163 + //恢复gps数据
  164 + GpsDataRecovery.recovery();
  165 + }
  166 +
137 public Map<String, String> getCurrSchDate() { 167 public Map<String, String> getCurrSchDate() {
138 return currSchDateMap; 168 return currSchDateMap;
139 } 169 }
@@ -189,17 +219,20 @@ public class DayOfSchedule implements CommandLineRunner { @@ -189,17 +219,20 @@ public class DayOfSchedule implements CommandLineRunner {
189 putAll(list); 219 putAll(list);
190 220
191 Set<String> cars = searchAllCars(list); 221 Set<String> cars = searchAllCars(list);
192 - //计算“起点站应到”时间  
193 - for(String nbbm : cars) 222 + for(String nbbm : cars){
  223 + //计算“起点站应到”时间
194 schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm)); 224 schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm));
195 - 225 + //车辆 ——> 要执行的班次对照
  226 + carExecutePlanMap.put(nbbm, schAttrCalculator.calcCurrentExecSch(nbbmScheduleMap.get(nbbm)));
  227 + }
  228 +
196 //是否是出站即出场 229 //是否是出站即出场
197 LineConfig conf = lineConfigData.get(lineCode); 230 LineConfig conf = lineConfigData.get(lineCode);
198 if(conf.getOutConfig() == 2){ 231 if(conf.getOutConfig() == 2){
199 for(String nbbm : cars) 232 for(String nbbm : cars)
200 schAttrCalculator.connectOutSchedule(nbbmScheduleMap.get(nbbm)); 233 schAttrCalculator.connectOutSchedule(nbbmScheduleMap.get(nbbm));
201 } 234 }
202 - 235 +
203 // 页面 翻班通知 236 // 页面 翻班通知
204 sendUtils.shiftSchedule(lineCode); 237 sendUtils.shiftSchedule(lineCode);
205 } catch (Exception e) { 238 } catch (Exception e) {
@@ -451,6 +484,10 @@ public class DayOfSchedule implements CommandLineRunner { @@ -451,6 +484,10 @@ public class DayOfSchedule implements CommandLineRunner {
451 public ScheduleRealInfo next(ScheduleRealInfo sch) { 484 public ScheduleRealInfo next(ScheduleRealInfo sch) {
452 485
453 List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh()); 486 List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  487 + int outConfig = -1;
  488 + LineConfig config = lineConfigData.get(sch.getXlBm());
  489 + if(config != null)
  490 + outConfig = config.getOutConfig();
454 491
455 boolean flag = false; 492 boolean flag = false;
456 ScheduleRealInfo next = null; 493 ScheduleRealInfo next = null;
@@ -462,6 +499,10 @@ public class DayOfSchedule implements CommandLineRunner { @@ -462,6 +499,10 @@ public class DayOfSchedule implements CommandLineRunner {
462 //忽略烂班 499 //忽略烂班
463 if(temp.isDestroy()) 500 if(temp.isDestroy())
464 continue; 501 continue;
  502 +
  503 + //出站既出场,忽略出场班次
  504 + if(outConfig == 2 && temp.getBcType().equals("out"))
  505 + continue;
465 506
466 if(flag){ 507 if(flag){
467 next = temp; 508 next = temp;
@@ -471,6 +512,30 @@ public class DayOfSchedule implements CommandLineRunner { @@ -471,6 +512,30 @@ public class DayOfSchedule implements CommandLineRunner {
471 return next; 512 return next;
472 } 513 }
473 514
  515 + /**
  516 + * 上一个班次
  517 + * @param sch
  518 + * @return
  519 + */
  520 + public ScheduleRealInfo prev(ScheduleRealInfo sch){
  521 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  522 +
  523 + //boolean flag = false;
  524 + ScheduleRealInfo prev = null;
  525 + int size = list.size();
  526 +
  527 + for(int i = 0; i < size; i ++){
  528 + if(list.get(i).isDestroy())
  529 + continue;
  530 +
  531 + if(list.get(i).getId().equals(sch.getId())){
  532 + return prev;
  533 + }
  534 + prev = list.get(i);
  535 + }
  536 + return prev;
  537 + }
  538 +
474 public void put(ScheduleRealInfo sch) { 539 public void put(ScheduleRealInfo sch) {
475 schAttrCalculator 540 schAttrCalculator
476 .calcRealDate(sch) 541 .calcRealDate(sch)
@@ -666,9 +731,18 @@ public class DayOfSchedule implements CommandLineRunner { @@ -666,9 +731,18 @@ public class DayOfSchedule implements CommandLineRunner {
666 carExecutePlanMap.remove(clzbh); 731 carExecutePlanMap.remove(clzbh);
667 } 732 }
668 733
669 - public Map<String, ScheduleRealInfo> execPlamMap(){ 734 + public Map<String, ScheduleRealInfo> execPlanMap(){
670 return carExecutePlanMap; 735 return carExecutePlanMap;
671 } 736 }
  737 +
  738 + /**
  739 + * 车辆当前执行的班次
  740 + * @param nbbm
  741 + * @return
  742 + */
  743 + public static ScheduleRealInfo executeCurr(String nbbm){
  744 + return carExecutePlanMap.get(nbbm);
  745 + }
672 746
673 /** 747 /**
674 * @Title: changeCar 748 * @Title: changeCar
src/main/java/com/bsth/data/schedule/SchAttrCalculator.java
@@ -215,4 +215,30 @@ public class SchAttrCalculator { @@ -215,4 +215,30 @@ public class SchAttrCalculator {
215 if(sch.getZdsjActualTime() == null && sch.getZdsjActual() != null) 215 if(sch.getZdsjActualTime() == null && sch.getZdsjActual() != null)
216 sch.setZdsjActualAll(sch.getZdsjActual()); 216 sch.setZdsjActualAll(sch.getZdsjActual());
217 } 217 }
  218 +
  219 + /**
  220 + * 计算当前要执行的班次
  221 + * @param list
  222 + * @return
  223 + */
  224 + public ScheduleRealInfo calcCurrentExecSch(List<ScheduleRealInfo> list){
  225 + String lineCode = list.get(0).getXlBm();
  226 + LineConfig conf = lineConfigData.get(lineCode);
  227 + int outConfig = -1;
  228 + if(conf != null)
  229 + outConfig = conf.getOutConfig();
  230 +
  231 + for(ScheduleRealInfo sch : list){
  232 + //如果是出站既出场,忽略出场班次
  233 + if(outConfig == 2 && sch.getBcType().equals("out"))
  234 + continue;
  235 +
  236 + //已执行
  237 + if(StringUtils.isNotEmpty(sch.getZdsjActual()))
  238 + continue;
  239 +
  240 + return sch;
  241 + }
  242 + return null;
  243 + }
218 } 244 }
src/main/java/com/bsth/data/schedule/thread/ScheduleRefreshThread.java
1 package com.bsth.data.schedule.thread; 1 package com.bsth.data.schedule.thread;
2 2
3 -import java.util.Collection;  
4 -import java.util.Set;  
5 -  
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 com.bsth.data.BasicData; 3 import com.bsth.data.BasicData;
12 import com.bsth.data.LineConfigData; 4 import com.bsth.data.LineConfigData;
13 import com.bsth.data.arrival.ArrivalData_GPS; 5 import com.bsth.data.arrival.ArrivalData_GPS;
@@ -15,6 +7,13 @@ import com.bsth.data.directive.DayOfDirectives; @@ -15,6 +7,13 @@ import com.bsth.data.directive.DayOfDirectives;
15 import com.bsth.data.pilot80.PilotReport; 7 import com.bsth.data.pilot80.PilotReport;
16 import com.bsth.data.schedule.DayOfSchedule; 8 import com.bsth.data.schedule.DayOfSchedule;
17 import com.bsth.entity.realcontrol.LineConfig; 9 import com.bsth.entity.realcontrol.LineConfig;
  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.Collection;
  16 +import java.util.Set;
18 17
19 /** 18 /**
20 * 19 *
@@ -57,6 +56,7 @@ public class ScheduleRefreshThread extends Thread{ @@ -57,6 +56,7 @@ public class ScheduleRefreshThread extends Thread{
57 currSchDate = dayOfSchedule.calcSchDate(lineCode); 56 currSchDate = dayOfSchedule.calcSchDate(lineCode);
58 57
59 if(oldSchDate == null || !oldSchDate.equals(currSchDate)){ 58 if(oldSchDate == null || !oldSchDate.equals(currSchDate)){
  59 +
60 logger.info(lineCode + "开始翻班, " + currSchDate); 60 logger.info(lineCode + "开始翻班, " + currSchDate);
61 //清除进出站数据 61 //清除进出站数据
62 arrivalData.clearRAMData(lineCode); 62 arrivalData.clearRAMData(lineCode);
src/main/java/com/bsth/entity/realcontrol/ScheduleType.java 0 → 100644
  1 +package com.bsth.entity.realcontrol;
  2 +
  3 +/**
  4 + * 班次类型
  5 + * Created by panzhao on 2016/12/23.
  6 + */
  7 +public enum ScheduleType {
  8 +
  9 + normal, //正常班次
  10 + out, //出场
  11 + in, //进场
  12 + region, //区间
  13 + venting,//直放
  14 + major //放站
  15 +}
src/main/resources/static/pages/mapmonitor/real/js/map/platform/baidu.js
@@ -57,37 +57,39 @@ var baiduMap = (function(){ @@ -57,37 +57,39 @@ var baiduMap = (function(){
57 57
58 map.clearOverlays(); 58 map.clearOverlays();
59 linePolyline = []; 59 linePolyline = [];
60 - //从localStorage里读取路由信息  
61 var upLineOps = {strokeColor:"blue", strokeWeight:6, strokeOpacity:0.5} 60 var upLineOps = {strokeColor:"blue", strokeWeight:6, strokeOpacity:0.5}
62 ,downLineOps = {strokeColor:"red", strokeWeight:6, strokeOpacity:0.5}; 61 ,downLineOps = {strokeColor:"red", strokeWeight:6, strokeOpacity:0.5};
63 62
64 - var upPos = [], downPos = [], tempArray;  
65 var route = opts.route; 63 var route = opts.route;
66 - //上行 64 + var pos,temps, polyline;
67 if(route.up){ 65 if(route.up){
68 - $.each(route.up.split(','), function(){  
69 - tempArray = this.split(' ');  
70 - upPos.push(new BMap.Point(tempArray[0], tempArray[1])); 66 + $.each(route.up_bd, function (i, item) {
  67 + pos = [];
  68 + $.each(item.split(','), function () {
  69 + temps = this.split(' ');
  70 + pos.push(new BMap.Point(temps[0], temps[1]));
  71 + });
  72 + polyline = new BMap.Polyline(pos, upLineOps);
  73 + map.addOverlay(polyline);
  74 +
  75 + linePolyline.push(polyline);
71 }); 76 });
72 77
73 - var upLine = new BMap.Polyline(upPos, upLineOps);  
74 - map.addOverlay(upLine);  
75 -  
76 - linePolyline.push(upLine);  
77 -  
78 - map.panTo(upPos[parseInt(upPos.length / 2)]); 78 + map.panTo(pos[parseInt(pos.length / 2)]);
79 } 79 }
80 - //下行 80 +
81 if(route.down){ 81 if(route.down){
82 - $.each(route.down.split(','), function(){  
83 - tempArray = this.split(' ');  
84 - downPos.push(new BMap.Point(tempArray[0], tempArray[1])); 82 + $.each(route.down_bd, function (i, item) {
  83 + pos = [];
  84 + $.each(item.split(','), function () {
  85 + temps = this.split(' ');
  86 + pos.push(new BMap.Point(temps[0], temps[1]));
  87 + });
  88 + polyline = new BMap.Polyline(pos, downLineOps);
  89 + map.addOverlay(polyline);
  90 +
  91 + linePolyline.push(polyline);
85 }); 92 });
86 -  
87 - var downLine = new BMap.Polyline(downPos, downLineOps);  
88 - map.addOverlay(downLine);  
89 -  
90 - linePolyline.push(downLine);  
91 } 93 }
92 }, 94 },
93 //绘制GPS信号 95 //绘制GPS信号
src/main/resources/static/pages/mapmonitor/real/js/map/platform/gaode.js
@@ -77,11 +77,43 @@ var gaodeMap = (function() { @@ -77,11 +77,43 @@ var gaodeMap = (function() {
77 77
78 map.clearMap(); 78 map.clearMap();
79 79
80 - var upArr = [], downArr = [];  
81 - var upLineOps = {path: upArr, strokeColor:"blue", strokeWeight:6, strokeOpacity:0.5}  
82 - ,downLineOps = {path: downArr, strokeColor:"red", strokeWeight:6, strokeOpacity:0.5}; 80 + //var upArr = [], downArr = [];
  81 + var upLineOps = {strokeColor:"blue", strokeWeight:6, strokeOpacity:0.5}
  82 + ,downLineOps = {strokeColor:"red", strokeWeight:6, strokeOpacity:0.5};
83 var route = opts.route; 83 var route = opts.route;
84 - //上行 84 +
  85 + var pos,temps;
  86 + if(route.up){
  87 + $.each(route.up_gcj, function (i, item) {
  88 + pos = [];
  89 + $.each(item.split(','), function () {
  90 + temps = this.split(' ');
  91 + pos.push([temps[0], temps[1]]);
  92 + });
  93 + upLineOps.path=pos;
  94 + var polyline = new AMap.Polyline(upLineOps);
  95 + polyline.setMap(map);
  96 +
  97 + linePolyline.push(polyline);
  98 + });
  99 + map.setCenter(pos[parseInt(pos.length / 2)]);
  100 + }
  101 +
  102 + if(route.down){
  103 + $.each(route.down_gcj, function (i, item) {
  104 + pos = [];
  105 + $.each(item.split(','), function () {
  106 + temps = this.split(' ');
  107 + pos.push([temps[0], temps[1]]);
  108 + });
  109 + downLineOps.path=pos;
  110 + var polyline = new AMap.Polyline(downLineOps);
  111 + polyline.setMap(map);
  112 +
  113 + linePolyline.push(polyline);
  114 + });
  115 + }
  116 + /*//上行
85 if(route.up){ 117 if(route.up){
86 $.each(route.up_gcj.split(','), function(){ 118 $.each(route.up_gcj.split(','), function(){
87 tempArray = this.split(' '); 119 tempArray = this.split(' ');
@@ -104,7 +136,7 @@ var gaodeMap = (function() { @@ -104,7 +136,7 @@ var gaodeMap = (function() {
104 //保存线条引用 136 //保存线条引用
105 linePolyline.push(downLine); 137 linePolyline.push(downLine);
106 downLine.setMap(map); 138 downLine.setMap(map);
107 - } 139 + }*/
108 //实时路况下不显示 140 //实时路况下不显示
109 if(traffVisible) 141 if(traffVisible)
110 hideLinePolyline(); 142 hideLinePolyline();
src/main/resources/static/real_control_v2/css/line_schedule.css
@@ -965,22 +965,32 @@ dd.fcsjActualCell div.last-sch-sunken{ @@ -965,22 +965,32 @@ dd.fcsjActualCell div.last-sch-sunken{
965 /*border-top: 1px solid #eeeeee;*/ 965 /*border-top: 1px solid #eeeeee;*/
966 } 966 }
967 967
  968 +dd.fcsjActualCell.tl-yzx div.last-sch-sunken {
  969 + background: #c1ddf0;
  970 + border-top: 1px solid #c1d3df;
  971 +}
  972 +
  973 +dd.fcsjActualCell.tl-yzx div.last-sch-sunken span._badge {
  974 + background: rgb(255, 255, 255);
  975 + color: black;
  976 +}
  977 +
968 dd.fcsjActualCell div.last-sch-sunken span._badge{ 978 dd.fcsjActualCell div.last-sch-sunken span._badge{
969 font-size: 12px; 979 font-size: 12px;
970 border-radius: 0 7px 7px 0; 980 border-radius: 0 7px 7px 0;
971 padding-left: 0; 981 padding-left: 0;
972 - width: 29px; 982 + width: 79px;
973 display: inline-block; 983 display: inline-block;
974 - height: 18px;  
975 - line-height: 18px; 984 + height: 22px;
  985 + line-height: 22px;
976 box-shadow: 2px 0px 2px 0 rgba(0,0,0,0.16), 2px 0px 4px 0 rgba(0,0,0,0.12); 986 box-shadow: 2px 0px 2px 0 rgba(0,0,0,0.16), 2px 0px 4px 0 rgba(0,0,0,0.12);
977 vertical-align: top; 987 vertical-align: top;
978 margin-right: 3px; 988 margin-right: 3px;
979 - margin-top: 3px; 989 + margin-top: 1px;
980 margin-left: -7px; 990 margin-left: -7px;
981 - text-indent: 2px; 991 + /*text-indent: 2px;*/
982 border-left: 0; 992 border-left: 0;
983 - transform: scale(.9); 993 + /* transform: scale(.9); */
984 color: grey; 994 color: grey;
985 } 995 }
986 996
src/main/resources/static/real_control_v2/fragments/line_schedule/sch_table.html
@@ -167,7 +167,7 @@ @@ -167,7 +167,7 @@
167 167
168 <script id="last-sch-sunken-temp" type="text/html"> 168 <script id="last-sch-sunken-temp" type="text/html">
169 <div class="last-sch-sunken"> 169 <div class="last-sch-sunken">
170 - <span class="_badge">终点</span>{{zdsj}}/{{zdsjActual}} 170 + <span class="_badge">{{zdsj}}/{{zdsjActual}}</span>
171 </div> 171 </div>
172 </script> 172 </script>
173 </div> 173 </div>
src/main/resources/static/real_control_v2/js/data/data_gps.js
@@ -30,7 +30,7 @@ var gb_data_gps = (function() { @@ -30,7 +30,7 @@ var gb_data_gps = (function() {
30 }, 30 },
31 error: function (xr, t) { 31 error: function (xr, t) {
32 notify_err('刷新GPS失败,稍后重试' + t); 32 notify_err('刷新GPS失败,稍后重试' + t);
33 - cb(); 33 + //cb();
34 } 34 }
35 }); 35 });
36 }; 36 };
src/main/resources/static/real_control_v2/mapmonitor/js/gps_tree.js
@@ -43,7 +43,7 @@ var gb_map_gps_tree = (function () { @@ -43,7 +43,7 @@ var gb_map_gps_tree = (function () {
43 'keep_selected_style': false, 43 'keep_selected_style': false,
44 'whole_node': false, 44 'whole_node': false,
45 'tie_selection': false 45 'tie_selection': false
46 - }, 46 + }/*,
47 'contextmenu': { 47 'contextmenu': {
48 'items': { 48 'items': {
49 '轨迹回放': { 49 '轨迹回放': {
@@ -59,12 +59,12 @@ var gb_map_gps_tree = (function () { @@ -59,12 +59,12 @@ var gb_map_gps_tree = (function () {
59 } 59 }
60 } 60 }
61 } 61 }
62 - }, 62 + }*/,
63 //local storage里的key 63 //local storage里的key
64 'state': { 64 'state': {
65 'key': 'jstree_map_devices' 65 'key': 'jstree_map_devices'
66 }, 66 },
67 - 'plugins': ['checkbox', 'contextmenu', 'state'] 67 + 'plugins': ['checkbox'/*, 'contextmenu'*/, 'state']
68 }); 68 });
69 }; 69 };
70 70