/// <summary>
 /// 
 /// </summary>
 /// <param name="seg"></param>
 /// <param name="inputPt"></param>
 /// <returns></returns>
 public static double SegmentFraction(LineSegment seg, ICoordinate inputPt)
 {
     double segFrac = seg.ProjectionFactor(inputPt);
     if (segFrac < 0.0)
         segFrac = 0.0;
     else if (segFrac > 1.0)
         segFrac = 1.0;
     return segFrac;
 }
        /**
         * @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;
            }
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="seg"></param>
 /// <param name="inputPt"></param>
 /// <param name="segmentStartMeasure"></param>
 /// <returns></returns>
 private double SegmentNearestMeasure(LineSegment seg, ICoordinate 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;
 }