From 08e3da6fe3a222296bde614f74322ecbe92c970d Mon Sep 17 00:00:00 2001 From: glax Date: Thu, 13 Apr 2023 01:00:56 +0200 Subject: [PATCH] Render result to png after every routing --- Pathfinding/Pathfinder.cs | 10 +++++- Pathfinding/Pathfinding.csproj | 1 + RenderPath/RenderPath.csproj | 8 ++--- RenderPath/Renderer.cs | 61 ++++++++++++++++++++++++++-------- Server/Server.cs | 1 - 5 files changed, 61 insertions(+), 20 deletions(-) diff --git a/Pathfinding/Pathfinder.cs b/Pathfinding/Pathfinder.cs index 0c4eca8..258f503 100644 --- a/Pathfinding/Pathfinder.cs +++ b/Pathfinding/Pathfinder.cs @@ -1,5 +1,6 @@ using OSMDatastructure; using OSMDatastructure.Graph; +using RenderPath; using static OSMDatastructure.Tag; using WayType = OSMDatastructure.Tag.WayType; @@ -28,7 +29,14 @@ public static class Pathfinder { OsmNode currentNode = openSetfScore.Dequeue(); if (currentNode.Equals(goalNode)) - return GetPath(cameFromDict, goalNode, regionManager); + { + List path = GetPath(cameFromDict, goalNode, regionManager); + List coords = new(); + foreach(PathNode pn in path) + coords.Add(pn.coordinates); + Renderer.DrawLoadedNodes(gScore, coords, workingDir); + return path; + } foreach (OsmEdge edge in currentNode.edges) { diff --git a/Pathfinding/Pathfinding.csproj b/Pathfinding/Pathfinding.csproj index 32b5e92..6582717 100644 --- a/Pathfinding/Pathfinding.csproj +++ b/Pathfinding/Pathfinding.csproj @@ -8,6 +8,7 @@ + diff --git a/RenderPath/RenderPath.csproj b/RenderPath/RenderPath.csproj index 2a4d985..3aebfb5 100644 --- a/RenderPath/RenderPath.csproj +++ b/RenderPath/RenderPath.csproj @@ -6,12 +6,12 @@ enable - - - - + + + + diff --git a/RenderPath/Renderer.cs b/RenderPath/Renderer.cs index da9cdaf..a4508c3 100644 --- a/RenderPath/Renderer.cs +++ b/RenderPath/Renderer.cs @@ -1,5 +1,4 @@ using System.Diagnostics.CodeAnalysis; -using Pathfinding; using System.Drawing; using System.Drawing.Imaging; using OSMDatastructure.Graph; @@ -9,13 +8,17 @@ namespace RenderPath; public class Renderer { [SuppressMessage("Interoperability", "CA1416:Plattformkompatibilität überprüfen")] - public static Bitmap DrawFromPath(List nodes) - { - float minLat = nodes.Min(node => node.coordinates.latitude); - float minLon = nodes.Min(node => node.coordinates.longitude); - float maxLat = nodes.Max(node => node.coordinates.latitude); - float maxLon = nodes.Max(node => node.coordinates.longitude); + public static void DrawLoadedNodes(Dictionary gScoreDict, List pathCoordinates, string workingDir) + { + float minLat = gScoreDict.Min(kv => kv.Key.coordinates.latitude); + float minLon = gScoreDict.Min(kv => kv.Key.coordinates.longitude); + float maxLat = gScoreDict.Max(kv => kv.Key.coordinates.latitude); + float maxLon = gScoreDict.Max(kv => kv.Key.coordinates.longitude); + + double minWeight = gScoreDict.Min(kv => kv.Value); + double maxWeight = gScoreDict.Max(kv => kv.Value); + float latDiff = maxLat - minLat; float lonDiff = maxLon - minLon; @@ -26,21 +29,51 @@ public class Renderer int pixelsY = (int)(latDiff * scaleFactor); Bitmap ret = new Bitmap(pixelsX, pixelsY, PixelFormat.Format32bppRgb); - Graphics g = Graphics.FromImage(ret); - Pen p = new Pen(Color.Black, 2); g.Clear(Color.White); - for (int i = 0; i < nodes.Count - 1; i++) + Color start = Color.FromArgb(0, 0, 255); + Color center = Color.FromArgb(255, 255, 0); + Color end = Color.FromArgb(255, 0, 0); + + foreach (KeyValuePair kv in gScoreDict) { - Coordinates c1 = nodes[i].coordinates; - Coordinates c2 = nodes[i+1].coordinates; + double percentage = kv.Value / maxWeight; + Brush b = new SolidBrush(GradientPick(percentage, start, center, end)); + float x = (kv.Key.coordinates.longitude - minLon) * scaleFactor; + float y = (maxLat - kv.Key.coordinates.latitude) * scaleFactor; + g.FillEllipse(b, x, y, 4, 4); + } + + Pen p = new Pen(Color.Red, 2); + + for (int i = 0; i < pathCoordinates.Count - 1; i++) + { + Coordinates c1 = pathCoordinates[i]; + Coordinates c2 = pathCoordinates[i+1]; Point p1 = new(Convert.ToInt32((c1.longitude - minLon) * scaleFactor), Convert.ToInt32((maxLat - c1.latitude) * scaleFactor)); Point p2 = new(Convert.ToInt32((c2.longitude - minLon) * scaleFactor), Convert.ToInt32((maxLat - c2.latitude) * scaleFactor)); g.DrawLine(p, p1, p2); } - ret.Save(@"D:\render.png", ImageFormat.Bmp); - return ret; + ret.Save(Path.Join(Directory.GetParent(workingDir)!.FullName, "routing.png"), ImageFormat.Bmp); + } + + /* + * https://stackoverflow.com/questions/55601338/get-a-color-value-within-a-gradient-based-on-a-value + */ + private static int LinearInterp(int start, int end, double percentage) => start + (int)Math.Round(percentage * (end - start)); + private static Color ColorInterp(Color start, Color end, double percentage) => + Color.FromArgb(LinearInterp(start.A, end.A, percentage), + LinearInterp(start.R, end.R, percentage), + LinearInterp(start.G, end.G, percentage), + LinearInterp(start.B, end.B, percentage)); + private static Color GradientPick(double percentage, Color Start, Color Center, Color End) { + if (percentage < 0.5) + return ColorInterp(Start, Center, percentage / 0.5); + else if (percentage == 0.5) + return Center; + else + return ColorInterp(Center, End, (percentage - 0.5)/0.5); } } \ No newline at end of file diff --git a/Server/Server.cs b/Server/Server.cs index 4ecbda9..d378dde 100644 --- a/Server/Server.cs +++ b/Server/Server.cs @@ -22,6 +22,5 @@ public class Server List result = Pathfinder.AStar("D:/stuttgart-regbez-latest", start, finish, Tag.SpeedType.car, 20, 2, 0); - RenderPath.Renderer.DrawFromPath(result); } } \ No newline at end of file