Commit 8d29c2ae7dcba7febebfd716121e330b27e2ead5
1 parent
08fe0ea4
update...
Showing
11 changed files
with
371 additions
and
27 deletions
src/main/java/com/bsth/controller/XmlInfoPublishController.java
| 1 | 1 | package com.bsth.controller; |
| 2 | 2 | |
| 3 | +import com.bsth.controller.dto.CarMonitorEntity; | |
| 3 | 4 | import com.bsth.controller.dto.DispatchScreen; |
| 4 | 5 | import com.bsth.data.BasicCacheData; |
| 6 | +import com.bsth.data.charts_data.AccuracyDataHandler; | |
| 5 | 7 | import com.bsth.data.geo.GeoCacheData; |
| 6 | 8 | import com.bsth.data.gps.GpsCacheData; |
| 7 | 9 | import com.bsth.data.history.HistoryConsumeTimeDataHandler; |
| ... | ... | @@ -19,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping; |
| 19 | 21 | import org.springframework.web.bind.annotation.RequestParam; |
| 20 | 22 | import org.springframework.web.bind.annotation.RestController; |
| 21 | 23 | |
| 24 | +import javax.servlet.http.HttpServletRequest; | |
| 22 | 25 | import java.text.DecimalFormat; |
| 23 | 26 | import java.util.*; |
| 24 | 27 | |
| ... | ... | @@ -33,6 +36,9 @@ public class XmlInfoPublishController { |
| 33 | 36 | @Autowired |
| 34 | 37 | JdbcTemplate jdbcTemplate; |
| 35 | 38 | |
| 39 | + @Autowired | |
| 40 | + AccuracyDataHandler accuracyDataHandler; | |
| 41 | + | |
| 36 | 42 | Logger logger = LoggerFactory.getLogger(this.getClass()); |
| 37 | 43 | |
| 38 | 44 | static DecimalFormat df = new DecimalFormat("#.00"); |
| ... | ... | @@ -131,7 +137,8 @@ public class XmlInfoPublishController { |
| 131 | 137 | } |
| 132 | 138 | |
| 133 | 139 | @RequestMapping("carMonitor") |
| 134 | - public String carMonitor(@RequestParam String lineid, @RequestParam String stopid, @RequestParam String direction, String t) { | |
| 140 | + public String carMonitor(@RequestParam String lineid, @RequestParam String stopid | |
| 141 | + , @RequestParam String direction, String t, HttpServletRequest request) { | |
| 135 | 142 | StringBuilder sb = new StringBuilder(); |
| 136 | 143 | |
| 137 | 144 | try { |
| ... | ... | @@ -196,36 +203,49 @@ public class XmlInfoPublishController { |
| 196 | 203 | |
| 197 | 204 | |
| 198 | 205 | Map<String, Integer> forecast = HistoryConsumeTimeDataHandler.forecastEnd(vs, stopid); |
| 199 | - | |
| 200 | - //to xml | |
| 201 | - | |
| 202 | - sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); | |
| 203 | - sb.append("<result>"); | |
| 204 | - sb.append("<cars lineid=\"" + lineid + "\">"); | |
| 205 | - | |
| 206 | + List<CarMonitorEntity> reals = new ArrayList<>(); | |
| 207 | + CarMonitorEntity cme; | |
| 206 | 208 | for (GpsEntity v : vs) { |
| 207 | 209 | if (v.getStationCode().equals(stopid) |
| 208 | 210 | && v.getInOut() != 1) |
| 209 | 211 | continue; //已出当前站 |
| 210 | 212 | |
| 211 | - sb.append("<car>"); | |
| 212 | - sb.append("<terminal>" + BasicCacheData.device2plateMap.get(v.getDeviceId()) + "</terminal>"); | |
| 213 | - | |
| 214 | - //当前站 缓冲区内 的车(进站时间不超过 40秒的,可以发布) | |
| 213 | + cme = new CarMonitorEntity(); | |
| 214 | + cme.setGps(v); | |
| 215 | + cme.setPlate(BasicCacheData.device2plateMap.get(v.getDeviceId())); | |
| 215 | 216 | if (v.getStationCode().equals(stopid) |
| 216 | 217 | && v.getInOut() == 1 |
| 217 | 218 | && (null != v.getInStationTime() && ct - v.getInStationTime() < 40)) { |
| 218 | - sb.append("<stopdis>0</stopdis>"); | |
| 219 | - sb.append("<distance>0</distance>"); | |
| 220 | - sb.append("<time>0</time>"); | |
| 219 | + | |
| 220 | + cme.setStopdis(0); | |
| 221 | + cme.setDistance("0"); | |
| 222 | + cme.setTime(0); | |
| 221 | 223 | } else { |
| 222 | - sb.append("<stopdis>" + snMap.get(v.getDeviceId()) + "</stopdis>"); | |
| 223 | - sb.append("<distance>" + df.format((disMap.get(v.getDeviceId()) + v.getDistance())) + "</distance>"); | |
| 224 | - sb.append("<time>" + forecast.get(v.getDeviceId()) + "</time>"); | |
| 224 | + cme.setStopdis(snMap.get(v.getDeviceId())); | |
| 225 | + cme.setDistance(df.format((disMap.get(v.getDeviceId()) + v.getDistance()))); | |
| 226 | + cme.setTime(forecast.get(v.getDeviceId())); | |
| 225 | 227 | } |
| 228 | + | |
| 229 | + reals.add(cme); | |
| 230 | + } | |
| 231 | + //to xml | |
| 232 | + | |
| 233 | + sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); | |
| 234 | + sb.append("<result>"); | |
| 235 | + sb.append("<cars lineid=\"" + lineid + "\">"); | |
| 236 | + | |
| 237 | + for (CarMonitorEntity obj : reals) { | |
| 238 | + sb.append("<car>"); | |
| 239 | + sb.append("<terminal>" + obj.getPlate() + "</terminal>"); | |
| 240 | + sb.append("<stopdis>" + obj.getStopdis() + "</stopdis>"); | |
| 241 | + sb.append("<distance>" + obj.getDistance() + "</distance>"); | |
| 242 | + sb.append("<time>" + obj.getTime() + "</time>"); | |
| 226 | 243 | sb.append("</car>"); |
| 227 | 244 | } |
| 228 | 245 | |
| 246 | + //预测准确性分析 | |
| 247 | + accuracyDataHandler.mark(reals, stopid, request); | |
| 248 | + | |
| 229 | 249 | sb.append("</cars>"); |
| 230 | 250 | sb.append("</result>"); |
| 231 | 251 | } catch (Exception e) { | ... | ... |
src/main/java/com/bsth/controller/dto/CarMonitorEntity.java
0 → 100644
| 1 | +package com.bsth.controller.dto; | |
| 2 | + | |
| 3 | +import com.bsth.entity.GpsEntity; | |
| 4 | + | |
| 5 | +public class CarMonitorEntity { | |
| 6 | + | |
| 7 | + private String plate; | |
| 8 | + private int stopdis; | |
| 9 | + private String distance; | |
| 10 | + private int time; | |
| 11 | + private GpsEntity gps; | |
| 12 | + | |
| 13 | + public int getStopdis() { | |
| 14 | + return stopdis; | |
| 15 | + } | |
| 16 | + | |
| 17 | + public void setStopdis(int stopdis) { | |
| 18 | + this.stopdis = stopdis; | |
| 19 | + } | |
| 20 | + | |
| 21 | + public String getDistance() { | |
| 22 | + return distance; | |
| 23 | + } | |
| 24 | + | |
| 25 | + public void setDistance(String distance) { | |
| 26 | + this.distance = distance; | |
| 27 | + } | |
| 28 | + | |
| 29 | + public int getTime() { | |
| 30 | + return time; | |
| 31 | + } | |
| 32 | + | |
| 33 | + public void setTime(int time) { | |
| 34 | + this.time = time; | |
| 35 | + } | |
| 36 | + | |
| 37 | + public GpsEntity getGps() { | |
| 38 | + return gps; | |
| 39 | + } | |
| 40 | + | |
| 41 | + public void setGps(GpsEntity gps) { | |
| 42 | + this.gps = gps; | |
| 43 | + } | |
| 44 | + | |
| 45 | + public String getPlate() { | |
| 46 | + return plate; | |
| 47 | + } | |
| 48 | + | |
| 49 | + public void setPlate(String plate) { | |
| 50 | + this.plate = plate; | |
| 51 | + } | |
| 52 | +} | ... | ... |
src/main/java/com/bsth/data/charts_data/AccuracyDataHandler.java
0 → 100644
| 1 | +package com.bsth.data.charts_data; | |
| 2 | + | |
| 3 | +import com.alibaba.fastjson.JSON; | |
| 4 | +import com.bsth.controller.dto.CarMonitorEntity; | |
| 5 | +import com.bsth.entity.Accuracy; | |
| 6 | +import com.bsth.entity.GpsEntity; | |
| 7 | +import com.bsth.util.IpUtils; | |
| 8 | +import com.google.common.collect.*; | |
| 9 | +import org.springframework.stereotype.Component; | |
| 10 | + | |
| 11 | +import javax.servlet.http.HttpServletRequest; | |
| 12 | +import java.util.Enumeration; | |
| 13 | +import java.util.List; | |
| 14 | +import java.util.Map; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * 发布预测准确性 数据 | |
| 18 | + */ | |
| 19 | +@Component | |
| 20 | +public class AccuracyDataHandler { | |
| 21 | + | |
| 22 | + private static ListMultimap<String, Accuracy> multimap; | |
| 23 | + | |
| 24 | + static { | |
| 25 | + multimap = Multimaps.synchronizedListMultimap(ArrayListMultimap.create()); | |
| 26 | + } | |
| 27 | + | |
| 28 | + private static String getHeaders(HttpServletRequest request) { | |
| 29 | + Map<String, List<String>> headers = Maps.newHashMap(); | |
| 30 | + Enumeration<String> namesEnumeration = request.getHeaderNames(); | |
| 31 | + while (namesEnumeration.hasMoreElements()) { | |
| 32 | + String name = namesEnumeration.nextElement(); | |
| 33 | + Enumeration<String> valueEnumeration = request.getHeaders(name); | |
| 34 | + List<String> values = Lists.newArrayList(); | |
| 35 | + while (valueEnumeration.hasMoreElements()) { | |
| 36 | + values.add(valueEnumeration.nextElement()); | |
| 37 | + } | |
| 38 | + headers.put(name, values); | |
| 39 | + } | |
| 40 | + return JSON.toJSONString(headers); | |
| 41 | + } | |
| 42 | + | |
| 43 | + /** | |
| 44 | + * 标记一条发布消息,待gps到站后校验准确性 | |
| 45 | + * | |
| 46 | + * @param request | |
| 47 | + */ | |
| 48 | + public void mark(List<CarMonitorEntity> list, String station, HttpServletRequest request) { | |
| 49 | + CarMonitorEntity near = null; | |
| 50 | + | |
| 51 | + for (CarMonitorEntity cme : list) { | |
| 52 | + if (null == near | |
| 53 | + || cme.getStopdis() < near.getStopdis() | |
| 54 | + || cme.getTime() < near.getTime()) | |
| 55 | + near = cme; | |
| 56 | + } | |
| 57 | + | |
| 58 | + GpsEntity gps = near.getGps(); | |
| 59 | + | |
| 60 | + Accuracy accuracy = new Accuracy(); | |
| 61 | + //request info | |
| 62 | + accuracy.setIp(IpUtils.getIpAddr(request)); | |
| 63 | + accuracy.setUserAgent(request.getHeader("User-Agent")); | |
| 64 | + accuracy.setHeaders(getHeaders(request)); | |
| 65 | + //params | |
| 66 | + accuracy.setLineCode(gps.getLineId()); | |
| 67 | + accuracy.setUpDown(gps.getUpDown()); | |
| 68 | + accuracy.setStation(station); | |
| 69 | + accuracy.setT1(gps.getTimestamp()); | |
| 70 | + accuracy.setNbbm(gps.getNbbm()); | |
| 71 | + accuracy.setPlate(near.getPlate()); | |
| 72 | + accuracy.setStopDis(near.getStopdis()); | |
| 73 | + accuracy.setSeconds(near.getTime()); | |
| 74 | + | |
| 75 | + multimap.put(gps.getNbbm() + "_" + station, accuracy); | |
| 76 | + } | |
| 77 | + | |
| 78 | + /** | |
| 79 | + * 校验发布准确性 | |
| 80 | + * @param gps | |
| 81 | + */ | |
| 82 | + public void check(GpsEntity gps) { | |
| 83 | + | |
| 84 | + } | |
| 85 | +} | ... | ... |
src/main/java/com/bsth/data/history/HistoryConsumeTimeDataHandler.java
| ... | ... | @@ -209,8 +209,9 @@ public class HistoryConsumeTimeDataHandler { |
| 209 | 209 | if (gps.getUpDown().intValue() != prev.getUpDown().intValue() |
| 210 | 210 | || null == lastInGps |
| 211 | 211 | || !lastInGps.getStationCode().equals(prev.getStationCode()) |
| 212 | - || prev.getTimestamp() - lastInGps.getTimestamp() > 1000 * 60 * 60) | |
| 212 | + || prev.getTimestamp() - lastInGps.getTimestamp() > 1000 * 60 * 60) { | |
| 213 | 213 | return; |
| 214 | + } | |
| 214 | 215 | |
| 215 | 216 | StationConsumeTime sct = StationConsumeTime.getInstance(lastInGps, gps); |
| 216 | 217 | pstQueue.add(sct); | ... | ... |
src/main/java/com/bsth/entity/Accuracy.java
0 → 100644
| 1 | +package com.bsth.entity; | |
| 2 | + | |
| 3 | +public class Accuracy { | |
| 4 | + | |
| 5 | + private String userAgent; | |
| 6 | + | |
| 7 | + private String headers; | |
| 8 | + | |
| 9 | + private String ip; | |
| 10 | + | |
| 11 | + private String lineCode; | |
| 12 | + | |
| 13 | + private int upDown; | |
| 14 | + | |
| 15 | + private String station; | |
| 16 | + | |
| 17 | + /** | |
| 18 | + * 预测信息 | |
| 19 | + */ | |
| 20 | + private String nbbm; | |
| 21 | + | |
| 22 | + private String plate; | |
| 23 | + | |
| 24 | + private int stopDis; | |
| 25 | + | |
| 26 | + private double distance; | |
| 27 | + | |
| 28 | + private int seconds; | |
| 29 | + | |
| 30 | + private long t1; | |
| 31 | + | |
| 32 | + | |
| 33 | + //实际 到站用时 | |
| 34 | + private int realSeconds; | |
| 35 | + | |
| 36 | + private long t2; | |
| 37 | + | |
| 38 | + public String getUserAgent() { | |
| 39 | + return userAgent; | |
| 40 | + } | |
| 41 | + | |
| 42 | + public void setUserAgent(String userAgent) { | |
| 43 | + this.userAgent = userAgent; | |
| 44 | + } | |
| 45 | + | |
| 46 | + public String getHeaders() { | |
| 47 | + return headers; | |
| 48 | + } | |
| 49 | + | |
| 50 | + public void setHeaders(String headers) { | |
| 51 | + this.headers = headers; | |
| 52 | + } | |
| 53 | + | |
| 54 | + public String getIp() { | |
| 55 | + return ip; | |
| 56 | + } | |
| 57 | + | |
| 58 | + public void setIp(String ip) { | |
| 59 | + this.ip = ip; | |
| 60 | + } | |
| 61 | + | |
| 62 | + public String getLineCode() { | |
| 63 | + return lineCode; | |
| 64 | + } | |
| 65 | + | |
| 66 | + public void setLineCode(String lineCode) { | |
| 67 | + this.lineCode = lineCode; | |
| 68 | + } | |
| 69 | + | |
| 70 | + public int getUpDown() { | |
| 71 | + return upDown; | |
| 72 | + } | |
| 73 | + | |
| 74 | + public void setUpDown(int upDown) { | |
| 75 | + this.upDown = upDown; | |
| 76 | + } | |
| 77 | + | |
| 78 | + public String getStation() { | |
| 79 | + return station; | |
| 80 | + } | |
| 81 | + | |
| 82 | + public void setStation(String station) { | |
| 83 | + this.station = station; | |
| 84 | + } | |
| 85 | + | |
| 86 | + public String getNbbm() { | |
| 87 | + return nbbm; | |
| 88 | + } | |
| 89 | + | |
| 90 | + public void setNbbm(String nbbm) { | |
| 91 | + this.nbbm = nbbm; | |
| 92 | + } | |
| 93 | + | |
| 94 | + public String getPlate() { | |
| 95 | + return plate; | |
| 96 | + } | |
| 97 | + | |
| 98 | + public void setPlate(String plate) { | |
| 99 | + this.plate = plate; | |
| 100 | + } | |
| 101 | + | |
| 102 | + public double getDistance() { | |
| 103 | + return distance; | |
| 104 | + } | |
| 105 | + | |
| 106 | + public void setDistance(double distance) { | |
| 107 | + this.distance = distance; | |
| 108 | + } | |
| 109 | + | |
| 110 | + public int getSeconds() { | |
| 111 | + return seconds; | |
| 112 | + } | |
| 113 | + | |
| 114 | + public void setSeconds(int seconds) { | |
| 115 | + this.seconds = seconds; | |
| 116 | + } | |
| 117 | + | |
| 118 | + | |
| 119 | + public int getRealSeconds() { | |
| 120 | + return realSeconds; | |
| 121 | + } | |
| 122 | + | |
| 123 | + public void setRealSeconds(int realSeconds) { | |
| 124 | + this.realSeconds = realSeconds; | |
| 125 | + } | |
| 126 | + | |
| 127 | + public long getT1() { | |
| 128 | + return t1; | |
| 129 | + } | |
| 130 | + | |
| 131 | + public void setT1(long t1) { | |
| 132 | + this.t1 = t1; | |
| 133 | + } | |
| 134 | + | |
| 135 | + public long getT2() { | |
| 136 | + return t2; | |
| 137 | + } | |
| 138 | + | |
| 139 | + public void setT2(long t2) { | |
| 140 | + this.t2 = t2; | |
| 141 | + } | |
| 142 | + | |
| 143 | + public int getStopDis() { | |
| 144 | + return stopDis; | |
| 145 | + } | |
| 146 | + | |
| 147 | + public void setStopDis(int stopDis) { | |
| 148 | + this.stopDis = stopDis; | |
| 149 | + } | |
| 150 | +} | ... | ... |
src/main/java/com/bsth/util/IpUtils.java
0 → 100644
| 1 | +package com.bsth.util; | |
| 2 | + | |
| 3 | +import javax.servlet.http.HttpServletRequest; | |
| 4 | + | |
| 5 | +public class IpUtils { | |
| 6 | + | |
| 7 | + public static String getIpAddr(HttpServletRequest request) { | |
| 8 | + if (request == null) { | |
| 9 | + return "unknown"; | |
| 10 | + } | |
| 11 | + String ip = request.getHeader("x-forwarded-for"); | |
| 12 | + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { | |
| 13 | + ip = request.getHeader("Proxy-Client-IP"); | |
| 14 | + } | |
| 15 | + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { | |
| 16 | + ip = request.getHeader("X-Forwarded-For"); | |
| 17 | + } | |
| 18 | + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { | |
| 19 | + ip = request.getHeader("WL-Proxy-Client-IP"); | |
| 20 | + } | |
| 21 | + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { | |
| 22 | + ip = request.getHeader("X-Real-IP"); | |
| 23 | + } | |
| 24 | + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { | |
| 25 | + ip = request.getRemoteAddr(); | |
| 26 | + } | |
| 27 | + return ip; | |
| 28 | + } | |
| 29 | +} | ... | ... |
src/main/resources/static/index.html
| ... | ... | @@ -38,27 +38,33 @@ |
| 38 | 38 | <li class="nav-item "> |
| 39 | 39 | <a class="nav-link" title="切割处理后的路段和原始路段" href="/pages/geo_data/map.html"> |
| 40 | 40 | <i class="material-icons">location_ons</i> |
| 41 | - <p>路段空间数据</p> | |
| 41 | + <p>站间距</p> | |
| 42 | 42 | </a> |
| 43 | 43 | </li> |
| 44 | 44 | <li class="nav-item "> |
| 45 | - <a class="nav-link" title="站点间行驶耗时(GPS)" href="/pages/h_consume/list.html"> | |
| 45 | + <a class="nav-link" title="线路上站点间行驶耗时(GPS)" href="/pages/h_consume/list.html"> | |
| 46 | 46 | <i class="material-icons">timer_3</i> |
| 47 | - <p>历史到站时间</p> | |
| 47 | + <p>站点间运送时间</p> | |
| 48 | 48 | </a> |
| 49 | 49 | </li> |
| 50 | 50 | <li class="nav-item "> |
| 51 | 51 | <a class="nav-link" title="实时信息发布预览" href="/pages/real/main.html"> |
| 52 | 52 | <i class="material-icons">voicemail</i> |
| 53 | - <p>实时预览</p> | |
| 53 | + <p>实时GPS</p> | |
| 54 | 54 | </a> |
| 55 | 55 | </li> |
| 56 | 56 | <li class="nav-item "> |
| 57 | 57 | <a class="nav-link" href="/pages/interface_test/iTest.html"> |
| 58 | - <i class="material-icons">info</i> | |
| 58 | + <i class="material-icons">build</i> | |
| 59 | 59 | <p>信息发布接口测试</p> |
| 60 | 60 | </a> |
| 61 | 61 | </li> |
| 62 | + <li class="nav-item "> | |
| 63 | + <a class="nav-link" title="所有通过 “carMonitor” 接口发布的预测,事后与实际GPS到站匹配" href="/pages/charts_data/accuracy.html"> | |
| 64 | + <i class="material-icons">spellcheck</i> | |
| 65 | + <p>信息发布准确性</p> | |
| 66 | + </a> | |
| 67 | + </li> | |
| 62 | 68 | |
| 63 | 69 | <li class="nav-item disabled"> |
| 64 | 70 | <a class="nav-link" > | ... | ... |
src/main/resources/static/pages/charts_data/accuracy.html
0 → 100644
src/main/resources/static/pages/geo_data/map.html
| ... | ... | @@ -8,7 +8,7 @@ |
| 8 | 8 | <div class="row"> |
| 9 | 9 | <div class="col-md-8" style="padding-right: 0;"> |
| 10 | 10 | <div class="form-group"> |
| 11 | - <label class="bmd-label-floating">选择线路</label> | |
| 11 | + <label class="bmd-label-floating">输入线路</label> | |
| 12 | 12 | <div class="ct_auto_wrap line_autocompleter"> |
| 13 | 13 | <input type="text" class="form-control"> |
| 14 | 14 | </div> | ... | ... |
src/main/resources/static/pages/h_consume/list.html
| ... | ... | @@ -76,7 +76,7 @@ |
| 76 | 76 | </div> |
| 77 | 77 | <div class="col-md-2"> |
| 78 | 78 | <div class="form-group"> |
| 79 | - <label class="bmd-label-floating">选择线路</label> | |
| 79 | + <label class="bmd-label-floating">输入线路</label> | |
| 80 | 80 | <div class="ct_auto_wrap line_autocompleter"> |
| 81 | 81 | <input type="text" name="lineName" required class="form-control" autocomplete="off"> |
| 82 | 82 | </div> | ... | ... |
src/main/resources/static/pages/real/main.html
| ... | ... | @@ -7,7 +7,7 @@ |
| 7 | 7 | <div class="row"> |
| 8 | 8 | <div class="col-md-7" style="padding-right: 0;"> |
| 9 | 9 | <div class="form-group"> |
| 10 | - <label class="bmd-label-floating">选择线路</label> | |
| 10 | + <label class="bmd-label-floating">输入线路</label> | |
| 11 | 11 | <div class="ct_auto_wrap line_autocompleter"> |
| 12 | 12 | <input type="text" class="form-control"> |
| 13 | 13 | </div> | ... | ... |