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); }
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); }
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; }
/// <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; }
/// <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); }
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; }
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); }
/// <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); }
/// <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 <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); }
/// <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); }
/// <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(); }