private bool AddSegmentToLine(ILineString line, SegmentWithLines segment, List <ILineString> linesToProlong, double minimalDistance) { if (linesToProlong.Contains(line) == false) { return(false); } if (line.Coordinates.Last().Distance(segment.StartProjected) < minimalDistance) { linesToProlong.Remove(line); var concatLine = CreateLineString(null, line.Coordinates.Concat(segment.OriginalCoordinates).ToArray(), segment.EndProjected); linesToProlong.Add(concatLine); return(true); } if (line.Coordinates.First().Distance(segment.EndProjected) < minimalDistance) { linesToProlong.Remove(line); var concatLine = CreateLineString(segment.StartProjected, segment.OriginalCoordinates.Concat(line.Coordinates).ToArray(), null); linesToProlong.Add(concatLine); return(true); } return(false); }
private void HandleTwoLinesCase(GpxProlongerExecutorInput input, SegmentWithLines segment, List <ILineString> linesToProlong) { var bothLinesAreInList = linesToProlong.Contains(segment.Start.Line) && linesToProlong.Contains(segment.End.Line); if (bothLinesAreInList && segment.Start.Line.Coordinates.Last().Distance(segment.Start.Coordinate) < input.MinimalDistance && segment.End.Line.Coordinates.First().Distance(segment.End.Coordinate) < input.MinimalDistance) { linesToProlong.Remove(segment.Start.Line); linesToProlong.Remove(segment.End.Line); linesToProlong.Add(_geometryFactory.CreateLineString( segment.Start.Line.Coordinates .Concat(segment.OriginalCoordinates) .Concat(segment.End.Line.Coordinates) .Distinct() .ToArray())); } else if (!AddSegmentToLine(segment.Start.Line, segment, linesToProlong, input.MinimalDistance)) { if (!AddSegmentToLine(segment.End.Line, segment, linesToProlong, input.MinimalDistance)) { linesToProlong.Add(CreateLineString(segment.StartProjected, segment.OriginalCoordinates, segment.EndProjected)); } } }
private SegmentWithLines CreateSegmentWithLines(Coordinate[] segment, LineAndCoordinate current, LineAndCoordinate next) { var currentLengthIndexedLine = new LengthIndexedLine(current.Line); var currentCoordinate = currentLengthIndexedLine.ExtractPoint(currentLengthIndexedLine.Project(current.Coordinate)); var nextLengthIndexedLine = new LengthIndexedLine(next.Line); var nextCoordinate = nextLengthIndexedLine.ExtractPoint(nextLengthIndexedLine.Project(next.Coordinate)); var segmentWithLines = new SegmentWithLines { OriginalCoordinates = segment, Start = current, StartProjected = currentCoordinate, End = next, EndProjected = nextCoordinate }; return(segmentWithLines); }
private void HandleIntersectionCase(GpxProlongerExecutorInput input, SegmentWithLines segment, List <ILineString> linesToProlong) { var intersection = segment.Start.Line.Intersection(segment.End.Line).Coordinates .OrderBy(c => c.Distance(segment.Start.Coordinate) + c.Distance(segment.End.Coordinate)).FirstOrDefault(); if (intersection == null) { var distance = new DistanceOp(segment.Start.Line, segment.End.Line); intersection = distance.NearestPoints().First(); } var currentLengthIndexedLine = new LengthIndexedLine(segment.Start.Line); var closestCoordinateCurrentIndex = currentLengthIndexedLine.Project(segment.Start.Coordinate); var closestCoordinateCurrentIntersectionIndex = currentLengthIndexedLine.Project(intersection); var currentSegment = currentLengthIndexedLine.ExtractLine(closestCoordinateCurrentIndex, closestCoordinateCurrentIntersectionIndex); var nextLengthIndexedLine = new LengthIndexedLine(segment.End.Line); var closestCoordinateNextIndex = nextLengthIndexedLine.Project(segment.End.Coordinate); var closestCoordinateNextIntersectionIndex = nextLengthIndexedLine.Project(intersection); var nextSegment = nextLengthIndexedLine.ExtractLine(closestCoordinateNextIntersectionIndex, closestCoordinateNextIndex); var coordinates = currentSegment.Coordinates.Concat(nextSegment.Coordinates) .Concat(new[] { currentSegment.Coordinates.First() }).ToArray(); if (coordinates.Length < 4) { return; } var polygon = new Polygon(new LinearRing(coordinates)); if (polygon.Area < input.MinimalAreaSize) { return; } var currentCoordinate = currentLengthIndexedLine.ExtractPoint(closestCoordinateCurrentIndex); var nextCoordinate = nextLengthIndexedLine.ExtractPoint(closestCoordinateNextIndex); var line = CreateLineString(currentCoordinate, segment.OriginalCoordinates, nextCoordinate); linesToProlong.Add(line); }
private void HandleSelfClosingCase(GpxProlongerExecutorInput input, SegmentWithLines segment, List <ILineString> linesToProlong) { var lengthIndexedLine = new LengthIndexedLine(segment.Start.Line); var closestCoordinateCurrentIndex = lengthIndexedLine.Project(segment.Start.Coordinate); var closestCoordinateNextIndex = lengthIndexedLine.Project(segment.End.Coordinate); var indexedSegment = lengthIndexedLine.ExtractLine(closestCoordinateCurrentIndex, closestCoordinateNextIndex); var coordinates = indexedSegment.Coordinates.Concat(new[] { indexedSegment.Coordinates.First() }).ToArray(); if (coordinates.Length < 4) { return; } var polygon = new Polygon(new LinearRing(coordinates)); if (polygon.Area < input.MinimalAreaSize) { return; } if (!AddSegmentToLine(segment.Start.Line, segment, linesToProlong, input.MinimalDistance)) { linesToProlong.Add(CreateLineString(segment.StartProjected, segment.OriginalCoordinates, segment.EndProjected)); } }