Compare commits

...

7 Commits

Author SHA1 Message Date
82d2de1537 working 2023-04-01 14:43:22 +02:00
01deb02666 Adjusted to new Region Format 2023-04-01 14:43:05 +02:00
2826ff2502 Fixed deserialization issue with wrong default values
ToString() uniform
2023-04-01 14:42:49 +02:00
8cf13efae3 code clean 2023-04-01 14:21:58 +02:00
b3da6936da Fixed return of GetTag to return value of searched Tag. 2023-04-01 14:21:39 +02:00
312536f0c0 ToString() adjustment 2023-04-01 14:21:11 +02:00
556d4b1ffb ToString() adjustment 2023-04-01 14:19:36 +02:00
8 changed files with 108 additions and 87 deletions

View File

@ -47,6 +47,6 @@ public class Coordinates
public override string ToString() public override string ToString()
{ {
return return
$"COORDINATES Lat: {this.latitude.ToString(NumberFormatInfo.InvariantInfo)} Lon: {this.longitude.ToString(CultureInfo.InvariantCulture)}"; $"lat:{latitude.ToString(NumberFormatInfo.InvariantInfo)} lon:{longitude.ToString(CultureInfo.InvariantCulture)}";
} }
} }

View File

@ -19,6 +19,6 @@ public class OsmEdge
public override string ToString() public override string ToString()
{ {
return $"EDGE WayID: {wayId} StartID: {startId} NeighborID: {neighborId} in {neighborRegion}"; return $"w:{wayId} n1:{startId} n2:{neighborId} in r:{neighborRegion}";
} }
} }

View File

@ -1,3 +1,6 @@
using System.ComponentModel;
using System.Runtime.Serialization;
namespace OSMDatastructure.Graph; namespace OSMDatastructure.Graph;
[Serializable] [Serializable]
@ -12,6 +15,14 @@ public class OsmNode
[NonSerialized]public double currentPathLength = double.MaxValue; [NonSerialized]public double currentPathLength = double.MaxValue;
[NonSerialized]public double directDistanceToGoal = double.MaxValue; [NonSerialized]public double directDistanceToGoal = double.MaxValue;
[OnDeserialized]
internal void SetDefaultValues(StreamingContext context)
{
currentPathWeight = double.MaxValue;
currentPathLength = double.MaxValue;
directDistanceToGoal = double.MaxValue;
}
public OsmNode(ulong nodeId, float lat, float lon) public OsmNode(ulong nodeId, float lat, float lon)
{ {
this.nodeId = nodeId; this.nodeId = nodeId;
@ -28,10 +39,10 @@ public class OsmNode
public OsmEdge? GetEdgeToNode(OsmNode n) public OsmEdge? GetEdgeToNode(OsmNode n)
{ {
foreach (OsmEdge e in this.edges) HashSet<OsmEdge> e = edges.Where(edge => edge.neighborId == n.nodeId).ToHashSet();
if (e.neighborId == n.nodeId) if (e.Count > 0)
return e; return e.First();
return null; else return null;
} }
public override bool Equals(object? obj) public override bool Equals(object? obj)
@ -39,22 +50,11 @@ public class OsmNode
return obj != null && obj.GetType() == this.GetType() && ((OsmNode)obj).nodeId == this.nodeId; return obj != null && obj.GetType() == this.GetType() && ((OsmNode)obj).nodeId == this.nodeId;
} }
public override int GetHashCode()
{
return HashCode.Combine(coordinates);
}
public override string ToString() public override string ToString()
{ {
if(this.previousPathNode != null) if(previousPathNode is not null)
return string.Format( return $"{nodeId} {coordinates} ec:{edges.Count} d:{directDistanceToGoal} w:{currentPathWeight} l:{currentPathLength} p:{previousPathNode.nodeId}";
"NODE {0} Edges-Count: {1} previousPathNode: {2} currentPathWeight: {3} currentPathLength: {4} directDistanceToGoal: {5}", return
this.coordinates.ToString(), this.edges.Count, this.previousPathNode.coordinates.ToString(), $"{nodeId} {coordinates} ec:{edges.Count} d:{directDistanceToGoal} w:{currentPathWeight} l:{currentPathLength} null";
this.currentPathWeight, this.currentPathLength, this.directDistanceToGoal);
else
return string.Format(
"NODE {0} Edges-Count: {1} previousPathNode: NO PREVIOUS NODE currentPathWeight: {2} currentPathLength: {3} directDistanceToGoal: {4}",
this.coordinates.ToString(), this.edges.Count,
this.currentPathWeight, this.currentPathLength, this.directDistanceToGoal);
} }
} }

View File

@ -39,36 +39,36 @@ public class Tag
case "highway": case "highway":
try try
{ {
return new Tag(Tag.TagType.highway, (Tag.WayType)Enum.Parse(typeof(Tag.WayType), value, true)); return new Tag(TagType.highway, (WayType)Enum.Parse(typeof(WayType), value, true));
} }
catch (ArgumentException) catch (ArgumentException)
{ {
return new Tag(Tag.TagType.highway, Tag.WayType.unclassified); return new Tag(TagType.highway, WayType.unclassified);
} }
case "maxspeed": case "maxspeed":
try try
{ {
byte speed = Convert.ToByte(value); byte speed = Convert.ToByte(value);
if (speed == 255) if (speed == 255)
return new Tag(Tag.TagType.highway, false); return new Tag(TagType.highway, false);
else else
return new Tag(Tag.TagType.maxspeed, speed); return new Tag(TagType.maxspeed, speed);
} }
catch (Exception) catch (Exception)
{ {
//Console.WriteLine(e); //Console.WriteLine(e);
//Console.WriteLine("Continuing..."); //Console.WriteLine("Continuing...");
return new Tag(Tag.TagType.maxspeed, byte.MaxValue); return new Tag(TagType.maxspeed, byte.MaxValue);
} }
case "oneway": case "oneway":
switch (value) switch (value)
{ {
case "yes": case "yes":
return new Tag(Tag.TagType.oneway, true); return new Tag(TagType.oneway, true);
case "-1": case "-1":
return new Tag(Tag.TagType.forward, false); return new Tag(TagType.forward, false);
case "no": case "no":
return new Tag(Tag.TagType.oneway, false); return new Tag(TagType.oneway, false);
} }
break; break;

View File

@ -14,7 +14,7 @@ public class TagManager
public object? GetTag(ulong wayId, Tag.TagType key) public object? GetTag(ulong wayId, Tag.TagType key)
{ {
return ContainsKey(wayId, key) ? wayTagSets[wayId].First(tag => tag.key == key) : null; return ContainsKey(wayId, key) ? wayTagSets[wayId].First(tag => tag.key == key).value : null;
} }
public void AddTag(ulong wayId, string key, string value) public void AddTag(ulong wayId, string key, string value)

View File

@ -6,20 +6,13 @@ namespace Pathfinding;
public class Pathfinder public class Pathfinder
{ {
/* public static List<OsmNode> CustomAStar(string workingDir, Coordinates start, Coordinates goal, Tag.SpeedType vehicle)
public static List<OsmNode> CustomAStar(string workingDir, Coordinates start, Coordinates goal, OsmWay.speedType vehicle)
{ {
RegionManager regionManager = new RegionManager(workingDir); RegionManager regionManager = new RegionManager(workingDir);
Region startRegion, goalRegion; Region? startRegion = regionManager.GetRegion(start);
try Region? goalRegion = regionManager.GetRegion(goal);
{ if (startRegion is null || goalRegion is null)
startRegion = regionManager.GetRegion(start); return new List<OsmNode>();
goalRegion = regionManager.GetRegion(goal);
}
catch (FileNotFoundException e)
{
throw new Exception(string.Format("No region at coordinates {0}", e.FileName), e);
}
OsmNode? startNode = ClosestNodeToCoordinates(start, startRegion); OsmNode? startNode = ClosestNodeToCoordinates(start, startRegion);
OsmNode? goalNode = ClosestNodeToCoordinates(goal, goalRegion); OsmNode? goalNode = ClosestNodeToCoordinates(goal, goalRegion);
@ -36,25 +29,20 @@ public class Pathfinder
{ {
//Console.WriteLine("toVisit-length: {0}", toVisit.Count); //Console.WriteLine("toVisit-length: {0}", toVisit.Count);
closestNodeToGoal = toVisit.First(); closestNodeToGoal = toVisit.First();
foreach (OsmNode node in toVisit) foreach (OsmNode node in toVisit.Where(node => node.directDistanceToGoal.Equals(Double.MaxValue)))
{
if (node.directDistanceToGoal.Equals(double.MaxValue))
{ {
node.directDistanceToGoal = Utils.DistanceBetween(node, goalNode); node.directDistanceToGoal = Utils.DistanceBetween(node, goalNode);
} }
if (node.directDistanceToGoal < closestNodeToGoal.directDistanceToGoal)
{
closestNodeToGoal = node;
}
}
foreach (OsmWay edge in closestNodeToGoal.edges) closestNodeToGoal = toVisit.OrderBy(node => node.directDistanceToGoal).First();
foreach (OsmEdge edge in closestNodeToGoal.edges)
{ {
OsmNode? neighbor = regionManager.GetNode(edge.neighborCoordinates); OsmNode? neighbor = regionManager.GetNode(edge.neighborId, edge.neighborRegion);
if (neighbor != null) if (neighbor is not null)
{ {
double newPotentialWeight = double newPotentialWeight =
closestNodeToGoal.currentPathWeight + edge.GetWeight(closestNodeToGoal, vehicle); closestNodeToGoal.currentPathWeight + EdgeWeight(closestNodeToGoal, neighbor, edge.wayId, vehicle, ref regionManager);
if (neighbor.currentPathWeight > newPotentialWeight) if (neighbor.currentPathWeight > newPotentialWeight)
{ {
neighbor.previousPathNode = closestNodeToGoal; neighbor.previousPathNode = closestNodeToGoal;
@ -100,5 +88,32 @@ public class Pathfinder
} }
return closest; return closest;
}*/ }
private static double EdgeWeight(OsmNode node1, OsmNode node2, ulong wayId, Tag.SpeedType vehicle, ref RegionManager regionManager)
{
TagManager tags = regionManager.GetRegion(node1.coordinates)!.tagManager;
double distance = Utils.DistanceBetween(node1, node2);
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 distance / speed;
else return Double.PositiveInfinity;
case Tag.SpeedType.car:
case Tag.SpeedType.road:
byte? maxspeed = (byte?)tags.GetTag(wayId, Tag.TagType.maxspeed);
if (maxspeed is not null)
return distance / Convert.ToDouble(maxspeed);
else
maxspeed = Tag.defaultSpeedCar[wayType];
if(maxspeed is not 0)
return distance / Tag.defaultSpeedCar[wayType];
else return Double.PositiveInfinity;;
default:
return double.PositiveInfinity;
}
}
} }

View File

@ -13,20 +13,20 @@ namespace OSMImporter
this.workingDirectory = workingDirectory; this.workingDirectory = workingDirectory;
} }
/// <summary> public Region? GetRegion(Coordinates coordinates)
/// Checks wether the Region is already loaded and returns the Region, or tries to load the Region from file in workingDirectory
/// </summary>
/// <param name="coordinates">Coordinates of the Region (or within the Region) to load</param>
/// <returns>The Region at the specified Coordinates containing Nodes and Connections</returns>
/// <exception cref="FileNotFoundException">If the Regionfile can not be found.</exception>
public Region GetRegion(Coordinates coordinates)
{ {
if(_regions.ContainsKey(Coordinates.GetRegionHashCode(coordinates))) return GetRegion(Coordinates.GetRegionHashCode(coordinates));
return _regions[Coordinates.GetRegionHashCode(coordinates)]; }
public Region? GetRegion(ulong id)
{
if(_regions.TryGetValue(id, out Region? value))
return value;
else else
{ {
Region loadedRegion = LoadRegion(coordinates); Region? loadedRegion = LoadRegion(id);
_regions.Add(loadedRegion.regionHash, value: loadedRegion); if(loadedRegion is not null)
_regions.Add(loadedRegion!.regionHash, value: loadedRegion);
return loadedRegion; return loadedRegion;
} }
} }
@ -36,21 +36,28 @@ namespace OSMImporter
return this._regions.Values.ToArray(); return this._regions.Values.ToArray();
} }
/// <summary> private Region? LoadRegion(Coordinates coordinates)
///
/// </summary>
/// <param name="coordinates">Coordinates of the Region (or within the Region) to load</param>
/// <returns>The Region at the specified Coordinates containing Nodes and Connections</returns>
/// <exception cref="FileNotFoundException">If the Regionfile can not be found.</exception>
private Region LoadRegion(Coordinates coordinates)
{ {
throw new NotImplementedException(); return LoadRegion(Coordinates.GetRegionHashCode(coordinates));
}
private Region? LoadRegion(ulong id)
{
return Region.FromId(workingDirectory, id);
} }
public OsmNode? GetNode(Coordinates coordinates) public OsmNode? GetNode(Coordinates coordinates)
{ {
Region regionWithNode = GetRegion(coordinates); Region? regionWithNode = GetRegion(coordinates);
if (regionWithNode is not null)
return regionWithNode.GetNode(coordinates); return regionWithNode.GetNode(coordinates);
else return null;
}
public OsmNode? GetNode(ulong nodeId, ulong regionId)
{
Region? r = GetRegion(regionId);
return r?.GetNode(nodeId);
} }
} }
} }

View File

@ -1,5 +1,6 @@
using OSMDatastructure; using OSMDatastructure;
using OSMDatastructure.Graph; using OSMDatastructure.Graph;
using Pathfinding;
namespace Server; namespace Server;
@ -13,15 +14,13 @@ public class Server
Console.SetError(newConsole); Console.SetError(newConsole);
//RegionConverter.ConvertXMLToRegions("D:/stuttgart-regbez-latest.osm", "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:/map.osm", "D:/map");
Console.WriteLine("Loaded"); Console.WriteLine("Loaded");
Region? r = Region.FromFile("D:/map/13870001898000.region");
Console.WriteLine("loaded region");
/*
Coordinates start = new Coordinates(48.243351f, 11.640417f); Coordinates start = new Coordinates(48.7933989f, 9.8301467f);
Coordinates finish = new Coordinates(48.25239f, 11.53272f); Coordinates finish = new Coordinates(48.7906258f, 9.8355983f);
OsmNode[] path = Pathfinder.CustomAStar("/home/glax/Downloads/oberbayern-latest", start, finish, OsmEdge.speedType.car).ToArray(); OsmNode[] path = Pathfinder.CustomAStar("D:/map", start, finish, Tag.SpeedType.pedestrian).ToArray();
Console.WriteLine("{0}\n", path[0].ToString()); Console.WriteLine("{0}\n", path[0].ToString());
for (int i = 0; i < path.Length - 1; i++) for (int i = 0; i < path.Length - 1; i++)
{ {
@ -33,6 +32,6 @@ public class Server
else else
Console.WriteLine("NO EDGE\n{0}", n2.ToString()); Console.WriteLine("NO EDGE\n{0}", n2.ToString());
} }
Console.WriteLine();*/ Console.WriteLine();
} }
} }