00001 #pragma once 00002 /** 00003 * \file NETGeographicLib/GeodesicLine.h 00004 * \brief Header for NETGeographicLib::GeodesicLine class 00005 * 00006 * NETGeographicLib is copyright (c) Scott Heiman (2013) 00007 * GeographicLib is Copyright (c) Charles Karney (2010-2012) 00008 * <charles@karney.com> and licensed under the MIT/X11 License. 00009 * For more information, see 00010 * http://geographiclib.sourceforge.net/ 00011 **********************************************************************/ 00012 #include "NETGeographicLib.h" 00013 00014 namespace NETGeographicLib 00015 { 00016 /** 00017 * \brief .NET wrapper for GeographicLib::GeodesicLine. 00018 * 00019 * This class allows .NET applications to access GeographicLib::GeodesicLine. 00020 * 00021 * GeodesicLine facilitates the determination of a series of points on a 00022 * single geodesic. The starting point (\e lat1, \e lon1) and the azimuth \e 00023 * azi1 are specified in the constructor. GeodesicLine.Position returns the 00024 * location of point 2 a distance \e s12 along the geodesic. Alternatively 00025 * GeodesicLine.ArcPosition gives the position of point 2 an arc length \e 00026 * a12 along the geodesic. 00027 * 00028 * The default copy constructor and assignment operators work with this 00029 * class. Similarly, a vector can be used to hold GeodesicLine objects. 00030 * 00031 * The calculations are accurate to better than 15 nm (15 nanometers). See 00032 * Sec. 9 of 00033 * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for 00034 * details. The algorithms used by this class are based on series expansions 00035 * using the flattening \e f as a small parameter. These are only accurate 00036 * for |<i>f</i>| < 0.02; however reasonably accurate results will be 00037 * obtained for |<i>f</i>| < 0.2. For very eccentric ellipsoids, use 00038 * GeodesicLineExact instead. 00039 * 00040 * The algorithms are described in 00041 * - C. F. F. Karney, 00042 * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> 00043 * Algorithms for geodesics</a>, 00044 * J. Geodesy <b>87</b>, 43--55 (2013); 00045 * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> 00046 * 10.1007/s00190-012-0578-z</a>; 00047 * addenda: <a href="http://geographiclib.sf.net/geod-addenda.html"> 00048 * geod-addenda.html</a>. 00049 * . 00050 * For more information on geodesics see \ref geodesic. 00051 * 00052 * C# Example: 00053 * \include example-GeodesicLine.cs 00054 * Managed C++ Example: 00055 * \include example-GeodesicLine.cpp 00056 * Visual Basic Example: 00057 * \include example-GeodesicLine.vb 00058 * 00059 * <B>INTERFACE DIFFERENCES:</B><BR> 00060 * A constructor has been provided which assumes WGS84 parameters. 00061 * 00062 * The following functions are implemented as properties: 00063 * Latitude, Longitude, Azimuth, EquatorialAzimuth, EquatorialArc, 00064 * MajorRadius, and Flattening. 00065 * 00066 * The constructors, Capabilities, and GenPosition functions accept the 00067 * "capabilities mask" as a NETGeographicLib::Mask rather than an 00068 * unsigned. The Capabilities function returns a NETGeographicLib::Mask 00069 * rather than an unsigned. 00070 **********************************************************************/ 00071 public ref class GeodesicLine 00072 { 00073 private: 00074 // pointer to the unmanaged GeographicLib::GeodesicLine. 00075 const GeographicLib::GeodesicLine* m_pGeodesicLine; 00076 00077 // The finalizer frees the unmanaged memory when this object is destroyed. 00078 !GeodesicLine(void); 00079 public: 00080 /** \name Constructors 00081 **********************************************************************/ 00082 ///@{ 00083 00084 /** 00085 * Constructor for a geodesic line staring at latitude \e lat1, longitude 00086 * \e lon1, and azimuth \e azi1 (all in degrees). 00087 * 00088 * @param[in] g A Geodesic object used to compute the necessary information 00089 * about the GeodesicLine. 00090 * @param[in] lat1 latitude of point 1 (degrees). 00091 * @param[in] lon1 longitude of point 1 (degrees). 00092 * @param[in] azi1 azimuth at point 1 (degrees). 00093 * @param[in] caps bitor'ed combination of NETGeographicLib::Mask values 00094 * specifying the capabilities the GeodesicLine object should possess, 00095 * i.e., which quantities can be returned in calls to 00096 * GeodesicLine::Position. 00097 * 00098 * \e lat1 should be in the range [−90°, 90°]; \e lon1 and \e 00099 * azi1 should be in the range [−540°, 540°). 00100 * 00101 * The NETGeographicLib::Mask values are 00102 * - \e caps |= GeodesicLine::LATITUDE for the latitude \e lat2; this is 00103 * added automatically; 00104 * - \e caps |= GeodesicLine::LONGITUDE for the latitude \e lon2; 00105 * - \e caps |= GeodesicLine::AZIMUTH for the latitude \e azi2; this is 00106 * added automatically; 00107 * - \e caps |= GeodesicLine::DISTANCE for the distance \e s12; 00108 * - \e caps |= GeodesicLine::REDUCEDLENGTH for the reduced length \e m12; 00109 * - \e caps |= GeodesicLine::GEODESICSCALE for the geodesic scales \e M12 00110 * and \e M21; 00111 * - \e caps |= GeodesicLine::AREA for the area \e S12; 00112 * - \e caps |= GeodesicLine::DISTANCE_IN permits the length of the 00113 * geodesic to be given in terms of \e s12; without this capability the 00114 * length can only be specified in terms of arc length; 00115 * - \e caps |= GeodesicLine::ALL for all of the above. 00116 * . 00117 * The default value of \e caps is GeodesicLine::ALL. 00118 * 00119 * If the point is at a pole, the azimuth is defined by keeping \e lon1 00120 * fixed, writing \e lat1 = ±(90° − ε), and taking 00121 * the limit ε → 0+. 00122 **********************************************************************/ 00123 GeodesicLine( Geodesic^ g, double lat1, double lon1, double azi1, 00124 NETGeographicLib::Mask caps ); 00125 00126 /** 00127 * A constructor which assumes the WGS84 ellipsoid. 00128 **********************************************************************/ 00129 GeodesicLine(double lat1, double lon1, double azi1, 00130 NETGeographicLib::Mask caps); 00131 ///@} 00132 00133 /** 00134 * The destructor calls the finalizer. 00135 **********************************************************************/ 00136 ~GeodesicLine() 00137 { this->!GeodesicLine(); } 00138 00139 /** \name Position in terms of distance 00140 **********************************************************************/ 00141 ///@{ 00142 00143 /** 00144 * Compute the position of point 2 which is a distance \e s12 (meters) from 00145 * point 1. 00146 * 00147 * @param[in] s12 distance between point 1 and point 2 (meters); it can be 00148 * negative. 00149 * @param[out] lat2 latitude of point 2 (degrees). 00150 * @param[out] lon2 longitude of point 2 (degrees); requires that the 00151 * GeodesicLine object was constructed with \e caps |= 00152 * GeodesicLine::LONGITUDE. 00153 * @param[out] azi2 (forward) azimuth at point 2 (degrees). 00154 * @param[out] m12 reduced length of geodesic (meters); requires that the 00155 * GeodesicLine object was constructed with \e caps |= 00156 * GeodesicLine::REDUCEDLENGTH. 00157 * @param[out] M12 geodesic scale of point 2 relative to point 1 00158 * (dimensionless); requires that the GeodesicLine object was constructed 00159 * with \e caps |= GeodesicLine::GEODESICSCALE. 00160 * @param[out] M21 geodesic scale of point 1 relative to point 2 00161 * (dimensionless); requires that the GeodesicLine object was constructed 00162 * with \e caps |= GeodesicLine::GEODESICSCALE. 00163 * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires 00164 * that the GeodesicLine object was constructed with \e caps |= 00165 * GeodesicLine::AREA. 00166 * @return \e a12 arc length of between point 1 and point 2 (degrees). 00167 * 00168 * The values of \e lon2 and \e azi2 returned are in the range 00169 * [−180°, 180°). 00170 * 00171 * The GeodesicLine object \e must have been constructed with \e caps |= 00172 * GeodesicLine::DISTANCE_IN; otherwise Math::NaN() is returned and no 00173 * parameters are set. Requesting a value which the GeodesicLine object is 00174 * not capable of computing is not an error; the corresponding argument 00175 * will not be altered. 00176 * 00177 * The following functions are overloaded versions of 00178 * GeodesicLine::Position which omit some of the output parameters. Note, 00179 * however, that the arc length is always computed and returned as the 00180 * function value. 00181 **********************************************************************/ 00182 double Position(double s12, 00183 [System::Runtime::InteropServices::Out] double% lat2, 00184 [System::Runtime::InteropServices::Out] double% lon2, 00185 [System::Runtime::InteropServices::Out] double% azi2, 00186 [System::Runtime::InteropServices::Out] double% m12, 00187 [System::Runtime::InteropServices::Out] double% M12, 00188 [System::Runtime::InteropServices::Out] double% M21, 00189 [System::Runtime::InteropServices::Out] double% S12); 00190 00191 /** 00192 * See the documentation for GeodesicLine::Position. 00193 **********************************************************************/ 00194 double Position(double s12, 00195 [System::Runtime::InteropServices::Out] double% lat2, 00196 [System::Runtime::InteropServices::Out] double% lon2); 00197 00198 /** 00199 * See the documentation for GeodesicLine::Position. 00200 **********************************************************************/ 00201 double Position(double s12, 00202 [System::Runtime::InteropServices::Out] double% lat2, 00203 [System::Runtime::InteropServices::Out] double% lon2, 00204 [System::Runtime::InteropServices::Out] double% azi2); 00205 00206 /** 00207 * See the documentation for GeodesicLine::Position. 00208 **********************************************************************/ 00209 double Position(double s12, 00210 [System::Runtime::InteropServices::Out] double% lat2, 00211 [System::Runtime::InteropServices::Out] double% lon2, 00212 [System::Runtime::InteropServices::Out] double% azi2, 00213 [System::Runtime::InteropServices::Out] double% m12); 00214 00215 /** 00216 * See the documentation for GeodesicLine::Position. 00217 **********************************************************************/ 00218 double Position(double s12, 00219 [System::Runtime::InteropServices::Out] double% lat2, 00220 [System::Runtime::InteropServices::Out] double% lon2, 00221 [System::Runtime::InteropServices::Out] double% azi2, 00222 [System::Runtime::InteropServices::Out] double% M12, 00223 [System::Runtime::InteropServices::Out] double% M21); 00224 00225 /** 00226 * See the documentation for GeodesicLine::Position. 00227 **********************************************************************/ 00228 double Position(double s12, 00229 [System::Runtime::InteropServices::Out] double% lat2, 00230 [System::Runtime::InteropServices::Out] double% lon2, 00231 [System::Runtime::InteropServices::Out] double% azi2, 00232 [System::Runtime::InteropServices::Out] double% m12, 00233 [System::Runtime::InteropServices::Out] double% M12, 00234 [System::Runtime::InteropServices::Out] double% M21); 00235 00236 ///@} 00237 00238 /** \name Position in terms of arc length 00239 **********************************************************************/ 00240 ///@{ 00241 00242 /** 00243 * Compute the position of point 2 which is an arc length \e a12 (degrees) 00244 * from point 1. 00245 * 00246 * @param[in] a12 arc length between point 1 and point 2 (degrees); it can 00247 * be negative. 00248 * @param[out] lat2 latitude of point 2 (degrees). 00249 * @param[out] lon2 longitude of point 2 (degrees); requires that the 00250 * GeodesicLine object was constructed with \e caps |= 00251 * NETGeographicLib::Mask::LONGITUDE. 00252 * @param[out] azi2 (forward) azimuth at point 2 (degrees). 00253 * @param[out] s12 distance between point 1 and point 2 (meters); requires 00254 * that the GeodesicLine object was constructed with \e caps |= 00255 * NETGeographicLib::Mask::DISTANCE. 00256 * @param[out] m12 reduced length of geodesic (meters); requires that the 00257 * GeodesicLine object was constructed with \e caps |= 00258 * NETGeographicLib::Mask::REDUCEDLENGTH. 00259 * @param[out] M12 geodesic scale of point 2 relative to point 1 00260 * (dimensionless); requires that the GeodesicLine object was constructed 00261 * with \e caps |= NETGeographicLib::Mask::GEODESICSCALE. 00262 * @param[out] M21 geodesic scale of point 1 relative to point 2 00263 * (dimensionless); requires that the GeodesicLine object was constructed 00264 * with \e caps |= NETGeographicLib::Mask::GEODESICSCALE. 00265 * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires 00266 * that the GeodesicLine object was constructed with \e caps |= 00267 * NETGeographicLib::Mask::AREA. 00268 * 00269 * The values of \e lon2 and \e azi2 returned are in the range 00270 * [−180°, 180°). 00271 * 00272 * Requesting a value which the GeodesicLine object is not capable of 00273 * computing is not an error; the corresponding argument will not be 00274 * altered. 00275 * 00276 * The following functions are overloaded versions of 00277 * GeodesicLine::ArcPosition which omit some of the output parameters. 00278 **********************************************************************/ 00279 void ArcPosition(double a12, 00280 [System::Runtime::InteropServices::Out] double% lat2, 00281 [System::Runtime::InteropServices::Out] double% lon2, 00282 [System::Runtime::InteropServices::Out] double% azi2, 00283 [System::Runtime::InteropServices::Out] double% s12, 00284 [System::Runtime::InteropServices::Out] double% m12, 00285 [System::Runtime::InteropServices::Out] double% M12, 00286 [System::Runtime::InteropServices::Out] double% M21, 00287 [System::Runtime::InteropServices::Out] double% S12); 00288 00289 /** 00290 * See the documentation for GeodesicLine::ArcPosition. 00291 **********************************************************************/ 00292 void ArcPosition(double a12, 00293 [System::Runtime::InteropServices::Out] double% lat2, 00294 [System::Runtime::InteropServices::Out] double% lon2); 00295 00296 /** 00297 * See the documentation for GeodesicLine::ArcPosition. 00298 **********************************************************************/ 00299 void ArcPosition(double a12, 00300 [System::Runtime::InteropServices::Out] double% lat2, 00301 [System::Runtime::InteropServices::Out] double% lon2, 00302 [System::Runtime::InteropServices::Out] double% azi2); 00303 00304 /** 00305 * See the documentation for GeodesicLine::ArcPosition. 00306 **********************************************************************/ 00307 void ArcPosition(double a12, 00308 [System::Runtime::InteropServices::Out] double% lat2, 00309 [System::Runtime::InteropServices::Out] double% lon2, 00310 [System::Runtime::InteropServices::Out] double% azi2, 00311 [System::Runtime::InteropServices::Out] double% s12); 00312 00313 /** 00314 * See the documentation for GeodesicLine::ArcPosition. 00315 **********************************************************************/ 00316 void ArcPosition(double a12, 00317 [System::Runtime::InteropServices::Out] double% lat2, 00318 [System::Runtime::InteropServices::Out] double% lon2, 00319 [System::Runtime::InteropServices::Out] double% azi2, 00320 [System::Runtime::InteropServices::Out] double% s12, 00321 [System::Runtime::InteropServices::Out] double% m12); 00322 00323 /** 00324 * See the documentation for GeodesicLine::ArcPosition. 00325 **********************************************************************/ 00326 void ArcPosition(double a12, 00327 [System::Runtime::InteropServices::Out] double% lat2, 00328 [System::Runtime::InteropServices::Out] double% lon2, 00329 [System::Runtime::InteropServices::Out] double% azi2, 00330 [System::Runtime::InteropServices::Out] double% s12, 00331 [System::Runtime::InteropServices::Out] double% M12, 00332 [System::Runtime::InteropServices::Out] double% M21); 00333 00334 /** 00335 * See the documentation for GeodesicLine::ArcPosition. 00336 **********************************************************************/ 00337 void ArcPosition(double a12, 00338 [System::Runtime::InteropServices::Out] double% lat2, 00339 [System::Runtime::InteropServices::Out] double% lon2, 00340 [System::Runtime::InteropServices::Out] double% azi2, 00341 [System::Runtime::InteropServices::Out] double% s12, 00342 [System::Runtime::InteropServices::Out] double% m12, 00343 [System::Runtime::InteropServices::Out] double% M12, 00344 [System::Runtime::InteropServices::Out] double% M21); 00345 ///@} 00346 00347 /** \name The general position function. 00348 **********************************************************************/ 00349 ///@{ 00350 00351 /** 00352 * The general position function. GeodesicLine::Position and 00353 * GeodesicLine::ArcPosition are defined in terms of this function. 00354 * 00355 * @param[in] arcmode boolean flag determining the meaning of the second 00356 * parameter; if arcmode is false, then the GeodesicLine object must have 00357 * been constructed with \e caps |= GeodesicLine::DISTANCE_IN. 00358 * @param[in] s12_a12 if \e arcmode is false, this is the distance between 00359 * point 1 and point 2 (meters); otherwise it is the arc length between 00360 * point 1 and point 2 (degrees); it can be negative. 00361 * @param[in] outmask a bitor'ed combination of NETGeographicLib::Mask values 00362 * specifying which of the following parameters should be set. 00363 * @param[out] lat2 latitude of point 2 (degrees). 00364 * @param[out] lon2 longitude of point 2 (degrees); requires that the 00365 * GeodesicLine object was constructed with \e caps |= 00366 * NETGeographicLib::Mask::LONGITUDE. 00367 * @param[out] azi2 (forward) azimuth at point 2 (degrees). 00368 * @param[out] s12 distance between point 1 and point 2 (meters); requires 00369 * that the GeodesicLine object was constructed with \e caps |= 00370 * NETGeographicLib::Mask::DISTANCE. 00371 * @param[out] m12 reduced length of geodesic (meters); requires that the 00372 * GeodesicLine object was constructed with \e caps |= 00373 * NETGeographicLib::Mask::REDUCEDLENGTH. 00374 * @param[out] M12 geodesic scale of point 2 relative to point 1 00375 * (dimensionless); requires that the GeodesicLine object was constructed 00376 * with \e caps |= NETGeographicLib::Mask::GEODESICSCALE. 00377 * @param[out] M21 geodesic scale of point 1 relative to point 2 00378 * (dimensionless); requires that the GeodesicLine object was constructed 00379 * with \e caps |= NETGeographicLib::Mask::GEODESICSCALE. 00380 * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requires 00381 * that the GeodesicLine object was constructed with \e caps |= 00382 * NETGeographicLib::Mask::AREA. 00383 * @return \e a12 arc length of between point 1 and point 2 (degrees). 00384 * 00385 * The GeodesicLine::mask values possible for \e outmask are 00386 * - \e outmask |= NETGeographicLib::Mask::LATITUDE for the latitude \e lat2; 00387 * - \e outmask |= NETGeographicLib::Mask::LONGITUDE for the latitude \e lon2; 00388 * - \e outmask |= NETGeographicLib::Mask::AZIMUTH for the latitude \e azi2; 00389 * - \e outmask |= NETGeographicLib::Mask::DISTANCE for the distance \e s12; 00390 * - \e outmask |= NETGeographicLib::Mask::REDUCEDLENGTH for the reduced length \e 00391 * m12; 00392 * - \e outmask |= NETGeographicLib::Mask::GEODESICSCALE for the geodesic scales \e 00393 * M12 and \e M21; 00394 * - \e outmask |= NETGeographicLib::Mask::AREA for the area \e S12; 00395 * - \e outmask |= NETGeographicLib::Mask::ALL for all of the above. 00396 * . 00397 * Requesting a value which the GeodesicLine object is not capable of 00398 * computing is not an error; the corresponding argument will not be 00399 * altered. Note, however, that the arc length is always computed and 00400 * returned as the function value. 00401 **********************************************************************/ 00402 double GenPosition(bool arcmode, double s12_a12, 00403 NETGeographicLib::Mask outmask, 00404 [System::Runtime::InteropServices::Out] double% lat2, 00405 [System::Runtime::InteropServices::Out] double% lon2, 00406 [System::Runtime::InteropServices::Out] double% azi2, 00407 [System::Runtime::InteropServices::Out] double% s12, 00408 [System::Runtime::InteropServices::Out] double% m12, 00409 [System::Runtime::InteropServices::Out] double% M12, 00410 [System::Runtime::InteropServices::Out] double% M21, 00411 [System::Runtime::InteropServices::Out] double% S12); 00412 00413 ///@} 00414 00415 /** \name Inspector functions 00416 **********************************************************************/ 00417 ///@{ 00418 00419 /** 00420 * @return \e lat1 the latitude of point 1 (degrees). 00421 **********************************************************************/ 00422 property double Latitude { double get(); } 00423 00424 /** 00425 * @return \e lon1 the longitude of point 1 (degrees). 00426 **********************************************************************/ 00427 property double Longitude { double get(); } 00428 00429 /** 00430 * @return \e azi1 the azimuth (degrees) of the geodesic line at point 1. 00431 **********************************************************************/ 00432 property double Azimuth { double get(); } 00433 00434 /** 00435 * @return \e azi0 the azimuth (degrees) of the geodesic line as it crosses 00436 * the equator in a northward direction. 00437 **********************************************************************/ 00438 property double EquatorialAzimuth { double get(); } 00439 00440 /** 00441 * @return \e a1 the arc length (degrees) between the northward equatorial 00442 * crossing and point 1. 00443 **********************************************************************/ 00444 property double EquatorialArc { double get(); } 00445 00446 /** 00447 * @return \e a the equatorial radius of the ellipsoid (meters). This is 00448 * the value inherited from the Geodesic object used in the constructor. 00449 **********************************************************************/ 00450 property double MajorRadius { double get(); } 00451 00452 /** 00453 * @return \e f the flattening of the ellipsoid. This is the value 00454 * inherited from the Geodesic object used in the constructor. 00455 **********************************************************************/ 00456 property double Flattening { double get(); } 00457 00458 /** 00459 * @return \e caps the computational capabilities that this object was 00460 * constructed with. LATITUDE and AZIMUTH are always included. 00461 **********************************************************************/ 00462 NETGeographicLib::Mask Capabilities(); 00463 00464 /** 00465 * @param[in] testcaps a set of bitor'ed GeodesicLine::mask values. 00466 * @return true if the GeodesicLine object has all these capabilities. 00467 **********************************************************************/ 00468 bool Capabilities(NETGeographicLib::Mask testcaps); 00469 ///@} 00470 }; 00471 } // namespace NETGeographicLib