00001 /** 00002 * \file NETGeographicLib/Geodesic.h 00003 * \brief Header for NETGeographicLib::Geodesic 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 #include "NETGeographicLib.h" 00013 00014 namespace NETGeographicLib 00015 { 00016 ref class GeodesicLine; 00017 /** 00018 * \brief .NET wrapper for GeographicLib::Geodesic. 00019 * 00020 * This class allows .NET applications to access GeographicLib::Geodesic. 00021 * 00022 * The shortest path between two points on a ellipsoid at (\e lat1, \e lon1) 00023 * and (\e lat2, \e lon2) is called the geodesic. Its length is \e s12 and 00024 * the geodesic from point 1 to point 2 has azimuths \e azi1 and \e azi2 at 00025 * the two end points. (The azimuth is the heading measured clockwise from 00026 * north. \e azi2 is the "forward" azimuth, i.e., the heading that takes you 00027 * beyond point 2 not back to point 1.) 00028 * 00029 * Given \e lat1, \e lon1, \e azi1, and \e s12, we can determine \e lat2, \e 00030 * lon2, and \e azi2. This is the \e direct geodesic problem and its 00031 * solution is given by the function Geodesic::Direct. (If \e s12 is 00032 * sufficiently large that the geodesic wraps more than halfway around the 00033 * earth, there will be another geodesic between the points with a smaller \e 00034 * s12.) 00035 * 00036 * Given \e lat1, \e lon1, \e lat2, and \e lon2, we can determine \e azi1, \e 00037 * azi2, and \e s12. This is the \e inverse geodesic problem, whose solution 00038 * is given by Geodesic::Inverse. Usually, the solution to the inverse 00039 * problem is unique. In cases where there are multiple solutions (all with 00040 * the same \e s12, of course), all the solutions can be easily generated 00041 * once a particular solution is provided. 00042 * 00043 * The standard way of specifying the direct problem is the specify the 00044 * distance \e s12 to the second point. However it is sometimes useful 00045 * instead to specify the arc length \e a12 (in degrees) on the auxiliary 00046 * sphere. This is a mathematical construct used in solving the geodesic 00047 * problems. The solution of the direct problem in this form is provided by 00048 * Geodesic::ArcDirect. An arc length in excess of 180° indicates that 00049 * the geodesic is not a shortest path. In addition, the arc length between 00050 * an equatorial crossing and the next extremum of latitude for a geodesic is 00051 * 90°. 00052 * 00053 * This class can also calculate several other quantities related to 00054 * geodesics. These are: 00055 * - <i>reduced length</i>. If we fix the first point and increase \e azi1 00056 * by \e dazi1 (radians), the second point is displaced \e m12 \e dazi1 in 00057 * the direction \e azi2 + 90°. The quantity \e m12 is called 00058 * the "reduced length" and is symmetric under interchange of the two 00059 * points. On a curved surface the reduced length obeys a symmetry 00060 * relation, \e m12 + \e m21 = 0. On a flat surface, we have \e m12 = \e 00061 * s12. The ratio <i>s12</i>/\e m12 gives the azimuthal scale for an 00062 * azimuthal equidistant projection. 00063 * - <i>geodesic scale</i>. Consider a reference geodesic and a second 00064 * geodesic parallel to this one at point 1 and separated by a small 00065 * distance \e dt. The separation of the two geodesics at point 2 is \e 00066 * M12 \e dt where \e M12 is called the "geodesic scale". \e M21 is 00067 * defined similarly (with the geodesics being parallel at point 2). On a 00068 * flat surface, we have \e M12 = \e M21 = 1. The quantity 1/\e M12 gives 00069 * the scale of the Cassini-Soldner projection. 00070 00071 * - <i>area</i>. The area between the geodesic from point 1 to point 2 and 00072 * the equation is represented by \e S12; it is the area, measured 00073 * counter-clockwise, of the geodesic quadrilateral with corners 00074 * (<i>lat1</i>,<i>lon1</i>), (0,<i>lon1</i>), (0,<i>lon2</i>), and 00075 * (<i>lat2</i>,<i>lon2</i>). It can be used to compute the area of any 00076 * simple geodesic polygon. 00077 * 00078 * Overloaded versions of Geodesic::Direct, Geodesic::ArcDirect, and 00079 * Geodesic::Inverse allow these quantities to be returned. In addition 00080 * there are general functions Geodesic::GenDirect, and Geodesic::GenInverse 00081 * which allow an arbitrary set of results to be computed. The quantities \e 00082 * m12, \e M12, \e M21 which all specify the behavior of nearby geodesics 00083 * obey addition rules. If points 1, 2, and 3 all lie on a single geodesic, 00084 * then the following rules hold: 00085 * - \e s13 = \e s12 + \e s23 00086 * - \e a13 = \e a12 + \e a23 00087 * - \e S13 = \e S12 + \e S23 00088 * - \e m13 = \e m12 \e M23 + \e m23 \e M21 00089 * - \e M13 = \e M12 \e M23 − (1 − \e M12 \e M21) \e m23 / \e m12 00090 * - \e M31 = \e M32 \e M21 − (1 − \e M23 \e M32) \e m12 / \e m23 00091 * 00092 * Additional functionality is provided by the GeodesicLine class, which 00093 * allows a sequence of points along a geodesic to be computed. 00094 * 00095 * The shortest distance returned by the solution of the inverse problem is 00096 * (obviously) uniquely defined. However, in a few special cases there are 00097 * multiple azimuths which yield the same shortest distance. Here is a 00098 * catalog of those cases: 00099 * - \e lat1 = −\e lat2 (with neither at a pole). If \e azi1 = \e 00100 * azi2, the geodesic is unique. Otherwise there are two geodesics and the 00101 * second one is obtained by setting [\e azi1, \e azi2] = [\e azi2, \e 00102 * azi1], [\e M12, \e M21] = [\e M21, \e M12], \e S12 = −\e S12. 00103 * (This occurs when the longitude difference is near ±180° for 00104 * oblate ellipsoids.) 00105 * - \e lon2 = \e lon1 ± 180° (with neither at a pole). If \e 00106 * azi1 = 0° or ±180°, the geodesic is unique. Otherwise 00107 * there are two geodesics and the second one is obtained by setting [\e 00108 * azi1, \e azi2] = [−\e azi1, −\e azi2], \e S12 = −\e 00109 * S12. (This occurs when the \e lat2 is near −\e lat1 for prolate 00110 * ellipsoids.) 00111 * - Points 1 and 2 at opposite poles. There are infinitely many geodesics 00112 * which can be generated by setting [\e azi1, \e azi2] = [\e azi1, \e 00113 * azi2] + [\e d, −\e d], for arbitrary \e d. (For spheres, this 00114 * prescription applies when points 1 and 2 are antipodal.) 00115 * - s12 = 0 (coincident points). There are infinitely many geodesics which 00116 * can be generated by setting [\e azi1, \e azi2] = [\e azi1, \e azi2] + 00117 * [\e d, \e d], for arbitrary \e d. 00118 * 00119 * The calculations are accurate to better than 15 nm (15 nanometers) for the 00120 * WGS84 ellipsoid. See Sec. 9 of 00121 * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for 00122 * details. The algorithms used by this class are based on series expansions 00123 * using the flattening \e f as a small parameter. These are only accurate 00124 * for |<i>f</i>| < 0.02; however reasonably accurate results will be 00125 * obtained for |<i>f</i>| < 0.2. Here is a table of the approximate 00126 * maximum error (expressed as a distance) for an ellipsoid with the same 00127 * major radius as the WGS84 ellipsoid and different values of the 00128 * flattening.<pre> 00129 * |f| error 00130 * 0.01 25 nm 00131 * 0.02 30 nm 00132 * 0.05 10 um 00133 * 0.1 1.5 mm 00134 * 0.2 300 mm 00135 * </pre> 00136 * For very eccentric ellipsoids, use GeodesicExact instead. 00137 * 00138 * The algorithms are described in 00139 * - C. F. F. Karney, 00140 * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> 00141 * Algorithms for geodesics</a>, 00142 * J. Geodesy <b>87</b>, 43--55 (2013); 00143 * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> 00144 * 10.1007/s00190-012-0578-z</a>; 00145 * addenda: <a href="http://geographiclib.sf.net/geod-addenda.html"> 00146 * geod-addenda.html</a>. 00147 * . 00148 * For more information on geodesics see \ref geodesic. 00149 * 00150 * C# Example: 00151 * \include example-Geodesic.cs 00152 * Managed C++ Example: 00153 * \include example-Geodesic.cpp 00154 * Visual Basic Example: 00155 * \include example-Geodesic.vb 00156 * 00157 * <B>INTERFACE DIFFERENCES:</B><BR> 00158 * A default constructor has been provided that assumes WGS84 parameters. 00159 * 00160 * The MajorRadius, Flattening, and EllipsoidArea functions are 00161 * implemented as properties. 00162 * 00163 * The GenDirect, GenInverse, and Line functions accept the 00164 * "capabilities mask" as a NETGeographicLib::Mask rather than an 00165 * unsigned. 00166 **********************************************************************/ 00167 public ref class Geodesic 00168 { 00169 private: 00170 // The pointer to the unmanaged GeographicLib::Geodesic. 00171 const GeographicLib::Geodesic* m_pGeodesic; 00172 00173 // Frees the unmanaged memory when this object is destroyed. 00174 !Geodesic(); 00175 public: 00176 /** \name Constructor 00177 **********************************************************************/ 00178 ///@{ 00179 /** 00180 * Constructor for a ellipsoid with 00181 * 00182 * @param[in] a equatorial radius (meters). 00183 * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere. 00184 * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flattening 00185 * to 1/\e f. 00186 * @exception GeographicErr if \e a or (1 − \e f ) \e a is not 00187 * positive. 00188 **********************************************************************/ 00189 Geodesic(double a, double f); 00190 00191 /** 00192 * Constructor for the WGS84 ellipsoid. 00193 **********************************************************************/ 00194 Geodesic(); 00195 ///@} 00196 00197 /** 00198 * \brief the destructor calls the finalizer. 00199 **********************************************************************/ 00200 ~Geodesic() { this->!Geodesic(); } 00201 00202 /** \name Direct geodesic problem specified in terms of distance. 00203 **********************************************************************/ 00204 ///@{ 00205 /** 00206 * Solve the direct geodesic problem where the length of the geodesic 00207 * is specified in terms of distance. 00208 * 00209 * @param[in] lat1 latitude of point 1 (degrees). 00210 * @param[in] lon1 longitude of point 1 (degrees). 00211 * @param[in] azi1 azimuth at point 1 (degrees). 00212 * @param[in] s12 distance between point 1 and point 2 (meters); it can be 00213 * negative. 00214 * @param[out] lat2 latitude of point 2 (degrees). 00215 * @param[out] lon2 longitude of point 2 (degrees). 00216 * @param[out] azi2 (forward) azimuth at point 2 (degrees). 00217 * @param[out] m12 reduced length of geodesic (meters). 00218 * @param[out] M12 geodesic scale of point 2 relative to point 1 00219 * (dimensionless). 00220 * @param[out] M21 geodesic scale of point 1 relative to point 2 00221 * (dimensionless). 00222 * @param[out] S12 area under the geodesic (meters<sup>2</sup>). 00223 * @return \e a12 arc length of between point 1 and point 2 (degrees). 00224 * 00225 * \e lat1 should be in the range [−90°, 90°]; \e lon1 and \e 00226 * azi1 should be in the range [−540°, 540°). The values of 00227 * \e lon2 and \e azi2 returned are in the range [−180°, 00228 * 180°). 00229 * 00230 * If either point is at a pole, the azimuth is defined by keeping the 00231 * longitude fixed, writing \e lat = ±(90° − ε), 00232 * and taking the limit ε → 0+. An arc length greater that 00233 * 180° signifies a geodesic which is not a shortest path. (For a 00234 * prolate ellipsoid, an additional condition is necessary for a shortest 00235 * path: the longitudinal extent must not exceed of 180°.) 00236 * 00237 * The following functions are overloaded versions of Geodesic::Direct 00238 * which omit some of the output parameters. Note, however, that the arc 00239 * length is always computed and returned as the function value. 00240 **********************************************************************/ 00241 double Direct(double lat1, double lon1, double azi1, double s12, 00242 [System::Runtime::InteropServices::Out] double% lat2, 00243 [System::Runtime::InteropServices::Out] double% lon2, 00244 [System::Runtime::InteropServices::Out] double% azi2, 00245 [System::Runtime::InteropServices::Out] double% m12, 00246 [System::Runtime::InteropServices::Out] double% M12, 00247 [System::Runtime::InteropServices::Out] double% M21, 00248 [System::Runtime::InteropServices::Out] double% S12); 00249 00250 /** 00251 * See the documentation for Geodesic::Direct. 00252 **********************************************************************/ 00253 double Direct(double lat1, double lon1, double azi1, double s12, 00254 [System::Runtime::InteropServices::Out] double% lat2, 00255 [System::Runtime::InteropServices::Out] double% lon2); 00256 00257 /** 00258 * See the documentation for Geodesic::Direct. 00259 **********************************************************************/ 00260 double Direct(double lat1, double lon1, double azi1, double s12, 00261 [System::Runtime::InteropServices::Out] double% lat2, 00262 [System::Runtime::InteropServices::Out] double% lon2, 00263 [System::Runtime::InteropServices::Out] double% azi2); 00264 00265 /** 00266 * See the documentation for Geodesic::Direct. 00267 **********************************************************************/ 00268 double Direct(double lat1, double lon1, double azi1, double s12, 00269 [System::Runtime::InteropServices::Out] double% lat2, 00270 [System::Runtime::InteropServices::Out] double% lon2, 00271 [System::Runtime::InteropServices::Out] double% azi2, 00272 [System::Runtime::InteropServices::Out] double% m12); 00273 00274 /** 00275 * See the documentation for Geodesic::Direct. 00276 **********************************************************************/ 00277 double Direct(double lat1, double lon1, double azi1, double s12, 00278 [System::Runtime::InteropServices::Out] double% lat2, 00279 [System::Runtime::InteropServices::Out] double% lon2, 00280 [System::Runtime::InteropServices::Out] double% azi2, 00281 [System::Runtime::InteropServices::Out] double% M12, 00282 [System::Runtime::InteropServices::Out] double% M21); 00283 00284 /** 00285 * See the documentation for Geodesic::Direct. 00286 **********************************************************************/ 00287 double Direct(double lat1, double lon1, double azi1, double s12, 00288 [System::Runtime::InteropServices::Out] double% lat2, 00289 [System::Runtime::InteropServices::Out] double% lon2, 00290 [System::Runtime::InteropServices::Out] double% azi2, 00291 [System::Runtime::InteropServices::Out] double% m12, 00292 [System::Runtime::InteropServices::Out] double% M12, 00293 [System::Runtime::InteropServices::Out] double% M21); 00294 ///@} 00295 00296 /** \name Direct geodesic problem specified in terms of arc length. 00297 **********************************************************************/ 00298 ///@{ 00299 /** 00300 * Solve the direct geodesic problem where the length of the geodesic 00301 * is specified in terms of arc length. 00302 * 00303 * @param[in] lat1 latitude of point 1 (degrees). 00304 * @param[in] lon1 longitude of point 1 (degrees). 00305 * @param[in] azi1 azimuth at point 1 (degrees). 00306 * @param[in] a12 arc length between point 1 and point 2 (degrees); it can 00307 * be negative. 00308 * @param[out] lat2 latitude of point 2 (degrees). 00309 * @param[out] lon2 longitude of point 2 (degrees). 00310 * @param[out] azi2 (forward) azimuth at point 2 (degrees). 00311 * @param[out] s12 distance between point 1 and point 2 (meters). 00312 * @param[out] m12 reduced length of geodesic (meters). 00313 * @param[out] M12 geodesic scale of point 2 relative to point 1 00314 * (dimensionless). 00315 * @param[out] M21 geodesic scale of point 1 relative to point 2 00316 * (dimensionless). 00317 * @param[out] S12 area under the geodesic (meters<sup>2</sup>). 00318 * 00319 * \e lat1 should be in the range [−90°, 90°]; \e lon1 and \e 00320 * azi1 should be in the range [−540°, 540°). The values of 00321 * \e lon2 and \e azi2 returned are in the range [−180°, 00322 * 180°). 00323 * 00324 * If either point is at a pole, the azimuth is defined by keeping the 00325 * longitude fixed, writing \e lat = ±(90° − ε), 00326 * and taking the limit ε → 0+. An arc length greater that 00327 * 180° signifies a geodesic which is not a shortest path. (For a 00328 * prolate ellipsoid, an additional condition is necessary for a shortest 00329 * path: the longitudinal extent must not exceed of 180°.) 00330 * 00331 * The following functions are overloaded versions of Geodesic::Direct 00332 * which omit some of the output parameters. 00333 **********************************************************************/ 00334 void ArcDirect(double lat1, double lon1, double azi1, double a12, 00335 [System::Runtime::InteropServices::Out] double% lat2, 00336 [System::Runtime::InteropServices::Out] double% lon2, 00337 [System::Runtime::InteropServices::Out] double% azi2, 00338 [System::Runtime::InteropServices::Out] double% s12, 00339 [System::Runtime::InteropServices::Out] double% m12, 00340 [System::Runtime::InteropServices::Out] double% M12, 00341 [System::Runtime::InteropServices::Out] double% M21, 00342 [System::Runtime::InteropServices::Out] double% S12); 00343 00344 /** 00345 * See the documentation for Geodesic::ArcDirect. 00346 **********************************************************************/ 00347 void ArcDirect(double lat1, double lon1, double azi1, double a12, 00348 [System::Runtime::InteropServices::Out] double% lat2, 00349 [System::Runtime::InteropServices::Out] double% lon2); 00350 00351 /** 00352 * See the documentation for Geodesic::ArcDirect. 00353 **********************************************************************/ 00354 void ArcDirect(double lat1, double lon1, double azi1, double a12, 00355 [System::Runtime::InteropServices::Out] double% lat2, 00356 [System::Runtime::InteropServices::Out] double% lon2, 00357 [System::Runtime::InteropServices::Out] double% azi2); 00358 00359 /** 00360 * See the documentation for Geodesic::ArcDirect. 00361 **********************************************************************/ 00362 void ArcDirect(double lat1, double lon1, double azi1, double a12, 00363 [System::Runtime::InteropServices::Out] double% lat2, 00364 [System::Runtime::InteropServices::Out] double% lon2, 00365 [System::Runtime::InteropServices::Out] double% azi2, 00366 [System::Runtime::InteropServices::Out] double% s12); 00367 00368 /** 00369 * See the documentation for Geodesic::ArcDirect. 00370 **********************************************************************/ 00371 void ArcDirect(double lat1, double lon1, double azi1, double a12, 00372 [System::Runtime::InteropServices::Out] double% lat2, 00373 [System::Runtime::InteropServices::Out] double% lon2, 00374 [System::Runtime::InteropServices::Out] double% azi2, 00375 [System::Runtime::InteropServices::Out] double% s12, 00376 [System::Runtime::InteropServices::Out] double% m12); 00377 00378 /** 00379 * See the documentation for Geodesic::ArcDirect. 00380 **********************************************************************/ 00381 void ArcDirect(double lat1, double lon1, double azi1, double a12, 00382 [System::Runtime::InteropServices::Out] double% lat2, 00383 [System::Runtime::InteropServices::Out] double% lon2, 00384 [System::Runtime::InteropServices::Out] double% azi2, 00385 [System::Runtime::InteropServices::Out] double% s12, 00386 [System::Runtime::InteropServices::Out] double% M12, 00387 [System::Runtime::InteropServices::Out] double% M21); 00388 00389 /** 00390 * See the documentation for Geodesic::ArcDirect. 00391 **********************************************************************/ 00392 void ArcDirect(double lat1, double lon1, double azi1, double a12, 00393 [System::Runtime::InteropServices::Out] double% lat2, 00394 [System::Runtime::InteropServices::Out] double% lon2, 00395 [System::Runtime::InteropServices::Out] double% azi2, 00396 [System::Runtime::InteropServices::Out] double% s12, 00397 [System::Runtime::InteropServices::Out] double% m12, 00398 [System::Runtime::InteropServices::Out] double% M12, 00399 [System::Runtime::InteropServices::Out] double% M21); 00400 ///@} 00401 00402 /** \name General version of the direct geodesic solution. 00403 **********************************************************************/ 00404 ///@{ 00405 00406 /** 00407 * The general direct geodesic problem. Geodesic::Direct and 00408 * Geodesic::ArcDirect are defined in terms of this function. 00409 * 00410 * @param[in] lat1 latitude of point 1 (degrees). 00411 * @param[in] lon1 longitude of point 1 (degrees). 00412 * @param[in] azi1 azimuth at point 1 (degrees). 00413 * @param[in] arcmode boolean flag determining the meaning of the \e 00414 * s12_a12. 00415 * @param[in] s12_a12 if \e arcmode is false, this is the distance between 00416 * point 1 and point 2 (meters); otherwise it is the arc length between 00417 * point 1 and point 2 (degrees); it can be negative. 00418 * @param[in] outmask a bitor'ed combination of NETGeographicLib::Mask values 00419 * specifying which of the following parameters should be set. 00420 * @param[out] lat2 latitude of point 2 (degrees). 00421 * @param[out] lon2 longitude of point 2 (degrees). 00422 * @param[out] azi2 (forward) azimuth at point 2 (degrees). 00423 * @param[out] s12 distance between point 1 and point 2 (meters). 00424 * @param[out] m12 reduced length of geodesic (meters). 00425 * @param[out] M12 geodesic scale of point 2 relative to point 1 00426 * (dimensionless). 00427 * @param[out] M21 geodesic scale of point 1 relative to point 2 00428 * (dimensionless). 00429 * @param[out] S12 area under the geodesic (meters<sup>2</sup>). 00430 * @return \e a12 arc length of between point 1 and point 2 (degrees). 00431 * 00432 * The NETGeographicLib::Mask values possible for \e outmask are 00433 * - \e outmask |= NETGeographicLib::Mask::LATITUDE for the latitude \e lat2; 00434 * - \e outmask |= NETGeographicLib::Mask::LONGITUDE for the latitude \e lon2; 00435 * - \e outmask |= NETGeographicLib::Mask::AZIMUTH for the latitude \e azi2; 00436 * - \e outmask |= NETGeographicLib::Mask::DISTANCE for the distance \e s12; 00437 * - \e outmask |= NETGeographicLib::Mask::REDUCEDLENGTH for the reduced length \e 00438 * m12; 00439 * - \e outmask |= NETGeographicLib::Mask::GEODESICSCALE for the geodesic scales \e 00440 * M12 and \e M21; 00441 * - \e outmask |= NETGeographicLib::Mask::AREA for the area \e S12; 00442 * - \e outmask |= NETGeographicLib::Mask::ALL for all of the above. 00443 * . 00444 * The function value \e a12 is always computed and returned and this 00445 * equals \e s12_a12 is \e arcmode is true. If \e outmask includes 00446 * NETGeographicLib::Mask::DISTANCE and \e arcmode is false, then 00447 * \e s12 = \e s12_a12. It is not necessary to include 00448 * NETGeographicLib::Mask::DISTANCE_IN in \e outmask; this is 00449 * automatically included is \e arcmode is false. 00450 **********************************************************************/ 00451 double GenDirect(double lat1, double lon1, double azi1, 00452 bool arcmode, double s12_a12, 00453 NETGeographicLib::Mask outmask, 00454 [System::Runtime::InteropServices::Out] double% lat2, 00455 [System::Runtime::InteropServices::Out] double% lon2, 00456 [System::Runtime::InteropServices::Out] double% azi2, 00457 [System::Runtime::InteropServices::Out] double% s12, 00458 [System::Runtime::InteropServices::Out] double% m12, 00459 [System::Runtime::InteropServices::Out] double% M12, 00460 [System::Runtime::InteropServices::Out] double% M21, 00461 [System::Runtime::InteropServices::Out] double% S12); 00462 ///@} 00463 00464 /** \name Inverse geodesic problem. 00465 **********************************************************************/ 00466 ///@{ 00467 /** 00468 * Solve the inverse geodesic problem. 00469 * 00470 * @param[in] lat1 latitude of point 1 (degrees). 00471 * @param[in] lon1 longitude of point 1 (degrees). 00472 * @param[in] lat2 latitude of point 2 (degrees). 00473 * @param[in] lon2 longitude of point 2 (degrees). 00474 * @param[out] s12 distance between point 1 and point 2 (meters). 00475 * @param[out] azi1 azimuth at point 1 (degrees). 00476 * @param[out] azi2 (forward) azimuth at point 2 (degrees). 00477 * @param[out] m12 reduced length of geodesic (meters). 00478 * @param[out] M12 geodesic scale of point 2 relative to point 1 00479 * (dimensionless). 00480 * @param[out] M21 geodesic scale of point 1 relative to point 2 00481 * (dimensionless). 00482 * @param[out] S12 area under the geodesic (meters<sup>2</sup>). 00483 * @return \e a12 arc length of between point 1 and point 2 (degrees). 00484 * 00485 * \e lat1 and \e lat2 should be in the range [−90°, 90°]; \e 00486 * lon1 and \e lon2 should be in the range [−540°, 540°). 00487 * The values of \e azi1 and \e azi2 returned are in the range 00488 * [−180°, 180°). 00489 * 00490 * If either point is at a pole, the azimuth is defined by keeping the 00491 * longitude fixed, writing \e lat = ±(90° − ε), 00492 * and taking the limit ε → 0+. 00493 * 00494 * The solution to the inverse problem is found using Newton's method. If 00495 * this fails to converge (this is very unlikely in geodetic applications 00496 * but does occur for very eccentric ellipsoids), then the bisection method 00497 * is used to refine the solution. 00498 * 00499 * The following functions are overloaded versions of Geodesic::Inverse 00500 * which omit some of the output parameters. Note, however, that the arc 00501 * length is always computed and returned as the function value. 00502 **********************************************************************/ 00503 double Inverse(double lat1, double lon1, double lat2, double lon2, 00504 [System::Runtime::InteropServices::Out] double% s12, 00505 [System::Runtime::InteropServices::Out] double% azi1, 00506 [System::Runtime::InteropServices::Out] double% azi2, 00507 [System::Runtime::InteropServices::Out] double% m12, 00508 [System::Runtime::InteropServices::Out] double% M12, 00509 [System::Runtime::InteropServices::Out] double% M21, 00510 [System::Runtime::InteropServices::Out] double% S12); 00511 00512 /** 00513 * See the documentation for Geodesic::Inverse. 00514 **********************************************************************/ 00515 double Inverse(double lat1, double lon1, double lat2, double lon2, 00516 [System::Runtime::InteropServices::Out] double% s12); 00517 00518 /** 00519 * See the documentation for Geodesic::Inverse. 00520 **********************************************************************/ 00521 double Inverse(double lat1, double lon1, double lat2, double lon2, 00522 [System::Runtime::InteropServices::Out] double% azi1, 00523 [System::Runtime::InteropServices::Out] double% azi2); 00524 00525 /** 00526 * See the documentation for Geodesic::Inverse. 00527 **********************************************************************/ 00528 double Inverse(double lat1, double lon1, double lat2, double lon2, 00529 [System::Runtime::InteropServices::Out] double% s12, 00530 [System::Runtime::InteropServices::Out] double% azi1, 00531 [System::Runtime::InteropServices::Out] double% azi2); 00532 00533 /** 00534 * See the documentation for Geodesic::Inverse. 00535 **********************************************************************/ 00536 double Inverse(double lat1, double lon1, double lat2, double lon2, 00537 [System::Runtime::InteropServices::Out] double% s12, 00538 [System::Runtime::InteropServices::Out] double% azi1, 00539 [System::Runtime::InteropServices::Out] double% azi2, 00540 [System::Runtime::InteropServices::Out] double% m12); 00541 00542 /** 00543 * See the documentation for Geodesic::Inverse. 00544 **********************************************************************/ 00545 double Inverse(double lat1, double lon1, double lat2, double lon2, 00546 [System::Runtime::InteropServices::Out] double% s12, 00547 [System::Runtime::InteropServices::Out] double% azi1, 00548 [System::Runtime::InteropServices::Out] double% azi2, 00549 [System::Runtime::InteropServices::Out] double% M12, 00550 [System::Runtime::InteropServices::Out] double% M21); 00551 00552 /** 00553 * See the documentation for Geodesic::Inverse. 00554 **********************************************************************/ 00555 double Inverse(double lat1, double lon1, double lat2, double lon2, 00556 [System::Runtime::InteropServices::Out] double% s12, 00557 [System::Runtime::InteropServices::Out] double% azi1, 00558 [System::Runtime::InteropServices::Out] double% azi2, 00559 [System::Runtime::InteropServices::Out] double% m12, 00560 [System::Runtime::InteropServices::Out] double% M12, 00561 [System::Runtime::InteropServices::Out] double% M21); 00562 ///@} 00563 00564 /** \name General version of inverse geodesic solution. 00565 **********************************************************************/ 00566 ///@{ 00567 /** 00568 * The general inverse geodesic calculation. Geodesic::Inverse is defined 00569 * in terms of this function. 00570 * 00571 * @param[in] lat1 latitude of point 1 (degrees). 00572 * @param[in] lon1 longitude of point 1 (degrees). 00573 * @param[in] lat2 latitude of point 2 (degrees). 00574 * @param[in] lon2 longitude of point 2 (degrees). 00575 * @param[in] outmask a bitor'ed combination of Geodesic::mask values 00576 * specifying which of the following parameters should be set. 00577 * @param[out] s12 distance between point 1 and point 2 (meters). 00578 * @param[out] azi1 azimuth at point 1 (degrees). 00579 * @param[out] azi2 (forward) azimuth at point 2 (degrees). 00580 * @param[out] m12 reduced length of geodesic (meters). 00581 * @param[out] M12 geodesic scale of point 2 relative to point 1 00582 * (dimensionless). 00583 * @param[out] M21 geodesic scale of point 1 relative to point 2 00584 * (dimensionless). 00585 * @param[out] S12 area under the geodesic (meters<sup>2</sup>). 00586 * @return \e a12 arc length of between point 1 and point 2 (degrees). 00587 * 00588 * The Geodesic::mask values possible for \e outmask are 00589 * - \e outmask |= Geodesic::DISTANCE for the distance \e s12; 00590 * - \e outmask |= Geodesic::AZIMUTH for the latitude \e azi2; 00591 * - \e outmask |= Geodesic::REDUCEDLENGTH for the reduced length \e 00592 * m12; 00593 * - \e outmask |= Geodesic::GEODESICSCALE for the geodesic scales \e 00594 * M12 and \e M21; 00595 * - \e outmask |= Geodesic::AREA for the area \e S12; 00596 * - \e outmask |= Geodesic::ALL for all of the above. 00597 * . 00598 * The arc length is always computed and returned as the function value. 00599 **********************************************************************/ 00600 double GenInverse(double lat1, double lon1, double lat2, double lon2, 00601 NETGeographicLib::Mask outmask, 00602 [System::Runtime::InteropServices::Out] double% s12, 00603 [System::Runtime::InteropServices::Out] double% azi1, 00604 [System::Runtime::InteropServices::Out] double% azi2, 00605 [System::Runtime::InteropServices::Out] double% m12, 00606 [System::Runtime::InteropServices::Out] double% M12, 00607 [System::Runtime::InteropServices::Out] double% M21, 00608 [System::Runtime::InteropServices::Out] double% S12); 00609 ///@} 00610 00611 /** \name Interface to GeodesicLine. 00612 **********************************************************************/ 00613 ///@{ 00614 00615 /** 00616 * Set up to compute several points on a single geodesic. 00617 * 00618 * @param[in] lat1 latitude of point 1 (degrees). 00619 * @param[in] lon1 longitude of point 1 (degrees). 00620 * @param[in] azi1 azimuth at point 1 (degrees). 00621 * @param[in] caps bitor'ed combination of NETGeographicLib::Mask values 00622 * specifying the capabilities the GeodesicLine object should possess, 00623 * i.e., which quantities can be returned in calls to 00624 * GeodesicLine::Position. 00625 * @return a GeodesicLine object. 00626 * 00627 * \e lat1 should be in the range [−90°, 90°]; \e lon1 and \e 00628 * azi1 should be in the range [−540°, 540°). 00629 * 00630 * The NETGeographicLib::Mask values are 00631 * - \e caps |= NETGeographicLib::Mask::LATITUDE for the latitude \e lat2; this is 00632 * added automatically; 00633 * - \e caps |= NETGeographicLib::Mask::LONGITUDE for the latitude \e lon2; 00634 * - \e caps |= NETGeographicLib::Mask::AZIMUTH for the azimuth \e azi2; this is 00635 * added automatically; 00636 * - \e caps |= NETGeographicLib::Mask::DISTANCE for the distance \e s12; 00637 * - \e caps |= NETGeographicLib::Mask::REDUCEDLENGTH for the reduced length \e m12; 00638 * - \e caps |= NETGeographicLib::Mask::GEODESICSCALE for the geodesic scales \e M12 00639 * and \e M21; 00640 * - \e caps |= NETGeographicLib::Mask::AREA for the area \e S12; 00641 * - \e caps |= NETGeographicLib::Mask::DISTANCE_IN permits the length of the 00642 * geodesic to be given in terms of \e s12; without this capability the 00643 * length can only be specified in terms of arc length; 00644 * - \e caps |= NETGeographicLib::Mask::ALL for all of the above. 00645 * . 00646 * 00647 * If the point is at a pole, the azimuth is defined by keeping \e lon1 00648 * fixed, writing \e lat1 = ±(90 − ε), and taking the 00649 * limit ε → 0+. 00650 **********************************************************************/ 00651 GeodesicLine^ Line(double lat1, double lon1, double azi1, 00652 NETGeographicLib::Mask caps ); 00653 00654 ///@} 00655 00656 /** \name Inspector functions. 00657 **********************************************************************/ 00658 ///@{ 00659 00660 /** 00661 * @return \e a the equatorial radius of the ellipsoid (meters). This is 00662 * the value used in the constructor. 00663 **********************************************************************/ 00664 property double MajorRadius { double get(); } 00665 00666 /** 00667 * @return \e f the flattening of the ellipsoid. This is the 00668 * value used in the constructor. 00669 **********************************************************************/ 00670 property double Flattening { double get(); } 00671 00672 /** 00673 * @return total area of ellipsoid in meters<sup>2</sup>. The area of a 00674 * polygon encircling a pole can be found by adding 00675 * Geodesic::EllipsoidArea()/2 to the sum of \e S12 for each side of the 00676 * polygon. 00677 **********************************************************************/ 00678 property double EllipsoidArea { double get(); } 00679 00680 /** 00681 * %return The unmanaged pointer to the GeographicLib::Geodesic. 00682 * 00683 * This function is for internal use only. 00684 **********************************************************************/ 00685 System::IntPtr^ GetUnmanaged(); 00686 ///@} 00687 }; 00688 } // namespace NETGeographicLib