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;
|
}
|
|
}
|