/// <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); }
/// <summary> /// Assumes input is valid (e.g. start <= 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)); }
private static int SegmentEndVertexIndex(LinearLocation loc) { if (loc.SegmentFraction > 0.0) { return(loc.SegmentIndex + 1); } return(loc.SegmentIndex); }
/// <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)); }
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); }
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)); }
/// <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)); }
/// <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)) { }
/// <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)); }
/// <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)); }
/// <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)); }