Compare commits

...

15 Commits

8 changed files with 82 additions and 57 deletions

View File

@ -16,7 +16,7 @@ var app = builder.Build();
app.MapGet("/getRoute", (float latStart, float lonStart, float latEnd, float lonEnd, Tag.SpeedType vehicle, double useHigherLevelRoadsPriority, double maxTurnAngle) => app.MapGet("/getRoute", (float latStart, float lonStart, float latEnd, float lonEnd, Tag.SpeedType vehicle, double useHigherLevelRoadsPriority, double maxTurnAngle) =>
{ {
Pathfinder result = new Pathfinder("D:/stuttgart-regbez-latest", useHigherLevelRoadsPriority, maxTurnAngle).AStar(new Coordinates(latStart, lonStart), Pathfinder result = new Pathfinder("D:/stuttgart-regbez-latest", useHigherLevelRoadsPriority, maxTurnAngle).AStar(new Coordinates(latStart, lonStart),
new Coordinates(latEnd, lonEnd), vehicle); new Coordinates(latEnd, lonEnd), vehicle, 3);
return result.pathResult; return result.pathResult;
} }
); );
@ -24,7 +24,7 @@ app.MapGet("/getRoute", (float latStart, float lonStart, float latEnd, float lon
app.MapGet("/getShortestRoute", (float latStart, float lonStart, float latEnd, float lonEnd) => app.MapGet("/getShortestRoute", (float latStart, float lonStart, float latEnd, float lonEnd) =>
{ {
Pathfinder result = new Pathfinder("D:/stuttgart-regbez-latest", 0, 30).AStar(new Coordinates(latStart, lonStart), Pathfinder result = new Pathfinder("D:/stuttgart-regbez-latest", 0, 30).AStar(new Coordinates(latStart, lonStart),
new Coordinates(latEnd, lonEnd), Tag.SpeedType.any); new Coordinates(latEnd, lonEnd), Tag.SpeedType.any, 3);
return result.pathResult; return result.pathResult;
} }
); );

View File

@ -61,6 +61,7 @@ public class Tag
} }
break; break;
case "maxspeed": case "maxspeed":
case "maxspeed:max":
try try
{ {
byte speed = Convert.ToByte(value); byte speed = Convert.ToByte(value);
@ -111,8 +112,8 @@ public class Tag
public static readonly Dictionary<WayType, byte> defaultSpeedCar = new() { public static readonly Dictionary<WayType, byte> defaultSpeedCar = new() {
{ WayType.NONE, 0 }, { WayType.NONE, 0 },
{ WayType.motorway, 100 }, { WayType.motorway, 130 },
{ WayType.motorroad, 90 }, { WayType.motorroad, 100 },
{ WayType.trunk, 85 }, { WayType.trunk, 85 },
{ WayType.primary, 65 }, { WayType.primary, 65 },
{ WayType.secondary, 60 }, { WayType.secondary, 60 },

View File

@ -31,7 +31,7 @@ public class Pathfinder
this.turnAngle = turnAngle; this.turnAngle = turnAngle;
} }
public Pathfinder AStar(Coordinates startCoordinates, Coordinates goalCoordinates, SpeedType vehicle) public Pathfinder AStar(Coordinates startCoordinates, Coordinates goalCoordinates, SpeedType vehicle, double extraTime)
{ {
DateTime startCalc = DateTime.Now; DateTime startCalc = DateTime.Now;
_speedType = vehicle; _speedType = vehicle;
@ -62,15 +62,12 @@ public class Pathfinder
{ {
firstFound = DateTime.Now - startCalc; firstFound = DateTime.Now - startCalc;
found = true; found = true;
Console.WriteLine($"First: {firstFound} Multiplied by {extraTime}: {firstFound.Multiply(extraTime)}");
} }
maxGscore = gScore[goalNode]; maxGscore = gScore[goalNode];
/*
int removed = openSetfScore.Remove(gScore.Where(item => item.Value > maxGscore)
.ToDictionary(item => item.Key, item => item.Value).Keys);
Console.WriteLine($"Removed {removed}");*/
} }
if (found && DateTime.Now - startCalc > firstFound.Multiply(2)) if (found && DateTime.Now - startCalc > firstFound.Multiply(extraTime))
stop = true; stop = true;
foreach (OsmEdge edge in currentNode.edges) foreach (OsmEdge edge in currentNode.edges)

View File

@ -33,4 +33,19 @@ public class RPriorityQueue<TKey, TPriority> where TKey : notnull
Count = queue.Count; Count = queue.Count;
return before - Count; return before - Count;
} }
public int RemoveExcept(IEnumerable<TKey> exceptKeys)
{
int before = Count;
queue = queue.IntersectBy(exceptKeys, item => item.Key).ToDictionary(item => item.Key, item => item.Value);
Count = queue.Count;
return before - Count;
}
public int Clear()
{
int before = Count;
queue.Clear();
return before;
}
} }

View File

@ -45,7 +45,10 @@ namespace Pathfinding
private static Region? RegionFromFile(string filePath) private static Region? RegionFromFile(string filePath)
{ {
if (!File.Exists(filePath)) if (!File.Exists(filePath))
{
throw new FileNotFoundException(filePath);
return null; return null;
}
FileStream regionFile = new (filePath, FileMode.Open, FileAccess.Read, FileShare.Read, (int)new FileInfo(filePath).Length, FileOptions.SequentialScan); FileStream regionFile = new (filePath, FileMode.Open, FileAccess.Read, FileShare.Read, (int)new FileInfo(filePath).Length, FileOptions.SequentialScan);
Region retRegion = JsonSerializer.Deserialize<Region>(regionFile, Region.serializerOptions)!; Region retRegion = JsonSerializer.Deserialize<Region>(regionFile, Region.serializerOptions)!;
@ -151,7 +154,7 @@ namespace Pathfinding
case WayType.motorway: case WayType.motorway:
case WayType.motorway_link: case WayType.motorway_link:
case WayType.motorroad: case WayType.motorroad:
return 17; return 20;
case WayType.trunk: case WayType.trunk:
case WayType.trunk_link: case WayType.trunk_link:
case WayType.primary: case WayType.primary:
@ -159,10 +162,9 @@ namespace Pathfinding
return 10; return 10;
case WayType.secondary: case WayType.secondary:
case WayType.secondary_link: case WayType.secondary_link:
return 7;
case WayType.tertiary: case WayType.tertiary:
case WayType.tertiary_link: case WayType.tertiary_link:
return 5; return 6;
case WayType.unclassified: case WayType.unclassified:
case WayType.residential: case WayType.residential:
case WayType.road: case WayType.road:

33
RenderPath/Bounds.cs Normal file
View File

@ -0,0 +1,33 @@
using System.Text.Json.Serialization;
using OSMDatastructure.Graph;
namespace RenderPath;
public class Bounds
{
[JsonInclude]public float minLat, maxLat, minLon, maxLon;
[JsonConstructor]
public Bounds(float minLat, float minLon, float maxLat, float maxLon)
{
this.minLon = minLon;
this.maxLat = maxLat;
this.maxLon = maxLon;
this.minLat = minLat;
}
public static Bounds FromCoords(float lat1, float lon1, float lat2, float lon2)
{
float minLat = lat1 < lat2 ? lat1 : lat2;
float minLon = lon1 < lon2 ? lon1 : lon2;
float maxLat = lat1 > lat2 ? lat1 : lat2;
float maxLon = lon1 > lon2 ? lon1 : lon2;
return new Bounds(minLat, minLon, maxLat, maxLon);
}
public static Bounds FromCoords(Coordinates c1, Coordinates c2)
{
return FromCoords(c1.latitude, c1.longitude, c2.latitude, c2.longitude);
}
}

View File

@ -1,6 +1,7 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Text.Json.Serialization;
using OSMDatastructure; using OSMDatastructure;
using OSMDatastructure.Graph; using OSMDatastructure.Graph;
using Pathfinding; using Pathfinding;
@ -17,19 +18,6 @@ public static class Renderer
private static readonly Color RoadPrioStart = Color.FromArgb(200, 100, 100, 100); private static readonly Color RoadPrioStart = Color.FromArgb(200, 100, 100, 100);
private static readonly Color RoadPrioEnd = Color.FromArgb(255, 255, 180, 0); private static readonly Color RoadPrioEnd = Color.FromArgb(255, 255, 180, 0);
public class Bounds
{
public readonly float minLat, maxLat, minLon, maxLon;
public Bounds(float minLat, float minLon, float maxLat, float maxLon)
{
this.minLon = minLon;
this.maxLat = maxLat;
this.maxLon = maxLon;
this.minLat = minLat;
}
}
[SuppressMessage("Interoperability", "CA1416:Plattformkompatibilität überprüfen")] [SuppressMessage("Interoperability", "CA1416:Plattformkompatibilität überprüfen")]
public static Image DrawPathfinder(Pathfinder pathfinder) public static Image DrawPathfinder(Pathfinder pathfinder)
{ {
@ -71,7 +59,7 @@ public static class Renderer
{ {
foreach (OsmEdge edge in node.edges) foreach (OsmEdge edge in node.edges)
{ {
double priority = rm.GetPriorityForVehicle(Tag.SpeedType.car, edge, node) / 17; double priority = rm.GetPriorityForVehicle(Tag.SpeedType.car, edge, node) / 20;
Coordinates c1 = node.coordinates; Coordinates c1 = node.coordinates;
OsmNode nNode = rm.GetNode(edge.neighborId, edge.neighborRegion)!; OsmNode nNode = rm.GetNode(edge.neighborId, edge.neighborRegion)!;
Coordinates c2 = nNode.coordinates; Coordinates c2 = nNode.coordinates;

View File

@ -44,9 +44,8 @@ public class Server
/* /*
string parentFolder = new DirectoryInfo(workingDir).Parent!.FullName; string parentFolder = new DirectoryInfo(workingDir).Parent!.FullName;
Pathfinder result = new Pathfinder(workingDir, 0.002, 0, Pathfinder result = new Pathfinder(workingDir, 0.0215, 30).AStar(start,
0, 1, 30).AStar(start, finish, Tag.SpeedType.car, 3);
finish, Tag.SpeedType.car);
Console.WriteLine($"Calc-time {result.pathResult!.calcTime} Path-length: {result.pathResult.pathNodes.Count} Visited-nodes: {result.gScore!.Count}"); Console.WriteLine($"Calc-time {result.pathResult!.calcTime} Path-length: {result.pathResult.pathNodes.Count} Visited-nodes: {result.gScore!.Count}");
@ -67,26 +66,20 @@ public class Server
{ {
DateTime start = DateTime.Now; DateTime start = DateTime.Now;
HashSet<string> allFiles = Directory.GetFiles(directory).Where(file => file.EndsWith(".result")).ToHashSet(); HashSet<string> allFiles = Directory.GetFiles(directory).Where(file => file.EndsWith(".result")).ToHashSet();
PathResult first = PathResult.PathresultFromFile(allFiles.First()); Dictionary<PathResult, string> results = new();
KeyValuePair<PathResult, string> shortest = new(first, allFiles.First());
KeyValuePair<PathResult, string> fastest = new(first, allFiles.First());
KeyValuePair<PathResult, string> calcTime = new(first, allFiles.First());
int loaded = 0; int loaded = 0;
foreach (string filePath in allFiles) foreach (string filePath in allFiles)
{ {
PathResult result = PathResult.PathresultFromFile(filePath); PathResult result = PathResult.PathresultFromFile(filePath);
results.Add(result, filePath);
Console.WriteLine($"{loaded++}/{allFiles.Count()} {filePath} " + Console.WriteLine($"{loaded++}/{allFiles.Count()} {filePath} " +
$"Time elapsed: {DateTime.Now - start} " + $"Time elapsed: {DateTime.Now - start} " +
$"Remaining {((DateTime.Now - start)/loaded)*(allFiles.Count-loaded)}"); $"Remaining {((DateTime.Now - start)/loaded)*(allFiles.Count-loaded)}");
if (shortest.Key.distance > result.distance)
shortest = new KeyValuePair<PathResult, string>(result, filePath);
if (fastest.Key.weight > result.weight)
fastest = new KeyValuePair<PathResult, string>(result, filePath);
if (calcTime.Key.calcTime > result.calcTime)
calcTime = new KeyValuePair<PathResult, string>(result, filePath);
} }
KeyValuePair<PathResult, string> shortest = results.MinBy(result => result.Key.distance);
KeyValuePair<PathResult, string> fastest = results.MinBy(result => result.Key.weight);
KeyValuePair<PathResult, string> 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" + 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" + $"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}"); $"CalcTime:\t{calcTime.Key.distance:0.0} {calcTime.Key.weight:0.00} {calcTime.Key.calcTime} {calcTime.Value}");
@ -119,21 +112,17 @@ public class Server
Queue<Thread> calcThreads = new(); Queue<Thread> calcThreads = new();
for (double roadLevelPriority = 0.016; roadLevelPriority < 0.02; roadLevelPriority += 0.0002) for (double extraTime = 30; extraTime > 1; extraTime -= 1)
{ {
for (double maxAngle = 25; maxAngle < 35; maxAngle += 1) double time = extraTime;
{
double priority = roadLevelPriority;
double angle = maxAngle;
calcThreads.Enqueue(new Thread(() => calcThreads.Enqueue(new Thread(() =>
{ {
Pathfinder testresult = new Pathfinder(rm, priority, angle).AStar(start, Pathfinder testresult = new Pathfinder(workingDir, 0.0215, 30).AStar(start,
finish, Tag.SpeedType.car); finish, Tag.SpeedType.car, time);
string fileName = $"angle{angle:00}_level{priority:0.0000}.result"; string fileName = $"time{time:0}.result";
testresult.SaveResult(Path.Join(parentFolder, fileName)); testresult.SaveResult(Path.Join(parentFolder, fileName));
})); }));
} }
}
int totalTasks = calcThreads.Count; int totalTasks = calcThreads.Count;
int completedTasks = 0; int completedTasks = 0;
@ -154,7 +143,7 @@ public class Server
if (newCompletedTasks > 0) if (newCompletedTasks > 0)
{ {
TimeSpan elapsedTime = DateTime.Now - startTime; TimeSpan elapsedTime = DateTime.Now - startTime;
Console.WriteLine($"To calculate: {calcThreads.Count}(+{runningThreads.Count})/{totalTasks} Time Average: {(elapsedTime)/(completedTasks)} Elapsed: {elapsedTime} Remaining: {(elapsedTime)/(completedTasks)*calcThreads.Count}"); Console.WriteLine($"To calculate: {calcThreads.Count}(+{runningThreads.Count} running)/{totalTasks} Time Average: {(elapsedTime/completedTasks)} Elapsed: {elapsedTime} Remaining: {(elapsedTime/completedTasks*calcThreads.Count)}");
} }
} }
} }