예제 #1
0
        /// <summary> Gets a location which refers to the end of a linear <see cref="Geometry"/>.</summary>
        /// <param name="linear">the linear geometry
        /// </param>
        /// <returns> a new <tt>LinearLocation</tt>
        /// </returns>
        public static LinearLocation GetEndLocation(Geometry linear)
        {
            // assert: linear is LineString or MultiLineString
            LinearLocation loc = new LinearLocation();

            loc.SetToEnd(linear);

            return(loc);
        }
예제 #2
0
        /// <summary>
        /// Assumes input is valid (e.g. start &lt;= end)
        /// </summary>
        /// <param name="start">
        /// </param>
        /// <param name="end">
        /// </param>
        /// <returns>A linear geometry.</returns>
        private LineString ComputeLine(LinearLocation start, LinearLocation end)
        {
            ICoordinateList      coordinates    = line.Coordinates;
            CoordinateCollection newCoordinates = new CoordinateCollection();

            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.Count)
            {
                lastSegmentIndex = coordinates.Count - 1;
            }
            // not needed - LinearLocation values should always be correct
            //Assert.isTrue(end.getSegmentFraction() <= 1.0, "invalid segment fraction value");

            if (!start.Vertex)
            {
                newCoordinates.Add(start.GetCoordinate(line));
            }

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

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

            Coordinate[] newCoordinateArray = newCoordinates.ToArray();

            // 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 Coordinate[] { newCoordinateArray[0],
                                                        newCoordinateArray[0] };
            }

            return(line.Factory.CreateLineString(newCoordinateArray));
        }
예제 #3
0
        private static int SegmentEndVertexIndex(LinearLocation loc)
        {
            if (loc.SegmentFraction > 0.0)
            {
                return(loc.SegmentIndex + 1);
            }

            return(loc.SegmentIndex);
        }
예제 #4
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>
        /// <remarks>
        /// If the endIndex lies before the startIndex, the computed
        /// geometry is reversed.
        /// </remarks>
        public virtual Geometry ExtractLine(double startIndex, double endIndex)
        {
//			LocationIndexedLine lil = new LocationIndexedLine(linearGeom);

            LinearLocation startLoc = LocationOf(startIndex);
            LinearLocation endLoc   = LocationOf(endIndex);

            return(ExtractLineByLocation.Extract(linearGeom,
                                                 startLoc, endLoc));
        }
예제 #5
0
        private LinearLocation IndexOfFromStart(Coordinate inputPt,
                                                LinearLocation minIndex)
        {
            double minDistance       = Double.MaxValue;
            int    minComponentIndex = 0;
            int    minSegmentIndex   = 0;
            double minFrac           = -1.0;

            LineSegment seg = new LineSegment(linearGeom.Factory);

            for (LinearIterator it = new LinearIterator(linearGeom);
                 it.HasNext(); it.Next())
            {
                if (!it.EndOfLine)
                {
                    seg.p0 = it.SegmentStart;
                    seg.p1 = it.SegmentEnd;
                    double segDistance = seg.Distance(inputPt);
                    double segFrac     = SegmentFraction(seg, inputPt);

                    int candidateComponentIndex = it.ComponentIndex;
                    int 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;
                        }
                    }
                }
            }

            LinearLocation loc = new LinearLocation(minComponentIndex,
                                                    minSegmentIndex, minFrac);

            return(loc);
        }
예제 #6
0
        private LinearLocation GetLocationForward(double length)
        {
            if (length <= 0.0)
            {
                return(new LinearLocation());
            }

            double totalLength = 0.0;

            LinearIterator it = new LinearIterator(linearGeom);

            while (it.HasNext())
            {
                if (!it.EndOfLine)
                {
                    Coordinate p0     = it.SegmentStart;
                    Coordinate 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));
        }
예제 #7
0
        /// <summary>
        /// Computes the length for a given <see cref="LinearLocation"/>
        /// on a linear <see cref="Geometry"/>.
        /// </summary>
        /// <param name="line">The linear geometry to use.</param>
        /// <param name="loc">
        /// The <see cref="LinearLocation"/> index of the location.
        /// </param>
        /// <returns>
        /// This 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));
        }
예제 #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(Geometry linear, LinearLocation start)
     : this(linear, start.ComponentIndex, SegmentEndVertexIndex(start))
 {
 }
예제 #9
0
 /// <summary> Tests whether an index is in the valid index range for the line.
 ///
 /// </summary>
 /// <param name="length">the index to test
 /// </param>
 /// <returns> <see langword="true"/> if the index is in the valid range
 /// </returns>
 public bool IsValidIndex(LinearLocation index)
 {
     return(index.IsValid(linearGeom));
 }
예제 #10
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 Geometry ExtractLine(LinearLocation startIndex,
                             LinearLocation endIndex)
 {
     return(ExtractLineByLocation.Extract(linearGeom,
                                          startIndex, endIndex));
 }
예제 #11
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>
 /// <param name="length">the index of the desired point
 /// </param>
 /// <returns> the Coordinate at the given index
 /// </returns>
 public Coordinate ExtractPoint(LinearLocation index)
 {
     return(index.GetCoordinate(linearGeom));
 }