/// <summary> /// Calculate how far the point is along a track from the start-point, heading towards the end-point. /// <para>That is, if a perpendicular is drawn from the point to the (great circle) path, the along-track distance is the distance from the start point to where the perpendicular crosses the path.</para> /// </summary> /// <param name="pointA">The point to calculate the distance from.</param> /// <param name="startPoint">Start point of great circle path.</param> /// <param name="endPoint">End point of great circle path.</param> /// <param name="radius">Radius of earth.</param> /// <returns>The distance along great circle to point nearest point A in the same units as the radius.</returns> public double AlongTrackDistance(ICoordinate pointA, ICoordinate startPoint, ICoordinate endPoint, double radius) { if (pointA == null) { throw new ArgumentNullException(nameof(pointA), "The argument cannot be null."); } if (startPoint == null) { throw new ArgumentNullException(nameof(startPoint), "The argument cannot be null."); } if (endPoint == null) { throw new ArgumentNullException(nameof(endPoint), "The argument cannot be null."); } ValidateRadius(radius); var δ13 = startPoint.DistanceTo(pointA, radius) / radius; var θ13 = startPoint.BearingTo(pointA).ToRadians(); var θ12 = startPoint.BearingTo(endPoint).ToRadians(); var δxt = Math.Asin(Math.Sin(δ13) * Math.Sin(θ13 - θ12)); var δat = Math.Acos(Math.Cos(δ13) / Math.Abs(Math.Cos(δxt))); var result = δat * Math.Sign(Math.Cos(θ12 - θ13)) * radius; return(result); }
public ICoordinate FindNearest(ICoordinate aPoint) { var mc = aPoint.HilbertIndex(); var nearestGuess = orderedData.Values[orderedIndexes.FindNearestIndex(mc)][0]; var guessDist = aPoint.DistanceTo(nearestGuess); var offsetPOI = new PointOfInterest(guessDist, guessDist); var minmc = (aPoint.Minus(offsetPOI)).HilbertIndex(); var minmci = orderedIndexes.FindNearestIndex(minmc); var maxmc = (aPoint.Plus(offsetPOI)).HilbertIndex(); var maxmci = orderedIndexes.FindNearestIndex(maxmc); for (int j2 = minmci; j2 < maxmci; ++j2) { var tryList = orderedData.Values[j2]; for (int j3 = 0; j3 < tryList.Count; ++j3) { var y = tryList[j3]; var ydist = ((y.Longitude - aPoint.Longitude) * (y.Longitude - aPoint.Longitude) + (y.Latitude - aPoint.Latitude) * (y.Latitude - aPoint.Latitude)); if (ydist < guessDist) { nearestGuess = y; guessDist = ydist; } } } return(nearestGuess); }