#
Junjie
2025-11-13 1b4fbdb92537036aed4d648967ef7e7ab8842aec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.zy.common.utils;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import org.springframework.stereotype.Component;
 
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.core.exception.CoolException;
import com.zy.common.model.NavigateNode;
 
@Component
public class NavigateUtils {
 
    public synchronized List<NavigateNode> calcByStationId(Integer startStationId, Integer endStationId) {
        NavigateSolution navigateSolution = new NavigateSolution();
        List<List<NavigateNode>> stationMap = navigateSolution.getStationMap();
 
        NavigateNode startNode = navigateSolution.findStationNavigateNode(stationMap, startStationId);
        if (startNode == null){
            throw new CoolException("未找到该 起点 对应的节点");
        }
 
        NavigateNode endNode = navigateSolution.findStationNavigateNode(stationMap, endStationId);
        if (endNode == null){
            throw new CoolException("未找到该 终点 对应的节点");
        }
 
        NavigateNode res_node = navigateSolution.astarSearchJava(stationMap, startNode, endNode);
        if (res_node == null) {
            throw new CoolException("未找到该路径");
        }
 
        ArrayList<NavigateNode> list = new ArrayList<>();
        // 使用 visited 集合防止父链出现环导致死循环,同时设置安全步数上限
        HashSet<NavigateNode> visited = new HashSet<>();
        int maxSteps = stationMap.size() * stationMap.get(0).size() + 5; // 安全上限
        int steps = 0;
        while (res_node != null && visited.add(res_node) && steps++ < maxSteps) {
            list.add(res_node);
            res_node = res_node.getFather();//迭代操作
        }
        if (steps >= maxSteps) {
            throw new CoolException("路径回溯超出安全上限,疑似存在父链循环");
        }
        Collections.reverse(list);
        //将每个节点里面的fatherNode至为null(方便后续计算时父节点过多导致显示的节点太多)
        for (NavigateNode navigateNode : list) {
            //父节点设置为null,不影响计算结果,不影响后续操作。
            //此操作仅为后续排查处理提供视觉方便。
            navigateNode.setFather(null);
        }
 
        //去重
        HashSet<Integer> set = new HashSet<>();
        List<NavigateNode> fitlerList = new ArrayList<>();
        for(NavigateNode navigateNode : list){
            JSONObject valuObject = JSON.parseObject(navigateNode.getNodeValue());
            if(set.add(valuObject.getInteger("stationId"))){
                fitlerList.add(navigateNode);
            }
        }
 
        return fitlerList;
    }
 
}