/// <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);
        }
示例#2
0
    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);
    }