Commit 9b2cec0e1fa25f04ff6c64935f90c8eb49783b8e
1 parent
f125ea9a
1.加入混合自动执行+自动执行偏移的托管以及营运后路单计算功能
Showing
14 changed files
with
1737 additions
and
1379 deletions
src/main/java/com/bsth/XDApplication.java
| ... | ... | @@ -151,7 +151,7 @@ public class XDApplication implements CommandLineRunner { |
| 151 | 151 | /** 线调业务 */ |
| 152 | 152 | sexec.scheduleWithFixedDelay(scheduleRefreshThread, 10, 120, TimeUnit.SECONDS);//班次更新线程 |
| 153 | 153 | sexec.scheduleWithFixedDelay(scheduleLateThread, 140, 20, TimeUnit.SECONDS);//检查班次误点 |
| 154 | - sexec.scheduleWithFixedDelay(gpsDataLoader, 100, 2, TimeUnit.SECONDS);//抓取GPS数据 | |
| 154 | + sexec.scheduleWithFixedDelay(gpsDataLoader, 0, 2, TimeUnit.SECONDS);//抓取GPS数据 | |
| 155 | 155 | //sexec.scheduleWithFixedDelay(rfidDataLoader, 5, 5, TimeUnit.SECONDS);//抓取RFID数据 |
| 156 | 156 | sexec.scheduleWithFixedDelay(fixedCheckStationCodeThread, 60, 60 * 5, TimeUnit.SECONDS);//检查班次站点编码 |
| 157 | 157 | ... | ... |
src/main/java/com/bsth/config/SchedulerConfig.java
0 → 100644
| 1 | +package com.bsth.config; | |
| 2 | + | |
| 3 | +import org.springframework.beans.BeansException; | |
| 4 | +import org.springframework.context.ApplicationContext; | |
| 5 | +import org.springframework.context.ApplicationContextAware; | |
| 6 | +import org.springframework.context.annotation.Bean; | |
| 7 | +import org.springframework.context.annotation.Configuration; | |
| 8 | +import org.springframework.scheduling.annotation.SchedulingConfigurer; | |
| 9 | +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; | |
| 10 | +import org.springframework.scheduling.config.ScheduledTaskRegistrar; | |
| 11 | + | |
| 12 | +@Configuration | |
| 13 | +public class SchedulerConfig implements SchedulingConfigurer, ApplicationContextAware { | |
| 14 | + | |
| 15 | + private static ApplicationContext context; | |
| 16 | + | |
| 17 | + private final int POOL_SIZE = 10; | |
| 18 | + | |
| 19 | + @Override | |
| 20 | + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { | |
| 21 | + ThreadPoolTaskScheduler scheduler = (ThreadPoolTaskScheduler) context.getBean("threadPoolTaskScheduler"); | |
| 22 | + taskRegistrar.setTaskScheduler(scheduler); | |
| 23 | + } | |
| 24 | + | |
| 25 | + @Bean("threadPoolTaskScheduler") | |
| 26 | + public ThreadPoolTaskScheduler threadPoolTaskScheduler() { | |
| 27 | + ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); | |
| 28 | + threadPoolTaskScheduler.setPoolSize(POOL_SIZE); | |
| 29 | + threadPoolTaskScheduler.setThreadNamePrefix("TaskScheduler-"); | |
| 30 | + threadPoolTaskScheduler.initialize(); | |
| 31 | + | |
| 32 | + return threadPoolTaskScheduler; | |
| 33 | + } | |
| 34 | + | |
| 35 | + @Override | |
| 36 | + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { | |
| 37 | + context = applicationContext; | |
| 38 | + } | |
| 39 | +} | ... | ... |
src/main/java/com/bsth/data/SystemParamCache.java
| ... | ... | @@ -30,7 +30,8 @@ public class SystemParamCache implements InitializingBean { |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | 32 | public static String getUrlHttpGpsReal() { |
| 33 | - return systemParamService1.getValue(SystemParamKeys.URL_HTTP_GPS_REAL); | |
| 33 | + return "http://10.10.2.20:8080/transport_server/rtgps/"; | |
| 34 | + //return systemParamService1.getValue(SystemParamKeys.URL_HTTP_GPS_REAL); | |
| 34 | 35 | } |
| 35 | 36 | |
| 36 | 37 | public static String getUrlHttpDirective() { | ... | ... |
src/main/java/com/bsth/data/gpsdata_v2/handlers/InStationProcess.java
| ... | ... | @@ -51,7 +51,7 @@ public class InStationProcess { |
| 51 | 51 | public void process(GpsEntity gps) { |
| 52 | 52 | //自动执行的班次信号,滚蛋 |
| 53 | 53 | LineConfig config = lineConfigData.get(gps.getLineId()); |
| 54 | - if (null != config && config.isAutoExec()) | |
| 54 | + if (null != config && config.isAutoExec() && config.getAutoExecOffset() == 0) | |
| 55 | 55 | return; |
| 56 | 56 | |
| 57 | 57 | GpsEntity prev = GpsCacheData.getPrev(gps); |
| ... | ... | @@ -139,6 +139,12 @@ public class InStationProcess { |
| 139 | 139 | */ |
| 140 | 140 | private void inEndStation(ScheduleRealInfo sch, GpsEntity gps) { |
| 141 | 141 | String nbbm = sch.getClZbh(); |
| 142 | + LineConfig lineConfig = lineConfigData.get(gps.getLineId()); | |
| 143 | + if (lineConfig != null && lineConfig.isAutoExec() && lineConfig.getAutoExecOffset() > 0) { | |
| 144 | + if (gps.getTimestamp() < sch.getZdsjT() - lineConfig.getAutoExecOffset() * 60000 || gps.getTimestamp() > sch.getZdsjT() + lineConfig.getAutoExecOffset() * 60000) { | |
| 145 | + return; | |
| 146 | + } | |
| 147 | + } | |
| 142 | 148 | //校验进站前置约束 |
| 143 | 149 | if (!validInPremise(gps) && isNormalSch(sch)) |
| 144 | 150 | return; | ... | ... |
src/main/java/com/bsth/data/gpsdata_v2/handlers/OutStationProcess.java
| ... | ... | @@ -46,7 +46,7 @@ public class OutStationProcess { |
| 46 | 46 | public void process(GpsEntity gps) { |
| 47 | 47 | //自动执行的线路,滚蛋 |
| 48 | 48 | LineConfig config = lineConfigData.get(gps.getLineId()); |
| 49 | - if (null != config && config.isAutoExec()) | |
| 49 | + if (null != config && config.isAutoExec() && config.getAutoExecOffset() == 0) | |
| 50 | 50 | return; |
| 51 | 51 | |
| 52 | 52 | GpsEntity prev = GpsCacheData.getPrev(gps); |
| ... | ... | @@ -86,6 +86,13 @@ public class OutStationProcess { |
| 86 | 86 | ((sch.getQdzCode().equals(prev.getStopNo()) |
| 87 | 87 | && (gps.getInstation() == 0 || !gps.getStopNo().equals(prev.getStopNo()))) |
| 88 | 88 | || sch.getQdzCode().equals(prev.getCarparkNo()))) { |
| 89 | + LineConfig lineConfig = lineConfigData.get(gps.getLineId()); | |
| 90 | + if (lineConfig != null && lineConfig.isAutoExec() && lineConfig.getAutoExecOffset() > 0) { | |
| 91 | + if (gps.getTimestamp() < sch.getDfsjT() - lineConfig.getAutoExecOffset() * 60000 || gps.getTimestamp() > sch.getDfsjT() + lineConfig.getAutoExecOffset() * 60000) { | |
| 92 | + return; | |
| 93 | + } | |
| 94 | + } | |
| 95 | + | |
| 89 | 96 | //发车班次匹配 |
| 90 | 97 | if (!signalSchPlanMatcher.outMatch(gps, sch)) { |
| 91 | 98 | outStation(gps, prev); | ... | ... |
src/main/java/com/bsth/data/gpsdata_v2/utils/GeoUtils.java
| 1 | -package com.bsth.data.gpsdata_v2.utils; | |
| 2 | - | |
| 3 | -import com.bsth.data.gpsdata_v2.cache.GeoCacheData; | |
| 4 | -import com.bsth.data.gpsdata_v2.cache.GpsCacheData; | |
| 5 | -import com.bsth.data.gpsdata_v2.entity.CtLineString; | |
| 6 | -import com.bsth.data.gpsdata_v2.entity.GpsEntity; | |
| 7 | -import com.bsth.data.gpsdata_v2.entity.PreconditionGeo; | |
| 8 | -import com.bsth.data.gpsdata_v2.entity.StationRoute; | |
| 9 | -import com.bsth.util.Geo.Bounds; | |
| 10 | -import com.bsth.util.Geo.Point; | |
| 11 | -import com.bsth.util.Geo.Polygon; | |
| 12 | - | |
| 13 | -import java.util.*; | |
| 14 | - | |
| 15 | -/** | |
| 16 | - * Created by panzhao on 2016/12/23. | |
| 17 | - */ | |
| 18 | -public class GeoUtils { | |
| 19 | - | |
| 20 | - private final static double EARTH_RADIUS = 6378137; | |
| 21 | - | |
| 22 | - private static StationRouteComp sComp = new StationRouteComp(); | |
| 23 | - /** | |
| 24 | - * gps是否在路由上的某个站内 | |
| 25 | - * | |
| 26 | - * @param gps | |
| 27 | - * @param srs | |
| 28 | - * @return | |
| 29 | - */ | |
| 30 | - public static StationRoute gpsInStation(GpsEntity gps, List<StationRoute> srs) { | |
| 31 | - List<StationRoute> rs = new ArrayList<>(); | |
| 32 | - | |
| 33 | - Point point = new Point(gps.getLon(), gps.getLat()); | |
| 34 | - double distance; | |
| 35 | - | |
| 36 | - for (StationRoute sr : srs) { | |
| 37 | - if (sr.getPolygon() == null) { | |
| 38 | - //圆形 | |
| 39 | - distance = getDistance(sr.getPoint(), point); | |
| 40 | - | |
| 41 | - if (distance > sr.getRadius()) | |
| 42 | - continue; | |
| 43 | - | |
| 44 | - rs.add(sr); | |
| 45 | - } else if(isPointInPolygon(point, sr.getPolygon())){ | |
| 46 | - rs.add(sr); | |
| 47 | - } | |
| 48 | - } | |
| 49 | - | |
| 50 | - if(rs.size() == 0) | |
| 51 | - return null; | |
| 52 | - else | |
| 53 | - return findNearStation(rs, gps); | |
| 54 | - } | |
| 55 | - | |
| 56 | - private static StationRoute findNearStation(List<StationRoute> rs, GpsEntity gps) { | |
| 57 | - if(rs.size() > 1){ | |
| 58 | - //按路由顺序排序 | |
| 59 | - Collections.sort(rs, sComp); | |
| 60 | - | |
| 61 | - //上一个进出的站点 | |
| 62 | - StationRoute ps = GpsCacheData.prevStation(gps); | |
| 63 | - if(null != ps){ | |
| 64 | - for(StationRoute s : rs){ | |
| 65 | - if(s.getRouteSort() >= ps.getRouteSort()) | |
| 66 | - return s; | |
| 67 | - } | |
| 68 | - } | |
| 69 | - } | |
| 70 | - return rs.get(0); | |
| 71 | - } | |
| 72 | - | |
| 73 | - | |
| 74 | - public static double getDistance(Point p1, Point p2) { | |
| 75 | - double lng1 = getLoop(p1.getLon(), -180, 180), lat1 = getRange( | |
| 76 | - p1.getLat(), -74, 74); | |
| 77 | - double lng2 = getLoop(p2.getLon(), -180, 180), lat2 = getRange( | |
| 78 | - p2.getLat(), -74, 74); | |
| 79 | - | |
| 80 | - double x1, x2, y1, y2; | |
| 81 | - x1 = degreeToRad(lng1); | |
| 82 | - y1 = degreeToRad(lat1); | |
| 83 | - x2 = degreeToRad(lng2); | |
| 84 | - y2 = degreeToRad(lat2); | |
| 85 | - return EARTH_RADIUS | |
| 86 | - * Math.acos((Math.sin(y1) * Math.sin(y2) + Math.cos(y1) | |
| 87 | - * Math.cos(y2) * Math.cos(x2 - x1))); | |
| 88 | - } | |
| 89 | - | |
| 90 | - private static double getLoop(double v, double a, double b) { | |
| 91 | - while (v > b) { | |
| 92 | - v -= b - a; | |
| 93 | - } | |
| 94 | - while (v < a) { | |
| 95 | - v += b - a; | |
| 96 | - } | |
| 97 | - return v; | |
| 98 | - } | |
| 99 | - | |
| 100 | - private static double getRange(double v, double a, double b) { | |
| 101 | - v = Math.min(Math.max(v, a), b); | |
| 102 | - return v; | |
| 103 | - } | |
| 104 | - | |
| 105 | - private static double degreeToRad(double degree) { | |
| 106 | - return Math.PI * degree / 180; | |
| 107 | - } | |
| 108 | - | |
| 109 | - public static double getDistanceFromLine(CtLineString lineString, Point p){ | |
| 110 | - return getDistanceFromLine(lineString.getS(), lineString.getE(), p); | |
| 111 | - } | |
| 112 | - | |
| 113 | - /** | |
| 114 | - * 计算点 到 线的距离 | |
| 115 | - * @param line | |
| 116 | - * @param p | |
| 117 | - * @return | |
| 118 | - */ | |
| 119 | - public static double getDistanceFromLine(Point s, Point e, Point p){ | |
| 120 | - double d1 = getDistance(s, p); | |
| 121 | - double d2 = getDistance(p, e); | |
| 122 | - double d3 = getDistance(s, e); | |
| 123 | - double distance = 0; | |
| 124 | - | |
| 125 | - double alpha = Math.acos((d1*d1 + d3*d3 - d2*d2)/(2*d1*d3)); | |
| 126 | - double beta = Math.acos((d2*d2 + d3*d3 - d1*d1)/(2*d2*d3)); | |
| 127 | - | |
| 128 | - if(alpha>Math.PI/2) { | |
| 129 | - distance = d1; | |
| 130 | - } | |
| 131 | - else if(beta > Math.PI/2) { | |
| 132 | - distance = d2; | |
| 133 | - } | |
| 134 | - else { | |
| 135 | - distance = Math.sin(alpha) * d1; | |
| 136 | - } | |
| 137 | - return distance; | |
| 138 | - } | |
| 139 | - | |
| 140 | - /** | |
| 141 | - * gps 是否在某个停车场内 | |
| 142 | - * @param gps | |
| 143 | - * @return | |
| 144 | - */ | |
| 145 | - public static String gpsInCarpark(GpsEntity gps){ | |
| 146 | - Point point = new Point(gps.getLon(), gps.getLat()); | |
| 147 | - Map<String, Polygon> carparkMap = GeoCacheData.tccMap; | |
| 148 | - | |
| 149 | - Set<String> codes = carparkMap.keySet(); | |
| 150 | - for(String code : codes){ | |
| 151 | - if(isPointInPolygon(point, carparkMap.get(code))){ | |
| 152 | - return code; | |
| 153 | - } | |
| 154 | - } | |
| 155 | - return null; | |
| 156 | - } | |
| 157 | - | |
| 158 | - /** | |
| 159 | - * 是否在进站前置围栏内 | |
| 160 | - * @param gps | |
| 161 | - * @return | |
| 162 | - */ | |
| 163 | - public static String gpsInPremiseGeo(GpsEntity gps) { | |
| 164 | - List<PreconditionGeo> list = GeoCacheData.premiseGeoMap.get(gps.getLineId()+"_"+gps.getUpDown()); | |
| 165 | - | |
| 166 | - if(null == list || list.size()==0) | |
| 167 | - return null; | |
| 168 | - | |
| 169 | - Point point = new Point(gps.getLon(), gps.getLat()); | |
| 170 | - for(PreconditionGeo p : list){ | |
| 171 | - if(isPointInPolygon(point, p.getPolygon())){ | |
| 172 | - return p.getStationCode(); | |
| 173 | - } | |
| 174 | - } | |
| 175 | - return null; | |
| 176 | - } | |
| 177 | - | |
| 178 | - /** | |
| 179 | - * 是否是有效的连续点 | |
| 180 | - * @param prevGps | |
| 181 | - * @param gps | |
| 182 | - * @return | |
| 183 | - */ | |
| 184 | - public static boolean overdue(GpsEntity prevGps, GpsEntity gps) { | |
| 185 | - return gps.getTimestamp() - prevGps.getTimestamp() < 120000; | |
| 186 | - } | |
| 187 | - | |
| 188 | - /** | |
| 189 | - * 计算2条直线的最短距离 | |
| 190 | - * @param p1 | |
| 191 | - * @param p2 | |
| 192 | - * @param p3 | |
| 193 | - * @param p4 | |
| 194 | - * @return | |
| 195 | - */ | |
| 196 | - public static double getDistanceLineToLine(Point p1, Point p2, Point p3, Point p4){ | |
| 197 | - double distance; | |
| 198 | - double x1 = p1.getLat(); //A点坐标(x1,y1,z1) | |
| 199 | - double y1 = p1.getLon(); | |
| 200 | - double z1 = 0; | |
| 201 | - double x2 = p2.getLat(); //B点坐标(x2,y2,z2) | |
| 202 | - double y2 = p2.getLon(); | |
| 203 | - double z2 = 0; | |
| 204 | - double x3 = p3.getLat(); //C点坐标(x3,y3,z3) | |
| 205 | - double y3 = p3.getLon(); | |
| 206 | - double z3 = 0; | |
| 207 | - double x4 = p4.getLat(); //D点坐标(x4,y4,z4) | |
| 208 | - double y4 = p4.getLon(); | |
| 209 | - double z4 = 0; | |
| 210 | - | |
| 211 | - double a = (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1); | |
| 212 | - double b = -((x2-x1)*(x4-x3)+(y2-y1)*(y4-y3)+(z2-z1)*(z4-z3)); | |
| 213 | - double c = -((x1-x2)*(x1-x3)+(y1-y2)*(y1-y3)+(z1-z2)*(z1-z3)); | |
| 214 | - | |
| 215 | - double d = -((x2-x1)*(x4-x3)+(y2-y1)*(y4-y3)+(z2-z1)*(z4-z3)); | |
| 216 | - double e = (x4-x3)*(x4-x3)+(y4-y3)*(y4-y3)+(z4-z3)*(z4-z3); | |
| 217 | - double f = -((x1-x3)*(x4-x3)+(y1-y3)*(y4-y3)+(z1-z3)*(z4-z3)); | |
| 218 | - | |
| 219 | - //平行 | |
| 220 | - if ((a*e-b*d)==0&&(b*d-a*e)==0) | |
| 221 | - { | |
| 222 | - double d1 = getDistance(p1, p3); | |
| 223 | - double d2 = getDistance(p1, p4); | |
| 224 | - distance = (d1<d2)?d1:d2; | |
| 225 | - return distance; | |
| 226 | - } | |
| 227 | - | |
| 228 | - double s = (b*f-e*c)/(a*e-b*d); | |
| 229 | - double t = (a*f-d*c)/(b*d-a*e); | |
| 230 | - | |
| 231 | - //说明P点落在线段AB上,Q点落在线段CD上 | |
| 232 | - if(0<=s&&s<=1&&0<=t&&t<=1) | |
| 233 | - { | |
| 234 | - //2条线段的公垂线段PQ; | |
| 235 | - //P点坐标 | |
| 236 | - double X = x1+s*(x2-x1); | |
| 237 | - double Y = y1+s*(y2-y1); | |
| 238 | - double Z = z1+s*(z2-z1); | |
| 239 | - //Q点坐标 | |
| 240 | - double U = x3+t*(x4-x3); | |
| 241 | - double V = y3+t*(y4-y3); | |
| 242 | - double W = z3+t*(z4-z3); | |
| 243 | - | |
| 244 | - Point p = new Point(Y, X); | |
| 245 | - Point q = new Point(V, U); | |
| 246 | - distance = getDistance(p, q); | |
| 247 | - } | |
| 248 | - else | |
| 249 | - { | |
| 250 | - double d1 = getDistanceFromLine(p3,p4,p1); | |
| 251 | - double d2 = getDistanceFromLine(p3,p4,p2); | |
| 252 | - double d3 = getDistanceFromLine(p1,p2,p3); | |
| 253 | - double d4 = getDistanceFromLine(p1,p2,p4); | |
| 254 | - distance = (d1<d2)?d1:d2; | |
| 255 | - distance = (distance<d3)?distance:d3; | |
| 256 | - distance = (distance<d4)?distance:d4; | |
| 257 | - } | |
| 258 | - | |
| 259 | - return distance; | |
| 260 | - } | |
| 261 | - | |
| 262 | - /** | |
| 263 | - * 计算点 到 线的垂直交点 | |
| 264 | - * @param lp1 | |
| 265 | - * @param lp2 | |
| 266 | - * @param p | |
| 267 | - * @return | |
| 268 | - */ | |
| 269 | - public static Point perpendularPoint(Point lp1, Point lp2, Point p){ | |
| 270 | - double a = lp1.getLat() - lp2.getLat(), b = lp2.getLon() - lp1.getLon(), c = lp1.getLon() * lp2.getLat() - lp2.getLon() * lp1.getLat(); | |
| 271 | - double lon = (Math.pow(b, 2) * p.getLon() - a * b * p.getLat() - a * c) / (Math.pow(a, 2) + Math.pow(b, 2)); | |
| 272 | - double lat = (Math.pow(a, 2) * p.getLat() - a * b * p.getLon() - b * c) / (Math.pow(a, 2) + Math.pow(b, 2)); | |
| 273 | - | |
| 274 | - return new Point(lon, lat); | |
| 275 | - } | |
| 276 | - | |
| 277 | - public static boolean isPointInRect(Point point, Bounds bounds) { | |
| 278 | - Point sw = bounds.getSouthWest(); // 西南脚点 | |
| 279 | - Point ne = bounds.getNorthEast(); // 东北脚点 | |
| 280 | - return (point.getLon() >= sw.getLon() && point.getLon() <= ne.getLon() | |
| 281 | - && point.getLat() >= sw.getLat() && point.getLat() <= ne | |
| 282 | - .getLat()); | |
| 283 | - } | |
| 284 | - | |
| 285 | - public static boolean isPointInPolygon(Point point, Polygon polygon) { | |
| 286 | - Bounds polygonBounds = polygon.getBounds(); | |
| 287 | - if (!isPointInRect(point, polygonBounds)) { | |
| 288 | - return false; | |
| 289 | - } | |
| 290 | - | |
| 291 | - List<Point> pts = polygon.getPoints();// 获取多边形点 | |
| 292 | - | |
| 293 | - // 下述代码来源:http://paulbourke.net/geometry/insidepoly/,进行了部分修改 | |
| 294 | - // 基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则 | |
| 295 | - // 在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。 | |
| 296 | - | |
| 297 | - int N = pts.size(); | |
| 298 | - boolean boundOrVertex = true; // 如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true | |
| 299 | - int intersectCount = 0;// cross points count of x | |
| 300 | - double precision = 2e-10; // 浮点类型计算时候与0比较时候的容差 | |
| 301 | - Point p1, p2;// neighbour bound vertices | |
| 302 | - Point p = point; // 测试点 | |
| 303 | - | |
| 304 | - p1 = pts.get(0);// left vertex | |
| 305 | - for (int i = 1; i <= N; ++i) {// check all rays | |
| 306 | - if (p.equals(p1)) { | |
| 307 | - return boundOrVertex;// p is an vertex | |
| 308 | - } | |
| 309 | - | |
| 310 | - p2 = pts.get(i % N);// right vertex | |
| 311 | - if (p.getLat() < Math.min(p1.getLat(), p2.getLat()) | |
| 312 | - || p.getLat() > Math.max(p1.getLat(), p2.getLat())) {// ray | |
| 313 | - // is | |
| 314 | - // outside | |
| 315 | - // of | |
| 316 | - // our | |
| 317 | - // interests | |
| 318 | - p1 = p2; | |
| 319 | - continue;// next ray left point | |
| 320 | - } | |
| 321 | - | |
| 322 | - if (p.getLat() > Math.min(p1.getLat(), p2.getLat()) | |
| 323 | - && p.getLat() < Math.max(p1.getLat(), p2.getLat())) {// ray | |
| 324 | - // is | |
| 325 | - // crossing | |
| 326 | - // over | |
| 327 | - // by | |
| 328 | - // the | |
| 329 | - // algorithm | |
| 330 | - // (common | |
| 331 | - // part | |
| 332 | - // of) | |
| 333 | - if (p.getLon() <= Math.max(p1.getLon(), p2.getLon())) {// x is | |
| 334 | - // before | |
| 335 | - // of | |
| 336 | - // ray | |
| 337 | - if (p1.getLat() == p2.getLat() | |
| 338 | - && p.getLon() >= Math.min(p1.getLon(), p2.getLon())) {// overlies | |
| 339 | - // on | |
| 340 | - // a | |
| 341 | - // horizontal | |
| 342 | - // ray | |
| 343 | - return boundOrVertex; | |
| 344 | - } | |
| 345 | - | |
| 346 | - if (p1.getLon() == p2.getLon()) {// ray is vertical | |
| 347 | - if (p1.getLon() == p.getLon()) {// overlies on a | |
| 348 | - // vertical ray | |
| 349 | - return boundOrVertex; | |
| 350 | - } else {// before ray | |
| 351 | - ++intersectCount; | |
| 352 | - } | |
| 353 | - } else {// cross point on the left side | |
| 354 | - double xinters = (p.getLat() - p1.getLat()) | |
| 355 | - * (p2.getLon() - p1.getLon()) | |
| 356 | - / (p2.getLat() - p1.getLat()) + p1.getLon();// cross | |
| 357 | - // point | |
| 358 | - // of | |
| 359 | - // lng | |
| 360 | - if (Math.abs(p.getLon() - xinters) < precision) {// overlies | |
| 361 | - // on | |
| 362 | - // a | |
| 363 | - // ray | |
| 364 | - return boundOrVertex; | |
| 365 | - } | |
| 366 | - | |
| 367 | - if (p.getLon() < xinters) {// before ray | |
| 368 | - ++intersectCount; | |
| 369 | - } | |
| 370 | - } | |
| 371 | - } | |
| 372 | - } else {// special case when ray is crossing through the vertex | |
| 373 | - if (p.getLat() == p2.getLat() && p.getLon() <= p2.getLon()) {// p | |
| 374 | - // crossing | |
| 375 | - // over | |
| 376 | - // p2 | |
| 377 | - Point p3 = pts.get((i + 1) % N); // next vertex | |
| 378 | - if (p.getLat() >= Math.min(p1.getLat(), p3.getLat()) | |
| 379 | - && p.getLat() <= Math.max(p1.getLat(), p3.getLat())) {// p.lat | |
| 380 | - // lies | |
| 381 | - // between | |
| 382 | - // p1.lat | |
| 383 | - // & | |
| 384 | - // p3.lat | |
| 385 | - ++intersectCount; | |
| 386 | - } else { | |
| 387 | - intersectCount += 2; | |
| 388 | - } | |
| 389 | - } | |
| 390 | - } | |
| 391 | - p1 = p2;// next ray left point | |
| 392 | - } | |
| 393 | - | |
| 394 | - if (intersectCount % 2 == 0) {// 偶数在多边形外 | |
| 395 | - return false; | |
| 396 | - } else { // 奇数在多边形内 | |
| 397 | - return true; | |
| 398 | - } | |
| 399 | - } | |
| 400 | - | |
| 401 | -} | |
| 1 | +package com.bsth.data.gpsdata_v2.utils; | |
| 2 | + | |
| 3 | +import com.bsth.data.gpsdata_v2.cache.GeoCacheData; | |
| 4 | +import com.bsth.data.gpsdata_v2.cache.GpsCacheData; | |
| 5 | +import com.bsth.data.gpsdata_v2.entity.CtLineString; | |
| 6 | +import com.bsth.data.gpsdata_v2.entity.GpsEntity; | |
| 7 | +import com.bsth.data.gpsdata_v2.entity.PreconditionGeo; | |
| 8 | +import com.bsth.data.gpsdata_v2.entity.StationRoute; | |
| 9 | +import com.bsth.util.Geo.Bounds; | |
| 10 | +import com.bsth.util.Geo.Point; | |
| 11 | +import com.bsth.util.Geo.Polygon; | |
| 12 | + | |
| 13 | +import java.util.*; | |
| 14 | + | |
| 15 | +/** | |
| 16 | + * Created by panzhao on 2016/12/23. | |
| 17 | + */ | |
| 18 | +public class GeoUtils { | |
| 19 | + | |
| 20 | + private final static double EARTH_RADIUS = 6378137; | |
| 21 | + | |
| 22 | + private static StationRouteComp sComp = new StationRouteComp(); | |
| 23 | + /** | |
| 24 | + * gps是否在路由上的某个站内 | |
| 25 | + * | |
| 26 | + * @param gps | |
| 27 | + * @param srs | |
| 28 | + * @return | |
| 29 | + */ | |
| 30 | + public static StationRoute gpsInStation(GpsEntity gps, List<StationRoute> srs) { | |
| 31 | + List<StationRoute> rs = new ArrayList<>(); | |
| 32 | + | |
| 33 | + Point point = new Point(gps.getLon(), gps.getLat()); | |
| 34 | + double distance; | |
| 35 | + | |
| 36 | + for (StationRoute sr : srs) { | |
| 37 | + if (sr.getPolygon() == null) { | |
| 38 | + //圆形 | |
| 39 | + distance = getDistance(sr.getPoint(), point); | |
| 40 | + | |
| 41 | + if (distance > sr.getRadius()) | |
| 42 | + continue; | |
| 43 | + | |
| 44 | + rs.add(sr); | |
| 45 | + } else if(isPointInPolygon(point, sr.getPolygon())){ | |
| 46 | + rs.add(sr); | |
| 47 | + } | |
| 48 | + } | |
| 49 | + | |
| 50 | + if(rs.size() == 0) | |
| 51 | + return null; | |
| 52 | + else | |
| 53 | + return findNearStation(rs, gps); | |
| 54 | + } | |
| 55 | + | |
| 56 | + public static boolean isGpsInSpecialStation(StationRoute sr, Point point) { | |
| 57 | + if (sr.getPolygon() == null) { | |
| 58 | + if (getDistance(sr.getPoint(), point) < sr.getRadius()) { | |
| 59 | + return true; | |
| 60 | + } | |
| 61 | + } else if(isPointInPolygon(point, sr.getPolygon())){ | |
| 62 | + return true; | |
| 63 | + } | |
| 64 | + | |
| 65 | + return false; | |
| 66 | + } | |
| 67 | + | |
| 68 | + private static StationRoute findNearStation(List<StationRoute> rs, GpsEntity gps) { | |
| 69 | + if(rs.size() > 1){ | |
| 70 | + //按路由顺序排序 | |
| 71 | + Collections.sort(rs, sComp); | |
| 72 | + | |
| 73 | + //上一个进出的站点 | |
| 74 | + StationRoute ps = GpsCacheData.prevStation(gps); | |
| 75 | + if(null != ps){ | |
| 76 | + for(StationRoute s : rs){ | |
| 77 | + if(s.getRouteSort() >= ps.getRouteSort()) | |
| 78 | + return s; | |
| 79 | + } | |
| 80 | + } | |
| 81 | + } | |
| 82 | + return rs.get(0); | |
| 83 | + } | |
| 84 | + | |
| 85 | + | |
| 86 | + public static double getDistance(Point p1, Point p2) { | |
| 87 | + double lng1 = getLoop(p1.getLon(), -180, 180), lat1 = getRange( | |
| 88 | + p1.getLat(), -74, 74); | |
| 89 | + double lng2 = getLoop(p2.getLon(), -180, 180), lat2 = getRange( | |
| 90 | + p2.getLat(), -74, 74); | |
| 91 | + | |
| 92 | + double x1, x2, y1, y2; | |
| 93 | + x1 = degreeToRad(lng1); | |
| 94 | + y1 = degreeToRad(lat1); | |
| 95 | + x2 = degreeToRad(lng2); | |
| 96 | + y2 = degreeToRad(lat2); | |
| 97 | + return EARTH_RADIUS | |
| 98 | + * Math.acos((Math.sin(y1) * Math.sin(y2) + Math.cos(y1) | |
| 99 | + * Math.cos(y2) * Math.cos(x2 - x1))); | |
| 100 | + } | |
| 101 | + | |
| 102 | + private static double getLoop(double v, double a, double b) { | |
| 103 | + while (v > b) { | |
| 104 | + v -= b - a; | |
| 105 | + } | |
| 106 | + while (v < a) { | |
| 107 | + v += b - a; | |
| 108 | + } | |
| 109 | + return v; | |
| 110 | + } | |
| 111 | + | |
| 112 | + private static double getRange(double v, double a, double b) { | |
| 113 | + v = Math.min(Math.max(v, a), b); | |
| 114 | + return v; | |
| 115 | + } | |
| 116 | + | |
| 117 | + private static double degreeToRad(double degree) { | |
| 118 | + return Math.PI * degree / 180; | |
| 119 | + } | |
| 120 | + | |
| 121 | + public static double getDistanceFromLine(CtLineString lineString, Point p){ | |
| 122 | + return getDistanceFromLine(lineString.getS(), lineString.getE(), p); | |
| 123 | + } | |
| 124 | + | |
| 125 | + /** | |
| 126 | + * 计算点 到 线的距离 | |
| 127 | + * @param line | |
| 128 | + * @param p | |
| 129 | + * @return | |
| 130 | + */ | |
| 131 | + public static double getDistanceFromLine(Point s, Point e, Point p){ | |
| 132 | + double d1 = getDistance(s, p); | |
| 133 | + double d2 = getDistance(p, e); | |
| 134 | + double d3 = getDistance(s, e); | |
| 135 | + double distance = 0; | |
| 136 | + | |
| 137 | + double alpha = Math.acos((d1*d1 + d3*d3 - d2*d2)/(2*d1*d3)); | |
| 138 | + double beta = Math.acos((d2*d2 + d3*d3 - d1*d1)/(2*d2*d3)); | |
| 139 | + | |
| 140 | + if(alpha>Math.PI/2) { | |
| 141 | + distance = d1; | |
| 142 | + } | |
| 143 | + else if(beta > Math.PI/2) { | |
| 144 | + distance = d2; | |
| 145 | + } | |
| 146 | + else { | |
| 147 | + distance = Math.sin(alpha) * d1; | |
| 148 | + } | |
| 149 | + return distance; | |
| 150 | + } | |
| 151 | + | |
| 152 | + /** | |
| 153 | + * gps 是否在某个停车场内 | |
| 154 | + * @param gps | |
| 155 | + * @return | |
| 156 | + */ | |
| 157 | + public static String gpsInCarpark(GpsEntity gps){ | |
| 158 | + Point point = new Point(gps.getLon(), gps.getLat()); | |
| 159 | + Map<String, Polygon> carparkMap = GeoCacheData.tccMap; | |
| 160 | + | |
| 161 | + Set<String> codes = carparkMap.keySet(); | |
| 162 | + for(String code : codes){ | |
| 163 | + if(isPointInPolygon(point, carparkMap.get(code))){ | |
| 164 | + return code; | |
| 165 | + } | |
| 166 | + } | |
| 167 | + return null; | |
| 168 | + } | |
| 169 | + | |
| 170 | + /** | |
| 171 | + * 是否在进站前置围栏内 | |
| 172 | + * @param gps | |
| 173 | + * @return | |
| 174 | + */ | |
| 175 | + public static String gpsInPremiseGeo(GpsEntity gps) { | |
| 176 | + List<PreconditionGeo> list = GeoCacheData.premiseGeoMap.get(gps.getLineId()+"_"+gps.getUpDown()); | |
| 177 | + | |
| 178 | + if(null == list || list.size()==0) | |
| 179 | + return null; | |
| 180 | + | |
| 181 | + Point point = new Point(gps.getLon(), gps.getLat()); | |
| 182 | + for(PreconditionGeo p : list){ | |
| 183 | + if(isPointInPolygon(point, p.getPolygon())){ | |
| 184 | + return p.getStationCode(); | |
| 185 | + } | |
| 186 | + } | |
| 187 | + return null; | |
| 188 | + } | |
| 189 | + | |
| 190 | + /** | |
| 191 | + * 是否是有效的连续点 | |
| 192 | + * @param prevGps | |
| 193 | + * @param gps | |
| 194 | + * @return | |
| 195 | + */ | |
| 196 | + public static boolean overdue(GpsEntity prevGps, GpsEntity gps) { | |
| 197 | + return gps.getTimestamp() - prevGps.getTimestamp() < 120000; | |
| 198 | + } | |
| 199 | + | |
| 200 | + /** | |
| 201 | + * 计算2条直线的最短距离 | |
| 202 | + * @param p1 | |
| 203 | + * @param p2 | |
| 204 | + * @param p3 | |
| 205 | + * @param p4 | |
| 206 | + * @return | |
| 207 | + */ | |
| 208 | + public static double getDistanceLineToLine(Point p1, Point p2, Point p3, Point p4){ | |
| 209 | + double distance; | |
| 210 | + double x1 = p1.getLat(); //A点坐标(x1,y1,z1) | |
| 211 | + double y1 = p1.getLon(); | |
| 212 | + double z1 = 0; | |
| 213 | + double x2 = p2.getLat(); //B点坐标(x2,y2,z2) | |
| 214 | + double y2 = p2.getLon(); | |
| 215 | + double z2 = 0; | |
| 216 | + double x3 = p3.getLat(); //C点坐标(x3,y3,z3) | |
| 217 | + double y3 = p3.getLon(); | |
| 218 | + double z3 = 0; | |
| 219 | + double x4 = p4.getLat(); //D点坐标(x4,y4,z4) | |
| 220 | + double y4 = p4.getLon(); | |
| 221 | + double z4 = 0; | |
| 222 | + | |
| 223 | + double a = (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1); | |
| 224 | + double b = -((x2-x1)*(x4-x3)+(y2-y1)*(y4-y3)+(z2-z1)*(z4-z3)); | |
| 225 | + double c = -((x1-x2)*(x1-x3)+(y1-y2)*(y1-y3)+(z1-z2)*(z1-z3)); | |
| 226 | + | |
| 227 | + double d = -((x2-x1)*(x4-x3)+(y2-y1)*(y4-y3)+(z2-z1)*(z4-z3)); | |
| 228 | + double e = (x4-x3)*(x4-x3)+(y4-y3)*(y4-y3)+(z4-z3)*(z4-z3); | |
| 229 | + double f = -((x1-x3)*(x4-x3)+(y1-y3)*(y4-y3)+(z1-z3)*(z4-z3)); | |
| 230 | + | |
| 231 | + //平行 | |
| 232 | + if ((a*e-b*d)==0&&(b*d-a*e)==0) | |
| 233 | + { | |
| 234 | + double d1 = getDistance(p1, p3); | |
| 235 | + double d2 = getDistance(p1, p4); | |
| 236 | + distance = (d1<d2)?d1:d2; | |
| 237 | + return distance; | |
| 238 | + } | |
| 239 | + | |
| 240 | + double s = (b*f-e*c)/(a*e-b*d); | |
| 241 | + double t = (a*f-d*c)/(b*d-a*e); | |
| 242 | + | |
| 243 | + //说明P点落在线段AB上,Q点落在线段CD上 | |
| 244 | + if(0<=s&&s<=1&&0<=t&&t<=1) | |
| 245 | + { | |
| 246 | + //2条线段的公垂线段PQ; | |
| 247 | + //P点坐标 | |
| 248 | + double X = x1+s*(x2-x1); | |
| 249 | + double Y = y1+s*(y2-y1); | |
| 250 | + double Z = z1+s*(z2-z1); | |
| 251 | + //Q点坐标 | |
| 252 | + double U = x3+t*(x4-x3); | |
| 253 | + double V = y3+t*(y4-y3); | |
| 254 | + double W = z3+t*(z4-z3); | |
| 255 | + | |
| 256 | + Point p = new Point(Y, X); | |
| 257 | + Point q = new Point(V, U); | |
| 258 | + distance = getDistance(p, q); | |
| 259 | + } | |
| 260 | + else | |
| 261 | + { | |
| 262 | + double d1 = getDistanceFromLine(p3,p4,p1); | |
| 263 | + double d2 = getDistanceFromLine(p3,p4,p2); | |
| 264 | + double d3 = getDistanceFromLine(p1,p2,p3); | |
| 265 | + double d4 = getDistanceFromLine(p1,p2,p4); | |
| 266 | + distance = (d1<d2)?d1:d2; | |
| 267 | + distance = (distance<d3)?distance:d3; | |
| 268 | + distance = (distance<d4)?distance:d4; | |
| 269 | + } | |
| 270 | + | |
| 271 | + return distance; | |
| 272 | + } | |
| 273 | + | |
| 274 | + /** | |
| 275 | + * 计算点 到 线的垂直交点 | |
| 276 | + * @param lp1 | |
| 277 | + * @param lp2 | |
| 278 | + * @param p | |
| 279 | + * @return | |
| 280 | + */ | |
| 281 | + public static Point perpendularPoint(Point lp1, Point lp2, Point p){ | |
| 282 | + double a = lp1.getLat() - lp2.getLat(), b = lp2.getLon() - lp1.getLon(), c = lp1.getLon() * lp2.getLat() - lp2.getLon() * lp1.getLat(); | |
| 283 | + double lon = (Math.pow(b, 2) * p.getLon() - a * b * p.getLat() - a * c) / (Math.pow(a, 2) + Math.pow(b, 2)); | |
| 284 | + double lat = (Math.pow(a, 2) * p.getLat() - a * b * p.getLon() - b * c) / (Math.pow(a, 2) + Math.pow(b, 2)); | |
| 285 | + | |
| 286 | + return new Point(lon, lat); | |
| 287 | + } | |
| 288 | + | |
| 289 | + public static boolean isPointInRect(Point point, Bounds bounds) { | |
| 290 | + Point sw = bounds.getSouthWest(); // 西南脚点 | |
| 291 | + Point ne = bounds.getNorthEast(); // 东北脚点 | |
| 292 | + return (point.getLon() >= sw.getLon() && point.getLon() <= ne.getLon() | |
| 293 | + && point.getLat() >= sw.getLat() && point.getLat() <= ne | |
| 294 | + .getLat()); | |
| 295 | + } | |
| 296 | + | |
| 297 | + public static boolean isPointInPolygon(Point point, Polygon polygon) { | |
| 298 | + Bounds polygonBounds = polygon.getBounds(); | |
| 299 | + if (!isPointInRect(point, polygonBounds)) { | |
| 300 | + return false; | |
| 301 | + } | |
| 302 | + | |
| 303 | + List<Point> pts = polygon.getPoints();// 获取多边形点 | |
| 304 | + | |
| 305 | + // 下述代码来源:http://paulbourke.net/geometry/insidepoly/,进行了部分修改 | |
| 306 | + // 基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则 | |
| 307 | + // 在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。 | |
| 308 | + | |
| 309 | + int N = pts.size(); | |
| 310 | + boolean boundOrVertex = true; // 如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true | |
| 311 | + int intersectCount = 0;// cross points count of x | |
| 312 | + double precision = 2e-10; // 浮点类型计算时候与0比较时候的容差 | |
| 313 | + Point p1, p2;// neighbour bound vertices | |
| 314 | + Point p = point; // 测试点 | |
| 315 | + | |
| 316 | + p1 = pts.get(0);// left vertex | |
| 317 | + for (int i = 1; i <= N; ++i) {// check all rays | |
| 318 | + if (p.equals(p1)) { | |
| 319 | + return boundOrVertex;// p is an vertex | |
| 320 | + } | |
| 321 | + | |
| 322 | + p2 = pts.get(i % N);// right vertex | |
| 323 | + if (p.getLat() < Math.min(p1.getLat(), p2.getLat()) | |
| 324 | + || p.getLat() > Math.max(p1.getLat(), p2.getLat())) {// ray | |
| 325 | + // is | |
| 326 | + // outside | |
| 327 | + // of | |
| 328 | + // our | |
| 329 | + // interests | |
| 330 | + p1 = p2; | |
| 331 | + continue;// next ray left point | |
| 332 | + } | |
| 333 | + | |
| 334 | + if (p.getLat() > Math.min(p1.getLat(), p2.getLat()) | |
| 335 | + && p.getLat() < Math.max(p1.getLat(), p2.getLat())) {// ray | |
| 336 | + // is | |
| 337 | + // crossing | |
| 338 | + // over | |
| 339 | + // by | |
| 340 | + // the | |
| 341 | + // algorithm | |
| 342 | + // (common | |
| 343 | + // part | |
| 344 | + // of) | |
| 345 | + if (p.getLon() <= Math.max(p1.getLon(), p2.getLon())) {// x is | |
| 346 | + // before | |
| 347 | + // of | |
| 348 | + // ray | |
| 349 | + if (p1.getLat() == p2.getLat() | |
| 350 | + && p.getLon() >= Math.min(p1.getLon(), p2.getLon())) {// overlies | |
| 351 | + // on | |
| 352 | + // a | |
| 353 | + // horizontal | |
| 354 | + // ray | |
| 355 | + return boundOrVertex; | |
| 356 | + } | |
| 357 | + | |
| 358 | + if (p1.getLon() == p2.getLon()) {// ray is vertical | |
| 359 | + if (p1.getLon() == p.getLon()) {// overlies on a | |
| 360 | + // vertical ray | |
| 361 | + return boundOrVertex; | |
| 362 | + } else {// before ray | |
| 363 | + ++intersectCount; | |
| 364 | + } | |
| 365 | + } else {// cross point on the left side | |
| 366 | + double xinters = (p.getLat() - p1.getLat()) | |
| 367 | + * (p2.getLon() - p1.getLon()) | |
| 368 | + / (p2.getLat() - p1.getLat()) + p1.getLon();// cross | |
| 369 | + // point | |
| 370 | + // of | |
| 371 | + // lng | |
| 372 | + if (Math.abs(p.getLon() - xinters) < precision) {// overlies | |
| 373 | + // on | |
| 374 | + // a | |
| 375 | + // ray | |
| 376 | + return boundOrVertex; | |
| 377 | + } | |
| 378 | + | |
| 379 | + if (p.getLon() < xinters) {// before ray | |
| 380 | + ++intersectCount; | |
| 381 | + } | |
| 382 | + } | |
| 383 | + } | |
| 384 | + } else {// special case when ray is crossing through the vertex | |
| 385 | + if (p.getLat() == p2.getLat() && p.getLon() <= p2.getLon()) {// p | |
| 386 | + // crossing | |
| 387 | + // over | |
| 388 | + // p2 | |
| 389 | + Point p3 = pts.get((i + 1) % N); // next vertex | |
| 390 | + if (p.getLat() >= Math.min(p1.getLat(), p3.getLat()) | |
| 391 | + && p.getLat() <= Math.max(p1.getLat(), p3.getLat())) {// p.lat | |
| 392 | + // lies | |
| 393 | + // between | |
| 394 | + // p1.lat | |
| 395 | + // & | |
| 396 | + // p3.lat | |
| 397 | + ++intersectCount; | |
| 398 | + } else { | |
| 399 | + intersectCount += 2; | |
| 400 | + } | |
| 401 | + } | |
| 402 | + } | |
| 403 | + p1 = p2;// next ray left point | |
| 404 | + } | |
| 405 | + | |
| 406 | + if (intersectCount % 2 == 0) {// 偶数在多边形外 | |
| 407 | + return false; | |
| 408 | + } else { // 奇数在多边形内 | |
| 409 | + return true; | |
| 410 | + } | |
| 411 | + } | |
| 412 | + | |
| 413 | +} | ... | ... |
src/main/java/com/bsth/data/schedule/SchAttrCalculator.java
| 1 | -package com.bsth.data.schedule; | |
| 2 | - | |
| 3 | -import com.bsth.data.LineConfigData; | |
| 4 | -import com.bsth.entity.realcontrol.LineConfig; | |
| 5 | -import com.bsth.entity.realcontrol.ScheduleRealInfo; | |
| 6 | -import org.apache.commons.lang3.StringUtils; | |
| 7 | -import org.joda.time.format.DateTimeFormat; | |
| 8 | -import org.joda.time.format.DateTimeFormatter; | |
| 9 | -import org.slf4j.Logger; | |
| 10 | -import org.slf4j.LoggerFactory; | |
| 11 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 12 | -import org.springframework.stereotype.Component; | |
| 13 | - | |
| 14 | -import java.text.ParseException; | |
| 15 | -import java.util.ArrayList; | |
| 16 | -import java.util.Collections; | |
| 17 | -import java.util.List; | |
| 18 | - | |
| 19 | -/** | |
| 20 | - * @author PanZhao | |
| 21 | - * @ClassName: SchAttrCalculator | |
| 22 | - * @Description: TODO(班次相关属性计算器) | |
| 23 | - * @date 2016年8月15日 下午4:40:26 | |
| 24 | - */ | |
| 25 | -@Component | |
| 26 | -public class SchAttrCalculator { | |
| 27 | - | |
| 28 | - @Autowired | |
| 29 | - LineConfigData lineConfigData; | |
| 30 | - | |
| 31 | - private final static long DAY_TIME = 1000 * 60 * 60 * 24L; | |
| 32 | - | |
| 33 | - Logger logger = LoggerFactory.getLogger(this.getClass()); | |
| 34 | - | |
| 35 | - private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd"), fmtHHmm = DateTimeFormat.forPattern("HH:mm"), fmtyyyyMMddHHmm = DateTimeFormat.forPattern("yyyy-MM-ddHH:mm"); | |
| 36 | - | |
| 37 | - /** | |
| 38 | - * @Title: calcRealDate | |
| 39 | - * @Description: TODO(计算班次的真实执行日期) | |
| 40 | - */ | |
| 41 | - public SchAttrCalculator calcRealDate(ScheduleRealInfo sch) { | |
| 42 | - LineConfig conf = lineConfigData.get(sch.getXlBm()); | |
| 43 | - | |
| 44 | - try { | |
| 45 | - if (null == sch.getFcsjT()) | |
| 46 | - calcFcsjTime(sch); | |
| 47 | - | |
| 48 | - String rq = sch.getScheduleDateStr(); | |
| 49 | - //计发時間 | |
| 50 | - sch.setFcsjAll(getTime(rq, sch.getFcsj(), conf)); | |
| 51 | - | |
| 52 | - //待发時間 | |
| 53 | - sch.setDfsjAll(getTime(rq, sch.getDfsj(), conf)); | |
| 54 | - /*if (sch.getDfsj().compareTo(conf.getStartOpt()) < 0) { | |
| 55 | - sch.setDfsjAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr() + sch.getDfsj()) + DAY_TIME); | |
| 56 | - } else | |
| 57 | - sch.setDfsjAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr() + sch.getDfsj()));*/ | |
| 58 | - | |
| 59 | - //实发時間 | |
| 60 | - sch.setFcsjActualAll(getTime(rq, sch.getFcsjActual(), conf)); | |
| 61 | - /*if (StringUtils.isNotEmpty(sch.getFcsjActual()) && | |
| 62 | - sch.getFcsjActual().compareTo(conf.getStartOpt()) < 0) { | |
| 63 | - sch.setFcsjActualAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr() + sch.getFcsjActual()) + DAY_TIME); | |
| 64 | - }*/ | |
| 65 | - | |
| 66 | - //实际终点時間 | |
| 67 | - sch.setZdsjActualAll(getTime(rq, sch.getZdsjActual(), conf)); | |
| 68 | - /*if (StringUtils.isNotEmpty(sch.getZdsjActual()) && | |
| 69 | - sch.getZdsjActual().compareTo(conf.getStartOpt()) < 0) { | |
| 70 | - sch.setZdsjActualAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr() + sch.getZdsjActual()) + DAY_TIME); | |
| 71 | - }*/ | |
| 72 | - | |
| 73 | - sch.setRealExecDate(fmtyyyyMMdd.print(sch.getFcsjT())); | |
| 74 | - } catch (Exception e) { | |
| 75 | - logger.error("", e); | |
| 76 | - } | |
| 77 | - return this; | |
| 78 | - } | |
| 79 | - | |
| 80 | - public Long getTime(String rq, String timeStr, LineConfig conf) { | |
| 81 | - Long t = null; | |
| 82 | - if (StringUtils.isNotEmpty(timeStr)) { | |
| 83 | - t = fmtyyyyMMddHHmm.parseMillis(rq + timeStr); | |
| 84 | - if(timeStr.compareTo(conf.getStartOpt()) < 0) | |
| 85 | - return t + DAY_TIME; | |
| 86 | - } | |
| 87 | - return t; | |
| 88 | - } | |
| 89 | - | |
| 90 | - /** | |
| 91 | - * @Title: calcAllTimeByFcsj | |
| 92 | - * @Description: TODO(根据发车时间字符串计算 (计发时间,终点时间,待发时间)) | |
| 93 | - */ | |
| 94 | - public SchAttrCalculator calcAllTimeByFcsj(ScheduleRealInfo sch) { | |
| 95 | - try { | |
| 96 | - // 生成时间戳 | |
| 97 | - calcTimestamp(sch); | |
| 98 | - | |
| 99 | - // 计划终点时间 | |
| 100 | - if (sch.getBcsj() != null) { | |
| 101 | - sch.setZdsjT(sch.getFcsjT() + (sch.getBcsj() * 60 * 1000)); | |
| 102 | - sch.setZdsj(fmtHHmm.print(sch.getZdsjT())); | |
| 103 | - } | |
| 104 | - } catch (ParseException e) { | |
| 105 | - logger.error("", e); | |
| 106 | - } | |
| 107 | - return this; | |
| 108 | - } | |
| 109 | - | |
| 110 | - /** | |
| 111 | - * @Title: calcQdzTimePlan | |
| 112 | - * @Description: TODO(计算班次的起点应到时间) | |
| 113 | - */ | |
| 114 | - public void calcQdzTimePlan(List<ScheduleRealInfo> list) { | |
| 115 | - Collections.sort(list, new ScheduleComparator.FCSJ()); | |
| 116 | - | |
| 117 | - int len = list.size(); | |
| 118 | - if (len == 0) | |
| 119 | - return; | |
| 120 | - | |
| 121 | - ScheduleRealInfo prve = list.get(0), curr; | |
| 122 | - for (int i = 1; i < len; i++) { | |
| 123 | - curr = list.get(i); | |
| 124 | - | |
| 125 | - if (isJoin(prve, curr)) { | |
| 126 | - curr.setQdzArrDatejh(prve.getZdsj()); | |
| 127 | - if (StringUtils.isNotEmpty(prve.getZdsjActual())) | |
| 128 | - curr.setQdzArrDatesj(prve.getZdsjActual()); | |
| 129 | - } | |
| 130 | - prve = curr; | |
| 131 | - } | |
| 132 | - } | |
| 133 | - | |
| 134 | - private boolean isJoin(ScheduleRealInfo prve, ScheduleRealInfo curr) { | |
| 135 | - return prve.getZdzName().equals(curr.getQdzName())//名称相等 | |
| 136 | - || prve.getZdzCode().equals(curr.getQdzCode())//编码相等 | |
| 137 | - || prve.getZdzName().startsWith(curr.getQdzName())//起始包括 | |
| 138 | - || curr.getQdzName().startsWith(prve.getZdzName());//起始包括 | |
| 139 | - } | |
| 140 | - | |
| 141 | - /** | |
| 142 | - * @Title: updateQdzTimePlan | |
| 143 | - * @Description: TODO(更新班次的起点应到时间) 并返回被更新的班次 | |
| 144 | - */ | |
| 145 | - public List<ScheduleRealInfo> updateQdzTimePlan(List<ScheduleRealInfo> list) { | |
| 146 | - Collections.sort(list, new ScheduleComparator.FCSJ()); | |
| 147 | - | |
| 148 | - List<ScheduleRealInfo> updateList = new ArrayList<>(); | |
| 149 | - int len = list.size(); | |
| 150 | - if (len == 0) | |
| 151 | - return updateList; | |
| 152 | - | |
| 153 | - ScheduleRealInfo prve = list.get(0), curr; | |
| 154 | - for (int i = 1; i < len; i++) { | |
| 155 | - curr = list.get(i); | |
| 156 | - | |
| 157 | - if (prve.getZdzName().equals(curr.getQdzName()) | |
| 158 | - || prve.getZdzCode().equals(curr.getQdzCode())) { | |
| 159 | - | |
| 160 | - if (curr.getQdzArrDatejh() != null && prve.getZdsj().equals(curr.getQdzArrDatejh())) { | |
| 161 | - prve = curr; | |
| 162 | - continue; | |
| 163 | - } | |
| 164 | - | |
| 165 | - curr.setQdzArrDatejh(prve.getZdsj()); | |
| 166 | - updateList.add(curr); | |
| 167 | - } else { | |
| 168 | - curr.setQdzArrDatejh(null); | |
| 169 | - updateList.add(curr); | |
| 170 | - } | |
| 171 | - prve = curr; | |
| 172 | - } | |
| 173 | - | |
| 174 | - return updateList; | |
| 175 | - } | |
| 176 | - | |
| 177 | - public SchAttrCalculator calcFcsjTime(ScheduleRealInfo sch) throws ParseException { | |
| 178 | - sch.setFcsjT(fmtyyyyMMddHHmm.parseMillis(sch.getRealExecDate() + sch.getFcsj())); | |
| 179 | - return this; | |
| 180 | - } | |
| 181 | - | |
| 182 | - public void calcTimestamp(ScheduleRealInfo sch) throws ParseException { | |
| 183 | - //计发时间 | |
| 184 | - if (sch.getFcsjT() == null) | |
| 185 | - calcFcsjTime(sch); | |
| 186 | - | |
| 187 | - //待发时间 | |
| 188 | - if (sch.getDfsj() == null) | |
| 189 | - sch.setDfsjAll(sch.getFcsjT()); | |
| 190 | - if (sch.getDfsjT() == null) | |
| 191 | - sch.setDfsjAll(sch.getDfsj()); | |
| 192 | - | |
| 193 | - //实发时间戳 | |
| 194 | - if (sch.getFcsjActualTime() == null && sch.getFcsjActual() != null) | |
| 195 | - sch.setFcsjActualAll(sch.getFcsjActual()); | |
| 196 | - | |
| 197 | - //实达时间戳 | |
| 198 | - if (sch.getZdsjActualTime() == null && sch.getZdsjActual() != null) | |
| 199 | - sch.setZdsjActualAll(sch.getZdsjActual()); | |
| 200 | - } | |
| 201 | - | |
| 202 | - /** | |
| 203 | - * 计算当前要执行的班次 | |
| 204 | - * | |
| 205 | - * @param list | |
| 206 | - * @return | |
| 207 | - */ | |
| 208 | - public ScheduleRealInfo calcCurrentExecSch(List<ScheduleRealInfo> list) { | |
| 209 | - if(list.size()==0) | |
| 210 | - return null; | |
| 211 | - String lineCode = list.get(0).getXlBm(); | |
| 212 | - LineConfig conf = lineConfigData.get(lineCode); | |
| 213 | - | |
| 214 | - int outConfig = -1; | |
| 215 | - //限定出站既出场的停车场 | |
| 216 | - List<String> parks = null; | |
| 217 | - if (conf != null) { | |
| 218 | - outConfig = conf.getOutConfig(); | |
| 219 | - parks = conf.findTwinsParkList(); | |
| 220 | - } | |
| 221 | - boolean limitPark = null != parks && parks.size() > 0; | |
| 222 | - | |
| 223 | - ScheduleRealInfo sch, prev = null; | |
| 224 | - for(int i = list.size() - 1; i >= 0; i --){ | |
| 225 | - sch = list.get(i); | |
| 226 | - | |
| 227 | - //如果是出站既出场,忽略出场班次 | |
| 228 | - if (outConfig == 2 && sch.getBcType().equals("out") | |
| 229 | - && (!limitPark || parks.contains(sch.getQdzCode())) | |
| 230 | - && (sch.getBcsj()==0 || sch.getJhlcOrig().intValue()==0)) | |
| 231 | - continue; | |
| 232 | - | |
| 233 | - //忽略烂班 | |
| 234 | - if (sch.isDestroy()) | |
| 235 | - continue; | |
| 236 | - | |
| 237 | - if (StringUtils.isNotEmpty(sch.getZdsjActual())) | |
| 238 | - break; | |
| 239 | - | |
| 240 | - prev = sch; | |
| 241 | - } | |
| 242 | - return prev; | |
| 243 | - } | |
| 244 | -} | |
| 1 | +package com.bsth.data.schedule; | |
| 2 | + | |
| 3 | +import com.bsth.data.LineConfigData; | |
| 4 | +import com.bsth.entity.realcontrol.LineConfig; | |
| 5 | +import com.bsth.entity.realcontrol.ScheduleRealInfo; | |
| 6 | +import org.apache.commons.lang3.StringUtils; | |
| 7 | +import org.joda.time.format.DateTimeFormat; | |
| 8 | +import org.joda.time.format.DateTimeFormatter; | |
| 9 | +import org.slf4j.Logger; | |
| 10 | +import org.slf4j.LoggerFactory; | |
| 11 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 12 | +import org.springframework.stereotype.Component; | |
| 13 | + | |
| 14 | +import java.text.ParseException; | |
| 15 | +import java.util.ArrayList; | |
| 16 | +import java.util.Collections; | |
| 17 | +import java.util.List; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * @author PanZhao | |
| 21 | + * @ClassName: SchAttrCalculator | |
| 22 | + * @Description: TODO(班次相关属性计算器) | |
| 23 | + * @date 2016年8月15日 下午4:40:26 | |
| 24 | + */ | |
| 25 | +@Component | |
| 26 | +public class SchAttrCalculator { | |
| 27 | + | |
| 28 | + @Autowired | |
| 29 | + LineConfigData lineConfigData; | |
| 30 | + | |
| 31 | + private final static long DAY_TIME = 1000 * 60 * 60 * 24L; | |
| 32 | + | |
| 33 | + Logger logger = LoggerFactory.getLogger(this.getClass()); | |
| 34 | + | |
| 35 | + private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd"), fmtHHmm = DateTimeFormat.forPattern("HH:mm"), fmtyyyyMMddHHmm = DateTimeFormat.forPattern("yyyy-MM-ddHH:mm"); | |
| 36 | + | |
| 37 | + /** | |
| 38 | + * @Title: calcRealDate | |
| 39 | + * @Description: TODO(计算班次的真实执行日期) | |
| 40 | + */ | |
| 41 | + public SchAttrCalculator calcRealDate(ScheduleRealInfo sch) { | |
| 42 | + LineConfig conf = lineConfigData.get(sch.getXlBm()); | |
| 43 | + | |
| 44 | + try { | |
| 45 | + if (null == sch.getFcsjT()) | |
| 46 | + calcFcsjTime(sch); | |
| 47 | + | |
| 48 | + String rq = sch.getScheduleDateStr(); | |
| 49 | + //计发時間 | |
| 50 | + sch.setFcsjAll(getTime(rq, sch.getFcsj(), conf)); | |
| 51 | + | |
| 52 | + //待发時間 | |
| 53 | + sch.setDfsjAll(getTime(rq, sch.getDfsj(), conf)); | |
| 54 | + /*if (sch.getDfsj().compareTo(conf.getStartOpt()) < 0) { | |
| 55 | + sch.setDfsjAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr() + sch.getDfsj()) + DAY_TIME); | |
| 56 | + } else | |
| 57 | + sch.setDfsjAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr() + sch.getDfsj()));*/ | |
| 58 | + | |
| 59 | + //实发時間 | |
| 60 | + sch.setFcsjActualAll(getTime(rq, sch.getFcsjActual(), conf)); | |
| 61 | + /*if (StringUtils.isNotEmpty(sch.getFcsjActual()) && | |
| 62 | + sch.getFcsjActual().compareTo(conf.getStartOpt()) < 0) { | |
| 63 | + sch.setFcsjActualAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr() + sch.getFcsjActual()) + DAY_TIME); | |
| 64 | + }*/ | |
| 65 | + | |
| 66 | + //实际终点時間 | |
| 67 | + sch.setZdsjActualAll(getTime(rq, sch.getZdsjActual(), conf)); | |
| 68 | + /*if (StringUtils.isNotEmpty(sch.getZdsjActual()) && | |
| 69 | + sch.getZdsjActual().compareTo(conf.getStartOpt()) < 0) { | |
| 70 | + sch.setZdsjActualAll(fmtyyyyMMddHHmm.parseMillis(sch.getScheduleDateStr() + sch.getZdsjActual()) + DAY_TIME); | |
| 71 | + }*/ | |
| 72 | + | |
| 73 | + sch.setRealExecDate(fmtyyyyMMdd.print(sch.getFcsjT())); | |
| 74 | + } catch (Exception e) { | |
| 75 | + logger.error("", e); | |
| 76 | + } | |
| 77 | + return this; | |
| 78 | + } | |
| 79 | + | |
| 80 | + public Long getTime(String rq, String timeStr, LineConfig conf) { | |
| 81 | + Long t = null; | |
| 82 | + if (StringUtils.isNotEmpty(timeStr)) { | |
| 83 | + t = fmtyyyyMMddHHmm.parseMillis(rq + timeStr); | |
| 84 | + if(timeStr.compareTo(conf.getStartOpt()) < 0) | |
| 85 | + return t + DAY_TIME; | |
| 86 | + } | |
| 87 | + return t; | |
| 88 | + } | |
| 89 | + | |
| 90 | + /** | |
| 91 | + * @Title: calcAllTimeByFcsj | |
| 92 | + * @Description: TODO(根据发车时间字符串计算 (计发时间,终点时间,待发时间)) | |
| 93 | + */ | |
| 94 | + public SchAttrCalculator calcAllTimeByFcsj(ScheduleRealInfo sch) { | |
| 95 | + try { | |
| 96 | + // 生成时间戳 | |
| 97 | + calcTimestamp(sch); | |
| 98 | + | |
| 99 | + // 计划终点时间 | |
| 100 | + if (sch.getBcsj() != null) { | |
| 101 | + sch.setZdsjT(sch.getFcsjT() + (sch.getBcsj() * 60 * 1000)); | |
| 102 | + sch.setZdsj(fmtHHmm.print(sch.getZdsjT())); | |
| 103 | + } | |
| 104 | + } catch (ParseException e) { | |
| 105 | + logger.error("", e); | |
| 106 | + } | |
| 107 | + return this; | |
| 108 | + } | |
| 109 | + | |
| 110 | + /** | |
| 111 | + * @Title: calcQdzTimePlan | |
| 112 | + * @Description: TODO(计算班次的起点应到时间) | |
| 113 | + */ | |
| 114 | + public void calcQdzTimePlan(List<ScheduleRealInfo> list) { | |
| 115 | + Collections.sort(list, new ScheduleComparator.FCSJ()); | |
| 116 | + | |
| 117 | + int len = list.size(); | |
| 118 | + if (len == 0) | |
| 119 | + return; | |
| 120 | + | |
| 121 | + ScheduleRealInfo prve = list.get(0), curr; | |
| 122 | + for (int i = 1; i < len; i++) { | |
| 123 | + curr = list.get(i); | |
| 124 | + | |
| 125 | + if (isJoin(prve, curr)) { | |
| 126 | + curr.setQdzArrDatejh(prve.getZdsj()); | |
| 127 | + if (StringUtils.isNotEmpty(prve.getZdsjActual())) | |
| 128 | + curr.setQdzArrDatesj(prve.getZdsjActual()); | |
| 129 | + } | |
| 130 | + prve = curr; | |
| 131 | + } | |
| 132 | + } | |
| 133 | + | |
| 134 | + private boolean isJoin(ScheduleRealInfo prve, ScheduleRealInfo curr) { | |
| 135 | + return prve.getZdzName().equals(curr.getQdzName())//名称相等 | |
| 136 | + || prve.getZdzCode().equals(curr.getQdzCode())//编码相等 | |
| 137 | + || prve.getZdzName().startsWith(curr.getQdzName())//起始包括 | |
| 138 | + || curr.getQdzName().startsWith(prve.getZdzName());//起始包括 | |
| 139 | + } | |
| 140 | + | |
| 141 | + /** | |
| 142 | + * @Title: updateQdzTimePlan | |
| 143 | + * @Description: TODO(更新班次的起点应到时间) 并返回被更新的班次 | |
| 144 | + */ | |
| 145 | + public List<ScheduleRealInfo> updateQdzTimePlan(List<ScheduleRealInfo> list) { | |
| 146 | + Collections.sort(list, new ScheduleComparator.FCSJ()); | |
| 147 | + | |
| 148 | + List<ScheduleRealInfo> updateList = new ArrayList<>(); | |
| 149 | + int len = list.size(); | |
| 150 | + if (len == 0) | |
| 151 | + return updateList; | |
| 152 | + | |
| 153 | + ScheduleRealInfo prve = list.get(0), curr; | |
| 154 | + for (int i = 1; i < len; i++) { | |
| 155 | + curr = list.get(i); | |
| 156 | + | |
| 157 | + if (prve.getZdzName().equals(curr.getQdzName()) | |
| 158 | + || prve.getZdzCode().equals(curr.getQdzCode())) { | |
| 159 | + | |
| 160 | + if (curr.getQdzArrDatejh() != null && prve.getZdsj().equals(curr.getQdzArrDatejh())) { | |
| 161 | + prve = curr; | |
| 162 | + continue; | |
| 163 | + } | |
| 164 | + | |
| 165 | + curr.setQdzArrDatejh(prve.getZdsj()); | |
| 166 | + updateList.add(curr); | |
| 167 | + } else { | |
| 168 | + curr.setQdzArrDatejh(null); | |
| 169 | + updateList.add(curr); | |
| 170 | + } | |
| 171 | + prve = curr; | |
| 172 | + } | |
| 173 | + | |
| 174 | + return updateList; | |
| 175 | + } | |
| 176 | + | |
| 177 | + public SchAttrCalculator calcFcsjTime(ScheduleRealInfo sch) throws ParseException { | |
| 178 | + sch.setFcsjT(fmtyyyyMMddHHmm.parseMillis(sch.getRealExecDate() + sch.getFcsj())); | |
| 179 | + return this; | |
| 180 | + } | |
| 181 | + | |
| 182 | + public void calcTimestamp(ScheduleRealInfo sch) throws ParseException { | |
| 183 | + //计发时间 | |
| 184 | + if (sch.getFcsjT() == null) | |
| 185 | + calcFcsjTime(sch); | |
| 186 | + | |
| 187 | + //待发时间 | |
| 188 | + if (sch.getDfsj() == null) | |
| 189 | + sch.setDfsjAll(sch.getFcsjT()); | |
| 190 | + if (sch.getDfsjT() == null) | |
| 191 | + sch.setDfsjAll(sch.getDfsj()); | |
| 192 | + | |
| 193 | + //实发时间戳 | |
| 194 | + if (sch.getFcsjActualTime() == null && sch.getFcsjActual() != null) | |
| 195 | + sch.setFcsjActualAll(sch.getFcsjActual()); | |
| 196 | + | |
| 197 | + //实达时间戳 | |
| 198 | + if (sch.getZdsjActualTime() == null && sch.getZdsjActual() != null) | |
| 199 | + sch.setZdsjActualAll(sch.getZdsjActual()); | |
| 200 | + } | |
| 201 | + | |
| 202 | + /** | |
| 203 | + * 计算当前要执行的班次 | |
| 204 | + * | |
| 205 | + * @param list | |
| 206 | + * @return | |
| 207 | + */ | |
| 208 | + public ScheduleRealInfo calcCurrentExecSch(List<ScheduleRealInfo> list) { | |
| 209 | + if(list.size()==0) | |
| 210 | + return null; | |
| 211 | + String lineCode = list.get(0).getXlBm(); | |
| 212 | + LineConfig conf = lineConfigData.get(lineCode); | |
| 213 | + | |
| 214 | + int outConfig = -1; | |
| 215 | + //限定出站既出场的停车场 | |
| 216 | + List<String> parks = null; | |
| 217 | + if (conf != null) { | |
| 218 | + outConfig = conf.getOutConfig(); | |
| 219 | + parks = conf.findTwinsParkList(); | |
| 220 | + } | |
| 221 | + boolean limitPark = null != parks && parks.size() > 0; | |
| 222 | + | |
| 223 | + ScheduleRealInfo sch, prev = null; | |
| 224 | + for(int i = list.size() - 1; i >= 0; i --){ | |
| 225 | + sch = list.get(i); | |
| 226 | + | |
| 227 | + //如果是出站既出场,忽略出场班次 | |
| 228 | + if (outConfig == 2 && sch.getBcType().equals("out") | |
| 229 | + && (!limitPark || parks.contains(sch.getQdzCode())) | |
| 230 | + && (sch.getBcsj()==0 || sch.getJhlcOrig().intValue()==0)) | |
| 231 | + continue; | |
| 232 | + | |
| 233 | + //忽略烂班 | |
| 234 | + if (sch.isDestroy()) | |
| 235 | + continue; | |
| 236 | + | |
| 237 | + if (StringUtils.isNotEmpty(sch.getZdsjActual()) || sch.getStatus() == 2) | |
| 238 | + break; | |
| 239 | + | |
| 240 | + prev = sch; | |
| 241 | + } | |
| 242 | + return prev; | |
| 243 | + } | |
| 244 | +} | ... | ... |
src/main/java/com/bsth/data/schedule/auto_exec/AfterServiceScheduler.java
0 → 100644
| 1 | +package com.bsth.data.schedule.auto_exec; | |
| 2 | + | |
| 3 | +import com.bsth.data.BasicData; | |
| 4 | +import com.bsth.data.LineConfigData; | |
| 5 | +import com.bsth.data.gpsdata_v2.cache.GeoCacheData; | |
| 6 | +import com.bsth.data.gpsdata_v2.entity.StationRoute; | |
| 7 | +import com.bsth.data.gpsdata_v2.utils.GeoUtils; | |
| 8 | +import com.bsth.data.schedule.DayOfSchedule; | |
| 9 | +import com.bsth.entity.realcontrol.LineConfig; | |
| 10 | +import com.bsth.entity.realcontrol.ScheduleRealInfo; | |
| 11 | +import com.bsth.util.Geo.Point; | |
| 12 | +import com.google.common.collect.ArrayListMultimap; | |
| 13 | +import com.google.common.collect.BiMap; | |
| 14 | +import com.google.common.collect.Multimap; | |
| 15 | +import org.joda.time.DateTime; | |
| 16 | +import org.joda.time.format.DateTimeFormat; | |
| 17 | +import org.joda.time.format.DateTimeFormatter; | |
| 18 | +import org.slf4j.Logger; | |
| 19 | +import org.slf4j.LoggerFactory; | |
| 20 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 21 | +import org.springframework.beans.factory.annotation.Qualifier; | |
| 22 | +import org.springframework.jdbc.core.BeanPropertyRowMapper; | |
| 23 | +import org.springframework.jdbc.core.JdbcTemplate; | |
| 24 | +import org.springframework.scheduling.annotation.EnableScheduling; | |
| 25 | +import org.springframework.scheduling.annotation.Scheduled; | |
| 26 | +import org.springframework.stereotype.Component; | |
| 27 | + | |
| 28 | +import java.util.*; | |
| 29 | + | |
| 30 | +@Component | |
| 31 | +@EnableScheduling | |
| 32 | +public class AfterServiceScheduler { | |
| 33 | + | |
| 34 | + private final static Logger log = LoggerFactory.getLogger(AfterServiceScheduler.class); | |
| 35 | + | |
| 36 | + @Autowired | |
| 37 | + private LineConfigData lineConfigData; | |
| 38 | + | |
| 39 | + @Autowired | |
| 40 | + private DayOfSchedule dayOfSchedule; | |
| 41 | + | |
| 42 | + @Autowired | |
| 43 | + @Qualifier("msJdbcTemplate") | |
| 44 | + private JdbcTemplate msJdbcTemplate; | |
| 45 | + | |
| 46 | + private Map<String, String> complete = new HashMap<>(); | |
| 47 | + | |
| 48 | + private DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd"); | |
| 49 | + | |
| 50 | + private final static int MAX_DIFF = 3600000; | |
| 51 | + | |
| 52 | + /** | |
| 53 | + * 自动执行的线路,营运结束后未正常完成的班次重新匹配最近发车时间和到达时间 | |
| 54 | + */ | |
| 55 | + @Scheduled(cron = "0 15/30 * * * ?") | |
| 56 | + public void compute() { | |
| 57 | + log.warn("自动执行线路营运后计算开始"); | |
| 58 | + Collection<LineConfig> lineConfigs = lineConfigData.getAll(); | |
| 59 | + if (lineConfigs == null || lineConfigs.isEmpty()) { | |
| 60 | + return; | |
| 61 | + } | |
| 62 | + for (LineConfig lineConfig : lineConfigs) { | |
| 63 | + if (lineConfig.isAutoExec() && lineConfig.getAutoExecOffset() > 0) { | |
| 64 | + String lineCode = lineConfig.getLine().getLineCode(); | |
| 65 | + String schDate = dayOfSchedule.getCurrSchDate().get(lineCode); | |
| 66 | + if (schDate == null) { | |
| 67 | + continue; | |
| 68 | + } | |
| 69 | + DateTime dateTime = formatter.parseDateTime(schDate); | |
| 70 | + if (!schDate.equals(complete.get(lineCode))) { | |
| 71 | + List<ScheduleRealInfo> schedules = dayOfSchedule.findByLineCode(lineCode); | |
| 72 | + Multimap<String, ScheduleRealInfo> multimap = ArrayListMultimap.create(); | |
| 73 | + long lastTime = 0; | |
| 74 | + for (ScheduleRealInfo schedule : schedules) { | |
| 75 | + multimap.put(schedule.getClZbh(), schedule); | |
| 76 | + if (lastTime < schedule.getZdsjT()) { | |
| 77 | + lastTime = schedule.getZdsjT(); | |
| 78 | + } | |
| 79 | + } | |
| 80 | + // 末班过后一个小时 | |
| 81 | + if (lastTime + MAX_DIFF < System.currentTimeMillis()) { | |
| 82 | + BiMap<String, String> inside2device = BasicData.deviceId2NbbmMap.inverse(); | |
| 83 | + for (String key : multimap.keySet()) { | |
| 84 | + String deviceId = inside2device.get(key); | |
| 85 | + Collection<ScheduleRealInfo> infos = multimap.get(key); | |
| 86 | + List<ScheduleRealInfo> list = new ArrayList<>(infos); | |
| 87 | + List<GpsInfo> gpsInfos = msJdbcTemplate.query("SELECT device_id,line_id,lon,lat,service_state,ts FROM bsth_c_gps_info_" + dateTime.getYear() + " WHERE days_year = ? AND device_id = ? AND service_state & 0x80000000 = 0 ORDER BY ts", new Object[]{dateTime.getDayOfYear(), deviceId}, BeanPropertyRowMapper.newInstance(GpsInfo.class)); | |
| 88 | + for (ScheduleRealInfo schedule : list) { | |
| 89 | + if (schedule.getFcsjActual() == null || schedule.getZdsjActual() == null) { | |
| 90 | + matchTime(schedule, gpsInfos); | |
| 91 | + dayOfSchedule.save(schedule); | |
| 92 | + } | |
| 93 | + } | |
| 94 | + } | |
| 95 | + complete.put(lineCode, schDate); | |
| 96 | + } | |
| 97 | + } | |
| 98 | + } | |
| 99 | + } | |
| 100 | + } | |
| 101 | + | |
| 102 | + private void matchTime(ScheduleRealInfo schedule, List<GpsInfo> gpsInfos) { | |
| 103 | + List<StationRoute> srs = GeoCacheData.getStationRoute(schedule.getXlBm(), Integer.parseInt(schedule.getXlDir())); | |
| 104 | + String qdz = schedule.getQdzCode(), zdz = schedule.getZdzCode(); | |
| 105 | + StationRoute qdzRoute = null, zdzRoute = null; | |
| 106 | + for (StationRoute route : srs) { | |
| 107 | + if (schedule.getFcsjActual() == null && qdz.equals(route.getCode())) { | |
| 108 | + qdzRoute = route; | |
| 109 | + } | |
| 110 | + if (schedule.getZdsjActual() == null && zdz.equals(route.getCode())) { | |
| 111 | + zdzRoute = route; | |
| 112 | + break; | |
| 113 | + } | |
| 114 | + } | |
| 115 | + int qdzIdx = -1, qdzIdx2 = -1, count = 0; | |
| 116 | + for (GpsInfo gpsInfo : gpsInfos) { | |
| 117 | + if (qdzRoute != null && gpsInfo.getTs() < schedule.getFcsjT() && GeoUtils.isGpsInSpecialStation(qdzRoute, new Point(gpsInfo.getLon(), gpsInfo.getLat()))) { | |
| 118 | + qdzIdx = count; | |
| 119 | + } | |
| 120 | + if (qdzIdx2 == -1 && qdzRoute != null && gpsInfo.getTs() > schedule.getFcsjT() && GeoUtils.isGpsInSpecialStation(qdzRoute, new Point(gpsInfo.getLon(), gpsInfo.getLat()))) { | |
| 121 | + qdzIdx2 = count; | |
| 122 | + } | |
| 123 | + if (zdzRoute != null && gpsInfo.getTs() > schedule.getFcsjT() && GeoUtils.isGpsInSpecialStation(zdzRoute, new Point(gpsInfo.getLon(), gpsInfo.getLat()))) { | |
| 124 | + schedule.setZdsjActual(new DateTime(gpsInfo.getTs()).toString("HH:mm")); | |
| 125 | + schedule.setZdsjActualTime(gpsInfo.getTs()); | |
| 126 | + break; | |
| 127 | + } | |
| 128 | + count++; | |
| 129 | + } | |
| 130 | + if (qdzIdx > -1 && qdzIdx2 > -1) { | |
| 131 | + GpsInfo gpsInfo1 = gpsInfos.get(qdzIdx), gpsInfo2 = gpsInfos.get(qdzIdx2); | |
| 132 | + if (Math.abs(schedule.getFcsjT() - gpsInfo1.getTs()) >= Math.abs(schedule.getFcsjT() - gpsInfo2.getTs()) && qdzIdx2 < gpsInfos.size() - 1) { | |
| 133 | + qdzIdx = qdzIdx2; | |
| 134 | + } | |
| 135 | + } else if (qdzIdx2 > -1) { | |
| 136 | + qdzIdx = qdzIdx2; | |
| 137 | + } | |
| 138 | + if (qdzIdx > -1 && qdzIdx < gpsInfos.size() - 1) { | |
| 139 | + for (int i = qdzIdx + 1;i < gpsInfos.size(); i++) { | |
| 140 | + GpsInfo gpsInfo = gpsInfos.get(i); | |
| 141 | + if (!GeoUtils.isGpsInSpecialStation(qdzRoute, new Point(gpsInfo.getLon(), gpsInfo.getLat()))) { | |
| 142 | + schedule.setFcsjActual(new DateTime(gpsInfo.getTs()).toString("HH:mm")); | |
| 143 | + schedule.setFcsjActualTime(gpsInfo.getTs()); | |
| 144 | + break; | |
| 145 | + } | |
| 146 | + } | |
| 147 | + } | |
| 148 | + } | |
| 149 | + | |
| 150 | + public static class GpsInfo { | |
| 151 | + | |
| 152 | + private String deviceId; | |
| 153 | + | |
| 154 | + private int lineId; | |
| 155 | + | |
| 156 | + private float lon; | |
| 157 | + | |
| 158 | + private float lat; | |
| 159 | + | |
| 160 | + private long serviceState; | |
| 161 | + | |
| 162 | + private long ts; | |
| 163 | + | |
| 164 | + public GpsInfo() { | |
| 165 | + | |
| 166 | + } | |
| 167 | + | |
| 168 | + public String getDeviceId() { | |
| 169 | + return deviceId; | |
| 170 | + } | |
| 171 | + | |
| 172 | + public void setDeviceId(String deviceId) { | |
| 173 | + this.deviceId = deviceId; | |
| 174 | + } | |
| 175 | + | |
| 176 | + public int getLineId() { | |
| 177 | + return lineId; | |
| 178 | + } | |
| 179 | + | |
| 180 | + public void setLineId(int lineId) { | |
| 181 | + this.lineId = lineId; | |
| 182 | + } | |
| 183 | + | |
| 184 | + public float getLon() { | |
| 185 | + return lon; | |
| 186 | + } | |
| 187 | + | |
| 188 | + public void setLon(float lon) { | |
| 189 | + this.lon = lon; | |
| 190 | + } | |
| 191 | + | |
| 192 | + public float getLat() { | |
| 193 | + return lat; | |
| 194 | + } | |
| 195 | + | |
| 196 | + public void setLat(float lat) { | |
| 197 | + this.lat = lat; | |
| 198 | + } | |
| 199 | + | |
| 200 | + public long getServiceState() { | |
| 201 | + return serviceState; | |
| 202 | + } | |
| 203 | + | |
| 204 | + public void setServiceState(long serviceState) { | |
| 205 | + this.serviceState = serviceState; | |
| 206 | + } | |
| 207 | + | |
| 208 | + public long getTs() { | |
| 209 | + return ts; | |
| 210 | + } | |
| 211 | + | |
| 212 | + public void setTs(long ts) { | |
| 213 | + this.ts = ts; | |
| 214 | + } | |
| 215 | + } | |
| 216 | +} | ... | ... |
src/main/java/com/bsth/data/schedule/auto_exec/AutoExecScanThread.java
| ... | ... | @@ -9,9 +9,7 @@ import org.slf4j.LoggerFactory; |
| 9 | 9 | import org.springframework.beans.factory.annotation.Autowired; |
| 10 | 10 | import org.springframework.stereotype.Component; |
| 11 | 11 | |
| 12 | -import java.util.ArrayList; | |
| 13 | -import java.util.Collection; | |
| 14 | -import java.util.List; | |
| 12 | +import java.util.*; | |
| 15 | 13 | |
| 16 | 14 | /** |
| 17 | 15 | * 班次自动执行扫描线程 |
| ... | ... | @@ -39,9 +37,11 @@ public class AutoExecScanThread extends Thread{ |
| 39 | 37 | //要自动执行的线路 |
| 40 | 38 | List<String> autos = new ArrayList<>(); |
| 41 | 39 | Collection<LineConfig> lcs = lineConfigData.getAll(); |
| 40 | + Map<String, LineConfig> line2config = new HashMap<>(); | |
| 42 | 41 | |
| 43 | 42 | for(LineConfig config : lcs){ |
| 44 | 43 | if(config.isAutoExec()){ |
| 44 | + line2config.put(config.getLine().getLineCode(), config); | |
| 45 | 45 | autos.add(config.getLine().getLineCode()); |
| 46 | 46 | } |
| 47 | 47 | } |
| ... | ... | @@ -51,7 +51,14 @@ public class AutoExecScanThread extends Thread{ |
| 51 | 51 | List<ScheduleRealInfo> all = new ArrayList<>(dayOfSchedule.findAll()); |
| 52 | 52 | for(ScheduleRealInfo sch : all){ |
| 53 | 53 | if(autos.contains(sch.getXlBm())){ |
| 54 | - realScheduleAutoExecHandler.exec(sch); | |
| 54 | + LineConfig config = line2config.get(sch.getXlBm()); | |
| 55 | + if (config != null) { | |
| 56 | + if (config.getAutoExecOffset() == 0) { | |
| 57 | + realScheduleAutoExecHandler.exec(sch); | |
| 58 | + } else if (config.getAutoExecOffset() > 0) { | |
| 59 | + realScheduleAutoExecHandler.exec1(sch, config); | |
| 60 | + } | |
| 61 | + } | |
| 55 | 62 | } |
| 56 | 63 | } |
| 57 | 64 | }catch (Exception e){ | ... | ... |
src/main/java/com/bsth/data/schedule/auto_exec/RealScheduleAutoExecHandler.java
| 1 | -package com.bsth.data.schedule.auto_exec; | |
| 2 | - | |
| 3 | -import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager; | |
| 4 | -import com.bsth.data.schedule.DayOfSchedule; | |
| 5 | -import com.bsth.entity.realcontrol.ScheduleRealInfo; | |
| 6 | -import com.bsth.websocket.handler.SendUtils; | |
| 7 | -import org.apache.commons.lang3.StringUtils; | |
| 8 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 9 | -import org.springframework.stereotype.Component; | |
| 10 | - | |
| 11 | -import java.util.ArrayList; | |
| 12 | -import java.util.List; | |
| 13 | - | |
| 14 | -/** | |
| 15 | - * 实际班次自动执行 | |
| 16 | - * Created by panzhao on 2017/10/31. | |
| 17 | - */ | |
| 18 | -@Component | |
| 19 | -public class RealScheduleAutoExecHandler { | |
| 20 | - | |
| 21 | - @Autowired | |
| 22 | - SendUtils sendUtils; | |
| 23 | - @Autowired | |
| 24 | - DayOfSchedule dayOfSchedule; | |
| 25 | - | |
| 26 | - @Autowired | |
| 27 | - GpsStatusManager gpsStatusManager; | |
| 28 | - | |
| 29 | - public void exec(ScheduleRealInfo sch) { | |
| 30 | - boolean flag = false; | |
| 31 | - long t = System.currentTimeMillis(); | |
| 32 | - | |
| 33 | - if (StringUtils.isEmpty(sch.getFcsjActual()) && sch.getDfsjT() < t) { | |
| 34 | - sch.setFcsjActualAll(sch.getDfsjT()); | |
| 35 | - flag = true; | |
| 36 | - } | |
| 37 | - | |
| 38 | - if (StringUtils.isEmpty(sch.getZdsjActual()) && sch.getZdsjT() < t) { | |
| 39 | - sch.setZdsjActualAll(sch.getZdsjT()); | |
| 40 | - flag = true; | |
| 41 | - | |
| 42 | - //准备执行下一个班次 | |
| 43 | - ScheduleRealInfo next = dayOfSchedule.next(sch); | |
| 44 | - if (next != null) { | |
| 45 | - dayOfSchedule.addExecPlan(next); | |
| 46 | - //套跑 -下发线路切换指令 | |
| 47 | - if(!next.getXlBm().equals(sch.getXlBm())){ | |
| 48 | - gpsStatusManager.changeLine(next.getClZbh(), next.getXlBm(), "auto@系统"); | |
| 49 | - } | |
| 50 | - } | |
| 51 | - | |
| 52 | - //路牌有下一个班次,线调页面显示 | |
| 53 | - ScheduleRealInfo nextLp = dayOfSchedule.nextByLp(sch); | |
| 54 | - if (null != nextLp) { | |
| 55 | - //入库 | |
| 56 | - dayOfSchedule.save(sch); | |
| 57 | - | |
| 58 | - nextLp.setQdzArrDatesj(sch.getZdsjActual()); | |
| 59 | - List<ScheduleRealInfo> refs = new ArrayList<>(); | |
| 60 | - refs.add(sch); | |
| 61 | - refs.add(nextLp); | |
| 62 | - sendUtils.refreshSch(refs); | |
| 63 | - return; | |
| 64 | - } | |
| 65 | - } | |
| 66 | - | |
| 67 | - if (flag) { | |
| 68 | - dayOfSchedule.save(sch); | |
| 69 | - sendUtils.refreshSch(sch); | |
| 70 | - } | |
| 71 | - } | |
| 72 | -} | |
| 1 | +package com.bsth.data.schedule.auto_exec; | |
| 2 | + | |
| 3 | +import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager; | |
| 4 | +import com.bsth.data.msg_queue.DirectivePushQueue; | |
| 5 | +import com.bsth.data.schedule.DayOfSchedule; | |
| 6 | +import com.bsth.entity.realcontrol.LineConfig; | |
| 7 | +import com.bsth.entity.realcontrol.ScheduleRealInfo; | |
| 8 | +import com.bsth.websocket.handler.SendUtils; | |
| 9 | +import org.apache.commons.lang3.StringUtils; | |
| 10 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 11 | +import org.springframework.stereotype.Component; | |
| 12 | + | |
| 13 | +import java.util.ArrayList; | |
| 14 | +import java.util.List; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * 实际班次自动执行 | |
| 18 | + * Created by panzhao on 2017/10/31. | |
| 19 | + */ | |
| 20 | +@Component | |
| 21 | +public class RealScheduleAutoExecHandler { | |
| 22 | + | |
| 23 | + @Autowired | |
| 24 | + SendUtils sendUtils; | |
| 25 | + @Autowired | |
| 26 | + DayOfSchedule dayOfSchedule; | |
| 27 | + | |
| 28 | + @Autowired | |
| 29 | + GpsStatusManager gpsStatusManager; | |
| 30 | + | |
| 31 | + /** | |
| 32 | + * 自动执行偏差为0的处理 | |
| 33 | + * @param sch | |
| 34 | + */ | |
| 35 | + public void exec(ScheduleRealInfo sch) { | |
| 36 | + boolean flag = false; | |
| 37 | + long t = System.currentTimeMillis(); | |
| 38 | + | |
| 39 | + if (StringUtils.isEmpty(sch.getFcsjActual()) && sch.getDfsjT() < t) { | |
| 40 | + sch.setFcsjActualAll(sch.getDfsjT()); | |
| 41 | + flag = true; | |
| 42 | + } | |
| 43 | + | |
| 44 | + if (StringUtils.isEmpty(sch.getZdsjActual()) && sch.getZdsjT() < t) { | |
| 45 | + sch.setZdsjActualAll(sch.getZdsjT()); | |
| 46 | + flag = true; | |
| 47 | + | |
| 48 | + //准备执行下一个班次 | |
| 49 | + ScheduleRealInfo next = dayOfSchedule.next(sch); | |
| 50 | + if (next != null) { | |
| 51 | + dayOfSchedule.addExecPlan(next); | |
| 52 | + //套跑 -下发线路切换指令 | |
| 53 | + if(!next.getXlBm().equals(sch.getXlBm())){ | |
| 54 | + gpsStatusManager.changeLine(next.getClZbh(), next.getXlBm(), "auto@系统"); | |
| 55 | + } | |
| 56 | + //已完成班次数 | |
| 57 | + int doneSum = dayOfSchedule.doneSum(sch.getClZbh()); | |
| 58 | + //下发调度指令 | |
| 59 | + DirectivePushQueue.put6002(next, doneSum, "到站@系统", ""); | |
| 60 | + } | |
| 61 | + | |
| 62 | + //路牌有下一个班次,线调页面显示 | |
| 63 | + ScheduleRealInfo nextLp = dayOfSchedule.nextByLp(sch); | |
| 64 | + if (null != nextLp) { | |
| 65 | + //入库 | |
| 66 | + dayOfSchedule.save(sch); | |
| 67 | + | |
| 68 | + nextLp.setQdzArrDatesj(sch.getZdsjActual()); | |
| 69 | + List<ScheduleRealInfo> refs = new ArrayList<>(); | |
| 70 | + refs.add(sch); | |
| 71 | + refs.add(nextLp); | |
| 72 | + sendUtils.refreshSch(refs); | |
| 73 | + return; | |
| 74 | + } | |
| 75 | + } | |
| 76 | + | |
| 77 | + if (flag) { | |
| 78 | + dayOfSchedule.save(sch); | |
| 79 | + sendUtils.refreshSch(sch); | |
| 80 | + } | |
| 81 | + } | |
| 82 | + | |
| 83 | + /** | |
| 84 | + * 自动执行偏差不为0的处理 | |
| 85 | + * @param sch | |
| 86 | + */ | |
| 87 | + public void exec1(ScheduleRealInfo sch, LineConfig lineConfig) { | |
| 88 | + long now = System.currentTimeMillis(); | |
| 89 | + if (sch.getStatus() == 2 || sch.getStatus() == -1) { | |
| 90 | + return; | |
| 91 | + } | |
| 92 | + // 如果超过了最大自动执行偏移时间 执行下一个班次 | |
| 93 | + if (now > sch.getZdsjT() + lineConfig.getAutoExecOffset() * 60000) { | |
| 94 | + //标记班次为完成 | |
| 95 | + sch.setStatus(2); | |
| 96 | + //准备执行下一个班次 | |
| 97 | + ScheduleRealInfo next = dayOfSchedule.next(sch); | |
| 98 | + if (next != null) { | |
| 99 | + dayOfSchedule.addExecPlan(next); | |
| 100 | + //套跑 -下发线路切换指令 | |
| 101 | + if(!next.getXlBm().equals(sch.getXlBm())){ | |
| 102 | + gpsStatusManager.changeLine(next.getClZbh(), next.getXlBm(), "auto@系统"); | |
| 103 | + } | |
| 104 | + //已完成班次数 | |
| 105 | + int doneSum = dayOfSchedule.doneSum(sch.getClZbh()); | |
| 106 | + //下发调度指令 | |
| 107 | + DirectivePushQueue.put6002(next, doneSum, "到站@系统", ""); | |
| 108 | + } else { | |
| 109 | + dayOfSchedule.removeExecPlan(sch.getClZbh()); | |
| 110 | + } | |
| 111 | + | |
| 112 | + //路牌有下一个班次,线调页面显示 | |
| 113 | + ScheduleRealInfo nextLp = dayOfSchedule.nextByLp(sch); | |
| 114 | + if (null != nextLp) { | |
| 115 | + //入库 | |
| 116 | + dayOfSchedule.save(sch); | |
| 117 | + | |
| 118 | + nextLp.setQdzArrDatesj(sch.getZdsjActual()); | |
| 119 | + List<ScheduleRealInfo> refs = new ArrayList<>(); | |
| 120 | + refs.add(sch); | |
| 121 | + refs.add(nextLp); | |
| 122 | + sendUtils.refreshSch(refs); | |
| 123 | + } | |
| 124 | + } | |
| 125 | + } | |
| 126 | +} | ... | ... |
src/main/java/com/bsth/entity/realcontrol/LineConfig.java
| ... | ... | @@ -58,6 +58,11 @@ public class LineConfig { |
| 58 | 58 | private boolean autoExec; |
| 59 | 59 | |
| 60 | 60 | /** |
| 61 | + * 自动执行偏差值(分钟) | |
| 62 | + */ | |
| 63 | + private int autoExecOffset; | |
| 64 | + | |
| 65 | + /** | |
| 61 | 66 | * 到离站偏移值 |
| 62 | 67 | */ |
| 63 | 68 | |
| ... | ... | @@ -232,6 +237,14 @@ public class LineConfig { |
| 232 | 237 | this.autoExec = autoExec; |
| 233 | 238 | } |
| 234 | 239 | |
| 240 | + public int getAutoExecOffset() { | |
| 241 | + return autoExecOffset; | |
| 242 | + } | |
| 243 | + | |
| 244 | + public void setAutoExecOffset(int autoExecOffset) { | |
| 245 | + this.autoExecOffset = autoExecOffset; | |
| 246 | + } | |
| 247 | + | |
| 235 | 248 | public String getTwinsParks() { |
| 236 | 249 | return twinsParks; |
| 237 | 250 | } | ... | ... |
src/main/java/com/bsth/service/realcontrol/impl/LineConfigServiceImpl.java
| 1 | -package com.bsth.service.realcontrol.impl; | |
| 2 | - | |
| 3 | -import com.bsth.common.ResponseCode; | |
| 4 | -import com.bsth.data.LineConfigData; | |
| 5 | -import com.bsth.entity.realcontrol.LineConfig; | |
| 6 | -import com.bsth.repository.realcontrol.LineConfigRepository; | |
| 7 | -import com.bsth.service.impl.BaseServiceImpl; | |
| 8 | -import com.bsth.service.realcontrol.LineConfigService; | |
| 9 | -import com.google.common.base.Splitter; | |
| 10 | -import org.slf4j.Logger; | |
| 11 | -import org.slf4j.LoggerFactory; | |
| 12 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 13 | -import org.springframework.stereotype.Service; | |
| 14 | - | |
| 15 | -import java.lang.reflect.Field; | |
| 16 | -import java.util.ArrayList; | |
| 17 | -import java.util.HashMap; | |
| 18 | -import java.util.List; | |
| 19 | -import java.util.Map; | |
| 20 | - | |
| 21 | -@Service | |
| 22 | -public class LineConfigServiceImpl extends BaseServiceImpl<LineConfig, Integer> implements LineConfigService { | |
| 23 | - | |
| 24 | - @Autowired | |
| 25 | - LineConfigRepository lineConfigRepository; | |
| 26 | - | |
| 27 | - @Autowired | |
| 28 | - LineConfigData lineConfigData; | |
| 29 | - | |
| 30 | - Logger logger = LoggerFactory.getLogger(this.getClass()); | |
| 31 | - | |
| 32 | - @Override | |
| 33 | - public Map<String, Object> check(String[] codeArray) { | |
| 34 | - Map<String, Object> rs = new HashMap<>(); | |
| 35 | - List<String> notArr = new ArrayList<>(); | |
| 36 | - | |
| 37 | - for (String lineCode : codeArray) { | |
| 38 | - if (null == lineConfigData.get(lineCode + "")) | |
| 39 | - notArr.add(lineCode); | |
| 40 | - } | |
| 41 | - | |
| 42 | - if (notArr.size() > 0) { | |
| 43 | - rs.put("status", 1); | |
| 44 | - rs.put("not", notArr); | |
| 45 | - } else | |
| 46 | - rs.put("status", 0); | |
| 47 | - return rs; | |
| 48 | - } | |
| 49 | - | |
| 50 | - @Override | |
| 51 | - public Integer init(String lineCode) throws Exception { | |
| 52 | - LineConfig conf = lineConfigData.get(lineCode); | |
| 53 | - | |
| 54 | - if (conf == null) | |
| 55 | - lineConfigData.init(lineCode); | |
| 56 | - | |
| 57 | - return 1; | |
| 58 | - } | |
| 59 | - | |
| 60 | - @Override | |
| 61 | - public Map<String, Object> editStartOptTime(String time, String lineCode) { | |
| 62 | - Map<String, Object> rs = new HashMap<>(); | |
| 63 | - try { | |
| 64 | - LineConfig conf = lineConfigData.get(lineCode); | |
| 65 | - conf.setStartOpt(time); | |
| 66 | - lineConfigData.set(conf); | |
| 67 | - | |
| 68 | - rs.put("status", ResponseCode.SUCCESS); | |
| 69 | - rs.put("time", time); | |
| 70 | - } catch (Exception e) { | |
| 71 | - rs.put("status", ResponseCode.ERROR); | |
| 72 | - rs.put("msg", e.getMessage()); | |
| 73 | - logger.error("", e); | |
| 74 | - } | |
| 75 | - return rs; | |
| 76 | - } | |
| 77 | - | |
| 78 | - @Override | |
| 79 | - public Map<String, Object> editOutTimeType(String lineCode, int type, String parkCode, String stationCode) { | |
| 80 | - Map<String, Object> rs = new HashMap<>(); | |
| 81 | - try { | |
| 82 | - LineConfig conf = lineConfigData.get(lineCode); | |
| 83 | - | |
| 84 | - conf.setOutConfig(type); | |
| 85 | - if(type == 2){ | |
| 86 | - conf.setTwinsParks(parkCode); | |
| 87 | - conf.setTwinsStations(stationCode); | |
| 88 | - } | |
| 89 | - lineConfigData.set(conf); | |
| 90 | - | |
| 91 | - rs.put("status", ResponseCode.SUCCESS); | |
| 92 | - rs.put("conf", conf); | |
| 93 | - } catch (Exception e) { | |
| 94 | - rs.put("status", ResponseCode.ERROR); | |
| 95 | - rs.put("msg", e.getMessage()); | |
| 96 | - logger.error("", e); | |
| 97 | - } | |
| 98 | - return rs; | |
| 99 | - } | |
| 100 | - | |
| 101 | - @Override | |
| 102 | - public LineConfig getByLineCode(String lineCode) { | |
| 103 | - return lineConfigData.get(lineCode); | |
| 104 | - } | |
| 105 | - | |
| 106 | - @Override | |
| 107 | - public Map<String, Object> enableInParkForSource(String lineCode, int enable) { | |
| 108 | - Map<String, Object> rs = new HashMap<>(); | |
| 109 | - try { | |
| 110 | - LineConfig conf = lineConfigData.get(lineCode); | |
| 111 | - | |
| 112 | - conf.setInParkForSource(enable == 1); | |
| 113 | - lineConfigData.set(conf); | |
| 114 | - | |
| 115 | - rs.put("status", ResponseCode.SUCCESS); | |
| 116 | - rs.put("enable", enable); | |
| 117 | - } catch (Exception e) { | |
| 118 | - rs.put("status", ResponseCode.ERROR); | |
| 119 | - rs.put("msg", e.getMessage()); | |
| 120 | - logger.error("", e); | |
| 121 | - } | |
| 122 | - return rs; | |
| 123 | - } | |
| 124 | - | |
| 125 | - @Override | |
| 126 | - public Map<String, Object> bufferTimeDiff(String lineCode, String field, String value) { | |
| 127 | - | |
| 128 | - Map<String, Object> rs = new HashMap<>(); | |
| 129 | - try { | |
| 130 | - LineConfig conf = lineConfigData.get(lineCode); | |
| 131 | - Field f = conf.getClass().getDeclaredField(field); | |
| 132 | - f.setAccessible(true); | |
| 133 | - f.setInt(conf, Integer.parseInt(value)); | |
| 134 | - | |
| 135 | - lineConfigData.set(conf); | |
| 136 | - | |
| 137 | - rs.put("status", ResponseCode.SUCCESS); | |
| 138 | - rs.put("field", field); | |
| 139 | - rs.put("value", value); | |
| 140 | - } catch (Exception e) { | |
| 141 | - rs.put("status", ResponseCode.ERROR); | |
| 142 | - rs.put("msg", e.getMessage()); | |
| 143 | - logger.error("", e); | |
| 144 | - } | |
| 145 | - return rs; | |
| 146 | - } | |
| 147 | - | |
| 148 | - @Override | |
| 149 | - public Map<String, Object> yjtkSet(Map<String, String> map) { | |
| 150 | - String lineCode = map.get("lineCode").toString(); | |
| 151 | - int enableYjtk = Integer.parseInt(map.get("enableYjtk").toString()); | |
| 152 | - | |
| 153 | - Map<String, Object> rs = new HashMap<>(); | |
| 154 | - try { | |
| 155 | - LineConfig conf = lineConfigData.get(lineCode); | |
| 156 | - | |
| 157 | - if(enableYjtk == 1){ | |
| 158 | - String yjtkStart = map.containsKey("yjtkStart") ? map.get("yjtkStart").toString() : "00:00"; | |
| 159 | - String yjtkEnd = map.containsKey("yjtkEnd") ? map.get("yjtkEnd").toString() : "23:59"; | |
| 160 | - int upStopMinute = Integer.parseInt(map.get("upStopMinute").toString()); | |
| 161 | - int downStopMinute = Integer.parseInt(map.get("downStopMinute").toString()); | |
| 162 | - | |
| 163 | - conf.setEnableYjtk(true); | |
| 164 | - conf.setYjtkStart(yjtkStart); | |
| 165 | - conf.setYjtkEnd(yjtkEnd); | |
| 166 | - conf.setUpStopMinute(upStopMinute); | |
| 167 | - conf.setDownStopMinute(downStopMinute); | |
| 168 | - } | |
| 169 | - else | |
| 170 | - conf.setEnableYjtk(false); | |
| 171 | - | |
| 172 | - lineConfigData.set(conf); | |
| 173 | - | |
| 174 | - rs.put("status", ResponseCode.SUCCESS); | |
| 175 | - rs.put("conf", conf); | |
| 176 | - } catch (Exception e) { | |
| 177 | - rs.put("status", ResponseCode.ERROR); | |
| 178 | - rs.put("msg", e.getMessage()); | |
| 179 | - logger.error("", e); | |
| 180 | - } | |
| 181 | - return rs; | |
| 182 | - } | |
| 183 | - | |
| 184 | - @Override | |
| 185 | - public Map<String, Object> parkAndStationSet(Map<String, String> map) { | |
| 186 | - String lineCode = map.get("lineCode").toString(); | |
| 187 | - String twinsPark = map.get("twinsPark").toString(); | |
| 188 | - String twinsStation = map.get("twinsStation").toString(); | |
| 189 | - | |
| 190 | - Map<String, Object> rs = new HashMap<>(); | |
| 191 | - try { | |
| 192 | - LineConfig conf = lineConfigData.get(lineCode); | |
| 193 | - conf.setTwinsParks(twinsPark); | |
| 194 | - conf.setTwinsStations(twinsStation); | |
| 195 | - | |
| 196 | - lineConfigData.set(conf); | |
| 197 | - | |
| 198 | - rs.put("status", ResponseCode.SUCCESS); | |
| 199 | - rs.put("conf", conf); | |
| 200 | - } catch (Exception e) { | |
| 201 | - rs.put("status", ResponseCode.ERROR); | |
| 202 | - rs.put("msg", e.getMessage()); | |
| 203 | - logger.error("", e); | |
| 204 | - } | |
| 205 | - return rs; | |
| 206 | - } | |
| 207 | - | |
| 208 | - @Override | |
| 209 | - public Map<String, Object> findByIdx(String idx) { | |
| 210 | - Map<String, Object> rs = new HashMap(); | |
| 211 | - try{ | |
| 212 | - List<LineConfig> list = new ArrayList<>(); | |
| 213 | - List<String> ids = Splitter.on(",").splitToList(idx); | |
| 214 | - | |
| 215 | - for(String id : ids){ | |
| 216 | - list.add(lineConfigData.get(id)); | |
| 217 | - } | |
| 218 | - | |
| 219 | - rs.put("status", ResponseCode.SUCCESS); | |
| 220 | - rs.put("list", list); | |
| 221 | - }catch (Exception e){ | |
| 222 | - rs.put("status", ResponseCode.ERROR); | |
| 223 | - logger.error("", e); | |
| 224 | - } | |
| 225 | - return rs; | |
| 226 | - } | |
| 227 | - | |
| 228 | - @Override | |
| 229 | - public Map<String, Object> setAutoExec(Map<String, String> map) { | |
| 230 | - String lineCode = map.get("lineCode").toString(); | |
| 231 | - boolean autoExec = Boolean.parseBoolean(map.get("autoExec").toString()); | |
| 232 | - | |
| 233 | - Map<String, Object> rs = new HashMap<>(); | |
| 234 | - try { | |
| 235 | - LineConfig conf = lineConfigData.get(lineCode); | |
| 236 | - conf.setAutoExec(autoExec); | |
| 237 | - | |
| 238 | - lineConfigData.set(conf); | |
| 239 | - rs.put("status", ResponseCode.SUCCESS); | |
| 240 | - rs.put("conf", conf); | |
| 241 | - } catch (Exception e) { | |
| 242 | - rs.put("status", ResponseCode.ERROR); | |
| 243 | - rs.put("msg", e.getMessage()); | |
| 244 | - logger.error("", e); | |
| 245 | - } | |
| 246 | - return rs; | |
| 247 | - } | |
| 248 | - | |
| 249 | - @Override | |
| 250 | - public Map<String, Object> setReadReverse(int status, String lineCode) { | |
| 251 | - Map<String, Object> rs = new HashMap<>(); | |
| 252 | - try { | |
| 253 | - LineConfig conf = lineConfigData.get(lineCode); | |
| 254 | - conf.setReadReverse(status==1?true:false); | |
| 255 | - | |
| 256 | - lineConfigData.set(conf); | |
| 257 | - rs.put("status", ResponseCode.SUCCESS); | |
| 258 | - rs.put("conf", conf); | |
| 259 | - } catch (Exception e) { | |
| 260 | - rs.put("status", ResponseCode.ERROR); | |
| 261 | - rs.put("msg", e.getMessage()); | |
| 262 | - logger.error("", e); | |
| 263 | - } | |
| 264 | - return rs; | |
| 265 | - } | |
| 266 | -} | |
| 1 | +package com.bsth.service.realcontrol.impl; | |
| 2 | + | |
| 3 | +import com.bsth.common.ResponseCode; | |
| 4 | +import com.bsth.data.LineConfigData; | |
| 5 | +import com.bsth.entity.realcontrol.LineConfig; | |
| 6 | +import com.bsth.repository.realcontrol.LineConfigRepository; | |
| 7 | +import com.bsth.service.impl.BaseServiceImpl; | |
| 8 | +import com.bsth.service.realcontrol.LineConfigService; | |
| 9 | +import com.google.common.base.Splitter; | |
| 10 | +import org.slf4j.Logger; | |
| 11 | +import org.slf4j.LoggerFactory; | |
| 12 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 13 | +import org.springframework.stereotype.Service; | |
| 14 | + | |
| 15 | +import java.lang.reflect.Field; | |
| 16 | +import java.util.ArrayList; | |
| 17 | +import java.util.HashMap; | |
| 18 | +import java.util.List; | |
| 19 | +import java.util.Map; | |
| 20 | + | |
| 21 | +@Service | |
| 22 | +public class LineConfigServiceImpl extends BaseServiceImpl<LineConfig, Integer> implements LineConfigService { | |
| 23 | + | |
| 24 | + @Autowired | |
| 25 | + LineConfigRepository lineConfigRepository; | |
| 26 | + | |
| 27 | + @Autowired | |
| 28 | + LineConfigData lineConfigData; | |
| 29 | + | |
| 30 | + Logger logger = LoggerFactory.getLogger(this.getClass()); | |
| 31 | + | |
| 32 | + @Override | |
| 33 | + public Map<String, Object> check(String[] codeArray) { | |
| 34 | + Map<String, Object> rs = new HashMap<>(); | |
| 35 | + List<String> notArr = new ArrayList<>(); | |
| 36 | + | |
| 37 | + for (String lineCode : codeArray) { | |
| 38 | + if (null == lineConfigData.get(lineCode + "")) | |
| 39 | + notArr.add(lineCode); | |
| 40 | + } | |
| 41 | + | |
| 42 | + if (notArr.size() > 0) { | |
| 43 | + rs.put("status", 1); | |
| 44 | + rs.put("not", notArr); | |
| 45 | + } else | |
| 46 | + rs.put("status", 0); | |
| 47 | + return rs; | |
| 48 | + } | |
| 49 | + | |
| 50 | + @Override | |
| 51 | + public Integer init(String lineCode) throws Exception { | |
| 52 | + LineConfig conf = lineConfigData.get(lineCode); | |
| 53 | + | |
| 54 | + if (conf == null) | |
| 55 | + lineConfigData.init(lineCode); | |
| 56 | + | |
| 57 | + return 1; | |
| 58 | + } | |
| 59 | + | |
| 60 | + @Override | |
| 61 | + public Map<String, Object> editStartOptTime(String time, String lineCode) { | |
| 62 | + Map<String, Object> rs = new HashMap<>(); | |
| 63 | + try { | |
| 64 | + LineConfig conf = lineConfigData.get(lineCode); | |
| 65 | + conf.setStartOpt(time); | |
| 66 | + lineConfigData.set(conf); | |
| 67 | + | |
| 68 | + rs.put("status", ResponseCode.SUCCESS); | |
| 69 | + rs.put("time", time); | |
| 70 | + } catch (Exception e) { | |
| 71 | + rs.put("status", ResponseCode.ERROR); | |
| 72 | + rs.put("msg", e.getMessage()); | |
| 73 | + logger.error("", e); | |
| 74 | + } | |
| 75 | + return rs; | |
| 76 | + } | |
| 77 | + | |
| 78 | + @Override | |
| 79 | + public Map<String, Object> editOutTimeType(String lineCode, int type, String parkCode, String stationCode) { | |
| 80 | + Map<String, Object> rs = new HashMap<>(); | |
| 81 | + try { | |
| 82 | + LineConfig conf = lineConfigData.get(lineCode); | |
| 83 | + | |
| 84 | + conf.setOutConfig(type); | |
| 85 | + if(type == 2){ | |
| 86 | + conf.setTwinsParks(parkCode); | |
| 87 | + conf.setTwinsStations(stationCode); | |
| 88 | + } | |
| 89 | + lineConfigData.set(conf); | |
| 90 | + | |
| 91 | + rs.put("status", ResponseCode.SUCCESS); | |
| 92 | + rs.put("conf", conf); | |
| 93 | + } catch (Exception e) { | |
| 94 | + rs.put("status", ResponseCode.ERROR); | |
| 95 | + rs.put("msg", e.getMessage()); | |
| 96 | + logger.error("", e); | |
| 97 | + } | |
| 98 | + return rs; | |
| 99 | + } | |
| 100 | + | |
| 101 | + @Override | |
| 102 | + public LineConfig getByLineCode(String lineCode) { | |
| 103 | + return lineConfigData.get(lineCode); | |
| 104 | + } | |
| 105 | + | |
| 106 | + @Override | |
| 107 | + public Map<String, Object> enableInParkForSource(String lineCode, int enable) { | |
| 108 | + Map<String, Object> rs = new HashMap<>(); | |
| 109 | + try { | |
| 110 | + LineConfig conf = lineConfigData.get(lineCode); | |
| 111 | + | |
| 112 | + conf.setInParkForSource(enable == 1); | |
| 113 | + lineConfigData.set(conf); | |
| 114 | + | |
| 115 | + rs.put("status", ResponseCode.SUCCESS); | |
| 116 | + rs.put("enable", enable); | |
| 117 | + } catch (Exception e) { | |
| 118 | + rs.put("status", ResponseCode.ERROR); | |
| 119 | + rs.put("msg", e.getMessage()); | |
| 120 | + logger.error("", e); | |
| 121 | + } | |
| 122 | + return rs; | |
| 123 | + } | |
| 124 | + | |
| 125 | + @Override | |
| 126 | + public Map<String, Object> bufferTimeDiff(String lineCode, String field, String value) { | |
| 127 | + | |
| 128 | + Map<String, Object> rs = new HashMap<>(); | |
| 129 | + try { | |
| 130 | + LineConfig conf = lineConfigData.get(lineCode); | |
| 131 | + Field f = conf.getClass().getDeclaredField(field); | |
| 132 | + f.setAccessible(true); | |
| 133 | + f.setInt(conf, Integer.parseInt(value)); | |
| 134 | + | |
| 135 | + lineConfigData.set(conf); | |
| 136 | + | |
| 137 | + rs.put("status", ResponseCode.SUCCESS); | |
| 138 | + rs.put("field", field); | |
| 139 | + rs.put("value", value); | |
| 140 | + } catch (Exception e) { | |
| 141 | + rs.put("status", ResponseCode.ERROR); | |
| 142 | + rs.put("msg", e.getMessage()); | |
| 143 | + logger.error("", e); | |
| 144 | + } | |
| 145 | + return rs; | |
| 146 | + } | |
| 147 | + | |
| 148 | + @Override | |
| 149 | + public Map<String, Object> yjtkSet(Map<String, String> map) { | |
| 150 | + String lineCode = map.get("lineCode").toString(); | |
| 151 | + int enableYjtk = Integer.parseInt(map.get("enableYjtk").toString()); | |
| 152 | + | |
| 153 | + Map<String, Object> rs = new HashMap<>(); | |
| 154 | + try { | |
| 155 | + LineConfig conf = lineConfigData.get(lineCode); | |
| 156 | + | |
| 157 | + if(enableYjtk == 1){ | |
| 158 | + String yjtkStart = map.containsKey("yjtkStart") ? map.get("yjtkStart").toString() : "00:00"; | |
| 159 | + String yjtkEnd = map.containsKey("yjtkEnd") ? map.get("yjtkEnd").toString() : "23:59"; | |
| 160 | + int upStopMinute = Integer.parseInt(map.get("upStopMinute").toString()); | |
| 161 | + int downStopMinute = Integer.parseInt(map.get("downStopMinute").toString()); | |
| 162 | + | |
| 163 | + conf.setEnableYjtk(true); | |
| 164 | + conf.setYjtkStart(yjtkStart); | |
| 165 | + conf.setYjtkEnd(yjtkEnd); | |
| 166 | + conf.setUpStopMinute(upStopMinute); | |
| 167 | + conf.setDownStopMinute(downStopMinute); | |
| 168 | + } | |
| 169 | + else | |
| 170 | + conf.setEnableYjtk(false); | |
| 171 | + | |
| 172 | + lineConfigData.set(conf); | |
| 173 | + | |
| 174 | + rs.put("status", ResponseCode.SUCCESS); | |
| 175 | + rs.put("conf", conf); | |
| 176 | + } catch (Exception e) { | |
| 177 | + rs.put("status", ResponseCode.ERROR); | |
| 178 | + rs.put("msg", e.getMessage()); | |
| 179 | + logger.error("", e); | |
| 180 | + } | |
| 181 | + return rs; | |
| 182 | + } | |
| 183 | + | |
| 184 | + @Override | |
| 185 | + public Map<String, Object> parkAndStationSet(Map<String, String> map) { | |
| 186 | + String lineCode = map.get("lineCode").toString(); | |
| 187 | + String twinsPark = map.get("twinsPark").toString(); | |
| 188 | + String twinsStation = map.get("twinsStation").toString(); | |
| 189 | + | |
| 190 | + Map<String, Object> rs = new HashMap<>(); | |
| 191 | + try { | |
| 192 | + LineConfig conf = lineConfigData.get(lineCode); | |
| 193 | + conf.setTwinsParks(twinsPark); | |
| 194 | + conf.setTwinsStations(twinsStation); | |
| 195 | + | |
| 196 | + lineConfigData.set(conf); | |
| 197 | + | |
| 198 | + rs.put("status", ResponseCode.SUCCESS); | |
| 199 | + rs.put("conf", conf); | |
| 200 | + } catch (Exception e) { | |
| 201 | + rs.put("status", ResponseCode.ERROR); | |
| 202 | + rs.put("msg", e.getMessage()); | |
| 203 | + logger.error("", e); | |
| 204 | + } | |
| 205 | + return rs; | |
| 206 | + } | |
| 207 | + | |
| 208 | + @Override | |
| 209 | + public Map<String, Object> findByIdx(String idx) { | |
| 210 | + Map<String, Object> rs = new HashMap(); | |
| 211 | + try{ | |
| 212 | + List<LineConfig> list = new ArrayList<>(); | |
| 213 | + List<String> ids = Splitter.on(",").splitToList(idx); | |
| 214 | + | |
| 215 | + for(String id : ids){ | |
| 216 | + list.add(lineConfigData.get(id)); | |
| 217 | + } | |
| 218 | + | |
| 219 | + rs.put("status", ResponseCode.SUCCESS); | |
| 220 | + rs.put("list", list); | |
| 221 | + }catch (Exception e){ | |
| 222 | + rs.put("status", ResponseCode.ERROR); | |
| 223 | + logger.error("", e); | |
| 224 | + } | |
| 225 | + return rs; | |
| 226 | + } | |
| 227 | + | |
| 228 | + @Override | |
| 229 | + public Map<String, Object> setAutoExec(Map<String, String> map) { | |
| 230 | + String lineCode = map.get("lineCode").toString(); | |
| 231 | + boolean autoExec = Boolean.parseBoolean(map.get("autoExec")); | |
| 232 | + int autoExecOffset = Integer.parseInt(map.get("autoExecOffset")); | |
| 233 | + | |
| 234 | + Map<String, Object> rs = new HashMap<>(); | |
| 235 | + try { | |
| 236 | + LineConfig conf = lineConfigData.get(lineCode); | |
| 237 | + conf.setAutoExec(autoExec); | |
| 238 | + conf.setAutoExecOffset(autoExecOffset); | |
| 239 | + | |
| 240 | + lineConfigData.set(conf); | |
| 241 | + rs.put("status", ResponseCode.SUCCESS); | |
| 242 | + rs.put("conf", conf); | |
| 243 | + } catch (Exception e) { | |
| 244 | + rs.put("status", ResponseCode.ERROR); | |
| 245 | + rs.put("msg", e.getMessage()); | |
| 246 | + logger.error("", e); | |
| 247 | + } | |
| 248 | + return rs; | |
| 249 | + } | |
| 250 | + | |
| 251 | + @Override | |
| 252 | + public Map<String, Object> setReadReverse(int status, String lineCode) { | |
| 253 | + Map<String, Object> rs = new HashMap<>(); | |
| 254 | + try { | |
| 255 | + LineConfig conf = lineConfigData.get(lineCode); | |
| 256 | + conf.setReadReverse(status==1?true:false); | |
| 257 | + | |
| 258 | + lineConfigData.set(conf); | |
| 259 | + rs.put("status", ResponseCode.SUCCESS); | |
| 260 | + rs.put("conf", conf); | |
| 261 | + } catch (Exception e) { | |
| 262 | + rs.put("status", ResponseCode.ERROR); | |
| 263 | + rs.put("msg", e.getMessage()); | |
| 264 | + logger.error("", e); | |
| 265 | + } | |
| 266 | + return rs; | |
| 267 | + } | |
| 268 | +} | ... | ... |
src/main/resources/static/real_control_v2/fragments/north/nav/line_config/fbzdzx_config.html
| 1 | -<div id="nav-fbzdzx_config-modal" class="uk-modal"> | |
| 2 | - <div class="uk-modal-dialog uk-modal-dialog-blank" style="overflow: hidden;"> | |
| 3 | - <button class="uk-modal-close uk-close" type="button"></button> | |
| 4 | - <div class="uk-grid uk-flex-middle" data-uk-grid-margin> | |
| 5 | - <div class="uk-width-medium-1-6 uk-height-viewport line-config-tree" data-uk-observe> | |
| 6 | - <h3 class="title">翻班与自动完成</h3> | |
| 7 | - <div class="uk-accordion" data-uk-accordion="{showfirst:false}" ></div> | |
| 8 | - </div> | |
| 9 | - <div class="uk-width-medium-5-6 uk-height-viewport right-container" data-uk-observe> | |
| 10 | - <div id="fbzdzx_config_entity_panel"></div> | |
| 11 | - <div id="buffer_config_panel"></div> | |
| 12 | - </div> | |
| 13 | - </div> | |
| 14 | - </div> | |
| 15 | - | |
| 16 | - | |
| 17 | - <script id="nav-fbzdzx_config-modal-tree-temp" type="text/html"> | |
| 18 | - {{each array as line i}} | |
| 19 | - <h3 class="uk-accordion-title" data-id="{{line.lineCode}}">{{line.name}}</h3> | |
| 20 | - <div class="uk-accordion-content"> | |
| 21 | - <ul class="uk-list uk-list-line" id="smooth_scroll_list"> | |
| 22 | - <li><a data-href="#schedule_reload_time_panel" >班次更新时间</a></li> | |
| 23 | - <li><a data-href="#schedule_auto_exec_panel" >班次自动执行</a></li> | |
| 24 | - </ul> | |
| 25 | - </div> | |
| 26 | - {{/each}} | |
| 27 | - </script> | |
| 28 | - | |
| 29 | - <script> | |
| 30 | - (function () { | |
| 31 | - var modal = '#nav-fbzdzx_config-modal', | |
| 32 | - lineConfig, activeCode; | |
| 33 | - | |
| 34 | - //初始化滚动条 | |
| 35 | - $('.right-container', modal).perfectScrollbar({suppressScrollX: true}); | |
| 36 | - /** | |
| 37 | - * 手风琴拨动 | |
| 38 | - */ | |
| 39 | - $('.uk-accordion').on('toggle.uk.accordion', function (e, active, toggle, content) { | |
| 40 | - if(active){ | |
| 41 | - activeCode = $(toggle).data('id'); | |
| 42 | - load(); | |
| 43 | - } | |
| 44 | - }); | |
| 45 | - | |
| 46 | - $(modal).on('init', function (e, data) { | |
| 47 | - e.stopPropagation(); | |
| 48 | - var htmlStr = template('nav-fbzdzx_config-modal-tree-temp', {array: gb_data_basic.activeLines}); | |
| 49 | - $('.line-config-tree .uk-accordion', modal).html(htmlStr); | |
| 50 | - | |
| 51 | - if(data.activeCode) | |
| 52 | - activeCode = data.activeCode; | |
| 53 | - else{ | |
| 54 | - //展开tab激活的线路 | |
| 55 | - var $activeTab = $('#main-tab-content>li.line_schedule.uk-active'); | |
| 56 | - if($activeTab.length > 0) | |
| 57 | - activeCode = $activeTab.data('id'); | |
| 58 | - else{ | |
| 59 | - //展开第一个 | |
| 60 | - var $first = $('.uk-accordion-title:eq(0)', modal); | |
| 61 | - activeCode = $first.data('id'); | |
| 62 | - } | |
| 63 | - } | |
| 64 | - | |
| 65 | - setTimeout(function () { | |
| 66 | - $('.uk-accordion-title[data-id='+activeCode+']', modal).trigger('click'); | |
| 67 | - }, 500); | |
| 68 | - }); | |
| 69 | - | |
| 70 | - | |
| 71 | - var load = function () { | |
| 72 | - //获取线路配置信息 | |
| 73 | - $.get('/lineConfig/getByLineCode', {lineCode: activeCode}, function (conf) { | |
| 74 | - lineConfig = conf; | |
| 75 | - | |
| 76 | - loadConfigEntity(); | |
| 77 | - loadBufferConfig(); | |
| 78 | - | |
| 79 | - setTimeout(function () { | |
| 80 | - //更新滚动条高度 | |
| 81 | - $('.right-container', modal).perfectScrollbar('update'); | |
| 82 | - }, 500); | |
| 83 | - }); | |
| 84 | - }; | |
| 85 | - | |
| 86 | - //线路配置表属性设置 | |
| 87 | - var loadConfigEntity = function () { | |
| 88 | - $.get('/real_control_v2/fragments/north/nav/line_config/fbzdzx_config_entity.html', function (attrDom) { | |
| 89 | - $('.right-container #fbzdzx_config_entity_panel', modal) | |
| 90 | - .html(attrDom) | |
| 91 | - .find('#fbzdzx_config_entity_wrap') | |
| 92 | - .trigger('init', {lineConfig: lineConfig}); | |
| 93 | - }); | |
| 94 | - }; | |
| 95 | - | |
| 96 | - | |
| 97 | - //瞄点 | |
| 98 | - $(modal).on('click', '#smooth_scroll_list>li>a', function () { | |
| 99 | - var id = $(this).data('href'); | |
| 100 | - scrollToElement($(id, modal)); | |
| 101 | - }); | |
| 102 | - | |
| 103 | - function scrollToElement(ele) { | |
| 104 | - var cont = $('.right-container', modal), diff = 10; | |
| 105 | - cont.animate({ | |
| 106 | - scrollTop: ele.offset().top - cont.offset().top + cont.scrollTop() - diff | |
| 107 | - }, 300); | |
| 108 | - } | |
| 109 | - })(); | |
| 110 | - </script> | |
| 111 | -</div> | |
| 1 | +<div id="nav-fbzdzx_config-modal" class="uk-modal"> | |
| 2 | + <div class="uk-modal-dialog uk-modal-dialog-blank" style="overflow: hidden;"> | |
| 3 | + <button class="uk-modal-close uk-close" type="button"></button> | |
| 4 | + <div class="uk-grid uk-flex-middle" data-uk-grid-margin> | |
| 5 | + <div class="uk-width-medium-1-6 uk-height-viewport line-config-tree" data-uk-observe> | |
| 6 | + <h3 class="title">翻班与自动完成</h3> | |
| 7 | + <div class="uk-accordion" data-uk-accordion="{showfirst:false}" ></div> | |
| 8 | + </div> | |
| 9 | + <div class="uk-width-medium-5-6 uk-height-viewport right-container" data-uk-observe> | |
| 10 | + <div id="fbzdzx_config_entity_panel"></div> | |
| 11 | + <div id="buffer_config_panel"></div> | |
| 12 | + </div> | |
| 13 | + </div> | |
| 14 | + </div> | |
| 15 | + | |
| 16 | + | |
| 17 | + <script id="nav-fbzdzx_config-modal-tree-temp" type="text/html"> | |
| 18 | + {{each array as line i}} | |
| 19 | + <h3 class="uk-accordion-title" data-id="{{line.lineCode}}">{{line.name}}</h3> | |
| 20 | + <div class="uk-accordion-content"> | |
| 21 | + <ul class="uk-list uk-list-line" id="smooth_scroll_list"> | |
| 22 | + <li><a data-href="#schedule_reload_time_panel" >班次更新时间</a></li> | |
| 23 | + <li><a data-href="#schedule_auto_exec_panel" >班次自动执行</a></li> | |
| 24 | + </ul> | |
| 25 | + </div> | |
| 26 | + {{/each}} | |
| 27 | + </script> | |
| 28 | + | |
| 29 | + <script> | |
| 30 | + (function () { | |
| 31 | + var modal = '#nav-fbzdzx_config-modal', | |
| 32 | + lineConfig, activeCode; | |
| 33 | + | |
| 34 | + //初始化滚动条 | |
| 35 | + $('.right-container', modal).perfectScrollbar({suppressScrollX: true}); | |
| 36 | + /** | |
| 37 | + * 手风琴拨动 | |
| 38 | + */ | |
| 39 | + $('.uk-accordion').on('toggle.uk.accordion', function (e, active, toggle, content) { | |
| 40 | + if(active){ | |
| 41 | + activeCode = $(toggle).data('id'); | |
| 42 | + load(); | |
| 43 | + } | |
| 44 | + }); | |
| 45 | + | |
| 46 | + $(modal).on('init', function (e, data) { | |
| 47 | + e.stopPropagation(); | |
| 48 | + var htmlStr = template('nav-fbzdzx_config-modal-tree-temp', {array: gb_data_basic.activeLines}); | |
| 49 | + $('.line-config-tree .uk-accordion', modal).html(htmlStr); | |
| 50 | + | |
| 51 | + if(data.activeCode) | |
| 52 | + activeCode = data.activeCode; | |
| 53 | + else{ | |
| 54 | + //展开tab激活的线路 | |
| 55 | + var $activeTab = $('#main-tab-content>li.line_schedule.uk-active'); | |
| 56 | + if($activeTab.length > 0) | |
| 57 | + activeCode = $activeTab.data('id'); | |
| 58 | + else{ | |
| 59 | + //展开第一个 | |
| 60 | + var $first = $('.uk-accordion-title:eq(0)', modal); | |
| 61 | + activeCode = $first.data('id'); | |
| 62 | + } | |
| 63 | + } | |
| 64 | + | |
| 65 | + setTimeout(function () { | |
| 66 | + $('.uk-accordion-title[data-id='+activeCode+']', modal).trigger('click'); | |
| 67 | + }, 500); | |
| 68 | + }); | |
| 69 | + | |
| 70 | + | |
| 71 | + var load = function () { | |
| 72 | + //获取线路配置信息 | |
| 73 | + $.get('/lineConfig/getByLineCode', {lineCode: activeCode}, function (conf) { | |
| 74 | + lineConfig = conf; | |
| 75 | + | |
| 76 | + loadConfigEntity(); | |
| 77 | + | |
| 78 | + setTimeout(function () { | |
| 79 | + //更新滚动条高度 | |
| 80 | + $('.right-container', modal).perfectScrollbar('update'); | |
| 81 | + }, 500); | |
| 82 | + }); | |
| 83 | + }; | |
| 84 | + | |
| 85 | + //线路配置表属性设置 | |
| 86 | + var loadConfigEntity = function () { | |
| 87 | + $.get('/real_control_v2/fragments/north/nav/line_config/fbzdzx_config_entity.html', function (attrDom) { | |
| 88 | + $('.right-container #fbzdzx_config_entity_panel', modal) | |
| 89 | + .html(attrDom) | |
| 90 | + .find('#fbzdzx_config_entity_wrap') | |
| 91 | + .trigger('init', {lineConfig: lineConfig}); | |
| 92 | + }); | |
| 93 | + }; | |
| 94 | + | |
| 95 | + | |
| 96 | + //瞄点 | |
| 97 | + $(modal).on('click', '#smooth_scroll_list>li>a', function () { | |
| 98 | + var id = $(this).data('href'); | |
| 99 | + scrollToElement($(id, modal)); | |
| 100 | + }); | |
| 101 | + | |
| 102 | + function scrollToElement(ele) { | |
| 103 | + var cont = $('.right-container', modal), diff = 10; | |
| 104 | + cont.animate({ | |
| 105 | + scrollTop: ele.offset().top - cont.offset().top + cont.scrollTop() - diff | |
| 106 | + }, 300); | |
| 107 | + } | |
| 108 | + })(); | |
| 109 | + </script> | |
| 110 | +</div> | ... | ... |
src/main/resources/static/real_control_v2/fragments/north/nav/line_config/fbzdzx_config_entity.html
| 1 | -<!-- 线路配置表相关属性 --> | |
| 2 | -<div id="fbzdzx_config_entity_wrap"> | |
| 3 | - <form class="uk-form"></form> | |
| 4 | - | |
| 5 | - <script id="fbzdzx_config_entity_form-temp" type="text/html"> | |
| 6 | - <div id="schedule_reload_time_panel"> | |
| 7 | - <h2 class="btn_title_line"> | |
| 8 | - <a class="uk-link-reset">班次更新时间</a> | |
| 9 | - </h2> | |
| 10 | - <div> | |
| 11 | - <div> | |
| 12 | - <span class="line_name"></span>每天 | |
| 13 | - <div class="uk-form-icon" style="margin: 0 5px;"> | |
| 14 | - <i class="uk-icon-clock-o"></i> | |
| 15 | - <input name="startOptInput" readonly type="text" class="z-depth-input" value="{{startOpt}}" | |
| 16 | - style="width: 151px;" | |
| 17 | - data-uk-timepicker> | |
| 18 | - </div> | |
| 19 | - 更新到当日排班 | |
| 20 | - </div> | |
| 21 | - <ul class="uk-list"> | |
| 22 | - <li> | |
| 23 | - <small><i class="uk-icon-question-circle"></i> 所有发车时间小于该时间的班次都默认跨过24点,手动调整的实发实达均应用此规则。</small> | |
| 24 | - </li> | |
| 25 | - </ul> | |
| 26 | - <button class="uk-button uk-button-mini" id="clearRealScheduleBtn">删除实际排班</button> | |
| 27 | - <button class="uk-button uk-button-mini" id="reLoadRealScheduleBtn">重新加载实际排班</button> | |
| 28 | - <button class="uk-button uk-button-mini" disabled>加载历史GPS恢复到离站</button> | |
| 29 | - </div> | |
| 30 | - </div> | |
| 31 | - | |
| 32 | - <div id="schedule_auto_exec_panel"> | |
| 33 | - <h2 class="btn_title_line"> | |
| 34 | - <a class="uk-link-reset">班次自动执行</a> | |
| 35 | - </h2> | |
| 36 | - <div> | |
| 37 | - <div> | |
| 38 | - <label> | |
| 39 | - <input type="checkbox" id="enableAutoExec" {{autoExec?"checked":""}}> 启用自动班次执行 | |
| 40 | - </label> | |
| 41 | - </div> | |
| 42 | - <ul class="uk-list"> | |
| 43 | - <li> | |
| 44 | - <small style="color: red;font-size: 14px;">1、 你必须只应该对【无固定走向且无人监管的线路】启用此项。</small> | |
| 45 | - </li> | |
| 46 | - <li> | |
| 47 | - <small>2、启用该选项后,系统将不再依赖相关定位信号来执行班次。</small> | |
| 48 | - </li> | |
| 49 | - <li> | |
| 50 | - <small>3、系统将在合适的时候自动填入实发实达时间,以完善报表。</small> | |
| 51 | - </li> | |
| 52 | - <li> | |
| 53 | - <small>4、系统不会下发班次调度指令。</small> | |
| 54 | - </li> | |
| 55 | - </ul> | |
| 56 | - </div> | |
| 57 | - </div> | |
| 58 | - | |
| 59 | - </script> | |
| 60 | - | |
| 61 | - <script> | |
| 62 | - (function () { | |
| 63 | - | |
| 64 | - var wrap = '#fbzdzx_config_entity_wrap', conf, parks, upStationRoutes; | |
| 65 | - | |
| 66 | - /** | |
| 67 | - * 删除实际排班 | |
| 68 | - */ | |
| 69 | - var clearRealSchedule = function (e) { | |
| 70 | - e.stopPropagation(); | |
| 71 | - var lineCode = conf.line.lineCode; | |
| 72 | - var htmlStr = '<h4 style="color: red;">你确定要删除【' + conf.line.name + '】今日的实际排班?</h4><h5 style="margin-top: 15px;">今日的实际排班会被删除</h5><h5 style="margin-top: 15px;">人车、路牌、待发等相关班次调整信息会被删除。</h5><h5 style="margin-top: 15px;">调度指令和期间与设备的通讯记录被保留</h5><h5 style="margin-top: 15px;">后台日志中的人工操作痕迹被保留</h5>'; | |
| 73 | - alt_confirm(htmlStr, function () { | |
| 74 | - show_wait_modal('正在清除数据...'); | |
| 75 | - gb_common.$post('/realSchedule/deleteRealSchedule', {lineCode: lineCode}, function () { | |
| 76 | - //刷新班次表格 | |
| 77 | - gb_schedule_table.reLoadAndRefresh(lineCode); | |
| 78 | - hide_wait_modal(); | |
| 79 | - notify_succ('删除班次成功!!!'); | |
| 80 | - }); | |
| 81 | - }, '确认删除' + conf.line.name + '的实际排班', true); | |
| 82 | - | |
| 83 | - return false; | |
| 84 | - }; | |
| 85 | - | |
| 86 | - /** | |
| 87 | - * 重新载入实际排班 | |
| 88 | - */ | |
| 89 | - var reLoadRealSchedule = function (e) { | |
| 90 | - e.stopPropagation(); | |
| 91 | - var lineCode = conf.line.lineCode; | |
| 92 | - show_wait_modal('正在重载数据...'); | |
| 93 | - gb_common.$post('/realSchedule/reLoadRealSchedule', {lineCode: lineCode}, function () { | |
| 94 | - //刷新班次表格 | |
| 95 | - gb_schedule_table.reLoadAndRefresh(lineCode); | |
| 96 | - hide_wait_modal(); | |
| 97 | - notify_succ('重新载入班次成功'); | |
| 98 | - }); | |
| 99 | - return false; | |
| 100 | - }; | |
| 101 | - | |
| 102 | - $(wrap).on('init', function (e, data) { | |
| 103 | - e.stopPropagation(); | |
| 104 | - conf = data.lineConfig; | |
| 105 | - //停车场 | |
| 106 | - $.get('/basic/parks', function (rs) { | |
| 107 | - parks = []; | |
| 108 | - for (var code in rs) { | |
| 109 | - parks.push({code: code, name: rs[code]}); | |
| 110 | - } | |
| 111 | - | |
| 112 | - parks.sort(function (a, b) { | |
| 113 | - return $.trim(a.name).localeCompare($.trim(b.name), 'zh-CN'); | |
| 114 | - }); | |
| 115 | - renderPSDom(); | |
| 116 | - }); | |
| 117 | - //上行站点路由 | |
| 118 | - upStationRoutes = gb_common.groupBy(gb_data_basic.stationRoutes(conf.line.lineCode).sort(function (a, b) { | |
| 119 | - return a.stationRouteCode - b.stationRouteCode; | |
| 120 | - }), 'directions')[0]; | |
| 121 | - | |
| 122 | - var htmlStr = template('fbzdzx_config_entity_form-temp', conf); | |
| 123 | - $('form', wrap).html(htmlStr); | |
| 124 | - | |
| 125 | - $('.line_name', '#fbzdzx_config_entity_wrap').text(conf.line.name); | |
| 126 | - //更新排班时间 | |
| 127 | - $('input[name=startOptInput]', wrap).on('change', updateStartTime); | |
| 128 | - //出场时间类型 | |
| 129 | - $('select[name=outParkTypeSelect]', wrap).on('change', updateOutParkType); | |
| 130 | - //原线路回场 | |
| 131 | - $('select[name=inParkForSourceSelect]', wrap).on('change', enableInParkForSource); | |
| 132 | - //删除班次 | |
| 133 | - $('#clearRealScheduleBtn', wrap).on('click', clearRealSchedule); | |
| 134 | - //重新载入实际排班 | |
| 135 | - $('#reLoadRealScheduleBtn', wrap).on('click', reLoadRealSchedule); | |
| 136 | - $('#enableAutoExec', wrap).on('click', autoExecFun); | |
| 137 | - }); | |
| 138 | - | |
| 139 | - function changeTwinsParkAndStation() { | |
| 140 | - var parks='',stations='' | |
| 141 | - ,$panel = $('.park-and-station-wrap', wrap); | |
| 142 | - | |
| 143 | - $('select[name=twinsPark]', $panel).each(function () { | |
| 144 | - parks += ($(this).val() + ','); | |
| 145 | - }); | |
| 146 | - | |
| 147 | - $('select[name=twinsStation]', $panel).each(function () { | |
| 148 | - stations += ($(this).val() + ','); | |
| 149 | - }); | |
| 150 | - | |
| 151 | - if(parks.length > 0) | |
| 152 | - parks = parks.substr(0, parks.length - 1); | |
| 153 | - if(stations.length > 0) | |
| 154 | - stations = stations.substr(0, stations.length - 1); | |
| 155 | - | |
| 156 | - gb_common.$post('/lineConfig/parkAndStationSet', { | |
| 157 | - lineCode: conf.line.lineCode, | |
| 158 | - twinsPark: parks, | |
| 159 | - twinsStation: stations | |
| 160 | - }, function (rs) { | |
| 161 | - notify_succ('已保存!!'); | |
| 162 | - conf = rs.conf; | |
| 163 | - }); | |
| 164 | - } | |
| 165 | - | |
| 166 | - //更新排班时间 | |
| 167 | - var startOptFlag; | |
| 168 | - | |
| 169 | - function updateStartTime() { | |
| 170 | - if (startOptFlag || $(this).val() == conf.startOpt) | |
| 171 | - return; | |
| 172 | - startOptFlag = true; | |
| 173 | - var that = this; | |
| 174 | - setTimeout(function () { | |
| 175 | - var timeStr = $(that).val(); | |
| 176 | - gb_common.$post('/lineConfig/editTime', { | |
| 177 | - lineCode: conf.line.lineCode, | |
| 178 | - time: timeStr | |
| 179 | - }, function (rs) { | |
| 180 | - notify_succ('班次更新时间调整为 ' + timeStr); | |
| 181 | - conf.startOpt = rs.time; | |
| 182 | - }); | |
| 183 | - startOptFlag = false; | |
| 184 | - }, 300); | |
| 185 | - } | |
| 186 | - | |
| 187 | - function updateOutParkType() { | |
| 188 | - var type = $(this).val(); | |
| 189 | - var lineCode = conf.line.lineCode; | |
| 190 | - | |
| 191 | - var data = {lineCode: lineCode, type: type, parkCode: '', stationCode: ''}; | |
| 192 | - //出站既是出场 | |
| 193 | - if (type == 2) { | |
| 194 | - //如果配置上有信息 | |
| 195 | - if(conf.twinsParks){ | |
| 196 | - data.parkCode = conf.twinsParks; | |
| 197 | - data.stationCode = conf.twinsStations; | |
| 198 | - } | |
| 199 | - else{ | |
| 200 | - data.parkCode = gb_data_basic.getLineInformation(lineCode).carPark;//默认关联 线路标准停车场 | |
| 201 | - data.stationCode = upStationRoutes[0].stationCode;//和上行起点站 | |
| 202 | - } | |
| 203 | - } | |
| 204 | - gb_common.$post('/lineConfig/editOutTimeType', data, function (rs) { | |
| 205 | - notify_succ('调整出场时间类型成功!'); | |
| 206 | - conf = rs.conf; | |
| 207 | - | |
| 208 | - //渲染场站关联dom | |
| 209 | - renderPSDom(); | |
| 210 | - }); | |
| 211 | - } | |
| 212 | - | |
| 213 | - | |
| 214 | - | |
| 215 | - function enableInParkForSource() { | |
| 216 | - var enable = $(this).val(); | |
| 217 | - gb_common.$post('/lineConfig/enableInParkForSource', { | |
| 218 | - lineCode: conf.line.lineCode, | |
| 219 | - enable: enable | |
| 220 | - }, function () { | |
| 221 | - notify_succ((enable == 1 ? '启用' : '禁用') + '原线路回场'); | |
| 222 | - conf.inParkForSource = enable; | |
| 223 | - }); | |
| 224 | - } | |
| 225 | - | |
| 226 | - | |
| 227 | - /** | |
| 228 | - * 自动执行 | |
| 229 | - */ | |
| 230 | - function autoExecFun(){ | |
| 231 | - var that = this; | |
| 232 | - if(that.checked){ | |
| 233 | - that.checked = false; | |
| 234 | - alt_confirm('<span style="color: red;font-size: 16px;">启用【' + conf.line.name + '】的自动执行功能?</span>', function () { | |
| 235 | - var data = { | |
| 236 | - lineCode: conf.line.lineCode, | |
| 237 | - autoExec: true | |
| 238 | - }; | |
| 239 | - gb_common.$post('/lineConfig/setAutoExec', data, function (rs) { | |
| 240 | - notify_succ('启用成功!'); | |
| 241 | - conf = rs.conf; | |
| 242 | - | |
| 243 | - that.checked = true; | |
| 244 | - }); | |
| 245 | - }, '我确定要将【' + conf.line.name + '】设置为自动执行', true); | |
| 246 | - } | |
| 247 | - else{ | |
| 248 | - that.checked = true; | |
| 249 | - alt_confirm('<span style="color: red;font-size: 16px;">禁用【' + conf.line.name + '】的自动执行功能?</span>', function () { | |
| 250 | - var data = { | |
| 251 | - lineCode: conf.line.lineCode, | |
| 252 | - autoExec: false | |
| 253 | - }; | |
| 254 | - gb_common.$post('/lineConfig/setAutoExec', data, function (rs) { | |
| 255 | - notify_succ('禁用成功!'); | |
| 256 | - conf = rs.conf; | |
| 257 | - | |
| 258 | - that.checked = false; | |
| 259 | - }); | |
| 260 | - }, '我确定要禁用【' + conf.line.name + '】的自动执行', true); | |
| 261 | - } | |
| 262 | - } | |
| 263 | - | |
| 264 | - | |
| 265 | - /** | |
| 266 | - * 删除 场既是站 项目 | |
| 267 | - */ | |
| 268 | - $(wrap).on('click', '.c_2_s_list .item .uk-close', function () { | |
| 269 | - $(this).parents('.item').remove(); | |
| 270 | - changeTwinsParkAndStation(); | |
| 271 | - }); | |
| 272 | - | |
| 273 | - | |
| 274 | - $(wrap).on('change', 'select[name=twinsPark]', changeTwinsParkAndStation); | |
| 275 | - $(wrap).on('change', 'select[name=twinsStation]', changeTwinsParkAndStation); | |
| 276 | - })(); | |
| 277 | - </script> | |
| 1 | +<!-- 线路配置表相关属性 --> | |
| 2 | +<div id="fbzdzx_config_entity_wrap"> | |
| 3 | + <form class="uk-form"></form> | |
| 4 | + | |
| 5 | + <script id="fbzdzx_config_entity_form-temp" type="text/html"> | |
| 6 | + <div id="schedule_reload_time_panel"> | |
| 7 | + <h2 class="btn_title_line"> | |
| 8 | + <a class="uk-link-reset">班次更新时间</a> | |
| 9 | + </h2> | |
| 10 | + <div> | |
| 11 | + <div> | |
| 12 | + <span class="line_name"></span>每天 | |
| 13 | + <div class="uk-form-icon" style="margin: 0 5px;"> | |
| 14 | + <i class="uk-icon-clock-o"></i> | |
| 15 | + <input name="startOptInput" readonly type="text" class="z-depth-input" value="{{startOpt}}" | |
| 16 | + style="width: 151px;" | |
| 17 | + data-uk-timepicker> | |
| 18 | + </div> | |
| 19 | + 更新到当日排班 | |
| 20 | + </div> | |
| 21 | + <ul class="uk-list"> | |
| 22 | + <li> | |
| 23 | + <small><i class="uk-icon-question-circle"></i> 所有发车时间小于该时间的班次都默认跨过24点,手动调整的实发实达均应用此规则。</small> | |
| 24 | + </li> | |
| 25 | + </ul> | |
| 26 | + <button class="uk-button uk-button-mini" id="clearRealScheduleBtn">删除实际排班</button> | |
| 27 | + <button class="uk-button uk-button-mini" id="reLoadRealScheduleBtn">重新加载实际排班</button> | |
| 28 | + <button class="uk-button uk-button-mini" disabled>加载历史GPS恢复到离站</button> | |
| 29 | + </div> | |
| 30 | + </div> | |
| 31 | + | |
| 32 | + <div id="schedule_auto_exec_panel"> | |
| 33 | + <h2 class="btn_title_line"> | |
| 34 | + <a class="uk-link-reset">班次自动执行</a> | |
| 35 | + </h2> | |
| 36 | + <div> | |
| 37 | + <table> | |
| 38 | + <tr> | |
| 39 | + <td> | |
| 40 | + <label> | |
| 41 | + <input type="checkbox" id="enableAutoExec" {{autoExec?"checked":""}}> 启用自动班次执行 | |
| 42 | + </label> | |
| 43 | + </td> | |
| 44 | + </tr> | |
| 45 | + <tr> | |
| 46 | + <td> | |
| 47 | + 自动执行偏移 | |
| 48 | + <input type="number" value="{{autoExecOffset}}" id="autoExecOffset" name="autoExecOffset" style="width: 100px;" {{if !autoExec}}readonly{{/if}}> 分钟 | |
| 49 | + </td> | |
| 50 | + </tr> | |
| 51 | + </table> | |
| 52 | + <ul class="uk-list"> | |
| 53 | + <li> | |
| 54 | + <small style="color: red;font-size: 14px;">1、 你必须只应该对【无固定走向且无人监管的线路】启用此项。</small> | |
| 55 | + </li> | |
| 56 | + <li> | |
| 57 | + <small>2、启用该选项后,系统将不再依赖相关定位信号来执行班次。</small> | |
| 58 | + </li> | |
| 59 | + <li> | |
| 60 | + <small>3、系统将在合适的时候自动填入实发实达时间,以完善报表。</small> | |
| 61 | + </li> | |
| 62 | + <li> | |
| 63 | + <small>4、自动执行偏移为0时按1-3执行,自动执行偏移>0时按5-7执行。</small> | |
| 64 | + </li> | |
| 65 | + <li> | |
| 66 | + <small>5、捕捉的GPS信号在计划发车、计划到达的前后偏移时间内,则自动填入。</small> | |
| 67 | + </li> | |
| 68 | + <li> | |
| 69 | + <small>6、当前时间超过到达时间达到偏移时间,则跳过当前班次,执行下一个班次。</small> | |
| 70 | + </li> | |
| 71 | + <li> | |
| 72 | + <small>7、对于存在实际发车时间或实际到达时间缺失的,将在收班后的合适时间根据当天GPS重新进行计算。</small> | |
| 73 | + </li> | |
| 74 | + </ul> | |
| 75 | + </div> | |
| 76 | + </div> | |
| 77 | + | |
| 78 | + </script> | |
| 79 | + | |
| 80 | + <script> | |
| 81 | + $(function () { | |
| 82 | + | |
| 83 | + var wrap = '#fbzdzx_config_entity_wrap', conf, parks, upStationRoutes; | |
| 84 | + | |
| 85 | + /** | |
| 86 | + * 删除实际排班 | |
| 87 | + */ | |
| 88 | + var clearRealSchedule = function (e) { | |
| 89 | + e.stopPropagation(); | |
| 90 | + var lineCode = conf.line.lineCode; | |
| 91 | + var htmlStr = '<h4 style="color: red;">你确定要删除【' + conf.line.name + '】今日的实际排班?</h4><h5 style="margin-top: 15px;">今日的实际排班会被删除</h5><h5 style="margin-top: 15px;">人车、路牌、待发等相关班次调整信息会被删除。</h5><h5 style="margin-top: 15px;">调度指令和期间与设备的通讯记录被保留</h5><h5 style="margin-top: 15px;">后台日志中的人工操作痕迹被保留</h5>'; | |
| 92 | + alt_confirm(htmlStr, function () { | |
| 93 | + show_wait_modal('正在清除数据...'); | |
| 94 | + gb_common.$post('/realSchedule/deleteRealSchedule', {lineCode: lineCode}, function () { | |
| 95 | + //刷新班次表格 | |
| 96 | + gb_schedule_table.reLoadAndRefresh(lineCode); | |
| 97 | + hide_wait_modal(); | |
| 98 | + notify_succ('删除班次成功!!!'); | |
| 99 | + }); | |
| 100 | + }, '确认删除' + conf.line.name + '的实际排班', true); | |
| 101 | + | |
| 102 | + return false; | |
| 103 | + }; | |
| 104 | + | |
| 105 | + /** | |
| 106 | + * 重新载入实际排班 | |
| 107 | + */ | |
| 108 | + var reLoadRealSchedule = function (e) { | |
| 109 | + e.stopPropagation(); | |
| 110 | + var lineCode = conf.line.lineCode; | |
| 111 | + show_wait_modal('正在重载数据...'); | |
| 112 | + gb_common.$post('/realSchedule/reLoadRealSchedule', {lineCode: lineCode}, function () { | |
| 113 | + //刷新班次表格 | |
| 114 | + gb_schedule_table.reLoadAndRefresh(lineCode); | |
| 115 | + hide_wait_modal(); | |
| 116 | + notify_succ('重新载入班次成功'); | |
| 117 | + }); | |
| 118 | + return false; | |
| 119 | + }; | |
| 120 | + | |
| 121 | + $(wrap).on('init', function (e, data) { | |
| 122 | + e.stopPropagation(); | |
| 123 | + conf = data.lineConfig; | |
| 124 | + //停车场 | |
| 125 | + $.get('/basic/parks', function (rs) { | |
| 126 | + parks = []; | |
| 127 | + for (var code in rs) { | |
| 128 | + parks.push({code: code, name: rs[code]}); | |
| 129 | + } | |
| 130 | + | |
| 131 | + parks.sort(function (a, b) { | |
| 132 | + return $.trim(a.name).localeCompare($.trim(b.name), 'zh-CN'); | |
| 133 | + }); | |
| 134 | + }); | |
| 135 | + //上行站点路由 | |
| 136 | + upStationRoutes = gb_common.groupBy(gb_data_basic.stationRoutes(conf.line.lineCode).sort(function (a, b) { | |
| 137 | + return a.stationRouteCode - b.stationRouteCode; | |
| 138 | + }), 'directions')[0]; | |
| 139 | + | |
| 140 | + var htmlStr = template('fbzdzx_config_entity_form-temp', conf); | |
| 141 | + $('form', wrap).html(htmlStr); | |
| 142 | + | |
| 143 | + $('.line_name', '#fbzdzx_config_entity_wrap').text(conf.line.name); | |
| 144 | + //更新排班时间 | |
| 145 | + $('input[name=startOptInput]', wrap).on('change', updateStartTime); | |
| 146 | + //出场时间类型 | |
| 147 | + $('select[name=outParkTypeSelect]', wrap).on('change', updateOutParkType); | |
| 148 | + //原线路回场 | |
| 149 | + $('select[name=inParkForSourceSelect]', wrap).on('change', enableInParkForSource); | |
| 150 | + //删除班次 | |
| 151 | + $('#clearRealScheduleBtn', wrap).on('click', clearRealSchedule); | |
| 152 | + //重新载入实际排班 | |
| 153 | + $('#reLoadRealScheduleBtn', wrap).on('click', reLoadRealSchedule); | |
| 154 | + $('#enableAutoExec', wrap).on('click', autoExecFun); | |
| 155 | + $('#autoExecOffset').on('change', autoExecOffsetFun) | |
| 156 | + }); | |
| 157 | + | |
| 158 | + //更新排班时间 | |
| 159 | + var startOptFlag; | |
| 160 | + | |
| 161 | + function updateStartTime() { | |
| 162 | + if (startOptFlag || $(this).val() == conf.startOpt) | |
| 163 | + return; | |
| 164 | + startOptFlag = true; | |
| 165 | + var that = this; | |
| 166 | + setTimeout(function () { | |
| 167 | + var timeStr = $(that).val(); | |
| 168 | + gb_common.$post('/lineConfig/editTime', { | |
| 169 | + lineCode: conf.line.lineCode, | |
| 170 | + time: timeStr | |
| 171 | + }, function (rs) { | |
| 172 | + notify_succ('班次更新时间调整为 ' + timeStr); | |
| 173 | + conf.startOpt = rs.time; | |
| 174 | + }); | |
| 175 | + startOptFlag = false; | |
| 176 | + }, 300); | |
| 177 | + } | |
| 178 | + | |
| 179 | + function updateOutParkType() { | |
| 180 | + var type = $(this).val(); | |
| 181 | + var lineCode = conf.line.lineCode; | |
| 182 | + | |
| 183 | + var data = {lineCode: lineCode, type: type, parkCode: '', stationCode: ''}; | |
| 184 | + //出站既是出场 | |
| 185 | + if (type == 2) { | |
| 186 | + //如果配置上有信息 | |
| 187 | + if(conf.twinsParks){ | |
| 188 | + data.parkCode = conf.twinsParks; | |
| 189 | + data.stationCode = conf.twinsStations; | |
| 190 | + } | |
| 191 | + else{ | |
| 192 | + data.parkCode = gb_data_basic.getLineInformation(lineCode).carPark;//默认关联 线路标准停车场 | |
| 193 | + data.stationCode = upStationRoutes[0].stationCode;//和上行起点站 | |
| 194 | + } | |
| 195 | + } | |
| 196 | + gb_common.$post('/lineConfig/editOutTimeType', data, function (rs) { | |
| 197 | + notify_succ('调整出场时间类型成功!'); | |
| 198 | + conf = rs.conf; | |
| 199 | + | |
| 200 | + //渲染场站关联dom | |
| 201 | + renderPSDom(); | |
| 202 | + }); | |
| 203 | + } | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + function enableInParkForSource() { | |
| 208 | + var enable = $(this).val(); | |
| 209 | + gb_common.$post('/lineConfig/enableInParkForSource', { | |
| 210 | + lineCode: conf.line.lineCode, | |
| 211 | + enable: enable | |
| 212 | + }, function () { | |
| 213 | + notify_succ((enable == 1 ? '启用' : '禁用') + '原线路回场'); | |
| 214 | + conf.inParkForSource = enable; | |
| 215 | + }); | |
| 216 | + } | |
| 217 | + | |
| 218 | + | |
| 219 | + /** | |
| 220 | + * 自动执行 | |
| 221 | + */ | |
| 222 | + function autoExecFun(){ | |
| 223 | + var that = this, autoExecOffset = $('#autoExecOffset').val(); | |
| 224 | + if(that.checked){ | |
| 225 | + that.checked = false; | |
| 226 | + alt_confirm('<span style="color: red;font-size: 16px;">启用【' + conf.line.name + '】的自动执行功能?</span>', function () { | |
| 227 | + var data = { | |
| 228 | + lineCode: conf.line.lineCode, | |
| 229 | + autoExec: true, | |
| 230 | + autoExecOffset: autoExecOffset | |
| 231 | + }; | |
| 232 | + gb_common.$post('/lineConfig/setAutoExec', data, function (rs) { | |
| 233 | + notify_succ('启用成功!'); | |
| 234 | + conf = rs.conf; | |
| 235 | + | |
| 236 | + that.checked = true; | |
| 237 | + $('#autoExecOffset').attr('readonly', false); | |
| 238 | + }); | |
| 239 | + }, '我确定要将【' + conf.line.name + '】设置为自动执行', true); | |
| 240 | + } | |
| 241 | + else{ | |
| 242 | + that.checked = true; | |
| 243 | + alt_confirm('<span style="color: red;font-size: 16px;">禁用【' + conf.line.name + '】的自动执行功能?</span>', function () { | |
| 244 | + var data = { | |
| 245 | + lineCode: conf.line.lineCode, | |
| 246 | + autoExec: false, | |
| 247 | + autoExecOffset: autoExecOffset | |
| 248 | + }; | |
| 249 | + gb_common.$post('/lineConfig/setAutoExec', data, function (rs) { | |
| 250 | + notify_succ('禁用成功!'); | |
| 251 | + conf = rs.conf; | |
| 252 | + | |
| 253 | + that.checked = false; | |
| 254 | + $('#autoExecOffset').attr('readonly', true); | |
| 255 | + }); | |
| 256 | + }, '我确定要禁用【' + conf.line.name + '】的自动执行', true); | |
| 257 | + } | |
| 258 | + } | |
| 259 | + | |
| 260 | + // 自动执行偏移 | |
| 261 | + function autoExecOffsetFun() { | |
| 262 | + var checked = $('#enableAutoExec').attr('checked'), autoExecOffset = $(this).val(); | |
| 263 | + if (!autoExecOffset) { | |
| 264 | + $(this).val(0); | |
| 265 | + } | |
| 266 | + if (checked == 'checked') { | |
| 267 | + var data = { | |
| 268 | + lineCode: conf.line.lineCode, | |
| 269 | + autoExec: true, | |
| 270 | + autoExecOffset: autoExecOffset | |
| 271 | + }; | |
| 272 | + gb_common.$post('/lineConfig/setAutoExec', data, function (rs) { | |
| 273 | + notify_succ('设置成功!'); | |
| 274 | + conf = rs.conf; | |
| 275 | + }); | |
| 276 | + } | |
| 277 | + } | |
| 278 | + }); | |
| 279 | + </script> | |
| 278 | 280 | </div> |
| 279 | 281 | \ No newline at end of file | ... | ... |