/// <summary> /// Adjusts this location to use valid LR-points. /// </summary> public static void AdjustToValidPoints(this ReferencedLine line, Coder coder) { if (line.Vertices.Length <= 1) { throw new ArgumentException("Cannot adjust a line location with only one vertex."); } var vertex1Valid = coder.IsVertexValid(line.Vertices[0]); var vertex2Valid = coder.IsVertexValid(line.Vertices[line.Vertices.Length - 1]); if (vertex1Valid && vertex2Valid) { // already valid. return; } if (line.Vertices.Length > 2) { return; } // line was already adjusted. var vertex1 = line.Vertices[0]; var vertex2 = line.Vertices[1]; if (!coder.IsOnShortestPath(line.Vertices[0], line.Vertices[line.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 = line.GetVerticesSet(); while (true) { // search backward. var workingCopy = line.Clone() as ReferencedLine; if (!workingCopy.TryAdjustToValidPointBackwards(coder, 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(coder, vertex1, vertex2, forwardExcludeSet)) { // no more forward options for the current backward. break; } // check valid. if (coder.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 (coder.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. line.Edges = validCopy.Edges; line.Vertices = validCopy.Vertices; line.NegativeOffsetPercentage = validCopy.NegativeOffsetPercentage; line.PositiveOffsetPercentage = validCopy.PositiveOffsetPercentage; }