Example #1
0
        /// <summary>
        /// Expands an island starting the given vertex.
        /// </summary>
        private uint Expand(uint vertex, ushort island)
        {
            var min = uint.MaxValue;

            _enumerator.MoveTo(vertex);

            while (_enumerator.MoveNext())
            {
                var neighbour = _enumerator.To;
                if (_vertexFlags.Contains(neighbour))
                {
                    continue;
                }

                float  distance;
                ushort edgeProfile;
                EdgeDataSerializer.Deserialize(_enumerator.Data0, out distance, out edgeProfile);

                if (!_canTraverse.Contains(edgeProfile))
                {
                    continue;
                }

                _islands[neighbour] = island; // set the island.

                if (neighbour < min)
                {
                    min = neighbour;
                }
            }
            return(min);
        }
Example #2
0
        public void TestOneHop()
        {
            var graph = new Graph(1);

            graph.AddVertex(0);
            graph.AddVertex(1);
            graph.AddVertex(2);
            var edge1 = graph.AddEdge(0, 1, EdgeDataSerializer.Serialize(100, 1));
            var edge2 = graph.AddEdge(1, 2, EdgeDataSerializer.Serialize(100, 1));

            var dykstra = new DirectedDykstra <float>(graph, new DefaultWeightHandler((profile) => new Itinero.Profiles.Factor()
            {
                Direction = 0,
                Value     = 1
            }), new Itinero.Algorithms.Restrictions.RestrictionCollection((c, v) => false), new DirectedEdgeId(edge1, true), float.MaxValue, false);

            dykstra.WasFound = (p, e, w) =>
            {
                if (e.EdgeId == edge1)
                {
                    Assert.AreEqual(true, e.Forward);
                    Assert.AreEqual(0, w);
                }
                else if (e.EdgeId == edge2)
                {
                    Assert.AreEqual(true, e.Forward);
                    Assert.AreEqual(100, w);
                }
                return(false);
            };
            dykstra.Run();

            Assert.IsTrue(dykstra.HasRun);
            Assert.IsTrue(dykstra.HasSucceeded);
        }
        /// <summary>
        /// Finds the best edge between the two given vertices.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="graph"></param>
        /// <param name="weightHandler"></param>
        /// <param name="vertex1"></param>
        /// <param name="vertex2"></param>
        /// <returns></returns>
        public static long FindBestEdge <T>(this Graph.EdgeEnumerator edgeEnumerator, WeightHandler <T> weightHandler, uint vertex1, uint vertex2, out T bestWeight)
            where T : struct
        {
            edgeEnumerator.MoveTo(vertex1);
            bestWeight = weightHandler.Infinite;
            long   bestEdge = Constants.NO_EDGE;
            Factor factor;

            while (edgeEnumerator.MoveNext())
            {
                if (edgeEnumerator.To == vertex2)
                {
                    float  distance;
                    ushort edgeProfile;
                    EdgeDataSerializer.Deserialize(edgeEnumerator.Data0, out distance, out edgeProfile);
                    var weight = weightHandler.Calculate(edgeProfile, distance, out factor);

                    if (factor.Value > 0 && (factor.Direction == 0 ||
                                             ((factor.Direction == 1) && !edgeEnumerator.DataInverted) ||
                                             ((factor.Direction == 2) && edgeEnumerator.DataInverted)))
                    { // it's ok; the edge can be traversed by the given vehicle.
                        if (weightHandler.IsSmallerThan(weight, bestWeight))
                        {
                            bestWeight = weight;
                            bestEdge   = edgeEnumerator.IdDirected();
                        }
                    }
                }
            }
            return(bestEdge);
        }
Example #4
0
 public Func <GeometricEdge, bool> GetIsAcceptable(bool verifyCanStopOn, params Profile[] profiles)
 {
     if (!this.ContainsAll(profiles))
     {
         throw new ArgumentException("Not all given profiles are supported.");
     }
     ProfileFactorCache.CachedFactor[][] cachedFactors = new ProfileFactorCache.CachedFactor[profiles.Length][];
     for (int index = 0; index < profiles.Length; ++index)
     {
         cachedFactors[index] = this._edgeProfileFactors[profiles[index].Name];
     }
     return((Func <GeometricEdge, bool>)(edge =>
     {
         float distance;
         ushort profile;
         EdgeDataSerializer.Deserialize(edge.Data[0], out distance, out profile);
         for (int index = 0; index < profiles.Length; ++index)
         {
             ProfileFactorCache.CachedFactor cachedFactor = cachedFactors[index][(int)profile];
             if (verifyCanStopOn && (int)cachedFactor.Type > 4 || (double)cachedFactor.Value <= 0.0)
             {
                 return false;
             }
         }
         return true;
     }));
 }
Example #5
0
        public void TestSerialize()
        {
            var edgeData = new EdgeData()
            {
                Distance = 100.1f,
                Profile  = 12
            };

            var data = EdgeDataSerializer.Serialize(edgeData);

            Assert.IsNotNull(data);
            Assert.AreEqual(1, data.Length);
            Assert.AreEqual((uint)16384 * (uint)(edgeData.Distance * 10) + (uint)edgeData.Profile,
                            data[0]);

            edgeData = new EdgeData()
            {
                Distance = 0f,
                Profile  = 12
            };

            data = EdgeDataSerializer.Serialize(edgeData);
            Assert.IsNotNull(data);
            Assert.AreEqual(1, data.Length);
            Assert.AreEqual((uint)16384 * (uint)(edgeData.Distance * 10) + (uint)edgeData.Profile,
                            data[0]);

            edgeData = new EdgeData()
            {
                Distance = EdgeDataSerializer.MAX_DISTANCE,
                Profile  = EdgeDataSerializer.MAX_PROFILE_COUNT - 1
            };

            data = EdgeDataSerializer.Serialize(edgeData);
            Assert.IsNotNull(data);
            Assert.AreEqual(1, data.Length);
            Assert.AreEqual((uint)16384 * (uint)(edgeData.Distance * 10) + (uint)edgeData.Profile,
                            data[0]);

            edgeData = new EdgeData()
            {
                Distance = EdgeDataSerializer.MAX_DISTANCE + 0.1f,
                Profile  = EdgeDataSerializer.MAX_PROFILE_COUNT - 1
            };

            Assert.Catch <ArgumentOutOfRangeException>(() =>
            {
                EdgeDataSerializer.Serialize(edgeData);
            });
            edgeData = new EdgeData()
            {
                Distance = EdgeDataSerializer.MAX_DISTANCE,
                Profile  = EdgeDataSerializer.MAX_PROFILE_COUNT
            };
            Assert.Catch <ArgumentOutOfRangeException>(() =>
            {
                EdgeDataSerializer.Serialize(edgeData);
            });
        }
        public void TestOneEdgeAugmented()
        {
            // build graph.
            var graph = new Itinero.Graphs.Graph(EdgeDataSerializer.Size);

            graph.AddVertex(0);
            graph.AddVertex(1);
            graph.AddEdge(0, 1, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            }));

            // build speed profile function.
            var speed = 100f / 3.6f;
            Func <ushort, FactorAndSpeed> getFactor = (x) =>
            {
                return(new FactorAndSpeed()
                {
                    Direction = 0,
                    SpeedFactor = 1.0f / speed,
                    Value = 1.0f / speed
                });
            };

            // convert graph.
            var directedGraph = new DirectedDynamicGraph(ContractedEdgeDataSerializer.DynamicAugmentedFixedSize);
            var algorithm     = new DirectedGraphBuilder <Weight>(graph, directedGraph, new WeightHandler(getFactor));

            algorithm.Run();

            // check result.
            Assert.IsTrue(algorithm.HasRun);
            Assert.IsTrue(algorithm.HasSucceeded);

            directedGraph.Compress();
            Assert.AreEqual(2, directedGraph.VertexCount);
            Assert.AreEqual(2, directedGraph.EdgeCount);

            // verify all edges.
            var edges = directedGraph.GetEdgeEnumerator(0);

            Assert.AreEqual(1, edges.Count());
            var data = ContractedEdgeDataSerializer.SerializeDynamicAugmented(100 * getFactor(1).Value, null, 100, 100 * getFactor(1).Value);

            Assert.AreEqual(data[0], edges.First().Data[0]);
            Assert.AreEqual(data[1], edges.First().Data[1]);
            Assert.AreEqual(data[2], edges.First().Data[2]);
            Assert.AreEqual(1, edges.First().Neighbour);

            edges = directedGraph.GetEdgeEnumerator(1);
            Assert.AreEqual(1, edges.Count());
            data = ContractedEdgeDataSerializer.SerializeDynamicAugmented(100 * getFactor(1).Value, null, 100, 100 * getFactor(1).Value);
            Assert.AreEqual(data[0], edges.First().Data[0]);
            Assert.AreEqual(data[1], edges.First().Data[1]);
            Assert.AreEqual(data[2], edges.First().Data[2]);
            Assert.AreEqual(0, edges.First().Neighbour);
        }
Example #7
0
        public void TestOneEdge()
        {
            // build graph.
            var graph = new Itinero.Graphs.Graph(EdgeDataSerializer.Size);

            graph.AddVertex(0);
            graph.AddVertex(1);
            graph.AddEdge(0, 1, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            }));

            // build speed profile function.
            var speed = 100f / 3.6f;
            Func <ushort, Factor> getFactor = (x) =>
            {
                return(new Factor()
                {
                    Direction = 0,
                    Value = 1.0f / speed
                });
            };

            // convert graph.
            var directedGraph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size,
                                                      ContractedEdgeDataSerializer.MetaSize);
            var algorithm = new DirectedGraphBuilder(graph, directedGraph, getFactor);

            algorithm.Run();

            // check result.
            Assert.IsTrue(algorithm.HasRun);
            Assert.IsTrue(algorithm.HasSucceeded);

            directedGraph.Compress();
            Assert.AreEqual(2, directedGraph.VertexCount);
            Assert.AreEqual(2, directedGraph.EdgeCount);

            // verify all edges.
            var edges = directedGraph.GetEdgeEnumerator(0);

            Assert.AreEqual(1, edges.Count);
            var data = ContractedEdgeDataSerializer.Serialize(100 * getFactor(1).Value, null);

            Assert.AreEqual(data, edges.First().Data[0]);
            Assert.AreEqual(Constants.NO_VERTEX, edges.First().MetaData[0]);
            Assert.AreEqual(1, edges.First().Neighbour);

            edges = directedGraph.GetEdgeEnumerator(1);
            Assert.AreEqual(1, edges.Count);
            data = ContractedEdgeDataSerializer.Serialize(100 * getFactor(1).Value, null);
            Assert.AreEqual(data, edges.First().Data[0]);
            Assert.AreEqual(Constants.NO_VERTEX, edges.First().MetaData[0]);
            Assert.AreEqual(0, edges.First().Neighbour);
        }
Example #8
0
        public RoutingEdge GetEdge(uint edgeId)
        {
            GeometricEdge edge = this._graph.GetEdge(edgeId);

            OsmSharp.Routing.Data.EdgeData         edgeData = EdgeDataSerializer.Deserialize(edge.Data);
            OsmSharp.Routing.Network.Data.EdgeData data     = new OsmSharp.Routing.Network.Data.EdgeData()
            {
                MetaId   = this._edgeData[(long)edgeId],
                Distance = edgeData.Distance,
                Profile  = edgeData.Profile
            };
            return(new RoutingEdge(edge.Id, edge.From, edge.To, data, edge.DataInverted, edge.Shape));
        }
Example #9
0
        public void TestLoopRestricted()
        {
            var graph = new Graph(1);

            graph.AddVertex(0);
            graph.AddVertex(1);
            graph.AddVertex(2);
            graph.AddVertex(3);
            graph.AddVertex(4);
            graph.AddEdge(0, 1, EdgeDataSerializer.Serialize(100, 1));
            graph.AddEdge(1, 4, EdgeDataSerializer.Serialize(100, 1));
            graph.AddEdge(1, 2, EdgeDataSerializer.Serialize(100, 1));
            graph.AddEdge(2, 3, EdgeDataSerializer.Serialize(100, 1));
            graph.AddEdge(3, 1, EdgeDataSerializer.Serialize(100, 1));

            var dykstra = new Dykstra(graph, (profile) => new Itinero.Profiles.Factor()
            {
                Direction = 0,
                Value     = 1
            }, (vertex) =>
            {
                if (vertex == 0)
                {
                    return(new uint[][] { new uint[] { 0, 1, 4 } });
                }
                return(null);
            },
                                      new EdgePath <float>[]
            {
                new EdgePath <float>(1, 50, 1, new EdgePath <float>()),
                new EdgePath <float>(0, 50, -1, new EdgePath <float>())
            }, float.MaxValue, false);

            dykstra.Run();

            Assert.IsTrue(dykstra.HasRun);
            Assert.IsTrue(dykstra.HasSucceeded);
            EdgePath <float> visit;

            Assert.IsTrue(dykstra.TryGetVisit(-1, out visit) && visit.Weight == 50);
            Assert.IsTrue(dykstra.TryGetVisit(1, out visit) && visit.Weight == 50);
            Assert.IsFalse(dykstra.TryGetVisit(-2, out visit));
            Assert.IsTrue(dykstra.TryGetVisit(2, out visit) && visit.Weight == 450);
            Assert.IsTrue(dykstra.TryGetVisit(-3, out visit) && visit.Weight == 350);
            Assert.IsTrue(dykstra.TryGetVisit(3, out visit) && visit.Weight == 150);
            Assert.IsTrue(dykstra.TryGetVisit(-4, out visit) && visit.Weight == 250);
            Assert.IsTrue(dykstra.TryGetVisit(4, out visit) && visit.Weight == 250);
            Assert.IsTrue(dykstra.TryGetVisit(-5, out visit) && visit.Weight == 150);
            Assert.IsTrue(dykstra.TryGetVisit(4, out visit) && visit.Weight == 250);
        }
Example #10
0
        public void TestTwoHopRestricted()
        {
            var graph = new Graph(1);

            graph.AddVertex(0);
            graph.AddVertex(1);
            graph.AddVertex(2);
            graph.AddVertex(3);
            graph.AddEdge(0, 1, EdgeDataSerializer.Serialize(100, 1));
            graph.AddEdge(1, 2, EdgeDataSerializer.Serialize(100, 1));
            graph.AddEdge(2, 3, EdgeDataSerializer.Serialize(100, 1));

            var dykstra = new Dykstra(graph, (profile) => new Itinero.Profiles.Factor()
            {
                Direction = 0,
                Value     = 1
            }, (vertex) =>
            {
                if (vertex == 1)
                {
                    return(new uint[][] { new uint[] { 1, 2, 3 } });
                }
                return(null);
            },
                                      new EdgePath <float>[]
            {
                new EdgePath <float>(0, 50, 1, new EdgePath <float>()),
                new EdgePath <float>(1, 50, -1, new EdgePath <float>())
            }, float.MaxValue, new List <uint>(), false);

            dykstra.Run();

            Assert.IsTrue(dykstra.HasRun);
            Assert.IsTrue(dykstra.HasSucceeded);
            EdgePath <float> visit;

            Assert.IsTrue(dykstra.TryGetVisit(-1, out visit));
            Assert.AreEqual(-1, visit.Edge);
            Assert.AreEqual(50, visit.Weight);
            Assert.IsTrue(dykstra.TryGetVisit(1, out visit));
            Assert.AreEqual(1, visit.Edge);
            Assert.AreEqual(50, visit.Weight);
            Assert.IsTrue(dykstra.TryGetVisit(2, out visit));
            Assert.AreEqual(2, visit.Edge);
            Assert.AreEqual(150, visit.Weight);
            Assert.IsFalse(dykstra.TryGetVisit(-2, out visit));
            Assert.IsFalse(dykstra.TryGetVisit(3, out visit));
            Assert.IsFalse(dykstra.TryGetVisit(-2, out visit));
        }
Example #11
0
        public uint AddEdge(uint vertex1, uint vertex2, OsmSharp.Routing.Network.Data.EdgeData data, ShapeBase shape)
        {
            if ((double)data.Distance > (double)this._maxEdgeDistance)
            {
                throw new ArgumentException("data.Distance too big for this network.");
            }
            uint edgeId = this._graph.AddEdge(vertex1, vertex2, EdgeDataSerializer.Serialize(data.Distance, data.Profile), shape);

            if ((long)edgeId >= this._edgeData.Length)
            {
                this.IncreaseSizeEdgeData(edgeId);
            }
            this._edgeData[(long)edgeId] = data.MetaId;
            return(edgeId);
        }
Example #12
0
        protected override void DoRun()
        {
            bool?nullable = new bool?();
            Dictionary <ushort, Factor> dictionary = new Dictionary <ushort, Factor>();

            Graph.EdgeEnumerator edgeEnumerator = this._source.GetEdgeEnumerator();
            for (uint vertex = 0; vertex < this._source.VertexCount; ++vertex)
            {
                edgeEnumerator.MoveTo(vertex);
                edgeEnumerator.Reset();
                while (edgeEnumerator.MoveNext())
                {
                    float  distance;
                    ushort profile;
                    EdgeDataSerializer.Deserialize(edgeEnumerator.Data0, out distance, out profile);
                    Factor factor = Factor.NoFactor;
                    if (!dictionary.TryGetValue(profile, out factor))
                    {
                        factor = this._getFactor(profile);
                        dictionary[profile] = factor;
                    }
                    if ((double)factor.Value != 0.0)
                    {
                        bool?direction = new bool?();
                        if ((int)factor.Direction == 1)
                        {
                            direction = new bool?(true);
                            if (edgeEnumerator.DataInverted)
                            {
                                direction = new bool?(false);
                            }
                        }
                        else if ((int)factor.Direction == 2)
                        {
                            direction = new bool?(false);
                            if (edgeEnumerator.DataInverted)
                            {
                                direction = new bool?(true);
                            }
                        }
                        uint data = ContractedEdgeDataSerializer.Serialize(distance * factor.Value, direction);
                        int  num  = (int)this._target.AddEdge(edgeEnumerator.From, edgeEnumerator.To, data, 4294967294U);
                    }
                }
            }
            this.HasSucceeded = true;
        }
Example #13
0
        /// <summary>
        /// Executes the actual run.
        /// </summary>
        protected override void DoRun()
        {
            float  distance;
            ushort edgeProfile;
            bool?  direction = null;

            var factors        = new Dictionary <ushort, Factor>();
            var edgeEnumerator = _source.GetEdgeEnumerator();

            for (uint vertex = 0; vertex < _source.VertexCount; vertex++)
            {
                edgeEnumerator.MoveTo(vertex);
                edgeEnumerator.Reset();
                while (edgeEnumerator.MoveNext())
                {
                    EdgeDataSerializer.Deserialize(edgeEnumerator.Data0,
                                                   out distance, out edgeProfile);
                    Factor factor;
                    var    weight = _weightHandler.Calculate(edgeProfile, distance, out factor);

                    if (factor.Value != 0)
                    {
                        direction = null;
                        if (factor.Direction == 1)
                        {
                            direction = true;
                            if (edgeEnumerator.DataInverted)
                            {
                                direction = false;
                            }
                        }
                        else if (factor.Direction == 2)
                        {
                            direction = false;
                            if (edgeEnumerator.DataInverted)
                            {
                                direction = true;
                            }
                        }

                        _weightHandler.AddEdge(_target, edgeEnumerator.From, edgeEnumerator.To, direction, weight);
                    }
                }
            }

            this.HasSucceeded = true;
        }
Example #14
0
        public void TestTriangle()
        {
            var graph = new Graph(1);

            graph.AddVertex(0);
            graph.AddVertex(1);
            graph.AddVertex(2);
            graph.AddEdge(0, 1, EdgeDataSerializer.Serialize(100, 1));
            graph.AddEdge(1, 2, EdgeDataSerializer.Serialize(100, 1));
            graph.AddEdge(2, 0, EdgeDataSerializer.Serialize(100, 1));

            var dykstra = new Dykstra(graph, (profile) => new Itinero.Profiles.Factor()
            {
                Direction = 0,
                Value     = 1
            }, null,
                                      new EdgePath <float>[]
            {
                new EdgePath <float>(0, 50, 1, new EdgePath <float>()),
                new EdgePath <float>(1, 50, -1, new EdgePath <float>())
            }, float.MaxValue, false);

            dykstra.Run();

            Assert.IsTrue(dykstra.HasRun);
            Assert.IsTrue(dykstra.HasSucceeded);
            EdgePath <float> visit;

            Assert.IsTrue(dykstra.TryGetVisit(-1, out visit));
            Assert.AreEqual(-1, visit.Edge);
            Assert.AreEqual(50, visit.Weight);
            Assert.IsTrue(dykstra.TryGetVisit(1, out visit));
            Assert.AreEqual(1, visit.Edge);
            Assert.AreEqual(50, visit.Weight);
            Assert.IsTrue(dykstra.TryGetVisit(2, out visit));
            Assert.AreEqual(2, visit.Edge);
            Assert.AreEqual(150, visit.Weight);
            Assert.IsTrue(dykstra.TryGetVisit(-2, out visit));
            Assert.AreEqual(-2, visit.Edge);
            Assert.AreEqual(250, visit.Weight);
            Assert.IsTrue(dykstra.TryGetVisit(3, out visit));
            Assert.AreEqual(3, visit.Edge);
            Assert.AreEqual(250, visit.Weight);
            Assert.IsTrue(dykstra.TryGetVisit(-3, out visit));
            Assert.AreEqual(-3, visit.Edge);
            Assert.AreEqual(150, visit.Weight);
        }
Example #15
0
        public void TestTwoEdges()
        {
            // build graph.
            var graph = new Graph(EdgeDataSerializer.Size);

            graph.AddVertex(0);
            graph.AddVertex(1);
            graph.AddVertex(2);
            graph.AddEdge(0, 1, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            }));
            graph.AddEdge(1, 2, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            }));

            // build speed profile function.
            var speed = 100f / 3.6f;
            Func <ushort, Factor> getFactor = (x) =>
            {
                return(new Factor()
                {
                    Direction = 0,
                    Value = 1.0f / speed
                });
            };

            // run algorithm.
            var sourceSearch = new Dykstra(graph, getFactor, null, new EdgePath <float>[] { new EdgePath <float>(0) },
                                           150 * 1 / speed, false);
            var targetSearch = new Dykstra(graph, getFactor, null, new EdgePath <float>[] { new EdgePath <float>(2) },
                                           150 * 1 / speed, true);
            var algorithm = new BidirectionalDykstra(sourceSearch, targetSearch, getFactor);

            algorithm.Run();

            Assert.IsTrue(algorithm.HasRun);
            Assert.IsTrue(algorithm.HasSucceeded);

            Assert.AreEqual(1, algorithm.BestVertex);
            Assert.AreEqual(new uint[] { 0, 1, 2 }, algorithm.GetPath().ToListAsVertices().ToArray());
        }
Example #16
0
        public void TestOneEdge()
        {
            // build graph.
            var graph = new Graph(EdgeDataSerializer.Size);

            graph.AddVertex(0);
            graph.AddVertex(1);
            graph.AddEdge(0, 1, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            }));

            // build speed profile function.
            var speed = 100f / 3.6f;
            Func <ushort, Itinero.Profiles.Factor> getFactor = (x) =>
            {
                return(new Itinero.Profiles.Factor()
                {
                    Direction = 0,
                    Value = 1.0f / speed
                });
            };

            // run algorithm.
            var algorithm = new Dykstra(graph, getFactor, null, new EdgePath <float>[] { new EdgePath <float>(0) },
                                        float.MaxValue, false);

            algorithm.Run();

            Assert.IsTrue(algorithm.HasRun);
            Assert.IsTrue(algorithm.HasSucceeded);

            EdgePath <float> visit;

            Assert.IsTrue(algorithm.TryGetVisit(0, out visit));
            Assert.AreEqual(null, visit.From);
            Assert.AreEqual(0, visit.Vertex);
            Assert.AreEqual(0, visit.Weight);
            Assert.IsTrue(algorithm.TryGetVisit(1, out visit));
            Assert.AreEqual(0, visit.From.Vertex);
            Assert.AreEqual(1, visit.Vertex);
            Assert.AreEqual(100 / speed, visit.Weight);
        }
        /// <summary>
        /// Converts the router point to paths leading to the closest 2 vertices, always returning paths, event if length zero.
        /// </summary>
        internal static EdgePath <T>[] ToEdgePathsComplete <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);

            EdgeDataSerializer.Deserialize(edge.Data[0], out var distance, out var profileId);
            var edgeWeight = weightHandler.Calculate(profileId, distance, out var factor);

            var offset = point.Offset / (float)ushort.MaxValue;

            if (factor.Direction == 0)
            { // bidirectional.
                return(new EdgePath <T>[] {
                    new EdgePath <T>(edge.From, weightHandler.Calculate(profileId, distance * offset), -edge.IdDirected(), new EdgePath <T>()),
                    new EdgePath <T>(edge.To, weightHandler.Calculate(profileId, distance * (1 - offset)), edge.IdDirected(), new EdgePath <T>())
                });
            }
            else if (factor.Direction == 1)
            { // edge is forward oneway.
                if (asSource)
                {
                    return(new EdgePath <T>[] {
                        new EdgePath <T>(edge.To, weightHandler.Calculate(profileId, distance * (1 - offset)), edge.IdDirected(), new EdgePath <T>())
                    });
                }
                return(new EdgePath <T>[] {
                    new EdgePath <T>(edge.From, weightHandler.Calculate(profileId, distance * offset), -edge.IdDirected(), new EdgePath <T>())
                });
            }
            else
            { // edge is backward oneway.
                if (!asSource)
                {
                    return(new EdgePath <T>[] {
                        new EdgePath <T>(edge.To, weightHandler.Calculate(profileId, distance * (1 - offset)), edge.IdDirected(), new EdgePath <T>())
                    });
                }
                return(new EdgePath <T>[] {
                    new EdgePath <T>(edge.From, weightHandler.Calculate(profileId, distance * offset), -edge.IdDirected(), new EdgePath <T>())
                });
            }
        }
Example #18
0
        public void TestDeserialize()
        {
            var edge = EdgeDataSerializer.Deserialize(new uint[] { 0 });

            Assert.AreEqual(0, edge.Distance);
            Assert.AreEqual(0, edge.Profile);

            edge = EdgeDataSerializer.Deserialize(new uint[] { 10 });
            Assert.AreEqual(0, edge.Distance);
            Assert.AreEqual(10, edge.Profile);

            edge = EdgeDataSerializer.Deserialize(new uint[] { EdgeDataSerializer.MAX_PROFILE_COUNT - 1 });
            Assert.AreEqual(0, edge.Distance);
            Assert.AreEqual(EdgeDataSerializer.MAX_PROFILE_COUNT - 1, edge.Profile);

            edge = EdgeDataSerializer.Deserialize(new uint[] {
                (uint)16384 * (uint)(EdgeDataSerializer.MAX_DISTANCE * 10) +
                (uint)(EdgeDataSerializer.MAX_PROFILE_COUNT - 1)
            });
            Assert.AreEqual(EdgeDataSerializer.MAX_DISTANCE, edge.Distance, .1f);
            Assert.AreEqual(EdgeDataSerializer.MAX_PROFILE_COUNT - 1, edge.Profile);
        }
Example #19
0
 protected Func <GeometricEdge, bool> GetIsAcceptable(Profile[] profiles)
 {
     if (this.ProfileFactorCache != null && this.ProfileFactorCache.ContainsAll(profiles))
     {
         return(this.ProfileFactorCache.GetIsAcceptable(this.VerifyAllStoppable, profiles));
     }
     return((Func <GeometricEdge, bool>)(edge =>
     {
         float distance;
         ushort profile;
         EdgeDataSerializer.Deserialize(edge.Data[0], out distance, out profile);
         TagsCollectionBase attributes = this._db.EdgeProfiles.Get((uint)profile);
         for (int index = 0; index < profiles.Length; ++index)
         {
             if ((double)profiles[index].Factor(attributes).Value <= 0.0 || this.VerifyAllStoppable && !profiles[index].CanStopOn(attributes))
             {
                 return false;
             }
         }
         return true;
     }));
 }
Example #20
0
 /// <summary>
 /// Returns the IsAcceptable function to use in the default resolver algorithm.
 /// </summary>
 public static Func <GeometricEdge, bool> GetIsAcceptable(this RouterBase router, params Profile[] profiles)
 {
     if (router.ProfileFactorAndSpeedCache != null && router.ProfileFactorAndSpeedCache.ContainsAll(profiles))
     { // use cached version and don't consult profiles anymore.
         return(router.ProfileFactorAndSpeedCache.GetIsAcceptable(router.VerifyAllStoppable,
                                                                  profiles));
     }
     else
     {     // use the regular function, and consult profiles continuously.
         return((edge) =>
         { // check all profiles, they all need to be traversible.
           // get profile.
             float distance;
             ushort edgeProfileId;
             EdgeDataSerializer.Deserialize(edge.Data[0],
                                            out distance, out edgeProfileId);
             var edgeProfile = router.Db.EdgeProfiles.Get(edgeProfileId);
             for (var i = 0; i < profiles.Length; i++)
             {
                 // get factor from profile.
                 if (profiles[i].Factor(edgeProfile).Value <= 0)
                 { // cannot be traversed by this profile.
                     return false;
                 }
                 if (router.VerifyAllStoppable)
                 {     // verify stoppable.
                     if (!profiles[i].CanStopOn(edgeProfile))
                     { // this profile cannot stop on this edge.
                         return false;
                     }
                 }
             }
             return true;
         });
     }
 }
Example #21
0
        /// <summary>
        /// Executes one step in the search.
        /// </summary>
        public bool Step()
        {
            // while the visit list is not empty.
            _current = null;
            if (_heap.Count > 0)
            { // choose the next vertex.
                _current = _heap.Pop();
                while (_current != null && _visits.ContainsKey(_current.Vertex))
                {     // keep dequeuing.
                    if (_heap.Count == 0)
                    { // nothing more to pop.
                        break;
                    }

                    if (this.Visit != null &&
                        this.Visit(_current))
                    { // edge was found and true was returned, this search should stop.
                        return(false);
                    }

                    _current = _heap.Pop();
                }
            }

            if (_current != null &&
                !_visits.ContainsKey(_current.Vertex))
            { // we visit this one, set visit.
                _visits[_current.Vertex] = _current;
            }
            else
            { // route is not found, there are no vertices left
                // or the search went outside of the max bounds.
                return(false);
            }

            if (this.WasFound != null &&
                this.WasFound(_current.Vertex, _current.Weight))
            { // vertex was found and true was returned, this search should stop.
                return(false);
            }

            // check for restrictions.
            var restriction = Constants.NO_VERTEX;

            if (_getRestriction != null)
            {
                restriction = _getRestriction(_current.Vertex);
            }
            if (restriction != Constants.NO_VERTEX)
            { // this vertex is restricted, step is a success but just move
                // to the next one because this vertex's neighbours are not allowed.
                return(true);
            }

            if (this.Visit != null &&
                this.Visit(_current))
            { // edge was found and true was returned, this search should stop.
                return(false);
            }

            // get neighbours and queue them.
            _edgeEnumerator.MoveTo(_current.Vertex);
            while (_edgeEnumerator.MoveNext())
            {
                var edge      = _edgeEnumerator;
                var neighbour = edge.To;

                if (_current.From != null &&
                    _current.From.Vertex == neighbour)
                { // don't go back
                    continue;
                }

                if (this.Visit == null)
                {
                    if (_visits.ContainsKey(neighbour))
                    { // has already been choosen
                        continue;
                    }
                }

                // get the speed from cache or calculate.
                float  distance;
                ushort edgeProfile;
                EdgeDataSerializer.Deserialize(edge.Data0, out distance, out edgeProfile);
                var factor      = Factor.NoFactor;
                var totalWeight = _weightHandler.Add(_current.Weight, edgeProfile, distance, out factor);

                // check the tags against the interpreter.
                if (factor.Value > 0 && (factor.Direction == 0 ||
                                         (!_backward && (factor.Direction == 1) != edge.DataInverted) ||
                                         (_backward && (factor.Direction == 1) == edge.DataInverted)))
                { // it's ok; the edge can be traversed by the given vehicle.
                    // calculate neighbors weight.
                    var edgeWeight = (distance * factor.Value);

                    if (_weightHandler.IsSmallerThan(totalWeight, _sourceMax))
                    { // update the visit list.
                        _heap.Push(new EdgePath <T>(neighbour, totalWeight, edge.IdDirected(), _current),
                                   _weightHandler.GetMetric(totalWeight));
                    }
                    else
                    { // the maxium was reached.
                        this.MaxReached = true;
                    }
                }
            }
            return(true);
        }
Example #22
0
        /// <summary>
        /// Executes the actual algorithm.
        /// </summary>
        protected override void DoRun()
        {
            float  distance;
            ushort edgeProfile;

            var enumerator1 = _source.GetEdgeEnumerator();
            var enumerator2 = _source.GetEdgeEnumerator();

            for (uint v = 0; v < _source.VertexCount; v++)
            {
                enumerator1.MoveTo(v);
                while (enumerator1.MoveNext())
                {
                    EdgeDataSerializer.Deserialize(enumerator1.Data0,
                                                   out distance, out edgeProfile);
                    var accessible1 = false;
                    var weight1     = _weightHandler.CalculateWeightAndDir(edgeProfile, distance, out accessible1);
                    if (enumerator1.DataInverted)
                    {
                        var dir = weight1.Direction;
                        dir.Reverse();
                        weight1.Direction = dir;
                    }
                    if (!accessible1)
                    { // not accessible.
                        continue;
                    }
                    var direction1 = weight1.Direction;
                    var edge1      = enumerator1.DirectedEdgeId();

                    // look at the neighbours of this edge.
                    enumerator2.MoveTo(enumerator1.To);
                    _restrictions.Update(enumerator1.To);
                    while (enumerator2.MoveNext())
                    {
                        var turn = new Turn(new OriginalEdge(v, enumerator1.To), Constants.NO_VERTEX);
                        EdgeDataSerializer.Deserialize(enumerator2.Data0,
                                                       out distance, out edgeProfile);
                        var accessible2 = false;
                        var weight2     = _weightHandler.CalculateWeightAndDir(edgeProfile, distance, out accessible2);
                        if (enumerator2.DataInverted)
                        {
                            var dir = weight2.Direction;
                            dir.Reverse();
                            weight2.Direction = dir;
                        }
                        if (!accessible2)
                        { // not accessible.
                            continue;
                        }

                        var direction2 = weight2.Direction;
                        turn.Vertex3 = enumerator2.To;
                        if (turn.IsUTurn)
                        { // is a u-turn, leave this out!
                            continue;
                        }

                        var direction = Dir.Combine(direction1, direction2);

                        if (direction.F &&
                            turn.IsRestrictedBy(_restrictions))
                        { // turn is restricted.
                            direction.F = false;
                        }

                        if (!direction.F)
                        { // there is no possible combination for these two edges.
                            continue;
                        }

                        // ok, we need to add this edge, it's a non-restricted turn, not a u-turn and edges are in correct direction.
                        var edge2 = enumerator2.DirectedEdgeId();

                        _weightHandler.AddOrUpdateEdge(_target, edge1.Raw, edge2.Raw, Constants.NO_VERTEX, true,
                                                       weight1.Weight);
                        //direction.Reverse();
                        _weightHandler.AddOrUpdateEdge(_target, edge2.Raw, edge1.Raw, Constants.NO_VERTEX, false,
                                                       weight1.Weight);
                    }
                }
            }
        }
Example #23
0
        public void TestSourceBetween()
        {
            // build graph.
            var graph = new Graph(EdgeDataSerializer.Size);

            graph.AddVertex(0);
            graph.AddVertex(1);
            graph.AddVertex(2);
            graph.AddEdge(0, 1, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            }));
            graph.AddEdge(1, 2, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            }));
            graph.AddEdge(0, 2, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            }));

            // build speed profile function.
            var speed = 100f / 3.6f;
            Func <ushort, Factor> getFactor = (x) =>
            {
                return(new Factor()
                {
                    Direction = 1,
                    Value = 1.0f / speed
                });
            };

            // run algorithm.
            var algorithm = new Dykstra(graph, getFactor, null, new EdgePath <float>[] {
                new EdgePath <float>(0, 10 / speed, new EdgePath <float>(uint.MaxValue)),
                new EdgePath <float>(1, 90 / speed, new EdgePath <float>(uint.MaxValue))
            },
                                        float.MaxValue, new List <uint>(), false);

            algorithm.Run();

            Assert.IsTrue(algorithm.HasRun);
            Assert.IsTrue(algorithm.HasSucceeded);

            EdgePath <float> visit;

            Assert.IsTrue(algorithm.TryGetVisit(0, out visit));
            Assert.IsNotNull(visit.From);
            Assert.AreEqual(uint.MaxValue, visit.From.Vertex);
            Assert.AreEqual(0, visit.Vertex);
            Assert.AreEqual(10 / speed, visit.Weight);
            Assert.IsTrue(algorithm.TryGetVisit(1, out visit));
            Assert.IsNotNull(visit.From);
            Assert.AreEqual(uint.MaxValue, visit.From.Vertex);
            Assert.AreEqual(1, visit.Vertex);
            Assert.AreEqual(90 / speed, visit.Weight);
            Assert.IsTrue(algorithm.TryGetVisit(2, out visit));
            Assert.IsNotNull(visit.From);
            Assert.AreEqual(0, visit.From.Vertex);
            Assert.AreEqual(2, visit.Vertex);
            Assert.AreEqual(110 / speed, visit.Weight);
        }
Example #24
0
 /// <summary>
 /// Returns the IsAcceptable function to use in the default resolver algorithm.
 /// </summary>
 public static Func <GeometricEdge, bool> GetIsAcceptable(this RouterBase router, params IProfileInstance[] profiles)
 {
     if (router.ProfileFactorAndSpeedCache != null && router.ProfileFactorAndSpeedCache.ContainsAll(profiles))
     { // use cached version and don't consult profiles anymore.
         return(router.ProfileFactorAndSpeedCache.GetIsAcceptable(router.VerifyAllStoppable,
                                                                  profiles));
     }
     else
     {     // use the regular function, and consult profiles continuously.
         if (router.ProfileFactorAndSpeedCache != null)
         { // when there is a cache, built it on demand.
             var profileNames = new StringBuilder();
             var profileArray = new Profile[profiles.Length];
             for (var i = 0; i < profiles.Length; i++)
             {
                 if (i > 0)
                 {
                     profileNames.Append(',');
                 }
                 profileNames.Append(profiles[i].Profile.FullName);
                 profileArray[i] = profiles[i].Profile;
             }
             Itinero.Logging.Logger.Log("RouterBaseExtensions", TraceEventType.Information, "Profile(s) {0} not cached, building cache.",
                                        profileNames.ToInvariantString());
             router.ProfileFactorAndSpeedCache.CalculateFor(profileArray);
             return(router.ProfileFactorAndSpeedCache.GetIsAcceptable(router.VerifyAllStoppable,
                                                                      profiles));
         }
         else
         {
             Itinero.Logging.Logger.Log("RouterBaseExtensions", TraceEventType.Warning,
                                        "Not all profiles are cached, this could slow down routing significantly, consider building a profile cache.");
             return((edge) =>
             { // check all profiles, they all need to be traversible.
               // get profile.
                 float distance;
                 ushort edgeProfileId;
                 EdgeDataSerializer.Deserialize(edge.Data[0],
                                                out distance, out edgeProfileId);
                 var edgeProfile = router.Db.EdgeProfiles.Get(edgeProfileId);
                 for (var i = 0; i < profiles.Length; i++)
                 {
                     var factorAndSpeed = profiles[i].Profile.FactorAndSpeed(edgeProfile);
                     // get factor from profile.
                     if (factorAndSpeed.Value <= 0)
                     { // cannot be traversed by this profile.
                         return false;
                     }
                     if (router.VerifyAllStoppable)
                     {     // verify stoppable.
                         if (!factorAndSpeed.CanStopOn())
                         { // this profile cannot stop on this edge.
                             return false;
                         }
                     }
                     if (profiles[i].IsConstrained(factorAndSpeed.Constraints))
                     { // this edge is constrained, this vehicle cannot travel here.
                         return false;
                     }
                 }
                 return true;
             });
         }
     }
 }
Example #25
0
        public void TestEdgeVisits()
        {
            // build graph.
            var graph = new Graph(EdgeDataSerializer.Size);

            graph.AddVertex(0);
            graph.AddVertex(1);
            graph.AddVertex(2);
            var e01 = graph.AddEdge(0, 1, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            })) + 1;
            var e12 = graph.AddEdge(1, 2, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            })) + 1;
            var e02 = graph.AddEdge(0, 2, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            })) + 1;

            // build speed profile function.
            var speed = 100f / 3.6f;
            Func <ushort, Factor> getFactor = (x) =>
            {
                return(new Factor()
                {
                    Direction = 0,
                    Value = 1.0f / speed
                });
            };

            // run algorithm.
            var reportedEdges = new HashSet <long>();
            var algorithm     = new Dykstra(graph, getFactor, null, new EdgePath <float>[] { new EdgePath <float>(0) }, float.MaxValue, false);

            algorithm.Visit += (path) =>
            {
                if (path.From == null)
                {
                    return(false);
                }

                var    v1   = path.From.Vertex;
                var    v2   = path.Vertex;
                var    w1   = path.From.Weight;
                var    w2   = path.Weight;
                var    e    = path.Edge;
                var    edge = graph.GetEdge(e);
                float  l;
                ushort p;
                Itinero.Data.Edges.EdgeDataSerializer.Deserialize(edge.Data[0], out l, out p);

                if (v1 == 0 && v2 == 1)
                {
                    Assert.AreEqual(100, l);
                    Assert.AreEqual(e01, e);
                    Assert.AreEqual(0, w1);
                    Assert.AreEqual(100 / speed, w2);
                    reportedEdges.Add(e01);
                }
                else if (v1 == 1 && v2 == 0)
                {
                    Assert.AreEqual(100, l);
                    Assert.AreEqual(-e01, e);
                    Assert.AreEqual(100 / speed, w1);
                    Assert.AreEqual(200 / speed, w2);
                    reportedEdges.Add(-e01);
                }
                else if (v1 == 0 && v2 == 2)
                {
                    Assert.AreEqual(100, l);
                    Assert.AreEqual(e02, e);
                    Assert.AreEqual(0, w1);
                    Assert.AreEqual(100 / speed, w2);
                    reportedEdges.Add(e02);
                }
                else if (v1 == 2 && v2 == 0)
                {
                    Assert.AreEqual(100, l);
                    Assert.AreEqual(-e02, e);
                    Assert.AreEqual(100 / speed, w1);
                    Assert.AreEqual(200 / speed, w2);
                    reportedEdges.Add(-e02);
                }
                else if (v1 == 1 && v2 == 2)
                {
                    Assert.AreEqual(100, l);
                    Assert.AreEqual(e12, e);
                    Assert.AreEqual(100 / speed, w1);
                    Assert.AreEqual(200 / speed, w2);
                    reportedEdges.Add(e12);
                }
                else if (v1 == 2 && v2 == 1)
                {
                    Assert.AreEqual(100, l);
                    Assert.AreEqual(-e12, e);
                    Assert.AreEqual(100 / speed, w1);
                    Assert.AreEqual(200 / speed, w2);
                    reportedEdges.Add(-e12);
                }
                return(false);
            };
            algorithm.Run();

            Assert.IsTrue(algorithm.HasRun);
            Assert.IsTrue(algorithm.HasSucceeded);

            Assert.IsTrue(reportedEdges.Contains(e01));
            Assert.IsTrue(reportedEdges.Contains(e02));
        }
Example #26
0
        /// <summary>
        /// Executes one step in the search.
        /// </summary>
        public bool Step()
        {
            // while the visit list is not empty.
            _current = null;
            if (_heap.Count > 0)
            { // choose the next vertex.
                _current = _heap.Pop();
                while (_current != null && _visits.ContainsKey(_current.Edge))
                {     // keep dequeuing.
                    if (_heap.Count == 0)
                    { // nothing more to pop.
                        break;
                    }
                    _current = _heap.Pop();
                }
            }

            if (_current != null)
            { // we visit this one, set visit.
                if (_current.Edge != Constants.NO_EDGE)
                {
                    _visits[_current.Edge] = _current;

                    // report on visit.
                    if (this.Visit != null)
                    {
                        if (this.Visit(_current))
                        {
                            return(true);
                        }
                    }
                }
            }
            else
            { // route is not found, there are no vertices left
                // or the search went outside of the max bounds.
                return(false);
            }

            // move to the current edge's target vertex.
            _edgeEnumerator.MoveTo(_current.Vertex);

            // get new restrictions at the current vertex.
            LinkedRestriction restrictions = null;

            if (_edgeRestrictions.TryGetValue(_current, out restrictions))
            {
                _edgeRestrictions.Remove(_current);
            }
            if (_getRestriction != null)
            {
                var targetVertexRestriction = _getRestriction(_current.Vertex);
                if (targetVertexRestriction != null)
                {
                    foreach (var restriction in targetVertexRestriction)
                    {
                        if (restriction != null &&
                            restriction.Length > 0)
                        {
                            if (restriction.Length == 1)
                            { // a simple restriction, restricted vertex, no need to check outgoing edges.
                                return(true);
                            }
                            else
                            { // a complex restriction.
                                restrictions = new LinkedRestriction()
                                {
                                    Restriction = restriction,
                                    Next        = restrictions
                                };
                            }
                        }
                    }
                }
            }
            while (_edgeEnumerator.MoveNext())
            {
                var edge           = _edgeEnumerator;
                var directedEdgeId = _edgeEnumerator.IdDirected();
                var neighbour      = edge.To;

                if (directedEdgeId == -_current.Edge)
                { // don't go back.
                    continue;
                }

                if (_visits.ContainsKey(directedEdgeId))
                { // has already been choosen.
                    continue;
                }

                // get the speed from cache or calculate.
                float  distance;
                ushort edgeProfile;
                EdgeDataSerializer.Deserialize(edge.Data0, out distance, out edgeProfile);
                var factor     = Factor.NoFactor;
                var edgeWeight = _weightHandler.Calculate(edgeProfile, distance, out factor);

                // check the tags against the interpreter.
                if (factor.Value > 0 && (factor.Direction == 0 ||
                                         (!_backward && (factor.Direction == 1) != edge.DataInverted) ||
                                         (_backward && (factor.Direction == 1) == edge.DataInverted)))
                { // it's ok; the edge can be traversed by the given vehicle.
                    // verify restriction(s).
                    var currentRestriction            = restrictions;
                    var forbidden                     = false;
                    LinkedRestriction newRestrictions = null;
                    while (currentRestriction != null)
                    { // check if some restriction prohibits this move or if we need add a new restriction
                        // for the current edge.
                        if (currentRestriction.Restriction[1] == _edgeEnumerator.To)
                        {     // ok restrictions applies to this edge and the previous one.
                            if (currentRestriction.Restriction.Length == 2)
                            { // ok this is the last edge in this restriction, prohibit this move.
                                forbidden = true;
                                break;
                            }
                            else
                            { // append this restriction to the restrictions in for the current edge.
                                newRestrictions = new LinkedRestriction()
                                {
                                    Restriction = currentRestriction.Restriction.SubArray(1, currentRestriction.Restriction.Length - 1),
                                    Next        = newRestrictions
                                };
                            }
                        }
                        currentRestriction = currentRestriction.Next;
                    }
                    if (forbidden)
                    { // move to next neighbour.
                        continue;
                    }

                    // calculate neighbors weight.
                    var totalWeight = _weightHandler.Add(_current.Weight, edgeWeight);
                    if (_weightHandler.IsSmallerThan(totalWeight, _sourceMax))
                    { // update the visit list.
                        var path = new EdgePath <T>(neighbour, totalWeight, directedEdgeId, _current);
                        if (newRestrictions != null)
                        {
                            _edgeRestrictions[path] = newRestrictions;
                        }
                        _heap.Push(path, _weightHandler.GetMetric(totalWeight));
                    }
                    else
                    { // the maxium was reached.
                        this.MaxReached = true;
                    }
                }
            }
            return(true);
        }
Example #27
0
        public void TestEdgeVisits()
        {
            // build graph.
            var graph = new Graph(EdgeDataSerializer.Size);

            graph.AddVertex(0);
            graph.AddVertex(1);
            graph.AddVertex(2);
            var e01 = graph.AddEdge(0, 1, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            })) + 1;
            var e12 = graph.AddEdge(1, 2, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            })) + 1;
            var e02 = graph.AddEdge(0, 2, EdgeDataSerializer.Serialize(new EdgeData()
            {
                Distance = 100,
                Profile  = 1
            })) + 1;

            // build speed profile function.
            var speed = 100f / 3.6f;
            Func <ushort, Factor> getFactor = (x) =>
            {
                return(new Factor()
                {
                    Direction = 0,
                    Value = 1.0f / speed
                });
            };

            // run algorithm.
            var reportedEdges = new HashSet <long>();
            var algorithm     = new Dykstra(graph, getFactor, null, new EdgePath <float>[] { new EdgePath <float>(0) }, float.MaxValue, false);

            algorithm.WasEdgeFound += (v1, v2, w1, w2, e, l) =>
            {
                if (v1 == 0 && v2 == 1)
                {
                    Assert.AreEqual(100, l);
                    Assert.AreEqual(e01, e);
                    Assert.AreEqual(0, w1);
                    Assert.AreEqual(100 / speed, w2);
                    reportedEdges.Add(e01);
                }
                else if (v1 == 1 && v2 == 0)
                {
                    Assert.AreEqual(100, l);
                    Assert.AreEqual(-e01, e);
                    Assert.AreEqual(100 / speed, w1);
                    Assert.AreEqual(200 / speed, w2);
                    reportedEdges.Add(-e01);
                }
                else if (v1 == 0 && v2 == 2)
                {
                    Assert.AreEqual(100, l);
                    Assert.AreEqual(e02, e);
                    Assert.AreEqual(0, w1);
                    Assert.AreEqual(100 / speed, w2);
                    reportedEdges.Add(e02);
                }
                else if (v1 == 2 && v2 == 0)
                {
                    Assert.AreEqual(100, l);
                    Assert.AreEqual(-e02, e);
                    Assert.AreEqual(100 / speed, w1);
                    Assert.AreEqual(200 / speed, w2);
                    reportedEdges.Add(-e02);
                }
                else if (v1 == 1 && v2 == 2)
                {
                    Assert.AreEqual(100, l);
                    Assert.AreEqual(e12, e);
                    Assert.AreEqual(100 / speed, w1);
                    Assert.AreEqual(200 / speed, w2);
                    reportedEdges.Add(e12);
                }
                else if (v1 == 2 && v2 == 1)
                {
                    Assert.AreEqual(100, l);
                    Assert.AreEqual(-e12, e);
                    Assert.AreEqual(100 / speed, w1);
                    Assert.AreEqual(200 / speed, w2);
                    reportedEdges.Add(-e12);
                }
                return(false);
            };
            algorithm.Run();

            Assert.IsTrue(algorithm.HasRun);
            Assert.IsTrue(algorithm.HasSucceeded);

            Assert.IsTrue(reportedEdges.Contains(e01));
            Assert.IsTrue(reportedEdges.Contains(-e01));
            Assert.IsTrue(reportedEdges.Contains(e02));
            Assert.IsTrue(reportedEdges.Contains(-e02));
            Assert.IsTrue(reportedEdges.Contains(e12));
            Assert.IsTrue(reportedEdges.Contains(-e12));
        }
Example #28
0
        /// <summary>
        /// Converts the router point to paths leading to the closest 2 vertices.
        /// </summary>
        public static EdgePath <T>[] ToEdgePaths <T>(this RouterPoint point, RouterDb routerDb, WeightHandler <T> weightHandler, bool asSource, bool?forward)
            where T : struct
        {
            if (forward == null)
            { // don't-care direction, use default implementation.
                return(point.ToEdgePaths(routerDb, weightHandler, asSource));
            }

            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.
                if (forward.Value)
                {
                    return(new EdgePath <T>[] {
                        new EdgePath <T>(edge.To, weightHandler.Calculate(profileId, distance * (1 - offset)), edge.IdDirected(), new EdgePath <T>())
                    });
                }
                return(new EdgePath <T>[] {
                    new EdgePath <T>(edge.From, weightHandler.Calculate(profileId, distance * offset), -edge.IdDirected(), new EdgePath <T>())
                });
            }
            else if (factor.Direction == 1)
            { // edge is forward oneway.
                if (asSource)
                {
                    if (forward.Value)
                    {
                        return(new EdgePath <T>[] {
                            new EdgePath <T>(edge.To, weightHandler.Calculate(profileId, distance * (1 - offset)), edge.IdDirected(), new EdgePath <T>())
                        });
                    }
                    return(new EdgePath <T> [0]);
                }
                if (forward.Value)
                {
                    return(new EdgePath <T> [0]);
                }
                return(new EdgePath <T>[] {
                    new EdgePath <T>(edge.From, weightHandler.Calculate(profileId, distance * offset), -edge.IdDirected(), new EdgePath <T>())
                });
            }
            else
            { // edge is backward oneway.
                if (!asSource)
                {
                    if (forward.Value)
                    {
                        return(new EdgePath <T>[] {
                            new EdgePath <T>(edge.To, weightHandler.Calculate(profileId, distance * (1 - offset)), edge.IdDirected(), new EdgePath <T>())
                        });
                    }
                    return(new EdgePath <T> [0]);
                }
                if (forward.Value)
                {
                    return(new EdgePath <T> [0]);
                }
                return(new EdgePath <T>[] {
                    new EdgePath <T>(edge.From, weightHandler.Calculate(profileId, distance * offset), -edge.IdDirected(), new EdgePath <T>())
                });
            }
        }
Example #29
0
        /// <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
                });
            }
        }
Example #30
0
        /// <summary>
        /// Converts the router point to paths leading to the closest 2 vertices.
        /// </summary>
        public static EdgePath <T>[] ToEdgePaths <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.
                if (offset == 0)
                { // the first part is just the first vertex.
                    return(new EdgePath <T>[] {
                        new EdgePath <T>(edge.From),
                        new EdgePath <T>(edge.To, weightHandler.Calculate(profileId, distance * (1 - offset)), edge.IdDirected(), new EdgePath <T>(edge.From))
                    });
                }
                else if (offset == 1)
                { // the second path it just the second vertex.
                    return(new EdgePath <T>[] {
                        new EdgePath <T>(edge.From, weightHandler.Calculate(profileId, distance * offset), -edge.IdDirected(), new EdgePath <T>(edge.To)),
                        new EdgePath <T>(edge.To)
                    });
                }
                return(new EdgePath <T>[] {
                    new EdgePath <T>(edge.From, weightHandler.Calculate(profileId, distance * offset), -edge.IdDirected(), new EdgePath <T>()),
                    new EdgePath <T>(edge.To, weightHandler.Calculate(profileId, distance * (1 - offset)), edge.IdDirected(), new EdgePath <T>())
                });
            }
            else if (factor.Direction == 1)
            { // edge is forward oneway.
                if (asSource)
                {
                    if (offset == 1)
                    { // just return the to-vertex.
                        return(new EdgePath <T>[] {
                            new EdgePath <T>(edge.To)
                        });
                    }
                    if (offset == 0)
                    { // return both, we are at the from-vertex.
                        return(new EdgePath <T>[] {
                            new EdgePath <T>(edge.From),
                            new EdgePath <T>(edge.To, weightHandler.Calculate(profileId, distance * (1 - offset)), edge.IdDirected(), new EdgePath <T>(edge.From))
                        });
                    }
                    return(new EdgePath <T>[] {
                        new EdgePath <T>(edge.To, weightHandler.Calculate(profileId, distance * (1 - offset)), edge.IdDirected(), new EdgePath <T>())
                    });
                }
                if (offset == 0)
                { // just return the from vertex.
                    return(new EdgePath <T>[] {
                        new EdgePath <T>(edge.From)
                    });
                }
                if (offset == 1)
                { // return both, we are at the to-vertex.
                    return(new EdgePath <T>[] {
                        new EdgePath <T>(edge.To),
                        new EdgePath <T>(edge.From, weightHandler.Calculate(profileId, distance * offset), -edge.IdDirected(), new EdgePath <T>(edge.To))
                    });
                }
                return(new EdgePath <T>[] {
                    new EdgePath <T>(edge.From, weightHandler.Calculate(profileId, distance * offset), -edge.IdDirected(), new EdgePath <T>())
                });
            }
            else
            { // edge is backward oneway.
                if (!asSource)
                {
                    if (offset == 1)
                    { // just return the to-vertex.
                        return(new EdgePath <T>[] {
                            new EdgePath <T>(edge.To)
                        });
                    }
                    if (offset == 0)
                    { // return both, we are at the from-vertex.
                        return(new EdgePath <T>[] {
                            new EdgePath <T>(edge.From),
                            new EdgePath <T>(edge.To, weightHandler.Calculate(profileId, distance * (1 - offset)), edge.IdDirected(), new EdgePath <T>(edge.From))
                        });
                    }
                    return(new EdgePath <T>[] {
                        new EdgePath <T>(edge.To, weightHandler.Calculate(profileId, distance * (1 - offset)), edge.IdDirected(), new EdgePath <T>())
                    });
                }
                if (offset == 0)
                { // just return the from-vertex.
                    return(new EdgePath <T>[] {
                        new EdgePath <T>(edge.From)
                    });
                }
                if (offset == 1)
                { // return both, we are at the to-vertex.
                    return(new EdgePath <T>[] {
                        new EdgePath <T>(edge.To),
                        new EdgePath <T>(edge.From, weightHandler.Calculate(profileId, distance * offset), -edge.IdDirected(), new EdgePath <T>(edge.To))
                    });
                }
                return(new EdgePath <T>[] {
                    new EdgePath <T>(edge.From, weightHandler.Calculate(profileId, distance * offset), -edge.IdDirected(), new EdgePath <T>())
                });
            }
        }