522 lines
24 KiB
C++
522 lines
24 KiB
C++
/**
|
|
* \file NETGeographicLib/Ellipsoid.h
|
|
* \brief Header for NETGeographicLib::Ellipsoid class
|
|
*
|
|
* NETGeographicLib is copyright (c) Scott Heiman (2013)
|
|
* GeographicLib is Copyright (c) Charles Karney (2010-2012)
|
|
* <charles@karney.com> and licensed under the MIT/X11 License.
|
|
* For more information, see
|
|
* http://geographiclib.sourceforge.net/
|
|
**********************************************************************/
|
|
#pragma once
|
|
|
|
namespace NETGeographicLib
|
|
{
|
|
/**
|
|
* \brief .NET wrapper for GeographicLib::Ellipsoid.
|
|
*
|
|
* This class allows .NET applications to access GeographicLib::Ellipsoid.
|
|
*
|
|
* This class returns various properties of the ellipsoid and converts
|
|
* between various types of latitudes. The latitude conversions are also
|
|
* possible using the various projections supported by %GeographicLib; but
|
|
* Ellipsoid provides more direct access (sometimes using private functions
|
|
* of the projection classes). Ellipsoid::RectifyingLatitude,
|
|
* Ellipsoid::InverseRectifyingLatitude, and Ellipsoid::MeridianDistance
|
|
* provide functionality which can be provided by the Geodesic class.
|
|
* However Geodesic uses a series approximation (valid for abs \e f < 1/150),
|
|
* whereas Ellipsoid computes these quantities using EllipticFunction which
|
|
* provides accurate results even when \e f is large. Use of this class
|
|
* should be limited to −3 < \e f < 3/4 (i.e., 1/4 < b/a < 4).
|
|
*
|
|
* C# Example:
|
|
* \include example-Ellipsoid.cs
|
|
* Managed C++ Example:
|
|
* \include example-Ellipsoid.cpp
|
|
* Visual Basic Example:
|
|
* \include example-Ellipsoid.vb
|
|
*
|
|
* <B>INTERFACE DIFFERENCES:</B><BR>
|
|
* A default constructor has been provided that assumes a WGS84 ellipsoid.
|
|
*
|
|
* The following functions are implemented as properties:
|
|
* MajorRadius, MinorRadius, QuarterMeridian, Area, Volume, Flattening,
|
|
* SecondFlattening, ThirdFlattening, EccentricitySq, SecondEccentricitySq,
|
|
* and ThirdEccentricitySq.
|
|
**********************************************************************/
|
|
public ref class Ellipsoid
|
|
{
|
|
private:
|
|
// A pointer to the unmanaged GeographicLib::Ellipsoid
|
|
GeographicLib::Ellipsoid* m_pEllipsoid;
|
|
|
|
// Th efinalizer frees the unmanaged memory when the object is destroyed.
|
|
!Ellipsoid();
|
|
public:
|
|
/** \name Constructor
|
|
**********************************************************************/
|
|
///@{
|
|
|
|
/**
|
|
* Constructor for a WGS84 ellipsoid
|
|
**********************************************************************/
|
|
Ellipsoid();
|
|
|
|
/**
|
|
* Constructor for a ellipsoid with
|
|
*
|
|
* @param[in] a equatorial radius (meters).
|
|
* @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
|
|
* Negative \e f gives a prolate ellipsoid. If \e f > 1, set flattening
|
|
* to 1/\e f.
|
|
* @exception GeographicErr if \e a or (1 − \e f ) \e a is not
|
|
* positive.
|
|
**********************************************************************/
|
|
Ellipsoid(double a, double f);
|
|
///@}
|
|
|
|
/** The destructor calls the finalizer.
|
|
**********************************************************************/
|
|
~Ellipsoid()
|
|
{ this->!Ellipsoid(); }
|
|
|
|
/** \name %Ellipsoid dimensions.
|
|
**********************************************************************/
|
|
///@{
|
|
|
|
/**
|
|
* @return \e a the equatorial radius of the ellipsoid (meters). This is
|
|
* the value used in the constructor.
|
|
**********************************************************************/
|
|
property double MajorRadius { double get(); }
|
|
|
|
/**
|
|
* @return \e b the polar semi-axis (meters).
|
|
**********************************************************************/
|
|
property double MinorRadius { double get(); }
|
|
|
|
/**
|
|
* @return \e L the distance between the equator and a pole along a
|
|
* meridian (meters). For a sphere \e L = (π/2) \e a. The radius
|
|
* of a sphere with the same meridian length is \e L / (π/2).
|
|
**********************************************************************/
|
|
property double QuarterMeridian { double get(); }
|
|
|
|
/**
|
|
* @return \e A the total area of the ellipsoid (meters<sup>2</sup>). For
|
|
* a sphere \e A = 4π <i>a</i><sup>2</sup>. The radius of a sphere
|
|
* with the same area is sqrt(\e A / (4π)).
|
|
**********************************************************************/
|
|
property double Area { double get(); }
|
|
|
|
/**
|
|
* @return \e V the total volume of the ellipsoid (meters<sup>3</sup>).
|
|
* For a sphere \e V = (4π / 3) <i>a</i><sup>3</sup>. The radius of
|
|
* a sphere with the same volume is cbrt(\e V / (4π/3)).
|
|
**********************************************************************/
|
|
property double Volume { double get(); }
|
|
///@}
|
|
|
|
/** \name %Ellipsoid shape
|
|
**********************************************************************/
|
|
///@{
|
|
|
|
/**
|
|
* @return \e f = (\e a − \e b) / \e a, the flattening of the
|
|
* ellipsoid. This is the value used in the constructor. This is zero,
|
|
* positive, or negative for a sphere, oblate ellipsoid, or prolate
|
|
* ellipsoid.
|
|
**********************************************************************/
|
|
property double Flattening { double get(); }
|
|
|
|
/**
|
|
* @return \e f ' = (\e a − \e b) / \e b, the second flattening of
|
|
* the ellipsoid. This is zero, positive, or negative for a sphere,
|
|
* oblate ellipsoid, or prolate ellipsoid.
|
|
**********************************************************************/
|
|
property double SecondFlattening { double get(); }
|
|
|
|
/**
|
|
* @return \e n = (\e a − \e b) / (\e a + \e b), the third flattening
|
|
* of the ellipsoid. This is zero, positive, or negative for a sphere,
|
|
* oblate ellipsoid, or prolate ellipsoid.
|
|
**********************************************************************/
|
|
property double ThirdFlattening { double get(); }
|
|
|
|
/**
|
|
* @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> −
|
|
* <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity squared
|
|
* of the ellipsoid. This is zero, positive, or negative for a sphere,
|
|
* oblate ellipsoid, or prolate ellipsoid.
|
|
**********************************************************************/
|
|
property double EccentricitySq { double get(); }
|
|
|
|
/**
|
|
* @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> −
|
|
* <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentricity
|
|
* squared of the ellipsoid. This is zero, positive, or negative for a
|
|
* sphere, oblate ellipsoid, or prolate ellipsoid.
|
|
**********************************************************************/
|
|
property double SecondEccentricitySq { double get(); }
|
|
|
|
/**
|
|
* @return <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> −
|
|
* <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + <i>b</i><sup>2</sup>),
|
|
* the third eccentricity squared of the ellipsoid. This is zero,
|
|
* positive, or negative for a sphere, oblate ellipsoid, or prolate
|
|
* ellipsoid.
|
|
**********************************************************************/
|
|
property double ThirdEccentricitySq { double get(); }
|
|
///@}
|
|
|
|
/** \name Latitude conversion.
|
|
**********************************************************************/
|
|
///@{
|
|
|
|
/**
|
|
* @param[in] phi the geographic latitude (degrees).
|
|
* @return β the parametric latitude (degrees).
|
|
*
|
|
* The geographic latitude, φ, is the angle beween the equatorial
|
|
* plane and a vector normal to the surface of the ellipsoid.
|
|
*
|
|
* The parametric latitude (also called the reduced latitude), β,
|
|
* allows the cartesian coordinated of a meridian to be expressed
|
|
* conveniently in parametric form as
|
|
* - \e R = \e a cos β
|
|
* - \e Z = \e b sin β
|
|
* .
|
|
* where \e a and \e b are the equatorial radius and the polar semi-axis.
|
|
* For a sphere β = φ.
|
|
*
|
|
* φ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold. The returned value
|
|
* β lies in [−90°, 90°].
|
|
**********************************************************************/
|
|
double ParametricLatitude(double phi);
|
|
|
|
/**
|
|
* @param[in] beta the parametric latitude (degrees).
|
|
* @return φ the geographic latitude (degrees).
|
|
*
|
|
* β must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold. The returned value
|
|
* φ lies in [−90°, 90°].
|
|
**********************************************************************/
|
|
double InverseParametricLatitude(double beta);
|
|
|
|
/**
|
|
* @param[in] phi the geographic latitude (degrees).
|
|
* @return θ the geocentric latitude (degrees).
|
|
*
|
|
* The geocentric latitude, θ, is the angle beween the equatorial
|
|
* plane and a line between the center of the ellipsoid and a point on the
|
|
* ellipsoid. For a sphere θ = φ.
|
|
*
|
|
* φ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold. The returned value
|
|
* θ lies in [−90°, 90°].
|
|
**********************************************************************/
|
|
double GeocentricLatitude(double phi);
|
|
|
|
/**
|
|
* @param[in] theta the geocentric latitude (degrees).
|
|
* @return φ the geographic latitude (degrees).
|
|
*
|
|
* θ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold. The returned value
|
|
* φ lies in [−90°, 90°].
|
|
**********************************************************************/
|
|
double InverseGeocentricLatitude(double theta);
|
|
|
|
/**
|
|
* @param[in] phi the geographic latitude (degrees).
|
|
* @return μ the rectifying latitude (degrees).
|
|
*
|
|
* The rectifying latitude, μ, has the property that the distance along
|
|
* a meridian of the ellipsoid between two points with rectifying latitudes
|
|
* μ<sub>1</sub> and μ<sub>2</sub> is equal to
|
|
* (μ<sub>2</sub> - μ<sub>1</sub>) \e L / 90°,
|
|
* where \e L = QuarterMeridian(). For a sphere μ = φ.
|
|
*
|
|
* φ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold. The returned value
|
|
* μ lies in [−90°, 90°].
|
|
**********************************************************************/
|
|
double RectifyingLatitude(double phi);
|
|
|
|
/**
|
|
* @param[in] mu the rectifying latitude (degrees).
|
|
* @return φ the geographic latitude (degrees).
|
|
*
|
|
* μ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold. The returned value
|
|
* φ lies in [−90°, 90°].
|
|
**********************************************************************/
|
|
double InverseRectifyingLatitude(double mu);
|
|
|
|
/**
|
|
* @param[in] phi the geographic latitude (degrees).
|
|
* @return ξ the authalic latitude (degrees).
|
|
*
|
|
* The authalic latitude, ξ, has the property that the area of the
|
|
* ellipsoid between two circles with authalic latitudes
|
|
* ξ<sub>1</sub> and ξ<sub>2</sub> is equal to (sin
|
|
* ξ<sub>2</sub> - sin ξ<sub>1</sub>) \e A / 2, where \e A
|
|
* = Area(). For a sphere ξ = φ.
|
|
*
|
|
* φ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold. The returned value
|
|
* ξ lies in [−90°, 90°].
|
|
**********************************************************************/
|
|
double AuthalicLatitude(double phi);
|
|
|
|
/**
|
|
* @param[in] xi the authalic latitude (degrees).
|
|
* @return φ the geographic latitude (degrees).
|
|
*
|
|
* ξ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold. The returned value
|
|
* φ lies in [−90°, 90°].
|
|
**********************************************************************/
|
|
double InverseAuthalicLatitude(double xi);
|
|
|
|
/**
|
|
* @param[in] phi the geographic latitude (degrees).
|
|
* @return χ the conformal latitude (degrees).
|
|
*
|
|
* The conformal latitude, χ, gives the mapping of the ellipsoid to a
|
|
* sphere which which is conformal (angles are preserved) and in which the
|
|
* equator of the ellipsoid maps to the equator of the sphere. For a
|
|
* sphere χ = φ.
|
|
*
|
|
* φ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold. The returned value
|
|
* χ lies in [−90°, 90°].
|
|
**********************************************************************/
|
|
double ConformalLatitude(double phi);
|
|
|
|
/**
|
|
* @param[in] chi the conformal latitude (degrees).
|
|
* @return φ the geographic latitude (degrees).
|
|
*
|
|
* χ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold. The returned value
|
|
* φ lies in [−90°, 90°].
|
|
**********************************************************************/
|
|
double InverseConformalLatitude(double chi);
|
|
|
|
/**
|
|
* @param[in] phi the geographic latitude (degrees).
|
|
* @return ψ the isometric latitude (degrees).
|
|
*
|
|
* The isometric latitude gives the mapping of the ellipsoid to a plane
|
|
* which which is conformal (angles are preserved) and in which the equator
|
|
* of the ellipsoid maps to a straight line of constant scale; this mapping
|
|
* defines the Mercator projection. For a sphere ψ =
|
|
* sinh<sup>−1</sup> tan φ.
|
|
*
|
|
* φ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold.
|
|
**********************************************************************/
|
|
double IsometricLatitude(double phi);
|
|
|
|
/**
|
|
* @param[in] psi the isometric latitude (degrees).
|
|
* @return φ the geographic latitude (degrees).
|
|
*
|
|
* The returned value φ lies in [−90°, 90°].
|
|
**********************************************************************/
|
|
double InverseIsometricLatitude(double psi);
|
|
///@}
|
|
|
|
/** \name Other quantities.
|
|
**********************************************************************/
|
|
///@{
|
|
|
|
/**
|
|
* @param[in] phi the geographic latitude (degrees).
|
|
* @return \e R = \e a cos β the radius of a circle of latitude
|
|
* φ (meters). \e R (π/180°) gives meters per degree
|
|
* longitude measured along a circle of latitude.
|
|
*
|
|
* φ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold.
|
|
**********************************************************************/
|
|
double CircleRadius(double phi);
|
|
|
|
/**
|
|
* @param[in] phi the geographic latitude (degrees).
|
|
* @return \e Z = \e b sin β the distance of a circle of latitude
|
|
* φ from the equator measured parallel to the ellipsoid axis
|
|
* (meters).
|
|
*
|
|
* φ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold.
|
|
**********************************************************************/
|
|
double CircleHeight(double phi);
|
|
|
|
/**
|
|
* @param[in] phi the geographic latitude (degrees).
|
|
* @return \e s the distance along a meridian
|
|
* between the equator and a point of latitude φ (meters). \e s is
|
|
* given by \e s = μ \e L / 90°, where \e L =
|
|
* QuarterMeridian()).
|
|
*
|
|
* φ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold.
|
|
**********************************************************************/
|
|
double MeridianDistance(double phi);
|
|
|
|
/**
|
|
* @param[in] phi the geographic latitude (degrees).
|
|
* @return ρ the meridional radius of curvature of the ellipsoid at
|
|
* latitude φ (meters); this is the curvature of the meridian. \e
|
|
* rho is given by ρ = (180°/π) d\e s / dφ,
|
|
* where \e s = MeridianDistance(); thus ρ (π/180°)
|
|
* gives meters per degree latitude measured along a meridian.
|
|
*
|
|
* φ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold.
|
|
**********************************************************************/
|
|
double MeridionalCurvatureRadius(double phi);
|
|
|
|
/**
|
|
* @param[in] phi the geographic latitude (degrees).
|
|
* @return ν the transverse radius of curvature of the ellipsoid at
|
|
* latitude φ (meters); this is the curvature of a curve on the
|
|
* ellipsoid which also lies in a plane perpendicular to the ellipsoid
|
|
* and to the meridian. ν is related to \e R = CircleRadius() by \e
|
|
* R = ν cos φ.
|
|
*
|
|
* φ must lie in the range [−90°, 90°]; the
|
|
* result is undefined if this condition does not hold.
|
|
**********************************************************************/
|
|
double TransverseCurvatureRadius(double phi);
|
|
|
|
/**
|
|
* @param[in] phi the geographic latitude (degrees).
|
|
* @param[in] azi the angle between the meridian and the normal section
|
|
* (degrees).
|
|
* @return the radius of curvature of the ellipsoid in the normal
|
|
* section at latitude φ inclined at an angle \e azi to the
|
|
* meridian (meters).
|
|
*
|
|
* φ must lie in the range [−90°, 90°] and \e
|
|
* azi must lie in the range [−540°, 540°); the
|
|
* result is undefined if either of conditions does not hold.
|
|
**********************************************************************/
|
|
double NormalCurvatureRadius(double phi, double azi);
|
|
///@}
|
|
|
|
/** \name Eccentricity conversions.
|
|
**********************************************************************/
|
|
///@{
|
|
|
|
/**
|
|
* @param[in] fp = \e f ' = (\e a − \e b) / \e b, the second
|
|
* flattening.
|
|
* @return \e f = (\e a − \e b) / \e a, the flattening.
|
|
*
|
|
* \e f ' should lie in (−1, ∞).
|
|
* The returned value \e f lies in (−∞, 1).
|
|
**********************************************************************/
|
|
static double SecondFlatteningToFlattening(double fp);
|
|
|
|
/**
|
|
* @param[in] f = (\e a − \e b) / \e a, the flattening.
|
|
* @return \e f ' = (\e a − \e b) / \e b, the second flattening.
|
|
*
|
|
* \e f should lie in (−∞, 1).
|
|
* The returned value \e f ' lies in (−1, ∞).
|
|
**********************************************************************/
|
|
static double FlatteningToSecondFlattening(double f);
|
|
|
|
/**
|
|
* @param[in] n = (\e a − \e b) / (\e a + \e b), the third
|
|
* flattening.
|
|
* @return \e f = (\e a − \e b) / \e a, the flattening.
|
|
*
|
|
* \e n should lie in (−1, 1).
|
|
* The returned value \e f lies in (−∞, 1).
|
|
**********************************************************************/
|
|
static double ThirdFlatteningToFlattening(double n);
|
|
|
|
/**
|
|
* @param[in] f = (\e a − \e b) / \e a, the flattening.
|
|
* @return \e n = (\e a − \e b) / (\e a + \e b), the third
|
|
* flattening.
|
|
*
|
|
* \e f should lie in (−∞, 1).
|
|
* The returned value \e n lies in (−1, 1).
|
|
**********************************************************************/
|
|
static double FlatteningToThirdFlattening(double f);
|
|
|
|
/**
|
|
* @param[in] e2 = <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> −
|
|
* <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity
|
|
* squared.
|
|
* @return \e f = (\e a − \e b) / \e a, the flattening.
|
|
*
|
|
* <i>e</i><sup>2</sup> should lie in (−∞, 1).
|
|
* The returned value \e f lies in (−∞, 1).
|
|
**********************************************************************/
|
|
static double EccentricitySqToFlattening(double e2);
|
|
|
|
/**
|
|
* @param[in] f = (\e a − \e b) / \e a, the flattening.
|
|
* @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> −
|
|
* <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity
|
|
* squared.
|
|
*
|
|
* \e f should lie in (−∞, 1).
|
|
* The returned value <i>e</i><sup>2</sup> lies in (−∞, 1).
|
|
**********************************************************************/
|
|
static double FlatteningToEccentricitySq(double f);
|
|
|
|
/**
|
|
* @param[in] ep2 = <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> −
|
|
* <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentricity
|
|
* squared.
|
|
* @return \e f = (\e a − \e b) / \e a, the flattening.
|
|
*
|
|
* <i>e'</i> <sup>2</sup> should lie in (−1, ∞).
|
|
* The returned value \e f lies in (−∞, 1).
|
|
**********************************************************************/
|
|
static double SecondEccentricitySqToFlattening(double ep2);
|
|
|
|
/**
|
|
* @param[in] f = (\e a − \e b) / \e a, the flattening.
|
|
* @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> −
|
|
* <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentricity
|
|
* squared.
|
|
*
|
|
* \e f should lie in (−∞, 1).
|
|
* The returned value <i>e'</i> <sup>2</sup> lies in (−1, ∞).
|
|
**********************************************************************/
|
|
static double FlatteningToSecondEccentricitySq(double f);
|
|
|
|
/**
|
|
* @param[in] epp2 = <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup>
|
|
* − <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> +
|
|
* <i>b</i><sup>2</sup>), the third eccentricity squared.
|
|
* @return \e f = (\e a − \e b) / \e a, the flattening.
|
|
*
|
|
* <i>e''</i> <sup>2</sup> should lie in (−1, 1).
|
|
* The returned value \e f lies in (−∞, 1).
|
|
**********************************************************************/
|
|
static double ThirdEccentricitySqToFlattening(double epp2);
|
|
|
|
/**
|
|
* @param[in] f = (\e a − \e b) / \e a, the flattening.
|
|
* @return <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> −
|
|
* <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + <i>b</i><sup>2</sup>),
|
|
* the third eccentricity squared.
|
|
*
|
|
* \e f should lie in (−∞, 1).
|
|
* The returned value <i>e''</i> <sup>2</sup> lies in (−1, 1).
|
|
**********************************************************************/
|
|
static double FlatteningToThirdEccentricitySq(double f);
|
|
};
|
|
} // namespace NETGeographicLib
|