/// <summary>
        ///
        /// </summary>
        /// <param name="loc"></param>
        /// <returns></returns>
        public virtual 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);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="subLine"></param>
        /// <returns></returns>
        public virtual LinearLocation[] IndicesOf(IGeometry subLine)
        {
            ICoordinate startPt  = ((ILineString)subLine.GetGeometryN(0)).GetCoordinateN(0);
            ILineString lastLine = (ILineString)subLine.GetGeometryN(subLine.NumGeometries - 1);
            ICoordinate endPt    = lastLine.GetCoordinateN(lastLine.NumPoints - 1);

            LocationIndexOfPoint locPt = new LocationIndexOfPoint(linearGeom);

            LinearLocation[] 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);
        }
        /// <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>
        /// 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());
        }
        /// <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 virtual 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);
        }
        /// <summary>
        /// Computes the <see cref="Coordinate" /> for the point
        /// on the line at the given index.
        /// If the 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 virtual ICoordinate ExtractPoint(double index)
        {
            LinearLocation loc = LengthLocationMap.GetLocation(linearGeom, index);

            return(loc.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));
        }
Example #8
0
 /// <summary>
 /// Creates an iterator starting at a <see cref="LinearLocation" /> on a linear <see cref="Geometry" />.
 /// </summary>
 /// <param name="linear">The linear geometry to iterate over.</param>
 /// <param name="start">The location to start at.</param>
 public LinearIterator(IGeometry linear, LinearLocation start) :
     this(linear, start.ComponentIndex, SegmentEndVertexIndex(start))
 {
 }
Example #9
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 virtual IGeometry ExtractLine(LinearLocation startIndex, LinearLocation endIndex)
 {
     return(ExtractLineByLocation.Extract(linearGeom, startIndex, endIndex));
 }
Example #10
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 virtual ICoordinate ExtractPoint(LinearLocation index)
 {
     return(index.GetCoordinate(linearGeom));
 }
Example #11
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 virtual bool isValidIndex(LinearLocation index)
 {
     return(index.IsValid(linearGeom));
 }
        /// <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(Geometry linearGeom, LinearLocation loc)
        {
            LengthLocationMap locater = new LengthLocationMap(linearGeom);

            return(locater.GetLength(loc));
        }