1 /**********************************************************
2  * Version $Id: datum.h 911 2011-02-14 16:38:15Z reklov_w $
3  *********************************************************/
4 #ifndef DATUM_H
5 #define DATUM_H
6 
7 /***************************************************************************/
8 /* RSC IDENTIFIER: Datum
9  *
10  * ABSTRACT
11  *
12  *    This component provides datum shifts for a large collection of local
13  *    datums, WGS72, and WGS84.  A particular datum can be accessed by using its
14  *    standard 5-letter code to find its index in the datum table.  The index
15  *    can then be used to retrieve the name, type, ellipsoid code, and datum
16  *    shift parameters, and to perform shifts to or from that datum.
17  *
18  *    By sequentially retrieving all of the datum codes and/or names, a menu
19  *    of the available datums can be constructed.  The index values resulting
20  *    from selections from this menu can then be used to access the parameters
21  *    of the selected datum, or to perform datum shifts involving that datum.
22  *
23  *    This component supports both 3-parameter local datums, for which only X,
24  *    Y, and Z translations relative to WGS 84 have been defined, and
25  *    7-parameter local datums, for which X, Y, and Z rotations, and a scale
26  *    factor, are also defined.  It also includes entries for WGS 84 (with an
27  *    index of 0), and WGS 72 (with an index of 1), but no shift parameter
28  *    values are defined for these.
29  *
30  *    This component provides datum shift functions for both geocentric and
31  *    geodetic coordinates.  WGS84 is used as an intermediate state when
32  *    shifting from one local datum to another.  When geodetic coordinates are
33  *    given Molodensky's method is used, except near the poles where the 3-step
34  *    step method is used instead.  Specific algorithms are used for shifting
35  *    between WGS72 and WGS84.
36  *
37  *    This component depends on two data files, named 3_param.dat and
38  *    7_param.dat, which contain the datum parameter values.  Copies of these
39  *    files must be located in the directory specified by the value of the
40  *    environment variable "DATUM_DATA", if defined, or else in the current
41  *    directory whenever a program containing this component is executed.
42  *
43  *    Additional datums can be added to these files, either manually or using
44  *    the Create_Datum function.  However, if a large number of datums are
45  *    added, the datum table array sizes in this component will have to be
46  *    increased.
47  *
48  *    This component depends on two other components: the Ellipsoid component
49  *    for access to ellipsoid parameters; and the Geocentric component for
50  *    conversions between geodetic and geocentric coordinates.
51  *
52  * ERROR HANDLING
53  *
54  *    This component checks for input file errors and input parameter errors.
55  *    If an invalid value is found, the error code is combined with the current
56  *    error code using the bitwise or.  This combining allows multiple error
57  *    codes to be returned. The possible error codes are:
58  *
59  *  DATUM_NO_ERROR                  : No errors occurred in function
60  *  DATUM_NOT_INITIALIZED_ERROR     : Datum module has not been initialized
61  *  DATUM_7PARAM_FILE_OPEN_ERROR    : 7 parameter file opening error
62  *  DATUM_7PARAM_FILE_PARSING_ERROR : 7 parameter file structure error
63  *  DATUM_7PARAM_OVERFLOW_ERROR     : 7 parameter table overflow
64  *  DATUM_3PARAM_FILE_OPEN_ERROR    : 3 parameter file opening error
65  *  DATUM_3PARAM_FILE_PARSING_ERROR : 3 parameter file structure error
66  *  DATUM_3PARAM_OVERFLOW_ERROR     : 3 parameter table overflow
67  *  DATUM_INVALID_INDEX_ERROR       : Index out of valid range (less than one
68  *                                      or more than Datum_Count)
69  *  DATUM_INVALID_SRC_INDEX_ERROR   : Source datum index invalid
70  *  DATUM_INVALID_DEST_INDEX_ERROR  : Destination datum index invalid
71  *  DATUM_INVALID_CODE_ERROR        : Datum code not found in table
72  *  DATUM_LAT_ERROR                 : Latitude out of valid range (-90 to 90)
73  *  DATUM_LON_ERROR                 : Longitude out of valid range (-180 to
74  *                                    360)
75  *  DATUM_SIGMA_ERROR               : Standard error values must be positive
76  *                                    (or -1 if unknown)
77  *  DATUM_DOMAIN_ERROR              : Domain of validity not well defined
78  *  DATUM_ELLIPSE_ERROR             : Error in ellipsoid module
79  *  DATUM_NOT_USERDEF_ERROR         : Datum code is not user defined - cannot
80  *                                    be deleted
81  *
82  *
83  * REUSE NOTES
84  *
85  *    Datum is intended for reuse by any application that needs access to
86  *    datum shift parameters relative to WGS 84.
87  *
88  *
89  * REFERENCES
90  *
91  *    Further information on Datum can be found in the Reuse Manual.
92  *
93  *    Datum originated from :  U.S. Army Topographic Engineering Center (USATEC)
94  *                             Geospatial Information Division (GID)
95  *                             7701 Telegraph Road
96  *                             Alexandria, VA  22310-3864
97  *
98  * LICENSES
99  *
100  *    None apply to this component.
101  *
102  * RESTRICTIONS
103  *
104  *    Datum has no restrictions.
105  *
106  * ENVIRONMENT
107  *
108  *    Datum was tested and certified in the following environments:
109  *
110  *    1. Solaris 2.5 with GCC 2.8.1
111  *    2. MS Windows 95 with MS Visual C++ 6
112  *
113  * MODIFICATIONS
114  *
115  *    Date              Description
116  *    ----              -----------
117  *    03/30/97          Original Code
118  *    05/28/99          Added user-definable datums (for JMTK)
119  *                      Added datum domain of validity checking (for JMTK)
120  *                      Added datum shift accuracy calculation (for JMTK)
121  */
122 
123 
124 /***************************************************************************/
125 /*
126  *                              DEFINES
127  */
128 
129 #define DATUM_NO_ERROR                          0x00000
130 #define DATUM_NOT_INITIALIZED_ERROR             0x00001
131 #define DATUM_7PARAM_FILE_OPEN_ERROR            0x00002
132 #define DATUM_7PARAM_FILE_PARSING_ERROR         0x00004
133 #define DATUM_7PARAM_OVERFLOW_ERROR             0x00008
134 #define DATUM_3PARAM_FILE_OPEN_ERROR            0x00010
135 #define DATUM_3PARAM_FILE_PARSING_ERROR         0x00020
136 #define DATUM_3PARAM_OVERFLOW_ERROR             0x00040
137 #define DATUM_INVALID_INDEX_ERROR               0x00080
138 #define DATUM_INVALID_SRC_INDEX_ERROR           0x00100
139 #define DATUM_INVALID_DEST_INDEX_ERROR          0x00200
140 #define DATUM_INVALID_CODE_ERROR                0x00400
141 #define DATUM_LAT_ERROR                         0x00800
142 #define DATUM_LON_ERROR                         0x01000
143 #define DATUM_SIGMA_ERROR                       0x02000
144 #define DATUM_DOMAIN_ERROR                      0x04000
145 #define DATUM_ELLIPSE_ERROR                     0x08000
146 #define DATUM_NOT_USERDEF_ERROR                 0x10000
147 
148 
149 /***************************************************************************/
150 /*
151  *                          GLOBAL DECLARATIONS
152  */
153 typedef enum Datum_Types
154 {
155   Three_Param_Datum,
156   Seven_Param_Datum,
157   WGS84_Datum,
158   WGS72_Datum
159 } Datum_Type; /* different types of datums */
160 
161 
162 /***************************************************************************/
163 /*
164  *                            FUNCTION PROTOTYPES
165  */
166 
167 /* ensure proper linkage to c++ programs */
168 #ifdef __cplusplus
169 extern "C" {
170 #endif
171 
172   long Initialize_Datums_File(const char *File_7Parms, const char *File_3Parms);
173   long Initialize_Datums(void);
174 /*
175  * The function Initialize_Datums creates the datum table from two external
176  * files.  If an error occurs, the initialization stops and an error code is
177  * returned.  This function must be called before any of the other functions
178  * in this component.
179  */
180 
181 
182   long Create_Datum ( const char *Code,
183                       const char *Name,
184                       const char *Ellipsoid_Code,
185                       double Delta_X,
186                       double Delta_Y,
187                       double Delta_Z,
188                       double Sigma_X,
189                       double Sigma_Y,
190                       double Sigma_Z,
191                       double South_latitude,
192                       double North_latitude,
193                       double West_longitude,
194                       double East_longitude);
195 /*
196  *   Code           : 5-letter new datum code.                      (input)
197  *   Name           : Name of the new datum                         (input)
198  *   Ellipsoid_Code : 2-letter code for the associated ellipsoid    (input)
199  *   Delta_X        : X translation to WGS84 in meters              (input)
200  *   Delta_Y        : Y translation to WGS84 in meters              (input)
201  *   Delta_Z        : Z translation to WGS84 in meters              (input)
202  *   Sigma_X        : Standard error in X in meters                 (input)
203  *   Sigma_Y        : Standard error in Y in meters                 (input)
204  *   Sigma_Z        : Standard error in Z in meters                 (input)
205  *   South_latitude : Southern edge of validity rectangle in radians(input)
206  *   North_latitude : Northern edge of validity rectangle in radians(input)
207  *   West_longitude : Western edge of validity rectangle in radians (input)
208  *   East_longitude : Eastern edge of validity rectangle in radians (input)
209  *
210  * The function Create_Datum creates a new local (3-parameter) datum with the
211  * specified code, name, shift values, and standard error values.  If the
212  * datum table has not been initialized, the specified code is already in use,
213  * or a new version of the 3-param.dat file cannot be created, an error code
214  * is returned, otherwise DATUM_NO_ERROR is returned.  Note that the indexes
215  * of all datums in the datum table may be changed by this function.
216  */
217 
218   long Delete_Datum (const char *Code);
219 
220 /*
221  *   Code           : 5-letter datum code.                      (input)
222  *
223  * The function Delete_Datum deletes a local (3-parameter) datum with the
224  * specified code.  If the datum table has not been initialized or a new
225  * version of the 3-param.dat file cannot be created, an error code is returned,
226  * otherwise DATUM_NO_ERROR is returned.  Note that the indexes of all datums
227  * in the datum table may be changed by this function.
228  */
229 
230   long Datum_Uses_Ellipsoid (const char *Code);
231 
232 /*
233  *  The function Datum_Uses_Ellipsoid returns 1 if the ellipsoid is in use by a
234  *  user defined datum.  Otherwise, 0 is returned.
235  *
236  *  Code               : The ellipsoid code being searched for.    (input)
237  */
238 
239   long Datum_Count ( long *Count );
240 /*
241  *  The function Datum_Count returns the number of Datums in the table
242  *  if the table was initialized without error.
243  *
244  *  Count   : number of datums in the datum table                   (output)
245  */
246 
247 
248   long Datum_Index ( const char *Code,
249                      long *Index );
250 /*
251  *  The function Datum_Index returns the index of the datum with the
252  *  specified code.
253  *
254  *  Code    : The datum code being searched for                     (input)
255  *  Index   : The index of the datum in the table with the          (output)
256  *              specified code
257  */
258 
259 
260   long Datum_Code ( const long Index,
261                     char *Code );
262 /*
263  *  The function Datum_Code returns the 5-letter code of the datum
264  *  referenced by index.
265  *
266  *  Index   : The index of a given datum in the datum table         (input)
267  *  Code    : The datum code of the datum referenced by index       (output)
268  */
269 
270 
271   long Datum_Name ( const long Index,
272                     char *Name );
273 /*
274  *  The function Datum_Name returns the name of the datum referenced by
275  *  index.
276  *
277  *  Index   : The index of a given datum in the datum table         (input)
278  *  Name    : The datum name of the datum referenced by index       (output)
279  */
280 
281 
282   long Datum_Ellipsoid_Code ( const long Index,
283                               char *Code );
284 /*
285  *  The function Datum_Ellipsoid_Code returns the 2-letter ellipsoid code
286  *  for the ellipsoid associated with the datum referenced by index.
287  *
288  *  Index   : The index of a given datum in the datum table           (input)
289  *  Code    : The ellisoid code for the ellipsoid associated with the (output)
290  *               datum referenced by index
291  */
292 
293 
294   long Retrieve_Datum_Type ( const long Index,
295                              Datum_Type *Type );
296 /*
297  *  The function Retrieve_Datum_Type returns the type of the datum referenced by
298  *  index.
299  *
300  *  Index   : The index of a given datum in the datum table         (input)
301  *  Type    : The type of the datum referenced by index             (output)
302  */
303 
304 
305   long Datum_Seven_Parameters ( const long Index,
306                                 double *Delta_X,
307                                 double *Delta_Y,
308                                 double *Delta_Z,
309                                 double *Rx,
310                                 double *Ry,
311                                 double *Rz,
312                                 double *Scale_Factor );
313 /*
314  *   The function Datum_Seven_Parameters returns the seven parameters
315  *   for the datum referenced by index.
316  *
317  *    Index      : The index of a given datum in the datum table   (input)
318  *    Delta_X    : X translation in meters                         (output)
319  *    Delta_Y    : Y translation in meters                         (output)
320  *    Delta_Z    : Z translation in meters                         (output)
321  *    Rx         : X rotation in radians                           (output)
322  *    Rx         : Y rotation in radians                           (output)
323  *    Ry         : Z rotation in radians                           (output)
324  *    Scale_Factor : Scale factor                                  (output)
325  */
326 
327 
328   long Datum_Three_Parameters ( const long Index,
329                                 double *Delta_X,
330                                 double *Delta_Y,
331                                 double *Delta_Z);
332 /*
333  *   The function Datum_Three_Parameters returns the three parameters
334  *   for the datum referenced by index.
335  *
336  *    Index      : The index of a given datum in the datum table   (input)
337  *    Delta_X    : X translation in meters                         (output)
338  *    Delta_Y    : Y translation in meters                         (output)
339  *    Delta_Z    : Z translation in meters                         (output)
340  */
341 
342 
343   long Datum_Errors ( const long Index,
344                       double *Sigma_X,
345                       double *Sigma_Y,
346                       double *Sigma_Z);
347 /*
348  *   The function Datum_Errors returns the standard errors in X,Y, & Z
349  *   for the datum referenced by index.
350  *
351  *    Index      : The index of a given datum in the datum table   (input)
352  *    Sigma_X    : Standard error in X in meters                   (output)
353  *    Sigma_Y    : Standard error in Y in meters                   (output)
354  *    Sigma_Z    : Standard error in Z in meters                   (output)
355  */
356 
357 
358   long Datum_Valid_Rectangle ( const long Index,
359                                double *South_latitude,
360                                double *North_latitude,
361                                double *West_longitude,
362                                double *East_longitude);
363 /*
364  *   The function Datum_Valid_Rectangle returns the edges of the validity
365  *   rectangle for the datum referenced by index.
366  *
367  *   Index          : The index of a given datum in the datum table   (input)
368  *   South_latitude : Southern edge of validity rectangle in radians  (input)
369  *   North_latitude : Northern edge of validity rectangle in radians  (input)
370  *   West_longitude : Western edge of validity rectangle in radians   (input)
371  *   East_longitude : Eastern edge of validity rectangle in radians   (input)
372  */
373 
374 
375   long Datum_User_Defined ( const long Index,
376 	                          long *result );
377 
378 /*
379  *    Index    : Index of a given datum in the datum table (input)
380  *    result   : Indicates whether specified datum is user defined (1)
381  *               or not (0)                                (output)
382  *
383  *  The function Get_Datum_User_Defined checks whether or not the specified datum is
384  *  user defined. It returns 1 if the datum is user defined, and returns
385  *  0 otherwise. If index is valid DATUM_NO_ERROR is returned, otherwise
386  *  DATUM_INVALID_INDEX_ERROR is returned.
387  */
388 
389 
390   long Valid_Datum ( const long Index,
391                      double latitude,
392                      double longitude,
393                      long *result );
394 /*
395  *  This function checks whether or not the specified location is within the
396  *  validity rectangle for the specified datum.  It returns zero if the specified
397  *  location is NOT within the validity rectangle, and returns 1 otherwise.
398  *
399  *   Index     : The index of a given datum in the datum table      (input)
400  *   latitude  : Latitude of the location to be checked in radians  (input)
401  *   longitude : Longitude of the location to be checked in radians (input)
402  *   result    : Indicates whether location is inside (1) or outside (0)
403  *               of the validity rectangle of the specified datum   (output)
404  */
405 
406 
407   long Geocentric_Shift_To_WGS84 (const long Index,
408                                   const double X,
409                                   const double Y,
410                                   const double Z,
411                                   double *X_WGS84,
412                                   double *Y_WGS84,
413                                   double *Z_WGS84);
414 /*
415  *  This function shifts a geocentric coordinate (X, Y, Z in meters) relative
416  *  to the datum referenced by index to a geocentric coordinate (X, Y, Z in
417  *  meters) relative to WGS84.
418  *
419  *  Index   : Index of local datum                       (input)
420  *  X       : X coordinate relative to the source datum  (input)
421  *  Y       : Y coordinate relative to the source datum  (input)
422  *  Z       : Z coordinate relative to the source datum  (input)
423  *  X_WGS84 : X coordinate relative to WGS84             (output)
424  *  Y_WGS84 : Y coordinate relative to WGS84             (output)
425  *  Z_WGS84 : Z coordinate relative to WGS84             (output)
426  */
427 
428 
429   long Geocentric_Shift_From_WGS84 (const double X_WGS84,
430                                     const double Y_WGS84,
431                                     const double Z_WGS84,
432                                     const long Index,
433                                     double *X,
434                                     double *Y,
435                                     double *Z);
436 /*
437  *  This function shifts a geocentric coordinate (X, Y, Z in meters) relative
438  *  to WGS84 to a geocentric coordinate (X, Y, Z in meters) relative to the
439  *  local datum referenced by index.
440  *
441  *  X_WGS84 : X coordinate relative to WGS84                 (input)
442  *  Y_WGS84 : Y coordinate relative to WGS84                 (input)
443  *  Z_WGS84 : Z coordinate relative to WGS84                 (input)
444  *  Index   : Index of destination datum                     (input)
445  *  X       : X coordinate relative to the destination datum (output)
446  *  Y       : Y coordinate relative to the destination datum (output)
447  *  Z       : Z coordinate relative to the destination datum (output)
448  */
449 
450 
451   long Geocentric_Datum_Shift ( const long Index_in,
452                                 const double X_in,
453                                 const double Y_in,
454                                 const double Z_in,
455                                 const long Index_out,
456                                 double *X_out,
457                                 double *Y_out,
458                                 double *Z_out);
459 /*
460  *  This function shifts a geocentric coordinate (X, Y, Z in meters) relative
461  *  to the source datum to geocentric coordinate (X, Y, Z in meters) relative
462  *  to the destination datum.
463  *
464  *  Index_in  : Index of source datum                      (input)
465  *  X_in      : X coordinate relative to source datum      (input)
466  *  Y_in      : Y coordinate relative to source datum      (input)
467  *  Z_in      : Z coordinate relative to source datum      (input)
468  *  Index_out : Index of destination datum                 (input)
469  *  X_out     : X coordinate relative to destination datum (output)
470  *  Y_out     : Y coordinate relative to destination datum (output)
471  *  Z_out     : Z coordinate relative to destination datum (output)
472  */
473 
474 
475   long Geodetic_Shift_To_WGS84 (const long Index,
476                                 const double Lat_in,
477                                 const double Lon_in,
478                                 const double Hgt_in,
479                                 double *WGS84_Lat,
480                                 double *WGS84_Lon,
481                                 double *WGS84_Hgt);
482 /*
483  *  This function shifts geodetic coordinates relative to a given source datum
484  *  to geodetic coordinates relative to WGS84.
485  *
486  *  Index     : Index of source datum                                 (input)
487  *  Lat_in    : Latitude in radians relative to source datum          (input)
488  *  Lon_in    : Longitude in radians relative to source datum         (input)
489  *  Hgt_in    : Height in meters relative to source datum's ellipsoid (input)
490  *  WGS84_Lat : Latitude in radians relative to WGS84                 (output)
491  *  WGS84_Lon : Longitude in radians relative to WGS84                (output)
492  *  WGS84_Hgt : Height in meters relative to WGS84 ellipsoid          (output)
493  */
494 
495 
496   long Geodetic_Shift_From_WGS84( const double WGS84_Lat,
497                                   const double WGS84_Lon,
498                                   const double WGS84_Hgt,
499                                   const long Index,
500                                   double *Lat_out,
501                                   double *Lon_out,
502                                   double *Hgt_out);
503 /*
504  *  This function shifts geodetic coordinates relative to a WGS84
505  *  to geodetic coordinates relative to a given local datum.
506  *
507  *  WGS84_Lat : Latitude in radians relative to WGS84                      (input)
508  *  WGS84_Lon : Longitude in radians relative to WGS84                     (input)
509  *  WGS84_Hgt : Height in meters relative to WGS84 ellipsoid               (input)
510  *  Index     : Index of destination datum                                 (input)
511  *  Lat_in    : Latitude in radians relative to destination datum          (output)
512  *  Lon_in    : Longitude in radians relative to destination datum         (output)
513  *  Hgt_in    : Height in meters relative to destination datum's ellipsoid (output)
514  */
515 
516 
517   long Geodetic_Datum_Shift ( const long Index_in,
518                               const double Lat_in,
519                               const double Lon_in,
520                               const double Hgt_in,
521                               const long Index_out,
522                               double *Lat_out,
523                               double *Lon_out,
524                               double *Hgt_out);
525 /*
526  *  This function shifts geodetic coordinates (latitude, longitude in radians
527  *  and height in meters) relative to the source datum to geodetic coordinates
528  *  (latitude, longitude in radians and height in meters) relative to the
529  *  destination datum.
530  *
531  *  Index_in  : Index of source datum                                      (input)
532  *  Lat_in    : Latitude in radians relative to source datum               (input)
533  *  Lon_in    : Longitude in radians relative to source datum              (input)
534  *  Hgt_in    : Height in meters relative to source datum's ellipsoid      (input)
535  *  Index_out : Index of destination datum                                 (input)
536  *  Lat_out   : Latitude in radians relative to destination datum          (output)
537  *  Lon_out   : Longitude in radians relative to destination datum         (output)
538  *  Hgt_out   : Height in meters relative to destination datum's ellipsoid (output)
539  */
540 
541 
542   long Datum_Shift_Error (const long Index_in,
543                           const long Index_out,
544                           double latitude,
545                           double longitude,
546                           double *ce90,
547                           double *le90,
548                           double *se90);
549 /*
550  *  This function returns the 90% horizontal (circular), vertical (linear), and
551  *  spherical errors for a shift from the specified source datum to the
552  *  specified destination datum at the specified location.
553  *
554  *  Index_in  : Index of source datum                                      (input)
555  *  Index_out : Index of destination datum                                 (input)
556  *  latitude  : Latitude of point being converted in radians               (input)
557  *  longitude : Longitude of point being converted in radians              (input)
558  *  ce90      : Combined 90% circular horizontal error in meters           (output)
559  *  le90      : Combined 90% linear vertical error in meters               (output)
560  *  se90      : Combined 90% spherical error in meters                     (output)
561  */
562 
563 
564 #ifdef __cplusplus
565 }
566 #endif
567 
568 #endif /* DATUM_H */
569 
570 
571