UNCLASSIFIED

GeographicTranslator
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Macros
Neys.cpp
Go to the documentation of this file.
1 // CLASSIFICATION: UNCLASSIFIED
2 
3 /***************************************************************************/
4 /* RSC IDENTIFIER: NEYS
5  *
6  * ABSTRACT
7  *
8  * This component provides conversions between Geodetic coordinates
9  * (latitude and longitude in radians) and Ney's (Modified Lambert
10  * Conformal Conic) projection coordinates (easting and northing in meters).
11  *
12  * ERROR HANDLING
13  *
14  * This component checks parameters for valid values. If an invalid value
15  * is found the error code is combined with the current error code using
16  * the bitwise or. This combining allows multiple error codes to be
17  * returned. The possible error codes are:
18  *
19  * NEYS_NO_ERROR : No errors occurred in function
20  * NEYS_LAT_ERROR : Latitude outside of valid range
21  * (-90 to 90 degrees)
22  * NEYS_LON_ERROR : Longitude outside of valid range
23  * (-180 to 360 degrees)
24  * NEYS_EASTING_ERROR : Easting outside of valid range
25  * (depends on ellipsoid and projection
26  * parameters)
27  * NEYS_NORTHING_ERROR : Northing outside of valid range
28  * (depends on ellipsoid and projection
29  * parameters)
30  * NEYS_FIRST_STDP_ERROR : First standard parallel outside of valid
31  * range (71 or 74 degrees)
32  * NEYS_ORIGIN_LAT_ERROR : Origin latitude outside of valid range
33  * (-89 59 59.0 to 89 59 59.0 degrees)
34  * NEYS_CENT_MER_ERROR : Central meridian outside of valid range
35  * (-180 to 360 degrees)
36  * NEYS_A_ERROR : Semi-major axis less than or equal to zero
37  * NEYS_INV_F_ERROR : Inverse flattening outside of valid range
38  * (250 to 350)
39  *
40  *
41  * REUSE NOTES
42  *
43  * NEYS is intended for reuse by any application that performs a Ney's (Modified
44  * Lambert Conformal Conic) projection or its inverse.
45  *
46  * REFERENCES
47  *
48  * Further information on NEYS can be found in the Reuse Manual.
49  *
50  * NEYS originated from:
51  * U.S. Army Topographic Engineering Center
52  * Geospatial Information Division
53  * 7701 Telegraph Road
54  * Alexandria, VA 22310-3864
55  *
56  * LICENSES
57  *
58  * None apply to this component.
59  *
60  * RESTRICTIONS
61  *
62  * NEYS has no restrictions.
63  *
64  * ENVIRONMENT
65  *
66  * NEYS was tested and certified in the following environments:
67  *
68  * 1. Solaris 2.5 with GCC, version 2.8.1
69  * 2. Windows 95 with MS Visual C++, version 6
70  *
71  * MODIFICATIONS
72  *
73  * Date Description
74  * ---- -----------
75  * 8-4-00 Original Code
76  * 3-2-07 Original C++ Code
77  *
78  *
79  *
80  */
81 
82 
83 /***************************************************************************/
84 /*
85  * INCLUDES
86  */
87 
88 #include <math.h>
89 #include "LambertConformalConic.h"
90 #include "Neys.h"
91 #include "NeysParameters.h"
93 #include "GeodeticCoordinates.h"
95 #include "ErrorMessages.h"
96 
97 /*
98  * math.h - Standard C math library
99  * LambertConformalConic2.h - Is used to convert lambert conformal conic coordinates
100  * Neys.h - Is for prototype error checking
101  * MapProjectionCoordinates.h - defines map projection coordinates
102  * GeodeticCoordinates.h - defines geodetic coordinates
103  * CoordinateConversionException.h - Exception handler
104  * ErrorMessages.h - Contains exception messages
105  */
106 
107 
108 using namespace MSP::CCS;
109 
110 
111 /***************************************************************************/
112 /* DEFINES
113  *
114  */
115 
116 const double PI = 3.14159265358979323e0; /* PI */
117 const double PI_OVER_2 = (PI / 2.0);
118 const double PI_OVER_180 = (PI / 180.0);
119 const double TWO_PI = (2.0 * PI);
120 const double SEVENTY_ONE = (71.0 * PI_OVER_180); /* 71 degrees */
121 const double SEVENTY_FOUR = (74.0 * PI_OVER_180); /* 74 degrees */
123 const double MAX_LAT = (89.999444444444444 * PI_OVER_180); /* 89 59 58.0 degrees */
124 
125 
126 /************************************************************************/
127 /* FUNCTIONS
128  *
129  */
130 
131 Neys::Neys( double ellipsoidSemiMajorAxis, double ellipsoidFlattening, double centralMeridian, double originLatitude, double standardParallel, double falseEasting, double falseNorthing ) :
133  lambertConformalConic2( 0 ),
134  Neys_Std_Parallel_1( SEVENTY_ONE ),
135  Neys_Std_Parallel_2( MAX_LAT ),
136  Neys_Origin_Long( 0.0 ),
137  Neys_Origin_Lat( 80.0 * PI_OVER_180 ),
138  Neys_False_Easting( 0.0 ),
139  Neys_False_Northing( 0.0 ),
140  Neys_Delta_Easting( 400000000.0 ),
141  Neys_Delta_Northing( 400000000.0 )
142 {
143 /*
144  * The constructor receives the ellipsoid parameters and
145  * Ney's (Modified Lambert Conformal Conic) projection parameters as inputs, and sets the
146  * corresponding state variables. If any errors occur, an exception is thrown
147  * with a description of the error.
148  *
149  * ellipsoidSemiMajorAxis : Semi-major axis of ellipsoid, in meters (input)
150  * ellipsoidFlattening : Flattening of ellipsoid (input)
151  * centralMeridian : Longitude of origin, in radians (input)
152  * originLatitude : Latitude of origin, in radians (input)
153  * standardParallel : First standard parallel, in radians (input)
154  * falseEasting : False easting, in meters (input)
155  * falseNorthing : False northing, in meters (input)
156  */
157 
158  double epsilon = 1.0e-10;
159  double inv_f = 1 / ellipsoidFlattening;
160 
161  if (ellipsoidSemiMajorAxis <= 0.0)
162  { /* Semi-major axis must be greater than zero */
164  }
165  if ((inv_f < 250) || (inv_f > 350))
166  { /* Inverse flattening must be between 250 and 350 */
168 
169  }
170  if ((originLatitude < -MAX_LAT) || (originLatitude > MAX_LAT))
171  { /* Origin Latitude out of range */
173  }
174  if ((fabs(standardParallel - SEVENTY_ONE) > epsilon) && (fabs(standardParallel - SEVENTY_FOUR) > epsilon))
175  { /* First Standard Parallel invalid */
177  }
178  if ((centralMeridian < -PI) || (centralMeridian > TWO_PI))
179  { /* Origin Longitude out of range */
181  }
182 
183  semiMajorAxis = ellipsoidSemiMajorAxis;
184  flattening = ellipsoidFlattening;
185 
186  Neys_Origin_Lat = originLatitude;
187  if (Neys_Origin_Lat >= 0)
188  {
189  Neys_Std_Parallel_1 = standardParallel;
190  Neys_Std_Parallel_2 = MAX_LAT;
191  }
192  else
193  {
194  Neys_Std_Parallel_1 = -standardParallel;
195  Neys_Std_Parallel_2 = -MAX_LAT;
196  }
197 
198  if (centralMeridian > PI)
199  centralMeridian -= TWO_PI;
200  Neys_Origin_Long = centralMeridian;
201  Neys_False_Easting = falseEasting;
202  Neys_False_Northing = falseNorthing;
203 
204  lambertConformalConic2 = new LambertConformalConic( semiMajorAxis, flattening, Neys_Origin_Long, Neys_Origin_Lat,
205  Neys_Std_Parallel_1, Neys_Std_Parallel_2,
206  Neys_False_Easting, Neys_False_Northing );
207 }
208 
209 
210 Neys::Neys( const Neys &n )
211 {
212  lambertConformalConic2 = new LambertConformalConic( *( n.lambertConformalConic2 ) );
215  Neys_Std_Parallel_1 = n.Neys_Std_Parallel_1;
216  Neys_Std_Parallel_2 = n.Neys_Std_Parallel_2;
217  Neys_Origin_Long = n.Neys_Origin_Long;
218  Neys_Origin_Lat = n.Neys_Origin_Lat;
219  Neys_False_Easting = n.Neys_False_Easting;
220  Neys_False_Northing = n.Neys_False_Northing;
221  Neys_Delta_Easting = n.Neys_Delta_Easting;
222  Neys_Delta_Northing = n.Neys_Delta_Northing;
223 }
224 
225 
227 {
228  delete lambertConformalConic2;
229  lambertConformalConic2 = 0;
230 }
231 
232 
234 {
235  if( this != &n )
236  {
237  lambertConformalConic2->operator=( *n.lambertConformalConic2 );
240  Neys_Std_Parallel_1 = n.Neys_Std_Parallel_1;
241  Neys_Std_Parallel_2 = n.Neys_Std_Parallel_2;
242  Neys_Origin_Long = n.Neys_Origin_Long;
243  Neys_Origin_Lat = n.Neys_Origin_Lat;
244  Neys_False_Easting = n.Neys_False_Easting;
245  Neys_False_Northing = n.Neys_False_Northing;
246  Neys_Delta_Easting = n.Neys_Delta_Easting;
247  Neys_Delta_Northing = n.Neys_Delta_Northing;
248  }
249 
250  return *this;
251 }
252 
253 
255 {
256 /*
257  * The function getParameters returns the current ellipsoid
258  * parameters and Ney's (Modified Lambert Conformal Conic) projection parameters.
259  *
260  * ellipsoidSemiMajorAxis : Semi-major axis of ellipsoid, in meters (output)
261  * ellipsoidFlattening : Flattening of ellipsoid (output)
262  * centralMeridian : Longitude of origin, in radians (output)
263  * originLatitude : Latitude of origin, in radians (output)
264  * standardParallel : First standard parallel, in radians (output)
265  * falseEasting : False easting, in meters (output)
266  * falseNorthing : False northing, in meters (output)
267  */
268 
269  return new NeysParameters( CoordinateType::neys, Neys_Origin_Long, Neys_Origin_Lat, Neys_Std_Parallel_1, Neys_False_Easting, Neys_False_Northing );
270 }
271 
272 
274 {
275 /*
276  * The function convertFromGeodetic converts Geodetic (latitude and
277  * longitude) coordinates to Ney's (Modified Lambert Conformal Conic) projection
278  * (easting and northing) coordinates, according to the current ellipsoid and
279  * Ney's (Modified Lambert Conformal Conic) projection parameters. If any errors
280  * occur, an exception is thrown with a description of the error.
281  *
282  * longitude : Longitude, in radians (input)
283  * latitude : Latitude, in radians (input)
284  * easting : Easting (X), in meters (output)
285  * northing : Northing (Y), in meters (output)
286  */
287 
288  double longitude = geodeticCoordinates->longitude();
289  double latitude = geodeticCoordinates->latitude();
290 
291  if ((latitude < -PI_OVER_2) || (latitude > PI_OVER_2))
292  { /* Latitude out of range */
294  }
295  if ((longitude < -PI) || (longitude > TWO_PI))
296  { /* Longitude out of range */
298  }
299 
300  MapProjectionCoordinates* mapProjectionCoordinates =
301  lambertConformalConic2->convertFromGeodetic( geodeticCoordinates );
302  double easting = mapProjectionCoordinates->easting();
303  double northing = mapProjectionCoordinates->northing();
304  delete mapProjectionCoordinates;
305 
306  return new MapProjectionCoordinates( CoordinateType::neys, easting, northing );
307 }
308 
309 
311  MSP::CCS::MapProjectionCoordinates* mapProjectionCoordinates )
312 {
313 /*
314  * The function convertToGeodetic converts Ney's (Modified Lambert Conformal
315  * Conic) projection (easting and northing) coordinates to Geodetic (latitude)
316  * and longitude) coordinates, according to the current ellipsoid and Ney's
317  * (Modified Lambert Conformal Conic) projection parameters. If any errors
318  * occur, an exception is thrown with a description of the error.
319  *
320  * easting : Easting (X), in meters (input)
321  * northing : Northing (Y), in meters (input)
322  * longitude : Longitude, in radians (output)
323  * latitude : Latitude, in radians (output)
324  */
325 
326  double easting = mapProjectionCoordinates->easting();
327  double northing = mapProjectionCoordinates->northing();
328 
329  if ((easting < (Neys_False_Easting - Neys_Delta_Easting))
330  ||(easting > (Neys_False_Easting + Neys_Delta_Easting)))
331  { /* Easting out of range */
333  }
334  if ((northing < (Neys_False_Northing - Neys_Delta_Northing))
335  || (northing > (Neys_False_Northing + Neys_Delta_Northing)))
336  { /* Northing out of range */
338  }
339 
340  GeodeticCoordinates* geodeticCoordinates =
341  lambertConformalConic2->convertToGeodetic( mapProjectionCoordinates );
342  double longitude = geodeticCoordinates->longitude();
343  double latitude = geodeticCoordinates->latitude();
344  delete geodeticCoordinates;
345 
346  return new GeodeticCoordinates( CoordinateType::geodetic, longitude, latitude );
347 }
348 
349 
350 
351 // CLASSIFICATION: UNCLASSIFIED