Save Pathfinding result to file.
Load result for render.
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Text.Json.Serialization;
|
||||
using OSMDatastructure;
|
||||
using OSMDatastructure.Graph;
|
||||
@ -7,6 +8,12 @@ namespace Pathfinding;
|
||||
public class PathNode : OsmNode
|
||||
{
|
||||
[JsonInclude]public Dictionary<string, string> tags = new();
|
||||
|
||||
[JsonConstructor]
|
||||
public PathNode(ulong nodeId, Coordinates coordinates, Dictionary<string, string> tags) : base(nodeId, coordinates)
|
||||
{
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public PathNode(ulong nodeId, float lat, float lon) : base(nodeId, lat, lon)
|
||||
{
|
||||
|
46
Pathfinding/PathResult.cs
Normal file
46
Pathfinding/PathResult.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using OSMDatastructure.Graph;
|
||||
|
||||
namespace Pathfinding;
|
||||
|
||||
public class PathResult
|
||||
{
|
||||
[JsonInclude]public TimeSpan calcTime;
|
||||
[JsonInclude]public List<PathNode> pathNodes;
|
||||
[JsonInclude]public Dictionary<ulong, double>? gScore;
|
||||
[JsonInclude]public HashSet<OsmNode>? nodes;
|
||||
public string? name { get; set; }
|
||||
|
||||
[JsonConstructor]
|
||||
public PathResult(TimeSpan calcTime, List<PathNode> pathNodes, Dictionary<ulong, double>? gScore, HashSet<OsmNode>? nodes)
|
||||
{
|
||||
this.calcTime = calcTime;
|
||||
this.pathNodes = pathNodes;
|
||||
this.gScore = gScore;
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
public PathResult(TimeSpan calcTime, List<PathNode> pathNodes)
|
||||
{
|
||||
this.calcTime = calcTime;
|
||||
this.pathNodes = pathNodes;
|
||||
}
|
||||
|
||||
public PathResult(TimeSpan calcTime, List<PathNode> pathNodes, Dictionary<OsmNode, double> gScore)
|
||||
{
|
||||
this.calcTime = calcTime;
|
||||
this.pathNodes = pathNodes;
|
||||
AddGScores(gScore);
|
||||
}
|
||||
|
||||
public void AddGScores(Dictionary<OsmNode, double> gScore)
|
||||
{
|
||||
this.gScore = new();
|
||||
this.nodes = new();
|
||||
foreach (KeyValuePair<OsmNode, double> kv in gScore)
|
||||
{
|
||||
this.gScore.Add(kv.Key.nodeId, kv.Value);
|
||||
this.nodes.Add(kv.Key);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using OSMDatastructure;
|
||||
using System.Text.Json;
|
||||
using OSMDatastructure;
|
||||
using OSMDatastructure.Graph;
|
||||
using RenderPath;
|
||||
using static OSMDatastructure.Tag;
|
||||
using WayType = OSMDatastructure.Tag.WayType;
|
||||
|
||||
@ -8,16 +8,17 @@ namespace Pathfinding;
|
||||
|
||||
public static class Pathfinder
|
||||
{
|
||||
|
||||
public static List<PathNode> AStar(string workingDir, Coordinates startCoordinates, Coordinates goalCoordinates,
|
||||
|
||||
public static PathResult AStar(string workingDir, Coordinates startCoordinates, Coordinates goalCoordinates,
|
||||
SpeedType vehicle, double heuristicRoadLevelPriority, double heuristicSameRoadPriority,
|
||||
double heuristicFewJunctionsPriority)
|
||||
{
|
||||
DateTime startCalc = DateTime.Now;
|
||||
RegionManager regionManager = new RegionManager(workingDir);
|
||||
OsmNode? startNode = regionManager.ClosestNodeToCoordinates(startCoordinates, vehicle);
|
||||
OsmNode? goalNode = regionManager.ClosestNodeToCoordinates(goalCoordinates, vehicle);
|
||||
if (startNode is null || goalNode is null)
|
||||
return new List<PathNode>();
|
||||
return new PathResult(DateTime.Now - startCalc, new List<PathNode>());
|
||||
|
||||
PriorityQueue<OsmNode, double> openSetfScore = new();
|
||||
openSetfScore.Enqueue(startNode, 0);
|
||||
@ -31,13 +32,12 @@ public static class Pathfinder
|
||||
if (currentNode.Equals(goalNode))
|
||||
{
|
||||
Console.WriteLine("Path found.");
|
||||
List<PathNode> path = GetPath(cameFromDict, goalNode, regionManager);
|
||||
Console.WriteLine("Rendering.");
|
||||
List<Coordinates> coords = new();
|
||||
foreach(PathNode pn in path)
|
||||
coords.Add(pn.coordinates);
|
||||
Renderer.DrawLoadedNodes(gScore, coords, workingDir);
|
||||
Console.WriteLine("Done.");
|
||||
PathResult path = GetPath(cameFromDict, goalNode, regionManager, DateTime.Now - startCalc);
|
||||
path.AddGScores(gScore);
|
||||
string fileName = $"{new DirectoryInfo(workingDir).Name}-{DateTime.Now.ToFileTime()}.result";
|
||||
string outputFilepath = Path.Join(Directory.GetParent(workingDir)!.FullName, fileName);
|
||||
path.name = outputFilepath;
|
||||
SaveGraph(path, outputFilepath);
|
||||
return path;
|
||||
}
|
||||
|
||||
@ -46,7 +46,8 @@ public static class Pathfinder
|
||||
OsmNode? neighbor = regionManager.GetNode(edge.neighborId, edge.neighborRegion);
|
||||
if (neighbor is not null)
|
||||
{
|
||||
double tentativeGScore = gScore[currentNode] + Weight(currentNode, neighbor, edge, vehicle, regionManager);
|
||||
double tentativeGScore =
|
||||
gScore[currentNode] + Weight(currentNode, neighbor, edge, vehicle, regionManager);
|
||||
gScore.TryAdd(neighbor, double.MaxValue);
|
||||
if (tentativeGScore < gScore[neighbor])
|
||||
{
|
||||
@ -62,16 +63,24 @@ public static class Pathfinder
|
||||
heuristicRoadLevelPriority, heuristicFewJunctionsPriority, heuristicSameRoadPriority);
|
||||
//Console.WriteLine($"Queue: {openSetfScore.Count:00000} Current Distance: {Utils.DistanceBetween(currentNode, goalNode):000000.00} Visited: {cameFromDict.Count:00000} Current heuristic: {h:00000.00}");
|
||||
openSetfScore.Enqueue(neighbor, tentativeGScore + h);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new List<PathNode>();
|
||||
return new PathResult(DateTime.Now - startCalc, new List<PathNode>());
|
||||
}
|
||||
|
||||
private static List<PathNode> GetPath(Dictionary<OsmNode, OsmNode> cameFromDict, OsmNode goalNode, RegionManager regionManager)
|
||||
private static void SaveGraph(PathResult pathResult, string outputFilepath)
|
||||
{
|
||||
FileStream fs = new FileStream(outputFilepath, FileMode.CreateNew);
|
||||
JsonSerializer.Serialize(fs, pathResult, JsonSerializerOptions.Default);
|
||||
fs.Dispose();
|
||||
Console.WriteLine($"Saved result to {outputFilepath}");
|
||||
}
|
||||
|
||||
private static PathResult GetPath(Dictionary<OsmNode, OsmNode> cameFromDict, OsmNode goalNode, RegionManager regionManager, TimeSpan calcFinished)
|
||||
{
|
||||
List<PathNode> path = new List<PathNode>();
|
||||
OsmNode currentNode = goalNode;
|
||||
@ -88,7 +97,7 @@ public static class Pathfinder
|
||||
|
||||
path.Reverse();
|
||||
|
||||
return path;
|
||||
return new PathResult(calcFinished, path);
|
||||
}
|
||||
|
||||
private static double Weight(OsmNode fromNode, OsmNode neighborNode, OsmEdge edge, SpeedType vehicle, RegionManager regionManager)
|
||||
|
@ -8,7 +8,10 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OSMDatastructure\OSMDatastructure.csproj" />
|
||||
<ProjectReference Include="..\RenderPath\RenderPath.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Runtime.Serialization.Json" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
Reference in New Issue
Block a user