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