Commit 74e7a89eaad00537b9fc341c667c9a69ac7a64a4

Authored by 潘钊
1 parent 1a8dd3f9

update

Showing 42 changed files with 1225 additions and 545 deletions
src/main/java/com/bsth/controller/directive/DirectiveController.java
... ... @@ -98,11 +98,11 @@ public class DirectiveController {
98 98 }
99 99  
100 100 @RequestMapping(value = "/findAll80", method = RequestMethod.GET)
101   - public Page<D80> findAll80(@RequestParam Map<String, Object> map,
  101 + public Map<String, Object> findAll80(@RequestParam Map<String, Object> map,
102 102 @RequestParam(defaultValue = "0") int page,
103 103 @RequestParam(defaultValue = "12") int size){
104 104  
105   - return directiveService.findAll80(map, new PageRequest(page, size, new Sort(Direction.DESC, "timestamp")));
  105 + return directiveService.findAll80(map, page,size);
106 106 }
107 107  
108 108 /**
... ...
src/main/java/com/bsth/controller/gps/GpsController.java
... ... @@ -61,4 +61,9 @@ public class GpsController {
61 61 public Map<String, String> findCarDeviceIdMap() {
62 62 return BasicData.deviceId2NbbmMap.inverse();
63 63 }
  64 +
  65 + @RequestMapping(value = "/buffAera")
  66 + public Map<String, Object> findBuffAeraByCode(@RequestParam String code,@RequestParam String type){
  67 + return gpsService.findBuffAeraByCode(code, type);
  68 + }
64 69 }
... ...
src/main/java/com/bsth/data/BasicData.java
1 1 package com.bsth.data;
2 2  
  3 +import java.util.ArrayList;
3 4 import java.util.HashMap;
4 5 import java.util.Iterator;
  6 +import java.util.List;
5 7 import java.util.Map;
6 8 import java.util.concurrent.TimeUnit;
7 9  
... ... @@ -16,11 +18,13 @@ import com.bsth.entity.CarPark;
16 18 import com.bsth.entity.Cars;
17 19 import com.bsth.entity.Line;
18 20 import com.bsth.entity.Station;
  21 +import com.bsth.entity.StationRoute;
19 22 import com.bsth.entity.schedule.CarConfigInfo;
20 23 import com.bsth.repository.CarParkRepository;
21 24 import com.bsth.repository.CarsRepository;
22 25 import com.bsth.repository.LineRepository;
23 26 import com.bsth.repository.StationRepository;
  27 +import com.bsth.repository.StationRouteRepository;
24 28 import com.bsth.repository.schedule.CarConfigInfoRepository;
25 29 import com.google.common.collect.BiMap;
26 30 import com.google.common.collect.HashBiMap;
... ... @@ -58,6 +62,12 @@ public class BasicData implements CommandLineRunner{
58 62 //线路编码和名称对照
59 63 public static Map<String, String> lineCode2NameMap;
60 64  
  65 + //线路编码_站点编码 == 0|1 上下行
  66 + public static Map<String, Integer> lineStationUpDownMap;
  67 +
  68 + //停车场
  69 + public static List<String> parkCodeList;
  70 +
61 71 static Logger logger = LoggerFactory.getLogger(BasicData.class);
62 72  
63 73 @Autowired
... ... @@ -87,6 +97,9 @@ public class BasicData implements CommandLineRunner{
87 97 @Autowired
88 98 LineRepository lineRepository;
89 99  
  100 + @Autowired
  101 + StationRouteRepository stationRouteRepository;
  102 +
90 103  
91 104 @Override
92 105 public void run() {
... ... @@ -103,6 +116,9 @@ public class BasicData implements CommandLineRunner{
103 116 loadStationInfo();
104 117 loadLineInfo();
105 118 loadNbbm2LineInfo();
  119 +
  120 + loadStationRouteInfo();
  121 + logger.info("加载基础数据成功!," );
106 122 }catch(Exception e){
107 123 logger.error("加载基础数据时出现异常," , e);
108 124 }
... ... @@ -110,6 +126,18 @@ public class BasicData implements CommandLineRunner{
110 126 }
111 127  
112 128  
  129 + private void loadStationRouteInfo() {
  130 + Iterator<StationRoute> iterator = stationRouteRepository.findAll().iterator();
  131 + Map<String, Integer> map = new HashMap<>();
  132 + StationRoute route;
  133 +
  134 + while(iterator.hasNext()){
  135 + route = iterator.next();
  136 + map.put(route.getLineCode() + "_" + route.getStationCode(), route.getDirections());
  137 + }
  138 + lineStationUpDownMap = map;
  139 + }
  140 +
113 141 /**
114 142 * @Title: loadDeviceInfo
115 143 * @Description: TODO(加载设备相关信息)
... ... @@ -145,12 +173,17 @@ public class BasicData implements CommandLineRunner{
145 173 }
146 174 //停车场
147 175 Iterator<CarPark> iterator2 = carParkRepository.findAll().iterator();
  176 +
  177 + List<String> parkCodes = new ArrayList<>();
  178 +
148 179 CarPark carPark;
149 180 while(iterator2.hasNext()){
150 181 carPark = iterator2.next();
151 182 stationCode2Name.put(carPark.getParkCode(), carPark.getParkName());
  183 +
  184 + parkCodes.add(carPark.getParkCode());
152 185 }
153   -
  186 + parkCodeList = parkCodes;
154 187 stationCode2NameMap = stationCode2Name;
155 188 }
156 189  
... ...
src/main/java/com/bsth/data/arrival/AnalyseArrivalData.java 0 → 100644
  1 +package com.bsth.data.arrival;
  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;
  9 +import org.slf4j.LoggerFactory;
  10 +import org.springframework.stereotype.Component;
  11 +
  12 +import com.bsth.data.BasicData;
  13 +
  14 +/**
  15 + *
  16 + * @ClassName: AnalyseArrivalData
  17 + * @Description: TODO(分析一下进出站场数据)
  18 + * @author PanZhao
  19 + * @date 2016年8月24日 上午11:09:37
  20 + *
  21 + */
  22 +@Component
  23 +public class AnalyseArrivalData {
  24 +
  25 + Logger logger = LoggerFactory.getLogger(AnalyseArrivalData.class);
  26 +
  27 + public void analyse(Set<String> cars){
  28 + try{
  29 + List<ArrivalEntity> list, clearList;
  30 + for(String car : cars){
  31 + list = ArrivalData_GPS.findByNbbm(car);
  32 + analyse(list);
  33 +
  34 + //清理掉无效的点
  35 + clearList = new ArrayList<>();
  36 + for(ArrivalEntity arr : list){
  37 + if(!arr.isEnable())
  38 + clearList.add(arr);
  39 + }
  40 + list.removeAll(clearList);
  41 + }
  42 + }catch(Exception e){
  43 + logger.error("", e);
  44 + }
  45 + }
  46 +
  47 + private final static int SHIFT_TIME = 1000 * 60 * 5,
  48 + SCH_TIME = 1000 * 60 * 10;
  49 +
  50 + static ArrivalComparator comp = new ArrivalComparator();
  51 +
  52 + public void analyse(List<ArrivalEntity> list){
  53 + if(list.size() <= 1)
  54 + return;
  55 +
  56 + //排序
  57 + Collections.sort(list, comp);
  58 + ArrivalEntity prve = list.get(0)
  59 + ,curr;
  60 + for(int i = 1; i < list.size(); i ++){
  61 + curr = list.get(i);
  62 + //如果第一个点无效
  63 + if(!effective(prve)){
  64 + prve.setEnable(false);
  65 + prve = curr;
  66 + continue;
  67 + }
  68 + //如果第二个点无效
  69 + else if(!effective(curr)){
  70 + curr.setEnable(false);
  71 + continue;
  72 + }
  73 + else if(curr.getTs() - prve.getTs() < SCH_TIME){
  74 + if(prve.getUpDown() == curr.getUpDown()){
  75 + //信号漂移,出站无效
  76 + if(prve.getStopNo().equals(prve.getStopNo())
  77 + && prve.getInOut() == 1 && curr.getInOut() == 0
  78 + && curr.getTs() - prve.getTs() < SHIFT_TIME){
  79 + prve.setEnable(false);
  80 + }
  81 + }
  82 + else{
  83 + //上下行的同名站,新走向的第一个出站信号开始有效
  84 + if(prve.getStopName().equals(curr.getStopName())){
  85 + if(curr.getInOut() == 0)
  86 + curr.setEnable(false);
  87 + else
  88 + prve = curr;
  89 + }
  90 + }
  91 + }
  92 + else
  93 + prve = curr;
  94 + }
  95 + }
  96 +
  97 + private boolean effective(ArrivalEntity arr){
  98 + //停车场
  99 + if(BasicData.parkCodeList.contains(arr.getStopNo())){
  100 + arr.setTcc(true);
  101 + return true;
  102 + }
  103 +
  104 + Integer upDown = BasicData.lineStationUpDownMap.get(arr.getLineCode() + "_" + arr.getStopNo());
  105 +
  106 + return arr.getUpDown() == upDown || BasicData.parkCodeList.contains(arr.getStopNo());
  107 + }
  108 +}
... ...
src/main/java/com/bsth/data/arrival/ArrivalData_GPS.java
... ... @@ -24,7 +24,7 @@ import com.google.common.collect.ListMultimap;
24 24 /**
25 25 *
26 26 * @ClassName: ArrivalData_GPS
27   - * @Description: TODO(这里用一句话描述这个类的作用)
  27 + * @Description: TODO(GPS到离站数据)
28 28 * @author PanZhao
29 29 * @date 2016年8月18日 下午10:05:27
30 30 *
... ... @@ -32,16 +32,12 @@ import com.google.common.collect.ListMultimap;
32 32 @Component
33 33 public class ArrivalData_GPS implements CommandLineRunner{
34 34  
35   - //全部进出站数据(当日) K:线路编码
36   - //private static ListMultimap<String, ArrivalEntity> allArrivals;
37   -
38 35 // 起终点站进出数据 K:车辆编码
39 36 private static ListMultimap<String, ArrivalEntity> startAndEndMaps;
40 37  
41 38 private static Map<String, Integer> carIndexMap;
42 39  
43 40 static{
44   - //allArrivals = ArrayListMultimap.create();
45 41 startAndEndMaps = ArrayListMultimap.create();
46 42  
47 43 carIndexMap = new HashMap<>();
... ... @@ -54,7 +50,7 @@ public class ArrivalData_GPS implements CommandLineRunner{
54 50  
55 51 @Override
56 52 public void run(String... arg0) throws Exception {
57   - Application.mainServices.scheduleWithFixedDelay(dataLoaderThread, 40, 45, TimeUnit.SECONDS);
  53 + Application.mainServices.scheduleWithFixedDelay(dataLoaderThread, 30, 15, TimeUnit.SECONDS);
58 54 }
59 55  
60 56 @Component
... ... @@ -66,27 +62,33 @@ public class ArrivalData_GPS implements CommandLineRunner{
66 62 @Autowired
67 63 DayOfSchedule dayOfSchedule;
68 64  
  65 + @Autowired
  66 + AnalyseArrivalData analyseData;
  67 +
69 68 @Override
70 69 public void run() {
71   - Set<ArrivalEntity> arrSets = dataLoader.load();
72   - //有起终点进出的车辆
73   - Set<String> carSet = new TreeSet<>();
74   - //按车辆起终点站过滤数据
75   - String nbbm;
76   - Set<String> seList;
77   - for(ArrivalEntity arr : arrSets){
78   - //allArrivals.put(arr.getLineCode(), arr);
79   - nbbm = arr.getNbbm();
80   -
81   - seList = dayOfSchedule.getSEStationList(nbbm);
82   - if(seList.contains(arr.getStopNo())){
83   - startAndEndMaps.put(nbbm, arr);
84   - carSet.add(nbbm);
85   - }
86   - }
87   -
88   - //System.out.println("起终点数据大小为:" + startAndEndMaps.size() + " -- 全量数据:" + allArrivals.size());
89 70 try{
  71 + List<ArrivalEntity> arrSets = dataLoader.load();
  72 + if(null == arrSets || arrSets.size() == 0)
  73 + return;
  74 +
  75 + //有起终点进出的车辆
  76 + Set<String> carSet = new TreeSet<>();
  77 + //按车辆起终点站过滤数据
  78 + String nbbm;
  79 + Set<String> seList;
  80 + for(ArrivalEntity arr : arrSets){
  81 + nbbm = arr.getNbbm();
  82 +
  83 + seList = dayOfSchedule.getSEStationList(nbbm);
  84 + if(seList.contains(arr.getStopNo())){
  85 + startAndEndMaps.put(nbbm, arr);
  86 + carSet.add(nbbm);
  87 + }
  88 + }
  89 + //从专业的角度分析一下数据
  90 + analyseData.analyse(carSet);
  91 + //开始匹配
90 92 Arrival2Schedule.start(carSet);
91 93 }catch(Exception e){
92 94 logger.error("", e);
... ...
src/main/java/com/bsth/data/arrival/ArrivalEntity.java
1 1 package com.bsth.data.arrival;
2 2  
  3 +import java.text.SimpleDateFormat;
  4 +import java.util.Date;
  5 +
3 6 /**
4 7 *
5 8 * @ClassName: ArrivalEntity
... ... @@ -35,11 +38,13 @@ public class ArrivalEntity {
35 38  
36 39 private Long createDate;
37 40  
  41 + /** 是否有效 */
  42 + private boolean enable;
  43 +
38 44 /**分区字段,当年的第几周*/
39 45 private Integer weeksYear;
40 46  
41   - //5分钟内不允许多次进同一个站,出同一个站。 忽略走向
42   - private final static int EQ_RANGE = 1000 * 60 * 5;
  47 + private boolean tcc;
43 48  
44 49 public ArrivalEntity(){}
45 50  
... ... @@ -56,7 +61,7 @@ public class ArrivalEntity {
56 61 this.createDate = createDate;
57 62 }
58 63  
59   - @Override
  64 +/* @Override
60 65 public boolean equals(Object obj) {
61 66 ArrivalEntity a2 = (ArrivalEntity)obj;
62 67  
... ... @@ -67,12 +72,13 @@ public class ArrivalEntity {
67 72 @Override
68 73 public int hashCode() {
69 74 return this.toString().hashCode();
70   - }
  75 + }*/
  76 +
  77 +static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
71 78  
72   -
73 79 @Override
74 80 public String toString() {
75   - return this.deviceId + "_" + this.inOut + "_" + this.stopName;
  81 + return sdf.format(new Date(this.ts)) + "_" + this.deviceId + "_" + this.inOut + "_" + this.stopName;
76 82 }
77 83  
78 84 public String getLineCode() {
... ... @@ -158,5 +164,20 @@ public class ArrivalEntity {
158 164 public void setNbbm(String nbbm) {
159 165 this.nbbm = nbbm;
160 166 }
161   -
  167 +
  168 + public boolean isEnable() {
  169 + return enable;
  170 + }
  171 +
  172 + public void setEnable(boolean enable) {
  173 + this.enable = enable;
  174 + }
  175 +
  176 + public boolean isTcc() {
  177 + return tcc;
  178 + }
  179 +
  180 + public void setTcc(boolean tcc) {
  181 + this.tcc = tcc;
  182 + }
162 183 }
... ...
src/main/java/com/bsth/data/arrival/DataLoader.java
... ... @@ -4,11 +4,10 @@ import java.sql.Connection;
4 4 import java.sql.PreparedStatement;
5 5 import java.sql.ResultSet;
6 6 import java.sql.SQLException;
  7 +import java.util.ArrayList;
7 8 import java.util.Calendar;
8 9 import java.util.Collection;
9   -import java.util.Date;
10   -import java.util.HashSet;
11   -import java.util.Set;
  10 +import java.util.List;
12 11  
13 12 import org.slf4j.Logger;
14 13 import org.slf4j.LoggerFactory;
... ... @@ -18,7 +17,6 @@ import org.springframework.stereotype.Component;
18 17 import com.bsth.data.BasicData;
19 18 import com.bsth.data.LineConfigData;
20 19 import com.bsth.entity.realcontrol.LineConfig;
21   -import com.bsth.util.DateUtils;
22 20 import com.bsth.util.db.DBUtils_MS;
23 21  
24 22 /**
... ... @@ -46,11 +44,11 @@ public class DataLoader {
46 44 * @Title: load
47 45 * @Description: TODO(根据上次加载时间,查询之后的增量数据)
48 46 */
49   - public Set<ArrivalEntity> load(){
50   - Set<ArrivalEntity> set = null;
  47 + public List<ArrivalEntity> load(){
  48 + List<ArrivalEntity> list = null;
51 49  
52 50 if(null == prveLoadTime)
53   - set = recovery();
  51 + list = recovery();
54 52 else{
55 53 Calendar cal = Calendar.getInstance();
56 54 //周数,表分区字段
... ... @@ -62,7 +60,7 @@ public class DataLoader {
62 60  
63 61 String sql = "select * from bsth_c_arrival_info where weeks_year=? AND create_timestamp > ? AND create_timestamp <=? AND ABS(create_timestamp - ts) < 3600000 order by ts";
64 62 try{
65   - long t = System.currentTimeMillis() /*prveLoadTime + (1000 * 60 * 60)*/;
  63 + long t = System.currentTimeMillis();
66 64  
67 65 conn = DBUtils_MS.getConnection();
68 66 ps = conn.prepareStatement(sql);
... ... @@ -71,7 +69,7 @@ public class DataLoader {
71 69 ps.setLong(3, t);
72 70 rs = ps.executeQuery();
73 71  
74   - set = resultSet2Set(rs);
  72 + list = resultSet2Set(rs);
75 73  
76 74 prveLoadTime = t;
77 75 }catch(Exception e){
... ... @@ -80,7 +78,7 @@ public class DataLoader {
80 78 DBUtils_MS.close(rs, ps, conn);
81 79 }
82 80 }
83   - return set;
  81 + return list;
84 82 }
85 83  
86 84 /**
... ... @@ -88,12 +86,12 @@ public class DataLoader {
88 86 * @Title: recovery
89 87 * @Description: TODO(从数据库恢复数据,按照线路的开始运营时间恢复)
90 88 */
91   - public Set<ArrivalEntity> recovery(){
  89 + public List<ArrivalEntity> recovery(){
92 90 Collection<LineConfig> confs = lineConfigData.getAll();
93 91 long t = System.currentTimeMillis()
94 92 ,st;
95 93  
96   - Set<ArrivalEntity> all = new HashSet<>();
  94 + List<ArrivalEntity> all = new ArrayList<>();
97 95 for(LineConfig conf : confs){
98 96 st = conf.getCurrStartTime();
99 97 if(t < st)
... ... @@ -111,7 +109,7 @@ public class DataLoader {
111 109 * @Title: loadByLineAndStartTime
112 110 * @Description: TODO(根据线路和时间戳加载数据)
113 111 */
114   - public Set<ArrivalEntity> loadByLineAndTime(String lineCode, long st, long et){
  112 + public List<ArrivalEntity> loadByLineAndTime(String lineCode, long st, long et){
115 113 Calendar cal = Calendar.getInstance();
116 114 cal.setTimeInMillis(st);
117 115 int weeks_year = cal.get(Calendar.WEEK_OF_YEAR);
... ... @@ -120,7 +118,7 @@ public class DataLoader {
120 118 PreparedStatement ps = null;
121 119 ResultSet rs = null;
122 120  
123   - Set<ArrivalEntity> set = new HashSet<>();
  121 + List<ArrivalEntity> list = new ArrayList<>();
124 122 String sql = "select * from bsth_c_arrival_info where weeks_year=? and line_id=? AND create_timestamp > ? AND create_timestamp <=? AND ABS(create_timestamp - ts) < 3600000 order by ts";
125 123 try{
126 124 conn = DBUtils_MS.getConnection();
... ... @@ -131,20 +129,17 @@ public class DataLoader {
131 129 ps.setLong(4, et);
132 130 rs = ps.executeQuery();
133 131  
134   - set = resultSet2Set(rs);
135   -
136   - System.out.println("加载 " + BasicData.lineCode2NameMap.get(lineCode) + DateUtils.sdfyyyyMMddHHmm.format(new Date(st))
137   - + "至" + DateUtils.sdfyyyyMMddHHmm.format(new Date(et)) + " 数据,共:" + set.size());
  132 + list = resultSet2Set(rs);
138 133 }catch(Exception e){
139 134 logger.error("", e);
140 135 }finally {
141 136 DBUtils_MS.close(rs, ps, conn);
142 137 }
143   - return set;
  138 + return list;
144 139 }
145 140  
146   - public Set<ArrivalEntity> resultSet2Set(ResultSet rs) throws SQLException{
147   - Set<ArrivalEntity> set = new HashSet<>();
  141 + public List<ArrivalEntity> resultSet2Set(ResultSet rs) throws SQLException{
  142 + List<ArrivalEntity> list = new ArrayList<>();
148 143  
149 144 ArrivalEntity arr;
150 145 while(rs.next()){
... ... @@ -164,10 +159,11 @@ public class DataLoader {
164 159 arr.setInOut(rs.getInt("in_out"));
165 160 arr.setCreateDate(rs.getLong("create_timestamp"));
166 161 arr.setWeeksYear(rs.getInt("weeks_year"));
  162 + arr.setEnable(true);
167 163  
168   - set.add(arr);
  164 + list.add(arr);
169 165 }
170   - return set;
  166 + return list;
171 167 }
172 168  
173 169 public static void setPrveLoadTime(long t){
... ...
src/main/java/com/bsth/data/directive/DayOfDirectives.java
... ... @@ -133,8 +133,8 @@ public class DayOfDirectives {
133 133 }
134 134  
135 135 private void saveD60(D60 d60) {
136   - // 调度指令等47再入库
137   - if (d60.isDispatch() && d60.getReply47() == null)
  136 + // 等47再入库
  137 + if (d60.getReply47() == null)
138 138 return;
139 139  
140 140 directiveService.save(d60);
... ... @@ -146,7 +146,10 @@ public class DayOfDirectives {
146 146 Collection<D60> d60s = d60Map.values();
147 147 for(D60 d60 : d60s){
148 148 if(d60.getDeviceId().equals(device)){
149   - directiveService.save(d60);
  149 + //入库
  150 + if(d60.getReply47() == null)
  151 + directiveService.save(d60);
  152 +
150 153 if(null != d60Map.remove(d60.getMsgId()))
151 154 c60 ++;
152 155 }
... ... @@ -157,7 +160,10 @@ public class DayOfDirectives {
157 160 Collection<D64> d64s = d64Map.values();
158 161 for(D64 d64 : d64s){
159 162 if(d64.getDeviceId().equals(device)){
160   - directiveService.save64(d64);
  163 + //入库
  164 + if(d64.getRespAck() == null)
  165 + directiveService.save64(d64);
  166 +
161 167 if(null != d64Map.remove(d64.getKey()))
162 168 c64 ++;
163 169 }
... ...
src/main/java/com/bsth/data/gpsdata/GpsRealData.java
... ... @@ -7,6 +7,7 @@ import java.util.HashMap;
7 7 import java.util.List;
8 8 import java.util.Map;
9 9 import java.util.NavigableSet;
  10 +import java.util.concurrent.TimeUnit;
10 11  
11 12 import org.apache.http.HttpEntity;
12 13 import org.apache.http.client.methods.CloseableHttpResponse;
... ... @@ -21,6 +22,7 @@ import org.springframework.stereotype.Component;
21 22  
22 23 import com.alibaba.fastjson.JSON;
23 24 import com.alibaba.fastjson.JSONObject;
  25 +import com.bsth.Application;
24 26 import com.bsth.data.BasicData;
25 27 import com.bsth.util.ConfigUtil;
26 28 import com.google.common.collect.TreeMultimap;
... ... @@ -60,7 +62,8 @@ public class GpsRealData implements CommandLineRunner{
60 62  
61 63 @Override
62 64 public void run(String... arg0) throws Exception {
63   - //Application.mainServices.scheduleWithFixedDelay(gpsDataLoader, 20, 8, TimeUnit.SECONDS);
  65 + logger.info("gpsDataLoader,20,8");
  66 + Application.mainServices.scheduleWithFixedDelay(gpsDataLoader, 20, 8, TimeUnit.SECONDS);
64 67 }
65 68  
66 69 public static GpsEntity add(GpsEntity gps) {
... ...
src/main/java/com/bsth/data/match/Arrival2Schedule.java
... ... @@ -19,28 +19,25 @@ import com.bsth.entity.realcontrol.ScheduleRealInfo;
19 19 import com.bsth.service.directive.DirectiveService;
20 20 import com.bsth.websocket.handler.SendUtils;
21 21  
22   -/**
23   - *
24   - * @ClassName: Arrival2Schedule
25   - * @Description: TODO(进出数据匹配班次)
26   - * @author PanZhao
27   - * @date 2016年8月10日 下午2:26:22
28   - *
29   - */
30 22 @Component
31   -public class Arrival2Schedule implements ApplicationContextAware{
  23 +public class Arrival2Schedule implements ApplicationContextAware {
  24 +
  25 + private static DayOfSchedule dayOfSchedule;
  26 +
32 27  
33 28 private static ScheduleComparator.FCSJ schComparator;
34 29 private static ArrivalComparator arrComparator;
  30 + private static MatchResultComparator mrComparator;;
35 31 private static SendUtils sendUtils;
36   - private static DayOfSchedule dayOfSchedule;
37 32 private static DirectiveService directiveService;
38   -
39   - private final static long MAX_RANGE = 1000 * 60 * 60 * 4L;
  33 + private final static int ONE_MINUTE = 1000 * 60;
  34 + //定一个4小时的范围,基本能对正常班次进行容错。主要防止早上停车场GPS飘导致完成晚上的进场班次
  35 + private final static int FOUR_HOURS = 1000 * 60 * 60 * 4;
40 36  
41 37 static{
42 38 schComparator = new ScheduleComparator.FCSJ();
43 39 arrComparator = new ArrivalComparator();
  40 + mrComparator = new MatchResultComparator();
44 41 }
45 42  
46 43 /**
... ... @@ -52,180 +49,154 @@ public class Arrival2Schedule implements ApplicationContextAware{
52 49 public static void start(Set<String> cars){
53 50  
54 51 for(String car : cars){
55   - new GpsMatchThread(car).start();
  52 + new SchMatchThread(car).start();
56 53 }
57 54 }
58 55  
59   - public static class GpsMatchThread extends Thread{
60   -
  56 + public static class SchMatchThread extends Thread{
61 57 String nbbm;
62   - public GpsMatchThread(String nbbm){
  58 + public SchMatchThread(String nbbm){
63 59 this.nbbm = nbbm;
64 60 }
65   -
66 61 @Override
67 62 public void run() {
68 63 //班次列表
69 64 List<ScheduleRealInfo> schList = dayOfSchedule.findByNbbm(nbbm);
70 65 //进出起终点数据
71   - List<ArrivalEntity> arrList = ArrivalData_GPS.getIncrement(nbbm);
72   - System.out.println("####匹配进出站增量数据 " + arrList.size());
  66 + List<ArrivalEntity> arrList = ArrivalData_GPS.findByNbbm(nbbm);
73 67 //排序
74 68 Collections.sort(schList, schComparator);
75 69 Collections.sort(arrList, arrComparator);
76 70  
77   - int si = lastMatchPoint(schList);
78   - int ai = afterByTime(arrList, lastMatchTime(schList.get(si)));
79   -
80   - //按起始索引开始匹配
81   - match(arrList, ai, schList, si);
  71 + //用实际来匹配计划
  72 + for(ArrivalEntity arr : arrList){
  73 + match(arr, schList);
  74 + }
82 75 }
83   -
84   - public void match(List<ArrivalEntity> arrList, int ai, List<ScheduleRealInfo> schList, int si){
  76 + private void match(ArrivalEntity arr, List<ScheduleRealInfo> schList) {
  77 + schList = matchFilter(schList);
85 78  
86   - int sLen = schList.size();
87   - for(; si < sLen; si ++)
88   - match(arrList, ai, schList.get(si));
  79 + if(arr.getInOut() == 1)
  80 + matchOut(arr, schList);
  81 + else if(arr.getInOut() == 0)
  82 + matchIn(arr, schList);
89 83 }
90 84  
91   - public void match(List<ArrivalEntity> arrList, int ai, ScheduleRealInfo sch){
92   - //烂班不参与
93   - if(sch.isDestroy())
94   - return;
95   -
96   - int aLen = arrList.size();
97   -
98   - List<MatchResult> inRsList = new ArrayList<>()
99   - ,outRsList = new ArrayList<>();
100   -
101   - MatchResult mrs;
102   - for(;ai < aLen; ai ++){
103   - mrs = match(arrList.get(ai), sch);
104   - if(!mrs.success)
  85 + private List<ScheduleRealInfo> matchFilter(List<ScheduleRealInfo> schList) {
  86 + List<ScheduleRealInfo> list = new ArrayList<>();
  87 + for(ScheduleRealInfo sch : schList){
  88 + //烂班不匹配
  89 + if(sch.isDestroy())
  90 + continue;
  91 +
  92 + //没有里程的不匹配
  93 + if(sch.getBcsj() == null && sch.getJhlc() == null)
105 94 continue;
106 95  
107   - if(mrs.inOut == 0)
108   - inRsList.add(mrs);
109   - else if(mrs.inOut == 1)
110   - outRsList.add(mrs);
  96 + list.add(sch);
111 97 }
112   -
113   - if(outRsList.size() > 0){
114   - //排序后的第一个 就是最合适的匹配
115   - Collections.sort(outRsList, new MatchResultComparator());
116   - mrs = outRsList.get(0);
  98 + return list;
  99 + }
  100 +
  101 + private void matchOut(ArrivalEntity arr, List<ScheduleRealInfo> schList){
  102 + List<MatchResult> mrs = new ArrayList<>();
  103 + ScheduleRealInfo sch;
  104 + MatchResult mr;
  105 + for(int i = 0; i < schList.size(); i ++){
  106 + sch = schList.get(i);
  107 + if(!arr.isTcc() && arr.getUpDown() != Integer.parseInt(sch.getXlDir()))
  108 + continue;
117 109  
118   - mrs.sch.setFcsjActualAll(mrs.ts);
119   - //通知客户端
120   - sendUtils.sendFcsj(mrs.sch);
121   - //持久化
122   - dayOfSchedule.save(mrs.sch);
  110 + if(!arr.getStopNo().equals(sch.getQdzCode()))
  111 + continue;
  112 +
  113 + //班次有实发时间
  114 + if(sch.getFcsjActualTime() != null){
  115 + //实际发车已经被引用
  116 + if(Math.abs(arr.getTs() - sch.getFcsjActualTime()) < ONE_MINUTE)
  117 + return;
  118 + else
  119 + continue;
  120 + }
  121 + //添加一个匹配结果
  122 + mr = new MatchResult();
  123 + mr.sch = sch;
  124 + mr.ts = arr.getTs();
  125 + mr.diff = arr.getTs() - sch.getFcsjT();
  126 + mr.success = dayOfSchedule.validStartTime(sch, arr.getTs());
  127 +
  128 + if(Math.abs(mr.diff) < FOUR_HOURS && mr.success)
  129 + mrs.add(mr);
123 130 }
124 131  
125   - if(inRsList.size() > 0){
  132 + if(mrs.size() > 0){
126 133 //排序后的第一个 就是最合适的匹配
127   - Collections.sort(inRsList, new MatchResultComparator());
128   - mrs = inRsList.get(0);
  134 + Collections.sort(mrs, mrComparator);
  135 + mr = mrs.get(0);
129 136  
130   - mrs.sch.setZdsjActualAll(mrs.ts);
131   - int doneSum = dayOfSchedule.doneSum(mrs.sch.getClZbh());
132   - ScheduleRealInfo next = dayOfSchedule.next(mrs.sch);
133   - if(null != next){
134   - next.setQdzArrDateSJ(mrs.sch.getZdsjActual());
135   - //下发调度指令
136   - //directiveService.send60Dispatch(next, doneSum, "系统");
137   - }
138   - else{
139   - //下发文本指令(已结束运营)
140   - directiveService.send60Phrase(nbbm, "到达终点 " + mrs.sch.getZdzName() + ",已完成当日所有排班。", "系统");
141   - }
  137 + mr.sch.setFcsjActualAll(mr.ts);
142 138 //通知客户端
143   - sendUtils.sendZdsj(mrs.sch, next, doneSum);
  139 + sendUtils.sendFcsj(mr.sch);
144 140 //持久化
145   - dayOfSchedule.save(mrs.sch);
146   - }
147   - }
148   -
149   - public MatchResult match(ArrivalEntity arr, ScheduleRealInfo sch){
150   - MatchResult mrs = new MatchResult();
151   - mrs.inOut = arr.getInOut();
152   - mrs.sch = sch;
153   - mrs.ts = arr.getTs();
154   -
155   - if(arr.getInOut() == 1){
156   - if(sch.getFcsjActual() == null
157   - && sch.getQdzName().equals(arr.getStopName())
158   - && dayOfSchedule.validStartTime(sch, arr.getTs())){
159   -
160   - mrs.diff = arr.getTs() - sch.getDfsjT();
161   - if(Math.abs(mrs.diff) < MAX_RANGE)
162   - mrs.success = true;
163   - }
164   - }
165   - else if(arr.getInOut() == 0 && sch.getZdsj() != null){
166   - if(sch.getZdsjActual() == null
167   - && sch.getZdzName().equals(arr.getStopName())
168   - && dayOfSchedule.validEndTime(sch, arr.getTs())){
169   -
170   - mrs.diff = arr.getTs() - sch.getZdsjT();
171   - if(Math.abs(mrs.diff) < MAX_RANGE)
172   - mrs.success = true;
173   - }
  141 + dayOfSchedule.save(mr.sch);
174 142 }
175   -
176   - return mrs;
177 143 }
178 144  
179   - /**
180   - *
181   - * @Title: lastMatchPoint
182   - * @Description: TODO(最后一个已实发的班次索引)
183   - */
184   - public int lastMatchPoint(List<ScheduleRealInfo> schList){
185   - int len = schList.size()
186   - ,rs = 0;
  145 + private void matchIn(ArrivalEntity inArr, List<ScheduleRealInfo> schList){
187 146  
  147 + List<MatchResult> mrs = new ArrayList<>();
188 148 ScheduleRealInfo sch;
189   - for(int i = len - 2; i >= 0; i --){
  149 + MatchResult mr;
  150 + for(int i = 0; i < schList.size(); i ++){
190 151 sch = schList.get(i);
191   - if(sch.getFcsjActual() != null){
192   - rs = i;
193   - if(sch.getStatus() == 2)
194   - rs ++;
195   - break;
  152 + if(!inArr.isTcc() && inArr.getUpDown() != Integer.parseInt(sch.getXlDir()))
  153 + continue;
  154 +
  155 + if(!inArr.getStopNo().equals(sch.getZdzCode()))
  156 + continue;
  157 +
  158 + //班次有实达时间
  159 + if(sch.getZdsjActualTime() != null){
  160 + //实际到达已经被引用
  161 + if(Math.abs(inArr.getTs() - sch.getZdsjActualTime()) < ONE_MINUTE)
  162 + return;
  163 + else
  164 + continue;
196 165 }
  166 +
  167 + //添加一个匹配结果
  168 + mr = new MatchResult();
  169 + mr.sch = sch;
  170 + mr.ts = inArr.getTs();
  171 + mr.diff = inArr.getTs() - sch.getZdsjT();
  172 + mr.success = dayOfSchedule.validEndTime(sch, inArr.getTs());
  173 + if(Math.abs(mr.diff) < FOUR_HOURS && mr.success)
  174 + mrs.add(mr);
197 175 }
198   - return rs;
199   - }
200   -
201   - public long lastMatchTime(ScheduleRealInfo sch){
202   - Long t = 0L;
203   - if(null != sch.getFcsjActualTime())
204   - t = sch.getFcsjActualTime();
205   - if(null != sch.getZdsjActualTime())
206   - t = sch.getZdsjActualTime();
207   - return t;
208   - }
209   -
210   - /**
211   - *
212   - * @Title: afterByTime
213   - * @Description: TODO(参数时间戳之后的起始索引)
214   - */
215   - public int afterByTime(List<ArrivalEntity> arrList, long t){
216   - int len = arrList.size()
217   - ,rs = len - 1;
218 176  
219   - for(int i = 0; i < len; i ++){
220   - if(arrList.get(i).getTs() > t){
221   - rs = i;
222   - break;
  177 + if(mrs.size() > 0){
  178 + //排序后的第一个 就是最合适的匹配
  179 + Collections.sort(mrs, mrComparator);
  180 + mr = mrs.get(0);
  181 + mr.sch.setZdsjActualAll(mr.ts);
  182 +
  183 + int doneSum = dayOfSchedule.doneSum(mr.sch.getClZbh());
  184 + ScheduleRealInfo next = dayOfSchedule.next(mr.sch);
  185 + if(null != next){
  186 + next.setQdzArrDateSJ(mr.sch.getZdsjActual());
  187 + //下发调度指令
  188 + directiveService.send60Dispatch(next, doneSum, "系统");
223 189 }
  190 + else//下发文本指令(已结束运营)
  191 + directiveService.send60Phrase(nbbm, "到达终点 " + mr.sch.getZdzName() + ",已完成当日所有排班。", "系统");
  192 + //通知客户端
  193 + sendUtils.sendZdsj(mr.sch, next, doneSum);
  194 + //持久化
  195 + dayOfSchedule.save(mr.sch);
224 196 }
225   - return rs;
226 197 }
227 198 }
228   -
  199 +
229 200 @Override
230 201 public void setApplicationContext(ApplicationContext arg0) throws BeansException {
231 202 sendUtils = arg0.getBean(SendUtils.class);
... ...
src/main/java/com/bsth/data/match/Arrival2Schedule_old.java 0 → 100644
  1 +package com.bsth.data.match;
  2 +//package com.bsth.data.match;
  3 +//
  4 +//import java.util.ArrayList;
  5 +//import java.util.Collections;
  6 +//import java.util.List;
  7 +//import java.util.Set;
  8 +//
  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 +//import com.bsth.data.arrival.ArrivalComparator;
  17 +//import com.bsth.data.arrival.ArrivalData_GPS;
  18 +//import com.bsth.data.arrival.ArrivalEntity;
  19 +//import com.bsth.data.schedule.DayOfSchedule;
  20 +//import com.bsth.data.schedule.ScheduleComparator;
  21 +//import com.bsth.entity.realcontrol.ScheduleRealInfo;
  22 +//import com.bsth.service.directive.DirectiveService;
  23 +//import com.bsth.websocket.handler.SendUtils;
  24 +//
  25 +///**
  26 +// *
  27 +// * @ClassName: Arrival2Schedule
  28 +// * @Description: TODO(进出数据匹配班次)
  29 +// * @author PanZhao
  30 +// * @date 2016年8月10日 下午2:26:22
  31 +// *
  32 +// */
  33 +//@Component
  34 +//public class Arrival2Schedule implements ApplicationContextAware{
  35 +//
  36 +// private static ScheduleComparator.FCSJ schComparator;
  37 +// private static ArrivalComparator arrComparator;
  38 +// private static SendUtils sendUtils;
  39 +// private static DayOfSchedule dayOfSchedule;
  40 +// private static DirectiveService directiveService;
  41 +//
  42 +// private final static long MAX_RANGE = 1000 * 60 * 60 * 1L;
  43 +//
  44 +// static{
  45 +// schComparator = new ScheduleComparator.FCSJ();
  46 +// arrComparator = new ArrivalComparator();
  47 +// }
  48 +//
  49 +// static Logger logger = LoggerFactory.getLogger(Arrival2Schedule.class);
  50 +//
  51 +// /**
  52 +// *
  53 +// * @Title: start
  54 +// * @Description: TODO(开始)
  55 +// * @param @param cars 需要匹配的车辆集合
  56 +// */
  57 +// public static void start(Set<String> cars){
  58 +//
  59 +// for(String car : cars){
  60 +// new GpsMatchThread(car).start();
  61 +// }
  62 +// }
  63 +//
  64 +// public static class GpsMatchThread extends Thread{
  65 +//
  66 +// String nbbm;
  67 +// public GpsMatchThread(String nbbm){
  68 +// this.nbbm = nbbm;
  69 +// }
  70 +//
  71 +// @Override
  72 +// public void run() {
  73 +// //班次列表
  74 +// List<ScheduleRealInfo> schList = dayOfSchedule.findByNbbm(nbbm);
  75 +// //进出起终点数据
  76 +// List<ArrivalEntity> arrList = ArrivalData_GPS.getIncrement(nbbm);
  77 +// logger.info("####匹配进出站增量数据 " + arrList.size());
  78 +// //排序
  79 +// Collections.sort(schList, schComparator);
  80 +// Collections.sort(arrList, arrComparator);
  81 +//
  82 +// int si = lastMatchPoint(schList);
  83 +// int ai = afterByTime(arrList, lastMatchTime(schList.get(si)));
  84 +//
  85 +// //按起始索引开始匹配
  86 +// match(arrList, ai, schList, si);
  87 +// }
  88 +//
  89 +// public void match(List<ArrivalEntity> arrList, int ai, List<ScheduleRealInfo> schList, int si){
  90 +//
  91 +// int sLen = schList.size();
  92 +// for(; si < sLen; si ++)
  93 +// match(arrList, ai, schList.get(si));
  94 +// }
  95 +//
  96 +// public void match(List<ArrivalEntity> arrList, int ai, ScheduleRealInfo sch){
  97 +// //烂班不参与
  98 +// if(sch.isDestroy())
  99 +// return;
  100 +//
  101 +// int aLen = arrList.size();
  102 +//
  103 +// List<MatchResult> inRsList = new ArrayList<>()
  104 +// ,outRsList = new ArrayList<>();
  105 +//
  106 +// MatchResult mrs;
  107 +// for(;ai < aLen; ai ++){
  108 +// mrs = match(arrList.get(ai), sch);
  109 +// if(!mrs.success)
  110 +// continue;
  111 +//
  112 +// if(mrs.inOut == 0)
  113 +// inRsList.add(mrs);
  114 +// else if(mrs.inOut == 1)
  115 +// outRsList.add(mrs);
  116 +// }
  117 +//
  118 +// if(outRsList.size() > 0){
  119 +// //排序后的第一个 就是最合适的匹配
  120 +// Collections.sort(outRsList, new MatchResultComparator());
  121 +// mrs = outRsList.get(0);
  122 +//
  123 +// mrs.sch.setFcsjActualAll(mrs.ts);
  124 +// //通知客户端
  125 +// sendUtils.sendFcsj(mrs.sch);
  126 +// //持久化
  127 +// dayOfSchedule.save(mrs.sch);
  128 +// }
  129 +//
  130 +// if(inRsList.size() > 0){
  131 +// //排序后的第一个 就是最合适的匹配
  132 +// Collections.sort(inRsList, new MatchResultComparator());
  133 +// mrs = inRsList.get(0);
  134 +//
  135 +// /*if(!dayOfSchedule.validEndTime(mrs.sch, mrs.ts)){
  136 +// return;
  137 +// }*/
  138 +//
  139 +// mrs.sch.setZdsjActualAll(mrs.ts);
  140 +// int doneSum = dayOfSchedule.doneSum(mrs.sch.getClZbh());
  141 +// ScheduleRealInfo next = dayOfSchedule.next(mrs.sch);
  142 +// if(null != next){
  143 +// next.setQdzArrDateSJ(mrs.sch.getZdsjActual());
  144 +// //下发调度指令
  145 +// directiveService.send60Dispatch(next, doneSum, "系统");
  146 +// }
  147 +// else{
  148 +// //下发文本指令(已结束运营)
  149 +// directiveService.send60Phrase(nbbm, "到达终点 " + mrs.sch.getZdzName() + ",已完成当日所有排班。", "系统");
  150 +// }
  151 +// //通知客户端
  152 +// sendUtils.sendZdsj(mrs.sch, next, doneSum);
  153 +// //持久化
  154 +// dayOfSchedule.save(mrs.sch);
  155 +// }
  156 +// }
  157 +//
  158 +// public MatchResult match(ArrivalEntity arr, ScheduleRealInfo sch){
  159 +// MatchResult mrs = new MatchResult();
  160 +// mrs.inOut = arr.getInOut();
  161 +// mrs.sch = sch;
  162 +// mrs.ts = arr.getTs();
  163 +//
  164 +// if(Integer.parseInt(sch.getXlDir()) != arr.getUpDown()){
  165 +// return mrs;
  166 +// }
  167 +//
  168 +// if(arr.getInOut() == 1){
  169 +// if(sch.getFcsjActual() == null
  170 +// && sch.getQdzCode().equals(arr.getStopNo())
  171 +// && dayOfSchedule.validStartTime(sch, arr.getTs())){
  172 +//
  173 +// mrs.diff = arr.getTs() - sch.getDfsjT();
  174 +// if(Math.abs(mrs.diff) < MAX_RANGE)
  175 +// mrs.success = true;
  176 +// }
  177 +// }
  178 +// else if(arr.getInOut() == 0 && sch.getZdsj() != null){
  179 +// if(sch.getZdsjActual() == null
  180 +// && sch.getZdzCode().equals(arr.getStopNo())
  181 +// && dayOfSchedule.validEndTime(sch, arr.getTs())){
  182 +//
  183 +// mrs.diff = arr.getTs() - sch.getZdsjT();
  184 +// if(Math.abs(mrs.diff) < MAX_RANGE)
  185 +// mrs.success = true;
  186 +// }
  187 +// }
  188 +//
  189 +// return mrs;
  190 +// }
  191 +//
  192 +// /**
  193 +// *
  194 +// * @Title: lastMatchPoint
  195 +// * @Description: TODO(最后一个已实发的班次索引)
  196 +// */
  197 +// public int lastMatchPoint(List<ScheduleRealInfo> schList){
  198 +// int len = schList.size()
  199 +// ,rs = 0;
  200 +//
  201 +// ScheduleRealInfo sch;
  202 +// for(int i = len - 2; i >= 0; i --){
  203 +// sch = schList.get(i);
  204 +// if(sch.getFcsjActual() != null){
  205 +// rs = i;
  206 +// if(sch.getStatus() == 2)
  207 +// rs ++;
  208 +// break;
  209 +// }
  210 +// }
  211 +// return rs;
  212 +// }
  213 +//
  214 +// public long lastMatchTime(ScheduleRealInfo sch){
  215 +// Long t = 0L;
  216 +// if(null != sch.getFcsjActualTime())
  217 +// t = sch.getFcsjActualTime();
  218 +// if(null != sch.getZdsjActualTime())
  219 +// t = sch.getZdsjActualTime();
  220 +// return t;
  221 +// }
  222 +//
  223 +// /**
  224 +// *
  225 +// * @Title: afterByTime
  226 +// * @Description: TODO(参数时间戳之后的起始索引)
  227 +// */
  228 +// public int afterByTime(List<ArrivalEntity> arrList, long t){
  229 +// int len = arrList.size()
  230 +// ,rs = len - 1;
  231 +//
  232 +// for(int i = 0; i < len; i ++){
  233 +// if(arrList.get(i).getTs() > t){
  234 +// rs = i;
  235 +// break;
  236 +// }
  237 +// }
  238 +// return rs;
  239 +// }
  240 +// }
  241 +//
  242 +// @Override
  243 +// public void setApplicationContext(ApplicationContext arg0) throws BeansException {
  244 +// sendUtils = arg0.getBean(SendUtils.class);
  245 +// dayOfSchedule = arg0.getBean(DayOfSchedule.class);
  246 +// directiveService = arg0.getBean(DirectiveService.class);
  247 +// }
  248 +//}
... ...
src/main/java/com/bsth/data/pilot80/PilotReport.java
... ... @@ -80,9 +80,13 @@ public class PilotReport {
80 80 if(outSch != null){
81 81 //下发调度指令
82 82 directiveService.send60Dispatch(outSch, dayOfSchedule.doneSum(nbbm), "系统");
  83 + d80.setRemarks("计划出场时间:" + outSch.getDfsj());
83 84 //当前GPS位置
84 85 GpsEntity gps = gpsRealData.get(d80.getDeviceId());
85   - d80.setRemarks("计划出场时间:" + outSch.getDfsj() + "<br> 位置:" + coordHtmlStr(gps));
  86 + if(null != gps)
  87 + d80.addRemarks("<br> 位置:" + coordHtmlStr(gps));
  88 +
  89 + sendUtils.refreshSch(outSch);
86 90 }else
87 91 d80.setRemarks("没有出场计划");
88 92  
... ... @@ -93,9 +97,11 @@ public class PilotReport {
93 97 ScheduleRealInfo inSch = dayOfSchedule.nextByBcType(nbbm, "in");
94 98 //如果有对应出场班次
95 99 if(inSch != null){
  100 + d80.setRemarks("计划进场时间:" + inSch.getDfsj());
96 101 //当前GPS位置
97 102 GpsEntity gps = gpsRealData.get(d80.getDeviceId());
98   - d80.setRemarks("计划进场时间:" + inSch.getDfsj() + "<br> 位置:" + coordHtmlStr(gps));
  103 + if(null != gps)
  104 + d80.addRemarks("<br> 位置:" + coordHtmlStr(gps));
99 105 }else
100 106 d80.setRemarks("没有进场计划");
101 107 break;
... ... @@ -147,6 +153,7 @@ public class PilotReport {
147 153 //为相关班次写入请求出场时间
148 154 sch.setFcsjActualAll(d80.getTimestamp());
149 155  
  156 + dayOfSchedule.save(sch);
150 157 //通知页面
151 158 sendUtils.refreshSch(sch);
152 159 }
... ... @@ -172,6 +179,11 @@ public class PilotReport {
172 179 //为相关班次写入进场时间
173 180 sch.setZdsjActualAll(d80.getTimestamp());
174 181  
  182 + //没有里程的进场班次
  183 + if(sch.getBcsj() == null && sch.getJhlc() == null)
  184 + sch.setFcsjActualAll(d80.getTimestamp());
  185 +
  186 + dayOfSchedule.save(sch);
175 187 //通知页面
176 188 sendUtils.refreshSch(sch);
177 189 }
... ... @@ -259,4 +271,26 @@ public class PilotReport {
259 271  
260 272 return "<span class=\"nt-coord\" data-lon=\""+gps.getLon()+"\" data-lat=\""+gps.getLat()+"\"></span>";
261 273 }
  274 +
  275 + public Collection<D80> findAll(){
  276 + return d80MultiMap.values();
  277 + }
  278 +
  279 + public void clear(String lineCode){
  280 + d80MultiMap.removeAll(lineCode);
  281 + }
  282 +
  283 + public Collection<? extends D80> findByCar(String nbbm) {
  284 + List<D80> rs = new ArrayList<>();
  285 + String deviceId = BasicData.deviceId2NbbmMap.inverse().get(nbbm);
  286 + if(null == deviceId)
  287 + return rs;
  288 +
  289 + Collection<D80> all = findAll();
  290 + for(D80 d80 : all){
  291 + if(d80.getDeviceId().equals(deviceId))
  292 + rs.add(d80);
  293 + }
  294 + return rs;
  295 + }
262 296 }
... ...
src/main/java/com/bsth/data/schedule/DayOfSchedule.java
... ... @@ -7,6 +7,7 @@ import java.util.Date;
7 7 import java.util.HashMap;
8 8 import java.util.HashSet;
9 9 import java.util.Iterator;
  10 +import java.util.LinkedList;
10 11 import java.util.List;
11 12 import java.util.Map;
12 13 import java.util.Set;
... ... @@ -56,7 +57,7 @@ public class DayOfSchedule implements CommandLineRunner {
56 57 private static TreeMultimap<String, String> nbbm2SEStationMap;
57 58  
58 59 // 持久化缓冲区
59   - //private static LinkedList<ScheduleRealInfo> pstBuffer;
  60 + public static LinkedList<ScheduleRealInfo> pstBuffer;
60 61  
61 62 // 排序器
62 63 private static ScheduleComparator.FCNO schNoComparator;
... ... @@ -86,7 +87,7 @@ public class DayOfSchedule implements CommandLineRunner {
86 87 static {
87 88 nbbmScheduleMap = ArrayListMultimap.create();
88 89 id2SchedulMap = new HashMap<>();
89   - //pstBuffer = new LinkedList<>();
  90 + pstBuffer = new LinkedList<>();
90 91 schNoComparator = new ScheduleComparator.FCNO();
91 92 currSchDateMap = new HashMap<>();
92 93 nbbm2SEStationMap = TreeMultimap.create();
... ... @@ -94,11 +95,16 @@ public class DayOfSchedule implements CommandLineRunner {
94 95  
95 96 @Autowired
96 97 ScheduleRefreshThread scheduleRefreshThread;
  98 +
  99 + @Autowired
  100 + SchedulePstThread schedulePstThread;
97 101  
98 102 @Override
99 103 public void run(String... arg0) throws Exception {
100 104 //翻班线程
101   - Application.mainServices.scheduleWithFixedDelay(scheduleRefreshThread, 20, 60, TimeUnit.SECONDS);
  105 + Application.mainServices.scheduleWithFixedDelay(scheduleRefreshThread, 20, 120, TimeUnit.SECONDS);
  106 + //入库
  107 + Application.mainServices.scheduleWithFixedDelay(schedulePstThread, 60, 60, TimeUnit.SECONDS);
102 108 }
103 109  
104 110 public Map<String, String> getCurrSchDate() {
... ... @@ -365,17 +371,25 @@ public class DayOfSchedule implements CommandLineRunner {
365 371 * @Description: TODO(下一个班次)
366 372 */
367 373 public ScheduleRealInfo next(ScheduleRealInfo sch) {
368   - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
369   - // 排序
370   - Collections.sort(list, schNoComparator);
371 374  
  375 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  376 +
  377 + boolean flag = false;
372 378 ScheduleRealInfo next = null;
373   - for (int i = 0; i < list.size() - 1; i++) {
374   - if (list.get(i).getId().equals(sch.getId()))
375   - next = list.get(i + 1);
376   -
  379 + for(ScheduleRealInfo temp : list){
  380 + if(temp.getId() == sch.getId()){
  381 + flag = true;
  382 + continue;
  383 + }
  384 + //忽略烂班
  385 + if(temp.isDestroy())
  386 + continue;
  387 +
  388 + if(flag){
  389 + next = temp;
  390 + break;
  391 + }
377 392 }
378   -
379 393 return next;
380 394 }
381 395  
... ... @@ -384,7 +398,7 @@ public class DayOfSchedule implements CommandLineRunner {
384 398 * @Title: prveRealSch
385 399 * @Description: TODO(获取上一个已实际发出的班次)
386 400 */
387   - public ScheduleRealInfo prveSjfc(ScheduleRealInfo sch) {
  401 +/* public ScheduleRealInfo prveSjfc(ScheduleRealInfo sch) {
388 402 List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
389 403 // 排序
390 404 Collections.sort(list, schNoComparator);
... ... @@ -399,7 +413,7 @@ public class DayOfSchedule implements CommandLineRunner {
399 413 }
400 414 }
401 415 return prve;
402   - }
  416 + }*/
403 417  
404 418 public void put(ScheduleRealInfo sch) {
405 419 schAttrCalculator
... ... @@ -414,15 +428,30 @@ public class DayOfSchedule implements CommandLineRunner {
414 428 //主键索引
415 429 id2SchedulMap.put(sch.getId(), sch);
416 430 }
  431 +
  432 + public void calcQdzTimePlan(String nbbm){
  433 + schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm));
  434 + }
417 435  
418 436 /**
419 437 *
420 438 * @Title: nextAll
421 439 * @Description: TODO(之后的所有班次)
422 440 */
423   - public List<ScheduleRealInfo> nextAll(ScheduleRealInfo t) {
424   - // TODO Auto-generated method stub
425   - return null;
  441 + public List<ScheduleRealInfo> nextAll(ScheduleRealInfo sch) {
  442 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  443 + // 排序
  444 + Collections.sort(list, schNoComparator);
  445 +
  446 + List<ScheduleRealInfo> rs = new ArrayList<>();
  447 + ScheduleRealInfo temp;
  448 + for (int i = 0; i < list.size() - 1; i++) {
  449 + temp = list.get(i);
  450 + if(temp.getFcsjT() > sch.getFcsjT())
  451 + rs.add(temp);
  452 +
  453 + }
  454 + return rs;
426 455 }
427 456  
428 457 /**
... ... @@ -435,7 +464,7 @@ public class DayOfSchedule implements CommandLineRunner {
435 464 int rs = 0;
436 465  
437 466 for(ScheduleRealInfo sch : list){
438   - if(sch.getStatus() == 2)
  467 + if(sch.getZdsjActual() != null && !sch.isDestroy())
439 468 rs ++;
440 469 }
441 470 return rs;
... ... @@ -447,32 +476,57 @@ public class DayOfSchedule implements CommandLineRunner {
447 476 * @Description: TODO(是否是有效的到达时间)
448 477 */
449 478 public boolean validEndTime(ScheduleRealInfo sch, Long ts) {
450   - if (sch.getFcsjActualTime() != null)
451   - return ts > sch.getFcsjActualTime();
452   - else {
453   - ScheduleRealInfo prve = prveSjfc(sch);
454   - if (null != prve)
455   - return ts > prve.getFcsjActualTime();
456   - else
457   - return true;
458   - }
  479 + if(sch.getFcsjActualTime() != null && sch.getFcsjActualTime() > ts)
  480 + return false;
  481 +
  482 + return validTime(sch, ts);
459 483 }
460 484  
461 485 /**
462 486 *
463 487 * @Title: validStartTime
464   - * @Description: TODO(是否是有效的发车时间)
  488 + * @Description: TODO(是否是合适的发车时间)
465 489 */
466 490 public boolean validStartTime(ScheduleRealInfo sch, Long ts) {
467   - ScheduleRealInfo prve = prveSjfc(sch);
468   - if(null != prve)
469   - return ts > prve.getFcsjActualTime();
470   - else
471   - return true;
  491 + if(sch.getZdsjActualTime() != null && sch.getZdsjActualTime() < ts)
  492 + return false;
  493 +
  494 + return validTime(sch, ts);
  495 + }
  496 +
  497 + public boolean validTime(ScheduleRealInfo sch, Long ts){
  498 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  499 + int ci = list.indexOf(sch);
  500 + ScheduleRealInfo prve, next;
  501 + if(ci > 0){
  502 + //之前班次实际时间不能大于该时间
  503 + for(int i = ci - 1; i >= 0; i --){
  504 + prve = list.get(i);
  505 + if(prve.getZdsjActualTime() != null && prve.getZdsjActualTime() > ts )
  506 + return false;
  507 +
  508 + if(prve.getFcsjActualTime() != null && prve.getFcsjActualTime() > ts)
  509 + return false;
  510 + }
  511 + }
  512 +
  513 + if(ci < list.size() - 1){
  514 + //之后班次实际时间不能小于该时间
  515 + for(int i = ci + 1; i < list.size(); i ++){
  516 + next = list.get(i);
  517 + if(next.getFcsjActualTime() != null && next.getFcsjActualTime() < ts)
  518 + return false;
  519 +
  520 + if(next.getZdsjActualTime() != null && next.getZdsjActualTime() < ts)
  521 + return false;
  522 + }
  523 + }
  524 + return true;
472 525 }
473 526  
474 527 public void save(ScheduleRealInfo sch){
475   - schRepository.save(sch);
  528 + //schRepository.save(sch);
  529 + pstBuffer.add(sch);
476 530 }
477 531  
478 532 /**
... ...
src/main/java/com/bsth/data/schedule/SchAttrCalculator.java
... ... @@ -44,8 +44,12 @@ public class SchAttrCalculator {
44 44 if (null == sch.getFcsjT())
45 45 calcFcsjTime(sch);
46 46  
47   - // 早于班次运营时间的 加一天
48   - if (conf.getCurrStartTime() > sch.getFcsjT())
  47 + /*
  48 + * 早于线路开始运营时间的,加一天
  49 + * 如该线路 2点开始运营,2016-08-23的班次,则 2016-08-23 0:25 的班次应该调整成 2016-08-24 0:25
  50 + */
  51 + long st = DateUtils.sdfyyyyMMddHHmm.parse(sch.getScheduleDateStr() + conf.getStartOpt()).getTime();
  52 + if (st > sch.getFcsjT())
49 53 sch.setFcsjAll(sch.getFcsjT() + DAY_TIME);
50 54  
51 55 sch.setRealExecDate(DateUtils.sdfyyyyMMdd.format(new Date(sch.getFcsjT())));
... ...
src/main/java/com/bsth/data/schedule/SchedulePstThread.java 0 → 100644
  1 +package com.bsth.data.schedule;
  2 +
  3 +import java.util.LinkedList;
  4 +
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  9 +import com.bsth.repository.realcontrol.ScheduleRealInfoRepository;
  10 +
  11 +/**
  12 + *
  13 + * @ClassName: SchedulePstThread
  14 + * @Description: TODO(班次异步持久化)
  15 + * @author PanZhao
  16 + * @date 2016年8月24日 上午1:47:05
  17 + *
  18 + */
  19 +@Component
  20 +public class SchedulePstThread extends Thread{
  21 +
  22 + @Autowired
  23 + ScheduleRealInfoRepository scheduleRepository;
  24 +
  25 + @Override
  26 + public void run() {
  27 + LinkedList<ScheduleRealInfo> list = DayOfSchedule.pstBuffer;
  28 +
  29 + ScheduleRealInfo schedule;
  30 + for (int i = 0; i < 1000; i++) {
  31 + schedule = list.poll();
  32 + if (null == schedule)
  33 + break;
  34 +
  35 + scheduleRepository.save(schedule);
  36 + }
  37 + }
  38 +}
... ...
src/main/java/com/bsth/data/schedule/ScheduleRefreshThread.java
... ... @@ -12,6 +12,7 @@ import com.bsth.data.BasicData;
12 12 import com.bsth.data.LineConfigData;
13 13 import com.bsth.data.arrival.ArrivalData_GPS;
14 14 import com.bsth.data.directive.DayOfDirectives;
  15 +import com.bsth.data.pilot80.PilotReport;
15 16 import com.bsth.entity.realcontrol.LineConfig;
16 17  
17 18 /**
... ... @@ -37,32 +38,41 @@ public class ScheduleRefreshThread extends Thread{
37 38 @Autowired
38 39 DayOfDirectives dayOfDirectives;
39 40  
  41 + @Autowired
  42 + PilotReport pilotReport;
  43 +
40 44 Logger logger = LoggerFactory.getLogger(ScheduleRefreshThread.class);
41 45  
42 46 @Override
43 47 public void run() {
44   - Collection<LineConfig> confs = lineConfs.getAll();
45   -
46   - String currSchDate, oldSchDate;
47   - String lineCode;
48   - for(LineConfig conf : confs){
49   - lineCode = conf.getLine().getLineCode();
50   - oldSchDate = dayOfSchedule.getCurrSchDate().get(lineCode);
51   - currSchDate = dayOfSchedule.calcSchDate(lineCode);
  48 + try {
  49 + Collection<LineConfig> confs = lineConfs.getAll();
52 50  
53   - if(oldSchDate == null || !oldSchDate.equals(currSchDate)){
54   - logger.info(lineCode + "开始翻班, " + currSchDate);
55   - //清除进出站数据
56   - arrivalData.clearRAMData(lineCode);
57   - //清除指令数据
58   - Set<String> cars = dayOfSchedule.findCarByLineCode(lineCode);
59   - for(String car : cars)
60   - dayOfDirectives.clear(BasicData.deviceId2NbbmMap.inverse().get(car));
  51 + String currSchDate, oldSchDate;
  52 + String lineCode;
  53 + for(LineConfig conf : confs){
  54 + lineCode = conf.getLine().getLineCode();
  55 + oldSchDate = dayOfSchedule.getCurrSchDate().get(lineCode);
  56 + currSchDate = dayOfSchedule.calcSchDate(lineCode);
61 57  
62   - //重载排班数据
63   - dayOfSchedule.reloadSch(lineCode, currSchDate, false);
64   - logger.info(lineCode + "翻班完成, " + currSchDate + " -班次数量:" + dayOfSchedule.findByLineCode(lineCode).size());
  58 + if(oldSchDate == null || !oldSchDate.equals(currSchDate)){
  59 + logger.info(lineCode + "开始翻班, " + currSchDate);
  60 + //清除进出站数据
  61 + arrivalData.clearRAMData(lineCode);
  62 + //清除指令数据
  63 + Set<String> cars = dayOfSchedule.findCarByLineCode(lineCode);
  64 + for(String car : cars)
  65 + dayOfDirectives.clear(BasicData.deviceId2NbbmMap.inverse().get(car));
  66 + //清除驾驶员上报数据
  67 + pilotReport.clear(lineCode);
  68 +
  69 + //重载排班数据
  70 + dayOfSchedule.reloadSch(lineCode, currSchDate, false);
  71 + logger.info(lineCode + "翻班完成, " + currSchDate + " -班次数量:" + dayOfSchedule.findByLineCode(lineCode).size());
  72 + }
65 73 }
  74 + } catch (Exception e) {
  75 + logger.error("", e);
66 76 }
67 77 }
68 78 }
... ...
src/main/java/com/bsth/entity/realcontrol/LineConfig.java
... ... @@ -31,8 +31,9 @@ import com.bsth.util.DateUtils;
31 31 @Entity
32 32 @Table(name = "bsth_c_line_config")
33 33 @NamedEntityGraphs({
34   - @NamedEntityGraph(name = "lineConfig_line", attributeNodes = {
35   - @NamedAttributeNode("line")
  34 + @NamedEntityGraph(name = "lineConfig_line_80temps", attributeNodes = {
  35 + @NamedAttributeNode("line"),
  36 + @NamedAttributeNode("d80Temps")
36 37 })
37 38 })
38 39 public class LineConfig {
... ...
src/main/java/com/bsth/entity/realcontrol/ScheduleRealInfo.java
... ... @@ -568,14 +568,14 @@ public class ScheduleRealInfo {
568 568 }
569 569 } */
570 570  
571   -/* public void calcEndTime(){
  571 + public void calcEndTime(){
572 572 //计划终点时间
573 573 if(this.getBcsj() != null){
574 574 Date zdDate = new Date(this.getDfsjT() + (this.getBcsj() * 60 * 1000));
575 575 this.setZdsjT(zdDate.getTime());
576   - this.setZdsj(sdfHHmm.format(zdDate));
  576 + this.setZdsj(DateUtils.sdfHHmm.format(zdDate));
577 577 }
578   - }*/
  578 + }
579 579  
580 580 public Integer getDirectiveState() {
581 581 return directiveState;
... ... @@ -651,7 +651,7 @@ public class ScheduleRealInfo {
651 651 this.fcsjActualTime = DateUtils.sdfyyyyMMddHHmm.parse(this.realExecDate + fcsjActual).getTime();
652 652 this.fcsjActual = fcsjActual;
653 653  
654   - //this.synchroFcsj();
  654 + calcStatus();
655 655 } catch (ParseException e) {
656 656 e.printStackTrace();
657 657 }
... ... @@ -669,7 +669,6 @@ public class ScheduleRealInfo {
669 669  
670 670 //更新班次状态
671 671 calcStatus();
672   - //this.synchroFcsj();
673 672 }
674 673  
675 674 //和依赖班次同步发车时间
... ... @@ -713,7 +712,7 @@ public class ScheduleRealInfo {
713 712 this.zdsjActualTime = DateUtils.sdfyyyyMMddHHmm.parse(this.realExecDate + zdsjActual).getTime();
714 713 this.zdsjActual = zdsjActual;
715 714  
716   - //this.synchroZdsj();
  715 + calcStatus();
717 716 } catch (ParseException e) {
718 717 e.printStackTrace();
719 718 }
... ... @@ -802,7 +801,7 @@ public class ScheduleRealInfo {
802 801 this.parkIsFirstStation = parkIsFirstStation;
803 802 }
804 803  
805   - public ScheduleRealInfo getTwins() {
  804 +/* public ScheduleRealInfo getTwins() {
806 805 return twins;
807 806 }
808 807  
... ... @@ -816,7 +815,7 @@ public class ScheduleRealInfo {
816 815  
817 816 public void setFirstStationIsPark(boolean firstStationIsPark) {
818 817 this.firstStationIsPark = firstStationIsPark;
819   - }
  818 + }*/
820 819  
821 820  
822 821 /*public boolean statusTostart(){
... ... @@ -844,27 +843,17 @@ public class ScheduleRealInfo {
844 843 this.calcStatus();
845 844 }
846 845  
847   - public boolean existDependent() {
  846 +/* public boolean existDependent() {
848 847 return this.isFirstStationIsPark() || this.parkIsFirstStation;
849   - }
  848 + }*/
850 849  
851   - /*//清除实际终点时间
  850 + //清除实际终点时间
852 851 public void clearZdsjActual(){
853 852 this.setZdsjActual(null);
854 853 this.setZdsjActualTime(null);
855   - if(null != this.getSjddModel())
856   - this.getSjddModel().resetNull();
857 854  
858   - //依赖班次
859   - if(this.existDependent()){
860   - ScheduleRealInfo twins = this.getTwins();
861   - twins.setZdsjActual(null);
862   - twins.setZdsjActualTime(null);
863   - if(null != twins.getSjddModel())
864   - twins.getSjddModel().resetNull();
865   -
866   - }
867   - }*/
  855 + calcStatus();
  856 + }
868 857  
869 858 public Integer getOpDirectiveState() {
870 859 return opDirectiveState;
... ...
src/main/java/com/bsth/repository/CarParkRepository.java
... ... @@ -104,5 +104,7 @@ public interface CarParkRepository extends BaseRepository&lt;CarPark, Integer&gt;{
104 104 String updateDate,Integer versions,String bCenterPoint,String gCenterPoint,String bParkPoint,
105 105  
106 106 String gParkPoint,String dbType,Integer radius,String shapesType,Integer id );
107   -
  107 +
  108 + @Query(value = "select st_astext(g_park_point), shapes_type, g_center_point, radius,park_code,park_name from bsth_c_car_park where park_code=?1", nativeQuery = true)
  109 + public Object[][] bufferAera(String parkCode);
108 110 }
... ...
src/main/java/com/bsth/repository/StationRepository.java
... ... @@ -108,4 +108,6 @@ public interface StationRepository extends BaseRepository&lt;Station, Integer&gt; {
108 108 Integer destroy, Integer radius,String shapesType, Integer versions,String descriptions,Integer stationId);
109 109  
110 110  
  111 + @Query(value = "select st_astext(g_polygon_grid) as g_polygon_grid, shapes_type,concat(g_lonx, ' ', g_laty) as g_center_point ,radius, station_cod,station_name from bsth_c_station where station_cod=?1", nativeQuery = true)
  112 + public Object[][] bufferAera(String stationCode);
111 113 }
... ...
src/main/java/com/bsth/repository/StationRouteRepository.java
... ... @@ -3,7 +3,7 @@ package com.bsth.repository;
3 3 import java.util.List;
4 4 import java.util.Map;
5 5  
6   -import com.bsth.entity.schedule.CarConfigInfo;
  6 +
7 7 import org.springframework.data.domain.Page;
8 8 import org.springframework.data.domain.Pageable;
9 9 import org.springframework.data.jpa.domain.Specification;
... ... @@ -14,7 +14,6 @@ import org.springframework.stereotype.Repository;
14 14 import org.springframework.transaction.annotation.Transactional;
15 15  
16 16 import com.bsth.entity.Line;
17   -import com.bsth.entity.LineInformation;
18 17 import com.bsth.entity.StationRoute;
19 18  
20 19 /**
... ... @@ -227,10 +226,17 @@ public interface StationRouteRepository extends BaseRepository&lt;StationRoute, Int
227 226  
228 227 List<StationRoute> findByLine(Line line);
229 228  
230   - @EntityGraph(value = "stationRoute_station", type = EntityGraph.EntityGraphType.FETCH)
231   - @Query("select s from StationRoute s where s.destroy=0")
232   - List<StationRoute> findAll2();
  229 + @EntityGraph(value = "stationRoute_station", type = EntityGraph.EntityGraphType.FETCH)
  230 + @Override
  231 + Page<StationRoute> findAll(Specification<StationRoute> spec, Pageable pageable);
  232 +
  233 + @EntityGraph(value = "stationRoute_station", type = EntityGraph.EntityGraphType.FETCH)
  234 + @Override
  235 + List<StationRoute> findAll(Specification<StationRoute> spec);
  236 +
233 237  
234 238 @Query("select new map(sr.station.id as stationid, sr.stationName as stationname) from StationRoute sr where sr.line.id=?1 and sr.directions=?2")
235 239 List<Map<String, Object>> findStations(Integer xlid, Integer xldir);
  240 +
  241 +
236 242 }
... ...
src/main/java/com/bsth/repository/realcontrol/LineConfigRepository.java
... ... @@ -14,12 +14,16 @@ import com.bsth.repository.BaseRepository;
14 14 @Repository
15 15 public interface LineConfigRepository extends BaseRepository<LineConfig, Integer>{
16 16  
17   - @EntityGraph(value = "lineConfig_line", type = EntityGraph.EntityGraphType.FETCH)
  17 + @EntityGraph(value = "lineConfig_line_80temps", type = EntityGraph.EntityGraphType.FETCH)
18 18 @Override
19 19 Page<LineConfig> findAll(Specification<LineConfig> spec, Pageable pageable);
20 20  
21   - @EntityGraph(value = "lineConfig_line", type = EntityGraph.EntityGraphType.FETCH)
  21 + @EntityGraph(value = "lineConfig_line_80temps", type = EntityGraph.EntityGraphType.FETCH)
22 22 @Override
23 23 List<LineConfig> findAll(Specification<LineConfig> spec);
  24 +
  25 + @EntityGraph(value = "lineConfig_line_80temps", type = EntityGraph.EntityGraphType.FETCH)
  26 + @Override
  27 + List<LineConfig> findAll();
24 28  
25 29 }
... ...
src/main/java/com/bsth/service/directive/DirectiveService.java
... ... @@ -82,7 +82,7 @@ public interface DirectiveService extends BaseService&lt;D60, Integer&gt;{
82 82  
83 83 Map<String, Object> findDirective(String nbbm, int dType, int page, int size);
84 84  
85   - Page<D80> findAll80(Map<String, Object> map, PageRequest pageRequest);
  85 + Map<String, Object> findAll80(Map<String, Object> map, int page, int size);
86 86  
87 87 D64 save64(D64 d64);
88 88 }
... ...
src/main/java/com/bsth/service/directive/DirectiveServiceImpl.java
... ... @@ -4,6 +4,7 @@ import java.text.SimpleDateFormat;
4 4 import java.util.ArrayList;
5 5 import java.util.Collection;
6 6 import java.util.Collections;
  7 +import java.util.Comparator;
7 8 import java.util.Date;
8 9 import java.util.HashMap;
9 10 import java.util.List;
... ... @@ -76,7 +77,7 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
76 77 @Autowired
77 78 DayOfSchedule dayOfSchedule;
78 79  
79   - SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH点mm分"), sdfHHmm2 = new SimpleDateFormat("HH:mm");
  80 + SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH点mm分");
80 81  
81 82 static Long schDiff = 1000 * 60 * 60L;
82 83  
... ... @@ -112,10 +113,14 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
112 113 public int send60Dispatch(ScheduleRealInfo sch, int finish, String sender) {
113 114 D60 d60 = null;
114 115 try {
  116 + if(sch.isDestroy()){
  117 + logger.warn("烂班不允许发送调度指令....");
  118 + return -1;
  119 + }
  120 +
115 121 String text = "已完成" + finish + "个班次,下一发车时间" + sdfHHmm.format(new Date(sch.getDfsjT())) + ",由"
116 122 + sch.getQdzName() + "发往" + sch.getZdzName();
117 123  
118   - //ScheduleRealInfo nextSch = dayOfSchedule.next(sch);
119 124 //下发0x02指令 调度指令(闹钟有效)
120 125 Long alarmTime = System.currentTimeMillis() + 1000 * 30;
121 126 d60 = DirectiveCreator.createD60_02(sch.getClZbh(), text, Integer.parseInt(sch.getXlDir())
... ... @@ -240,8 +245,18 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
240 245 if (null == sch) {
241 246 GpsEntity gpsData = gpsRealDataBuffer.findByDeviceId(deviceId);
242 247 if (null == gpsData) {
243   - logger.error("没有找到gps对照,无法确认营运状态和上下行:" + nbbm);
244   - return null;
  248 + /*
  249 + * 短语指令不会变更设备状态,所以在没有gps状态对照的情况下可以下发
  250 + * 其他指令在不确定状态的情况下,一律不允许
  251 + */
  252 + if(dispatchInstruct == 0){
  253 + upDown = 0;
  254 + state = 0;
  255 + }
  256 + else{
  257 + logger.error("没有找到gps对照,无法确认营运状态和上下行:" + nbbm);
  258 + return null;
  259 + }
245 260 }
246 261 upDown = gpsData.getUpDown();
247 262 state = gpsData.getState();
... ... @@ -372,7 +387,7 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
372 387 // 时间格式化,车辆自编号转换
373 388 for (Directive d : rs) {
374 389 if (d.getTimeHHmm() == null)
375   - d.setTimeHHmm(sdfHHmm2.format(new Date(d.getTimestamp())));
  390 + d.setTimeHHmm(DateUtils.sdfHHmm.format(new Date(d.getTimestamp())));
376 391 if (d.getNbbm() == null)
377 392 d.setNbbm(BasicData.deviceId2NbbmMap.get(d.getDeviceId()));
378 393 }
... ... @@ -384,23 +399,54 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
384 399 }
385 400  
386 401 @Override
387   - public Page<D80> findAll80(Map<String, Object> map, PageRequest pageRequest) {
388   - //默认只查看当天的
389   - map.put("timestamp_gt", DateUtils.getTimestamp());
  402 + public Map<String, Object> findAll80(Map<String, Object> map, int page, int size) {
  403 + List<D80> d80s = new ArrayList<>();
390 404  
391 405 Object nbbm = map.get("nbbm");
392   - if(null != nbbm && StringUtils.isNotBlank(nbbm.toString())){
393   - map.put("deviceId_eq", BasicData.deviceId2NbbmMap.inverse().get(nbbm.toString()));
  406 + if(null != nbbm && StringUtils.isNotEmpty(nbbm.toString())){
  407 + d80s.addAll(pilotReport.findByCar(nbbm.toString()));
  408 + }
  409 + else{
  410 + d80s.addAll(pilotReport.findAll());
394 411 }
395 412  
396   - Page<D80> pageData = d80Repository.findAll(new CustomerSpecs<D80>(map), pageRequest);
397   - //格式化时间和转换车辆自编号
398   - List<D80> list = pageData.getContent();
399   - for(D80 d80 : list){
400   - d80.setTimeStr(sdfHHmm2.format(new Date(d80.getTimestamp())));
401   - d80.getData().setNbbm(BasicData.deviceId2NbbmMap.get(d80.getDeviceId()));
  413 + Short requestCode = Short.parseShort(map.get("requestCode").toString());
  414 + if(requestCode != -1){
  415 + List<D80> temps = new ArrayList<>();
  416 + for(D80 d80 : d80s){
  417 + if(d80.getData().getRequestCode().equals(requestCode))
  418 + temps.add(d80);
  419 + }
  420 + d80s = temps;
  421 + }
  422 +
  423 + //排序
  424 + Collections.sort(d80s, new Comparator<D80>() {
  425 + @Override
  426 + public int compare(D80 o1, D80 o2) {
  427 + return (int) (o1.getTimestamp() - o2.getTimestamp());
  428 + }
  429 + });
  430 +
  431 + //分页
  432 + int count = d80s.size();
  433 + // 分页
  434 + int s = page * size, e = s + size;
  435 +
  436 + if (e > count)
  437 + e = count;
  438 +
  439 + List<D80> rs = d80s.subList(s, e);
  440 + for(D80 d80 : rs){
  441 + d80.setTimeStr(DateUtils.sdfHHmm.format(new Date(d80.getTimestamp())));
402 442 }
403   - return pageData;
  443 +
  444 + Map<String, Object> rsMap = new HashMap<>();
  445 + rsMap.put("list", rs);
  446 + rsMap.put("totalPages", count % size == 0 ? count / size : count / size + 1);
  447 + rsMap.put("page", page);
  448 +
  449 + return rsMap;
404 450 }
405 451  
406 452 @Override
... ...
src/main/java/com/bsth/service/gps/GpsService.java
... ... @@ -8,4 +8,6 @@ public interface GpsService {
8 8 List<Map<String, Object>> history(String device, Long startTime, Long endTime, int directions);
9 9  
10 10 List<Map<String, Object>> history(String[] nbbmArray, Long st, Long et);
  11 +
  12 + Map<String, Object> findBuffAeraByCode(String code, String type);
11 13 }
... ...
src/main/java/com/bsth/service/gps/GpsServiceImpl.java
... ... @@ -14,10 +14,13 @@ import java.util.Map;
14 14  
15 15 import org.slf4j.Logger;
16 16 import org.slf4j.LoggerFactory;
  17 +import org.springframework.beans.factory.annotation.Autowired;
17 18 import org.springframework.stereotype.Service;
18 19  
19 20 import com.bsth.data.BasicData;
20 21 import com.bsth.data.arrival.ArrivalEntity;
  22 +import com.bsth.repository.CarParkRepository;
  23 +import com.bsth.repository.StationRepository;
21 24 import com.bsth.util.DateUtils;
22 25 import com.bsth.util.TransGPS;
23 26 import com.bsth.util.TransGPS.Location;
... ... @@ -199,6 +202,7 @@ public class GpsServiceImpl implements GpsService{
199 202 Float lon, lat;
200 203 Location bdLoc, gdLoc;
201 204 int upDown, inOutStop;
  205 + ArrivalEntity arrival;
202 206 while (rs.next()) {
203 207 upDown = getUpOrDown(rs.getLong("SERVICE_STATE"));
204 208 map = new HashMap<>();
... ... @@ -222,9 +226,10 @@ public class GpsServiceImpl implements GpsService{
222 226 inOutStop = rs.getInt("INOUT_STOP");
223 227 map.put("inout_stop", inOutStop);
224 228  
225   - if (inOutStop != -1) {
226   - map.put("inout_stop_info",
227   - arrivalMap.get(rs.getString("DEVICE_ID") + "_" + rs.getLong("TS") + "_" + inOutStop));
  229 + arrival = arrivalMap.get(rs.getString("DEVICE_ID") + "_" + rs.getLong("TS"));
  230 + if (arrival != null) {
  231 + map.put("inout_stop_info",arrival);
  232 + map.put("inout_stop", arrival.getInOut());
228 233 }
229 234 map.put("nbbm", BasicData.deviceId2NbbmMap.get(rs.getString("DEVICE_ID")));
230 235 map.put("state", 0);
... ... @@ -263,7 +268,7 @@ public class GpsServiceImpl implements GpsService{
263 268 // 设备号_时间戳_进出状态 为key
264 269 // 反转进出状态
265 270 inOut = arr.getInOut() == 0 ? 1 : 0;
266   - map.put(arr.getDeviceId() + "_" + arr.getTs() + "_" + inOut, arr);
  271 + map.put(arr.getDeviceId() + "_" + arr.getTs(), arr);
267 272 }
268 273 } catch (Exception e) {
269 274 logger.error("", e);
... ... @@ -272,4 +277,34 @@ public class GpsServiceImpl implements GpsService{
272 277 }
273 278 return map;
274 279 }
  280 +
  281 +
  282 + @Autowired
  283 + StationRepository stationRepository;
  284 +
  285 + @Autowired
  286 + CarParkRepository carParkRepository;
  287 +
  288 + @Override
  289 + public Map<String, Object> findBuffAeraByCode(String code, String type) {
  290 + Object[][] obj = null;
  291 + if(type.equals("station"))
  292 + obj = stationRepository.bufferAera(code);
  293 + else if(type.equals("park"))
  294 + obj = carParkRepository.bufferAera(code);
  295 +
  296 + Map<String, Object> rs = new HashMap<>();
  297 +
  298 + Object[] subObj = obj[0];
  299 + if(subObj != null && subObj.length == 6){
  300 + rs.put("polygon", subObj[0]);
  301 + rs.put("type", subObj[1]);
  302 + rs.put("cPoint", subObj[2]);
  303 + rs.put("radius", subObj[3]);
  304 + rs.put("code", subObj[4]);
  305 + rs.put("text", subObj[5]);
  306 + }
  307 +
  308 + return rs;
  309 + }
275 310 }
... ...
src/main/java/com/bsth/service/realcontrol/impl/ScheduleRealInfoServiceImpl.java
... ... @@ -23,6 +23,8 @@ import com.alibaba.fastjson.JSONArray;
23 23 import com.alibaba.fastjson.JSONObject;
24 24 import com.bsth.common.ResponseCode;
25 25 import com.bsth.data.BasicData;
  26 +import com.bsth.data.arrival.ArrivalData_GPS;
  27 +import com.bsth.data.arrival.ArrivalEntity;
26 28 import com.bsth.data.schedule.DayOfSchedule;
27 29 import com.bsth.data.schedule.ScheduleComparator;
28 30 import com.bsth.entity.Cars;
... ... @@ -132,7 +134,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
132 134 List<ScheduleRealInfo> ts = new ArrayList<>();
133 135 ts.add(schedule);
134 136 //调整终点时间和下一个班次的应到时间
135   - //schedule.calcEndTime();
  137 + schedule.calcEndTime();
136 138 ScheduleRealInfo nextSch = dayOfSchedule.next(schedule);
137 139 if(null != nextSch){
138 140 nextSch.setQdzArrDateJH(schedule.getZdsj());
... ... @@ -140,8 +142,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
140 142 }
141 143  
142 144 // 持久化到数据库
143   - scheduleRealInfoRepository.save(schedule);
144   - //ScheduleBuffer.persistentList.add(schedule);
  145 + dayOfSchedule.save(schedule);
145 146  
146 147 map.put("status", ResponseCode.SUCCESS);
147 148 map.put("ts", ts);
... ... @@ -172,6 +173,8 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
172 173  
173 174 schedule.destroy();
174 175 schedule.addRemarks(remarks);
  176 +
  177 + dayOfSchedule.save(schedule);
175 178 rsList.add(schedule);
176 179 }
177 180  
... ... @@ -211,7 +214,8 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
211 214 schedule.setDfsjT(st);
212 215 schedule.setDfsj(sdfShort.format(new Date(st)));
213 216  
214   - scheduleRealInfoRepository.save(schedule);
  217 + dayOfSchedule.save(schedule);
  218 + //scheduleRealInfoRepository.save(schedule);
215 219 //ScheduleBuffer.persistentList.add(schedule);
216 220 // 将调整的班次返回给页面
217 221 rsList.add(schedule);
... ... @@ -306,13 +310,12 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
306 310 t.setScheduleDate(d);
307 311 t.setRealExecDate(sdfMonth.format(d));
308 312 t.setCreateBy(user);
309   - //t.syncTime();
310 313 t.setSflj(true);
311 314 Map<String, Object> map = super.save(t);
312 315  
313 316 // 加入缓存
314 317 dayOfSchedule.put(t);
315   - //ScheduleBuffer.put(t);
  318 + dayOfSchedule.calcQdzTimePlan(t.getClZbh());
316 319 //将该临加之后的班次作为更新返回页面
317 320 List<ScheduleRealInfo> list = dayOfSchedule.nextAll(t)
318 321 ,rsList = null;
... ... @@ -603,9 +606,9 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
603 606 //ScheduleBuffer.persistentList.add(sch);
604 607  
605 608 ts.add(sch);
606   - //关联班次
  609 + /*//关联班次
607 610 if(sch.existDependent())
608   - ts.add(sch.getTwins());
  611 + ts.add(sch.getTwins());*/
609 612  
610 613 rs.put("status", ResponseCode.SUCCESS);
611 614 rs.put("ts", ts);
... ... @@ -652,6 +655,18 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
652 655 rs.put("status", ResponseCode.ERROR);
653 656 rs.put("msg", "无实发时间,无法撤销!");
654 657 } else {
  658 + //将对应的到离站数据标记为不可信
  659 + List<ArrivalEntity> list = ArrivalData_GPS.findByNbbm(sch.getClZbh());
  660 + for(ArrivalEntity arr : list){
  661 + if(arr.getInOut() == 1
  662 + && arr.getUpDown() == Integer.parseInt(sch.getXlDir())
  663 + && arr.getStopNo().equals(sch.getQdzCode())
  664 + && Math.abs(arr.getTs() - sch.getFcsjActualTime()) < 1000 * 60){
  665 + arr.setEnable(false);
  666 + break;
  667 + }
  668 + }
  669 +
655 670 sch.clearFcsjActual();
656 671 rs.put("status", ResponseCode.SUCCESS);
657 672  
... ... @@ -752,19 +767,11 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
752 767 sch.setFcsjAll(fcsj);
753 768  
754 769 if(StringUtils.isNotBlank(fcsjActual)){
755   -
756   - if(!fcsjActual.equals(sch.getFcsjActual())){
757   - //调整实发
  770 + //调整实发
  771 + if(!fcsjActual.equals(sch.getFcsjActual()))
758 772 sch.setFcsjActualAll(fcsjActual);
759   - /*if(null != sch.getSjfcModel())
760   - sch.getSjfcModel().setPersonTime(sch.getFcsjActualTime());*/
761   - }
762 773 }
763 774 else{
764   - /*sch.setFcsjActual(null);
765   - sch.setFcsjActualTime(null);
766   - if(null != sch.getSjfcModel())
767   - sch.getSjfcModel().resetNull();*/
768 775 //撤销实发
769 776 revokeRealOutgo(sch.getId());
770 777 }
... ... @@ -783,13 +790,20 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
783 790 }
784 791 }
785 792 else {
786   - //清除实达时间
787   - //sch.clearZdsjActual();
788   - /*sch.setZdsjActual(null);
789   - sch.setZdsjActualTime(null);
790   - if(null != sch.getSjddModel())
791   - sch.getSjddModel().resetNull();*/
  793 + //将对应的到离站数据标记为不可信
  794 + List<ArrivalEntity> list = ArrivalData_GPS.findByNbbm(sch.getClZbh());
  795 + for(ArrivalEntity arr : list){
  796 + if(arr.getInOut() == 0
  797 + && arr.getUpDown() == Integer.parseInt(sch.getXlDir())
  798 + && arr.getStopNo().equals(sch.getZdzCode())
  799 + && Math.abs(arr.getTs() - sch.getZdsjActualTime()) < 1000 * 60){
  800 + arr.setEnable(false);
  801 + break;
  802 + }
  803 + }
792 804  
  805 + //清除实达时间
  806 + sch.clearZdsjActual();
793 807 //清除下一班次起点到达时间
794 808 ScheduleRealInfo next = dayOfSchedule.next(sch);
795 809 if(null != next){
... ... @@ -803,16 +817,12 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
803 817  
804 818 //班次状态
805 819 sch.calcStatus();
806   - scheduleRealInfoRepository.save(sch);
807   - //ScheduleBuffer.persistentList.add(sch);
  820 + dayOfSchedule.save(sch);
808 821 //页面需要更新的班次信息
809 822 ts.add(sch);
810   - if(sch.existDependent())
811   - ts.add(sch.getTwins());
812 823  
813 824 rs.put("status", ResponseCode.SUCCESS);
814 825 rs.put("ts", ts);
815   - //rs.put("t", sch);
816 826 } catch (Exception e) {
817 827 logger.error("", e);
818 828 rs.put("status", ResponseCode.ERROR);
... ... @@ -836,8 +846,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
836 846 //设置待发时间
837 847 schedule.setDfsjAll(dfsj);
838 848  
839   - scheduleRealInfoRepository.save(schedule);
840   - //ScheduleBuffer.persistentList.add(schedule);
  849 + dayOfSchedule.save(schedule);
841 850 }
842 851  
843 852 rs.put("status", ResponseCode.SUCCESS);
... ...
src/main/resources/static/login.html
... ... @@ -89,7 +89,7 @@ Login page
89 89  
90 90 <div class="input-icon right" style="display: inline-block;">
91 91 <i class="fa fa-user"></i>
92   - <input type="text" class="form-control " placeholder="用户名" name="username" value="admin"> </div>
  92 + <input type="text" class="form-control " placeholder="用户名" name="username" value=""> </div>
93 93  
94 94  
95 95 <div class="input-icon right" style="display: inline-block;">
... ... @@ -112,7 +112,7 @@ Login page
112 112  
113 113 <script type="text/javascript">
114 114 $(function() {
115   - $('input[name=password]').focus();
  115 + $('input[name=username]').focus();
116 116 /* setCenterCss(); */
117 117 if ($.url().param('error')) {
118 118 //去session里查一下失败信息
... ...
src/main/resources/static/pages/control/line/child_pages/deviceReport.html
... ... @@ -4,17 +4,17 @@
4 4 <div class="form-group" style="margin: 18px;">
5 5 <label class="" for="directiveSelect">请求代码:</label>
6 6 <select class="form-control" id="requestCodeSelect" name="requestCode">
7   - <option value="-1">全部</option>
8   - <option value="0xA1">恢复运营</option>
9   - <option value="0xA2">申请调档</option>
10   - <option value="0xA3">出场请求</option>
11   - <option value="0xA5">进场请求</option>
12   - <option value="0xA7">加油请求</option>
13   - <option value="0x50">车辆故障</option>
14   - <option value="0x70">路阻报告</option>
15   - <option value="0x60">事故报告</option>
16   - <option value="0x11">扣证纠纷</option>
17   - <option value="0x12">报警</option>
  7 + <option value=-1>全部</option>
  8 + <option value=161>恢复运营</option>
  9 + <option value=162>申请调档</option>
  10 + <option value=163>出场请求</option>
  11 + <option value=165>进场请求</option>
  12 + <option value=167>加油请求</option>
  13 + <option value=80>车辆故障</option>
  14 + <option value=112>路阻报告</option>
  15 + <option value=96>事故报告</option>
  16 + <option value=17>扣证纠纷</option>
  17 + <option value=18>报警</option>
18 18 </select>
19 19 </div>
20 20  
... ... @@ -47,7 +47,7 @@
47 47 </div>
48 48 </div>
49 49 <script id="device_report_list_temp" type="text/html">
50   -{{each content as item i}}
  50 +{{each list as item i}}
51 51 <tr>
52 52 <td width="7%" >
53 53 {{item.lineName}}
... ... @@ -103,6 +103,12 @@
103 103 jsDoQuery(true);
104 104 });
105 105  
  106 + //请求代码
  107 + $('#requestCodeSelect').on('change', function(){
  108 + page = 0;
  109 + jsDoQuery(true);
  110 + });
  111 +
106 112 function jsDoQuery(pagination){
107 113 var params = $form.serializeJSON();
108 114 params.page = page;
... ... @@ -110,7 +116,7 @@
110 116  
111 117 $.get('/directive/findAll80', params, function(rs){
112 118 //命令字转中文
113   - $.each(rs.content, function(){
  119 + $.each(rs.list, function(){
114 120 this.text = reqCodeMap[this.data.requestCode];
115 121  
116 122 if(this.handleTime)
... ...
src/main/resources/static/pages/control/line/css/lineControl.css
... ... @@ -2272,10 +2272,12 @@ tr._active .blue-badge{
2272 2272 color: #afafaf !important;
2273 2273 }
2274 2274  
2275   -.pb-table tr.selected.next-sch a{
  2275 +.pb-table tr.selected.next-sch a,
  2276 +.pb-table tr.selected.next-sch td.tl-xxfc{
2276 2277 color: white !important;
2277 2278 }
2278 2279  
  2280 +
2279 2281 .tab_line .pb-table tr._tr_active.active-line-no a.remarks-popover{
2280 2282 color: #bebebe;
2281 2283 }
... ... @@ -2511,4 +2513,9 @@ tr._tr_active.active-line-no .out-badge{
2511 2513  
2512 2514 span.nt-coord:before{
2513 2515 content: "...";
  2516 +}
  2517 +.updete_log p{
  2518 + font-size: 13px;
  2519 + text-indent: 15px;
  2520 + margin: 8px 0;
2514 2521 }
2515 2522 \ No newline at end of file
... ...
src/main/resources/static/pages/control/line/index.html
... ... @@ -40,12 +40,9 @@
40 40 <li>
41 41 <a href="javascript:;" id="ttsConfigure"> TTS 语音设置 </a>
42 42 </li>
43   - <!-- <li>
44   - <a href="javascript:;" id="reply80Config"> 设备上报处理 </a>
45   - </li>
46 43 <li>
47   - <a href="javascript:;" id=""> 停靠时间 </a>
48   - </li> -->
  44 + <a href="javascript:;" id="updateLogLink"> 更新日志 </a>
  45 + </li>
49 46 </ul>
50 47 </div>
51 48  
... ... @@ -230,6 +227,10 @@ function countDown(name){
230 227 <script src="/pages/control/line/js/home.js"></script>
231 228  
232 229 <script>
  230 +var updateLog = {
  231 + text: '<div class="updete_log"><p>1、调整实到实发匹配算法,调整了东川路电子围栏。</p><p>2、修复了烂班的班次指令会发送给驾驶员的问题。</p><p>3、修复了车辆到达终点后马上跳出下一班实发的问题。</p><p>4、修复轨迹回放缓冲区重复绘制问题。</p><p class="font-red">注意:进出场班次必须按照起点站划分上下行,如 兰坪路浦江路 ——> 停车场 必须是下行班次,否则该班次将不会有发车时间。</p></div>'
  232 + ,title: '2016年8月25号凌晨更新日志'
  233 +}
233 234  
234 235 var lineCodes = '' //全部线路编码字符串,由data.js初始化
235 236 , lineMap = {} //编码和线路详细对照,由data.js初始化;
... ...
src/main/resources/static/pages/control/line/js/alone.js
... ... @@ -142,7 +142,7 @@ var _alone = (function(){
142 142 var currTr = table.find('tr[data-id='+sch.id+']')
143 143 ,half = table.parents('._body').height() / 2
144 144 ,top = parseInt(currTr.find('td[name=lineNo]').text()) * 37 - half;
145   -
  145 +
146 146 top = top>0?top:0;
147 147 currTr.addClass('anim-delay animated flash').one(animationend, function(){
148 148 $(this).removeClass('anim-delay animated flash');
... ...
src/main/resources/static/pages/control/line/js/home.js
... ... @@ -84,6 +84,19 @@ var _home = (function() {
84 84 $('.load-anim').fadeOut(800);
85 85 $('menu.menu').show();
86 86 }, 400);
  87 +
  88 + setTimeout(function() {
  89 + // 提示文本
  90 + var promptFlag = storage.getItem('promptFlag_08251');
  91 + if (!promptFlag) {
  92 + layer.alert(updateLog.text, {
  93 + title: updateLog.title,
  94 + area: ['400px', '260px'],
  95 + shift : 5
  96 + });
  97 + storage.setItem('promptFlag_08251', 1);
  98 + }
  99 + }, 1500);
87 100 }
88 101 }
89 102  
... ...
src/main/resources/static/pages/control/line/js/messenger.js
... ... @@ -6,7 +6,7 @@ var _messenger = (function(){
6 6 ,ct = Date.parse(new Date()) / 1000
7 7 ,list, time, lineCode;
8 8  
9   - if(_data){
  9 + try {
10 10 var lineArray = _data.getLines();
11 11  
12 12 $.each(lineArray, function(){
... ... @@ -21,8 +21,9 @@ var _messenger = (function(){
21 21 //更新未处理的消息数量
22 22 setUntreatedNum(lineCode);
23 23 });
  24 + } catch (e) {
  25 + console.log(e);
24 26 }
25   -
26 27 setTimeout(f, 3000);
27 28 }();
28 29  
... ...
src/main/resources/static/pages/control/line/js/toolbarEvent.js
... ... @@ -61,5 +61,13 @@ var _toolbarEvent = (function(){
61 61 });
62 62 });
63 63  
  64 + $('#updateLogLink').on('click', function(){
  65 + layer.alert(updateLog.text, {
  66 + title: updateLog.title,
  67 + area: ['490px', '320px'],
  68 + shift : 5
  69 + });
  70 + });
  71 +
64 72 countDown('toolbarEvent.js');
65 73 })();
66 74 \ No newline at end of file
... ...
src/main/resources/static/pages/control/line/temps/alone_tp.html
... ... @@ -275,7 +275,7 @@
275 275  
276 276 <div class="form-custom-row">
277 277 <div class="item full" >
278   - <textarea class="form-control" rows="4" name="remarks" placeholder="烂班说明,必填" required></textarea>
  278 + <textarea class="form-control" rows="4" name="remarks" placeholder="烂班说明,必填" ></textarea>
279 279 </div>
280 280 </div>
281 281  
... ...
src/main/resources/static/pages/mapmonitor/real/bufferAreaConfig.html
... ... @@ -10,135 +10,17 @@
10 10 <li class=""><a href="#tab_other" data-toggle="tab"
11 11 aria-expanded="false"> 其他 </a></li>
12 12 </ul>
13   - <div class="tab-content" style="height: calc(100% - 46px);overflow-x: auto;">
  13 + <div class="tab-content" style="height: calc(100% - 46px);overflow-x: auto;padding: 20px 0;">
14 14 <div class="tab-pane active" id="tab_up">
15 15 <ul class="list">
16   - <li>
17   - <label>
18   - <input type="checkbox" class="icheck"> 东川路地铁站
19   - </label>
20   - </li>
21   - <li>
22   - <label>
23   - <input type="checkbox" class="icheck"> 东川路地铁站
24   - </label>
25   - </li>
26   - <li>
27   - <label>
28   - <input type="checkbox" class="icheck"> 东川路地铁站
29   - </label>
30   - </li>
31   - <li>
32   - <label>
33   - <input type="checkbox" class="icheck"> 东川路地铁站
34   - </label>
35   - </li>
36   - <li>
37   - <label>
38   - <input type="checkbox" class="icheck"> 东川路地铁站
39   - </label>
40   - </li>
41   - <li>
42   - <label>
43   - <input type="checkbox" class="icheck"> 东川路地铁站
44   - </label>
45   - </li>
46   - <li>
47   - <label>
48   - <input type="checkbox" class="icheck"> 东川路地铁站
49   - </label>
50   - </li>
51   - <li>
52   - <label>
53   - <input type="checkbox" class="icheck"> 东川路地铁站
54   - </label>
55   - </li>
56   - <li>
57   - <label>
58   - <input type="checkbox" class="icheck"> 东川路地铁站
59   - </label>
60   - </li>
61   - <li>
62   - <label>
63   - <input type="checkbox" class="icheck"> 东川路地铁站
64   - </label>
65   - </li>
66   - <li>
67   - <label>
68   - <input type="checkbox" class="icheck"> 东川路地铁站
69   - </label>
70   - </li>
71   - <li>
72   - <label>
73   - <input type="checkbox" class="icheck"> 东川路地铁站
74   - </label>
75   - </li>
76 16 </ul>
77 17 </div>
78 18 <div class="tab-pane" id="tab_down">
79 19 <ul class="list">
80   - <li>
81   - <label>
82   - <input type="checkbox" class="icheck"> 塘经路尚义路
83   - </label>
84   - </li>
85   - <li>
86   - <label>
87   - <input type="checkbox" class="icheck"> 塘经路尚义路
88   - </label>
89   - </li>
90   - <li>
91   - <label>
92   - <input type="checkbox" class="icheck"> 塘经路尚义路
93   - </label>
94   - </li>
95   - <li>
96   - <label>
97   - <input type="checkbox" class="icheck"> 塘经路尚义路
98   - </label>
99   - </li>
100   - <li>
101   - <label>
102   - <input type="checkbox" class="icheck"> 塘经路尚义路
103   - </label>
104   - </li>
105   - <li>
106   - <label>
107   - <input type="checkbox" class="icheck"> 塘经路尚义路
108   - </label>
109   - </li>
110   - <li>
111   - <label>
112   - <input type="checkbox" class="icheck"> 塘经路尚义路
113   - </label>
114   - </li>
115   - <li>
116   - <label>
117   - <input type="checkbox" class="icheck"> 塘经路尚义路
118   - </label>
119   - </li>
120   - <li>
121   - <label>
122   - <input type="checkbox" class="icheck"> 塘经路尚义路
123   - </label>
124   - </li>
125   - <li>
126   - <label>
127   - <input type="checkbox" class="icheck"> 塘经路尚义路
128   - </label>
129   - </li>
130 20 </ul>
131 21 </div>
132 22 <div class="tab-pane" id="tab_tcc">
133 23 <ul class="list">
134   - <li>
135   - <label>
136   - <input type="checkbox" class="icheck"> 江南旅游有限公司停车场
137   - </label>
138   - <label>
139   - <input type="checkbox" class="icheck"> 东川路停车场
140   - </label>
141   - </li>
142 24 </ul>
143 25 </div>
144 26 <div class="tab-pane" id="tab_other">
... ... @@ -149,22 +31,140 @@
149 31  
150 32 </div>
151 33  
  34 +<script id="buffer_area_station_temp" type="text/html">
  35 +{{each list as route i}}
  36 +<li>
  37 + <label>
  38 + <input type="checkbox" class="icheck" data-type="station" data-code="{{route.stationCode}}" data-dir={{route.directions}}> {{route.stationName}}
  39 + </label>
  40 +</li>
  41 +{{/each}}
  42 +</script>
  43 +
  44 +<script id="buffer_area_park_temp" type="text/html">
  45 +{{each list as park i}}
  46 +<li>
  47 + <label>
  48 + <input type="checkbox" class="icheck" data-type="park" data-code="{{park.parkCode}}"> {{park.parkName}}
  49 + </label>
  50 +</li>
  51 +{{/each}}
  52 +</script>
152 53 <script>
153 54 !function(){
154   - $('#bufferAreaConfigPanel').on('init', function(e, lineCode ,buffAeraArray){
155   - //获取站点缓冲区数据
  55 + var iMap, selItems;
  56 + $('#bufferAreaConfigPanel').on('init', function(e, lineCode ,selBuffAera, mapObj){
  57 + iMap = mapObj;
  58 + selItems= selBuffAera;
  59 +
  60 + var temp = 'buffer_area_station_temp'
  61 + ,parkTemp = 'buffer_area_park_temp';
156 62 $get('/stationroute/all', {'line.lineCode_eq': lineCode, 'destroy_eq': 0}, function(routes){
157   - console.log(routes);
  63 + //排序
  64 + routes.sort(function(a, b){
  65 + return a.stationRouteCode - b.stationRouteCode;
  66 + });
  67 +
  68 + //上下行分组
  69 + var ups = [],downs = [];
  70 + $.each(routes, function(){
  71 + if(this.directions == 0)
  72 + ups.push(this);
  73 + else
  74 + downs.push(this);
  75 + });
  76 +
  77 + $('#bufferAreaConfigPanel #tab_up ul').html(template(temp, {list: ups}));
  78 + $('#bufferAreaConfigPanel #tab_down ul').html(template(temp, {list: downs}));
  79 +
  80 + //停车场数据
  81 + $.get('/carpark/all', function(parks){
  82 + $('#bufferAreaConfigPanel #tab_tcc ul').html(template(parkTemp, {list: parks}));
  83 +
  84 + //默认选中项
  85 + for(var code in selItems){
  86 + $('.icheck[data-code='+code+']').iCheck('check');
  87 + }
  88 +
  89 + initICheck();
  90 + });
158 91 });
159   -
  92 + });
  93 +
  94 + function initICheck(){
  95 + //icheck
160 96 $('#bufferAreaConfigPanel').find('.icheck').iCheck({
161 97 checkboxClass: 'icheckbox_square-green',
162 98 increaseArea: '20%'
163 99 })
164 100 .on('ifChanged', function(){
165   -
  101 + var code = $(this).data('code')
  102 + ,type = $(this).data('type');
  103 + if(this.checked)
  104 + drawBuffAera(code, type, colour($(this).data('dir')));
  105 + else{
  106 + //删除缓冲区
  107 + if(selItems[code]){
  108 + iMap.call('clearBuffArea', [code]);
  109 + selItems[code] = null;
  110 + delete selItems[code];
  111 + }
  112 + }
166 113 });
  114 + }
  115 +
  116 + function colour(dir){
  117 + var color;
  118 + if(dir == null)
  119 + color = '#333333';
  120 + else if(dir == 0)
  121 + color = 'blue';
  122 + else if(dir == 1)
  123 + color = 'red';
  124 + return color;
  125 + }
  126 +
  127 + function drawBuffAera(code, type, color){
  128 + $.get('/gps/buffAera', {code: code, type: type}, function(rs){
  129 + rs.color = color;
  130 + if(rs.type == 'r')
  131 + drawCircle(rs);
  132 + else if(rs.type == 'd')
  133 + drawPolygon(rs);
  134 + //保存选中项
  135 + selItems[code] = 1;
  136 + });
  137 + }
  138 +
  139 + function drawCircle(data){
  140 + var wgs = data.cPoint.split(' ');
  141 + var opt = {
  142 + lon: parseFloat(wgs[0]),
  143 + lat: parseFloat(wgs[1]),
  144 + text: data.text,
  145 + color: data.color,
  146 + weight: 2,
  147 + radius: parseFloat(data.radius),
  148 + id: data.code
  149 + };
167 150  
168   - });
  151 + iMap.call('drawCircle', opt);
  152 + }
  153 +
  154 + function drawPolygon(data){
  155 + var cdsArray = [];
  156 + var polyStr = coords = data.polygon.substring(9, data.polygon.length - 2);
  157 + cdsArray = polyStr.split(',');
  158 +
  159 + var opt = {
  160 + cds: cdsArray,
  161 + text: data.text,
  162 + color: data.color,
  163 + weight: 2,
  164 + radius: parseFloat(data.radius),
  165 + id: data.code
  166 + };
  167 + iMap.call('drawPolygon', opt);
  168 + }
169 169 }();
170 170 </script>
171 171 \ No newline at end of file
... ...
src/main/resources/static/pages/mapmonitor/real/css/real.css
... ... @@ -843,11 +843,18 @@ html{
843 843 font-weight: 600;
844 844 margin-right: 5px;
845 845 color: #c7c7c7;
846   - padding: 4px 3px 0 8px;
  846 + padding: 10px 3px 10px 8px;
847 847 cursor: pointer;
848 848 border-left: 1px solid #4b4a4a;
849 849 }
850 850  
  851 +#bufferArea.angle-up-item{
  852 + font-weight: 400;
  853 + font-size: 13px;
  854 + border-right: 1px solid #4b4a4a;
  855 + padding-right: 12px;
  856 +}
  857 +
851 858 .angle-up-item:HOVER{
852 859 background: #484949;
853 860 }
... ...
src/main/resources/static/pages/mapmonitor/real/js/map/platform/baidu.js
... ... @@ -8,6 +8,7 @@ var baiduMap = (function(){
8 8 var traffVisible;
9 9 //线路 Polyline
10 10 var linePolyline;
  11 + var buffAreas = {};
11 12 var baiduInstance = {
12 13 //初始化
13 14 init: function(){
... ... @@ -15,11 +16,9 @@ var baiduMap = (function(){
15 16 //中心点和缩放级别
16 17 map.centerAndZoom(new BMap.Point(consts.center_point.lng, consts.center_point.lat), 15);
17 18 map.enableScrollWheelZoom();
18   - //加载完成
19   - map.addEventListener("tilesloaded", function() {
20   - layer.closeAll();
21   - window.localStorage.setItem('real_map', 'baidu');
22   - });
  19 +
  20 + layer.closeAll();
  21 + window.localStorage.setItem('real_map', 'baidu');
23 22  
24 23 // 路况控件
25 24 var ctrl = new BMapLib.TrafficControl();
... ... @@ -133,6 +132,38 @@ var baiduMap = (function(){
133 132 var deviceId = opts.deviceId
134 133 ,m = realMarkers[deviceId];
135 134 bdOpenWindow(m);
  135 + },
  136 + //绘制圆形
  137 + drawCircle: function(opts){
  138 + var coord = TransGPS.wgsToBD(opts.lat, opts.lon);
  139 + var circle = new BMap.Circle(new BMap.Point(coord.lng, coord.lat), opts.radius);
  140 + if(opts.color)
  141 + circle.setStrokeColor(opts.color);
  142 + if(opts.weight)
  143 + circle.setStrokeWeight(opts.weight);
  144 +
  145 + map.addOverlay(circle);
  146 + buffAreas[opts.id] = circle;
  147 + },
  148 + //绘制多边形
  149 + drawPolygon: function(opts){
  150 + var wgs,coord, points = [];
  151 + $.each(opts.cds, function(){
  152 + wgs = this.split(' ');
  153 + coord = TransGPS.wgsToBD(parseFloat(wgs[1]), parseFloat(wgs[0]));
  154 + points.push(new BMap.Point(coord.lng, coord.lat));
  155 + });
  156 +
  157 + var polygon = new BMap.Polygon(points, {strokeColor: opts.color, strokeWeight: opts.weight, strokeOpacity: 0.7});
  158 + map.addOverlay(polygon);
  159 + buffAreas[opts.id] = polygon;
  160 + },
  161 + //删除缓冲区
  162 + clearBuffArea: function(code){
  163 + if(buffAreas[code]){
  164 + map.removeOverlay(buffAreas[code]);
  165 + delete buffAreas[code];
  166 + }
136 167 }
137 168 };
138 169  
... ...
src/main/resources/static/pages/mapmonitor/real/js/playBack.js
... ... @@ -133,23 +133,34 @@ var playBack = (function() {
133 133 });
134 134  
135 135 //被选中的缓冲区
136   - var buffAeraArray = [];
  136 + var buffAeraArray = {}, bConfLayer;
137 137 //缓冲区
138 138 $('#bufferArea').on('click', function(){
  139 + if(bConfLayer){
  140 + layer.close(bConfLayer);
  141 + bConfLayer = null;
  142 + return;
  143 + }
  144 +
139 145 //计算弹出位置
140 146 var top = $(this).offset().top - 450
141 147 ,left = $(this).offset().left - 230 / 2;
142 148 $.get('/pages/mapmonitor/real/bufferAreaConfig.html', function(rs){
143   - layer.open({
  149 +
  150 + bConfLayer = layer.open({
144 151 type: 1,
145 152 area: ['280px', '430px'],
146 153 offset: [top, left],
147 154 title: false,
148 155 content: rs,
149   - shift :4,
150   - shadeClose: true,
  156 + shift :5,
  157 + shade : 0,
  158 + shadeClose: false,
151 159 success: function(){
152   - $('#bufferAreaConfigPanel').trigger('init', [defaultLine, buffAeraArray]);
  160 + $('#bufferAreaConfigPanel').trigger('init', [defaultLine, buffAeraArray, iMap]);
  161 + },
  162 + end: function(){
  163 + bConfLayer = null;
153 164 }
154 165 });
155 166 });
... ... @@ -276,6 +287,7 @@ var playBack = (function() {
276 287 else
277 288 layer.closeAll();
278 289 });
  290 + buffAeraArray = {};
279 291 }
280 292 else
281 293 play();
... ...
src/main/resources/static/pages/mapmonitor/real/js/real.js
... ... @@ -63,15 +63,10 @@
63 63 var toolsEvent = {
64 64 // 车辆
65 65 vehicle : function() {
66   -
67   - /*mrw.html('').addClass('to_vehicle vehicle');
68   - resetRotate(null, vehiclePanel.showData);*/
69 66 mrw.html('').addClass('vehicle');
70 67 lineGroup.showData();
71 68 },
72 69 search : function() {
73   - /*mrw.html('').addClass('to_searchPanel search');
74   - resetRotate(null, searchPanel.init);*/
75 70 mrw.html('').addClass('search');
76 71 searchPanel.init();
77 72 },
... ... @@ -79,8 +74,6 @@
79 74 alert('notice');
80 75 },
81 76 playBack : function() {
82   - /*mrw.html('').addClass('to_playBack playBack');
83   - resetRotate(null, playBack.init);*/
84 77 mrw.html('').addClass('playBack');
85 78 playBack.init();
86 79  
... ... @@ -94,13 +87,6 @@
94 87 // 地图切换
95 88 $('#mapTypeDrop li').on('click', function() {
96 89 iMap.changeDefault(this.id);
97   - /*var type = $('.mapTools .item.active').data('click');
98   - if(type == 'vehicle'){
99   - var activePanel = $('.mapRightWrap .panel-collapse.collapse.in');
100   - if(activePanel.length > 0){
101   - vehiclePanel.drawLineAndGps(activePanel.data('line'));
102   - }
103   - }*/
104 90 });
105 91  
106 92 // 关闭左侧栏
... ... @@ -111,27 +97,6 @@
111 97 $('#mapContainer').height($(pjaxContainer).height() + 49);
112 98  
113 99 mrw.html(spinnerLoad);
114   - //realMap.init();
115 100 lineGroup.showDataLazy();
116 101  
117   - //function init(){
118   - /*//初始化地图
119   - (function(){
120   - var f = arguments.callee;
121   - try {
122   - realMap.init();
123   - } catch (e) {
124   - setTimeout(f , 100);
125   - }
126   - })();
127   - //初始化车辆列表
128   - (function(){
129   - var f = arguments.callee;
130   - try {
131   - vehiclePanel.showDataLazy();
132   - } catch (e) {
133   - setTimeout(f , 100);
134   - }
135   - })();*/
136   - //}
137 102 }();
138 103 \ No newline at end of file
... ...
src/main/resources/static/pages/mapmonitor/real/real.html
... ... @@ -64,7 +64,7 @@
64 64 </div>
65 65  
66 66 <div class="dropup" >
67   - <span class="angle-up-item" id="bufferArea" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  67 + <span class="angle-up-item" id="bufferArea" >
68 68 <span>缓冲区</span><i class="fa fa-angle-up" ></i>
69 69 </span>
70 70 </div>
... ...