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) =>
{
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;
}
);
@ -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) =>
{
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;
}
);

View File

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

View File

@ -31,7 +31,7 @@ public class Pathfinder
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;
_speedType = vehicle;
@ -62,15 +62,12 @@ public class Pathfinder
{
firstFound = DateTime.Now - startCalc;
found = true;
Console.WriteLine($"First: {firstFound} Multiplied by {extraTime}: {firstFound.Multiply(extraTime)}");
}
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;
foreach (OsmEdge edge in currentNode.edges)

View File

@ -33,4 +33,19 @@ public class RPriorityQueue<TKey, TPriority> where TKey : notnull
Count = queue.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)
{
if (!File.Exists(filePath))
{
throw new FileNotFoundException(filePath);
return null;
}
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)!;
@ -151,7 +154,7 @@ namespace Pathfinding
case WayType.motorway:
case WayType.motorway_link:
case WayType.motorroad:
return 17;
return 20;
case WayType.trunk:
case WayType.trunk_link:
case WayType.primary:
@ -159,10 +162,9 @@ namespace Pathfinding
return 10;
case WayType.secondary:
case WayType.secondary_link:
return 7;
case WayType.tertiary:
case WayType.tertiary_link:
return 5;
return 6;
case WayType.unclassified:
case WayType.residential:
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.Drawing;
using System.Drawing.Imaging;
using System.Text.Json.Serialization;
using OSMDatastructure;
using OSMDatastructure.Graph;
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 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")]
public static Image DrawPathfinder(Pathfinder pathfinder)
{
@ -71,7 +59,7 @@ public static class Renderer
{
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;
OsmNode nNode = rm.GetNode(edge.neighborId, edge.neighborRegion)!;
Coordinates c2 = nNode.coordinates;

View File

@ -44,9 +44,8 @@ public class Server
/*
string parentFolder = new DirectoryInfo(workingDir).Parent!.FullName;
Pathfinder result = new Pathfinder(workingDir, 0.002, 0,
0, 1, 30).AStar(start,
finish, Tag.SpeedType.car);
Pathfinder result = new Pathfinder(workingDir, 0.0215, 30).AStar(start,
finish, Tag.SpeedType.car, 3);
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;
HashSet<string> allFiles = Directory.GetFiles(directory).Where(file => file.EndsWith(".result")).ToHashSet();
PathResult first = PathResult.PathresultFromFile(allFiles.First());
KeyValuePair<PathResult, string> shortest = new(first, allFiles.First());
KeyValuePair<PathResult, string> fastest = new(first, allFiles.First());
KeyValuePair<PathResult, string> calcTime = new(first, allFiles.First());
Dictionary<PathResult, string> 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)}");
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" +
$"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}");
@ -119,20 +112,16 @@ public class Server
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;
calcThreads.Enqueue(new Thread(() =>
{
double priority = roadLevelPriority;
double angle = maxAngle;
calcThreads.Enqueue(new Thread(() =>
{
Pathfinder testresult = new Pathfinder(rm, priority, angle).AStar(start,
finish, Tag.SpeedType.car);
string fileName = $"angle{angle:00}_level{priority:0.0000}.result";
testresult.SaveResult(Path.Join(parentFolder, fileName));
}));
}
Pathfinder testresult = new Pathfinder(workingDir, 0.0215, 30).AStar(start,
finish, Tag.SpeedType.car, time);
string fileName = $"time{time:0}.result";
testresult.SaveResult(Path.Join(parentFolder, fileName));
}));
}
int totalTasks = calcThreads.Count;
@ -154,7 +143,7 @@ public class Server
if (newCompletedTasks > 0)
{
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)}");
}
}
}