Example #1
0
        private bool TryAdjustToValidPointForwards(ReferencedEncoderBase encoder, long vertex1, long vertex2,
                                                   HashSet <long> exclude)
        {
            var length = (float)this.Length(encoder).Value;
            var negativeOffsetLength = (this.NegativeOffsetPercentage / 100) * length;

            exclude = new HashSet <long>(exclude);
            foreach (var vertex in this.Vertices)
            {
                exclude.Add(vertex);
            }

            if (!encoder.IsVertexValid(this.Vertices[this.Vertices.Length - 1]))
            { // from is not valid, try to find a valid point.
                var vertexCount = this.Vertices.Length;
                var pathToValid = encoder.FindValidVertexFor(this.Vertices[vertexCount - 1], this.Edges[
                                                                 this.Edges.Length - 1].ToReverse(), this.Vertices[vertexCount - 2], exclude, true);

                // build edges list.
                if (pathToValid != null)
                { // no path found, just leave things as is.
                    var shortestRoute = encoder.FindShortestPath(this.Vertices[vertexCount - 2], pathToValid.Vertex, true);
                    while (shortestRoute != null && !shortestRoute.Contains(this.Vertices[vertexCount - 1]))
                    { // the vertex that should be on this shortest route, isn't anymore.
                        // exclude the current target vertex,
                        exclude.Add(pathToValid.Vertex);
                        // calulate a new path-to-valid.
                        pathToValid = encoder.FindValidVertexFor(this.Vertices[vertexCount - 1], this.Edges[
                                                                     this.Edges.Length - 1].ToReverse(), this.Vertices[vertexCount - 2], exclude, true);
                        if (pathToValid == null)
                        { // a new path was not found.
                            break;
                        }
                        shortestRoute = encoder.FindShortestPath(this.Vertices[vertexCount - 2], pathToValid.Vertex, true);
                    }
                    if (pathToValid != null)
                    { // no path found, just leave things as is.
                        var newVertices = pathToValid.ToArray().ToList();
                        var newEdges    = new List <LiveEdge>();
                        for (int idx = 1; idx < newVertices.Count; idx++)
                        { // loop over edges.
                            var edge = newVertices[idx].Edge;
                            newEdges.Add(edge);
                        }

                        // create new location.
                        var edgesArray = new LiveEdge[newEdges.Count + this.Edges.Length];
                        this.Edges.CopyTo(0, edgesArray, 0, this.Edges.Length);
                        newEdges.CopyTo(0, edgesArray, this.Edges.Length, newEdges.Count);
                        var vertexArray = new long[newVertices.Count - 1 + this.Vertices.Length];
                        this.Vertices.CopyTo(0, vertexArray, 0, this.Vertices.Length);
                        newVertices.ConvertAll(x => (long)x.Vertex).CopyTo(1, vertexArray, this.Vertices.Length, newVertices.Count - 1);

                        this.Edges    = edgesArray;
                        this.Vertices = vertexArray;

                        // adjust offset length.
                        var newLength = (float)this.Length(encoder).Value;
                        negativeOffsetLength = negativeOffsetLength + (newLength - length);
                        length = newLength;
                    }
                    else
                    { // no valid path was found.
                        return(false);
                    }
                }
                else
                { // no valid path was found.
                    return(false);
                }
            }

            // update offset percentage
            this.NegativeOffsetPercentage = (float)((negativeOffsetLength / length) * 100.0);

            return(true);
        }
Example #2
0
        /// <summary>
        /// Adjusts this location to use valid LR-points.
        /// </summary>
        public void AdjustToValidPoints(ReferencedEncoderBase encoder)
        {
            if (this.Vertices.Length <= 1)
            {
                throw new ArgumentException("Cannot adjust a line location with only one vertex.");
            }

            var vertex1Valid = encoder.IsVertexValid(this.Vertices[0]);
            var vertex2Valid = encoder.IsVertexValid(this.Vertices[this.Vertices.Length - 1]);

            if (vertex1Valid && vertex2Valid)
            { // already valid.
                return;
            }
            if (this.Vertices.Length > 2)
            {
                return;
            }                                         // line was already adjusted.

            var vertex1 = this.Vertices[0];
            var vertex2 = this.Vertices[1];

            if (!encoder.IsOnShortestPath(this.Vertices[0], this.Vertices[this.Vertices.Length - 1],
                                          vertex1, vertex2))
            { // impossible to expand edge.
                return;
            }

            // make sure the original sequence is still there on the shortest path.
            ReferencedLine validCopy          = null;
            var            backwardExcludeSet = this.GetVerticesSet();

            while (true)
            {
                // search backward.
                var workingCopy = this.Clone() as ReferencedLine;
                if (!workingCopy.TryAdjustToValidPointBackwards(encoder, vertex1, vertex2, backwardExcludeSet))
                { // no more options exist, impossible to expand edge, just keep the edge itself.
                    return;
                }

                if (!vertex2Valid)
                { // search forward.
                    var forwardExcludeSet = workingCopy.GetVerticesSet();
                    do
                    {
                        var forwardWorkingCopy = workingCopy.Clone() as ReferencedLine;
                        if (!forwardWorkingCopy.TryAdjustToValidPointForwards(encoder, vertex1, vertex2, forwardExcludeSet))
                        { // no more forward options for the current backward.
                            break;
                        }

                        // check valid.
                        if (encoder.IsOnShortestPath(forwardWorkingCopy.Vertices[0], forwardWorkingCopy.Vertices[forwardWorkingCopy.Vertices.Length - 1],
                                                     vertex1, vertex2))
                        { // current location is valid.
                            validCopy = forwardWorkingCopy;
                            break;
                        }

                        // not valid here, exclude current forward.
                        forwardExcludeSet.Add(forwardWorkingCopy.Vertices[forwardWorkingCopy.Vertices.Length - 1]);
                    } while (true);
                }
                else
                { // check valid.
                    if (encoder.IsOnShortestPath(workingCopy.Vertices[0], workingCopy.Vertices[workingCopy.Vertices.Length - 1],
                                                 vertex1, vertex2))
                    { // current location is valid.
                        validCopy = workingCopy;
                        break;
                    }
                }

                if (validCopy != null)
                { // current location is valid.
                    break;
                }

                if (vertex1Valid)
                { // vertex1 was already valid, no reason to continue searching.
                    return;
                }

                // exclude current backward and continue.
                backwardExcludeSet.Add(workingCopy.Vertices[0]);
            }

            // copy from working copy.
            this.Edges    = validCopy.Edges;
            this.Vertices = validCopy.Vertices;
            this.NegativeOffsetPercentage = validCopy.NegativeOffsetPercentage;
            this.PositiveOffsetPercentage = validCopy.PositiveOffsetPercentage;

            // fill shapes.
            this.EdgeShapes = new GeoCoordinateSimple[this.Edges.Length][];
            for (int i = 0; i < this.Edges.Length; i++)
            {
                this.EdgeShapes[i] = encoder.Graph.GetEdgeShape(
                    this.Vertices[i], this.Vertices[i + 1]);
            }
        }