1 #pragma once 2 /** 3 * \file NETGeographicLib/LambertConformalConic.h 4 * \brief Header for NETGeographicLib::LambertConformalConic class 5 * 6 * NETGeographicLib is copyright (c) Scott Heiman (2013) 7 * GeographicLib is Copyright (c) Charles Karney (2010-2012) 8 * <charles@karney.com> and licensed under the MIT/X11 License. 9 * For more information, see 10 * https://geographiclib.sourceforge.io/ 11 **********************************************************************/ 12 13 namespace NETGeographicLib 14 { 15 /** 16 * \brief .NET wrapper for GeographicLib::LambertConformalConic. 17 * 18 * This class allows .NET applications to access GeographicLib::LambertConformalConic. 19 * 20 * Implementation taken from the report, 21 * - J. P. Snyder, 22 * <a href="http://pubs.er.usgs.gov/usgspubs/pp/pp1395"> Map Projections: A 23 * Working Manual</a>, USGS Professional Paper 1395 (1987), 24 * pp. 107--109. 25 * 26 * This is a implementation of the equations in Snyder except that divided 27 * differences have been used to transform the expressions into ones which 28 * may be evaluated accurately and that Newton's method is used to invert the 29 * projection. In this implementation, the projection correctly becomes the 30 * Mercator projection or the polar stereographic projection when the 31 * standard latitude is the equator or a pole. The accuracy of the 32 * projections is about 10 nm (10 nanometers). 33 * 34 * The ellipsoid parameters, the standard parallels, and the scale on the 35 * standard parallels are set in the constructor. Internally, the case with 36 * two standard parallels is converted into a single standard parallel, the 37 * latitude of tangency (also the latitude of minimum scale), with a scale 38 * specified on this parallel. This latitude is also used as the latitude of 39 * origin which is returned by LambertConformalConic::OriginLatitude. The 40 * scale on the latitude of origin is given by 41 * LambertConformalConic::CentralScale. The case with two distinct standard 42 * parallels where one is a pole is singular and is disallowed. The central 43 * meridian (which is a trivial shift of the longitude) is specified as the 44 * \e lon0 argument of the LambertConformalConic::Forward and 45 * LambertConformalConic::Reverse functions. There is no provision in this 46 * class for specifying a false easting or false northing or a different 47 * latitude of origin. However these are can be simply included by the 48 * calling function. For example the Pennsylvania South state coordinate 49 * system (<a href="http://www.spatialreference.org/ref/epsg/3364/"> 50 * EPSG:3364</a>) is obtained by: 51 * C# Example: 52 * \include example-LambertConformalConic.cs 53 * Managed C++ Example: 54 * \include example-LambertConformalConic.cpp 55 * Visual Basic Example: 56 * \include example-LambertConformalConic.vb 57 * 58 * <B>INTERFACE DIFFERENCES:</B><BR> 59 * A default constructor has been provided that assumes a Mercator 60 * projection. 61 * 62 * The EquatorialRadius, Flattening, OriginLatitude, and CentralScale 63 * functions are implemented as properties. 64 **********************************************************************/ 65 public ref class LambertConformalConic 66 { 67 private: 68 // Pointer to the unmanaged GeographicLib::LambertConformalConic. 69 GeographicLib::LambertConformalConic* m_pLambertConformalConic; 70 71 // the finalizer frres the unmanaged memory when the object is destroyed. 72 !LambertConformalConic(void); 73 public: 74 75 /** 76 * Constructor with a single standard parallel. 77 * 78 * @param[in] a equatorial radius of ellipsoid (meters). 79 * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere. 80 * Negative \e f gives a prolate ellipsoid. 81 * @param[in] stdlat standard parallel (degrees), the circle of tangency. 82 * @param[in] k0 scale on the standard parallel. 83 * @exception GeographicErr if \e a, (1 − \e f ) \e a, or \e k0 is 84 * not positive. 85 * @exception GeographicErr if \e stdlat is not in [−90°, 86 * 90°]. 87 **********************************************************************/ 88 LambertConformalConic(double a, double f, double stdlat, double k0); 89 90 /** 91 * Constructor with two standard parallels. 92 * 93 * @param[in] a equatorial radius of ellipsoid (meters). 94 * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere. 95 * Negative \e f gives a prolate ellipsoid. 96 * @param[in] stdlat1 first standard parallel (degrees). 97 * @param[in] stdlat2 second standard parallel (degrees). 98 * @param[in] k1 scale on the standard parallels. 99 * @exception GeographicErr if \e a, (1 − \e f ) \e a, or \e k1 is 100 * not positive. 101 * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in 102 * [−90°, 90°], or if either \e stdlat1 or \e 103 * stdlat2 is a pole and \e stdlat1 is not equal \e stdlat2. 104 **********************************************************************/ 105 LambertConformalConic(double a, double f, double stdlat1, double stdlat2, double k1); 106 107 /** 108 * Constructor with two standard parallels specified by sines and cosines. 109 * 110 * @param[in] a equatorial radius of ellipsoid (meters). 111 * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere. 112 * Negative \e f gives a prolate ellipsoid. 113 * @param[in] sinlat1 sine of first standard parallel. 114 * @param[in] coslat1 cosine of first standard parallel. 115 * @param[in] sinlat2 sine of second standard parallel. 116 * @param[in] coslat2 cosine of second standard parallel. 117 * @param[in] k1 scale on the standard parallels. 118 * @exception GeographicErr if \e a, (1 − \e f ) \e a, or \e k1 is 119 * not positive. 120 * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in 121 * [−90°, 90°], or if either \e stdlat1 or \e 122 * stdlat2 is a pole and \e stdlat1 is not equal \e stdlat2. 123 * 124 * This allows parallels close to the poles to be specified accurately. 125 * This routine computes the latitude of origin and the scale at this 126 * latitude. In the case where \e lat1 and \e lat2 are different, the 127 * errors in this routines are as follows: if \e dlat = abs(\e lat2 − 128 * \e lat1) ≤ 160° and max(abs(\e lat1), abs(\e lat2)) ≤ 90 129 * − min(0.0002, 2.2 × 10<sup>−6</sup>(180 − \e 130 * dlat), 6 × 10<sup>−8</sup> <i>dlat</i><sup>2</sup>) (in 131 * degrees), then the error in the latitude of origin is less than 4.5 132 * × 10<sup>−14</sup>d and the relative error in the scale is 133 * less than 7 × 10<sup>−15</sup>. 134 **********************************************************************/ 135 LambertConformalConic(double a, double f, 136 double sinlat1, double coslat1, 137 double sinlat2, double coslat2, 138 double k1); 139 140 /** 141 * The default constructor assumes a Mercator projection. 142 **********************************************************************/ 143 LambertConformalConic(); 144 145 /** 146 * The destructor calls the finalizer. 147 **********************************************************************/ ~LambertConformalConic()148 ~LambertConformalConic() 149 { this->!LambertConformalConic(); } 150 151 /** 152 * Set the scale for the projection. 153 * 154 * @param[in] lat (degrees). 155 * @param[in] k scale at latitude \e lat (default 1). 156 * @exception GeographicErr \e k is not positive. 157 * @exception GeographicErr if \e lat is not in [−90°, 158 * 90°]. 159 **********************************************************************/ 160 void SetScale(double lat, double k); 161 162 /** 163 * Forward projection, from geographic to Lambert conformal conic. 164 * 165 * @param[in] lon0 central meridian longitude (degrees). 166 * @param[in] lat latitude of point (degrees). 167 * @param[in] lon longitude of point (degrees). 168 * @param[out] x easting of point (meters). 169 * @param[out] y northing of point (meters). 170 * @param[out] gamma meridian convergence at point (degrees). 171 * @param[out] k scale of projection at point. 172 * 173 * The latitude origin is given by 174 * LambertConformalConic::LatitudeOrigin(). No false easting or 175 * northing is added and \e lat should be in the range [−90°, 176 * 90°]. The error in the projection is less than about 10 nm (10 177 * nanometers), true distance, and the errors in the meridian 178 * convergence and scale are consistent with this. The values of \e x 179 * and \e y returned for points which project to infinity (i.e., one or 180 * both of the poles) will be large but finite. 181 **********************************************************************/ 182 void Forward(double lon0, double lat, double lon, 183 [System::Runtime::InteropServices::Out] double% x, 184 [System::Runtime::InteropServices::Out] double% y, 185 [System::Runtime::InteropServices::Out] double% gamma, 186 [System::Runtime::InteropServices::Out] double% k); 187 188 /** 189 * Reverse projection, from Lambert conformal conic to geographic. 190 * 191 * @param[in] lon0 central meridian longitude (degrees). 192 * @param[in] x easting of point (meters). 193 * @param[in] y northing of point (meters). 194 * @param[out] lat latitude of point (degrees). 195 * @param[out] lon longitude of point (degrees). 196 * @param[out] gamma meridian convergence at point (degrees). 197 * @param[out] k scale of projection at point. 198 * 199 * The latitude origin is given by 200 * LambertConformalConic::LatitudeOrigin(). No false easting or 201 * northing is added. The value of \e lon returned is in the range 202 * [−180°, 180°). The error in the projection is less 203 * than about 10 nm (10 nanometers), true distance, and the errors in 204 * the meridian convergence and scale are consistent with this. 205 **********************************************************************/ 206 void Reverse(double lon0, double x, double y, 207 [System::Runtime::InteropServices::Out] double% lat, 208 [System::Runtime::InteropServices::Out] double% lon, 209 [System::Runtime::InteropServices::Out] double% gamma, 210 [System::Runtime::InteropServices::Out] double% k); 211 212 /** 213 * LambertConformalConic::Forward without returning the convergence and 214 * scale. 215 **********************************************************************/ 216 void Forward(double lon0, double lat, double lon, 217 [System::Runtime::InteropServices::Out] double% x, 218 [System::Runtime::InteropServices::Out] double% y); 219 220 /** 221 * LambertConformalConic::Reverse without returning the convergence and 222 * scale. 223 **********************************************************************/ 224 void Reverse(double lon0, double x, double y, 225 [System::Runtime::InteropServices::Out] double% lat, 226 [System::Runtime::InteropServices::Out] double% lon); 227 228 /** \name Inspector functions 229 **********************************************************************/ 230 ///@{ 231 /** 232 * @return \e a the equatorial radius of the ellipsoid (meters). This is 233 * the value used in the constructor. 234 **********************************************************************/ 235 property double EquatorialRadius { double get(); } 236 237 /** 238 * @return \e f the flattening of the ellipsoid. This is the 239 * value used in the constructor. 240 **********************************************************************/ 241 property double Flattening { double get(); } 242 243 /** 244 * @return latitude of the origin for the projection (degrees). 245 * 246 * This is the latitude of minimum scale and equals the \e stdlat in the 247 * 1-parallel constructor and lies between \e stdlat1 and \e stdlat2 in the 248 * 2-parallel constructors. 249 **********************************************************************/ 250 property double OriginLatitude { double get(); } 251 252 /** 253 * @return central scale for the projection. This is the scale on the 254 * latitude of origin. 255 **********************************************************************/ 256 property double CentralScale { double get(); } 257 ///@} 258 }; 259 } //namespace NETGeographicLib 260