internal GeodeticMeasurement CalculateGeodeticMeasurement(Ellipsoid refEllipsoid, GlobalPosition start, GlobalPosition end, double tolerance)
        {
            // get the coordinates
            GlobalCoordinates startCoords = start.Coordinates;
            GlobalCoordinates endCoords   = end.Coordinates;

            // calculate elevation differences
            double elev1  = start.ElevationMeters;
            double elev2  = end.ElevationMeters;
            double elev12 = (elev1 + elev2) / 2.0;

            // calculate latitude differences
            double phi1  = startCoords.Latitude.Radians;
            double phi2  = endCoords.Latitude.Radians;
            double phi12 = (phi1 + phi2) / 2.0;

            // calculate a new ellipsoid to accommodate average elevation
            double    refA      = refEllipsoid.SemiMajorAxisMeters;
            double    f         = refEllipsoid.Flattening;
            double    a         = refA + elev12 * (1.0 + f * Math.Sin(phi12));
            Ellipsoid ellipsoid = Ellipsoid.FromAAndF(a, f);

            // calculate the curve at the average elevation
            GeodeticCurve averageCurve = CalculateGeodeticCurve(ellipsoid, startCoords, endCoords, tolerance);

            // return the measurement
            return(new GeodeticMeasurement(averageCurve, elev2 - elev1));
        }
 /// <summary>
 /// Calculate the three dimensional geodetic measurement between two positions
 /// measured in reference to a specified ellipsoid.
 ///
 /// This calculation is performed by first computing a new ellipsoid by expanding or contracting
 /// the reference ellipsoid such that the new ellipsoid passes through the average elevation
 /// of the two positions.  A geodetic curve across the new ellisoid is calculated.  The
 /// point-to-point distance is calculated as the hypotenuse of a right triangle where the length
 /// of one side is the ellipsoidal distance and the other is the difference in elevation.
 /// </summary>
 /// <param name="refEllipsoid">reference ellipsoid to use</param>
 /// <param name="start">starting position</param>
 /// <param name="end">ending position</param>
 /// <returns></returns>
 public GeodeticMeasurement CalculateGeodeticMeasurement(Ellipsoid refEllipsoid, GlobalPosition start, GlobalPosition end) => this.CalculateGeodeticMeasurement(refEllipsoid, start, end, StandardTolerance);