private void RunExtractLine(String wkt, LinearLocation start, LinearLocation end, String expected)
 {
     IGeometry geom = Read(wkt);
     LocationIndexedLine lil = new LocationIndexedLine(geom);
     IGeometry result = lil.ExtractLine(start, end);
     //System.out.println(result);
     CheckExpected(result, expected);
 }
Example #2
0
        private void RunExtractLine(string wkt, LinearLocation start, LinearLocation end, string expected)
        {
            var geom   = Read(wkt);
            var lil    = new LocationIndexedLine(geom);
            var result = lil.ExtractLine(start, end);

            //System.out.println(result);
            CheckExpected(result, expected);
        }
Example #3
0
        private void RunExtractLine(String wkt, LinearLocation start, LinearLocation end, String expected)
        {
            IGeometry           geom   = Read(wkt);
            LocationIndexedLine lil    = new LocationIndexedLine(geom);
            IGeometry           result = lil.ExtractLine(start, end);

            //System.out.println(result);
            CheckExpected(result, expected);
        }
Example #4
0
 private bool IsStartOrEnd(LinearLocation lip, LineString candidate)
 {
     if (!lip.IsVertex)
     {
         return(false);
     }
     if (lip.SegmentIndex == 0)
     {
         return(true);
     }
     return(lip.IsEndpoint(candidate));
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="subLine"></param>
        /// <returns></returns>
        public virtual LinearLocation[] IndicesOf(IGeometry subLine)
        {
            var startPt = ((ILineString) subLine.GetGeometryN(0)).GetCoordinateN(0);
            var lastLine = (ILineString) subLine.GetGeometryN(subLine.NumGeometries - 1);
            var endPt = lastLine.GetCoordinateN(lastLine.NumPoints - 1);

            var locPt = new LocationIndexOfPoint(_linearGeom);
            var subLineLoc = new LinearLocation[2];
            subLineLoc[0] = locPt.IndexOf(startPt);

            // check for case where subline is zero length
            if (subLine.Length == 0)
                 subLineLoc[1] = (LinearLocation) subLineLoc[0].Clone();
            else subLineLoc[1] = locPt.IndexOfAfter(endPt, subLineLoc[0]);
            return subLineLoc;
        }
        private LinearLocation IndexOfFromStart(Coordinate inputPt, LinearLocation minIndex)
        {
            var minDistance = Double.MaxValue;
            var minComponentIndex = 0;
            var minSegmentIndex = 0;
            var minFrac = -1.0;

            var seg = new LineSegment();
            for (var it = new LinearIterator(_linearGeom);
                 it.HasNext(); it.Next())
            {
                if (!it.IsEndOfLine)
                {
                    seg.P0 = it.SegmentStart;
                    seg.P1 = it.SegmentEnd;
                    var segDistance = seg.Distance(inputPt);
                    var segFrac = seg.SegmentFraction(inputPt);

                    var candidateComponentIndex = it.ComponentIndex;
                    var candidateSegmentIndex = it.VertexIndex;
                    if (segDistance < minDistance)
                    {
                        // ensure after minLocation, if any
                        if (minIndex == null ||
                            minIndex.CompareLocationValues(candidateComponentIndex, candidateSegmentIndex, segFrac) < 0)
                        {
                            // otherwise, save this as new minimum
                            minComponentIndex = candidateComponentIndex;
                            minSegmentIndex = candidateSegmentIndex;
                            minFrac = segFrac;
                            minDistance = segDistance;
                        }
                    }
                }
            }

            if (minDistance == Double.MaxValue)
            {
                // no minimum was found past minLocation, so return it
                return new LinearLocation(minIndex);
            }
            // otherwise, return computed location
            var loc = new LinearLocation(minComponentIndex, minSegmentIndex, minFrac);
            return loc;
        }
Example #7
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="loc"></param>
        /// <returns></returns>
        public double GetLength(LinearLocation loc)
        {
            double totalLength = 0.0;

            foreach (LinearIterator.LinearElement element in new LinearIterator(linearGeom))
            {
                if (!element.IsEndOfLine)
                {
                    ICoordinate p0 = element.SegmentStart;
                    ICoordinate p1 = element.SegmentEnd;
                    double segLen = p1.Distance(p0);
                    // length falls in this segment
                    if (loc.ComponentIndex == element.ComponentIndex && loc.SegmentIndex == element.VertexIndex)
                        return totalLength + segLen * loc.SegmentFraction;
                    totalLength += segLen;
                }
            }
            return totalLength;
        }
Example #8
0
        /// <summary>
        /// Find the nearest <see cref="LinearLocation" /> along the linear <see cref="Geometry" />
        /// to a given <see cref="Geometry" /> after the specified minimum <see cref="LinearLocation" />.
        /// If possible the location returned will be strictly greater than the <paramref name="minIndex" />.
        /// If this is not possible, the value returned will equal <paramref name="minIndex" />.
        /// (An example where this is not possible is when <paramref name="minIndex" /> = [end of line] ).
        /// </summary>
        /// <param name="inputPt">The coordinate to locate.</param>
        /// <param name="minIndex">The minimum location for the point location.</param>
        /// <returns>The location of the nearest point.</returns>
        public LinearLocation IndexOfAfter(ICoordinate inputPt, LinearLocation minIndex)
        {
            if (minIndex == null)
                return IndexOf(inputPt);

            // sanity check for minLocation at or past end of line
            LinearLocation endLoc = LinearLocation.GetEndLocation(linearGeom);
            if (endLoc.CompareTo(minIndex) <= 0)
                return endLoc;

            LinearLocation closestAfter = IndexOfFromStart(inputPt, minIndex);

            /*
             * Return the minDistanceLocation found.
             * This will not be null, since it was initialized to minLocation
             */
            Assert.IsTrue(closestAfter.CompareTo(minIndex) >= 0, "computed location is before specified minimum location");
            return closestAfter;
        }
        public void TestSameSegmentMultiLineString()
        {
            IGeometry           line        = reader.Read("MULTILINESTRING ((0 0, 10 0, 20 0), (20 0, 30 0))");
            LocationIndexedLine indexedLine = new LocationIndexedLine(line);

            LinearLocation loc0   = indexedLine.IndexOf(new Coordinate(0, 0));
            LinearLocation loc0_5 = indexedLine.IndexOf(new Coordinate(5, 0));
            LinearLocation loc1   = indexedLine.IndexOf(new Coordinate(10, 0));
            LinearLocation loc2   = indexedLine.IndexOf(new Coordinate(20, 0));
            LinearLocation loc2B  = new LinearLocation(1, 0, 0.0);

            LinearLocation loc2_5 = indexedLine.IndexOf(new Coordinate(25, 0));
            LinearLocation loc3   = indexedLine.IndexOf(new Coordinate(30, 0));

            Assert.IsTrue(loc0.IsOnSameSegment(loc0));
            Assert.IsTrue(loc0.IsOnSameSegment(loc0_5));
            Assert.IsTrue(loc0.IsOnSameSegment(loc1));
            Assert.IsTrue(!loc0.IsOnSameSegment(loc2));
            Assert.IsTrue(!loc0.IsOnSameSegment(loc2_5));
            Assert.IsTrue(!loc0.IsOnSameSegment(loc3));

            Assert.IsTrue(loc0_5.IsOnSameSegment(loc0));
            Assert.IsTrue(loc0_5.IsOnSameSegment(loc1));
            Assert.IsTrue(!loc0_5.IsOnSameSegment(loc2));
            Assert.IsTrue(!loc0_5.IsOnSameSegment(loc3));

            Assert.IsTrue(!loc2.IsOnSameSegment(loc0));
            Assert.IsTrue(loc2.IsOnSameSegment(loc1));
            Assert.IsTrue(loc2.IsOnSameSegment(loc2));
            Assert.IsTrue(!loc2.IsOnSameSegment(loc3));
            Assert.IsTrue(loc2B.IsOnSameSegment(loc3));

            Assert.IsTrue(loc2_5.IsOnSameSegment(loc3));

            Assert.IsTrue(!loc3.IsOnSameSegment(loc0));
            Assert.IsTrue(!loc3.IsOnSameSegment(loc2));
            Assert.IsTrue(loc3.IsOnSameSegment(loc2B));
            Assert.IsTrue(loc3.IsOnSameSegment(loc2_5));
            Assert.IsTrue(loc3.IsOnSameSegment(loc3));
        }
        /// <summary>
        /// Assumes input is valid 
        /// (e.g. <paramref name="start" /> minor or equals to <paramref name="end" />).
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private ILineString ComputeLine(LinearLocation start, LinearLocation end)
        {
            ICoordinate[] coordinates = line.Coordinates;
            CoordinateList newCoordinates = new CoordinateList();

            int startSegmentIndex = start.SegmentIndex;
            if (start.SegmentFraction > 0.0)
                startSegmentIndex += 1;
            int lastSegmentIndex = end.SegmentIndex;
            if (end.SegmentFraction == 1.0)
                lastSegmentIndex += 1;
            if (lastSegmentIndex >= coordinates.Length)
                lastSegmentIndex = coordinates.Length - 1;
            // not needed - LinearLocation values should always be correct
            // Assert.IsTrue(end.SegmentFraction <= 1.0, "invalid segment fraction value");

            if (!start.IsVertex)
                newCoordinates.Add(start.GetCoordinate(line));
            for (int i = startSegmentIndex; i <= lastSegmentIndex; i++)
                newCoordinates.Add(coordinates[i]);            
            if (!end.IsVertex)
                newCoordinates.Add(end.GetCoordinate(line));

            // ensure there is at least one coordinate in the result
            if (newCoordinates.Count <= 0)
                newCoordinates.Add(start.GetCoordinate(line));

            ICoordinate[] newCoordinateArray = newCoordinates.ToCoordinateArray();

            /*
             * Ensure there is enough coordinates to build a valid line.
             * Make a 2-point line with duplicate coordinates, if necessary.
             * There will always be at least one coordinate in the coordList.
             */
            if (newCoordinateArray.Length <= 1)
                newCoordinateArray = new ICoordinate[] { newCoordinateArray[0], newCoordinateArray[0] };
            
            return line.Factory.CreateLineString(newCoordinateArray);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="inputPt"></param>
        /// <param name="minIndex"></param>
        /// <returns></returns>
        private LinearLocation IndexOfFromStart(ICoordinate inputPt, LinearLocation minIndex)
        {
            double minDistance = Double.MaxValue;
            int minComponentIndex = 0;
            int minSegmentIndex = 0;
            double minFrac = -1.0;

            LineSegment seg = new LineSegment();
            foreach (LinearIterator.LinearElement element in new LinearIterator(linearGeom))
            {
                if (!element.IsEndOfLine)
                {
                    seg.P0 = element.SegmentStart;
                    seg.P1 = element.SegmentEnd;
                    double segDistance = seg.Distance(inputPt);
                    double segFrac = SegmentFraction(seg, inputPt);

                    int candidateComponentIndex = element.ComponentIndex;
                    int candidateSegmentIndex = element.VertexIndex;
                    if (segDistance < minDistance)
                    {
                        // ensure after minLocation, if any                        
                        if (minIndex == null ||
                            minIndex.CompareLocationValues(candidateComponentIndex, candidateSegmentIndex, segFrac) < 0)
                        {
                            // otherwise, save this as new minimum
                            minComponentIndex = candidateComponentIndex;
                            minSegmentIndex = candidateSegmentIndex;
                            minFrac = segFrac;
                            minDistance = segDistance;
                        }
                    }
                }                
            }

            LinearLocation loc = new LinearLocation(minComponentIndex, minSegmentIndex, minFrac);
            return loc;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="loc"></param>
        /// <returns></returns>
        public double GetLength(LinearLocation loc)
        {
            var totalLength = 0.0;

            var it = new LinearIterator(_linearGeom);
            while (it.HasNext())
            {
                if (!it.IsEndOfLine)
                {
                    var p0 = it.SegmentStart;
                    var p1 = it.SegmentEnd;
                    var segLen = p1.Distance(p0);
                    // length falls in this segment
                    if (loc.ComponentIndex == it.ComponentIndex
                        && loc.SegmentIndex == it.VertexIndex)
                    {
                        return totalLength + segLen * loc.SegmentFraction;
                    }
                    totalLength += segLen;
                }
                it.Next();
            }
            return totalLength;
        }
 ///<summary>
 /// Finds the index for a point on the line which is greater than the given index. 
 /// If no such index exists, returns <paramref name="minIndex" />.
 ///</summary>
 /// <remarks>
 /// <para>
 /// This method can be used to determine all indexes for
 /// a point which occurs more than once on a non-simple line.
 /// It can also be used to disambiguate cases where the given point lies
 /// slightly off the line and is equidistant from two different
 /// points on the line.
 /// </para>
 /// <para>
 /// The supplied point does not <i>necessarily</i> have to lie precisely
 /// on the line, but if it is far from the line the accuracy and
 /// performance of this function is not guaranteed.
 /// Use <see cref="Project"/> to compute a guaranteed result for points
 /// which may be far from the line.
 /// </para>
 /// </remarks>
 /// <param name="pt">A point on the line</param>
 /// <param name="minIndex">The value the returned index must be greater than</param>
 /// <returns>The index of the point greater than the given minimum index</returns>
 /// <seealso cref="Project(Coordinate)"/>
 public LinearLocation IndexOfAfter(Coordinate pt, LinearLocation minIndex)
 {
     return LocationIndexOfPoint.IndexOfAfter(_linearGeom, pt, minIndex);
 }
Example #14
0
        public ILineString[] SplitTheLine(ILineString toBeSplit, IPoint splitPoint)
        {
            var llStart = new LinearLocation(0, 0);
            var llSplit = LocationIndexOfPoint.IndexOf(toBeSplit, splitPoint.Coordinate);
            var llEnd = new LinearLocation(0, 1);

            var res = new[]
                {
                    (ILineString)ExtractLineByLocation.Extract(toBeSplit, llStart, llSplit),
                    (ILineString)ExtractLineByLocation.Extract(toBeSplit, llSplit, llEnd)
                };

            return res;
            
            var cDistance = double.MaxValue;
            Coordinate cPoint = null;

            // From this point on it becomes a bit of a 'fudge'. Because the NTS functionality is a map matching dream (ie it returns 
            // a point that may not be on the line. But We need to split the line into two. Therefore we have to get the distance 
            // from the intersection to the cloest point on the line. More on this when we get there.
            // ToDo: Perhaps theres a much better way of doing this already in either SharpMap/ or more likely NTS?????????????????
            for (var i = 0; i < toBeSplit.Coordinates.Length; i++)
            {
                var pointOnTheLine = toBeSplit.Coordinates[i];

                double lDistance = pointOnTheLine.Distance(splitPoint.Coordinate);

                if (lDistance < cDistance)
                {
                    cDistance = lDistance;
                    cPoint = pointOnTheLine;
                }

            }

            // Now We Need To Try And Calculate The Length Along The Line Of That Node.
            var indexAlongLine = 0;
            var firstPart = new List<Coordinate>();
            var secondPart = new List<Coordinate>();


            for (var i = 0; i < toBeSplit.Coordinates.Length; i++)
            {
                var pointOnTheLine =
                    toBeSplit.Coordinates[i];

                firstPart.Add(pointOnTheLine);

                if (ReferenceEquals(pointOnTheLine, cPoint))
                    break;

                indexAlongLine++;
            }

            for (int i = indexAlongLine; i < toBeSplit.Coordinates.Length; i++)
            {
                var pointOnTheLine = toBeSplit.Coordinates[i];

                secondPart.Add(pointOnTheLine);
            }

            var firstPartAsString = _geomFactory.CreateLineString(firstPart.ToArray());
            var secondPartAsString = _geomFactory.CreateLineString(secondPart.ToArray());

            var splitLineParts = new ILineString[2];
            splitLineParts[0] = firstPartAsString;
            splitLineParts[1] = secondPartAsString;

            return splitLineParts;
        }
Example #15
0
        public ILineString[] SplitTheLine(ILineString toBeSplit, IPoint splitPoint)
        {
            var llStart = new LinearLocation(0, 0);
            var llSplit = LocationIndexOfPoint.IndexOf(toBeSplit, splitPoint.Coordinate);
            var llEnd   = new LinearLocation(0, 1);

            var res = new[]
            {
                (ILineString)ExtractLineByLocation.Extract(toBeSplit, llStart, llSplit),
                (ILineString)ExtractLineByLocation.Extract(toBeSplit, llSplit, llEnd)
            };

            return(res);

            var        cDistance = double.MaxValue;
            Coordinate cPoint    = null;

            // From this point on it becomes a bit of a 'fudge'. Because the NTS functionality is a map matching dream (ie it returns
            // a point that may not be on the line. But We need to split the line into two. Therefore we have to get the distance
            // from the intersection to the cloest point on the line. More on this when we get there.
            // ToDo: Perhaps theres a much better way of doing this already in either SharpMap/ or more likely NTS?????????????????
            for (var i = 0; i < toBeSplit.Coordinates.Length; i++)
            {
                var pointOnTheLine = toBeSplit.Coordinates[i];

                double lDistance = pointOnTheLine.Distance(splitPoint.Coordinate);

                if (lDistance < cDistance)
                {
                    cDistance = lDistance;
                    cPoint    = pointOnTheLine;
                }
            }

            // Now We Need To Try And Calculate The Length Along The Line Of That Node.
            var indexAlongLine = 0;
            var firstPart      = new List <Coordinate>();
            var secondPart     = new List <Coordinate>();


            for (var i = 0; i < toBeSplit.Coordinates.Length; i++)
            {
                var pointOnTheLine =
                    toBeSplit.Coordinates[i];

                firstPart.Add(pointOnTheLine);

                if (ReferenceEquals(pointOnTheLine, cPoint))
                {
                    break;
                }

                indexAlongLine++;
            }

            for (int i = indexAlongLine; i < toBeSplit.Coordinates.Length; i++)
            {
                var pointOnTheLine = toBeSplit.Coordinates[i];

                secondPart.Add(pointOnTheLine);
            }

            var firstPartAsString  = _geomFactory.CreateLineString(firstPart.ToArray());
            var secondPartAsString = _geomFactory.CreateLineString(secondPart.ToArray());

            var splitLineParts = new ILineString[2];

            splitLineParts[0] = firstPartAsString;
            splitLineParts[1] = secondPartAsString;

            return(splitLineParts);
        }
Example #16
0
 /// <summary>
 /// Computes a valid index for this line by clamping 
 /// the given index to the valid range of index values.
 /// </summary>
 /// <param name="index"></param>
 /// <returns>A valid index value.</returns>
 public LinearLocation ClampIndex(LinearLocation index)
 {
     LinearLocation loc = (LinearLocation) index.Clone();
     loc.Clamp(linearGeom);
     return loc;
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="loc"></param>
 /// <returns></returns>
 public static int SegmentEndVertexIndex(LinearLocation loc)
 {
     if (loc.SegmentFraction > 0.0)
         return loc.SegmentIndex + 1;
     return loc.SegmentIndex;
 }
 public static LinearLocation IndexOfAfter(IGeometry linearGeom, Coordinate inputPt, LinearLocation minIndex)
 {
     var locater = new LocationIndexOfPoint(linearGeom);
     return locater.IndexOfAfter(inputPt, minIndex);
 }
 /// <summary>
 /// Computes the length for a given <see cref="LinearLocation" />
 /// on a linear <see cref="Geometry" />.
 /// </summary>
 /// <param name="linearGeom">The linear geometry to use.</param>
 /// <param name="loc">The <see cref="LinearLocation" /> index of the location.</param>
 /// <returns>The length for the <see cref="LinearLocation" />.</returns>
 public static double GetLength(IGeometry linearGeom, LinearLocation loc)
 {
     var locater = new LengthLocationMap(linearGeom);
     return locater.GetLength(loc);
 }
        private LinearLocation ResolveHigher(LinearLocation loc)
        {
            if (!loc.IsEndpoint(_linearGeom))
                return loc;
            int compIndex = loc.ComponentIndex;
            // if last component can't resolve any higher
            if (compIndex >= _linearGeom.NumGeometries - 1) return loc;

            do
            {
                compIndex++;
            } while (compIndex < _linearGeom.NumGeometries - 1
                && _linearGeom.GetGeometryN(compIndex).Length == 0);
            // resolve to next higher location
            return new LinearLocation(compIndex, 0, 0.0);
        }
        public void TestGetSegmentMultiLineString()
        {
            IGeometry line = reader.Read("MULTILINESTRING ((0 0, 10 0, 20 0), (20 0, 30 0))");
            LocationIndexedLine indexedLine = new LocationIndexedLine(line);

            LinearLocation loc0 = indexedLine.IndexOf(new Coordinate(0, 0));
            LinearLocation loc0_5 = indexedLine.IndexOf(new Coordinate(5, 0));
            LinearLocation loc1 = indexedLine.IndexOf(new Coordinate(10, 0));
            LinearLocation loc2 = indexedLine.IndexOf(new Coordinate(20, 0));
            LinearLocation loc2B = new LinearLocation(1, 0, 0.0);

            LinearLocation loc2_5 = indexedLine.IndexOf(new Coordinate(25, 0));
            LinearLocation loc3 = indexedLine.IndexOf(new Coordinate(30, 0));

            LineSegment seg0 = new LineSegment(new Coordinate(0, 0), new Coordinate(10, 0));
            LineSegment seg1 = new LineSegment(new Coordinate(10, 0), new Coordinate(20, 0));
            LineSegment seg2 = new LineSegment(new Coordinate(20, 0), new Coordinate(30, 0));

            Assert.IsTrue(loc0.GetSegment(line).Equals(seg0));
            Assert.IsTrue(loc0_5.GetSegment(line).Equals(seg0));

            Assert.IsTrue(loc1.GetSegment(line).Equals(seg1));
            Assert.IsTrue(loc2.GetSegment(line).Equals(seg1));

            Assert.IsTrue(loc2_5.GetSegment(line).Equals(seg2));
            Assert.IsTrue(loc3.GetSegment(line).Equals(seg2));
        }
        ///// <summary>
        ///// Assumes input is valid
        ///// (e.g. <paramref name="start" /> minor or equals to <paramref name="end" />).
        ///// </summary>
        ///// <param name="start"></param>
        ///// <param name="end"></param>
        ///// <returns></returns>
        //private ILineString ComputeLine(LinearLocation start, LinearLocation end)
        //{
        //    var coordinates = _line.Coordinates;
        //    var newCoordinates = new CoordinateList();
        //    var startSegmentIndex = start.SegmentIndex;
        //    if (start.SegmentFraction > 0.0)
        //        startSegmentIndex += 1;
        //    var lastSegmentIndex = end.SegmentIndex;
        //    if (end.SegmentFraction == 1.0)
        //        lastSegmentIndex += 1;
        //    if (lastSegmentIndex >= coordinates.Length)
        //        lastSegmentIndex = coordinates.Length - 1;
        //    // not needed - LinearLocation values should always be correct
        //    // Assert.IsTrue(end.SegmentFraction <= 1.0, "invalid segment fraction value");
        //    if (!start.IsVertex)
        //        newCoordinates.Add(start.GetCoordinate(_line));
        //    for (var i = startSegmentIndex; i <= lastSegmentIndex; i++)
        //        newCoordinates.Add(coordinates[i]);
        //    if (!end.IsVertex)
        //        newCoordinates.Add(end.GetCoordinate(_line));
        //    // ensure there is at least one coordinate in the result
        //    if (newCoordinates.Count <= 0)
        //        newCoordinates.Add(start.GetCoordinate(_line));
        //    var newCoordinateArray = newCoordinates.ToCoordinateArray();
        //    /*
        //     * Ensure there is enough coordinates to build a valid line.
        //     * Make a 2-point line with duplicate coordinates, if necessary.
        //     * There will always be at least one coordinate in the coordList.
        //     */
        //    if (newCoordinateArray.Length <= 1)
        //        newCoordinateArray = new[] { newCoordinateArray[0], newCoordinateArray[0] };
        //    return _line.Factory.CreateLineString(newCoordinateArray);
        //}
        /// <summary>
        /// Assumes input is valid
        /// (e.g. <paramref name="start" /> minor or equals to <paramref name="end" />).
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private IGeometry ComputeLinear(LinearLocation start, LinearLocation end)
        {
            var builder = new LinearGeometryBuilder(_line.Factory);
            builder.FixInvalidLines = true;

            if (!start.IsVertex)
                builder.Add(start.GetCoordinate(_line));

            for (var it = new LinearIterator(_line, start); it.HasNext(); it.Next())
            {
                if (end.CompareLocationValues(it.ComponentIndex, it.VertexIndex, 0.0) < 0)
                    break;

                var pt = it.SegmentStart;
                builder.Add(pt);
                if (it.IsEndOfLine)
                    builder.EndLine();
            }

            if (!end.IsVertex)
                builder.Add(end.GetCoordinate(_line));

            return builder.GetGeometry();
        }
 /// <summary>
 /// Computes the <see cref="Coordinate"/> for the point
 /// on the line at the given index, offset by the given distance.
 /// If the index is out of range the first or last point on the
 /// line will be returned.<para/>
 /// The computed point is offset to the left of the line if the offset distance is
 /// positive, to the right if negative.<para/>
 /// The Z-ordinate of the computed point will be interpolated from
 /// the Z-ordinates of the line segment containing it, if they exist.
 /// </summary>
 /// <param name="index">The index of the desired point</param>
 /// <param name="offsetDistance">The distance the point is offset from the segment
 /// (positive is to the left, negative is to the right)</param>
 /// <returns>The Coordinate at the given index</returns>
 public Coordinate ExtractPoint(LinearLocation index, double offsetDistance)
 {
     LinearLocation indexLow = index.ToLowest(_linearGeom);
     return indexLow.GetSegment(_linearGeom).PointAlongOffset(indexLow.SegmentFraction, offsetDistance);
 }
Example #24
0
 /// <summary>
 /// Tests whether an index is in the valid index range for the line.
 /// </summary>
 /// <param name="index">The index to test.</param>
 /// <returns><c>true</c> if the index is in the valid range.</returns>
 public bool isValidIndex(LinearLocation index)
 {
     return index.IsValid(linearGeom);
 }
Example #25
0
 /// <summary>
 /// Computes the <see cref="LineString" /> for the interval
 /// on the line between the given indices.
 /// </summary>
 /// <param name="startIndex">The index of the start of the interval.</param>
 /// <param name="endIndex">The index of the end of the interval.</param>
 /// <returns>The linear interval between the indices.</returns>
 public IGeometry ExtractLine(LinearLocation startIndex, LinearLocation endIndex)
 {
     return ExtractLineByLocation.Extract(linearGeom, startIndex, endIndex);
 }
Example #26
0
 /// <summary>
 /// Computes the <see cref="Coordinate" />for the point on the line at the given index.
 /// If the <paramref name="index" /> is out of range,
 /// the first or last point on the line will be returned.
 /// </summary>
 /// <param name="index">The index of the desired point.</param>
 /// <returns>The <see cref="Coordinate" /> at the given index.</returns>
 public ICoordinate ExtractPoint(LinearLocation index)
 {
     return index.GetCoordinate(linearGeom);
 }
 /// <summary>
 /// Computes the subline of a <see cref="LineString" /> between
 /// two LineStringLocations on the line.
 /// If the start location is after the end location,
 /// the computed geometry is reversed.
 /// </summary>
 /// <param name="line">The line to use as the baseline.</param>
 /// <param name="start">The start location.</param>
 /// <param name="end">The end location.</param>
 /// <returns>The extracted subline.</returns>
 public static IGeometry Extract(IGeometry line, LinearLocation start, LinearLocation end)
 {
     ExtractLineByLocation ls = new ExtractLineByLocation(line);
     return ls.Extract(start, end);
 }
 /// <summary>
 /// Extracts a subline of the input.
 /// If <paramref name="end" /> is minor that <paramref name="start" />,
 /// the linear geometry computed will be reversed.
 /// </summary>
 /// <param name="start">The start location.</param>
 /// <param name="end">The end location.</param>
 /// <returns>A linear geometry.</returns>
 public IGeometry Extract(LinearLocation start, LinearLocation end)
 {
     if (end.CompareTo(start) < 0)
         return Reverse(ComputeLinear(end, start));            
     return ComputeLinear(start, end);
 }
        public void TestSameSegmentMultiLineString()
        {
            IGeometry line = reader.Read("MULTILINESTRING ((0 0, 10 0, 20 0), (20 0, 30 0))");
            LocationIndexedLine indexedLine = new LocationIndexedLine(line);

            LinearLocation loc0 = indexedLine.IndexOf(new Coordinate(0, 0));
            LinearLocation loc0_5 = indexedLine.IndexOf(new Coordinate(5, 0));
            LinearLocation loc1 = indexedLine.IndexOf(new Coordinate(10, 0));
            LinearLocation loc2 = indexedLine.IndexOf(new Coordinate(20, 0));
            LinearLocation loc2B = new LinearLocation(1, 0, 0.0);

            LinearLocation loc2_5 = indexedLine.IndexOf(new Coordinate(25, 0));
            LinearLocation loc3 = indexedLine.IndexOf(new Coordinate(30, 0));

            Assert.IsTrue(loc0.IsOnSameSegment(loc0));
            Assert.IsTrue(loc0.IsOnSameSegment(loc0_5));
            Assert.IsTrue(loc0.IsOnSameSegment(loc1));
            Assert.IsTrue(!loc0.IsOnSameSegment(loc2));
            Assert.IsTrue(!loc0.IsOnSameSegment(loc2_5));
            Assert.IsTrue(!loc0.IsOnSameSegment(loc3));

            Assert.IsTrue(loc0_5.IsOnSameSegment(loc0));
            Assert.IsTrue(loc0_5.IsOnSameSegment(loc1));
            Assert.IsTrue(!loc0_5.IsOnSameSegment(loc2));
            Assert.IsTrue(!loc0_5.IsOnSameSegment(loc3));

            Assert.IsTrue(!loc2.IsOnSameSegment(loc0));
            Assert.IsTrue(loc2.IsOnSameSegment(loc1));
            Assert.IsTrue(loc2.IsOnSameSegment(loc2));
            Assert.IsTrue(!loc2.IsOnSameSegment(loc3));
            Assert.IsTrue(loc2B.IsOnSameSegment(loc3));

            Assert.IsTrue(loc2_5.IsOnSameSegment(loc3));

            Assert.IsTrue(!loc3.IsOnSameSegment(loc0));
            Assert.IsTrue(!loc3.IsOnSameSegment(loc2));
            Assert.IsTrue(loc3.IsOnSameSegment(loc2B));
            Assert.IsTrue(loc3.IsOnSameSegment(loc2_5));
            Assert.IsTrue(loc3.IsOnSameSegment(loc3));
        }
 /// <summary>
 /// Creates an iterator starting at a <see cref="LinearLocation" /> on a linear <see cref="Geometry" />.
 /// </summary>
 /// <param name="linearGeom">The linear geometry to iterate over.</param>
 /// <param name="start">The location to start at.</param>
 /// <exception cref="ArgumentException"> if <paramref name="linearGeom"/> is not <see cref="ILineal"/></exception>
 public LinearIterator(IGeometry linearGeom, LinearLocation start) :
     this(linearGeom, start.ComponentIndex, SegmentEndVertexIndex(start)) { }
        /// <summary>
        /// Assumes input is valid 
        /// (e.g. <paramref name="start" /> minor or equals to <paramref name="end" />).
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private IGeometry ComputeLinear(LinearLocation start, LinearLocation end)
        {
            LinearGeometryBuilder builder = new LinearGeometryBuilder(line.Factory);
            builder.FixInvalidLines = true;

            if (!start.IsVertex)
                builder.Add(start.GetCoordinate(line));

            LinearIterator it = new LinearIterator(line, start);
            foreach (LinearIterator.LinearElement element in it)
            {
                int compare = end.CompareLocationValues(element.ComponentIndex, element.VertexIndex, 0.0);
                if (compare < 0)
                    break;

                ICoordinate pt = element.SegmentStart;
                builder.Add(pt);
                if (element.IsEndOfLine)
                    builder.EndLine();
            }            
            
            if (!end.IsVertex)
                builder.Add(end.GetCoordinate(line));

            return builder.GetGeometry();
        }