| | |
| | | if (adjacencyCodeMap.getOrDefault(codeData, Collections.emptyList()).size() != 2) { |
| | | List<String> neighbors = adjacencyCodeMap.getOrDefault(codeData, Collections.emptyList()); |
| | | for (String neighbor : neighbors) { |
| | | // 仅遍历度数为2且未被访问的邻居 |
| | | if (adjacencyCodeMap.getOrDefault(neighbor, Collections.emptyList()).size() == 2 && !visited.contains(neighbor)) { |
| | | Lane lane = new Lane(String.valueOf(snowflakeIdWorker.nextId()).substring(3)); |
| | | dfsCalc(neighbor, codeData, lane, visited, adjacencyCodeMap); |
| | | lane.getCodes().add(codeData); // 包含起点 |
| | | dfsCalcIncludingEnd(codeData, neighbor, lane, visited, adjacencyCodeMap); |
| | | lanes.add(lane); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 处理度数为2且连接两个拐弯点的节点(独立巷道) |
| | | // 处理独立的度数为2的环路或未连接到度数不等于2的节点的部分 |
| | | for (String codeData : codeDataList) { |
| | | if (adjacencyCodeMap.getOrDefault(codeData, Collections.emptyList()).size() == 2 && !visited.contains(codeData)) { |
| | | List<String> neighbors = adjacencyCodeMap.getOrDefault(codeData, Collections.emptyList()); |
| | | boolean connectedToTwoTurningPoints = true; |
| | | for (String neighbor : neighbors) { |
| | | if (adjacencyCodeMap.getOrDefault(neighbor, Collections.emptyList()).size() == 2) { |
| | | connectedToTwoTurningPoints = false; |
| | | break; |
| | | } |
| | | } |
| | | if (connectedToTwoTurningPoints) { |
| | | // 检查是否为环路的一部分 |
| | | Lane lane = new Lane(String.valueOf(snowflakeIdWorker.nextId()).substring(3)); |
| | | lane.getCodes().add(codeData); |
| | | dfsCalcForLoop(codeData, null, lane, visited, adjacencyCodeMap); |
| | | lanes.add(lane); |
| | | visited.add(codeData); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | return R.ok().add(lanes); |
| | | } |
| | | |
| | | private void dfsCalcIncludingEnd(String start, String current, Lane lane, Set<String> visited, Map<String, List<String>> adjacencyCodeMap) { |
| | | // 添加当前节点 |
| | | lane.getCodes().add(current); |
| | | visited.add(current); |
| | | |
| | | private void dfsCalc(String code, String parent, Lane lane, Set<String> visited, Map<String, List<String>> adjacencyCodeMap) { |
| | | // 检查当前节点的度数是否为2 |
| | | if (adjacencyCodeMap.getOrDefault(code, Collections.emptyList()).size() != 2) { |
| | | // 不包含拐弯点 |
| | | List<String> neighbors = adjacencyCodeMap.getOrDefault(current, Collections.emptyList()); |
| | | if (neighbors == null || neighbors.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | // 标记为已访问并加入巷道 |
| | | visited.add(code); |
| | | lane.getCodes().add(code); |
| | | for (String neighbor : neighbors) { |
| | | if (neighbor.equals(start)) { |
| | | continue; |
| | | } |
| | | |
| | | List<String> neighbors = adjacencyCodeMap.get(code); |
| | | if (!visited.contains(neighbor)) { |
| | | int degree = adjacencyCodeMap.getOrDefault(neighbor, Collections.emptyList()).size(); |
| | | if (degree == 2) { |
| | | if (isSameDirection(current, neighbor, start)) { |
| | | dfsCalcIncludingEnd(current, neighbor, lane, visited, adjacencyCodeMap); |
| | | } |
| | | } else { |
| | | // 终点或拐弯点,包含并停止 |
| | | lane.getCodes().add(neighbor); |
| | | visited.add(neighbor); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | private void dfsCalcForLoop(String current, String parent, Lane lane, Set<String> visited, Map<String, List<String>> adjacencyCodeMap) { |
| | | lane.getCodes().add(current); |
| | | visited.add(current); |
| | | |
| | | List<String> neighbors = adjacencyCodeMap.getOrDefault(current, Collections.emptyList()); |
| | | if (neighbors == null || neighbors.isEmpty()) { |
| | | return; |
| | | } |
| | |
| | | continue; |
| | | } |
| | | |
| | | if (adjacencyCodeMap.getOrDefault(neighbor, Collections.emptyList()).size() == 2 && !visited.contains(neighbor)) { |
| | | // 检查方向是否一致 |
| | | if (isSameDirection(code, neighbor, parent)) { |
| | | dfsCalc(neighbor, code, lane, visited, adjacencyCodeMap); |
| | | if (!visited.contains(neighbor)) { |
| | | int degree = adjacencyCodeMap.getOrDefault(neighbor, Collections.emptyList()).size(); |
| | | if (degree == 2) { |
| | | if (isSameDirection(current, neighbor, parent)) { |
| | | dfsCalcForLoop(current, neighbor, lane, visited, adjacencyCodeMap); |
| | | } |
| | | } else { |
| | | lane.getCodes().add(neighbor); |
| | | visited.add(neighbor); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | public boolean isSameDirection(String code, String neighbor, String parent) { |
| | | public boolean isSameDirection(String current, String neighbor, String parent) { |
| | | if (parent == null) { |
| | | return true; |
| | | } |
| | | |
| | | Code parentCode = codeService.selectByData(parent); |
| | | Code currentCode = codeService.selectByData(code); |
| | | Code currentCode = codeService.selectByData(current); |
| | | Code neighborCode = codeService.selectByData(neighbor); |
| | | |
| | | double direction1 = calculateDirection(parentCode, currentCode); |
| | |
| | | return angleDifference < Math.toRadians(3); |
| | | } |
| | | |
| | | /** |
| | | * 计算两个点之间的方向角 |
| | | * |
| | | * @param from 起点 |
| | | * @param to 终点 |
| | | * @return 方向角(弧度) |
| | | */ |
| | | public double calculateDirection(Code from, Code to) { |
| | | double deltaX = to.getX() - from.getX(); |
| | | double deltaY = to.getY() - from.getY(); |