public void TestProjectionFactor() { // zero-length line var seg = new LineSegment(10, 0, 10, 0); Assert.IsTrue(Double.IsNaN(seg.ProjectionFactor(new Coordinate(11, 0)))); var seg2 = new LineSegment(10, 0, 20, 0); Assert.IsTrue(seg2.ProjectionFactor(new Coordinate(11, 0)) == 0.1); }
/// <summary> /// /// </summary> /// <param name="seg"></param> /// <param name="inputPt"></param> /// <param name="segmentStartMeasure"></param> /// <returns></returns> private static double SegmentNearestMeasure(LineSegment seg, Coordinate inputPt, double segmentStartMeasure) { // found new minimum, so compute location distance of point double projFactor = seg.ProjectionFactor(inputPt); if (projFactor <= 0.0) return segmentStartMeasure; if (projFactor <= 1.0) return segmentStartMeasure + projFactor * seg.Length; // ASSERT: projFactor > 1.0 return segmentStartMeasure + seg.Length; }
/** * @param co * input coordinate in the neighbourhood of the MLineString * @param tolerance * max. distance that co may be from this MLineString * @return an MCoordinate on this MLineString with appropriate M-value */ public MCoordinate GetClosestPoint(ICoordinate co, double tolerance) { if (!this.IsMonotone(false)) { throw new ApplicationException("MGeometryException.OPERATION_REQUIRES_MONOTONE"); } if (!this.IsEmpty) { LineSegment seg = new LineSegment(); ICoordinate[] coAr = this.Coordinates; seg.P0 = coAr[0]; double d = 0.0; double projfact = 0.0; double minDist = Double.PositiveInfinity; MCoordinate mincp = null; for (int i = 1; i < coAr.Length; i++) { seg.P1 = coAr[i]; ICoordinate cp = seg.ClosestPoint(co); d = cp.Distance(co); if (d <= tolerance && d <= minDist) { MCoordinate testcp = new MCoordinate(cp); projfact = seg.ProjectionFactor(cp); testcp.M = ((MCoordinate)coAr[i - 1]).M + projfact * (((MCoordinate)coAr[i]).M - ((MCoordinate)coAr[i - 1]).M); if (d < minDist || testcp.M < mincp.M) { mincp = testcp; minDist = d; } } seg.P0 = seg.P1; } if (minDist > tolerance) { return null; } else { return mincp; } } else { return null; } }