UNCLASSIFIED

GeographicTranslator
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Macros
DatumLibrary.cpp
Go to the documentation of this file.
1 // CLASSIFICATION: UNCLASSIFIED
2 
3 /***************************************************************************/
4 /* RSC IDENTIFIER: Datum Library
5  *
6  * ABSTRACT
7  *
8  * This component provides datum shifts for a large collection of local
9  * datums, WGS72, and WGS84. A particular datum can be accessed by using its
10  * standard 5-letter code to find its index in the datum table. The index
11  * can then be used to retrieve the name, type, ellipsoid code, and datum
12  * shift parameters, and to perform shifts to or from that datum.
13  *
14  * By sequentially retrieving all of the datum codes and/or names, a menu
15  * of the available datums can be constructed. The index values resulting
16  * from selections from this menu can then be used to access the parameters
17  * of the selected datum, or to perform datum shifts involving that datum.
18  *
19  * This component supports both 3-parameter local datums, for which only X,
20  * Y, and Z translations relative to WGS 84 have been defined, and
21  * 7-parameter local datums, for which X, Y, and Z rotations, and a scale
22  * factor, are also defined. It also includes entries for WGS 84 (with an
23  * index of 0), and WGS 72 (with an index of 1), but no shift parameter
24  * values are defined for these.
25  *
26  * This component provides datum shift functions for both geocentric and
27  * geodetic coordinates. WGS84 is used as an intermediate state when
28  * shifting from one local datum to another. When geodetic coordinates are
29  * given Molodensky's method is used, except near the poles where the 3-step
30  * step method is used instead. Specific algorithms are used for shifting
31  * between WGS72 and WGS84.
32  *
33  * This component depends on two data files, named 3_param.dat and
34  * 7_param.dat, which contain the datum parameter values. Copies of these
35  * files must be located in the directory specified by the value of the
36  * environment variable "MSPCCS_DATA", if defined, or else in the current
37  * directory whenever a program containing this component is executed.
38  *
39  * Additional datums can be added to these files, either manually or using
40  * the Create_Datum function. However, if a large number of datums are
41  * added, the datum table array sizes in this component will have to be
42  * increased.
43  *
44  * This component depends on two other components: the Ellipsoid component
45  * for access to ellipsoid parameters; and the Geocentric component for
46  * conversions between geodetic and geocentric coordinates.
47  *
48  * ERROR HANDLING
49  *
50  * This component checks for input file errors and input parameter errors.
51  * If an invalid value is found, the error code is combined with the current
52  * error code using the bitwise or. This combining allows multiple error
53  * codes to be returned. The possible error codes are:
54  *
55  * DATUM_NO_ERROR : No errors occurred in function
56  * DATUM_NOT_INITIALIZED_ERROR : Datum module has not been initialized
57  * DATUM_7PARAM_FILE_OPEN_ERROR : 7 parameter file opening error
58  * DATUM_7PARAM_FILE_PARSING_ERROR : 7 parameter file structure error
59  * DATUM_3PARAM_FILE_OPEN_ERROR : 3 parameter file opening error
60  * DATUM_3PARAM_FILE_PARSING_ERROR : 3 parameter file structure error
61  * DATUM_INVALID_INDEX_ERROR : Index out of valid range (less than one
62  * or more than Number_of_Datums)
63  * DATUM_INVALID_SRC_INDEX_ERROR : Source datum index invalid
64  * DATUM_INVALID_DEST_INDEX_ERROR : Destination datum index invalid
65  * DATUM_INVALID_CODE_ERROR : Datum code not found in table
66  * DATUM_LAT_ERROR : Latitude out of valid range (-90 to 90)
67  * DATUM_LON_ERROR : Longitude out of valid range (-180 to
68  * 360)
69  * DATUM_SIGMA_ERROR : Standard error values must be positive
70  * (or -1 if unknown)
71  * DATUM_DOMAIN_ERROR : Domain of validity not well defined
72  * DATUM_ELLIPSE_ERROR : Error in ellipsoid module
73  * DATUM_NOT_USERDEF_ERROR : Datum code is not user defined - cannot
74  * be deleted
75  *
76  *
77  * REUSE NOTES
78  *
79  * Datum is intended for reuse by any application that needs access to
80  * datum shift parameters relative to WGS 84.
81  *
82  *
83  * REFERENCES
84  *
85  * Further information on Datum can be found in the Reuse Manual.
86  *
87  * Datum originated from : U.S. Army Topographic Engineering Center (USATEC)
88  * Geospatial Information Division (GID)
89  * 7701 Telegraph Road
90  * Alexandria, VA 22310-3864
91  *
92  * LICENSES
93  *
94  * None apply to this component.
95  *
96  * RESTRICTIONS
97  *
98  * Datum has no restrictions.
99  *
100  * ENVIRONMENT
101  *
102  * Datum was tested and certified in the following environments:
103  *
104  * 1. Solaris 2.5 with GCC 2.8.1
105  * 2. MS Windows 95 with MS Visual C++ 6
106  *
107  * MODIFICATIONS
108  *
109  * Date Description
110  * ---- -----------
111  * 11/20/08 Original Code
112  * 05/26/10 S. Gillis, BAEts26674, Added Validate Datum API to the
113  * in MSP Geotrans 3.0
114  * 06/04/10 S. Gillis, BAEts26676, Fixed the error always returned
115  * when calling CCS API getDatumParamters
116  * 08/13/12 S. Gillis, MSP_00029654, Added lat/lon to define7ParamDatum
117  */
118 
119 /***************************************************************************/
120 /*
121  * INCLUDES
122  */
123 
124 #include "DatumLibrary.h"
127 #include "ErrorMessages.h"
128 
129 /*
130  * DatumLibrary.h - accesses datum information
131  * DatumLibraryImplementation.h - for prototype error ehecking and error codes
132  */
133 
134 
135 using namespace MSP::CCS;
136 
137 
138 /************************************************************************/
139 /* FUNCTIONS
140  *
141  */
142 
144 {
145 /*
146  * The constructor creates an empty list to store the datum information
147  * contained in two external files, 3_param.dat and 7_param.dat.
148  */
149 
150  _datumLibraryImplementation = __datumLibraryImplementation;
151 }
152 
153 
155 {
156  _datumLibraryImplementation = dl._datumLibraryImplementation;
157 }
158 
159 
161 {
162  _datumLibraryImplementation = 0;
163 }
164 
165 
167 {
168  if ( &dl == this )
169  return *this;
170 
171  _datumLibraryImplementation = dl._datumLibraryImplementation;
172 
173  return *this;
174 }
175 
176 
177 void DatumLibrary::defineDatum( const int datumType, const char *datumCode, const char *datumName, const char *ellipsoidCode,
178  double deltaX, double deltaY, double deltaZ,
179  double sigmaX, double sigmaY, double sigmaZ,
180  double westLongitude, double eastLongitude, double southLatitude, double northLatitude,
181  double rotationX, double rotationY, double rotationZ, double scaleFactor)
182 {
183 /* The function defineDatum creates a new local (3 or 7-parameter) datum with the
184  * specified code, name, shift values, and standard error values or rotation and scale factor values.
185  * If the datum table has not been initialized, the specified code is already in use,
186  * or a new version of the 3-param.dat or 7-param.dat file cannot be created, an
187  * exception is thrown. Note that the indexes
188  * of all datums in the datum table may be changed by this function.
189  *
190  * datumType : Specifies 3 parameter or 7 parameter datum (input)
191  * datumCode : 5-letter new datum code. (input)
192  * datumName : Name of the new datum (input)
193  * ellipsoidCode : 2-letter code for the associated ellipsoid (input)
194  * deltaX : X translation to WGS84 in meters (input)
195  * deltaY : Y translation to WGS84 in meters (input)
196  * deltaZ : Z translation to WGS84 in meters (input)
197  * sigmaX : Standard error in X in meters (input)
198  * sigmaY : Standard error in Y in meters (input)
199  * sigmaZ : Standard error in Z in meters (input)
200  * westLongitude : Western edge of validity rectangle in radians (input)
201  * eastLongitude : Eastern edge of validity rectangle in radians (input)
202  * southLatitude : Southern edge of validity rectangle in radians(input)
203  * northLatitude : Northern edge of validity rectangle in radians(input)
204  * rotationX : X rotation to WGS84 in arc seconds (input)
205  * rotationY : Y rotation to WGS84 in arc seconds (input)
206  * rotationZ : Z rotation to WGS84 in arc seconds (input)
207  * scalefactor : Scale factor (input)
208  *
209  */
210 
211  if( datumType == DatumType::threeParamDatum )
212  {
213  _datumLibraryImplementation->define3ParamDatum( datumCode, datumName, ellipsoidCode,
214  deltaX, deltaY, deltaZ, sigmaX, sigmaY, sigmaZ,
215  westLongitude, eastLongitude, southLatitude, northLatitude );
216  }
217  else if( datumType == DatumType::sevenParamDatum )
218  {
219  _datumLibraryImplementation->define7ParamDatum( datumCode, datumName, ellipsoidCode,
220  deltaX, deltaY, deltaZ, rotationX, rotationY, rotationZ,
221  scaleFactor,westLongitude, eastLongitude,
222  southLatitude, northLatitude );
223  }
224 }
225 
226 
227 void DatumLibrary::removeDatum( const char* code )
228 {
229 /*
230  * The function removeDatum deletes a local (3-parameter) datum with the
231  * specified code. If the datum table has not been initialized or a new
232  * version of the 3-param.dat file cannot be created, an error code is returned,
233  * otherwise DATUM_NO_ERROR is returned. Note that the indexes of all datums
234  * in the datum table may be changed by this function.
235  *
236  * code : 5-letter datum code. (input)
237  *
238  */
239 
240  _datumLibraryImplementation->removeDatum( code );
241 }
242 
243 
244 void DatumLibrary::getDatumCount( long *count )
245 {
246 /*
247  * The function datumCount returns the number of Datums in the table
248  * if the table was initialized without error.
249  *
250  * count : number of datums in the datum table (output)
251  */
252 
253  _datumLibraryImplementation->datumCount( count );
254 }
255 
256 
257 void DatumLibrary::getDatumIndex( const char *code, long *index )
258 {
259 /*
260  * The function datumIndex returns the index of the datum with the
261  * specified code.
262  *
263  * code : The datum code being searched for. (input)
264  * index : The index of the datum in the table with the (output)
265  * specified code.
266  */
267 
268  _datumLibraryImplementation->datumIndex( code, index );
269 }
270 
271 
272 void DatumLibrary::getDatumInfo( const long index, char *code, char *name, char *ellipsoidCode )
273 {
274 /*
275  * The function getDatumInfo returns the 5-letter code, name and
276  * 2-letter ellipsoid code of the datum referenced by index.
277  *
278  * index : The index of a given datum in the datum table. (input)
279  * code : The datum Code of the datum referenced by Index. (output)
280  * name : The datum Name of the datum referenced by Index. (output)
281  * ellipsoidCode : The ellipsoid code for the ellipsoid associated with (output)
282  * the datum referenced by index.
283  */
284 
285  _datumLibraryImplementation->datumCode( index, code );
286  _datumLibraryImplementation->datumName( index, name );
287  _datumLibraryImplementation->datumEllipsoidCode( index, ellipsoidCode );
288 }
289 
290 
291 void DatumLibrary::getDatumParameters( const long index, DatumType::Enum *datumType, double *deltaX, double *deltaY, double *deltaZ,
292  double *sigmaX, double *sigmaY, double *sigmaZ,
293  double *westLongitude, double *eastLongitude, double *southLatitude, double *northLatitude,
294  double *rotationX, double *rotationY, double *rotationZ, double *scaleFactor )
295 {
296 /*
297  * The function getDatumParameters returns the following datum parameters
298  * (specified as output parameters below): datumType, deltaX, deltaY, deltaZ,
299  * sigmaX, sigmaY, sigmaZ, westLongitude, eastLongitude, southLatitude,
300  * northLatitude, rotationX, rotationY, rotationZ, and scaleFactor.
301  *
302  * sigmaX, sigmaY, and sigmaZ only apply to 3 parameter datum and will be
303  * set to 0 if the datum type is a 7 parameter datum.
304  *
305  * rotationX, rotationY, rotationZ, and scaleFactor only apply to 7
306  * parameter datum and will be set to 0 if the datum type is a 3 parameter
307  * datum.
308  *
309  * If the datum type is neither a 3 parameter datum nor a 7 parameter datum,
310  * a CoordinateConversionException will be thrown.
311  *
312  * index : The index of a given datum in the datum table (input)
313  * datumType : Specifies datum type (output)
314  * deltaX : X translation to WGS84 in meters (output)
315  * deltaY : Y translation to WGS84 in meters (output)
316  * deltaZ : Z translation to WGS84 in meters (output)
317  * sigmaX : Standard error in X in meters (output)
318  * sigmaY : Standard error in Y in meters (output)
319  * sigmaZ : Standard error in Z in meters (output)
320  * westLongitude : Western edge of validity rectangle in radians (output)
321  * eastLongitude : Eastern edge of validity rectangle in radians (output)
322  * southLatitude : Southern edge of validity rectangle in radians (output)
323  * northLatitude : Northern edge of validity rectangle in radians (output)
324  * rotationX : X rotation to WGS84 in arc seconds (output)
325  * rotationY : Y rotation to WGS84 in arc seconds (output)
326  * rotationZ : Z rotation to WGS84 in arc seconds (output)
327  * scaleFactor : Scale factor (output)
328  */
329 
330  _datumLibraryImplementation->retrieveDatumType( index, datumType );
331  _datumLibraryImplementation->datumTranslationValues(
332  index, deltaX, deltaY, deltaZ );
333  _datumLibraryImplementation->datumValidRectangle(
334  index, westLongitude, eastLongitude, southLatitude, northLatitude );
335 
336  //If DatumType is DatumType::threeParamDatum
337  if(*datumType == DatumType::threeParamDatum)
338  {
339  _datumLibraryImplementation->datumStandardErrors(
340  index, sigmaX, sigmaY, sigmaZ );
341 
342  //Initialize since they could not be set in datumSevenParameters()
343  *rotationX = 0;
344  *rotationY = 0;
345  *rotationZ = 0;
346  *scaleFactor = 0;
347  }
348  //If DatumType is DatumType::sevenParamDatum
349  else if(*datumType == DatumType::sevenParamDatum)
350  {
351  _datumLibraryImplementation->datumSevenParameters(
352  index, rotationX, rotationY, rotationZ, scaleFactor );
353 
354  //Initialize since they could not be set in datumStandardErrors()
355  *sigmaX = 0;
356  *sigmaY = 0;
357  *sigmaZ = 0;
358  }
359  else
360  {
362  }
363 }
364 
365 
366 void DatumLibrary::getDatumValidRectangle( const long index, double *westLongitude, double *eastLongitude, double *southLatitude, double *northLatitude )
367 {
368 /*
369  * The function datumValidRectangle returns the edges of the validity
370  * rectangle for the datum referenced by index.
371  *
372  * index : The index of a given datum in the datum table (input)
373  * westLongitude : Western edge of validity rectangle in radians (output)
374  * eastLongitude : Eastern edge of validity rectangle in radians (output)
375  * southLatitude : Southern edge of validity rectangle in radians (output)
376  * northLatitude : Northern edge of validity rectangle in radians (output)
377  *
378  */
379 
380  _datumLibraryImplementation->datumValidRectangle( index, westLongitude, eastLongitude, southLatitude, northLatitude );
381 }
382 
383 void DatumLibrary::validDatum( const long index, double longitude,
384  double latitude, long *result )
385 {
386 /*
387  * The function validDatum checks whether or not the specified location
388  * is within the validity rectangle for the specified datum. It returns
389  * zero if the specified location is NOT within the validity rectangle,
390  * and returns 1 otherwise.
391  *
392  * index : The index of a given datum in the datum table (input)
393  * latitude : Latitude of the location to be checked in radians (input)
394  * longitude : Longitude of the location to be checked in radians (input)
395  * result : Indicates whether location is inside (1) or outside (0)
396  * of the validity rectangle of the specified datum (output)
397  */
398 
399  _datumLibraryImplementation->validDatum( index, longitude, latitude, result );
400 }
401 
402 
403 // CLASSIFICATION: UNCLASSIFIED