/// <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)
        {
            // get the coordinates
            GlobalCoordinates startCoords = start.Coordinates;
            GlobalCoordinates endCoords   = end.Coordinates;

            // calculate elevation differences
            double elev1  = start.Elevation;
            double elev2  = end.Elevation;
            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.SemiMajorAxis;
            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);

            // return the measurement
            return(new GeodeticMeasurement(averageCurve, elev2 - elev1));
        }
        /// <summary>
        /// Creates a new instance of GeodeticMeasurement.
        /// </summary>
        /// <param name="averageCurve">the geodetic curve as measured at the average elevation between two points</param>
        /// <param name="elevationChange">the change in elevation, in meters, going from the starting point to the ending point</param>
        public GeodeticMeasurement(GeodeticCurve averageCurve, double elevationChange)
        {
            double ellDist = averageCurve.EllipsoidalDistance;

            mCurve           = averageCurve;
            mElevationChange = elevationChange;
            mP2P             = Math.Sqrt(ellDist * ellDist + mElevationChange * mElevationChange);
        }