using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Drawing.Imaging; using System.Text.Json; using OSMDatastructure; using OSMDatastructure.Graph; using Pathfinding; using RenderPath; using Region = OSMDatastructure.Region; namespace Server; public class Server { [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")] public static void Main(string[] args) { ConsoleWriter newConsole = new(); Console.SetOut(newConsole); Console.SetError(newConsole); string workingDir = "D:/stuttgart-regbez-latest"; //RegionConverter.ConvertXMLToRegions("D:/stuttgart-regbez-latest.osm", "D:/stuttgart-regbez-latest"); //RegionConverter.ConvertXMLToRegions("D:/map.osm", "D:/map"); //RegionConverter.ConvertXMLToRegions("D:/germany-latest.osm", "D:/germany-latest"); Coordinates start = new (48.7933798f, 9.8275859f); Coordinates finish = new (48.795918f, 9.021618f); Pathfinder result = new Pathfinder(workingDir, 2, 30).AStar(start, finish, Tag.SpeedType.car, 1); Renderer image = Renderer.DrawPathfinder(result, Renderer.RenderType.png); image.Save("D:/stuttgart-regbez-latest"); /* if(File.Exists(@"D:\bounds")) File.Delete(@"D:\bounds"); RegionManager rm = LoadRegions(workingDir, start, finish); Renderer areaRender = Renderer.DrawArea(rm, Renderer.RenderType.PNG); FileStream s = new(@"D:\bounds", FileMode.OpenOrCreate); JsonSerializer.Serialize(s, areaRender.bounds, JsonSerializerOptions.Default); areaRender.Save(@"D:\Base"); s.Dispose(); */ //TestVariables(workingDir, start, finish, 12); //GetShortestRoute("D:"); /* string parentFolder = new DirectoryInfo(workingDir).Parent!.FullName; Renderer.Bounds bounds = JsonSerializer.Deserialize(new FileStream(@"D:\bounds", FileMode.Open)); Image baseImage = Image.FromFile(@"D:\Base.png"); Pathfinder result = new Pathfinder(workingDir, 2, 30).AStar(start, finish, Tag.SpeedType.car, 4); Console.WriteLine($"Calc-time {result.pathResult!.calcTime} Path-length: {result.pathResult.pathNodes.Count} Visited-nodes: {result.gScore!.Count}"); string fileName = DateTime.Now.ToFileTime().ToString(); string resultFileName = $"{new DirectoryInfo(workingDir).Name}-{fileName}.result"; result.SaveResult(Path.Join(parentFolder, resultFileName)); string renderFileName = $"{new DirectoryInfo(workingDir).Name}-{fileName}.render.png"; Image renderWeights = Renderer.DrawGScores(result.gScore, baseImage, bounds).Item1; Image render = Renderer.DrawPath(result.pathResult, renderWeights, bounds).Item1; render.Save(Path.Join(parentFolder, renderFileName), ImageFormat.Png); */ Console.Beep(400, 50); Console.Beep(600, 50); Console.Beep(400, 50); Console.Beep(600, 50); } private static void GetShortestRoute(string directory) { DateTime start = DateTime.Now; HashSet allFiles = Directory.GetFiles(directory).Where(file => file.EndsWith(".result")).ToHashSet(); Dictionary results = new(); int loaded = 0; foreach (string filePath in allFiles) { PathResult result = PathResult.PathresultFromFile(filePath); results.Add(result, filePath); Console.WriteLine($"{loaded++}/{allFiles.Count()} {filePath} " + $"Time elapsed: {DateTime.Now - start} " + $"Remaining {((DateTime.Now - start)/loaded)*(allFiles.Count-loaded)}"); } KeyValuePair shortest = results.MinBy(result => result.Key.distance); KeyValuePair fastest = results.MinBy(result => result.Key.weight); KeyValuePair calcTime = results.MinBy(result => result.Key.calcTime); Console.WriteLine($"\nShortest:\t{shortest.Key.distance:0.0} {shortest.Key.weight:0.00} {shortest.Key.calcTime} {shortest.Value}\n" + $"Fastest:\t{fastest.Key.distance:0.0} {fastest.Key.weight:0.00} {fastest.Key.calcTime} {fastest.Value}\n" + $"CalcTime:\t{calcTime.Key.distance:0.0} {calcTime.Key.weight:0.00} {calcTime.Key.calcTime} {calcTime.Value}"); } private static RegionManager LoadRegions(string workingDir, Coordinates c1, Coordinates c2) { float minLat = c1.latitude < c2.latitude ? c1.latitude : c2.latitude; float minLon = c1.longitude < c2.longitude ? c1.longitude : c2.longitude; float maxLat = c1.latitude > c2.latitude ? c1.latitude : c2.latitude; float maxLon = c1.longitude > c2.longitude ? c1.longitude : c2.longitude; RegionManager allRegions = new(workingDir); for (float lat = minLat - Region.RegionSize * 3; lat < maxLat + Region.RegionSize * 3; lat += Region.RegionSize / 2) { for (float lon = minLon - Region.RegionSize; lon < maxLon + Region.RegionSize; lon += Region.RegionSize / 2) { allRegions.GetRegion(new Coordinates(lat, lon)); } } Console.WriteLine("Loaded needed Regions"); return allRegions; } [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")] private static void TestVariables(string workingDir, Coordinates start, Coordinates finish, int threads) { string parentFolder = new DirectoryInfo(workingDir).Parent!.FullName; RegionManager rm = LoadRegions(workingDir, start, finish); Queue calcThreads = new(); Bounds bounds = JsonSerializer.Deserialize(new FileStream(@"D:\bounds", FileMode.Open))!; for (double extraTime = 1.5; extraTime >= 1; extraTime -= 0.25) { for (double roadFactor = 0.05; roadFactor < 5; roadFactor += 0.05) { double road = roadFactor; double time = extraTime; calcThreads.Enqueue(new Thread(() => { Pathfinder testresult = new Pathfinder(workingDir, road, 30).AStar(start, finish, Tag.SpeedType.car, time); Image baseImage = Image.FromStream(new FileStream(@"D:\Base.png", FileMode.Open, FileAccess.Read, FileShare.Read, (int)new FileInfo(@"D:\Base.png").Length, FileOptions.Asynchronous)); Renderer renderer = new PNGRenderer(baseImage); renderer.bounds = bounds; Renderer renderWeights = Renderer.DrawGScores(testresult.gScore!, Renderer.RenderType.png, renderer); Renderer render = Renderer.DrawPath(testresult.pathResult!, Renderer.RenderType.png, renderWeights); string fileName = $"road{road:0.00}_time{time:0.00}"; string resultFileName = Path.Combine("D:", $"{fileName}.result"); testresult.SaveResult(resultFileName); string imageFileName = Path.Combine("D:", fileName); render.Save(imageFileName); Console.WriteLine($"Saved {fileName}"); })); } } int totalTasks = calcThreads.Count; int completedTasks = 0; DateTime startTime = DateTime.Now; HashSet runningThreads = new(); Console.WriteLine($"Running {threads} Threads on {totalTasks} Tasks."); while (calcThreads.Count > 0 || runningThreads.Count > 0) { while (runningThreads.Count < threads && calcThreads.Count > 0) { Thread t = calcThreads.Dequeue(); runningThreads.Add(t); t.Start(); } int newCompletedTasks = runningThreads.RemoveWhere(thread => !thread.IsAlive); completedTasks += newCompletedTasks; if (newCompletedTasks > 0) { TimeSpan elapsedTime = DateTime.Now - startTime; Console.WriteLine($"To calculate: {calcThreads.Count}(+{runningThreads.Count} running)/{totalTasks} Time Average: {(elapsedTime/completedTasks)} Elapsed: {elapsedTime} Remaining: {(elapsedTime/completedTasks*calcThreads.Count)}"); } } } }