Compare commits

..

7 Commits

Author SHA1 Message Date
08ebc9a26b Changed some display values 2023-04-13 01:12:29 +02:00
d35aab9c39 More logging 2023-04-13 01:12:16 +02:00
08e3da6fe3 Render result to png after every routing 2023-04-13 01:00:56 +02:00
367e9cfde0 Removed API 2023-04-13 01:00:38 +02:00
a70284aa87 Added visualization to confirm paths 2023-04-13 00:24:33 +02:00
13915c9773 No more use of "track" or "service" for cars. 2023-04-13 00:24:03 +02:00
c373451007 fixed missing oneway streets without "forward" tag 2023-04-13 00:18:30 +02:00
11 changed files with 130 additions and 32 deletions

View File

@ -17,6 +17,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Pathfinding\Pathfinding.csproj" /> <ProjectReference Include="..\Pathfinding\Pathfinding.csproj" />
<ProjectReference Include="..\RenderPath\RenderPath.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -14,17 +14,6 @@ builder.Services.AddSwaggerGen();
var app = builder.Build(); var app = builder.Build();
app.MapGet("/getRouteBeta", (float latStart, float lonStart, float latEnd, float lonEnd, Tag.SpeedType vehicle, double stayOnSameRoadPriority, double useHigherLevelRoadsPriority, double useRoadsWithLessJunctionsPriority) =>
{
DateTime startCalc = DateTime.Now;
List<PathNode> result = Pathfinder.AStar("D:/stuttgart-regbez-latest", new Coordinates(latStart, lonStart),
new Coordinates(latEnd, lonEnd), vehicle, useHigherLevelRoadsPriority, stayOnSameRoadPriority,
useRoadsWithLessJunctionsPriority);
PathResult pathResult = new PathResult(DateTime.Now - startCalc, result);
return RenderPath.Renderer.DrawFromPath(result);
}
);
app.MapGet("/getRoute", (float latStart, float lonStart, float latEnd, float lonEnd, Tag.SpeedType vehicle, double stayOnSameRoadPriority, double useHigherLevelRoadsPriority, double useRoadsWithLessJunctionsPriority) => app.MapGet("/getRoute", (float latStart, float lonStart, float latEnd, float lonEnd, Tag.SpeedType vehicle, double stayOnSameRoadPriority, double useHigherLevelRoadsPriority, double useRoadsWithLessJunctionsPriority) =>
{ {
DateTime startCalc = DateTime.Now; DateTime startCalc = DateTime.Now;

View File

@ -118,16 +118,16 @@ public class Tag
{ WayType.secondary, 60 }, { WayType.secondary, 60 },
{ WayType.tertiary, 50 }, { WayType.tertiary, 50 },
{ WayType.unclassified, 30 }, { WayType.unclassified, 30 },
{ WayType.residential, 15 }, { WayType.residential, 20 },
{ WayType.motorway_link, 60 }, { WayType.motorway_link, 60 },
{ WayType.trunk_link, 50 }, { WayType.trunk_link, 50 },
{ WayType.primary_link, 50 }, { WayType.primary_link, 50 },
{ WayType.secondary_link, 50 }, { WayType.secondary_link, 50 },
{ WayType.tertiary_link, 30 }, { WayType.tertiary_link, 30 },
{ WayType.living_street, 10 }, { WayType.living_street, 10 },
{ WayType.service, 1 }, { WayType.service, 0 },
{ WayType.pedestrian, 0 }, { WayType.pedestrian, 0 },
{ WayType.track, 1 }, { WayType.track, 0 },
{ WayType.bus_guideway, 0 }, { WayType.bus_guideway, 0 },
{ WayType.escape, 0 }, { WayType.escape, 0 },
{ WayType.raceway, 0 }, { WayType.raceway, 0 },

View File

@ -8,6 +8,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pathfinding", "Pathfinding\
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "API", "API\API.csproj", "{1D364F40-1681-4D36-A625-83B324F6AC89}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "API", "API\API.csproj", "{1D364F40-1681-4D36-A625-83B324F6AC89}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenderPath", "RenderPath\RenderPath.csproj", "{54CAC127-4EB6-4E06-A5C8-35343C5FF76A}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -30,5 +32,9 @@ Global
{1D364F40-1681-4D36-A625-83B324F6AC89}.Debug|Any CPU.Build.0 = Debug|Any CPU {1D364F40-1681-4D36-A625-83B324F6AC89}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D364F40-1681-4D36-A625-83B324F6AC89}.Release|Any CPU.ActiveCfg = Release|Any CPU {1D364F40-1681-4D36-A625-83B324F6AC89}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D364F40-1681-4D36-A625-83B324F6AC89}.Release|Any CPU.Build.0 = Release|Any CPU {1D364F40-1681-4D36-A625-83B324F6AC89}.Release|Any CPU.Build.0 = Release|Any CPU
{54CAC127-4EB6-4E06-A5C8-35343C5FF76A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{54CAC127-4EB6-4E06-A5C8-35343C5FF76A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54CAC127-4EB6-4E06-A5C8-35343C5FF76A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54CAC127-4EB6-4E06-A5C8-35343C5FF76A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -1,5 +1,6 @@
using OSMDatastructure; using OSMDatastructure;
using OSMDatastructure.Graph; using OSMDatastructure.Graph;
using RenderPath;
using static OSMDatastructure.Tag; using static OSMDatastructure.Tag;
using WayType = OSMDatastructure.Tag.WayType; using WayType = OSMDatastructure.Tag.WayType;
@ -28,7 +29,17 @@ public static class Pathfinder
{ {
OsmNode currentNode = openSetfScore.Dequeue(); OsmNode currentNode = openSetfScore.Dequeue();
if (currentNode.Equals(goalNode)) if (currentNode.Equals(goalNode))
return GetPath(cameFromDict, goalNode, regionManager); {
Console.WriteLine("Path found.");
List<PathNode> path = GetPath(cameFromDict, goalNode, regionManager);
Console.WriteLine("Rendering.");
List<Coordinates> coords = new();
foreach(PathNode pn in path)
coords.Add(pn.coordinates);
Renderer.DrawLoadedNodes(gScore, coords, workingDir);
Console.WriteLine("Done.");
return path;
}
foreach (OsmEdge edge in currentNode.edges) foreach (OsmEdge edge in currentNode.edges)
{ {
@ -85,7 +96,7 @@ public static class Pathfinder
double distance = Utils.DistanceBetween(fromNode, neighborNode); double distance = Utils.DistanceBetween(fromNode, neighborNode);
double speed = regionManager.GetSpeedForEdge(fromNode, edge.wayId, vehicle); double speed = regionManager.GetSpeedForEdge(fromNode, edge.wayId, vehicle);
double prio = GetPriorityVehicleRoad(edge, vehicle, regionManager.GetRegion(fromNode.coordinates)!); double prio = GetPriorityVehicleRoad(edge, vehicle, regionManager.GetRegion(fromNode.coordinates)!);
return distance / (speed + (prio * 10)); return distance / (speed + prio * 50);
} }
private static double Heuristic(OsmNode fromNode, OsmNode neighborNode, OsmNode goalNode, OsmEdge edge, SpeedType vehicle, RegionManager regionManager, double roadPriorityFactor, double junctionFactor, double sameRoadFactor) private static double Heuristic(OsmNode fromNode, OsmNode neighborNode, OsmNode goalNode, OsmEdge edge, SpeedType vehicle, RegionManager regionManager, double roadPriorityFactor, double junctionFactor, double sameRoadFactor)
@ -113,7 +124,7 @@ public static class Pathfinder
//Console.WriteLine($"{roadPriority:000.00} {sameRoadName:000.00} {junctionCount:000.00} {distanceImprovement:+000.00;-000.00;0000.00}"); //Console.WriteLine($"{roadPriority:000.00} {sameRoadName:000.00} {junctionCount:000.00} {distanceImprovement:+000.00;-000.00;0000.00}");
return Utils.DistanceBetween(neighborNode, goalNode) - (roadPriority + sameRoadName + junctionCount) * 100; return Utils.DistanceBetween(neighborNode, goalNode) - (roadPriority + sameRoadName + junctionCount) * 20;
} }
private static double GetPriorityVehicleRoad(OsmEdge edge, SpeedType vehicle, Region region) private static double GetPriorityVehicleRoad(OsmEdge edge, SpeedType vehicle, Region region)

View File

@ -8,6 +8,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\OSMDatastructure\OSMDatastructure.csproj" /> <ProjectReference Include="..\OSMDatastructure\OSMDatastructure.csproj" />
<ProjectReference Include="..\RenderPath\RenderPath.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OSMDatastructure\OSMDatastructure.csproj" />
</ItemGroup>
</Project>

79
RenderPath/Renderer.cs Normal file
View File

@ -0,0 +1,79 @@
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Drawing.Imaging;
using OSMDatastructure.Graph;
namespace RenderPath;
public class Renderer
{
[SuppressMessage("Interoperability", "CA1416:Plattformkompatibilität überprüfen")]
public static void DrawLoadedNodes(Dictionary<OsmNode, double> gScoreDict, List<Coordinates> pathCoordinates, string workingDir)
{
float minLat = gScoreDict.Min(kv => kv.Key.coordinates.latitude);
float minLon = gScoreDict.Min(kv => kv.Key.coordinates.longitude);
float maxLat = gScoreDict.Max(kv => kv.Key.coordinates.latitude);
float maxLon = gScoreDict.Max(kv => kv.Key.coordinates.longitude);
double minWeight = gScoreDict.Min(kv => kv.Value);
double maxWeight = gScoreDict.Max(kv => kv.Value);
float latDiff = maxLat - minLat;
float lonDiff = maxLon - minLon;
const int imageMaxSize = 10000;
float scaleFactor = latDiff > lonDiff ? imageMaxSize / latDiff : imageMaxSize / lonDiff;
int pixelsX = (int)(lonDiff * scaleFactor);
int pixelsY = (int)(latDiff * scaleFactor);
Bitmap ret = new Bitmap(pixelsX, pixelsY, PixelFormat.Format32bppRgb);
Graphics g = Graphics.FromImage(ret);
g.Clear(Color.White);
Color start = Color.FromArgb(0, 0, 255);
Color center = Color.FromArgb(255, 255, 0);
Color end = Color.FromArgb(0, 255, 0);
foreach (KeyValuePair<OsmNode, double> kv in gScoreDict)
{
double percentage = (kv.Value - minWeight) / (maxWeight - minWeight);
Brush b = new SolidBrush(GradientPick(percentage, start, center, end));
float x = (kv.Key.coordinates.longitude - minLon) * scaleFactor;
float y = (maxLat - kv.Key.coordinates.latitude) * scaleFactor;
g.FillEllipse(b, x, y, 2, 2);
}
Pen p = new Pen(Color.Red, 2);
for (int i = 0; i < pathCoordinates.Count - 1; i++)
{
Coordinates c1 = pathCoordinates[i];
Coordinates c2 = pathCoordinates[i+1];
Point p1 = new(Convert.ToInt32((c1.longitude - minLon) * scaleFactor), Convert.ToInt32((maxLat - c1.latitude) * scaleFactor));
Point p2 = new(Convert.ToInt32((c2.longitude - minLon) * scaleFactor), Convert.ToInt32((maxLat - c2.latitude) * scaleFactor));
g.DrawLine(p, p1, p2);
}
ret.Save(Path.Join(Directory.GetParent(workingDir)!.FullName, "routing.png"), ImageFormat.Bmp);
}
/*
* https://stackoverflow.com/questions/55601338/get-a-color-value-within-a-gradient-based-on-a-value
*/
private static int LinearInterp(int start, int end, double percentage) => start + (int)Math.Round(percentage * (end - start));
private static Color ColorInterp(Color start, Color end, double percentage) =>
Color.FromArgb(LinearInterp(start.A, end.A, percentage),
LinearInterp(start.R, end.R, percentage),
LinearInterp(start.G, end.G, percentage),
LinearInterp(start.B, end.B, percentage));
private static Color GradientPick(double percentage, Color Start, Color Center, Color End) {
if (percentage < 0.5)
return ColorInterp(Start, Center, percentage / 0.5);
else if (percentage == 0.5)
return Center;
else
return ColorInterp(Center, End, (percentage - 0.5)/0.5);
}
}

View File

@ -159,7 +159,7 @@ public class RegionConverter
WriteTags(ref regionTagsFileStreams, ref writtenWayTagsInRegion, nodeRegions[node2Id], WriteTags(ref regionTagsFileStreams, ref writtenWayTagsInRegion, nodeRegions[node2Id],
currentTags, outputPath); currentTags, outputPath);
} }
else if (currentTags.ContainsKey(Tag.TagType.forward) && (bool)currentTags[Tag.TagType.forward]) else
{ {
OsmEdge n12e = new OsmEdge(currentTags[Tag.TagType.id], node1Id, node2Id, OsmEdge n12e = new OsmEdge(currentTags[Tag.TagType.id], node1Id, node2Id,
nodeRegions[node2Id]); nodeRegions[node2Id]);

View File

@ -13,21 +13,14 @@ public class Server
Console.SetOut(newConsole); Console.SetOut(newConsole);
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");
//RegionConverter.ConvertXMLToRegions("D:/germany-latest.osm", "D:/germany-latest"); //RegionConverter.ConvertXMLToRegions("D:/germany-latest.osm", "D:/germany-latest");
/* Coordinates start = new Coordinates( 48.7933798f, 9.8275859f);
Coordinates start = new Coordinates(48.794567f, 9.820625f); Coordinates finish = new Coordinates( 48.8407632f, 10.0676979f);
Coordinates finish = new Coordinates(48.79593f, 9.824013f); List<PathNode> result = Pathfinder.AStar("D:/stuttgart-regbez-latest", start,
DateTime startTime = DateTime.Now; finish, Tag.SpeedType.car, 20, 2,
OsmNode[] path = Pathfinder.CustomAStar("D:/map", start, finish, Tag.SpeedType.car).ToArray(); 0);
TimeSpan duration = DateTime.Now - startTime;
Console.WriteLine($"Took {duration.TotalMilliseconds}ms ({duration:g})");
for (int i = 0; i < path.Length - 1; i++)
{
Console.WriteLine(path[i]);
}
Console.WriteLine();*/
} }
} }

View File

@ -9,6 +9,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Pathfinding\Pathfinding.csproj" /> <ProjectReference Include="..\Pathfinding\Pathfinding.csproj" />
<ProjectReference Include="..\RenderPath\RenderPath.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>