Commit 20fd58967ab667c62b276b50480c3bd5766945e9
1 parent
c8fe5e60
1.加入导航点位信息接口(常规、绕改道)
Showing
3 changed files
with
312 additions
and
33 deletions
src/main/java/com/bsth/entity/LineRegion.java
0 → 100644
| 1 | +package com.bsth.entity; | |
| 2 | + | |
| 3 | +import com.bsth.server_rs.base_info.station.entity.StationRotue; | |
| 4 | + | |
| 5 | +import javax.persistence.*; | |
| 6 | +import java.util.ArrayList; | |
| 7 | +import java.util.List; | |
| 8 | + | |
| 9 | +public class LineRegion { | |
| 10 | + | |
| 11 | + @Id | |
| 12 | + @GeneratedValue(strategy = GenerationType.IDENTITY) | |
| 13 | + private Integer id; | |
| 14 | + | |
| 15 | + private Integer line; | |
| 16 | + | |
| 17 | + private Integer version; | |
| 18 | + | |
| 19 | + private Integer direction; | |
| 20 | + | |
| 21 | + private String regionAlias; | |
| 22 | + | |
| 23 | + private Integer seq; | |
| 24 | + | |
| 25 | + private List<Integer> stationRouteIds = new ArrayList<>(); | |
| 26 | + | |
| 27 | + public Integer getId() { | |
| 28 | + return id; | |
| 29 | + } | |
| 30 | + | |
| 31 | + public void setId(Integer id) { | |
| 32 | + this.id = id; | |
| 33 | + } | |
| 34 | + | |
| 35 | + public Integer getLine() { | |
| 36 | + return line; | |
| 37 | + } | |
| 38 | + | |
| 39 | + public void setLine(Integer line) { | |
| 40 | + this.line = line; | |
| 41 | + } | |
| 42 | + | |
| 43 | + public Integer getVersion() { | |
| 44 | + return version; | |
| 45 | + } | |
| 46 | + | |
| 47 | + public void setVersion(Integer version) { | |
| 48 | + this.version = version; | |
| 49 | + } | |
| 50 | + | |
| 51 | + public Integer getDirection() { | |
| 52 | + return direction; | |
| 53 | + } | |
| 54 | + | |
| 55 | + public void setDirection(Integer direction) { | |
| 56 | + this.direction = direction; | |
| 57 | + } | |
| 58 | + | |
| 59 | + public String getRegionAlias() { | |
| 60 | + return regionAlias; | |
| 61 | + } | |
| 62 | + | |
| 63 | + public void setRegionAlias(String regionAlias) { | |
| 64 | + this.regionAlias = regionAlias; | |
| 65 | + } | |
| 66 | + | |
| 67 | + public Integer getSeq() { | |
| 68 | + return seq; | |
| 69 | + } | |
| 70 | + | |
| 71 | + public void setSeq(Integer seq) { | |
| 72 | + this.seq = seq; | |
| 73 | + } | |
| 74 | + | |
| 75 | + public List<Integer> getStationRouteIds() { | |
| 76 | + return stationRouteIds; | |
| 77 | + } | |
| 78 | + | |
| 79 | + public void setStationRouteIds(List<Integer> stationRouteIds) { | |
| 80 | + this.stationRouteIds = stationRouteIds; | |
| 81 | + } | |
| 82 | +} | ... | ... |
src/main/java/com/bsth/server_rs/base_info/navigation/NavigationRestService.java
| 1 | 1 | package com.bsth.server_rs.base_info.navigation; |
| 2 | 2 | |
| 3 | 3 | import com.bsth.entity.Detour; |
| 4 | +import com.bsth.entity.LineRegion; | |
| 4 | 5 | import com.bsth.entity.Point; |
| 5 | 6 | import com.bsth.server_rs.base_info.section.buffer.LD_SectionBufferData; |
| 6 | 7 | import com.bsth.server_rs.base_info.section.entity.LD_Section; |
| ... | ... | @@ -37,7 +38,9 @@ public class NavigationRestService implements InitializingBean { |
| 37 | 38 | private LD_SectionBufferData ldSectionBufferData; |
| 38 | 39 | |
| 39 | 40 | private static Map<String, Integer> line2version = new ConcurrentHashMap<>(); |
| 40 | - | |
| 41 | + | |
| 42 | + private static Map<String, LineRegion> line2regionMap = new ConcurrentHashMap<>(); | |
| 43 | + | |
| 41 | 44 | @GET |
| 42 | 45 | @Path("/version/reload") |
| 43 | 46 | @Scheduled(cron = "0 0 * * * *") // 每小时执行一次 |
| ... | ... | @@ -50,6 +53,103 @@ public class NavigationRestService implements InitializingBean { |
| 50 | 53 | if (!line2versionMap.isEmpty()) { |
| 51 | 54 | line2version = line2versionMap; |
| 52 | 55 | } |
| 56 | + | |
| 57 | + loadLineRegions(); | |
| 58 | + } | |
| 59 | + | |
| 60 | + /** | |
| 61 | + * 加载线路区间信息 | |
| 62 | + */ | |
| 63 | + private void loadLineRegions() { | |
| 64 | + Map<String, LineRegion> regionMap = new ConcurrentHashMap<>(); | |
| 65 | + Map<Integer, List<Integer>> region2stationRouteIdsMap = new ConcurrentHashMap<>(); | |
| 66 | + | |
| 67 | + List<LineRegion> regionList = jdbcTemplate.query("SELECT t1.* FROM `bsth_c_line_region` t1 join bsth_c_line_versions t2 on t1.line = t2.line and t1.version = t2.versions where NOW() BETWEEN start_date and end_date", BeanPropertyRowMapper.newInstance(LineRegion.class)); | |
| 68 | + List<Map<String, Object>> mapList = jdbcTemplate.queryForList("SELECT region_id, station_route_id from bsth_c_line_region_stationroute"); | |
| 69 | + | |
| 70 | + Integer oldRegionId = null; | |
| 71 | + for (Map<String, Object> map : mapList) { | |
| 72 | + Integer regionId = (Integer) map.get("region_id"), stationRouteId = (Integer) map.get("station_route_id"); | |
| 73 | + if (oldRegionId == null || !oldRegionId.equals(regionId)) { | |
| 74 | + oldRegionId = (Integer) map.get("region_id"); | |
| 75 | + List<Integer> stationRouteIds = new ArrayList<>(); | |
| 76 | + stationRouteIds.add(stationRouteId); | |
| 77 | + region2stationRouteIdsMap.put(oldRegionId, stationRouteIds); | |
| 78 | + } else { | |
| 79 | + List<Integer> stationRouteIds = region2stationRouteIdsMap.get(regionId); | |
| 80 | + stationRouteIds.add(stationRouteId); | |
| 81 | + } | |
| 82 | + } | |
| 83 | + for (LineRegion region : regionList) { | |
| 84 | + String regionKey = region.getLine() + "-" + region.getSeq(); | |
| 85 | + List<Integer> stationRouteIds = region2stationRouteIdsMap.get(region.getId()); | |
| 86 | + region.setStationRouteIds(stationRouteIds == null ? new ArrayList<Integer>() : stationRouteIds); | |
| 87 | + regionMap.put(regionKey, region); | |
| 88 | + } | |
| 89 | + | |
| 90 | + if (!regionMap.isEmpty()) { | |
| 91 | + line2regionMap = regionMap; | |
| 92 | + } | |
| 93 | + } | |
| 94 | + | |
| 95 | + /** | |
| 96 | + * 解析线路编码,区分普通线路和区间线路 | |
| 97 | + * @param lineCode 线路编码 | |
| 98 | + * @return 解析结果,包含isRegion(是否区间线路)、lineCode(线路代码)、seq(区间序号) | |
| 99 | + */ | |
| 100 | + private Map<String, Object> parseLineCode(String lineCode) { | |
| 101 | + Map<String, Object> result = new HashMap<>(); | |
| 102 | + | |
| 103 | + if (lineCode.contains("-")) { | |
| 104 | + String[] parts = lineCode.split("-"); | |
| 105 | + result.put("isRegion", true); | |
| 106 | + result.put("lineCode", parts[0]); | |
| 107 | + result.put("seq", Integer.parseInt(parts[1])); | |
| 108 | + } else { | |
| 109 | + result.put("isRegion", false); | |
| 110 | + result.put("lineCode", lineCode); | |
| 111 | + result.put("seq", null); | |
| 112 | + } | |
| 113 | + | |
| 114 | + return result; | |
| 115 | + } | |
| 116 | + | |
| 117 | + /** | |
| 118 | + * 获取指定的 LineRegion | |
| 119 | + * @param lineCode 线路编码 | |
| 120 | + * @param seq 区间序号 | |
| 121 | + * @return LineRegion | |
| 122 | + */ | |
| 123 | + private LineRegion getLineRegion(String lineCode, Integer seq) { | |
| 124 | + String regionKey = lineCode + "-" + seq; | |
| 125 | + return line2regionMap.get(regionKey); | |
| 126 | + } | |
| 127 | + | |
| 128 | + /** | |
| 129 | + * 根据区间过滤站点路由 | |
| 130 | + * @param stationRotueList 站点路由列表 | |
| 131 | + * @param lineRegion 线路区间 | |
| 132 | + * @return 过滤后的站点路由列表 | |
| 133 | + */ | |
| 134 | + private List<StationRotue> filterStationRoutesByRegion(List<StationRotue> stationRotueList, LineRegion lineRegion) { | |
| 135 | + if (stationRotueList == null || stationRotueList.isEmpty() || lineRegion == null) { | |
| 136 | + return new ArrayList<>(); | |
| 137 | + } | |
| 138 | + | |
| 139 | + List<Integer> stationRouteIds = lineRegion.getStationRouteIds(); | |
| 140 | + if (stationRouteIds.isEmpty()) { | |
| 141 | + return stationRotueList; | |
| 142 | + } | |
| 143 | + | |
| 144 | + // 过滤站点 | |
| 145 | + List<StationRotue> filteredList = new ArrayList<>(); | |
| 146 | + for (StationRotue stationRotue : stationRotueList) { | |
| 147 | + if (stationRotue.getId() != 0 && stationRouteIds.contains(stationRotue.getId())) { | |
| 148 | + filteredList.add(stationRotue); | |
| 149 | + } | |
| 150 | + } | |
| 151 | + | |
| 152 | + return filteredList; | |
| 53 | 153 | } |
| 54 | 154 | |
| 55 | 155 | /** |
| ... | ... | @@ -65,30 +165,63 @@ public class NavigationRestService implements InitializingBean { |
| 65 | 165 | result.put("lineCode", lineCode); |
| 66 | 166 | result.put("direction", direction); |
| 67 | 167 | |
| 168 | + // 解析线路编码,判断是否为区间线路 | |
| 169 | + Map<String, Object> parseResult = parseLineCode(lineCode); | |
| 170 | + boolean isRegion = (boolean) parseResult.get("isRegion"); | |
| 171 | + String actualLineCode = (String) parseResult.get("lineCode"); | |
| 172 | + | |
| 173 | + // 如果是区间线路,检查版本是否一致 | |
| 174 | + if (isRegion) { | |
| 175 | + LineRegion region = line2regionMap.get(lineCode); | |
| 176 | + | |
| 177 | + if (region == null) { | |
| 178 | + result.put("list", new ArrayList<Point>()); | |
| 179 | + return result; | |
| 180 | + } | |
| 181 | + direction = region.getDirection(); | |
| 182 | + result.put("direction", direction); | |
| 183 | + | |
| 184 | + // 获取线路当前版本 | |
| 185 | + Integer currentVersion = line2version.get(actualLineCode); | |
| 186 | + | |
| 187 | + // 判断版本是否一致 | |
| 188 | + if (!currentVersion.equals(region.getVersion())) { | |
| 189 | + result.put("list", new ArrayList<Point>()); | |
| 190 | + return result; | |
| 191 | + } | |
| 192 | + } | |
| 193 | + | |
| 68 | 194 | // 获取路段数据 |
| 69 | - Map<String, Collection<LD_SectionRoute>> sectionRoutesMap = ldSectionBufferData.findByLineCode(lineCode); | |
| 195 | + Map<String, Collection<LD_SectionRoute>> sectionRoutesMap = ldSectionBufferData.findByLineCode(actualLineCode); | |
| 70 | 196 | if (sectionRoutesMap.isEmpty()) { |
| 71 | 197 | result.put("list", new ArrayList<Point>()); |
| 72 | 198 | return result; |
| 73 | 199 | } |
| 74 | 200 | |
| 75 | 201 | // 获取对应方向的路段路由 |
| 76 | - Collection<LD_SectionRoute> sectionRoutes = sectionRoutesMap.get(lineCode + "_" + direction); | |
| 202 | + Collection<LD_SectionRoute> sectionRoutes = sectionRoutesMap.get(actualLineCode + "_" + direction); | |
| 77 | 203 | if (sectionRoutes == null || sectionRoutes.isEmpty()) { |
| 78 | 204 | result.put("list", new ArrayList<Point>()); |
| 79 | 205 | return result; |
| 80 | 206 | } |
| 81 | 207 | |
| 82 | 208 | // 获取站点数据 |
| 83 | - Map<String, Collection<StationRotue>> stationRoutesMap = StationBufferData.findRouteByLineCode(lineCode); | |
| 84 | - Collection<StationRotue> stationRoutes = stationRoutesMap.get(lineCode + "_" + direction); | |
| 209 | + Map<String, Collection<StationRotue>> stationRoutesMap = StationBufferData.findRouteByLineCode(actualLineCode); | |
| 210 | + Collection<StationRotue> stationRoutes = stationRoutesMap.get(actualLineCode + "_" + direction); | |
| 85 | 211 | List<StationRotue> stationRotueList = stationRoutes != null ? new ArrayList<>(stationRoutes) : new ArrayList<StationRotue>(); |
| 86 | 212 | |
| 213 | + // 如果是区间线路,需要过滤站点 | |
| 214 | + if (isRegion) { | |
| 215 | + Integer seq = (Integer) parseResult.get("seq"); | |
| 216 | + LineRegion lineRegion = getLineRegion(actualLineCode, seq); | |
| 217 | + stationRotueList = filterStationRoutesByRegion(stationRotueList, lineRegion); | |
| 218 | + } | |
| 219 | + | |
| 87 | 220 | // 创建点位信息列表 |
| 88 | - List<Point> points = new ArrayList<>(); | |
| 221 | + List<Point> points = new ArrayList<>(), filteredPoints = new ArrayList<>(); | |
| 89 | 222 | |
| 90 | - // 建立路段到站点的映射 | |
| 91 | - Map<String, StationRotue> sectionToStationMap = new HashMap<>(); | |
| 223 | + // 建立路段到站点的映射(一条路段可能有多个站点) | |
| 224 | + Map<String, List<StationRotue>> sectionToStationMap = new HashMap<>(); | |
| 92 | 225 | |
| 93 | 226 | // 遍历站点,为每个站点找最近的路段 |
| 94 | 227 | for (StationRotue stationRotue : stationRotueList) { |
| ... | ... | @@ -105,7 +238,11 @@ public class NavigationRestService implements InitializingBean { |
| 105 | 238 | LD_Section nearestSection = findNearestSection(stationRotue, sectionRoutes); |
| 106 | 239 | if (nearestSection != null) { |
| 107 | 240 | // 建立路段到站点的映射 |
| 108 | - sectionToStationMap.put(nearestSection.getSectionCode(), stationRotue); | |
| 241 | + String sectionCode = nearestSection.getSectionCode(); | |
| 242 | + if (!sectionToStationMap.containsKey(sectionCode)) { | |
| 243 | + sectionToStationMap.put(sectionCode, new ArrayList<StationRotue>()); | |
| 244 | + } | |
| 245 | + sectionToStationMap.get(sectionCode).add(stationRotue); | |
| 109 | 246 | } |
| 110 | 247 | } |
| 111 | 248 | |
| ... | ... | @@ -117,16 +254,30 @@ public class NavigationRestService implements InitializingBean { |
| 117 | 254 | } |
| 118 | 255 | |
| 119 | 256 | // 检查路段是否有对应的站点 |
| 120 | - StationRotue stationRotue = sectionToStationMap.get(section.getSectionCode()); | |
| 257 | + List<StationRotue> stationRotueListInSection = sectionToStationMap.get(section.getSectionCode()); | |
| 121 | 258 | |
| 122 | 259 | // 创建点位信息 |
| 123 | - Point point = createPointFromSection(section, stationRotue); | |
| 124 | - if (point != null) { | |
| 125 | - points.add(point); | |
| 260 | + List<Point> sectionPoints = createPointsFromSection(section, stationRotueListInSection); | |
| 261 | + if (sectionPoints != null && !sectionPoints.isEmpty()) { | |
| 262 | + points.addAll(sectionPoints); | |
| 263 | + } | |
| 264 | + } | |
| 265 | + int i = 0; | |
| 266 | + for (;i < points.size();i++) { | |
| 267 | + if (points.get(i).isStation()) { | |
| 268 | + break; | |
| 269 | + } | |
| 270 | + } | |
| 271 | + boolean isStart = false; | |
| 272 | + for (int j = points.size() - 1;j >= i;j--) { | |
| 273 | + Point point = points.get(j); | |
| 274 | + if (isStart || point.isStation()) { | |
| 275 | + isStart = true; | |
| 276 | + filteredPoints.add(point); | |
| 126 | 277 | } |
| 127 | 278 | } |
| 128 | 279 | |
| 129 | - result.put("list", points); | |
| 280 | + result.put("list", filteredPoints); | |
| 130 | 281 | return result; |
| 131 | 282 | } |
| 132 | 283 | |
| ... | ... | @@ -311,50 +462,86 @@ public class NavigationRestService implements InitializingBean { |
| 311 | 462 | } |
| 312 | 463 | |
| 313 | 464 | /** |
| 314 | - * 根据路段和站点创建点位信息 | |
| 465 | + * 根据路段和站点列表创建点位信息 | |
| 315 | 466 | * @param section 路段 |
| 316 | - * @param station 站点 | |
| 317 | - * @return 点位信息 | |
| 467 | + * @param stationList 站点列表 | |
| 468 | + * @return 点位信息列表 | |
| 318 | 469 | */ |
| 319 | - private Point createPointFromSection(LD_Section section, StationRotue station) { | |
| 320 | - Point point = new Point(); | |
| 321 | - | |
| 322 | - if (station != null && station.getStation() != null) { | |
| 323 | - // 如果有站点,使用站点的坐标 | |
| 324 | - point.setLon(station.getLon()); | |
| 325 | - point.setLat(station.getLat()); | |
| 326 | - point.setStation(true); | |
| 470 | + private List<Point> createPointsFromSection(LD_Section section, List<StationRotue> stationList) { | |
| 471 | + List<Point> points = new ArrayList<>(); | |
| 472 | + | |
| 473 | + if (stationList != null && !stationList.isEmpty()) { | |
| 474 | + // 如果有站点,为每个站点创建一个点位 | |
| 475 | + for (StationRotue station : stationList) { | |
| 476 | + if (station != null && station.getStation() != null) { | |
| 477 | + Point point = new Point(); | |
| 478 | + point.setLon(station.getLon()); | |
| 479 | + point.setLat(station.getLat()); | |
| 480 | + point.setStation(true); | |
| 481 | + points.add(point); | |
| 482 | + } | |
| 483 | + } | |
| 327 | 484 | } else { |
| 328 | - // 否则使用路段的中间点坐标 | |
| 485 | + // 如果没有站点,使用路段的中间点坐标 | |
| 329 | 486 | Point midPoint = getSectionMidPoint(section); |
| 330 | 487 | if (midPoint != null) { |
| 488 | + Point point = new Point(); | |
| 331 | 489 | point.setLon(midPoint.getLon()); |
| 332 | 490 | point.setLat(midPoint.getLat()); |
| 333 | 491 | point.setStation(false); |
| 334 | - } else { | |
| 335 | - return null; | |
| 492 | + points.add(point); | |
| 336 | 493 | } |
| 337 | 494 | } |
| 338 | 495 | |
| 339 | - return point; | |
| 496 | + return points; | |
| 340 | 497 | } |
| 341 | 498 | |
| 342 | 499 | @GET |
| 343 | 500 | @Path("/detour/{lineCode}/{direction}") |
| 344 | 501 | public List<Detour> detour(@PathParam("lineCode") String lineCode, @PathParam("direction") int direction) { |
| 345 | - Integer version = line2version.get(lineCode); | |
| 502 | + // 解析线路编码,判断是否为区间线路 | |
| 503 | + Map<String, Object> parseResult = parseLineCode(lineCode); | |
| 504 | + boolean isRegion = (boolean) parseResult.get("isRegion"); | |
| 505 | + String actualLineCode = (String) parseResult.get("lineCode"); | |
| 506 | + | |
| 507 | + Integer version = line2version.get(actualLineCode); | |
| 346 | 508 | if (version == null) { |
| 347 | 509 | version = 1; |
| 348 | 510 | } |
| 511 | + // 如果是区间线路,检查版本是否一致 | |
| 512 | + if (isRegion) { | |
| 513 | + LineRegion region = line2regionMap.get(lineCode); | |
| 514 | + | |
| 515 | + if (region == null) { | |
| 516 | + return new ArrayList<>(); | |
| 517 | + } | |
| 518 | + direction = region.getDirection(); | |
| 519 | + | |
| 520 | + // 获取线路当前版本 | |
| 521 | + Integer currentVersion = line2version.get(actualLineCode); | |
| 522 | + | |
| 523 | + // 判断版本是否一致 | |
| 524 | + if (!currentVersion.equals(region.getVersion())) { | |
| 525 | + return new ArrayList<>(); | |
| 526 | + } | |
| 527 | + } | |
| 349 | 528 | List<Detour> detourList = jdbcTemplate.query("select * from bsth_c_detour where line = ? and versions = ? and direction = ?", new Object[]{ lineCode, version, direction }, BeanPropertyRowMapper.newInstance(Detour.class)); |
| 350 | - Map<String, Collection<StationRotue>> map = StationBufferData.findRouteByLineCode(lineCode); | |
| 529 | + Map<String, Collection<StationRotue>> map = StationBufferData.findRouteByLineCode(actualLineCode); | |
| 351 | 530 | if (map.isEmpty()) { |
| 352 | 531 | return new ArrayList<>(); |
| 353 | 532 | } |
| 354 | - Collection<StationRotue> stationRotueCollection = map.get(String.format("%s_%d", lineCode, direction)); | |
| 533 | + Collection<StationRotue> stationRotueCollection = map.get(String.format("%s_%d", actualLineCode, direction)); | |
| 534 | + List<StationRotue> stationRotueList = new ArrayList<>(stationRotueCollection); | |
| 535 | + | |
| 536 | + // 如果是区间线路,需要过滤站点 | |
| 537 | + if (isRegion) { | |
| 538 | + Integer seq = (Integer) parseResult.get("seq"); | |
| 539 | + LineRegion lineRegion = getLineRegion(actualLineCode, seq); | |
| 540 | + stationRotueList = filterStationRoutesByRegion(stationRotueList, lineRegion); | |
| 541 | + } | |
| 355 | 542 | |
| 356 | 543 | // 处理 detourList,将 startStationCode 和 terminalStationCode 替换为对应的索引值+1 |
| 357 | - processDetourStations(detourList, stationRotueCollection); | |
| 544 | + processDetourStations(detourList, stationRotueList); | |
| 358 | 545 | |
| 359 | 546 | // 过滤掉 terminalIdx 不大于 startIdx 的对象 |
| 360 | 547 | List<Detour> filteredDetourList = new ArrayList<>(); | ... | ... |
src/main/java/com/bsth/server_rs/base_info/station/entity/StationRotue.java
| ... | ... | @@ -5,6 +5,8 @@ package com.bsth.server_rs.base_info.station.entity; |
| 5 | 5 | */ |
| 6 | 6 | public class StationRotue { |
| 7 | 7 | |
| 8 | + private int id; | |
| 9 | + | |
| 8 | 10 | /** 线路编码 */ |
| 9 | 11 | private String lineCode; |
| 10 | 12 | |
| ... | ... | @@ -63,6 +65,14 @@ public class StationRotue { |
| 63 | 65 | |
| 64 | 66 | private Double lat; |
| 65 | 67 | |
| 68 | + public int getId() { | |
| 69 | + return id; | |
| 70 | + } | |
| 71 | + | |
| 72 | + public void setId(int id) { | |
| 73 | + this.id = id; | |
| 74 | + } | |
| 75 | + | |
| 66 | 76 | public String getLineCode() { |
| 67 | 77 | return lineCode; |
| 68 | 78 | } | ... | ... |