Пример #1
0
        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));
                }
            }
        }
Пример #2
0
        private void HandleTwoLinesCase(GpxProlongerExecutorInput input, LineAndCoordinate current, LineAndCoordinate next, List <ILineString> linesToProlong)
        {
            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 bothLinesAreInList = linesToProlong.Contains(current.Line) && linesToProlong.Contains(next.Line);

            if (bothLinesAreInList && current.Line.Coordinates.Last().Distance(current.Coordinate) < input.MinimalDistance &&
                next.Line.Coordinates.First().Distance(next.Coordinate) < input.MinimalDistance)
            {
                linesToProlong.Remove(current.Line);
                linesToProlong.Remove(next.Line);
                linesToProlong.Add(_geometryFactory.CreateLineString(current.Line.Coordinates
                                                                     .Concat(next.Line.Coordinates).ToArray()));
            }
            else if (bothLinesAreInList &&
                     current.Line.Coordinates.First().Distance(current.Coordinate) < input.MinimalDistance &&
                     next.Line.Coordinates.Last().Distance(next.Coordinate) < input.MinimalDistance)
            {
                linesToProlong.Remove(current.Line);
                linesToProlong.Remove(next.Line);
                linesToProlong.Add(_geometryFactory.CreateLineString(next.Line.Coordinates
                                                                     .Concat(current.Line.Coordinates).ToArray()));
            }
            else if (!AddCoordinate(current.Line, currentCoordinate, nextCoordinate, linesToProlong, input.MinimalDistance))
            {
                if (!AddCoordinate(next.Line, currentCoordinate, nextCoordinate, linesToProlong, input.MinimalDistance))
                {
                    linesToProlong.Add(_geometryFactory.CreateLineString(new[] { currentCoordinate, nextCoordinate }));
                }
            }
        }
Пример #3
0
        private void HandleSelfClosingCase(GpxProlongerExecutorInput input, LineAndCoordinate current, LineAndCoordinate next, List <ILineString> linesToProlong)
        {
            var lengthIndexedLine             = new LengthIndexedLine(current.Line);
            var closestCoordinateCurrentIndex = lengthIndexedLine.Project(current.Coordinate);
            var closestCoordinateNextIndex    = lengthIndexedLine.Project(next.Coordinate);
            var segment     = lengthIndexedLine.ExtractLine(closestCoordinateCurrentIndex, closestCoordinateNextIndex);
            var coordinates = segment.Coordinates.Concat(new[] { segment.Coordinates.First() }).ToArray();

            if (coordinates.Length < 4)
            {
                return;
            }
            var polygon = new Polygon(new LinearRing(coordinates));

            if (polygon.Area < input.MinimalAreaSize)
            {
                return;
            }
            var currentCoordinate = lengthIndexedLine.ExtractPoint(closestCoordinateCurrentIndex);
            var nextCoordinate    = lengthIndexedLine.ExtractPoint(closestCoordinateNextIndex);

            if (!AddCoordinate(current.Line, currentCoordinate, nextCoordinate, linesToProlong, input.MinimalDistance))
            {
                linesToProlong.Add(_geometryFactory.CreateLineString(new[] { currentCoordinate, nextCoordinate }));
            }
        }
Пример #4
0
        /// <inheritdoc/>
        public List <ILineString> Prolong(GpxProlongerExecutorInput input)
        {
            // going from end to start.
            var endTostart     = input.OriginalCoordinates.Reverse().ToList();
            var linesToProlong = input.LinesToProlong.Select(l => l.Reverse() as ILineString).Reverse().ToList();
            var allLines       = input.ExistingItmHighways.Concat(linesToProlong).ToList();
            var current        = GetClosest(endTostart, allLines, input);

            if (current == null)
            {
                return(input.LinesToProlong);
            }
            endTostart = endTostart.Skip(endTostart.IndexOf(current.Coordinate) + 1).ToList();
            while (endTostart.Any())
            {
                var next = GetClosest(endTostart, allLines, input);
                if (next == null)
                {
                    break;
                }
                var endIndex = endTostart.IndexOf(next.Coordinate);
                var originalBridgingSegment = new [] { current.Coordinate }.Concat(endTostart.Take(endIndex + 1)).ToArray();
                var segmentWithLines = CreateSegmentWithLines(originalBridgingSegment, current, next);
                if (next.Line == current.Line && linesToProlong.Contains(current.Line))
                {
                    HandleSelfClosingCase(input, segmentWithLines, linesToProlong);
                }
                else if (current.Line.Intersects(next.Line) || current.Line.Distance(next.Line) < 0.1)
                {
                    HandleIntersectionCase(input, segmentWithLines, linesToProlong);
                }
                else
                {
                    HandleTwoLinesCase(input, segmentWithLines, linesToProlong);
                }
                allLines           = input.ExistingItmHighways.Concat(linesToProlong).ToList();
                endTostart         = endTostart.Skip(endTostart.IndexOf(next.Coordinate) + 1).ToList();
                current.Coordinate = next.Coordinate;
                current.Line       = next.Line;
            }
            return(linesToProlong.Select(l => l.Reverse() as ILineString).Reverse().ToList());
        }
Пример #5
0
        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);
        }
Пример #6
0
        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));
            }
        }
Пример #7
0
 /// <summary>
 /// Get the closest line and the coordinate that is close to that line on the original list.
 /// </summary>
 /// <param name="endTostart"></param>
 /// <param name="allLines"></param>
 /// <param name="input"></param>
 /// <returns></returns>
 private LineAndCoordinate GetClosest(List <Coordinate> endTostart, List <ILineString> allLines, GpxProlongerExecutorInput input)
 {
     foreach (var coordinate in endTostart)
     {
         var point      = new Point(coordinate);
         var lineString = allLines.FirstOrDefault(l => l.Distance(point) < input.MinimalDistance);
         if (lineString == null)
         {
             continue;
         }
         return(new LineAndCoordinate
         {
             Coordinate = coordinate,
             Line = lineString
         });
     }
     return(null);
 }