/// <summary> /// Creates a new routing algorithm instance. /// </summary> public Dykstra(DirectedMetaGraph graph, WeightHandler <T> weightHandler, DykstraSource <T> source, bool backward, T max) { weightHandler.CheckCanUse(graph); _graph = graph; _source = source; _backward = backward; _weightHandler = weightHandler; _max = max; }
/// <summary> /// Creates a new one-to-all dykstra algorithm instance. /// </summary> public Dykstra(Graph graph, Func <uint, uint> getRestriction, WeightHandler <T> weightHandler, IEnumerable <EdgePath <T> > sources, T sourceMax, bool backward) { _graph = graph; _sources = sources; _sourceMax = sourceMax; _backward = backward; _getRestriction = getRestriction; _weightHandler = weightHandler; }
/// <summary> /// Creates a new routing algorithm instance. /// </summary> public Dykstra(DirectedMetaGraph graph, WeightHandler <T> weightHandler, IEnumerable <EdgePath <T> > sources, bool backward, T max) { weightHandler.CheckCanUse(graph); _graph = graph; _sources = sources; _backward = backward; _weightHandler = weightHandler; _max = max; }
/// <summary> /// Builds a route. /// </summary> public override sealed Result <Route> BuildRoute <T>(Profile profile, WeightHandler <T> weightHandler, RouterPoint source, RouterPoint target, EdgePath <T> path) { if (this.CustomRouteBuilder != null) { // there is a custom route builder. return(this.CustomRouteBuilder.TryBuild(_db, profile, source, target, path)); } // use the default. return(CompleteRouteBuilder.TryBuild(_db, profile, source, target, path)); }
/// <summary> /// Creates a new one-to-all dykstra algorithm instance. /// </summary> public DirectedDykstra(Graph graph, WeightHandler <T> weightHandler, RestrictionCollection restrictions, DirectedDykstraSource <T> source, T sourceMax, bool backward) { _graph = graph; _source = source; _weightHandler = weightHandler; _sourceMax = sourceMax; _backward = backward; _restrictions = restrictions; }
/// <summary> /// Creates a new contracted bidirectional router. /// </summary> public BidirectionalDykstra(DirectedMetaGraph graph, RestrictionCollection restrictions, WeightHandler <T> weightHandler, IEnumerable <EdgePath <T> > sources, IEnumerable <EdgePath <T> > targets) { weightHandler.CheckCanUse(graph); _graph = graph; _sources = sources; _targets = targets; _weightHandler = weightHandler; _restrictions = restrictions; }
/// <summary> /// Creates a new algorithm. /// </summary> public ManyToMany(Router router, WeightHandler <T> weightHandler, Func <uint, IEnumerable <uint[]> > getRestrictions, RouterPoint[] sources, RouterPoint[] targets, T maxSearch) { _routerDb = router.Db; _weightHandler = weightHandler; _sources = sources; _targets = targets; _maxSearch = maxSearch; _getRestrictions = getRestrictions; }
/// <summary> /// Creates a new many-to-many algorithm instance. /// </summary> public DirectedManyToMany(Graph graph, WeightHandler <T> weightHandler, RestrictionCollection restrictions, DirectedDykstraSource <T>[] sources, DirectedDykstraSource <T>[] targets, T maxSearch) { _graph = graph; _sources = sources; _targets = targets; _weightHandler = weightHandler; _maxSearch = maxSearch; _restrictions = restrictions; }
/// <summary> /// Creates a new hierarchy builder. /// </summary> public HierarchyBuilder(DirectedMetaGraph graph, IPriorityCalculator priorityCalculator, IWitnessCalculator witnessCalculator, WeightHandler <T> weightHandler) { weightHandler.CheckCanUse(graph); _graph = graph; _priorityCalculator = priorityCalculator; _witnessCalculator = witnessCalculator; _weightHandler = weightHandler; }
/// <summary> /// Creates a new one-to-all dykstra algorithm instance. /// </summary> public Dykstra(Graph graph, WeightHandler <T> weightHandler, Func <uint, IEnumerable <uint[]> > getRestriction, IEnumerable <EdgePath <T> > sources, T sourceMax, List <uint> closures, bool backward) { _graph = graph; _sources = sources; _weightHandler = weightHandler; _sourceMax = sourceMax; _backward = backward; _getRestriction = getRestriction; _closures = closures; }
/// <summary> /// Creates a new hierarchy builder. /// </summary> public HierarchyBuilder(DirectedDynamicGraph graph, IPriorityCalculator priorityCalculator, IWitnessCalculator <T> witnessCalculator, WeightHandler <T> weightHandler, Func <uint, IEnumerable <uint[]> > getRestrictions) { weightHandler.CheckCanUse(graph); _graph = graph; _priorityCalculator = priorityCalculator; _witnessCalculator = witnessCalculator; _getRestrictions = getRestrictions; _weightHandler = weightHandler; }
/// <summary> /// Creates a new algorithm. /// </summary> public OneToMany(RouterDb routerDb, WeightHandler <T> weightHandler, Func <uint, IEnumerable <uint[]> > getRestrictions, RouterPoint source, IList <RouterPoint> targets, T maxSearch, List <uint> closures) { _routerDb = routerDb; _weightHandler = weightHandler; _source = source; _targets = targets; _maxSearch = maxSearch; _getRestrictions = getRestrictions; _closures = closures; }
public override Result <Route> BuildRoute <T>(IProfileInstance profile, WeightHandler <T> weightHandler, RouterPoint source, RouterPoint target, EdgePath <T> path) { var route = new Route(); route.Shape = new Coordinate[] { source.Location(), target.Location() }; return(new Result <Route>(route)); }
/// <summary> /// Creates a new algorithm. /// </summary> public VertexToVertexAlgorithm(DirectedMetaGraph graph, WeightHandler <T> weightHandler, DykstraSource <T>[] sources, DykstraSource <T>[] targets, T max) { _graph = graph; _sources = sources; _targets = targets; _weightHandler = weightHandler; _max = max; _buckets = new Dictionary <uint, Dictionary <int, EdgePath <T> > >(); }
/// <summary> /// Creates a new weight-matrix algorithm. /// </summary> public WeightMatrixAlgorithm(RouterBase router, Profile profile, WeightHandler <T> weightHandler, Coordinate[] locations, Func <RoutingEdge, int, bool> matchEdge) { _router = router; _profile = profile; _locations = locations; _matchEdge = matchEdge; _weightHandler = weightHandler; this.SearchDistanceInMeter = Constants.SearchDistanceInMeter; }
/// <summary> /// Creates a new priority calculator. /// </summary> public EdgeDifferencePriorityCalculator(DirectedDynamicGraph graph, WeightHandler <T> weightHandler, IWitnessCalculator <T> witnessCalculator) { _graph = graph; _witnessCalculator = witnessCalculator; _contractionCount = new Dictionary <uint, int>(); _depth = new Dictionary <long, int>(); _weightHandler = weightHandler; this.DifferenceFactor = 1; this.DepthFactor = 2; this.ContractedFactor = 1; }
/// <summary> /// Creates a new routing algorithm instance. /// </summary> public Dykstra(DirectedDynamicGraph graph, WeightHandler <T> weightHandler, IEnumerable <EdgePath <T> > sources, Func <uint, IEnumerable <uint[]> > getRestrictions, bool backward) { weightHandler.CheckCanUse(graph); _graph = graph; _getRestrictions = getRestrictions; _sources = sources.Select(x => { x.StripEdges(); return(x); }); _backward = backward; _weightHandler = weightHandler; }
/// <summary> /// Builds the potential shortcuts. /// </summary> public static void BuildShortcuts <T>(this VertexInfo <T> vertexinfo, WeightHandler <T> weightHandler) where T : struct { var vertex = vertexinfo.Vertex; var shortcuts = vertexinfo.Shortcuts; // loop over all edge-pairs once. var shortcut = new Shortcut <T>() { Backward = weightHandler.Infinite, Forward = weightHandler.Infinite }; var shortcutEdge = new OriginalEdge(); for (var j = 1; j < vertexinfo.Count; j++) { var edge1 = vertexinfo[j]; var edge1Weight = weightHandler.GetEdgeWeight(edge1); shortcutEdge.Vertex1 = edge1.Neighbour; // figure out what witness paths to calculate. for (var k = 0; k < j; k++) { var edge2 = vertexinfo[k]; var edge2Weight = weightHandler.GetEdgeWeight(edge2); shortcutEdge.Vertex2 = edge2.Neighbour; if (!(edge1Weight.Direction.B && edge2Weight.Direction.F) && !(edge1Weight.Direction.F && edge2Weight.Direction.B)) { // impossible route, do nothing. continue; } shortcut.Backward = weightHandler.Infinite; shortcut.Forward = weightHandler.Infinite; if (edge1Weight.Direction.B && edge2Weight.Direction.F) { shortcut.Forward = weightHandler.Add(edge1Weight.Weight, edge2Weight.Weight); } if (edge1Weight.Direction.F && edge2Weight.Direction.B) { shortcut.Backward = weightHandler.Add(edge1Weight.Weight, edge2Weight.Weight); } shortcuts.AddOrUpdate(shortcutEdge, shortcut, weightHandler); } } }
/// <summary> /// Gets the best path in this linked list. /// </summary> public EdgePath <T> Best(WeightHandler <T> weightHandler) { var best = this.Path; var current = this.Next; while (current != null) { if (weightHandler.IsSmallerThan(current.Path.Weight, best.Weight)) { best = current.Path; } current = current.Next; } return(best); }
/// Interface for per-tag custom weights. This method populates a per-Navigator list of custom weight handlers. /// A custom weight handler is associated with a tag and will be invoked whenever Path is considering the /// weight of an object with the corresponding tag. A neutral return value of a WeightHandler is 1.0f. public void RegisterWeightHandler(string tag, WeightHandler handler) { if (m_WeightHandlers.ContainsKey(tag)) { if (!m_WeightHandlers[tag].Contains(handler)) { m_WeightHandlers[tag].Add(handler); } } else { m_WeightHandlers[tag] = new List <WeightHandler> (); m_WeightHandlers[tag].Add(handler); } }
/// <summary> /// Creates a new hierarchy builder. /// </summary> public FastHierarchyBuilder(DirectedMetaGraph graph, WeightHandler <T> weightHandler) { weightHandler.CheckCanUse(graph); _graph = graph; _weightHandler = weightHandler; _vertexInfo = new VertexInfo <T>(); _depth = new Dictionary <long, int>(); _contractionCount = new Dictionary <uint, int>(); this.DifferenceFactor = 4; this.DepthFactor = 14; this.ContractedFactor = 1; }
/// <summary> /// Creates a new hierarchy builder. /// </summary> public HierarchyBuilder(DirectedMetaGraph graph, DykstraWitnessCalculator <T> witnessCalculator, WeightHandler <T> weightHandler) { weightHandler.CheckCanUse(graph); _graph = graph; _witnessCalculator = witnessCalculator; _weightHandler = weightHandler; _vertexInfo = new VertexInfo <T>(); _depth = new Dictionary <long, int>(); _contractionCount = new Dictionary <uint, int>(); this.DifferenceFactor = 5; this.DepthFactor = 5; this.ContractedFactor = 8; }
/// <summary> /// Creates a new contracted bidirectional router. /// </summary> public BidirectionalDykstra(DirectedDynamicGraph graph, WeightHandler <T> weightHandler, IEnumerable <EdgePath <T> > sources, IEnumerable <EdgePath <T> > targets, Func <uint, IEnumerable <uint[]> > getRestrictions) { weightHandler.CheckCanUse(graph); _graph = graph; _weightHandler = weightHandler; _sources = sources.Select(x => { x.StripEdges(); return(x); }); _targets = targets.Select(x => { x.StripEdges(); return(x); }); _getRestrictions = getRestrictions; }
/// <summary> /// Builds an edge path from a path consisiting of only vertices. /// </summary> public static EdgePath <T> BuildEdgePath <T>(this RouterDb routerDb, WeightHandler <T> weightHandler, RouterPoint source, RouterPoint target, List <uint> vertexPath) where T : struct { if (vertexPath == null || vertexPath.Count == 0) { return(null); } var path = new EdgePath <T>(vertexPath[0]); var i = 1; if (path.Vertex == Constants.NO_VERTEX) { // add first router point segment from source. path = source.EdgePathTo(routerDb, weightHandler, vertexPath[1]); i = 2; } var edgeEnumerator = routerDb.Network.GeometricGraph.Graph.GetEdgeEnumerator(); for (; i < vertexPath.Count; i++) { var vertex = vertexPath[i]; if (vertex == Constants.NO_VERTEX) { if (i != vertexPath.Count - 1) { throw new Exception("Invalid data found in vertex path: a non-vertex id was found at an invalid location."); } var toTarget = target.EdgePathTo(routerDb, weightHandler, path.Vertex, true); path = new EdgePath <T>(toTarget.Vertex, weightHandler.Add(toTarget.Weight, path.Weight), toTarget.Edge, path); break; } T weight; var best = edgeEnumerator.FindBestEdge(weightHandler, path.Vertex, vertexPath[i], out weight); if (best == Constants.NO_EDGE) { throw new Exception(string.Format("Cannot build vertex path, edge {0} -> {1} not found.", path.Vertex, vertexPath[i])); } path = new EdgePath <T>(vertexPath[i], weightHandler.Add(weight, path.Weight), best, path); } return(path); }
/// <summary> /// Generates an edge path for the given edge. /// </summary> public static EdgePath <T> GetPathForEdge <T>(this RouterDb routerDb, WeightHandler <T> weightHandler, RoutingEdge edge, bool edgeForward, bool asSource) where T : struct { var weight = weightHandler.Calculate(edge.Data.Profile, edge.Data.Distance); if (asSource) { if (edgeForward) { return(new EdgePath <T>(edge.To, weight, edge.IdDirected(), new EdgePath <T>(edge.From))); } return(new EdgePath <T>(edge.From, weight, -edge.IdDirected(), new EdgePath <T>(edge.To))); } else { if (edgeForward) { return(new EdgePath <T>(edge.From, weight, -edge.IdDirected(), new EdgePath <T>(edge.To))); } return(new EdgePath <T>(edge.To, weight, edge.IdDirected(), new EdgePath <T>(edge.From))); } }
public override Result <T[][]> TryCalculateWeight <T>(Profile profile, WeightHandler <T> weightHandler, RouterPoint[] sources, RouterPoint[] targets, ISet <int> invalidSources, ISet <int> invalidTargets, RoutingSettings <T> settings) { var weights = new T[sources.Length][]; for (var s = 0; s < sources.Length; s++) { weights[s] = new T[targets.Length]; for (var t = 0; t < sources.Length; t++) { weights[s][t] = weightHandler.Calculate(0, Coordinate.DistanceEstimateInMeter( new Coordinate(sources[s].Latitude, sources[s].Longitude), new Coordinate(targets[t].Latitude, targets[t].Longitude))); } } foreach (var invalid in _invalidSet) { invalidSources.Add(invalid); invalidTargets.Add(invalid); } return(new Result <T[][]>(weights)); }
/// <summary> /// Creates a new instance of search algorithm. /// </summary> public BidirectionalDykstra(Dykstra <T> sourceSearch, Dykstra <T> targetSearch, WeightHandler <T> weightHandler) { _sourceSearch = sourceSearch; _targetSearch = targetSearch; _weightHandler = weightHandler; }
/// <summary> /// Creates a new contracted graph and adds it to the router db for the given profile. /// </summary> public static void AddContracted <T>(this RouterDb db, Profiles.Profile profile, WeightHandler <T> weightHandler, bool forceEdgeBased = false) where T : struct { // create the raw directed graph. ContractedDb contractedDb = null; lock (db) { if (forceEdgeBased) { // edge-based is needed when complex restrictions found. var contracted = new DirectedDynamicGraph(weightHandler.DynamicSize); var directedGraphBuilder = new Itinero.Algorithms.Contracted.EdgeBased.DirectedGraphBuilder <T>(db.Network.GeometricGraph.Graph, contracted, weightHandler); directedGraphBuilder.Run(); // contract the graph. var priorityCalculator = new Itinero.Algorithms.Contracted.EdgeBased.EdgeDifferencePriorityCalculator <T>(contracted, weightHandler, new Itinero.Algorithms.Contracted.EdgeBased.Witness.DykstraWitnessCalculator <T>(weightHandler, int.MaxValue)); priorityCalculator.DifferenceFactor = 5; priorityCalculator.DepthFactor = 5; priorityCalculator.ContractedFactor = 8; var hierarchyBuilder = new Itinero.Algorithms.Contracted.EdgeBased.HierarchyBuilder <T>(contracted, priorityCalculator, new Itinero.Algorithms.Contracted.EdgeBased.Witness.DykstraWitnessCalculator <T>(weightHandler, int.MaxValue), weightHandler, db.GetGetRestrictions(profile, null)); hierarchyBuilder.Run(); contractedDb = new ContractedDb(contracted); } else { // vertex-based is ok when no complex restrictions found. var contracted = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, weightHandler.MetaSize); var directedGraphBuilder = new DirectedGraphBuilder <T>(db.Network.GeometricGraph.Graph, contracted, weightHandler); directedGraphBuilder.Run(); // contract the graph. var priorityCalculator = new EdgeDifferencePriorityCalculator(contracted, new DykstraWitnessCalculator(int.MaxValue)); priorityCalculator.DifferenceFactor = 5; priorityCalculator.DepthFactor = 5; priorityCalculator.ContractedFactor = 8; var hierarchyBuilder = new HierarchyBuilder <T>(contracted, priorityCalculator, new DykstraWitnessCalculator(int.MaxValue), weightHandler); hierarchyBuilder.Run(); contractedDb = new ContractedDb(contracted); } } // add the graph. lock (db) { db.AddContracted(profile, contractedDb); } }
/// <summary> /// Converts all the router points to vertex and weights with vertex id being the directed edge id. This results in one dykstra source of this routerpoint. /// </summary> public static DykstraSource <T>[] ToDualDykstraSources <T>(this RouterPoint[] points, RouterDb routerDb, WeightHandler <T> weightHandler, bool asSource) where T : struct { var results = new DykstraSource <T> [points.Length]; for (var i = 0; i < points.Length; i++) // TODO: this only reads stuff, perfect to parallelise { results[i] = points[i].ToDualDykstraSource(routerDb, weightHandler, asSource); } return(results); }
/// Interface for per-tag custom weights. This method populates a per-Navigator list of custom weight handlers. /// A custom weight handler is associated with a tag and will be invoked whenever Path is considering the /// weight of an object with the corresponding tag. A neutral return value of a WeightHandler is 1.0f. public void RegisterWeightHandler(string tag, WeightHandler handler) { if (m_WeightHandlers.ContainsKey (tag)) { if (!m_WeightHandlers[tag].Contains (handler)) { m_WeightHandlers[tag].Add (handler); } } else { m_WeightHandlers[tag] = new List<WeightHandler> (); m_WeightHandlers[tag].Add (handler); } }
/// <summary> /// Converts the router point to vertex and weights with vertex id being the directed edge id. This results in one dykstra source of this routerpoint. /// </summary> public static DykstraSource <T> ToDualDykstraSource <T>(this RouterPoint point, RouterDb routerDb, WeightHandler <T> weightHandler, bool asSource) where T : struct { var graph = routerDb.Network.GeometricGraph; var edge = graph.GetEdge(point.EdgeId); float distance; ushort profileId; EdgeDataSerializer.Deserialize(edge.Data[0], out distance, out profileId); Factor factor; var edgeWeight = weightHandler.Calculate(profileId, distance, out factor); var offset = point.Offset / (float)ushort.MaxValue; if (factor.Direction == 0) { // bidirectional. return(new DykstraSource <T> { Vertex1 = (new DirectedEdgeId(point.EdgeId, true)).Raw, Weight1 = weightHandler.Calculate(profileId, distance * offset), Vertex2 = (new DirectedEdgeId(point.EdgeId, false)).Raw, Weight2 = weightHandler.Calculate(profileId, distance * (1 - offset)) }); } else if (factor.Direction == 1) { // edge is forward oneway if (asSource) { return(new DykstraSource <T> { Vertex1 = (new DirectedEdgeId(point.EdgeId, true)).Raw, Weight1 = weightHandler.Calculate(profileId, distance * offset), Vertex2 = Constants.NO_VERTEX, Weight2 = weightHandler.Infinite }); } return(new DykstraSource <T> { Vertex1 = Constants.NO_VERTEX, Weight1 = weightHandler.Infinite, Vertex2 = (new DirectedEdgeId(point.EdgeId, false)).Raw, Weight2 = weightHandler.Calculate(profileId, distance * (1 - offset)) }); } else { // edge is backward oneway. if (asSource) { return(new DykstraSource <T> { Vertex1 = Constants.NO_VERTEX, Weight1 = weightHandler.Infinite, Vertex2 = (new DirectedEdgeId(point.EdgeId, false)).Raw, Weight2 = weightHandler.Calculate(profileId, distance * (1 - offset)) }); } return(new DykstraSource <T> { Vertex1 = (new DirectedEdgeId(point.EdgeId, true)).Raw, Weight1 = weightHandler.Calculate(profileId, distance * offset), Vertex2 = Constants.NO_VERTEX, Weight2 = weightHandler.Infinite }); } }