00001 /** 00002 * \file NETGeographicLib/CassiniSoldner.h 00003 * \brief Header for NETGeographicLib::CassiniSoldner 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::CassiniSoldner. 00017 * 00018 * This class allows .NET applications to access GeographicLib::CassiniSoldner. 00019 * 00020 * Cassini-Soldner projection centered at an arbitrary position, \e lat0, \e 00021 * lon0, on the ellipsoid. This projection is a transverse cylindrical 00022 * equidistant projection. The projection from (\e lat, \e lon) to easting 00023 * and northing (\e x, \e y) is defined by geodesics as follows. Go north 00024 * along a geodesic a distance \e y from the central point; then turn 00025 * clockwise 90° and go a distance \e x along a geodesic. 00026 * (Although the initial heading is north, this changes to south if the pole 00027 * is crossed.) This procedure uniquely defines the reverse projection. The 00028 * forward projection is constructed as follows. Find the point (\e lat1, \e 00029 * lon1) on the meridian closest to (\e lat, \e lon). Here we consider the 00030 * full meridian so that \e lon1 may be either \e lon0 or \e lon0 + 00031 * 180°. \e x is the geodesic distance from (\e lat1, \e lon1) to 00032 * (\e lat, \e lon), appropriately signed according to which side of the 00033 * central meridian (\e lat, \e lon) lies. \e y is the shortest distance 00034 * along the meridian from (\e lat0, \e lon0) to (\e lat1, \e lon1), again, 00035 * appropriately signed according to the initial heading. [Note that, in the 00036 * case of prolate ellipsoids, the shortest meridional path from (\e lat0, \e 00037 * lon0) to (\e lat1, \e lon1) may not be the shortest path.] This procedure 00038 * uniquely defines the forward projection except for a small class of points 00039 * for which there may be two equally short routes for either leg of the 00040 * path. 00041 * 00042 * Because of the properties of geodesics, the (\e x, \e y) grid is 00043 * orthogonal. The scale in the easting direction is unity. The scale, \e 00044 * k, in the northing direction is unity on the central meridian and 00045 * increases away from the central meridian. The projection routines return 00046 * \e azi, the true bearing of the easting direction, and \e rk = 1/\e k, the 00047 * reciprocal of the scale in the northing direction. 00048 * 00049 * The conversions all take place using a Geodesic object (by default 00050 * Geodesic::WGS84). For more information on geodesics see \ref geodesic. 00051 * The determination of (\e lat1, \e lon1) in the forward projection is by 00052 * solving the inverse geodesic problem for (\e lat, \e lon) and its twin 00053 * obtained by reflection in the meridional plane. The scale is found by 00054 * determining where two neighboring geodesics intersecting the central 00055 * meridian at \e lat1 and \e lat1 + \e dlat1 intersect and taking the ratio 00056 * of the reduced lengths for the two geodesics between that point and, 00057 * respectively, (\e lat1, \e lon1) and (\e lat, \e lon). 00058 * 00059 * C# Example: 00060 * \include example-CassiniSoldner.cs 00061 * Managed C++ Example: 00062 * \include example-CassiniSoldner.cpp 00063 * Visual Basic Example: 00064 * \include example-CassiniSoldner.vb 00065 * 00066 * <B>INTERFACE DIFFERENCES:</B><BR> 00067 * The LatitudeOrigin, LongitudeOrigin, MajorRadius and Flattening 00068 * functions are implimented as properties. 00069 **********************************************************************/ 00070 public ref class CassiniSoldner 00071 { 00072 private: 00073 // A pointer to the unmanaged GeographicLib::CassiniSoldner 00074 GeographicLib::CassiniSoldner* m_pCassiniSoldner; 00075 00076 // The finalizer frees the unmanaged memory when the object is destroyed. 00077 !CassiniSoldner(); 00078 public: 00079 /** 00080 * Constructor for CassiniSoldner specifying a center point and 00081 * assuming the WGS84 ellipsoid. 00082 * 00083 * @param[in] lat0 latitude of center point of projection (degrees). 00084 * @param[in] lon0 longitude of center point of projection (degrees). 00085 **********************************************************************/ 00086 CassiniSoldner(double lat0, double lon0); 00087 00088 /** 00089 * Constructor for CassiniSoldner specifying a center point. 00090 * 00091 * @param[in] lat0 latitude of center point of projection (degrees). 00092 * @param[in] lon0 longitude of center point of projection (degrees). 00093 * @param[in] earth the Geodesic object to use for geodesic calculations. 00094 * By default this uses the WGS84 ellipsoid. 00095 * 00096 * \e lat0 should be in the range [−90°, 90°] and \e 00097 * lon0 should be in the range [−540°, 540°). 00098 **********************************************************************/ 00099 CassiniSoldner(double lat0, double lon0, Geodesic^ earth ); 00100 00101 /** 00102 * The destructor calls the finalizer. 00103 **********************************************************************/ 00104 ~CassiniSoldner() 00105 { this->!CassiniSoldner(); } 00106 00107 /** 00108 * Set the central point of the projection 00109 * 00110 * @param[in] lat0 latitude of center point of projection (degrees). 00111 * @param[in] lon0 longitude of center point of projection (degrees). 00112 * 00113 * \e lat0 should be in the range [−90°, 90°] and \e 00114 * lon0 should be in the range [−540°, 540°). 00115 **********************************************************************/ 00116 void Reset(double lat0, double lon0); 00117 00118 /** 00119 * Forward projection, from geographic to Cassini-Soldner. 00120 * 00121 * @param[in] lat latitude of point (degrees). 00122 * @param[in] lon longitude of point (degrees). 00123 * @param[out] x easting of point (meters). 00124 * @param[out] y northing of point (meters). 00125 * @param[out] azi azimuth of easting direction at point (degrees). 00126 * @param[out] rk reciprocal of azimuthal northing scale at point. 00127 * 00128 * \e lat should be in the range [−90°, 90°] and \e 00129 * lon should be in the range [−540°, 540°). A call 00130 * to Forward followed by a call to Reverse will return the original (\e 00131 * lat, \e lon) (to within roundoff). The routine does nothing if the 00132 * origin has not been set. 00133 **********************************************************************/ 00134 void Forward(double lat, double lon, 00135 [System::Runtime::InteropServices::Out] double% x, 00136 [System::Runtime::InteropServices::Out] double% y, 00137 [System::Runtime::InteropServices::Out] double% azi, 00138 [System::Runtime::InteropServices::Out] double% rk); 00139 00140 /** 00141 * Reverse projection, from Cassini-Soldner to geographic. 00142 * 00143 * @param[in] x easting of point (meters). 00144 * @param[in] y northing of point (meters). 00145 * @param[out] lat latitude of point (degrees). 00146 * @param[out] lon longitude of point (degrees). 00147 * @param[out] azi azimuth of easting direction at point (degrees). 00148 * @param[out] rk reciprocal of azimuthal northing scale at point. 00149 * 00150 * A call to Reverse followed by a call to Forward will return the original 00151 * (\e x, \e y) (to within roundoff), provided that \e x and \e y are 00152 * sufficiently small not to "wrap around" the earth. The routine does 00153 * nothing if the origin has not been set. 00154 **********************************************************************/ 00155 void Reverse(double x, double y, 00156 [System::Runtime::InteropServices::Out] double% lat, 00157 [System::Runtime::InteropServices::Out] double% lon, 00158 [System::Runtime::InteropServices::Out] double% azi, 00159 [System::Runtime::InteropServices::Out] double% rk); 00160 00161 /** 00162 * CassiniSoldner::Forward without returning the azimuth and scale. 00163 **********************************************************************/ 00164 void Forward(double lat, double lon, 00165 [System::Runtime::InteropServices::Out] double% x, 00166 [System::Runtime::InteropServices::Out] double% y); 00167 00168 /** 00169 * CassiniSoldner::Reverse without returning the azimuth and scale. 00170 **********************************************************************/ 00171 void Reverse(double x, double y, 00172 [System::Runtime::InteropServices::Out] double% lat, 00173 [System::Runtime::InteropServices::Out] double% lon); 00174 00175 /** \name Inspector functions 00176 **********************************************************************/ 00177 ///@{ 00178 /** 00179 * @return \e lat0 the latitude of origin (degrees). 00180 **********************************************************************/ 00181 property double LatitudeOrigin { double get(); } 00182 00183 /** 00184 * @return \e lon0 the longitude of origin (degrees). 00185 **********************************************************************/ 00186 property double LongitudeOrigin { double get(); } 00187 00188 /** 00189 * @return \e a the equatorial radius of the ellipsoid (meters). This is 00190 * the value inherited from the Geodesic object used in the constructor. 00191 **********************************************************************/ 00192 property double MajorRadius { double get(); } 00193 00194 /** 00195 * @return \e f the flattening of the ellipsoid. This is the value 00196 * inherited from the Geodesic object used in the constructor. 00197 **********************************************************************/ 00198 property double Flattening { double get(); } 00199 ///@} 00200 }; 00201 } // namespace NETGeographicLib