From 9ef0e421bc2c3d7aa111e5f5c1596c57b731b552 Mon Sep 17 00:00:00 2001 From: glax Date: Sun, 9 Apr 2023 16:41:42 +0200 Subject: [PATCH] Moved Pathfinding ClosestNode and SpeedCalc to RegionManager (more appropriate). Added validation if edge is valid connection for vehicle. --- API/Program.cs | 2 +- Pathfinding/Pathfinder.cs | 58 ++------------------------ Pathfinding/RegionManager.cs | 79 ++++++++++++++++++++++++++++++++---- 3 files changed, 75 insertions(+), 64 deletions(-) diff --git a/API/Program.cs b/API/Program.cs index a195c59..62a5fbc 100644 --- a/API/Program.cs +++ b/API/Program.cs @@ -27,7 +27,7 @@ app.MapGet("/getRoute", (float latStart, float lonStart, float latEnd, float lon app.MapGet("/getClosestNode", (float lat, float lon) => { RegionManager regionManager = new RegionManager("D:/stuttgart-regbez-latest"); - return Pathfinder.ClosestNodeToCoordinates(new Coordinates(lat, lon), Tag.SpeedType.car, regionManager); + return regionManager.ClosestNodeToCoordinates(new Coordinates(lat, lon), Tag.SpeedType.road); }); // Configure the HTTP request pipeline. diff --git a/Pathfinding/Pathfinder.cs b/Pathfinding/Pathfinder.cs index 8f4b917..66b2bea 100644 --- a/Pathfinding/Pathfinder.cs +++ b/Pathfinding/Pathfinder.cs @@ -9,8 +9,8 @@ public static partial class Pathfinder private static ValueTuple SetupNodes(Coordinates startCoordinates, Coordinates goalCoordinates, RegionManager regionManager ) { ValueTuple retTuple = new(); - retTuple.Item1 = ClosestNodeToCoordinates(startCoordinates, Tag.SpeedType.road, regionManager); - retTuple.Item2 = ClosestNodeToCoordinates(goalCoordinates, Tag.SpeedType.road, regionManager); + retTuple.Item1 = regionManager.ClosestNodeToCoordinates(startCoordinates, Tag.SpeedType.road); + retTuple.Item2 = regionManager.ClosestNodeToCoordinates(goalCoordinates, Tag.SpeedType.road); if (retTuple.Item1 is null || retTuple.Item2 is null) return retTuple; retTuple.Item1.currentPathWeight = 0; @@ -19,62 +19,10 @@ public static partial class Pathfinder return retTuple; } - public static OsmNode? ClosestNodeToCoordinates(Coordinates coordinates, Tag.SpeedType vehicle, RegionManager regionManager) - { - OsmNode? closest = null; - double distance = double.MaxValue; - Region? region = regionManager.GetRegion(coordinates); - if (region is null) - return null; - foreach (OsmNode node in region.nodes) - { - bool hasConnectionUsingVehicle = false; - foreach (OsmEdge edge in node.edges) - { - double speed = GetSpeedForEdge(node, edge.wayId, vehicle, regionManager); - if (speed != 0) - hasConnectionUsingVehicle = true; - } - double nodeDistance = Utils.DistanceBetween(node, coordinates); - if (nodeDistance < distance && hasConnectionUsingVehicle) - { - closest = node; - distance = nodeDistance; - } - } - - return closest; - } - - private static double GetSpeedForEdge(OsmNode node1, ulong wayId, Tag.SpeedType vehicle, RegionManager regionManager) - { - TagManager tags = regionManager.GetRegion(node1.coordinates)!.tagManager; - Tag.WayType wayType = (Tag.WayType)tags.GetTag(wayId, Tag.TagType.highway)!; - switch (vehicle) - { - case Tag.SpeedType.pedestrian: - byte speed = Tag.defaultSpeedPedestrian[wayType]; - if (speed is not 0) - return speed; - return 0; - case Tag.SpeedType.car: - case Tag.SpeedType.road: - byte? maxSpeed = (byte?)tags.GetTag(wayId, Tag.TagType.maxspeed); - if (maxSpeed is not null) - return (double)maxSpeed; - maxSpeed = Tag.defaultSpeedCar[wayType]; - if(maxSpeed is not 0) - return (byte)maxSpeed; - return 0; - default: - return 0; - } - } - private static double EdgeWeight(OsmNode node1, OsmNode node2, ulong wayId, Tag.SpeedType vehicle, ref RegionManager regionManager) { double distance = Utils.DistanceBetween(node1, node2); - double speed = GetSpeedForEdge(node1, wayId, vehicle, regionManager); + double speed = regionManager.GetSpeedForEdge(node1, wayId, vehicle); if (speed is not 0) return distance / speed; return double.PositiveInfinity; diff --git a/Pathfinding/RegionManager.cs b/Pathfinding/RegionManager.cs index 22eab6d..08e34f4 100644 --- a/Pathfinding/RegionManager.cs +++ b/Pathfinding/RegionManager.cs @@ -54,19 +54,82 @@ namespace Pathfinding string filePath = Path.Join(workingDirectory, $"{regionId}.region"); return RegionFromFile(filePath); } - - public OsmNode? GetNode(Coordinates coordinates) - { - Region? regionWithNode = GetRegion(coordinates); - if (regionWithNode is not null) - return regionWithNode.GetNode(coordinates); - return null; - } public OsmNode? GetNode(ulong nodeId, ulong regionId) { Region? r = GetRegion(regionId); return r?.GetNode(nodeId); } + + public bool TestValidConnectionForType(OsmNode node1, OsmNode node2, Tag.SpeedType type) + { + foreach (OsmEdge edge in node1.edges) + { + if (edge.neighborId.Equals(node2.nodeId)) + return TestValidConnectionForType(node1, edge, type); + } + + return false; + } + + public bool TestValidConnectionForType(OsmNode node1, OsmEdge edge, Tag.SpeedType type) + { + double speed = GetSpeedForEdge(node1, edge.wayId, type); + if (speed != 0) + return true; + return false; + } + + public OsmNode? ClosestNodeToCoordinates(Coordinates coordinates, Tag.SpeedType vehicle) + { + OsmNode? closest = null; + double distance = double.MaxValue; + Region? region = GetRegion(coordinates); + if (region is null) + return null; + foreach (OsmNode node in region.nodes) + { + bool hasConnectionUsingVehicle = false; + foreach (OsmEdge edge in node.edges) + { + double speed = GetSpeedForEdge(node, edge.wayId, vehicle); + if (speed != 0) + hasConnectionUsingVehicle = true; + } + double nodeDistance = Utils.DistanceBetween(node, coordinates); + if (nodeDistance < distance && hasConnectionUsingVehicle) + { + closest = node; + distance = nodeDistance; + } + } + + return closest; + } + + public double GetSpeedForEdge(OsmNode node1, ulong wayId, Tag.SpeedType vehicle) + { + TagManager tags = GetRegion(node1.coordinates)!.tagManager; + Tag.WayType wayType = (Tag.WayType)tags.GetTag(wayId, Tag.TagType.highway)!; + switch (vehicle) + { + case Tag.SpeedType.pedestrian: + byte speed = Tag.defaultSpeedPedestrian[wayType]; + if (speed is not 0) + return speed; + return 0; + case Tag.SpeedType.car: + case Tag.SpeedType.road: + byte? maxSpeed = (byte?)tags.GetTag(wayId, Tag.TagType.maxspeed); + if (maxSpeed is not null) + return (double)maxSpeed; + maxSpeed = Tag.defaultSpeedCar[wayType]; + if(maxSpeed is not 0) + return (byte)maxSpeed; + return 0; + default: + return 0; + } + } } } \ No newline at end of file