Commit 14ac7c5220c0929e2da8a6a12838474b53308ce2
1 parent
aff94c8c
update...
Showing
7 changed files
with
81 additions
and
34 deletions
src/main/java/com/bsth/data/charts_data/AccuracyDataHandler.java
| @@ -9,7 +9,8 @@ import com.bsth.entity.GpsEntity; | @@ -9,7 +9,8 @@ import com.bsth.entity.GpsEntity; | ||
| 9 | import com.bsth.entity.StationRoute; | 9 | import com.bsth.entity.StationRoute; |
| 10 | import com.bsth.util.IpUtils; | 10 | import com.bsth.util.IpUtils; |
| 11 | import com.bsth.util.db_utils.DBUtils_InfoPublish; | 11 | import com.bsth.util.db_utils.DBUtils_InfoPublish; |
| 12 | -import com.google.common.collect.*; | 12 | +import com.google.common.collect.Lists; |
| 13 | +import com.google.common.collect.Maps; | ||
| 13 | import org.joda.time.format.DateTimeFormat; | 14 | import org.joda.time.format.DateTimeFormat; |
| 14 | import org.joda.time.format.DateTimeFormatter; | 15 | import org.joda.time.format.DateTimeFormatter; |
| 15 | import org.slf4j.Logger; | 16 | import org.slf4j.Logger; |
| @@ -22,11 +23,10 @@ import org.springframework.stereotype.Component; | @@ -22,11 +23,10 @@ import org.springframework.stereotype.Component; | ||
| 22 | import javax.servlet.http.HttpServletRequest; | 23 | import javax.servlet.http.HttpServletRequest; |
| 23 | import java.sql.PreparedStatement; | 24 | import java.sql.PreparedStatement; |
| 24 | import java.sql.SQLException; | 25 | import java.sql.SQLException; |
| 25 | -import java.util.ArrayList; | ||
| 26 | -import java.util.Enumeration; | ||
| 27 | -import java.util.List; | ||
| 28 | -import java.util.Map; | 26 | +import java.util.*; |
| 27 | +import java.util.concurrent.ConcurrentHashMap; | ||
| 29 | import java.util.concurrent.ConcurrentLinkedQueue; | 28 | import java.util.concurrent.ConcurrentLinkedQueue; |
| 29 | +import java.util.concurrent.ConcurrentMap; | ||
| 30 | import java.util.concurrent.TimeUnit; | 30 | import java.util.concurrent.TimeUnit; |
| 31 | 31 | ||
| 32 | /** | 32 | /** |
| @@ -35,11 +35,12 @@ import java.util.concurrent.TimeUnit; | @@ -35,11 +35,12 @@ import java.util.concurrent.TimeUnit; | ||
| 35 | @Component | 35 | @Component |
| 36 | public class AccuracyDataHandler { | 36 | public class AccuracyDataHandler { |
| 37 | 37 | ||
| 38 | - private static ListMultimap<String, Accuracy> multimap; | 38 | + private static ConcurrentMap<String, Accuracy> map; |
| 39 | 39 | ||
| 40 | private static ConcurrentLinkedQueue<Accuracy> pstQueue; | 40 | private static ConcurrentLinkedQueue<Accuracy> pstQueue; |
| 41 | 41 | ||
| 42 | private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyyMMdd"); | 42 | private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyyMMdd"); |
| 43 | + private static DateTimeFormatter fmtyyyyMMddHHmm = DateTimeFormat.forPattern("yyyyMMddHHmm"); | ||
| 43 | 44 | ||
| 44 | Logger logger = LoggerFactory.getLogger(this.getClass()); | 45 | Logger logger = LoggerFactory.getLogger(this.getClass()); |
| 45 | 46 | ||
| @@ -47,7 +48,7 @@ public class AccuracyDataHandler { | @@ -47,7 +48,7 @@ public class AccuracyDataHandler { | ||
| 47 | AccuracyPstThread accuracyPstThread; | 48 | AccuracyPstThread accuracyPstThread; |
| 48 | 49 | ||
| 49 | static { | 50 | static { |
| 50 | - multimap = Multimaps.synchronizedListMultimap(ArrayListMultimap.create()); | 51 | + map = new ConcurrentHashMap<>(); |
| 51 | pstQueue = new ConcurrentLinkedQueue(); | 52 | pstQueue = new ConcurrentLinkedQueue(); |
| 52 | } | 53 | } |
| 53 | 54 | ||
| @@ -77,6 +78,13 @@ public class AccuracyDataHandler { | @@ -77,6 +78,13 @@ public class AccuracyDataHandler { | ||
| 77 | 78 | ||
| 78 | GpsEntity gps = near.getGps(); | 79 | GpsEntity gps = near.getGps(); |
| 79 | 80 | ||
| 81 | + long t = System.currentTimeMillis(); | ||
| 82 | + String timeStr = fmtyyyyMMddHHmm.print(t); | ||
| 83 | + String key = gps.getNbbm() + "_" + station + "_" + timeStr; | ||
| 84 | + | ||
| 85 | + if (map.containsKey(key)) | ||
| 86 | + return; | ||
| 87 | + | ||
| 80 | Accuracy accuracy = new Accuracy(); | 88 | Accuracy accuracy = new Accuracy(); |
| 81 | accuracy.setRq(Integer.parseInt(fmtyyyyMMdd.print(gps.getTimestamp()))); | 89 | accuracy.setRq(Integer.parseInt(fmtyyyyMMdd.print(gps.getTimestamp()))); |
| 82 | //request info | 90 | //request info |
| @@ -95,7 +103,7 @@ public class AccuracyDataHandler { | @@ -95,7 +103,7 @@ public class AccuracyDataHandler { | ||
| 95 | accuracy.setDistance(Double.parseDouble(near.getDistance())); | 103 | accuracy.setDistance(Double.parseDouble(near.getDistance())); |
| 96 | accuracy.setSeconds(near.getTime()); | 104 | accuracy.setSeconds(near.getTime()); |
| 97 | 105 | ||
| 98 | - multimap.put(gps.getNbbm() + "_" + station, accuracy); | 106 | + map.put(key, accuracy); |
| 99 | } | 107 | } |
| 100 | 108 | ||
| 101 | /** | 109 | /** |
| @@ -107,21 +115,22 @@ public class AccuracyDataHandler { | @@ -107,21 +115,22 @@ public class AccuracyDataHandler { | ||
| 107 | if (gps.getInOut() != 1) | 115 | if (gps.getInOut() != 1) |
| 108 | return; | 116 | return; |
| 109 | 117 | ||
| 110 | - String k = gps.getNbbm() + "_" + gps.getStationCode(); | ||
| 111 | - List<Accuracy> list = multimap.get(k); | 118 | + String p = gps.getNbbm() + "_" + gps.getStationCode() + "_"; |
| 112 | 119 | ||
| 113 | - if (null == list || list.size() == 0) | ||
| 114 | - return; | 120 | + Set<String> ks = map.keySet(); |
| 115 | 121 | ||
| 116 | - for (Accuracy a : list) { | ||
| 117 | - a.setT2(gps.getServerTimestamp()); | ||
| 118 | - a.setRealSeconds((int) ((a.getT2() - a.getT1()) / 1000)); | ||
| 119 | - a.setD2(gps.getInStationDistance()); | 122 | + for (String k : ks) { |
| 123 | + if (k.startsWith(p)) { | ||
| 124 | + Accuracy a = map.get(k); | ||
| 125 | + a.setT2(gps.getServerTimestamp()); | ||
| 126 | + a.setRealSeconds((int) ((a.getT2() - a.getT1()) / 1000)); | ||
| 127 | + a.setD2(gps.getInStationDistance()); | ||
| 120 | 128 | ||
| 121 | - pstQueue.add(a); | ||
| 122 | - } | 129 | + pstQueue.add(a); |
| 123 | 130 | ||
| 124 | - multimap.removeAll(k); | 131 | + map.remove(k); |
| 132 | + } | ||
| 133 | + } | ||
| 125 | } | 134 | } |
| 126 | 135 | ||
| 127 | private static String getHeaders(HttpServletRequest request) { | 136 | private static String getHeaders(HttpServletRequest request) { |
src/main/java/com/bsth/data/geo/GeoCacheData.java
| @@ -149,6 +149,8 @@ public class GeoCacheData { | @@ -149,6 +149,8 @@ public class GeoCacheData { | ||
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | public static StationRoute findByCode(GpsEntity gps) { | 151 | public static StationRoute findByCode(GpsEntity gps) { |
| 152 | + if(null == gps.getStationCode()) | ||
| 153 | + return null; | ||
| 152 | return codeMap.get(gps.getLineId() + "_" + gps.getUpDown() + "_" + gps.getStationCode()); | 154 | return codeMap.get(gps.getLineId() + "_" + gps.getUpDown() + "_" + gps.getStationCode()); |
| 153 | } | 155 | } |
| 154 | 156 |
src/main/java/com/bsth/data/gps/process/chains/ForecastProcess.java
| @@ -16,7 +16,7 @@ import java.util.List; | @@ -16,7 +16,7 @@ import java.util.List; | ||
| 16 | @Component | 16 | @Component |
| 17 | public class ForecastProcess { | 17 | public class ForecastProcess { |
| 18 | 18 | ||
| 19 | - private final static int OFFLINE_TIME = 1000 * 60 * 3; | 19 | + private final static int OFFLINE_TIME = 1000 * 30; |
| 20 | private final static int OUT_BOUNDS = 80; | 20 | private final static int OUT_BOUNDS = 80; |
| 21 | 21 | ||
| 22 | public void process(GpsEntity gps) { | 22 | public void process(GpsEntity gps) { |
| @@ -32,19 +32,49 @@ public class ForecastProcess { | @@ -32,19 +32,49 @@ public class ForecastProcess { | ||
| 32 | double avgSpeed = sumDist / seconds;//均速 | 32 | double avgSpeed = sumDist / seconds;//均速 |
| 33 | gps.setSeconds((int) (gps.getDistance() / avgSpeed) + 30);//到下一站的时间(30 秒 尝试稀疏一下红绿灯) | 33 | gps.setSeconds((int) (gps.getDistance() / avgSpeed) + 30);//到下一站的时间(30 秒 尝试稀疏一下红绿灯) |
| 34 | } else { | 34 | } else { |
| 35 | + jiMinusSj(gps); | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * 用计划时间 - 当前实际已行驶时间 | ||
| 41 | + * | ||
| 42 | + * @param gps | ||
| 43 | + */ | ||
| 44 | + private void jiMinusSj(GpsEntity gps) { | ||
| 45 | + GpsEntity pi = HistoryConsumeTimeDataHandler.prevIn(gps.getDeviceId()); | ||
| 46 | + if (pi != null && pi.getStationCode().equals(gps.getStationCode())) { | ||
| 47 | + Integer time = HistoryConsumeTimeDataHandler.findConsume(gps); | ||
| 48 | + | ||
| 49 | + if (null != time) | ||
| 50 | + gps.setSeconds((int) (time - ((gps.getTimestamp() - pi.getTimestamp()) / 1000))); | ||
| 35 | 51 | ||
| 36 | - //用行驶距离 的比例 取计划时间 | ||
| 37 | - StationRoute s = GeoCacheData.findByCode(gps); | ||
| 38 | - if (null != s && null != gps.getDistance()) { | ||
| 39 | - double scale = gps.getDistance() / s.getLength(); | ||
| 40 | - Integer time = HistoryConsumeTimeDataHandler.findConsume(gps); | 52 | + if (gps.getSeconds() < 0) { |
| 41 | 53 | ||
| 42 | - if (null != time) | ||
| 43 | - gps.setSeconds((int) (time * scale)); | 54 | + if (null != gps.getDistance() && gps.getDistance() < 150) |
| 55 | + gps.setSeconds(0); | ||
| 56 | + | ||
| 57 | + byDistanceScale(gps); | ||
| 44 | } | 58 | } |
| 45 | } | 59 | } |
| 46 | } | 60 | } |
| 47 | 61 | ||
| 62 | + /** | ||
| 63 | + * 用行驶距离 的比例 取计划时间 | ||
| 64 | + * | ||
| 65 | + * @param gps | ||
| 66 | + */ | ||
| 67 | + private void byDistanceScale(GpsEntity gps) { | ||
| 68 | + StationRoute s = GeoCacheData.findByCode(gps); | ||
| 69 | + if (null != s && null != gps.getDistance()) { | ||
| 70 | + double scale = gps.getDistance() / s.getLength(); | ||
| 71 | + Integer time = HistoryConsumeTimeDataHandler.findConsume(gps); | ||
| 72 | + | ||
| 73 | + if (null != time) | ||
| 74 | + gps.setSeconds((int) (time * scale)); | ||
| 75 | + } | ||
| 76 | + } | ||
| 77 | + | ||
| 48 | private boolean isValidSignal(List<GpsEntity> list) { | 78 | private boolean isValidSignal(List<GpsEntity> list) { |
| 49 | if (list.size() <= 1) | 79 | if (list.size() <= 1) |
| 50 | return false; | 80 | return false; |
src/main/java/com/bsth/data/history/HistoryConsumeTimeDataHandler.java
| @@ -102,6 +102,10 @@ public class HistoryConsumeTimeDataHandler { | @@ -102,6 +102,10 @@ public class HistoryConsumeTimeDataHandler { | ||
| 102 | return rs; | 102 | return rs; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | + public static GpsEntity prevIn(String device){ | ||
| 106 | + return lastInStationMap.get(device); | ||
| 107 | + } | ||
| 108 | + | ||
| 105 | private static Integer forecastEnd(GpsEntity gps, int peakVal, String eCode) { | 109 | private static Integer forecastEnd(GpsEntity gps, int peakVal, String eCode) { |
| 106 | int sum = 0; | 110 | int sum = 0; |
| 107 | Integer[] ns = findConsumeArray(gps, peakVal, eCode); | 111 | Integer[] ns = findConsumeArray(gps, peakVal, eCode); |
src/main/resources/static/index.html
src/main/resources/static/pages/charts_data/accuracy.html
| @@ -70,8 +70,7 @@ | @@ -70,8 +70,7 @@ | ||
| 70 | <div class="col-md-2"> | 70 | <div class="col-md-2"> |
| 71 | <div class="form-group"> | 71 | <div class="form-group"> |
| 72 | <label class="bmd-label-floating">日期</label> | 72 | <label class="bmd-label-floating">日期</label> |
| 73 | - <input type="text" name="rq" required class="form-control flatpickr_date" | ||
| 74 | - value="2018-07-02"> | 73 | + <input type="text" name="rq" required class="form-control flatpickr_date"> |
| 75 | </div> | 74 | </div> |
| 76 | </div> | 75 | </div> |
| 77 | <div class="col-md-2"> | 76 | <div class="col-md-2"> |
| @@ -91,7 +90,7 @@ | @@ -91,7 +90,7 @@ | ||
| 91 | <div class="col-md-2" style="padding-left: 0"> | 90 | <div class="col-md-2" style="padding-left: 0"> |
| 92 | <div class="form-group"> | 91 | <div class="form-group"> |
| 93 | <label class="bmd-label-floating">至</label> | 92 | <label class="bmd-label-floating">至</label> |
| 94 | - <input type="time" name="et" required class="form-control flatpickr_time" value="23:00"> | 93 | + <input type="time" name="et" required class="form-control flatpickr_time" value="09:30"> |
| 95 | </div> | 94 | </div> |
| 96 | </div> | 95 | </div> |
| 97 | <div class="col-md-2"> | 96 | <div class="col-md-2"> |
src/main/resources/static/pages/m/m.html
| @@ -69,6 +69,7 @@ | @@ -69,6 +69,7 @@ | ||
| 69 | font-size: 20px; | 69 | font-size: 20px; |
| 70 | top: 2px; | 70 | top: 2px; |
| 71 | color: #6565ff; | 71 | color: #6565ff; |
| 72 | + cursor: pointer; | ||
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | .top_form .form-group > label, | 75 | .top_form .form-group > label, |
| @@ -190,11 +191,12 @@ | @@ -190,11 +191,12 @@ | ||
| 190 | } | 191 | } |
| 191 | 192 | ||
| 192 | rect.station_text_rect{ | 193 | rect.station_text_rect{ |
| 193 | - width: 250px; | 194 | + width: 100%; |
| 194 | height: 30px; | 195 | height: 30px; |
| 195 | - transform: translate(-9px, -11px); | 196 | + transform: translate(-9px, -18px); |
| 196 | fill: #fff0; | 197 | fill: #fff0; |
| 197 | opacity: 0; | 198 | opacity: 0; |
| 199 | + cursor: pointer; | ||
| 198 | } | 200 | } |
| 199 | </style> | 201 | </style> |
| 200 | </head> | 202 | </head> |
| @@ -372,7 +374,7 @@ | @@ -372,7 +374,7 @@ | ||
| 372 | var line = d3.svg.line().x(cx).y(yScale); | 374 | var line = d3.svg.line().x(cx).y(yScale); |
| 373 | 375 | ||
| 374 | $('svg', wrap).empty(); | 376 | $('svg', wrap).empty(); |
| 375 | - var svg = d3.select('svg', wrap).style('height', h); | 377 | + var svg = d3.select('svg', wrap).style('height', h).style('width', '100%'); |
| 376 | //add item g | 378 | //add item g |
| 377 | var items = svg.selectAll('g.item').data(data) | 379 | var items = svg.selectAll('g.item').data(data) |
| 378 | .enter().append('g').classed({ | 380 | .enter().append('g').classed({ |