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()
{
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()
{
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;
[Serializable]
@ -12,6 +15,14 @@ public class OsmNode
[NonSerialized]public double currentPathLength = 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)
{
this.nodeId = nodeId;
@ -28,10 +39,10 @@ public class OsmNode
public OsmEdge? GetEdgeToNode(OsmNode n)
{
foreach (OsmEdge e in this.edges)
if (e.neighborId == n.nodeId)
return e;
return null;
HashSet<OsmEdge> e = edges.Where(edge => edge.neighborId == n.nodeId).ToHashSet();
if (e.Count > 0)
return e.First();
else return null;
}
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;
}
public override int GetHashCode()
{
return HashCode.Combine(coordinates);
}
public override string ToString()
{
if(this.previousPathNode != null)
return string.Format(
"NODE {0} Edges-Count: {1} previousPathNode: {2} currentPathWeight: {3} currentPathLength: {4} directDistanceToGoal: {5}",
this.coordinates.ToString(), this.edges.Count, this.previousPathNode.coordinates.ToString(),
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);
if(previousPathNode is not null)
return $"{nodeId} {coordinates} ec:{edges.Count} d:{directDistanceToGoal} w:{currentPathWeight} l:{currentPathLength} p:{previousPathNode.nodeId}";
return
$"{nodeId} {coordinates} ec:{edges.Count} d:{directDistanceToGoal} w:{currentPathWeight} l:{currentPathLength} null";
}
}

View File

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

View File

@ -14,7 +14,7 @@ public class TagManager
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)

View File

@ -6,20 +6,13 @@ namespace Pathfinding;
public class Pathfinder
{
/*
public static List<OsmNode> CustomAStar(string workingDir, Coordinates start, Coordinates goal, OsmWay.speedType vehicle)
public static List<OsmNode> CustomAStar(string workingDir, Coordinates start, Coordinates goal, Tag.SpeedType vehicle)
{
RegionManager regionManager = new RegionManager(workingDir);
Region startRegion, goalRegion;
try
{
startRegion = regionManager.GetRegion(start);
goalRegion = regionManager.GetRegion(goal);
}
catch (FileNotFoundException e)
{
throw new Exception(string.Format("No region at coordinates {0}", e.FileName), e);
}
Region? startRegion = regionManager.GetRegion(start);
Region? goalRegion = regionManager.GetRegion(goal);
if (startRegion is null || goalRegion is null)
return new List<OsmNode>();
OsmNode? startNode = ClosestNodeToCoordinates(start, startRegion);
OsmNode? goalNode = ClosestNodeToCoordinates(goal, goalRegion);
@ -36,25 +29,20 @@ public class Pathfinder
{
//Console.WriteLine("toVisit-length: {0}", toVisit.Count);
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);
}
if (node.directDistanceToGoal < closestNodeToGoal.directDistanceToGoal)
{
closestNodeToGoal = node;
}
node.directDistanceToGoal = Utils.DistanceBetween(node, goalNode);
}
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);
if (neighbor != null)
OsmNode? neighbor = regionManager.GetNode(edge.neighborId, edge.neighborRegion);
if (neighbor is not null)
{
double newPotentialWeight =
closestNodeToGoal.currentPathWeight + edge.GetWeight(closestNodeToGoal, vehicle);
closestNodeToGoal.currentPathWeight + EdgeWeight(closestNodeToGoal, neighbor, edge.wayId, vehicle, ref regionManager);
if (neighbor.currentPathWeight > newPotentialWeight)
{
neighbor.previousPathNode = closestNodeToGoal;
@ -100,5 +88,32 @@ public class Pathfinder
}
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;
}
/// <summary>
/// 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)
public Region? GetRegion(Coordinates coordinates)
{
if(_regions.ContainsKey(Coordinates.GetRegionHashCode(coordinates)))
return _regions[Coordinates.GetRegionHashCode(coordinates)];
return GetRegion(Coordinates.GetRegionHashCode(coordinates));
}
public Region? GetRegion(ulong id)
{
if(_regions.TryGetValue(id, out Region? value))
return value;
else
{
Region loadedRegion = LoadRegion(coordinates);
_regions.Add(loadedRegion.regionHash, value: loadedRegion);
Region? loadedRegion = LoadRegion(id);
if(loadedRegion is not null)
_regions.Add(loadedRegion!.regionHash, value: loadedRegion);
return loadedRegion;
}
}
@ -36,21 +36,28 @@ namespace OSMImporter
return this._regions.Values.ToArray();
}
/// <summary>
///
/// </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)
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)
{
Region regionWithNode = GetRegion(coordinates);
return regionWithNode.GetNode(coordinates);
Region? regionWithNode = GetRegion(coordinates);
if (regionWithNode is not null)
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.Graph;
using Pathfinding;
namespace Server;
@ -13,15 +14,13 @@ public class Server
Console.SetError(newConsole);
//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");
Region? r = Region.FromFile("D:/map/13870001898000.region");
Console.WriteLine("loaded region");
/*
Coordinates start = new Coordinates(48.243351f, 11.640417f);
Coordinates finish = new Coordinates(48.25239f, 11.53272f);
OsmNode[] path = Pathfinder.CustomAStar("/home/glax/Downloads/oberbayern-latest", start, finish, OsmEdge.speedType.car).ToArray();
Coordinates start = new Coordinates(48.7933989f, 9.8301467f);
Coordinates finish = new Coordinates(48.7906258f, 9.8355983f);
OsmNode[] path = Pathfinder.CustomAStar("D:/map", start, finish, Tag.SpeedType.pedestrian).ToArray();
Console.WriteLine("{0}\n", path[0].ToString());
for (int i = 0; i < path.Length - 1; i++)
{
@ -33,6 +32,6 @@ public class Server
else
Console.WriteLine("NO EDGE\n{0}", n2.ToString());
}
Console.WriteLine();*/
Console.WriteLine();
}
}