Compare commits

..

No commits in common. "95c0088b73c306af36808bb4f802823af527ec9d" and "b87d8a03002243c9d1a8e332e108d39309255be6" have entirely different histories.

12 changed files with 162 additions and 292 deletions

View File

@ -1,3 +1,4 @@
using System.Text.Json.Serialization;
using OSMDatastructure; using OSMDatastructure;
using OSMDatastructure.Graph; using OSMDatastructure.Graph;
using Pathfinding; using Pathfinding;
@ -13,11 +14,11 @@ builder.Services.AddSwaggerGen();
var app = builder.Build(); var app = builder.Build();
app.MapGet("/getRoute", (float latStart, float lonStart, float latEnd, float lonEnd, Tag.SpeedType vehicle, double stayOnSameRoadPriority, double useHigherLevelRoadsPriority, double useRoadsWithLessJunctionsPriority, double angleFactor) => app.MapGet("/getRoute", (float latStart, float lonStart, float latEnd, float lonEnd, Tag.SpeedType vehicle, double stayOnSameRoadPriority, double useHigherLevelRoadsPriority, double useRoadsWithLessJunctionsPriority) =>
{ {
Pathfinder result = new Pathfinder("D:/stuttgart-regbez-latest").AStar(new Coordinates(latStart, lonStart), Pathfinder result = new Pathfinder("D:/stuttgart-regbez-latest").AStar(new Coordinates(latStart, lonStart),
new Coordinates(latEnd, lonEnd), vehicle, useHigherLevelRoadsPriority, stayOnSameRoadPriority, new Coordinates(latEnd, lonEnd), vehicle, useHigherLevelRoadsPriority, stayOnSameRoadPriority,
useRoadsWithLessJunctionsPriority, angleFactor); useRoadsWithLessJunctionsPriority);
return result.pathResult; return result.pathResult;
} }
); );
@ -26,7 +27,7 @@ app.MapGet("/getShortestRoute", (float latStart, float lonStart, float latEnd, f
{ {
Pathfinder result = new Pathfinder("D:/stuttgart-regbez-latest").AStar(new Coordinates(latStart, lonStart), Pathfinder result = new Pathfinder("D:/stuttgart-regbez-latest").AStar(new Coordinates(latStart, lonStart),
new Coordinates(latEnd, lonEnd), Tag.SpeedType.any, 0, 0, new Coordinates(latEnd, lonEnd), Tag.SpeedType.any, 0, 0,
0, 0); 0);
return result.pathResult; return result.pathResult;
} }
); );

View File

@ -12,15 +12,15 @@ public class OsmNode
public OsmNode(ulong nodeId, float lat, float lon) public OsmNode(ulong nodeId, float lat, float lon)
{ {
this.nodeId = nodeId; this.nodeId = nodeId;
edges = new(); this.edges = new();
coordinates = new Coordinates(lat, lon); this.coordinates = new Coordinates(lat, lon);
} }
[JsonConstructor] [JsonConstructor]
public OsmNode(ulong nodeId, Coordinates coordinates) public OsmNode(ulong nodeId, Coordinates coordinates)
{ {
this.nodeId = nodeId; this.nodeId = nodeId;
edges = new(); this.edges = new();
this.coordinates = coordinates; this.coordinates = coordinates;
} }
@ -29,8 +29,7 @@ public class OsmNode
HashSet<OsmEdge> e = edges.Where(edge => edge.neighborId == n.nodeId).ToHashSet(); HashSet<OsmEdge> e = edges.Where(edge => edge.neighborId == n.nodeId).ToHashSet();
if (e.Count > 0) if (e.Count > 0)
return e.First(); return e.First();
else return null;
return null;
} }
public override bool Equals(object? obj) public override bool Equals(object? obj)

View File

@ -47,12 +47,16 @@ public class Region
public OsmNode? GetNode(ulong id) public OsmNode? GetNode(ulong id)
{ {
return ContainsNode(id) ? nodes.First(node => node.nodeId == id) : null; if (ContainsNode(id))
return nodes.First(node => node.nodeId == id);
else return null;
} }
public OsmNode? GetNode(Coordinates coordinates) public OsmNode? GetNode(Coordinates coordinates)
{ {
return ContainsNode(coordinates) ? nodes.First(node => node.coordinates.Equals(coordinates)) : null; if (ContainsNode(coordinates))
return nodes.First(node => node.coordinates.Equals(coordinates));
else return null;
} }
} }

View File

@ -1,4 +1,5 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using OSMDatastructure.Graph;
namespace OSMDatastructure; namespace OSMDatastructure;

View File

@ -65,12 +65,12 @@ namespace OSMDatastructure
return d; return d;
} }
public static double DegreesToRadians(double deg) private static double DegreesToRadians(double deg)
{ {
return deg * Math.PI / 180.0; return deg * Math.PI / 180.0;
} }
public static double RadiansToDegrees(double rad) private static double RadiansToDegrees(double rad)
{ {
return rad * 180.0 / Math.PI; return rad * 180.0 / Math.PI;
} }

View File

@ -1,3 +1,4 @@
using System.Diagnostics.Tracing;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using OSMDatastructure; using OSMDatastructure;
using OSMDatastructure.Graph; using OSMDatastructure.Graph;

View File

@ -6,15 +6,11 @@ public class PathResult
{ {
[JsonInclude]public TimeSpan calcTime; [JsonInclude]public TimeSpan calcTime;
[JsonInclude]public List<PathNode> pathNodes; [JsonInclude]public List<PathNode> pathNodes;
[JsonInclude]public double distance;
[JsonInclude]public double weight;
[JsonConstructor] [JsonConstructor]
public PathResult(TimeSpan calcTime, List<PathNode> pathNodes, double distance, double weight) public PathResult(TimeSpan calcTime, List<PathNode> pathNodes)
{ {
this.calcTime = calcTime; this.calcTime = calcTime;
this.pathNodes = pathNodes; this.pathNodes = pathNodes;
this.distance = distance;
this.weight = weight;
} }
} }

View File

@ -2,9 +2,11 @@
using OSMDatastructure; using OSMDatastructure;
using OSMDatastructure.Graph; using OSMDatastructure.Graph;
using static OSMDatastructure.Tag; using static OSMDatastructure.Tag;
using WayType = OSMDatastructure.Tag.WayType;
namespace Pathfinding; namespace Pathfinding;
//TODO check parameters for all functions and determine global fields
public class Pathfinder public class Pathfinder
{ {
@ -12,8 +14,6 @@ public class Pathfinder
public readonly string workingDir; public readonly string workingDir;
public PathResult? pathResult; public PathResult? pathResult;
public Dictionary<OsmNode, double>? gScore; public Dictionary<OsmNode, double>? gScore;
private Dictionary<OsmNode, OsmNode>? _cameFromDict;
private SpeedType _speedType;
public Pathfinder(string workingDirectory) public Pathfinder(string workingDirectory)
{ {
@ -25,32 +25,30 @@ public class Pathfinder
public Pathfinder AStar(Coordinates startCoordinates, Coordinates goalCoordinates, public Pathfinder AStar(Coordinates startCoordinates, Coordinates goalCoordinates,
SpeedType vehicle, double heuristicRoadLevelPriority, double heuristicSameRoadPriority, SpeedType vehicle, double heuristicRoadLevelPriority, double heuristicSameRoadPriority,
double heuristicFewJunctionsPriority, double angleWeightFactor) double heuristicFewJunctionsPriority)
{ {
DateTime startCalc = DateTime.Now; DateTime startCalc = DateTime.Now;
regionManager = new RegionManager(workingDir); regionManager = new RegionManager(workingDir);
_speedType = vehicle; OsmNode? startNode = regionManager.ClosestNodeToCoordinates(startCoordinates, vehicle);
OsmNode? startNode = regionManager.ClosestNodeToCoordinates(startCoordinates, _speedType); OsmNode? goalNode = regionManager.ClosestNodeToCoordinates(goalCoordinates, vehicle);
OsmNode? goalNode = regionManager.ClosestNodeToCoordinates(goalCoordinates, _speedType);
if (startNode is null || goalNode is null) if (startNode is null || goalNode is null)
{ {
pathResult = new(DateTime.Now - startCalc, new List<PathNode>(),0 ,0); pathResult = new(DateTime.Now - startCalc, new List<PathNode>());
return this; return this;
} }
PriorityQueue<OsmNode, double> openSetfScore = new(); PriorityQueue<OsmNode, double> openSetfScore = new();
openSetfScore.Enqueue(startNode, 0); openSetfScore.Enqueue(startNode, 0);
Dictionary<OsmNode, OsmNode> cameFromDict = new();
gScore = new() { { startNode, 0 } }; gScore = new() { { startNode, 0 } };
_cameFromDict = new();
while (openSetfScore.Count > 0) while (openSetfScore.Count > 0)
{ {
OsmNode currentNode = openSetfScore.Dequeue(); OsmNode currentNode = openSetfScore.Dequeue();
if (currentNode.Equals(goalNode)) if (currentNode.Equals(goalNode))
{ {
TimeSpan calcTime = DateTime.Now - startCalc; Console.WriteLine("Path found.");
pathResult = GetPath(goalNode, calcTime); this.pathResult = GetPath(cameFromDict, goalNode, DateTime.Now - startCalc);
Console.WriteLine($"Path found. {calcTime} PathLength {pathResult.pathNodes.Count} VisitedNodes {gScore.Count} Distance {pathResult.distance} Duration {pathResult.weight}");
return this; return this;
} }
@ -60,15 +58,20 @@ public class Pathfinder
if (neighbor is not null) if (neighbor is not null)
{ {
double tentativeGScore = double tentativeGScore =
gScore[currentNode] + Weight(currentNode, neighbor, edge, angleWeightFactor); gScore[currentNode] + Weight(currentNode, neighbor, edge, vehicle);
gScore.TryAdd(neighbor, double.MaxValue); gScore.TryAdd(neighbor, double.MaxValue);
if (tentativeGScore < gScore[neighbor]) if (tentativeGScore < gScore[neighbor])
{ {
if(!_cameFromDict.TryAdd(neighbor, currentNode)) if (cameFromDict.ContainsKey(neighbor))
_cameFromDict[neighbor] = currentNode; cameFromDict[neighbor] = currentNode;
else
cameFromDict.Add(neighbor, currentNode);
if (gScore.ContainsKey(neighbor))
gScore[neighbor] = tentativeGScore; gScore[neighbor] = tentativeGScore;
double h = Heuristic(currentNode, neighbor, goalNode, edge, else
heuristicRoadLevelPriority, heuristicFewJunctionsPriority, heuristicSameRoadPriority, angleWeightFactor); gScore.Add(neighbor, tentativeGScore);
double h = Heuristic(currentNode, neighbor, goalNode, edge, vehicle,
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}"); //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); openSetfScore.Enqueue(neighbor, tentativeGScore + h);
} }
@ -76,37 +79,51 @@ public class Pathfinder
} }
} }
pathResult = new(DateTime.Now - startCalc, new List<PathNode>(),0 ,0); pathResult = new(DateTime.Now - startCalc, new List<PathNode>());
return this; return this;
} }
private double Weight(OsmNode currentNode, OsmNode neighborNode, OsmEdge edge, double angleWeightFactor) public void SaveResult(string path)
{ {
double distance = Utils.DistanceBetween(currentNode, neighborNode); FileStream fs = new (path, FileMode.CreateNew);
double speed = regionManager.GetSpeedForEdge(currentNode, edge.wayId, _speedType); JsonSerializer.Serialize(fs, pathResult, JsonSerializerOptions.Default);
fs.Dispose();
double angle = 1; Console.WriteLine($"Saved result to {path}");
if (_cameFromDict!.ContainsKey(currentNode))
{
OsmNode previousNode = _cameFromDict[currentNode];
Vector v1 = new(previousNode, currentNode);
Vector v2 = new(currentNode, neighborNode);
double nodeAngle = v1.Angle(v2);
angle = ((180 - nodeAngle) / 180) * angleWeightFactor;
}
double prio = regionManager.GetPriorityForVehicle(_speedType,edge, currentNode);
return distance / (1 + speed + angle + prio);
} }
private double Heuristic(OsmNode currentNode, OsmNode neighborNode, OsmNode goalNode, OsmEdge edge, double roadPriorityFactor, double junctionFactor, double sameRoadFactor, double nodeAngleFactor) private PathResult GetPath(Dictionary<OsmNode, OsmNode> cameFromDict, OsmNode goalNode, TimeSpan calcFinished)
{ {
double roadPriority = regionManager.GetPriorityForVehicle(_speedType, edge, currentNode) * roadPriorityFactor; List<PathNode> path = new();
if (roadPriority == 0) OsmNode currentNode = goalNode;
return double.MaxValue; while (cameFromDict.ContainsKey(cameFromDict[currentNode]))
{
OsmEdge? currentEdge = cameFromDict[currentNode].edges.First(edge => edge.neighborId == currentNode.nodeId);
HashSet<Tag>? tags =
regionManager.GetRegion(currentNode.coordinates)!.tagManager.GetTagsForWayId(currentEdge.wayId);
PathNode? newNode = PathNode.FromOsmNode(currentNode, tags);
if(newNode is not null)
path.Add(newNode);
currentNode = cameFromDict[currentNode];
}
double speed = regionManager.GetSpeedForEdge(currentNode, edge.wayId, _speedType) * 0.0003; path.Reverse();
TagManager curTags = regionManager.GetRegion(currentNode.coordinates)!.tagManager; return new PathResult(calcFinished, path);
}
private double Weight(OsmNode fromNode, OsmNode neighborNode, OsmEdge edge, SpeedType vehicle)
{
double distance = Utils.DistanceBetween(fromNode, neighborNode);
double speed = regionManager.GetSpeedForEdge(fromNode, edge.wayId, vehicle);
//double prio = GetPriorityVehicleRoad(edge, vehicle, regionManager.GetRegion(fromNode.coordinates)!);
return distance / speed;
}
private double Heuristic(OsmNode fromNode, OsmNode neighborNode, OsmNode goalNode, OsmEdge edge, SpeedType vehicle, double roadPriorityFactor, double junctionFactor, double sameRoadFactor)
{
double roadPriority = GetPriorityVehicleRoad(edge, vehicle, regionManager.GetRegion(fromNode.coordinates)!) * roadPriorityFactor;
TagManager curTags = regionManager.GetRegion(fromNode.coordinates)!.tagManager;
TagManager nextTags = regionManager.GetRegion(neighborNode.coordinates)!.tagManager; TagManager nextTags = regionManager.GetRegion(neighborNode.coordinates)!.tagManager;
bool sameName = false; bool sameName = false;
@ -125,82 +142,70 @@ public class Pathfinder
double junctionCount = (neighborNode.edges.Count > 2 ? 0 : 1) * junctionFactor; double junctionCount = (neighborNode.edges.Count > 2 ? 0 : 1) * junctionFactor;
double angle = 0; return Utils.DistanceBetween(neighborNode, goalNode) / (1 + roadPriority + sameRoadName + junctionCount);
if (_cameFromDict!.ContainsKey(currentNode))
{
OsmNode previousNode = _cameFromDict[currentNode];
Vector v1 = new(previousNode, currentNode);
Vector v2 = new(currentNode, neighborNode);
double nodeAngle = v1.Angle(v2);
angle = ((180 - nodeAngle) / 180) * nodeAngleFactor;
}
return Utils.DistanceBetween(neighborNode, goalNode) / (roadPriority + sameRoadName + junctionCount + angle);
} }
public void SaveResult(string path) private static double GetPriorityVehicleRoad(OsmEdge edge, SpeedType vehicle, Region region)
{ {
FileStream fs = new (path, FileMode.CreateNew); if (vehicle == SpeedType.any)
JsonSerializer.Serialize(fs, pathResult, JsonSerializerOptions.Default); return 1;
fs.Dispose(); WayType? wayType = (WayType?)region.tagManager.GetTag(edge.wayId, TagType.highway);
Console.WriteLine($"Saved result to {path}"); if(wayType is null)
return 0;
if (vehicle == SpeedType.car)
{
switch (wayType)
{
case WayType.motorway:
case WayType.motorway_link:
case WayType.motorroad:
case WayType.trunk:
case WayType.trunk_link:
case WayType.primary:
case WayType.primary_link:
return 10;
case WayType.secondary:
case WayType.secondary_link:
return 7;
case WayType.tertiary:
case WayType.tertiary_link:
return 5;
case WayType.unclassified:
case WayType.residential:
case WayType.road:
case WayType.living_street:
return 2;
case WayType.service:
case WayType.track:
return 0.0001;
}
}
if (vehicle == SpeedType.pedestrian)
{
switch (wayType)
{
case WayType.pedestrian:
case WayType.corridor:
case WayType.footway:
case WayType.path:
case WayType.steps:
case WayType.residential:
case WayType.living_street:
return 10;
case WayType.service:
case WayType.cycleway:
case WayType.bridleway:
case WayType.road:
case WayType.track:
case WayType.unclassified:
return 5;
case WayType.tertiary:
case WayType.tertiary_link:
case WayType.escape:
return 2;
}
} }
private PathResult GetPath(OsmNode goalNode, TimeSpan calcFinished) return 0.01;
{
List<PathNode> path = new();
OsmNode currentNode = goalNode;
double retDistance = 0;
double weight = 0;
while (_cameFromDict!.ContainsKey(_cameFromDict[currentNode]))
{
OsmEdge? currentEdge = _cameFromDict[currentNode].edges.FirstOrDefault(edge => edge.neighborId == currentNode.nodeId);
HashSet<Tag>? tags =
regionManager.GetRegion(currentNode.coordinates)!.tagManager.GetTagsForWayId(currentEdge!.wayId);
PathNode? newNode = PathNode.FromOsmNode(currentNode, tags);
if(newNode is not null)
path.Add(newNode);
double distance = Utils.DistanceBetween(currentNode, _cameFromDict[currentNode]);
retDistance += distance;
weight += regionManager.GetSpeedForEdge(_cameFromDict[currentNode], currentEdge.wayId, _speedType);
currentNode = _cameFromDict[currentNode];
}
path.Reverse();
return new PathResult(calcFinished, path, retDistance, retDistance / (weight / path.Count));
}
private class Vector
{
public readonly float x, y;
public Vector(float x, float y)
{
this.x = x;
this.y = y;
}
public Vector(OsmNode n1, OsmNode n2)
{
this.x = n1.coordinates.longitude - n2.coordinates.longitude;
this.y = n1.coordinates.latitude - n2.coordinates.latitude;
}
public double Angle(Vector v2)
{
return Angle(this, v2);
}
public static double Angle(Vector v1, Vector v2)
{
double dotProd = v1.x * v2.x + v1.y * v2.y;
double v1L = Math.Sqrt(v1.x * v1.x + v1.y * v1.y);
double v2L = Math.Sqrt(v2.x * v2.x + v2.y * v2.y);
double ang = Math.Acos(dotProd / (v1L * v2L));
double angle = Utils.RadiansToDegrees(ang);
return angle;
}
} }
} }

View File

@ -1,8 +1,6 @@
using System.Text.Json; using System.Text.Json;
using OSMDatastructure; using OSMDatastructure;
using OSMDatastructure.Graph; using OSMDatastructure.Graph;
using SpeedType = OSMDatastructure.Tag.SpeedType;
using WayType = OSMDatastructure.Tag.WayType;
namespace Pathfinding namespace Pathfinding
{ {
@ -25,26 +23,29 @@ namespace Pathfinding
{ {
if(_regions.TryGetValue(id, out Region? value)) if(_regions.TryGetValue(id, out Region? value))
return value; return value;
else
{
Region? loadedRegion = RegionFromId(id); Region? loadedRegion = RegionFromId(id);
if(loadedRegion is not null) if(loadedRegion is not null)
_regions.Add(loadedRegion!.regionHash, value: loadedRegion); _regions.Add(loadedRegion!.regionHash, value: loadedRegion);
return loadedRegion; return loadedRegion;
} }
}
public Region[] GetAllRegions() public Region[] GetAllRegions()
{ {
return _regions.Values.ToArray(); return this._regions.Values.ToArray();
} }
private Region? RegionFromFile(string filePath) private Region? RegionFromFile(string filePath)
{ {
if (!File.Exists(filePath)) Region? retRegion = null;
return null; if (File.Exists(filePath))
{
FileStream regionFile = new (filePath, FileMode.Open, FileAccess.Read, FileShare.Read); FileStream regionFile = new FileStream(filePath, FileMode.Open);
Region retRegion = JsonSerializer.Deserialize<Region>(regionFile, Region.serializerOptions)!; retRegion = JsonSerializer.Deserialize<Region>(regionFile, Region.serializerOptions)!;
regionFile.Dispose(); regionFile.Dispose();
}
return retRegion; return retRegion;
} }
@ -130,69 +131,5 @@ namespace Pathfinding
return 0; return 0;
} }
} }
public double GetPriorityForVehicle(SpeedType speedType, OsmEdge edge, OsmNode node)
{
if (speedType == SpeedType.any)
return 1;
Region region = GetRegion(node.coordinates)!;
WayType? wayType = (WayType?)region.tagManager.GetTag(edge.wayId, Tag.TagType.highway);
if(wayType is null)
return 0;
if (speedType == SpeedType.car)
{
switch (wayType)
{
case WayType.motorway:
case WayType.motorway_link:
case WayType.motorroad:
return 17;
case WayType.trunk:
case WayType.trunk_link:
case WayType.primary:
case WayType.primary_link:
return 10;
case WayType.secondary:
case WayType.secondary_link:
return 7;
case WayType.tertiary:
case WayType.tertiary_link:
return 5;
case WayType.unclassified:
case WayType.residential:
case WayType.road:
case WayType.living_street:
return 2;
}
}
if (speedType == SpeedType.pedestrian)
{
switch (wayType)
{
case WayType.pedestrian:
case WayType.corridor:
case WayType.footway:
case WayType.path:
case WayType.steps:
case WayType.residential:
case WayType.living_street:
return 10;
case WayType.service:
case WayType.cycleway:
case WayType.bridleway:
case WayType.road:
case WayType.track:
case WayType.unclassified:
return 5;
case WayType.tertiary:
case WayType.tertiary_link:
case WayType.escape:
return 2;
}
}
return 0;
}
} }
} }

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;
using OSMDatastructure.Graph; using OSMDatastructure.Graph;
using Pathfinding; using Pathfinding;
@ -44,7 +45,7 @@ public static class Renderer
[SuppressMessage("Interoperability", "CA1416:Plattformkompatibilität überprüfen")] [SuppressMessage("Interoperability", "CA1416:Plattformkompatibilität überprüfen")]
public static ValueTuple<Image, Bounds> DrawArea(RegionManager rm) public static ValueTuple<Image, Bounds> DrawArea(RegionManager rm)
{ {
HashSet<OsmNode> nodes = new(); HashSet<OsmNode> nodes = new HashSet<OsmNode>();
foreach (OSMDatastructure.Region r in rm.GetAllRegions()) foreach (OSMDatastructure.Region r in rm.GetAllRegions())
nodes = nodes.Concat(r.nodes).ToHashSet(); nodes = nodes.Concat(r.nodes).ToHashSet();
@ -78,7 +79,7 @@ public static class Renderer
OsmNode nNode = rm.GetNode(edge.neighborId, edge.neighborRegion)!; OsmNode nNode = rm.GetNode(edge.neighborId, edge.neighborRegion)!;
Coordinates c2 = nNode.coordinates; Coordinates c2 = nNode.coordinates;
Pen p = new(GradientPick(0, start, center, end), PenThickness); Pen p = new Pen(GradientPick(0, start, center, end), PenThickness);
float x1 = (c1.longitude - minLon) * scaleFactor; float x1 = (c1.longitude - minLon) * scaleFactor;
float y1 = (maxLat - c1.latitude) * scaleFactor; float y1 = (maxLat - c1.latitude) * scaleFactor;
float x2 = (c2.longitude - minLon) * scaleFactor; float x2 = (c2.longitude - minLon) * scaleFactor;

View File

@ -1,3 +1,4 @@
using System.Globalization;
using System.Text; using System.Text;
namespace Server; namespace Server;

View File

@ -4,7 +4,6 @@ using OSMDatastructure;
using OSMDatastructure.Graph; using OSMDatastructure.Graph;
using Pathfinding; using Pathfinding;
using RenderPath; using RenderPath;
using Region = OSMDatastructure.Region;
namespace Server; namespace Server;
@ -25,93 +24,18 @@ public class Server
Coordinates start = new (48.7933798f, 9.8275859f); Coordinates start = new (48.7933798f, 9.8275859f);
Coordinates finish = new (48.795918f, 9.021618f); Coordinates finish = new (48.795918f, 9.021618f);
Pathfinder result = new Pathfinder(workingDir).AStar(start,
TestVariables(workingDir, start, finish); finish, Tag.SpeedType.car, 0.01, 0.0001,
0);
string parentFolder = new DirectoryInfo(workingDir).Parent!.FullName; string parentFolder = new DirectoryInfo(workingDir).Parent!.FullName;
string resultFileName = $"{new DirectoryInfo(workingDir).Name}-{DateTime.Now.ToFileTime()}.result";
/*
Console.WriteLine("Preparing BaseRender");
RegionManager allRegions = new(workingDir);
for (float lat = 48.78f - Region.RegionSize / 2; lat < 48.87f + Region.RegionSize / 2; lat += Region.RegionSize / 2)
{
for (float lon = 9f - Region.RegionSize / 2; lon < 9.9f + Region.RegionSize / 2; lon += Region.RegionSize / 2)
{
allRegions.GetRegion(new Coordinates(lat, lon));
}
}
Console.WriteLine("Regions Loaded. Rendering.");
ValueTuple<Image, Renderer.Bounds> baseRender = Renderer.DrawArea(allRegions);
*/
/*
Pathfinder result = new Pathfinder(workingDir).AStar(start,
finish, Tag.SpeedType.car, 0.034, 0.012,
0, 0.18);
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)); result.SaveResult(Path.Join(parentFolder, resultFileName));
string renderFileName = $"{new DirectoryInfo(workingDir).Name}-{fileName}.render.png"; string renderFileName = $"{new DirectoryInfo(workingDir).Name}-{DateTime.Now.ToFileTime()}.render.png";
Image render = Renderer.DrawPathfinder(result); Image render = Renderer.DrawPathfinder(result);
#pragma warning disable CA1416 #pragma warning disable CA1416
render.Save(Path.Join(parentFolder, renderFileName), ImageFormat.Png); render.Save(Path.Join(parentFolder, renderFileName), ImageFormat.Png);
#pragma warning restore CA1416*/ #pragma warning restore CA1416
}
private static void TestVariables(string workingDir, Coordinates start, Coordinates finish)
{
string parentFolder = new DirectoryInfo(workingDir).Parent!.FullName;
Queue<Thread> CalcThreads = new();
for (double sameRoadPriority = 0.002; sameRoadPriority < 0.4; sameRoadPriority += 0.02)
{
for (double roadLevelPriority = 0.4; roadLevelPriority > 0; roadLevelPriority -= 0.02)
{
for (double angleWeightFactor = 0.01; angleWeightFactor < 0.25; angleWeightFactor += 0.01)
{
double priority = roadLevelPriority;
double roadPriority = sameRoadPriority;
double factor = angleWeightFactor;
CalcThreads.Enqueue(new Thread(() =>
{
Pathfinder testresult = new Pathfinder(workingDir).AStar(start,
finish, Tag.SpeedType.car, priority, roadPriority,
0, factor);
string fileName =
$"angle{factor:0.000}_level{priority:0.000}_same{roadPriority:0.000}.result";
testresult.SaveResult(Path.Join(parentFolder, fileName));
}));
}
}
}
int totalTasks = CalcThreads.Count;
int completed = 0;
DateTime startTime = DateTime.Now;
HashSet<Thread> runningThreads = new();
while (CalcThreads.Count > 0)
{
while (runningThreads.Count < 16 && CalcThreads.Count > 0)
{
Thread t = CalcThreads.Dequeue();
runningThreads.Add(t);
t.Start();
}
int newCompleted = runningThreads.RemoveWhere(thread => !thread.IsAlive);
completed += newCompleted;
if(newCompleted > 0)
Console.WriteLine($"To calculate: {CalcThreads.Count}/{totalTasks} Average Time: {(DateTime.Now - startTime)/(completed)} Elapsed: {DateTime.Now - startTime} Remaining: {(DateTime.Now - startTime)/(completed)*CalcThreads.Count}");
}
} }
} }