Commit c4167f3d05fd4f7f6a5720a4c3dfbec538fc63d8

Authored by panzh
1 parent 04521cb1

update...

src/main/java/com/bsth/StartCommand.java
... ... @@ -2,9 +2,11 @@ package com.bsth;
2 2  
3 3 import com.bsth.client.ClientApp;
4 4 import com.bsth.data.BasicCacheData;
  5 +import com.bsth.data.charts_data.AccuracyDataHandler;
5 6 import com.bsth.data.geo.loader.thread.DataLoadThread;
6 7 import com.bsth.data.gps.process.DataMainProcessor;
7 8 import com.bsth.data.history.HistoryConsumeTimeDataHandler;
  9 +import com.bsth.data.history.recovery.RecoveryByHistoryGps;
8 10 import com.bsth.data.schedule.ScheduleCacheData;
9 11 import org.slf4j.Logger;
10 12 import org.slf4j.LoggerFactory;
... ... @@ -40,6 +42,12 @@ public class StartCommand implements CommandLineRunner {
40 42 @Autowired
41 43 HistoryConsumeTimeDataHandler historyConsumeTimeDataHandler;
42 44  
  45 + @Autowired
  46 + AccuracyDataHandler accuracyDataHandler;
  47 +
  48 + @Autowired
  49 + RecoveryByHistoryGps recoveryByHistoryGps;
  50 +
43 51 Logger logger = LoggerFactory.getLogger(this.getClass());
44 52  
45 53 @Override
... ... @@ -57,16 +65,25 @@ public class StartCommand implements CommandLineRunner {
57 65 logger.info("load geo data end...");
58 66 sexec.scheduleWithFixedDelay(fixedLoadCacheThread, 60 * 300, 60 * 300, TimeUnit.SECONDS);
59 67  
60   - //定时刷新班次信息
61   - sexec.scheduleWithFixedDelay(refreshScheduleCacheThread, 60, 30, TimeUnit.SECONDS);
62 68  
63   - //gps socket client
64   - clientApp.init();
65   - //gps 数据处理
66   - dataMainProcessor.start();
  69 + /**/ //定时刷新班次信息
  70 + sexec.scheduleWithFixedDelay(refreshScheduleCacheThread, 60, 30, TimeUnit.SECONDS);
  71 +
  72 + //gps socket client
  73 + clientApp.init();
  74 + //gps 数据处理
  75 + dataMainProcessor.start();
  76 +
  77 + //历史站点耗时数据
  78 + historyConsumeTimeDataHandler.start();
  79 +
  80 + //预测准确性
  81 + accuracyDataHandler.start();
  82 +
  83 +
67 84  
68   - //历史站点耗时数据
69   - historyConsumeTimeDataHandler.start();
  85 + //historyConsumeTimeDataHandler.start();//历史站点耗时数据
  86 + //recoveryByHistoryGps.recovery();//恢复到离站
70 87 } catch (Exception e) {
71 88 e.printStackTrace();
72 89 }
... ...
src/main/java/com/bsth/controller/AccuracyDataController.java 0 → 100644
  1 +package com.bsth.controller;
  2 +
  3 +import com.bsth.entity.Accuracy;
  4 +import com.bsth.service.AccuracyDataService;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.web.bind.annotation.RequestMapping;
  7 +import org.springframework.web.bind.annotation.RequestParam;
  8 +import org.springframework.web.bind.annotation.RestController;
  9 +
  10 +import java.util.List;
  11 +
  12 +@RestController
  13 +@RequestMapping("accuracy_data")
  14 +public class AccuracyDataController {
  15 +
  16 + @Autowired
  17 + AccuracyDataService accuracyDataService;
  18 +
  19 + @RequestMapping("search")
  20 + public List<Accuracy> search(@RequestParam String rq
  21 + , @RequestParam String lineCode
  22 + , @RequestParam String st
  23 + , @RequestParam String et, String nbbm) {
  24 +
  25 + return accuracyDataService.search(rq, lineCode, st, et, nbbm);
  26 + }
  27 +}
... ...
src/main/java/com/bsth/data/charts_data/AccuracyDataHandler.java
... ... @@ -3,8 +3,10 @@ package com.bsth.data.charts_data;
3 3 import com.alibaba.fastjson.JSON;
4 4 import com.bsth.Application;
5 5 import com.bsth.controller.dto.CarMonitorEntity;
  6 +import com.bsth.data.geo.GeoCacheData;
6 7 import com.bsth.entity.Accuracy;
7 8 import com.bsth.entity.GpsEntity;
  9 +import com.bsth.entity.StationRoute;
8 10 import com.bsth.util.IpUtils;
9 11 import com.bsth.util.db_utils.DBUtils_InfoPublish;
10 12 import com.google.common.collect.*;
... ... @@ -82,8 +84,9 @@ public class AccuracyDataHandler {
82 84 //params
83 85 accuracy.setLineCode(gps.getLineId());
84 86 accuracy.setUpDown(gps.getUpDown());
85   - accuracy.setStation(station);
86   - accuracy.setT1(gps.getTimestamp());
  87 + StationRoute sr = GeoCacheData.findByCode(gps.getLineId(), gps.getUpDown(), station);
  88 + accuracy.setStation(null == sr ? station : sr.getName());
  89 + accuracy.setT1(System.currentTimeMillis());
87 90 accuracy.setNbbm(gps.getNbbm());
88 91 accuracy.setPlate(near.getPlate());
89 92 accuracy.setStopDis(near.getStopdis());
... ... @@ -108,9 +111,8 @@ public class AccuracyDataHandler {
108 111 if (null == list || list.size() == 0)
109 112 return;
110 113  
111   -
112 114 for (Accuracy a : list) {
113   - a.setT2(gps.getTimestamp());
  115 + a.setT2(gps.getServerTimestamp());
114 116 a.setRealSeconds((int) ((a.getT2() - a.getT1()) / 1000));
115 117 a.setD2(gps.getInStationDistance());
116 118  
... ...
src/main/java/com/bsth/data/gps/process/chains/ForecastProcess.java
... ... @@ -28,7 +28,7 @@ public class ForecastProcess {
28 28 if (isValidSignal(list)) {
29 29 GpsEntity first = list.get(0);
30 30 double sumDist = GeoUtils.getDistance(first, gps);//行驶距离
31   - double seconds = (gps.getTimestamp() - first.getTimestamp()) / 1000 - 30;//耗时
  31 + double seconds = (gps.getTimestamp() - first.getTimestamp()) / 1000 - 45;//耗时
32 32 double avgSpeed = sumDist / seconds;//均速
33 33 gps.setSeconds((int) (gps.getDistance() / avgSpeed));//到下一站的时间
34 34 } else {
... ...
src/main/java/com/bsth/data/history/HistoryConsumeTimeDataHandler.java
... ... @@ -60,7 +60,7 @@ public class HistoryConsumeTimeDataHandler {
60 60 private final static int IN_STATION_SPEED = 15;
61 61  
62 62 //按实时路段距离换算时间时,给的默认速度
63   - private final static int DEFAULT_SPEED = 18;
  63 + private final static int DEFAULT_SPEED = 10;
64 64  
65 65 /**
66 66 * K : lineCode_upDown
... ... @@ -230,7 +230,7 @@ public class HistoryConsumeTimeDataHandler {
230 230 dt.minusDays(7);//减7天
231 231 String rq = dt.toString("yyyyMMdd ");
232 232  
233   - rq = "20180627";
  233 + rq = "20180625";
234 234 String sql = "select * from bsth_h_consume_time where rq=" + rq;
235 235 JdbcTemplate jdbcTemplate = new JdbcTemplate(DBUtils_InfoPublish.getDataSource());
236 236 List<StationConsumeTime> list =
... ... @@ -428,7 +428,7 @@ public class HistoryConsumeTimeDataHandler {
428 428 List<StationConsumeTime> list = new ArrayList<>();
429 429 try {
430 430 StationConsumeTime sct;
431   - for (int i = 0; i < 1000; i++) {
  431 + for (int i = 0; i < 4000; i++) {
432 432 sct = pstQueue.poll();
433 433 if (null == sct)
434 434 break;
... ...
src/main/java/com/bsth/data/history/recovery/RecoveryByHistoryGps.java
... ... @@ -30,13 +30,21 @@ public class RecoveryByHistoryGps {
30 30  
31 31 public void recovery() {
32 32  
33   - Collection<Line> lines = BasicCacheData.code2LineMap.values();
  33 + List<Line> lines = new ArrayList<>(BasicCacheData.code2LineMap.values());
34 34  
35 35 List<GpsEntity> list;
36   - for (Line line : lines) {
37   - list = loadByLineCode(line.getLineCode(), 176);
  36 + Line line;
  37 + for (int i = 0, len = lines.size(); i < len; i++) {
  38 + line = lines.get(i);
38 39  
39   - handler(list);
  40 + try {
  41 + logger.info("线路:" + line.getName() + " -i: " + i + " -size: " + len);
  42 + list = loadByLineCode(line.getLineCode(), 177);
  43 +
  44 + handler(list);
  45 + } catch (Exception e) {
  46 + logger.error("", e);
  47 + }
40 48 }
41 49 }
42 50  
... ... @@ -44,7 +52,7 @@ public class RecoveryByHistoryGps {
44 52 //按设备号分组
45 53 ArrayListMultimap<String, GpsEntity> listMap = ArrayListMultimap.create();
46 54 for (GpsEntity gps : list) {
47   - if (gps.getDeviceId() != null) {
  55 + if (gps.getDeviceId() != null && gps.getValid() == 0) {
48 56 gps.setNbbm(BasicCacheData.device2nbbmMap.get(gps.getDeviceId()));
49 57 listMap.put(gps.getDeviceId(), gps);
50 58 }
... ... @@ -71,7 +79,7 @@ public class RecoveryByHistoryGps {
71 79 logger.info("load gps start -" + lineCode);
72 80 JdbcTemplate jdbcTemplate = new JdbcTemplate(DBUtils_InfoPublish.getDataSource());
73 81  
74   - String sql = "select DEVICE_ID,LAT,LON,TS,SPEED_GPS,LINE_ID,SERVICE_STATE,SERVER_TS from bsth_c_gps_info_2018 where days_year=" + days_year + " and line_id='" + lineCode + "'";
  82 + String sql = "select DEVICE_ID,LAT,LON,TS,SPEED_GPS,LINE_ID,SERVICE_STATE,SERVER_TS from test_gps_info177all where days_year=" + days_year + " and line_id='" + lineCode + "'";
75 83 List<GpsEntity> list =
76 84 jdbcTemplate.query(sql, (rs, rowNum) -> {
77 85 GpsEntity gps = new GpsEntity();
... ... @@ -85,6 +93,7 @@ public class RecoveryByHistoryGps {
85 93 gps.setUpDown((byte) getUpOrDown(rs.getLong("SERVICE_STATE")));
86 94 gps.setServerTimestamp(rs.getLong("SERVER_TS"));
87 95 gps.setState((int) getService(rs.getLong("SERVICE_STATE")));
  96 + gps.setValid(getGpsValid(rs.getLong("SERVICE_STATE")));
88 97 return gps;
89 98 });
90 99  
... ... @@ -92,6 +101,10 @@ public class RecoveryByHistoryGps {
92 101 return list;
93 102 }
94 103  
  104 + public static byte getGpsValid(long serviceState) {
  105 + return (byte) (((serviceState & 0x80000000) == 0x80000000) ? 1 : 0);
  106 + }
  107 +
95 108 public static int getUpOrDown(long serviceState) {
96 109 if ((serviceState & 0x00020000) == 0x00020000 || (serviceState & 0x80000000) == 0x80000000
97 110 || (serviceState & 0x01000000) == 0x01000000 || (serviceState & 0x08000000) == 0x08000000)
... ... @@ -109,7 +122,7 @@ public class RecoveryByHistoryGps {
109 122 @Override
110 123 public int compare(GpsEntity g1, GpsEntity g2) {
111 124 if (g1.getTimestamp() == g2.getTimestamp())
112   - return -1;
  125 + return 0;
113 126 return (int) (g1.getTimestamp() - g2.getTimestamp());
114 127 }
115 128 }
... ...
src/main/java/com/bsth/entity/GpsEntity.java
... ... @@ -163,8 +163,8 @@ public class GpsEntity implements Serializable {
163 163  
164 164 public void smoothTransition(long t) {
165 165 int diff = (int) (t - timestamp), newSeconds;
166   - //掉线1分半的,平滑过渡一下预测时间
167   - if (diff > 1000 * 60 * 1.5) {
  166 + //时间差半分钟的,平滑过渡一下预测时间
  167 + if (diff > 1000 * 30) {
168 168 newSeconds = seconds - (diff / 1000 - 15);
169 169 seconds2 = newSeconds < 0 ? 0 : newSeconds;
170 170 }
... ...
src/main/java/com/bsth/service/AccuracyDataService.java 0 → 100644
  1 +package com.bsth.service;
  2 +
  3 +import com.bsth.entity.Accuracy;
  4 +
  5 +import java.util.List;
  6 +
  7 +public interface AccuracyDataService {
  8 +
  9 + List<Accuracy> search(String rq
  10 + , String lineCode
  11 + , String st
  12 + , String et, String nbbm);
  13 +}
... ...
src/main/java/com/bsth/service/impl/AccuracyDataServiceImpl.java 0 → 100644
  1 +package com.bsth.service.impl;
  2 +
  3 +import com.bsth.entity.Accuracy;
  4 +import com.bsth.service.AccuracyDataService;
  5 +import com.bsth.util.db_utils.DBUtils_InfoPublish;
  6 +import org.apache.commons.lang3.StringUtils;
  7 +import org.joda.time.format.DateTimeFormat;
  8 +import org.joda.time.format.DateTimeFormatter;
  9 +import org.slf4j.Logger;
  10 +import org.slf4j.LoggerFactory;
  11 +import org.springframework.jdbc.core.BeanPropertyRowMapper;
  12 +import org.springframework.jdbc.core.JdbcTemplate;
  13 +import org.springframework.stereotype.Service;
  14 +
  15 +import java.util.List;
  16 +
  17 +@Service
  18 +public class AccuracyDataServiceImpl implements AccuracyDataService {
  19 +
  20 + Logger logger = LoggerFactory.getLogger(this.getClass());
  21 +
  22 + private static DateTimeFormatter fmtyyyyMMddHHmm = DateTimeFormat.forPattern("yyyyMMddHH:mm");
  23 +
  24 + @Override
  25 + public List<Accuracy> search(String rq, String lineCode, String st, String et, String nbbm) {
  26 + List<Accuracy> list = null;
  27 + try {
  28 +
  29 + rq = rq.replaceAll("-", "");
  30 + long s = fmtyyyyMMddHHmm.parseMillis(rq + st);
  31 + long e = fmtyyyyMMddHHmm.parseMillis(rq + et);
  32 +
  33 + String sql = "select * from bsth_h_forecast_accuracy where rq=" + rq + " and line_code='" + lineCode + "' and t1>=" + s + " and t1<=" + e;
  34 + if (StringUtils.isNotBlank(nbbm))
  35 + sql += " and nbbm like '%" + nbbm + "%'";
  36 +
  37 + sql += " order by t1";
  38 + JdbcTemplate jdbcTemplate = new JdbcTemplate(DBUtils_InfoPublish.getDataSource());
  39 + list = jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(Accuracy.class));
  40 + } catch (Exception e) {
  41 + logger.error("", e);
  42 + }
  43 + return list;
  44 + }
  45 +}
... ...
src/main/resources/static/index.html
... ... @@ -161,7 +161,7 @@
161 161 $('.left_menus ul>li.nav-item.active').removeClass('active');
162 162 $(this).parents('li.nav-item').addClass('active');
163 163 return false;
164   - }).eq(4).trigger('click');
  164 + }).eq(5).trigger('click');
165 165  
166 166  
167 167 $('body').bootstrapMaterialDesign();
... ...
src/main/resources/static/pages/charts_data/accuracy.html
1   -aaaa
2 1 \ No newline at end of file
  2 +<style>
  3 + #accuracy_data_page .table_wrap {
  4 + height: calc(100% - 70px);
  5 + margin-top: 25px;
  6 + }
  7 +
  8 + #accuracy_data_page div.data_list {
  9 + overflow: auto;
  10 + height: calc(100% - 66px);
  11 + display: block;
  12 + position: relative;
  13 + font-size: 14px;
  14 + }
  15 +
  16 + #accuracy_data_page table th:nth-of-type(1), #accuracy_data_page table td:nth-of-type(1) {
  17 + width: 10%;
  18 + }
  19 +
  20 + #accuracy_data_page table th:nth-of-type(2), #accuracy_data_page table td:nth-of-type(2) {
  21 + width: 10%;
  22 + }
  23 +
  24 + #accuracy_data_page table th:nth-of-type(3), #accuracy_data_page table td:nth-of-type(3) {
  25 + width: 10%;
  26 + }
  27 +
  28 + #accuracy_data_page table th:nth-of-type(4), #accuracy_data_page table td:nth-of-type(4) {
  29 + width: 10%;
  30 + }
  31 +
  32 + #accuracy_data_page table th:nth-of-type(5), #accuracy_data_page table td:nth-of-type(5) {
  33 + width: 10%;
  34 + }
  35 +
  36 + #accuracy_data_page table th:nth-of-type(6), #accuracy_data_page table td:nth-of-type(6) {
  37 + width: 10%;
  38 + }
  39 +
  40 + #accuracy_data_page table th:nth-of-type(7), #accuracy_data_page table td:nth-of-type(7) {
  41 + width: 10%;
  42 + }
  43 +
  44 + #accuracy_data_page table th:nth-of-type(8), #accuracy_data_page table td:nth-of-type(8) {
  45 + width: 10%;
  46 + }
  47 +
  48 + #accuracy_data_page table th:nth-of-type(9), #accuracy_data_page table td:nth-of-type(9) {
  49 + width: 10%;
  50 + }
  51 +
  52 + #accuracy_data_page table th:nth-of-type(10), #accuracy_data_page table td:nth-of-type(10) {
  53 + width: 10%;
  54 + }
  55 +
  56 + table i.material-icons {
  57 + font-size: 16px !important;
  58 + vertical-align: middle !important;
  59 + color: #FFC107;
  60 + margin-left: 2px;
  61 + cursor: default;
  62 + }
  63 +</style>
  64 +<div class="container-fluid page" id="accuracy_data_page">
  65 + <div class="card">
  66 +
  67 + <div class="card-body" style="height: 100%">
  68 + <div class="top_form_card" style="width: 100%;">
  69 + <form>
  70 + <div class="row">
  71 + <div class="col-md-2">
  72 + <div class="form-group">
  73 + <label class="bmd-label-floating">日期</label>
  74 + <input type="text" name="rq" required class="form-control flatpickr_date"
  75 + value="2018-07-02">
  76 + </div>
  77 + </div>
  78 + <div class="col-md-2">
  79 + <div class="form-group">
  80 + <label class="bmd-label-floating">线路</label>
  81 + <div class="ct_auto_wrap line_autocompleter">
  82 + <input type="text" name="lineName" required class="form-control" autocomplete="off">
  83 + </div>
  84 + </div>
  85 + </div>
  86 + <div class="col-md-2" style="padding-right: 0">
  87 + <div class="form-group">
  88 + <label class="bmd-label-floating">时间</label>
  89 + <input type="time" name="st" required class="form-control flatpickr_time" value="00:00">
  90 + </div>
  91 + </div>
  92 + <div class="col-md-2" style="padding-left: 0">
  93 + <div class="form-group">
  94 + <label class="bmd-label-floating">至</label>
  95 + <input type="time" name="et" required class="form-control flatpickr_time" value="23:00">
  96 + </div>
  97 + </div>
  98 + <div class="col-md-2">
  99 + <div class="form-group">
  100 + <label class="bmd-label-floating">车辆</label>
  101 + <input type="text" name="nbbm" class="form-control " autocomplete="off">
  102 + </div>
  103 + </div>
  104 + <div class="col-md-1">
  105 + <div class="form-group">
  106 + <button type="submit" class="btn btn-primary btn-raised" style="margin-top: 22px;">
  107 + <i class="material-icons">search</i> 搜索
  108 + </button>
  109 + </div>
  110 + </div>
  111 + </div>
  112 + </form>
  113 + </div>
  114 +
  115 + <div class="table_wrap">
  116 + <div class="table-responsive">
  117 + <table class="table table-hover" style="margin-bottom: 0;">
  118 + <thead class="">
  119 + <th>发布时间</th>
  120 + <th>站点</th>
  121 + <th>自编号</th>
  122 + <th>车牌号</th>
  123 + <th>站数</th>
  124 + <th>距离(米)</th>
  125 + <th>预计(秒)</th>
  126 + <th>实际(秒)</th>
  127 + <th>dd2</th>
  128 + <th>状态</th>
  129 + </thead>
  130 + </table>
  131 +
  132 + <div class="data_list">
  133 + <table class="table table-hover">
  134 + <tbody></tbody>
  135 + </table>
  136 + </div>
  137 + </div>
  138 + </div>
  139 + </div>
  140 + </div>
  141 +</div>
  142 +
  143 +<script id="accuracy_list-temp" type="text/html">
  144 + {{each list as obj i}}
  145 + <tr>
  146 + <td>{{obj.timeStr}}</td>
  147 + <td>{{obj.station}}</td>
  148 + <td>{{obj.nbbm}}</td>
  149 + <td>{{obj.plate}}</td>
  150 + <td>{{obj.stopDis}}</td>
  151 + <td>{{obj.distance}}</td>
  152 + <td>{{obj.seconds}}</td>
  153 + <td>{{obj.realSeconds}}</td>
  154 + <td>{{obj.d2}}</td>
  155 + <td>
  156 + {{if obj.status == 1}}
  157 + <span class="badge badge-success">准</span>
  158 + {{else if obj.status == -1}}
  159 + <span class="badge badge-danger">不准确</span>
  160 + {{/if}}
  161 + </td>
  162 + </tr>
  163 + {{/each}}
  164 +</script>
  165 +
  166 +<script>
  167 + (function () {
  168 + var wrap = '#accuracy_data_page';
  169 +
  170 + flatpickr(wrap + ' .flatpickr_date', flatpickrDateConfig);
  171 + $('[data-toggle="tooltip"]').tooltip();
  172 + //滚动条
  173 + $('div.data_list', wrap).perfectScrollbar({suppressScrollX: true});
  174 + //线路自动补全
  175 + $.get('/basic/lines', function (rs) {
  176 + var data = [], item;
  177 + for (var i = 0, len = rs.length; i < len; i++) {
  178 + item = rs[i];
  179 + data.push({
  180 + code: item.lineCode,
  181 + text: item.name,
  182 + others: [item.fullChars, item.camelChars]
  183 + });
  184 + }
  185 + gb_ct_autocompleter.build($('.line_autocompleter', wrap), data);
  186 + });
  187 +
  188 +
  189 + var f = $('form', wrap);
  190 + f.on('submit', function () {
  191 + try {
  192 + query();
  193 + } catch (e) {
  194 + console.log(e);
  195 + }
  196 + return false;
  197 + });
  198 +
  199 + function query() {
  200 + var data = f.serializeJSON();
  201 + data.lineCode = $('[name=lineName]', f).data('val');
  202 + if (!data.rq) {
  203 + gb_utils.showNotification('参数异常', '必须选择日期', 'danger');
  204 + return;
  205 + }
  206 +
  207 + $.get('/accuracy_data/search', data, function (rs) {
  208 + var diff;
  209 + for (var i = 0, len = rs.length; i < len; i++) {
  210 + rs[i].timeStr = moment(rs[i].t1).format('HH:mm');
  211 +
  212 + diff = Math.abs(rs[i]['realSeconds'] - rs[i]['seconds']);
  213 + //是否准点
  214 + if (diff > 60 * 3)
  215 + rs[i].status = -1;
  216 + else {
  217 +
  218 + if (diff / rs[i]['stopDis'] < 40)
  219 + rs[i].status = 1;
  220 + else
  221 + rs[i].status = -1;
  222 + }
  223 + }
  224 +
  225 + var htmlStr = template('accuracy_list-temp', {list: rs});
  226 +
  227 + $('div.data_list>table tbody', wrap).html(htmlStr);
  228 + $('div.data_list', wrap).perfectScrollbar('update');
  229 + });
  230 + }
  231 + })();
  232 +</script>
3 233 \ No newline at end of file
... ...