using OSMDatastructure; using OSMDatastructure.Graph; namespace Pathfinding; public static partial class Pathfinder { public static List AStarDistance(string workingDir, Coordinates start, Coordinates goal) { RegionManager regionManager = new (workingDir); ValueTuple startAndEndNode = SetupNodes(start, goal, regionManager); if (startAndEndNode.Item1 is null || startAndEndNode.Item2 is null) return new List(); OsmNode goalNode = startAndEndNode.Item2!; PriorityQueue toVisit = new(); toVisit.Enqueue(startAndEndNode.Item1, 0); bool stop = false; while (toVisit.Count > 0) { OsmNode closestNodeToGoal = toVisit.Dequeue(); foreach (OsmEdge edge in closestNodeToGoal.edges) { OsmNode? neighbor = regionManager.GetNode(edge.neighborId, edge.neighborRegion); if (neighbor is not null) { double newPotentialLength = closestNodeToGoal.currentPathLength + Utils.DistanceBetween(closestNodeToGoal, neighbor); if (newPotentialLength < neighbor.currentPathLength) { neighbor.previousPathNode = closestNodeToGoal; neighbor.currentPathLength = newPotentialLength; neighbor.currentPathWeight = closestNodeToGoal.currentPathWeight + EdgeWeight(closestNodeToGoal, edge, Tag.SpeedType.road, regionManager); neighbor.directDistanceToGoal = Utils.DistanceBetween(neighbor, goalNode); if (neighbor.Equals(goalNode)) { stop = true; } else if(!stop) { toVisit.Enqueue(neighbor, neighbor.directDistanceToGoal); } } } } } List path = new(); OsmNode? currentNode = goalNode; while (currentNode is not null) { path.Add(PathNode.FromOsmNode(currentNode)!); currentNode = currentNode.previousPathNode; } path.Reverse(); return path; } }