- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# Y:/msp/devkits/temp_geotrans/master/geotrans3.1/CCS/src/dtcc/CoordinateSystems/ellipse/EllipsoidLibraryImplementation.cpp

Go to the documentation of this file.

    00001 // CLASSIFICATION: UNCLASSIFIED
    00002
    00003 /****************************************************************************/
    00004 /* RSC IDENTIFIER:  Ellipsoid Library Implementation
    00005  *
    00006  * ABSTRACT
    00007  *
    00008  *    The purpose of ELLIPSOID is to provide access to ellipsoid parameters
    00009  *    for a collection of common ellipsoids.  A particular ellipsoid can be
    00010  *    accessed by using its standard 2-letter code to find its index in the
    00011  *    ellipsoid table.  The index can then be used to retrieve the ellipsoid
    00012  *    name and parameters.
    00013  *
    00014  *    By sequentially retrieving all of the ellipsoid codes and/or names, a
    00015  *    menu of the available ellipsoids can be constructed.  The index values
    00016  *    resulting from selections from this menu can then be used to access the
    00017  *    parameters of the selected ellipsoid.
    00018  *
    00019  *    This component depends on a data file named "ellips.dat", which contains
    00020  *    the ellipsoid parameter values.  A copy of this file must be located in
    00021  *    the directory specified by the environment variable "MSPCCS_DATA", if
    00022  *    defined, or else in the current directory, whenever a program containing
    00023  *    this component is executed.
    00024  *
    00025  *    Additional ellipsoids can be added to this file, either manually or using
    00026  *    the Create_Ellipsoid function.  However, if a large number of ellipsoids
    00027  *    are added, the ellipsoid table array size in this component will have to
    00028  *    be increased.
    00029  *
    00030  * ERROR HANDLING
    00031  *
    00032  *    This component checks parameters for valid values.  If an invalid value
    00033  *    is found, the error code is combined with the current error code using
    00034  *    the bitwise or.  This combining allows multiple error codes to be
    00035  *    returned. The possible error codes are:
    00036  *
    00037  *  ELLIPSE_NO_ERROR             : No errors occured in function
    00038  *  ELLIPSE_FILE_OPEN_ERROR      : Ellipsoid file opening error
    00039  *  ELLIPSE_INITIALIZE_ERROR     : Ellipsoid table can not initialize
    00040  *  ELLIPSE_TABLE_OVERFLOW_ERROR : Ellipsoid table overflow
    00041  *  ELLIPSE_NOT_INITIALIZED_ERROR: Ellipsoid table not initialized properly
    00042  *  ELLIPSE_INVALID_INDEX_ERROR  : Index is an invalid value
    00043  *  ELLIPSE_INVALID_CODE_ERROR   : Code was not found in table
    00044  *  ELLIPSE_A_ERROR              : Semi-major axis less than or equal to zero
    00045  *  ELLIPSE_INV_F_ERROR          : Inverse flattening outside of valid range
    00046  *                                  (250 to 350)
    00047  *  ELLIPSE_NOT_USERDEF_ERROR    : Ellipsoid is not user defined - cannot be
    00048  *                                  deleted
    00049  *
    00050  * REUSE NOTES
    00051  *
    00052  *    Ellipsoid is intended for reuse by any application that requires Earth
    00053  *    approximating ellipsoids.
    00054  *
    00055  * REFERENCES
    00056  *
    00057  *    Further information on Ellipsoid can be found in the Reuse Manual.
    00058  *
    00059  *    Ellipsoid originated from :  U.S. Army Topographic Engineering Center (USATEC)
    00060  *                                 Geospatial Information Division (GID)
    00061  *                                 7701 Telegraph Road
    00062  *                                 Alexandria, VA  22310-3864
    00063  *
    00064  * LICENSES
    00065  *
    00066  *    None apply to this component.
    00067  *
    00068  * RESTRICTIONS
    00069  *
    00070  *    Ellipsoid has no restrictions.
    00071  *
    00072  * ENVIRONMENT
    00073  *
    00074  *    Ellipsoid was tested and certified in the following environments
    00075  *
    00076  *    1. Solaris 2.5
    00077  *    2. Windows 95
    00078  *
    00079  * MODIFICATIONS
    00080  *
    00081  *    Date              Description
    00082  *    ----              -----------
    00083  *    11-19-95          Original Code
    00084  *    17-Jan-97         Moved local constants out of public interface
    00085  *                      Improved efficiency in algorithms (GEOTRANS)
    00086  *    24-May-99         Added user-defined ellipsoids (GEOTRANS for JMTK)
    00087  *    06-27-06          Moved data file to data directory
    00088  *    03-09-07          Original C++ Code
    00089  *    06-11-10          S. Gillis, BAEts26724, Fixed memory error problem
    00090  *                      when MSPCCS_DATA is not set
    00091  *    07-07-10          K.Lam, BAEts27269, Replace C functions in threads.h
    00092  *                      with C++ methods in classes CCSThreadMutex
    00093  */
    00094
    00095
    00096 /***************************************************************************/
    00097 /*
    00098  *                               INCLUDES
    00099  */
    00100
    00101 #include <stdlib.h>
    00102 #include <ctype.h>
    00103 #include <stdio.h>
    00104 #include <string.h>
    00105 #include "EllipsoidLibraryImplementation.h"
    00106 #include "Ellipsoid.h"
    00107 #include "DatumLibraryImplementation.h"
    00108 #include "CoordinateConversionException.h"
    00109 #include "ErrorMessages.h"
    00110 #include "CCSThreadMutex.h"
    00111 #include "CCSThreadLock.h"
    00112
    00113 /*
    00114  *    ctype.h    - standard C character handling library
    00115  *    stdio.h    - standard C input/output library
    00116  *    stdlib.h   - standard C general utilities library
    00117  *    string.h   - standard C string handling library
    00118  *    DatumLibraryImplementation.h    - used to determine
    00119  *          if user defined ellipsoid is in use by a user defined datum
    00120  *    EllipsoidLibraryImplementation.h  - prototype error checking and error codes
    00121  *    Ellipsoid.h  - used to store individual ellipsoid information
    00122  *    threads.h  - used for thread safety
    00123  *    CoordinateConversionException.h - Exception handler
    00124  *    ErrorMessages.h  - Contains exception messages
    00125  */
    00126
    00127
    00128 using namespace MSP::CCS;
    00129 using MSP::CCSThreadMutex;
    00130 using MSP::CCSThreadLock;
    00131
    00132
    00133 /***************************************************************************/
    00134 /*                               DEFINES
    00135  *
    00136  */
    00137
    00138 const int MAX_ELLIPSOIDS = 32;        /* Maximum number of ellipsoids in table */
    00139 const int ELLIPSOID_CODE_LENGTH = 3;  /* Length of ellipsoid code (including null) */
    00140 const int ELLIPSOID_NAME_LENGTH = 30; /* Max length of ellipsoid name */
    00141 const int ELLIPSOID_BUF = 90;
    00142 const int FILENAME_LENGTH = 128;
    00143 const char *WGS84_Ellipsoid_Code = "WE";
    00144 const char *WGS72_Ellipsoid_Code = "WD";
    00145
    00146
    00147 /************************************************************************/
    00148 /*                              FUNCTIONS
    00149  *
    00150  */
    00151
    00152 /* This class is a safeguard to make sure the singleton gets deleted
    00153  * when the application exits
    00154  */
    00155 class MSP::CCS::EllipsoidLibraryImplementationCleaner
    00156 {
    00157   public:
    00158
    00159   ~EllipsoidLibraryImplementationCleaner()
    00160   {
    00161     CCSThreadLock lock(&EllipsoidLibraryImplementation::mutex);
    00162     EllipsoidLibraryImplementation::deleteInstance();
    00163   }
    00164
    00165 } ellipsoidLibraryImplementationCleanerInstance;
    00166
    00167
    00168 // Make this class a singleton, so the data file is only initialized once
    00169 CCSThreadMutex EllipsoidLibraryImplementation::mutex;
    00170 EllipsoidLibraryImplementation* EllipsoidLibraryImplementation::instance = 0;
    00171 int EllipsoidLibraryImplementation::instanceCount = 0;
    00172
    00173
    00174 EllipsoidLibraryImplementation* EllipsoidLibraryImplementation::getInstance()
    00175 {
    00176   CCSThreadLock lock(&mutex);
    00177   if( instance == 0 )
    00178     instance = new EllipsoidLibraryImplementation;
    00179
    00180   instanceCount++;
    00181
    00182   return instance;
    00183 }
    00184
    00185
    00186 void EllipsoidLibraryImplementation::removeInstance()
    00187 {
    00188 /*
    00189  * The function removeInstance removes this EllipsoidLibraryImplementation instance from the
    00190  * total number of instances.
    00191  */
    00192   CCSThreadLock lock(&mutex);
    00193   if( --instanceCount < 1 )
    00194   {
    00195     deleteInstance();
    00196   }
    00197 }
    00198
    00199
    00200 void EllipsoidLibraryImplementation::deleteInstance()
    00201 {
    00202 /*
    00203  * Delete the singleton.
    00204  */
    00205
    00206   if( instance != 0 )
    00207   {
    00208     delete instance;
    00209     instance = 0;
    00210   }
    00211 }
    00212
    00213
    00214 EllipsoidLibraryImplementation::EllipsoidLibraryImplementation():
    00215   _datumLibraryImplementation( 0 )
    00216 {
    00217 /*
    00218  * The constructor creates an empty list to store the ellipsoid data from ellips.dat
    00219  * which is used to build the ellipsoid table.
    00220  */
    00221
    00222   ellipsoidList.reserve( MAX_ELLIPSOIDS );
    00223
    00224   try
    00225   {
    00226     loadEllipsoids();
    00227   }
    00228   catch(CoordinateConversionException e)
    00229   {
    00230     throw e;
    00231   }
    00232 }
    00233
    00234
    00235 EllipsoidLibraryImplementation::EllipsoidLibraryImplementation( const EllipsoidLibraryImplementation &el )
    00236 {
    00237   int size = el.ellipsoidList.size();
    00238   for( int i = 0; i < size; i++ )
    00239     ellipsoidList.push_back( new Ellipsoid( *( el.ellipsoidList[i] ) ) );
    00240
    00241   _datumLibraryImplementation = el._datumLibraryImplementation;
    00242 }
    00243
    00244
    00245 EllipsoidLibraryImplementation::~EllipsoidLibraryImplementation()
    00246 {
    00247   std::vector<Ellipsoid*>::iterator iter = ellipsoidList.begin();
    00248   while( iter != ellipsoidList.end() )
    00249         {
    00250                 delete( *iter );
    00251     iter++;
    00252         }
    00253   ellipsoidList.clear();
    00254
    00255   _datumLibraryImplementation = 0;
    00256 }
    00257
    00258
    00259 EllipsoidLibraryImplementation& EllipsoidLibraryImplementation::operator=( const EllipsoidLibraryImplementation &el )
    00260 {
    00261   if ( &el == this )
    00262           return *this;
    00263
    00264   int size = el.ellipsoidList.size();
    00265   for( int i = 0; i < size; i++ )
    00266     ellipsoidList[i] = new Ellipsoid( *( el.ellipsoidList[i] ) );
    00267
    00268   _datumLibraryImplementation = el._datumLibraryImplementation;
    00269
    00270   return *this;
    00271 }
    00272
    00273
    00274 void EllipsoidLibraryImplementation::defineEllipsoid( const char* code, const char* name, double semiMajorAxis, double flattening )
    00275 {
    00276 /*
    00277  * The function defineEllipsoid creates a new ellipsoid with the specified
    00278  * Code, name, and axes.  If the ellipsoid table has not been initialized,
    00279  * the specified code is already in use, or a new version of the ellips.dat
    00280  * file cannot be created, an exception is thrown.
    00281  * Note that the indexes of all ellipsoids in the ellipsoid
    00282  * table may be changed by this function.
    00283  *
    00284  *   code           : 2-letter ellipsoid code.                      (input)
    00285  *   name           : Name of the new ellipsoid                     (input)
    00286  *   semiMajorAxis  : Semi-major axis, in meters, of new ellipsoid  (input)
    00287  *   flattening     : Flattening of new ellipsoid.                  (input)
    00288  *
    00289  */
    00290
    00291   long code_length = 0;
    00292   char *PathName = NULL;
    00293   char FileName[FILENAME_LENGTH];
    00294   char ellipsoid_code[ELLIPSOID_CODE_LENGTH];
    00295   FILE *fp = NULL;                    /* File pointer to file ellips.dat     */
    00296   long index = 0;
    00297   long numEllipsoids = ellipsoidList.size();
    00298   double inv_f = 1 / flattening;
    00299
    00300   if( !( numEllipsoids < MAX_ELLIPSOIDS ) )
    00301     throw CoordinateConversionException( ErrorMessages::ellipsoidOverflow );
    00302   else
    00303   {
    00304     try
    00305     {
    00306       ellipsoidIndex( code, &index );
    00307       throw CoordinateConversionException( ErrorMessages::invalidEllipsoidCode );
    00308     }
    00309     catch(CoordinateConversionException e)
    00310     {
    00311     }
    00312
    00313     code_length = strlen( code );
    00314     if( /*( !ellipsoidIndex( code, &index ) ) || */( code_length > ( ELLIPSOID_CODE_LENGTH - 1 ) ) )
    00315       throw CoordinateConversionException( ErrorMessages::invalidEllipsoidCode );
    00316     if( semiMajorAxis <= 0.0 )
    00317       throw CoordinateConversionException( ErrorMessages::semiMajorAxis );
    00318     if( (inv_f < 250 ) || ( inv_f > 350 ) )
    00319     { /* Inverse flattening must be between 250 and 350 */
    00320       throw CoordinateConversionException( ErrorMessages::ellipsoidFlattening );
    00321     }
    00322
    00323     strcpy( ellipsoid_code, code );
    00324     /* Convert code to upper case */
    00325     for( int i = 0; i < code_length; i++ )
    00326       ellipsoid_code[i] = ( char )toupper( ellipsoid_code[i] );
    00327
    00328     double semiMinorAxis = semiMajorAxis * ( 1 - flattening );
    00329     double eccentricitySquared = 2.0 * flattening - flattening * flattening;
    00330     ellipsoidList.push_back( new Ellipsoid( index, ellipsoid_code, ( char* )name, semiMajorAxis, semiMinorAxis, flattening, eccentricitySquared, true ) );
    00331
    00332     numEllipsoids++;
    00333
    00334     CCSThreadLock lock(&mutex);
    00335
    00336     /*output updated ellipsoid table*/
    00337     PathName = getenv( "MSPCCS_DATA" );
    00338     if( PathName != NULL )
    00339     {
    00340       strcpy( FileName, PathName );
    00341       strcat( FileName, "/" );
    00342     }
    00343     else
    00344     {
    00345       strcpy( FileName, "../../data/" );
    00346     }
    00347     strcat( FileName, "ellips.dat" );
    00348
    00349     if( ( fp = fopen( FileName, "w" ) ) == NULL )
    00350     { /* fatal error */
    00351       throw CoordinateConversionException( ErrorMessages::ellipsoidFileOpenError );
    00352     }
    00353
    00354     /* write file */
    00355     index = 0;
    00356     while( index < numEllipsoids )
    00357     {
    00358       if( ellipsoidList[index]->userDefined() )
    00359         fprintf( fp, "*");
    00360
    00361       fprintf( fp, "%-29s  %-2s %11.9f %12.9f %13.13f \n",
    00362                ellipsoidList[index]->name(),
    00363                ellipsoidList[index]->code(),
    00364                ellipsoidList[index]->semiMajorAxis(),
    00365                ellipsoidList[index]->semiMinorAxis(),
    00366                1 / ellipsoidList[index]->flattening() );
    00367       index++;
    00368     }
    00369
    00370     fclose( fp );
    00371   }
    00372 }
    00373
    00374
    00375 void EllipsoidLibraryImplementation::removeEllipsoid( const char* code )
    00376 {
    00377 /*
    00378  * The function removeEllipsoid deletes a user defined ellipsoid with
    00379  * the specified Code.  If the ellipsoid table has not been created,
    00380  * the specified code is in use by a user defined datum, or a new version
    00381  * of the ellips.dat file cannot be created, an exception is thrown.
    00382  * Note that the indexes of all
    00383  * ellipsoids in the ellipsoid table may be changed by this function.
    00384  *
    00385  *   code     : 2-letter ellipsoid code.                      (input)
    00386  *
    00387  */
    00388
    00389   long index = 0;
    00390   char *PathName = NULL;
    00391   char FileName[FILENAME_LENGTH];
    00392   FILE *fp = NULL;                    /* File pointer to file ellips.dat     */
    00393
    00394   ellipsoidIndex( code, &index );
    00395   if( ellipsoidList[index]->userDefined() )
    00396   {
    00397     if( _datumLibraryImplementation )
    00398     {
    00399       if( _datumLibraryImplementation->datumUsesEllipsoid( code ) )
    00400         throw CoordinateConversionException( ErrorMessages::ellipseInUse );
    00401     }
    00402   }
    00403   else
    00404     throw CoordinateConversionException( ErrorMessages::notUserDefined );
    00405
    00406 //  if( /*ellipsoidIndex( code, &index ) ||*/ !ellipsoidList[index]->userDefined() )
    00407 //    throw CoordinateConversionException( ErrorMessages::notUserDefined );
    00408 //  else
    00409   {
    00410     int numEllipsoids = ellipsoidList.size();
    00411
    00412     int i = 0;
    00413     for( i = index; i < numEllipsoids; i++ )
    00414       ellipsoidList[i] = ellipsoidList[i+1];
    00415
    00416     if( numEllipsoids != MAX_ELLIPSOIDS )
    00417       ellipsoidList[i] = ellipsoidList[i+1];
    00418     else
    00419       ellipsoidList.erase( ellipsoidList.end() - 1 );
    00420
    00421     numEllipsoids--;
    00422     ellipsoidList.resize( numEllipsoids );
    00423
    00424     CCSThreadLock lock(&mutex);
    00425
    00426     /*output updated ellipsoid table*/
    00427     PathName = getenv( "MSPCCS_DATA" );
    00428     if( PathName != NULL )
    00429     {
    00430       strcpy( FileName, PathName );
    00431       strcat( FileName, "/" );
    00432     }
    00433     else
    00434     {
    00435       strcpy( FileName, "../../data/" );
    00436     }
    00437     strcat( FileName, "ellips.dat" );
    00438     if( ( fp = fopen( FileName, "w" ) ) == NULL )
    00439     { /* fatal error */
    00440       throw CoordinateConversionException( ErrorMessages::ellipsoidFileOpenError );
    00441     }
    00442     /* write file */
    00443     index = 0;
    00444     while( index < numEllipsoids )
    00445     {
    00446       if( ellipsoidList[index]->userDefined() )
    00447         fprintf( fp, "*" );
    00448
    00449       fprintf(fp, "%-29s  %-2s %11.3f %12.4f %13.9f \n",
    00450                  ellipsoidList[index]->name(),
    00451                  ellipsoidList[index]->code(),
    00452                  ellipsoidList[index]->semiMajorAxis(),
    00453                  ellipsoidList[index]->semiMinorAxis(),
    00454                  1 / ellipsoidList[index]->flattening() );
    00455       index++;
    00456     }
    00457
    00458     fclose( fp );
    00459   }
    00460 }
    00461
    00462
    00463 void EllipsoidLibraryImplementation::ellipsoidCount( long *count )
    00464 {
    00465 /*
    00466  * The function ellipsoidCount returns the number of ellipsoids in the
    00467  * ellipsoid table.  If the ellipsoid table has not been initialized,
    00468  * an exception is thrown.
    00469  *
    00470  *   count    : The number of ellipsoids in the ellipsoid table. (output)
    00471  *
    00472  */
    00473
    00474   *count = ellipsoidList.size();
    00475 }
    00476
    00477
    00478 void EllipsoidLibraryImplementation::ellipsoidIndex( const char *code, long* index )
    00479 {
    00480 /*
    00481  *  The function ellipsoidIndex returns the index of the ellipsoid in
    00482  *  the ellipsoid table with the specified code.  If ellipsoid code is not found,
    00483  *  an exception is thrown.
    00484  *
    00485  *    code     : 2-letter ellipsoid code.                      (input)
    00486  *    index    : Index of the ellipsoid in the ellipsoid table with the
    00487  *                  specified code                             (output)
    00488  *
    00489  */
    00490
    00491   char temp_code[3];
    00492   long i = 0;                   /* index for ellipsoid table */
    00493   long j = 0;
    00494
    00495   while( j < ELLIPSOID_CODE_LENGTH )
    00496   {
    00497     temp_code[j] = ( char )toupper(code[j]);
    00498     j++;
    00499   }
    00500   temp_code[ELLIPSOID_CODE_LENGTH - 1] = 0;
    00501
    00502   int numEllipsoids = ellipsoidList.size();
    00503   while( ( i < numEllipsoids )
    00504          && strcmp( temp_code, ellipsoidList[i]->code() ) )
    00505   {
    00506     i++;
    00507   }
    00508
    00509   if( i == numEllipsoids )
    00510     throw CoordinateConversionException( ErrorMessages::invalidEllipsoidCode );
    00511   else
    00512   {
    00513     if ( strcmp( temp_code, ellipsoidList[i]->code() ) )
    00514       throw CoordinateConversionException( ErrorMessages::invalidEllipsoidCode );
    00515     else
    00516       *index = i;
    00517   }
    00518 }
    00519
    00520
    00521 void EllipsoidLibraryImplementation::ellipsoidCode( const long index, char *code )
    00522 {
    00523 /*
    00524  *  The Function ellipsoidCode returns the 2-letter code for the
    00525  *  ellipsoid in the ellipsoid table with the specified index.  If index is
    00526  *  invalid, an exception is thrown.
    00527  *
    00528  *    index    : Index of a given ellipsoid in the ellipsoid table (input)
    00529  *    code     : 2-letter ellipsoid code.                          (output)
    00530  *
    00531  */
    00532
    00533   strcpy( code, "" );
    00534
    00535   if ( ( index < 0 ) || ( index >= ellipsoidList.size() ) )
    00536     throw CoordinateConversionException( ErrorMessages::invalidIndex );
    00537   else
    00538     strcpy( code, ellipsoidList[index]->code() );
    00539 }
    00540
    00541
    00542 void EllipsoidLibraryImplementation::ellipsoidName( const long index, char *name )
    00543 {
    00544 /*
    00545  *  The function ellipsoidName returns the name of the ellipsoid in
    00546  *  the ellipsoid table with the specified index.  If index is invalid,
    00547  *  an exception is thrown.
    00548  *
    00549  *    index   : Index of a given ellipsoid.in the ellipsoid table with the
    00550  *                 specified index                             (input)
    00551  *    name    : Name of the ellipsoid referencd by index       (output)
    00552  *
    00553  */
    00554
    00555   strcpy( name,"" );
    00556
    00557   if( ( index < 0 ) || ( index >= ellipsoidList.size() ) )
    00558     throw CoordinateConversionException( ErrorMessages::invalidIndex );
    00559   else
    00560     strcpy( name, ellipsoidList[index]->name() );
    00561 }
    00562
    00563
    00564 void EllipsoidLibraryImplementation::ellipsoidParameters( const long index, double *a, double *f )
    00565 {
    00566 /*
    00567  *  The function ellipsoidParameters returns the semi-major axis and flattening
    00568  *  for the ellipsoid with the specified index.  If index is invalid,
    00569  *  exception is thrown.
    00570  *
    00571  *    index    : Index of a given ellipsoid in the ellipsoid table (input)
    00572  *    a        : Semi-major axis, in meters, of ellipsoid          (output)
    00573  *    f        : Flattening of ellipsoid.                          (output)
    00574  *
    00575  */
    00576
    00577   *a = 0;
    00578   *f = 0;
    00579
    00580   if( ( index < 0 ) || ( index >= ellipsoidList.size() ) )
    00581     throw CoordinateConversionException( ErrorMessages::invalidIndex );
    00582   else
    00583   {
    00584     Ellipsoid* ellipsoid = ellipsoidList[index];
    00585     *a = ellipsoid->semiMajorAxis();
    00586     *f = ellipsoid->flattening();
    00587   }
    00588 }
    00589
    00590
    00591 void EllipsoidLibraryImplementation::ellipsoidEccentricity2( const long index, double *eccentricitySquared )
    00592 {
    00593 /*
    00594  *  The function ellipsoidEccentricity2 returns the square of the
    00595  *  eccentricity for the ellipsoid with the specified index.  If index is
    00596  *  invalid, an exception is thrown.
    00597  *
    00598  *    index                : Index of a given ellipsoid in the ellipsoid table (input)
    00599  *    eccentricitySquared  : Square of eccentricity of ellipsoid               (output)
    00600  *
    00601  */
    00602
    00603   *eccentricitySquared = 0;
    00604
    00605   if( ( index < 0 ) || ( index >= ellipsoidList.size() ) )
    00606     throw CoordinateConversionException( ErrorMessages::invalidIndex );
    00607   else
    00608     *eccentricitySquared = ellipsoidList[index]->eccentricitySquared();
    00609 }
    00610
    00611
    00612 void EllipsoidLibraryImplementation::ellipsoidUserDefined( const long index, long *result )
    00613 {
    00614 /*
    00615  *  The function ellipsoidUserDefined returns 1 if the ellipsoid is user
    00616  *  defined.  Otherwise, 0 is returned.  If index is invalid,
    00617  *  an exception is thrown.
    00618  *
    00619  *    index    : Index of a given ellipsoid in the ellipsoid table (input)
    00620  *    result   : Indicates whether specified ellipsoid is user defined (1)
    00621  *               or not (0)                                        (output)
    00622  *
    00623  */
    00624
    00625   *result = false;
    00626
    00627   if( ( index < 0 ) || ( index >= ellipsoidList.size() ) )
    00628     throw CoordinateConversionException( ErrorMessages::invalidIndex );
    00629   else
    00630     *result = ellipsoidList[index]->userDefined();
    00631 }
    00632
    00633
    00634 void EllipsoidLibraryImplementation::setDatumLibraryImplementation( DatumLibraryImplementation* __datumLibraryImplementation )
    00635 {
    00636 /*
    00637  *  The function setDatumLibraryImplementation sets the datum library information
    00638  *  which is needed to ensure a user defined ellipsoid is not in use before being deleted.
    00639  *
    00640  *   __datumLibraryImplementation  : Datum library implementation      (input)
    00641  *
    00642  */
    00643
    00644   _datumLibraryImplementation = __datumLibraryImplementation;
    00645 }
    00646
    00647
    00648 /************************************************************************/
    00649 /*                              PRIVATE FUNCTIONS
    00650  *
    00651  */
    00652
    00653 void EllipsoidLibraryImplementation::loadEllipsoids()
    00654 {
    00655 /*
    00656  * The function loadEllipsoids reads ellipsoid data from ellips.dat
    00657  * and builds the ellipsoid table from it.  If an error occurs, an
    00658  * exception is thrown.
    00659  */
    00660
    00661   char* PathName = NULL;
    00662   char* FileName = 0;
    00663   FILE* fp = NULL;                    /* File pointer to file ellips.dat     */
    00664   char buffer[ELLIPSOID_BUF];
    00665   long index = 0;                     /* Array index                         */
    00666
    00667   CCSThreadLock lock(&mutex);
    00668
    00669   /*  Check the environment for a user provided path, else current directory;   */
    00670   /*  Build a File Name, including specified or default path:                   */
    00671
    00672   PathName = getenv( "MSPCCS_DATA" );
    00673   if (PathName != NULL)
    00674   {
    00675     FileName = new char[ strlen( PathName ) + 12 ];
    00676     strcpy( FileName, PathName );
    00677     strcat( FileName, "/" );
    00678   }
    00679   else
    00680   {
    00681     FileName = new char[ 22 ];
    00682     strcpy( FileName, "../../data/" );
    00683   }
    00684   strcat( FileName, "ellips.dat" );
    00685
    00686   /*  Open the File READONLY, or Return Error Condition:                        */
    00687
    00688   if( ( fp = fopen( FileName, "r" ) ) == NULL )
    00689   {
    00690     delete [] FileName;
    00691     FileName = 0;
    00692
    00693     throw CoordinateConversionException( ErrorMessages::ellipsoidFileOpenError );
    00694   }
    00695
    00696   /* read file */
    00697   while( !feof( fp ) )
    00698   {
    00699     if( index <= MAX_ELLIPSOIDS )
    00700     {
    00701
    00702       if( fgets( buffer, ELLIPSOID_BUF, fp ) )
    00703       {
    00704         char name[ELLIPSOID_NAME_LENGTH];
    00705         char code[ELLIPSOID_CODE_LENGTH];
    00706         double semiMajorAxis;
    00707         double semiMinorAxis;
    00708         double recpF;
    00709
    00710         sscanf( buffer, "%30c %s %lf %lf %lf", name, code,  &semiMajorAxis, &semiMinorAxis, &recpF );
    00711
    00712         bool userDefined = false;  /* Identifies a user defined ellipsoid */
    00713         if( name[0] == '*' )
    00714         {
    00715           userDefined = true;
    00716           for( int i = 0; i < ELLIPSOID_NAME_LENGTH; i++ )
    00717             name[i] = name[i+1];
    00718         }
    00719
    00720         name[ELLIPSOID_NAME_LENGTH - 1] = '\0'; /* null terminate */
    00721
    00722         double flattening = 1 / recpF;
    00723         double eccentricitySquared = 2.0 * flattening - flattening * flattening;
    00724
    00725         ellipsoidList.push_back( new Ellipsoid( index, code, name, semiMajorAxis, semiMinorAxis, flattening, eccentricitySquared, userDefined ) );
    00726
    00727         index++;
    00728       }
    00729     }
    00730     else
    00731       throw CoordinateConversionException( ErrorMessages::ellipsoidOverflow );
    00732   }
    00733
    00734   fclose( fp );
    00735
    00736   delete [] FileName;
    00737   FileName = 0;
    00738 }
    00739
    00740 // CLASSIFICATION: UNCLASSIFIED