/// <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> ///// 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> /// /// </summary> /// <param name="inputPt"></param> /// <param name="minIndex"></param> /// <returns></returns> private double IndexOfFromStart(Coordinate inputPt, double minIndex) { var minDistance = Double.MaxValue; var ptMeasure = minIndex; var segmentStartMeasure = 0.0; var seg = new LineSegment(); var it = new LinearIterator(_linearGeom); while (it.HasNext()) { if (!it.IsEndOfLine) { seg.P0 = it.SegmentStart; seg.P1 = it.SegmentEnd; var segDistance = seg.Distance(inputPt); var segMeasureToPt = SegmentNearestMeasure(seg, inputPt, segmentStartMeasure); if (segDistance < minDistance && segMeasureToPt > minIndex) { ptMeasure = segMeasureToPt; minDistance = segDistance; } segmentStartMeasure += seg.Length; } it.Next(); } return(ptMeasure); }
/// <summary> /// /// </summary> /// <param name="length"></param> /// <returns></returns> private LinearLocation GetLocationForward(double length) { if (length <= 0.0) { return(new LinearLocation()); } var 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; var segLen = p1.Distance(p0); // length falls in this segment if (totalLength + segLen > length) { var frac = (length - totalLength) / segLen; var compIndex = it.ComponentIndex; var 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)); }
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); }