00001 /** 00002 * \file NETGeographicLib/Geocentric.h 00003 * \brief Header for NETGeographicLib::Geocentric class 00004 * 00005 * NETGeographicLib is copyright (c) Scott Heiman (2013) 00006 * GeographicLib is Copyright (c) Charles Karney (2010-2012) 00007 * <charles@karney.com> and licensed under the MIT/X11 License. 00008 * For more information, see 00009 * http://geographiclib.sourceforge.net/ 00010 **********************************************************************/ 00011 #pragma once 00012 00013 namespace NETGeographicLib 00014 { 00015 /** 00016 * \brief .NET wrapper for GeographicLib::Geocentric. 00017 * 00018 * This class allows .NET applications to access GeographicLib::Geocentric. 00019 * 00020 * Convert between geodetic coordinates latitude = \e lat, longitude = \e 00021 * lon, height = \e h (measured vertically from the surface of the ellipsoid) 00022 * to geocentric coordinates (\e X, \e Y, \e Z). The origin of geocentric 00023 * coordinates is at the center of the earth. The \e Z axis goes thru the 00024 * north pole, \e lat = 90°. The \e X axis goes thru \e lat = 0, 00025 * \e lon = 0. %Geocentric coordinates are also known as earth centered, 00026 * earth fixed (ECEF) coordinates. 00027 * 00028 * The conversion from geographic to geocentric coordinates is 00029 * straightforward. For the reverse transformation we use 00030 * - H. Vermeille, 00031 * <a href="http://dx.doi.org/10.1007/s00190-002-0273-6"> Direct 00032 * transformation from geocentric coordinates to geodetic coordinates</a>, 00033 * J. Geodesy 76, 451--454 (2002). 00034 * . 00035 * Several changes have been made to ensure that the method returns accurate 00036 * results for all finite inputs (even if \e h is infinite). The changes are 00037 * described in Appendix B of 00038 * - C. F. F. Karney, 00039 * <a href="http://arxiv.org/abs/1102.1215v1">Geodesics 00040 * on an ellipsoid of revolution</a>, 00041 * Feb. 2011; 00042 * preprint 00043 * <a href="http://arxiv.org/abs/1102.1215v1">arxiv:1102.1215v1</a>. 00044 * . 00045 * See \ref geocentric for more information. 00046 * 00047 * The errors in these routines are close to round-off. Specifically, for 00048 * points within 5000 km of the surface of the ellipsoid (either inside or 00049 * outside the ellipsoid), the error is bounded by 7 nm (7 nanometers) for 00050 * the WGS84 ellipsoid. See \ref geocentric for further information on the 00051 * errors. 00052 * 00053 * C# Example: 00054 * \include example-Geocentric.cs 00055 * Managed C++ Example: 00056 * \include example-Geocentric.cpp 00057 * Visual Basic Example: 00058 * \include example-Geocentric.vb 00059 * 00060 * <B>INTERFACE DIFFERENCES:</B><BR> 00061 * A default constructor is provided that assumes WGS84 parameters. 00062 * 00063 * The MajorRadius and Flattening functions are implemented as properties. 00064 * 00065 * The Forward and Reverse functions return rotation matrices as 2D, 00066 * 3 × 3 arrays rather than vectors. 00067 **********************************************************************/ 00068 public ref class Geocentric 00069 { 00070 private: 00071 // pointer to the unmanaged GeographicLib::Geocentric 00072 const GeographicLib::Geocentric* m_pGeocentric; 00073 00074 // The finalizer frees unmanaged memory when the object is destroyed. 00075 !Geocentric(); 00076 public: 00077 /** 00078 * Constructor for a ellipsoid with 00079 * 00080 * @param[in] a equatorial radius (meters). 00081 * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere. 00082 * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flattening 00083 * to 1/\e f. 00084 * @exception GeographicErr if \e a or (1 − \e f ) \e a is not 00085 * positive. 00086 **********************************************************************/ 00087 Geocentric(double a, double f); 00088 00089 /** 00090 * A default constructor which assumes WGS84. 00091 **********************************************************************/ 00092 Geocentric(); 00093 00094 /** 00095 * A constructor that is initialized from an unmanaged 00096 * GeographicLib::Geocentric. For internal use only. 00097 * @param[in] g An existing GeographicLib::Geocentric. 00098 **********************************************************************/ 00099 Geocentric( const GeographicLib::Geocentric& g ); 00100 00101 /** 00102 * The destructor calls the finalizer. 00103 **********************************************************************/ 00104 ~Geocentric() 00105 { this->!Geocentric(); } 00106 00107 /** 00108 * Convert from geodetic to geocentric coordinates. 00109 * 00110 * @param[in] lat latitude of point (degrees). 00111 * @param[in] lon longitude of point (degrees). 00112 * @param[in] h height of point above the ellipsoid (meters). 00113 * @param[out] X geocentric coordinate (meters). 00114 * @param[out] Y geocentric coordinate (meters). 00115 * @param[out] Z geocentric coordinate (meters). 00116 * 00117 * \e lat should be in the range [−90°, 90°]; \e lon 00118 * should be in the range [−540°, 540°). 00119 **********************************************************************/ 00120 void Forward(double lat, double lon, double h, 00121 [System::Runtime::InteropServices::Out] double% X, 00122 [System::Runtime::InteropServices::Out] double% Y, 00123 [System::Runtime::InteropServices::Out] double% Z); 00124 00125 /** 00126 * Convert from geodetic to geocentric coordinates and return rotation 00127 * matrix. 00128 * 00129 * @param[in] lat latitude of point (degrees). 00130 * @param[in] lon longitude of point (degrees). 00131 * @param[in] h height of point above the ellipsoid (meters). 00132 * @param[out] X geocentric coordinate (meters). 00133 * @param[out] Y geocentric coordinate (meters). 00134 * @param[out] Z geocentric coordinate (meters). 00135 * @param[out] M a 3 × 3 rotation matrix. 00136 * 00137 * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can 00138 * express \e v as \e column vectors in one of two ways 00139 * - in east, north, up coordinates (where the components are relative to a 00140 * local coordinate system at (\e lat, \e lon, \e h)); call this 00141 * representation \e v1. 00142 * - in geocentric \e X, \e Y, \e Z coordinates; call this representation 00143 * \e v0. 00144 * . 00145 * Then we have \e v0 = \e M ⋅ \e v1. 00146 **********************************************************************/ 00147 void Forward(double lat, double lon, double h, 00148 [System::Runtime::InteropServices::Out] double% X, 00149 [System::Runtime::InteropServices::Out] double% Y, 00150 [System::Runtime::InteropServices::Out] double% Z, 00151 [System::Runtime::InteropServices::Out] array<double,2>^% M); 00152 00153 /** 00154 * Convert from geocentric to geodetic to coordinates. 00155 * 00156 * @param[in] X geocentric coordinate (meters). 00157 * @param[in] Y geocentric coordinate (meters). 00158 * @param[in] Z geocentric coordinate (meters). 00159 * @param[out] lat latitude of point (degrees). 00160 * @param[out] lon longitude of point (degrees). 00161 * @param[out] h height of point above the ellipsoid (meters). 00162 * 00163 * In general there are multiple solutions and the result which maximizes 00164 * \e h is returned. If there are still multiple solutions with different 00165 * latitudes (applies only if \e Z = 0), then the solution with \e lat > 0 00166 * is returned. If there are still multiple solutions with different 00167 * longitudes (applies only if \e X = \e Y = 0) then \e lon = 0 is 00168 * returned. The value of \e h returned satisfies \e h ≥ − \e a 00169 * (1 − <i>e</i><sup>2</sup>) / sqrt(1 − <i>e</i><sup>2</sup> 00170 * sin<sup>2</sup>\e lat). The value of \e lon returned is in the range 00171 * [−180°, 180°). 00172 **********************************************************************/ 00173 void Reverse(double X, double Y, double Z, 00174 [System::Runtime::InteropServices::Out] double% lat, 00175 [System::Runtime::InteropServices::Out] double% lon, 00176 [System::Runtime::InteropServices::Out] double% h); 00177 00178 /** 00179 * Convert from geocentric to geodetic to coordinates. 00180 * 00181 * @param[in] X geocentric coordinate (meters). 00182 * @param[in] Y geocentric coordinate (meters). 00183 * @param[in] Z geocentric coordinate (meters). 00184 * @param[out] lat latitude of point (degrees). 00185 * @param[out] lon longitude of point (degrees). 00186 * @param[out] h height of point above the ellipsoid (meters). 00187 * @param[out] M a 3 × 3 rotation matrix. 00188 * 00189 * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can 00190 * express \e v as \e column vectors in one of two ways 00191 * - in east, north, up coordinates (where the components are relative to a 00192 * local coordinate system at (\e lat, \e lon, \e h)); call this 00193 * representation \e v1. 00194 * - in geocentric \e X, \e Y, \e Z coordinates; call this representation 00195 * \e v0. 00196 * . 00197 * Then we have \e v1 = \e M<sup>T</sup> ⋅ \e v0, where \e 00198 * M<sup>T</sup> is the transpose of \e M. 00199 **********************************************************************/ 00200 void Reverse(double X, double Y, double Z, 00201 [System::Runtime::InteropServices::Out] double% lat, 00202 [System::Runtime::InteropServices::Out] double% lon, 00203 [System::Runtime::InteropServices::Out] double% h, 00204 [System::Runtime::InteropServices::Out] array<double,2>^% M); 00205 00206 /** \name Inspector functions 00207 **********************************************************************/ 00208 ///@{ 00209 /** 00210 * @return a pointer to the unmanaged GeographicLib::Geocentric. 00211 **********************************************************************/ 00212 System::IntPtr^ GetUnmanaged(); 00213 00214 /** 00215 * @return \e a the equatorial radius of the ellipsoid (meters). This is 00216 * the value used in the constructor. 00217 **********************************************************************/ 00218 property double MajorRadius { double get(); } 00219 00220 /** 00221 * @return \e f the flattening of the ellipsoid. This is the 00222 * value used in the constructor. 00223 **********************************************************************/ 00224 property double Flattening { double get(); } 00225 ///@} 00226 }; 00227 } // namespace NETGeographicLib