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);