Beispiel #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="length"></param>
        /// <returns></returns>
        private LinearLocation GetLocationForward(double length)
        {
            if (length <= 0.0)
            {
                return(new LinearLocation());
            }

            double totalLength = 0.0;

            var it = new LinearIterator(_linearGeom);

            while (it.HasNext())
            {
                /**
                 * Special handling is required for the situation when the
                 * length references exactly to a component endpoint.
                 * In this case, the endpoint location of the current component
                 * is returned,
                 * rather than the startpoint location of the next component.
                 * This produces consistent behaviour with the project method.
                 */
                if (it.IsEndOfLine)
                {
                    if (totalLength == length)
                    {
                        int compIndex = it.ComponentIndex;
                        int segIndex  = it.VertexIndex;
                        return(new LinearLocation(compIndex, segIndex, 0.0));
                    }
                }
                else
                {
                    var    p0     = it.SegmentStart;
                    var    p1     = it.SegmentEnd;
                    double segLen = p1.Distance(p0);
                    // length falls in this segment
                    if (totalLength + segLen > length)
                    {
                        double frac      = (length - totalLength) / segLen;
                        int    compIndex = it.ComponentIndex;
                        int    segIndex  = it.VertexIndex;
                        return(new LinearLocation(compIndex, segIndex, frac));
                    }
                    totalLength += segLen;
                }

                it.Next();
            }
            // length is longer than line - return end location
            return(LinearLocation.GetEndLocation(_linearGeom));
        }
Beispiel #2
0
        /// <summary>
        /// Computes the <see cref="LineString" /> for the interval
        /// on the line between the given indices.
        /// If the <paramref name="endIndex" /> lies before the <paramref name="startIndex" />,
        /// the computed geometry is reversed.
        /// </summary>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <returns></returns>
        public IGeometry ExtractLine(double startIndex, double endIndex)
        {
            LocationIndexedLine lil = new LocationIndexedLine(_linearGeom);
            double startIndex2      = ClampIndex(startIndex);
            double endIndex2        = ClampIndex(endIndex);
            // if extracted line is zero-length, resolve start lower as well to ensure they are equal
            bool           resolveStartLower = startIndex2 == endIndex2;
            LinearLocation startLoc          = LocationOf(startIndex2, resolveStartLower);
            //    LinearLocation endLoc = locationOf(endIndex2, true);
            //    LinearLocation startLoc = locationOf(startIndex2);
            LinearLocation endLoc = LocationOf(endIndex2);

            return(ExtractLineByLocation.Extract(_linearGeom, startLoc, endLoc));
        }
        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);
        }
Beispiel #4
0
        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));
        }
        /// <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].Copy();
            }
            else
            {
                subLineLoc[1] = locPt.IndexOfAfter(endPt, subLineLoc[0]);
            }
            return(subLineLoc);
        }
        /// <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(Coordinate inputPt, LinearLocation minIndex)
        {
            if (minIndex == null)
            {
                return(IndexOf(inputPt));
            }

            // sanity check for minLocation at or past end of line
            var endLoc = LinearLocation.GetEndLocation(_linearGeom);

            if (endLoc.CompareTo(minIndex) <= 0)
            {
                return(endLoc);
            }

            var 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>
 /// 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))
 {
 }
Beispiel #8
0
        /// <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>
        /// <remarks>
        /// The Z-ordinate of the computed point will be interpolated from
        /// the Z-ordinates of the line segment containing it, if they exist.
        /// </remarks>
        /// <param name="index">The index of the desired point.</param>
        /// <returns>The <see cref="Coordinate" /> at the given index.</returns>
        public Coordinate ExtractPoint(double index)
        {
            LinearLocation loc = LengthLocationMap.GetLocation(_linearGeom, index);

            return(loc.GetCoordinate(_linearGeom));
        }
Beispiel #9
0
 /// <summary>
 /// Computes the <see cref="LineString" /> for the interval
 /// on the line between the given indices.
 /// If the start location is after the end location,
 /// the computed linear geometry has reverse orientation to the input line.
 /// </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 Geometry ExtractLine(LinearLocation startIndex, LinearLocation endIndex)
 {
     return(ExtractLineByLocation.Extract(_linearGeom, startIndex, endIndex));
 }
Beispiel #10
0
        /// <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)
        {
            var indexLow = index.ToLowest(_linearGeom);

            return(indexLow.GetSegment(_linearGeom).PointAlongOffset(indexLow.SegmentFraction, offsetDistance));
        }
Beispiel #11
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>
 /// <remarks>
 /// The Z-ordinate of the computed point will be interpolated from
 /// the Z-ordinates of the line segment containing it, if they exist.
 /// </remarks>
 /// <param name="index">The index of the desired point.</param>
 /// <returns>The <see cref="Coordinate" /> at the given index.</returns>
 public Coordinate ExtractPoint(LinearLocation index)
 {
     return(index.GetCoordinate(_linearGeom));
 }
Beispiel #12
0
 /// <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));
 }
        public static LinearLocation IndexOfAfter(IGeometry linearGeom, Coordinate inputPt, LinearLocation minIndex)
        {
            var locater = new LocationIndexOfPoint(linearGeom);

            return(locater.IndexOfAfter(inputPt, minIndex));
        }
Beispiel #14
0
        /// <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)
        {
            var locater = new LengthLocationMap(linearGeom);

            return(locater.GetLength(loc));
        }
Beispiel #15
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));
 }
        /// <summary>
        /// Computes the subline of a <see cref="ILineString" /> between
        /// two <see cref="LinearLocation"/>s 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)
        {
            var ls = new ExtractLineByLocation(line);

            return(ls.Extract(start, end));
        }
        ///<summary>
        /// Computes the <see cref="Coordinate"/> for the point on the line at the given index, offset by the given distance.
        ///</summary>
        /// <remarks>
        /// If the index is out of range the first or last point on the line will be returned.
        /// The computed point is offset to the left of the line if the offset distance is
        /// positive, to the right if negative.
        /// The Z-ordinate of the computed point will be interpolated from the Z-ordinates of the line segment containing it, if they exist.
        /// </remarks>
        /// <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(double index, double offsetDistance)
        {
            LinearLocation loc = LengthLocationMap.GetLocation(_linearGeom, index);

            return(loc.GetSegment(_linearGeom).PointAlongOffset(loc.SegmentFraction, offsetDistance));
        }