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