Пример #1
0
        /// <summary>
        /// Executes one step in the search.
        /// </summary>
        public bool Step()
        {
            // while the visit list is not empty.
            var cPointer = uint.MaxValue;

            while (cPointer == uint.MaxValue)
            { // choose the next edge.
                if (_pointerHeap.Count == 0)
                {
                    return(false);
                }
                cPointer = _pointerHeap.Pop();
            }

            // get details.
            uint cEdge, cPreviousPointer;
            T    cWeight;

            _weightHandler.GetPathTree(_pathTree, cPointer, out cEdge, out cWeight, out cPreviousPointer);
            if (_visits.Contains(cEdge))
            {
                return(true);
            }
            _visits.Add(cEdge);
            var cDirectedEdge = new DirectedEdgeId()
            {
                Raw = cEdge
            };

            // signal was found.
            if (this.WasFound != null)
            {
                this.WasFound(cPointer, cDirectedEdge, cWeight);
            }

            // move to the current edge's target vertex.
            _edgeEnumerator.MoveToEdge(cDirectedEdge.EdgeId);
            var cOriginalEdge = new OriginalEdge(_edgeEnumerator.From, _edgeEnumerator.To);

            if (!cDirectedEdge.Forward)
            {
                cOriginalEdge = cOriginalEdge.Reverse();
            }
            var cEdgeWeightAndDirection = _weightHandler.GetEdgeWeight(_edgeEnumerator);

            // calculate total weight.
            var totalWeight = _weightHandler.Add(cEdgeWeightAndDirection.Weight, cWeight);

            if (!_weightHandler.IsSmallerThan(totalWeight, _sourceMax))
            { // weight is too big.
                this.MaxReached = true;
                return(true);
            }

            // loop over all neighbours.
            _edgeEnumerator.MoveTo(cOriginalEdge.Vertex2);
            var turn = new Turn(cOriginalEdge, Constants.NO_VERTEX);

            _restrictions.Update(turn.Vertex2);
            while (_edgeEnumerator.MoveNext())
            {
                turn.Vertex3 = _edgeEnumerator.To;
                if (turn.IsUTurn ||
                    turn.IsRestrictedBy(_restrictions))
                { // turn is restricted.
                    continue;
                }

                var nDirectedEdgeId = _edgeEnumerator.DirectedEdgeId();
                if (_visits.Contains(nDirectedEdgeId.Raw))
                { // has already been choosen.
                    continue;
                }

                // get the speed from cache or calculate.
                var nWeightAndDirection = _weightHandler.GetEdgeWeight(_edgeEnumerator);
                var nWeightMetric       = _weightHandler.GetMetric(nWeightAndDirection.Weight);
                if (nWeightMetric <= 0)
                { // edge is not valid for profile.
                    continue;
                }
                if (!_backward && !nWeightAndDirection.Direction.F)
                { // cannot do forward search on edge.
                    continue;
                }
                if (_backward && !nWeightAndDirection.Direction.B)
                { // cannot do backward on edge.
                    continue;
                }

                // update the visit list.
                _pointerHeap.Push(_weightHandler.AddPathTree(_pathTree, nDirectedEdgeId.Raw, totalWeight, cPointer), _weightHandler.GetMetric(totalWeight));
            }
            return(true);
        }
Пример #2
0
 /// <summary>
 /// Moves to the given edge.
 /// </summary>
 /// <returns></returns>
 public void MoveToEdge(uint edge)
 {
     _enumerator.MoveToEdge(edge);
 }
Пример #3
0
 /// <summary>
 /// Moves the enumerator to the edge represented by the given directed edge id.
 /// </summary>
 public static void MoveToEdge(this Graph.EdgeEnumerator enumerator, DirectedEdgeId edgeId)
 {
     enumerator.MoveToEdge(edgeId.EdgeId);
 }