00001 #pragma once 00002 /** 00003 * \file NETGeographicLib/Gnomonic.h 00004 * \brief Header for NETGeographicLib::Gnomonic 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 00013 namespace NETGeographicLib 00014 { 00015 ref class Geodesic; 00016 /** 00017 * \brief .NET wrapper for GeographicLib::Gnomonic. 00018 * 00019 * This class allows .NET applications to access GeographicLib::Gnomonic. 00020 * 00021 * %Gnomonic projection centered at an arbitrary position \e C on the 00022 * ellipsoid. This projection is derived in Section 8 of 00023 * - C. F. F. Karney, 00024 * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> 00025 * Algorithms for geodesics</a>, 00026 * J. Geodesy <b>87</b>, 43--55 (2013); 00027 * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> 00028 * 10.1007/s00190-012-0578-z</a>; 00029 * addenda: <a href="http://geographiclib.sf.net/geod-addenda.html"> 00030 * geod-addenda.html</a>. 00031 * . 00032 * The projection of \e P is defined as follows: compute the geodesic line 00033 * from \e C to \e P; compute the reduced length \e m12, geodesic scale \e 00034 * M12, and ρ = <i>m12</i>/\e M12; finally \e x = ρ sin \e azi1; \e 00035 * y = ρ cos \e azi1, where \e azi1 is the azimuth of the geodesic at \e 00036 * C. The Gnomonic::Forward and Gnomonic::Reverse methods also return the 00037 * azimuth \e azi of the geodesic at \e P and reciprocal scale \e rk in the 00038 * azimuthal direction. The scale in the radial direction if 00039 * 1/<i>rk</i><sup>2</sup>. 00040 * 00041 * For a sphere, ρ is reduces to \e a tan(<i>s12</i>/<i>a</i>), where \e 00042 * s12 is the length of the geodesic from \e C to \e P, and the gnomonic 00043 * projection has the property that all geodesics appear as straight lines. 00044 * For an ellipsoid, this property holds only for geodesics interesting the 00045 * centers. However geodesic segments close to the center are approximately 00046 * straight. 00047 * 00048 * Consider a geodesic segment of length \e l. Let \e T be the point on the 00049 * geodesic (extended if necessary) closest to \e C the center of the 00050 * projection and \e t be the distance \e CT. To lowest order, the maximum 00051 * deviation (as a true distance) of the corresponding gnomonic line segment 00052 * (i.e., with the same end points) from the geodesic is<br> 00053 * <br> 00054 * (<i>K</i>(<i>T</i>) - <i>K</i>(<i>C</i>)) 00055 * <i>l</i><sup>2</sup> \e t / 32.<br> 00056 * <br> 00057 * where \e K is the Gaussian curvature. 00058 * 00059 * This result applies for any surface. For an ellipsoid of revolution, 00060 * consider all geodesics whose end points are within a distance \e r of \e 00061 * C. For a given \e r, the deviation is maximum when the latitude of \e C 00062 * is 45°, when endpoints are a distance \e r away, and when their 00063 * azimuths from the center are ± 45° or ± 135°. 00064 * To lowest order in \e r and the flattening \e f, the deviation is \e f 00065 * (<i>r</i>/2<i>a</i>)<sup>3</sup> \e r. 00066 * 00067 * The conversions all take place using a Geodesic object (by default 00068 * Geodesic::WGS84). For more information on geodesics see \ref geodesic. 00069 * 00070 * <b>CAUTION:</b> The definition of this projection for a sphere is 00071 * standard. However, there is no standard for how it should be extended to 00072 * an ellipsoid. The choices are: 00073 * - Declare that the projection is undefined for an ellipsoid. 00074 * - Project to a tangent plane from the center of the ellipsoid. This 00075 * causes great ellipses to appear as straight lines in the projection; 00076 * i.e., it generalizes the spherical great circle to a great ellipse. 00077 * This was proposed by independently by Bowring and Williams in 1997. 00078 * - Project to the conformal sphere with the constant of integration chosen 00079 * so that the values of the latitude match for the center point and 00080 * perform a central projection onto the plane tangent to the conformal 00081 * sphere at the center point. This causes normal sections through the 00082 * center point to appear as straight lines in the projection; i.e., it 00083 * generalizes the spherical great circle to a normal section. This was 00084 * proposed by I. G. Letoval'tsev, Generalization of the %Gnomonic 00085 * Projection for a Spheroid and the Principal Geodetic Problems Involved 00086 * in the Alignment of Surface Routes, Geodesy and Aerophotography (5), 00087 * 271--274 (1963). 00088 * - The projection given here. This causes geodesics close to the center 00089 * point to appear as straight lines in the projection; i.e., it 00090 * generalizes the spherical great circle to a geodesic. 00091 * 00092 * C# Example: 00093 * \include example-Gnomonic.cs 00094 * Managed C++ Example: 00095 * \include example-Gnomonic.cpp 00096 * Visual Basic Example: 00097 * \include example-Gnomonic.vb 00098 * 00099 * <B>INTERFACE DIFFERENCES:</B><BR> 00100 * A default constructor has been provided that assumes WGS84 parameters. 00101 * 00102 * The MajorRadius and Flattening functions are implemented as properties. 00103 **********************************************************************/ 00104 public ref class Gnomonic 00105 { 00106 private: 00107 // the pointer to the unmanaged GeographicLib::Gnomonic. 00108 const GeographicLib::Gnomonic* m_pGnomonic; 00109 00110 // The finalizer frees the unmanaged memory when the object is destroyed. 00111 !Gnomonic(void); 00112 public: 00113 /** 00114 * Constructor for Gnomonic. 00115 * 00116 * @param[in] earth the Geodesic object to use for geodesic calculations. 00117 **********************************************************************/ 00118 Gnomonic( Geodesic^ earth ); 00119 00120 /** 00121 * The default constructor assumes a WGS84 ellipsoid.. 00122 **********************************************************************/ 00123 Gnomonic(); 00124 00125 /** 00126 * The destructor calls the finalizer 00127 **********************************************************************/ 00128 ~Gnomonic() 00129 { this->!Gnomonic(); } 00130 00131 /** 00132 * Forward projection, from geographic to gnomonic. 00133 * 00134 * @param[in] lat0 latitude of center point of projection (degrees). 00135 * @param[in] lon0 longitude of center point of projection (degrees). 00136 * @param[in] lat latitude of point (degrees). 00137 * @param[in] lon longitude of point (degrees). 00138 * @param[out] x easting of point (meters). 00139 * @param[out] y northing of point (meters). 00140 * @param[out] azi azimuth of geodesic at point (degrees). 00141 * @param[out] rk reciprocal of azimuthal scale at point. 00142 * 00143 * \e lat0 and \e lat should be in the range [−90°, 90°] and 00144 * \e lon0 and \e lon should be in the range [−540°, 540°). 00145 * The scale of the projection is 1/<i>rk</i><sup>2</sup> in the "radial" 00146 * direction, \e azi clockwise from true north, and is 1/\e rk in the 00147 * direction perpendicular to this. If the point lies "over the horizon", 00148 * i.e., if \e rk ≤ 0, then NaNs are returned for \e x and \e y (the 00149 * correct values are returned for \e azi and \e rk). A call to Forward 00150 * followed by a call to Reverse will return the original (\e lat, \e lon) 00151 * (to within roundoff) provided the point in not over the horizon. 00152 **********************************************************************/ 00153 void Forward(double lat0, double lon0, double lat, double lon, 00154 [System::Runtime::InteropServices::Out] double% x, 00155 [System::Runtime::InteropServices::Out] double% y, 00156 [System::Runtime::InteropServices::Out] double% azi, 00157 [System::Runtime::InteropServices::Out] double% rk); 00158 00159 /** 00160 * Reverse projection, from gnomonic to geographic. 00161 * 00162 * @param[in] lat0 latitude of center point of projection (degrees). 00163 * @param[in] lon0 longitude of center point of projection (degrees). 00164 * @param[in] x easting of point (meters). 00165 * @param[in] y northing of point (meters). 00166 * @param[out] lat latitude of point (degrees). 00167 * @param[out] lon longitude of point (degrees). 00168 * @param[out] azi azimuth of geodesic at point (degrees). 00169 * @param[out] rk reciprocal of azimuthal scale at point. 00170 * 00171 * \e lat0 should be in the range [−90°, 90°] and \e 00172 * lon0 should be in the range [−540°, 540°). \e lat 00173 * will be in the range [−90°, 90°] and \e lon will 00174 * be in the range [−180°, 180°). The scale of the 00175 * projection is 1/\e rk<sup>2</sup> in the "radial" direction, \e azi 00176 * clockwise from true north, and is 1/\e rk in the direction perpendicular 00177 * to this. Even though all inputs should return a valid \e lat and \e 00178 * lon, it's possible that the procedure fails to converge for very large 00179 * \e x or \e y; in this case NaNs are returned for all the output 00180 * arguments. A call to Reverse followed by a call to Forward will return 00181 * the original (\e x, \e y) (to roundoff). 00182 **********************************************************************/ 00183 void Reverse(double lat0, double lon0, double x, double y, 00184 [System::Runtime::InteropServices::Out] double% lat, 00185 [System::Runtime::InteropServices::Out] double% lon, 00186 [System::Runtime::InteropServices::Out] double% azi, 00187 [System::Runtime::InteropServices::Out] double% rk); 00188 00189 /** 00190 * Gnomonic::Forward without returning the azimuth and scale. 00191 **********************************************************************/ 00192 void Forward(double lat0, double lon0, double lat, double lon, 00193 [System::Runtime::InteropServices::Out] double% x, 00194 [System::Runtime::InteropServices::Out] double% y); 00195 00196 /** 00197 * Gnomonic::Reverse without returning the azimuth and scale. 00198 **********************************************************************/ 00199 void Reverse(double lat0, double lon0, double x, double y, 00200 [System::Runtime::InteropServices::Out] double% lat, 00201 [System::Runtime::InteropServices::Out] double% lon); 00202 00203 /** \name Inspector functions 00204 **********************************************************************/ 00205 ///@{ 00206 /** 00207 * @return \e a the equatorial radius of the ellipsoid (meters). This is 00208 * the value inherited from the Geodesic object used in the constructor. 00209 **********************************************************************/ 00210 property double MajorRadius { double get(); } 00211 00212 /** 00213 * @return \e f the flattening of the ellipsoid. This is the value 00214 * inherited from the Geodesic object used in the constructor. 00215 **********************************************************************/ 00216 property double Flattening { double get(); } 00217 ///@} 00218 }; 00219 } // namespace NETGeographicLib