, IEquatable
11 | {
12 |
13 | IEnumerable Route(P source, P target,
14 | Func cost, Func bound = null, double max = double.NaN);
15 |
16 | IReadOnlyDictionary> Route(P source, IEnumerable
targets,
17 | Func cost, Func bound = null, double max = double.NaN);
18 |
19 | IReadOnlyDictionary)> Route(IEnumerable
sources, IEnumerable
targets,
20 | Func cost, Func bound = null, double max = double.NaN);
21 | }
22 |
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/Sandwych.MapMatchingKit/Topology/IPath.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Sandwych.MapMatchingKit.Topology
6 | {
7 | public interface IPath
8 | where TEdge : IGraphEdge
9 | where TPoint : IEdgePoint
10 | {
11 | ref readonly TPoint StartPoint { get; }
12 | ref readonly TPoint EndPoint { get; }
13 | IEnumerable Edges { get; }
14 | float Length { get; }
15 | double Cost(Func costFunc);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Sandwych.MapMatchingKit/Topology/PrecomputedDijkstra/BoundedDijkstraShortestPathAlgorithm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using QuickGraph;
6 | using QuickGraph.Algorithms.ShortestPath;
7 |
8 | namespace Sandwych.MapMatchingKit.Topology.PrecomputedDijkstra
9 | {
10 |
11 | public class BoundedDijkstraShortestPathAlgorithm
12 | where TVertex : IEquatable
13 | where TEdge : IEdge
14 | {
15 | private readonly HashSet _visitedVertices;
16 | private readonly Dictionary _vertexPredecessors;
17 |
18 | public Func BoundingCost { get; }
19 | public DijkstraShortestPathAlgorithm Algorithm { get; }
20 | public double MaxRadius { get; }
21 | public IEnumerable VisitedVertices => _visitedVertices;
22 | public IReadOnlyDictionary Predecessors => _vertexPredecessors;
23 |
24 | public BoundedDijkstraShortestPathAlgorithm(
25 | IVertexAndEdgeListGraph graph, Func cost,
26 | Func bound, double maxRadius)
27 | {
28 | if (maxRadius < 0D)
29 | {
30 | throw new ArgumentOutOfRangeException(nameof(maxRadius));
31 | }
32 |
33 | var nVertices = graph.VertexCount;
34 |
35 | _visitedVertices = new HashSet();
36 | _vertexPredecessors = new Dictionary(nVertices);
37 |
38 | this.Algorithm = new DijkstraShortestPathAlgorithm(graph, cost);
39 | this.Algorithm.ExamineVertex += this.ExamineVertex;
40 | this.Algorithm.TreeEdge += this.OnTreeEdge;
41 | this.BoundingCost = bound;
42 | this.MaxRadius = maxRadius;
43 | }
44 |
45 | private void Initialize()
46 | {
47 | _vertexPredecessors.Clear();
48 | _visitedVertices.Clear();
49 | }
50 |
51 | public void Compute(TVertex rootVertex)
52 | {
53 | this.Initialize();
54 |
55 | this.Algorithm.Compute(rootVertex);
56 | }
57 |
58 | public double GetDistance(TVertex vertex) =>
59 | this.Algorithm.Distances[vertex];
60 |
61 | public bool TryGetDistance(TVertex vertex, out double distance) =>
62 | this.Algorithm.TryGetDistance(vertex, out distance);
63 |
64 | private void ExamineVertex(TVertex vertex)
65 | {
66 | if (this.BoundingCost != null && !double.IsNaN(this.MaxRadius))
67 | {
68 | if (this.TryGetPath(vertex, out var path) && path.Sum(this.BoundingCost) > this.MaxRadius)
69 | {
70 | throw new OutOfRadiusException();
71 | }
72 | }
73 |
74 | this._visitedVertices.Add(vertex);
75 | }
76 |
77 | private void OnTreeEdge(TEdge e)
78 | {
79 | _vertexPredecessors[e.Target] = e;
80 | }
81 |
82 | public bool TryGetPath(TVertex vertex, out IEnumerable path) =>
83 | this._vertexPredecessors.TryGetPath(vertex, out path);
84 |
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/Sandwych.MapMatchingKit/Topology/PrecomputedDijkstra/OutOfRadiusException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Sandwych.MapMatchingKit.Topology.PrecomputedDijkstra
6 | {
7 |
8 | public class OutOfRadiusException : Exception
9 | {
10 |
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/Sandwych.MapMatchingKit/Topology/PrecomputedDijkstra/PrecomputedDijkstraRouter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using Microsoft.Extensions.Logging;
6 | using Sandwych.MapMatchingKit.Roads;
7 | using Sandwych.MapMatchingKit.Utility;
8 |
9 | namespace Sandwych.MapMatchingKit.Topology.PrecomputedDijkstra
10 | {
11 | public class PrecomputedDijkstraRouter : IGraphRouter
12 | where TEdge : class, IGraphEdge, IEquatable
13 | where P : IEdgePoint, IEquatable
14 | {
15 | private static readonly TEdge[] EmptyPath = new TEdge[] { };
16 | public ILogger Logger { get; set; } = NullLogger.Instance;
17 |
18 | private readonly IGraph _graph;
19 | private readonly PrecomputedDijkstraTable _precomputedTable;
20 | private readonly Func _cost;
21 | private readonly Func _boundingCost;
22 | private readonly double _maxRadius;
23 |
24 | public PrecomputedDijkstraRouter(IGraph graph, Func cost, Func boundingCost, double max)
25 | {
26 | _graph = graph;
27 | _cost = cost;
28 | _boundingCost = boundingCost;
29 | _maxRadius = max;
30 | _precomputedTable = this.CreateTable();
31 | }
32 |
33 | public IReadOnlyDictionary> Route(P source, IEnumerable
targets, Func cost,
34 | Func bound = null, double max = double.NaN)
35 | {
36 | var dict = new Dictionary>(targets.Count());
37 | foreach (var target in targets)
38 | {
39 | var path = this.Route(source, target, cost, bound, max);
40 | if (path != null && path.Count() > 0)
41 | {
42 | dict.Add(target, path);
43 | }
44 | }
45 | return dict;
46 | }
47 |
48 | public IReadOnlyDictionary
)> Route(IEnumerable
sources, IEnumerable
targets, Func cost = null,
49 | Func bound = null, double max = double.NaN)
50 | {
51 | throw new NotSupportedException();
52 | }
53 |
54 | public IEnumerable Route(P source, P target, Func