171 using namespace MSP::CCS;
 
  181 const double PI = 3.14159265358979323e0;
 
  213    const double sourceLongitude,
 
  214    const double sourceLatitude,
 
  215    const double sourceHeight )
 
  258   if (sourceLongitude > 
PI)
 
  259     tLon_in = sourceLongitude - 
TWO_PI;
 
  261     tLon_in = sourceLongitude;
 
  265   sin_Lat = sin(sourceLatitude);
 
  266   cos_Lat = cos(sourceLatitude);
 
  267   sin_Lon = sin(tLon_in);
 
  268   cos_Lon = cos(tLon_in);
 
  269   sin2_Lat = sin_Lat * sin_Lat;
 
  270   w2  = 1.0 - e2 * sin2_Lat;
 
  273   m   = (a * (1.0 - e2)) / w3;
 
  275   dp1 = cos_Lat * dz - sin_Lat * cos_Lon * dx - sin_Lat * sin_Lon * dy;
 
  276   dp2 = ((e2 * sin_Lat * cos_Lat) / w) * da;
 
  277   dp3 = sin_Lat * cos_Lat * (2.0 * n + ep2 * m * sin2_Lat) * (1.0 - f) * df;
 
  278   dp  = (dp1 + dp2 + dp3) / (m + sourceHeight);
 
  279   dl  = (-sin_Lon * dx + cos_Lon * dy) / ((n + sourceHeight) * cos_Lat);
 
  280   dh1 = (cos_Lat * cos_Lon * dx) + (cos_Lat * sin_Lon * dy) + (sin_Lat * dz);
 
  281   dh2 = -(w * da) + ((a * (1 - f)) / w) * sin2_Lat * df;
 
  284   double targetLatitude = sourceLatitude + dp;
 
  285   double targetLongitude = sourceLongitude + dl;
 
  286   double targetHeight = sourceHeight + dh;
 
  288   if (targetLongitude > TWO_PI)
 
  289     targetLongitude -= 
TWO_PI;
 
  290   if (targetLongitude < (- 
PI))
 
  291     targetLongitude += TWO_PI;
 
  317               DatumLibraryImplementation::deleteInstance();
 
  327 int DatumLibraryImplementation::instanceCount = 0;
 
  349   if( --instanceCount < 1 )
 
  356 void DatumLibraryImplementation::deleteInstance()
 
  371   _ellipsoidLibraryImplementation( 0 ),
 
  372   datum3ParamCount( 0 ),
 
  373   datum7ParamCount( 0 )
 
  382   int size = dl.datumList.size();
 
  383   for( 
int i = 0; i < size; i++ )
 
  385     switch( dl.datumList[i]->datumType() )
 
  397           datumList.push_back( 
new Datum( *( dl.datumList[i] ) ) );
 
  402   _ellipsoidLibraryImplementation = dl._ellipsoidLibraryImplementation;
 
  403   datum3ParamCount = dl.datum3ParamCount;
 
  404   datum7ParamCount = dl.datum7ParamCount;
 
  410   std::vector<Datum*>::iterator iter = datumList.begin();
 
  411   while( iter != datumList.end() )
 
  418   _ellipsoidLibraryImplementation = 0;
 
  428   int size = dl.datumList.size();
 
  429   for( 
int i = 0; i < size; i++ )
 
  431      switch( dl.datumList[i]->datumType() )
 
  443            datumList.push_back( 
new Datum( *( dl.datumList[i] ) ) );
 
  448   _ellipsoidLibraryImplementation = dl._ellipsoidLibraryImplementation;
 
  449   datum3ParamCount = dl.datum3ParamCount;
 
  450   datum7ParamCount = dl.datum7ParamCount;
 
  459    const char *ellipsoidCode, 
 
  466    double westLongitude,
 
  467    double eastLongitude,
 
  468    double southLatitude,
 
  469    double northLatitude )
 
  496   long  ellipsoid_index = 0;
 
  497   long  code_length = 0;
 
  498   char *PathName = NULL;
 
  499   FILE *fp_3param = NULL;
 
  501   if (!(((sigmaX > 0.0) || (sigmaX == -1.0)) &&
 
  502         ((sigmaY > 0.0) || (sigmaY == -1.0)) &&
 
  503         ((sigmaZ > 0.0) || (sigmaZ == -1.0))))
 
  514   if (southLatitude >= northLatitude)
 
  516   if((westLongitude >= eastLongitude) &&
 
  517      (westLongitude >= 0 && westLongitude < 180) &&
 
  518      (eastLongitude >= 0 && eastLongitude < 180))
 
  522   bool isNewDatumCode = 
true;
 
  528     isNewDatumCode = 
false;
 
  536   if ( !isNewDatumCode )
 
  539   code_length = strlen( code );
 
  544   if( _ellipsoidLibraryImplementation )
 
  547        ellipsoidCode, &ellipsoid_index );
 
  553   strcpy( datum_Code, code );
 
  555   for( 
long i = 0; i < code_length; i++ )
 
  556     datum_Code[i] = ( 
char )toupper( datum_Code[i] );
 
  558   int numDatums = datumList.size();
 
  560      numDatums, ( 
char* )datum_Code, ( 
char* )ellipsoidCode,
 
  562      westLongitude, eastLongitude, southLatitude, northLatitude, sigmaX,
 
  563      sigmaY, sigmaZ, 
true ) );
 
  573    const char *ellipsoidCode, 
 
  581    double westLongitude,                            
 
  582    double eastLongitude, 
 
  583    double southLatitude, 
 
  584    double northLatitude )
 
  612   long ellipsoid_index = 0;
 
  613   long code_length = 0;
 
  614   char *PathName = NULL;
 
  615   FILE *fp_7param = NULL;
 
  617   if ((rotationX < -60.0) || (rotationX > 60.0))
 
  619   if ((rotationY < -60.0) || (rotationY > 60.0))
 
  621   if ((rotationZ < -60.0) || (rotationZ > 60.0))
 
  624   if ((scale < -0.001) || (scale > 0.001))
 
  628   bool isNewDatumCode = 
true;
 
  634     isNewDatumCode = 
false;
 
  642   if ( !isNewDatumCode )
 
  645   code_length = strlen( code );
 
  649   if( _ellipsoidLibraryImplementation )
 
  652        ellipsoidCode, &ellipsoid_index );
 
  658   strcpy( datum_Code, code );
 
  660   for( i = 0; i < code_length; i++ )
 
  661     datum_Code[i] = ( 
char )toupper( datum_Code[i] );
 
  663   datumList.insert( datumList.begin() + 
MAX_WGS + datum7ParamCount,
 
  666         deltaX, deltaY, deltaZ, 
 
  667         westLongitude, eastLongitude, southLatitude, northLatitude,
 
  690   char *PathName = NULL;
 
  691   FILE *fp_3param = NULL;
 
  692   FILE *fp_7param = NULL;
 
  694   bool delete_3param_datum = 
true;
 
  705     delete_3param_datum = 
false;
 
  712   datumList.erase( datumList.begin() + index ); 
 
  714   if( !delete_3param_datum )
 
  720   else if( delete_3param_datum )
 
  738   *count = datumList.size();
 
  763   length = strlen( code );
 
  768     strcpy( temp_code, code );
 
  771     for( i=0; i < length; i++ )
 
  772       temp_code[i] = ( 
char )toupper( temp_code[i] );
 
  775     while( pos < length )
 
  777       if( isspace( temp_code[pos] ) )
 
  779         for( i=pos; i <= length; i++ )
 
  780           temp_code[i] = temp_code[i+1];
 
  787     int numDatums = datumList.size();
 
  790     while( i < numDatums && strcmp( temp_code, datumList[i]->code() ) )
 
  794     if( i == numDatums || strcmp( temp_code, datumList[i]->code() ) )
 
  812   if( index < 0 || index >= datumList.size() )
 
  815     strcpy( code, datumList[index]->code() );
 
  829   if( index < 0 || index >= datumList.size() )
 
  832     strcpy( name, datumList[index]->name() );
 
  837    const long index, 
char *code )
 
  848   if( index < 0 || index >= datumList.size() )
 
  851     strcpy( code, datumList[index]->ellipsoidCode() );
 
  871   if( index < 0 || index >= datumList.size() )
 
  875     Datum* datum = datumList[index];
 
  880       *sigmaX = threeParameterDatum->
sigmaX();
 
  881       *sigmaY = threeParameterDatum->
sigmaY();
 
  882       *sigmaZ = threeParameterDatum->
sigmaZ();
 
  895    double *scaleFactor )
 
  909   if( index < 0 || index >= datumList.size() )
 
  913     Datum* datum = datumList[index];
 
  919       *rotationX = sevenParameterDatum->
rotationX();
 
  920       *rotationY = sevenParameterDatum->
rotationY();
 
  921       *rotationZ = sevenParameterDatum->
rotationZ();
 
  946   if( index < 0 || index >= datumList.size() )
 
  950     Datum* datum = datumList[index];
 
  952     *deltaX = datum->
deltaX();
 
  953     *deltaY = datum->
deltaY();
 
  954     *deltaZ = datum->
deltaZ();
 
  960    const long      sourceIndex,
 
  961    const long      targetIndex, 
 
  967   double sinlat = sin( latitude );
 
  968   double coslat = cos( latitude );
 
  969   double sinlon = sin( longitude );
 
  970   double coslon = cos( longitude );
 
  971   double sigma_delta_lat;
 
  972   double sigma_delta_lon;
 
  973   double sigma_delta_height;
 
  975   double ce90_in = -1.0;
 
  976   double le90_in = -1.0;
 
  977   double se90_in = -1.0;
 
  978   double ce90_out = -1.0;
 
  979   double le90_out = -1.0;
 
  980   double se90_out = -1.0;
 
  985   int numDatums = datumList.size();
 
  987   if( ( sourceIndex < 0 ) || ( sourceIndex >= numDatums ) )
 
  989   if( ( targetIndex < 0 ) || ( targetIndex >= numDatums ) )
 
  994   if( ( longitude < ( -
PI ) ) || ( longitude > 
TWO_PI ) )
 
  997   if( sourceIndex == targetIndex )
 
  999     circularError90 = circularError90;
 
 1000     linearError90 = linearError90;
 
 1001     sphericalError90 = sphericalError90;
 
 1005     Datum* sourceDatum = datumList[sourceIndex];
 
 1006     Datum* targetDatum = datumList[targetIndex];
 
 1025         if( ( sourceThreeParameterDatum->
sigmaX() < 0 )
 
 1026             || ( sourceThreeParameterDatum->
sigmaY() < 0 )
 
 1027             || ( sourceThreeParameterDatum->
sigmaZ() < 0 ) )
 
 1035           sx = sourceThreeParameterDatum->
sigmaX() * sinlat * coslon;
 
 1036           sy = sourceThreeParameterDatum->
sigmaY() * sinlat * sinlon;
 
 1037           sz = sourceThreeParameterDatum->
sigmaZ() * coslat;
 
 1038           sigma_delta_lat = sqrt( ( sx * sx ) + ( sy * sy ) + ( sz * sz ) );
 
 1040           sx = sourceThreeParameterDatum->
sigmaX() * sinlon;
 
 1041           sy = sourceThreeParameterDatum->
sigmaY() * coslon;
 
 1042           sigma_delta_lon = sqrt( ( sx * sx ) + ( sy * sy ) );
 
 1044           sx = sourceThreeParameterDatum->
sigmaX() * coslat * coslon;
 
 1045           sy = sourceThreeParameterDatum->
sigmaY() * coslat * sinlon;
 
 1046           sz = sourceThreeParameterDatum->
sigmaZ() * sinlat;
 
 1047           sigma_delta_height = sqrt( ( sx * sx ) + ( sy * sy ) + ( sz * sz ) );
 
 1049           ce90_in = 2.146 * ( sigma_delta_lat + sigma_delta_lon ) / 2.0;
 
 1050           le90_in = 1.6449 * sigma_delta_height;
 
 1052              ( sourceThreeParameterDatum->
sigmaX() +
 
 1053                 sourceThreeParameterDatum->
sigmaY() +
 
 1054                 sourceThreeParameterDatum->
sigmaZ() ) / 3.0;
 
 1076         if ((targetThreeParameterDatum->
sigmaX() < 0)
 
 1077             ||(targetThreeParameterDatum->
sigmaY() < 0)
 
 1078             ||(targetThreeParameterDatum->
sigmaZ() < 0))
 
 1086           sx = targetThreeParameterDatum->
sigmaX() * sinlat * coslon;
 
 1087           sy = targetThreeParameterDatum->
sigmaY() * sinlat * sinlon;
 
 1088           sz = targetThreeParameterDatum->
sigmaZ() * coslat;
 
 1089           sigma_delta_lat = sqrt((sx * sx) + (sy * sy) + (sz * sz));
 
 1091           sx = targetThreeParameterDatum->
sigmaX() * sinlon;
 
 1092           sy = targetThreeParameterDatum->
sigmaY() * coslon;
 
 1093           sigma_delta_lon = sqrt( ( sx * sx ) + ( sy * sy ) );
 
 1095           sx = targetThreeParameterDatum->
sigmaX() * coslat * coslon;
 
 1096           sy = targetThreeParameterDatum->
sigmaY() * coslat * sinlon;
 
 1097           sz = targetThreeParameterDatum->
sigmaZ() * sinlat;
 
 1098           sigma_delta_height = sqrt( ( sx * sx ) + ( sy * sy ) + ( sz * sz ) );
 
 1100           ce90_out = 2.146 * ( sigma_delta_lat + sigma_delta_lon ) / 2.0;
 
 1101           le90_out = 1.6449 * sigma_delta_height;
 
 1103              ( targetThreeParameterDatum->
sigmaX() +
 
 1104                 targetThreeParameterDatum->
sigmaY() +
 
 1105                 targetThreeParameterDatum->
sigmaZ() ) / 3.0;
 
 1112     if( ( circularError90 < 0.0 ) || ( ce90_in < 0.0 ) || ( ce90_out < 0.0 ) )
 
 1114       circularError90 = -1.0;
 
 1115       linearError90 = -1.0;
 
 1116       sphericalError90 = -1.0;
 
 1120       circularError90 = sqrt( ( circularError90 * circularError90 ) +
 
 1121          ( ce90_in * ce90_in ) + ( ce90_out * ce90_out ) );
 
 1122       if( circularError90 < 1.0 )
 
 1124         circularError90 = 1.0;
 
 1127       if( ( linearError90 < 0.0 ) || ( le90_in < 0.0 ) || ( le90_out < 0.0 ) )
 
 1129         linearError90 = -1.0;
 
 1130         sphericalError90 = -1.0;
 
 1134         linearError90 = sqrt( ( linearError90 * linearError90 ) +
 
 1135            ( le90_in * le90_in ) + ( le90_out * le90_out ) );
 
 1136         if( linearError90 < 1.0 )
 
 1138           linearError90 = 1.0;
 
 1141         if( ( sphericalError90 < 0.0 )
 
 1142            || ( se90_in < 0.0 )
 
 1143            || ( se90_out < 0.0 ) )
 
 1144           sphericalError90 = -1.0;
 
 1147           sphericalError90 = sqrt( 
 
 1148              ( sphericalError90 * sphericalError90 ) + 
 
 1149              ( se90_in * se90_in ) + ( se90_out * se90_out ) );
 
 1150           if( sphericalError90 < 1.0 )
 
 1152             sphericalError90 = 1.0;
 
 1165   if( linearError90 > 0.0 )
 
 1167      double lePrec = 1.6449 * sigma;
 
 1168      linearError90 = sqrt(
 
 1169         linearError90 * linearError90 + lePrec * lePrec);
 
 1173   if( circularError90 > 0.0 )
 
 1175      double cePrec = 2.146 * sigma;
 
 1176      circularError90 = sqrt(
 
 1177         circularError90 * circularError90 + cePrec * cePrec);
 
 1181   if( sphericalError90 > 0.0 )
 
 1184      double sePrec = 2.5003 * sigma;
 
 1185      sphericalError90 = sqrt( 
 
 1186         sphericalError90 * sphericalError90 + sePrec * sePrec );
 
 1189   return new Accuracy( circularError90, linearError90, sphericalError90 );
 
 1194    const long index, 
long *result )
 
 1209   if( index < 0 || index >= datumList.size() )
 
 1213     Datum* datum = datumList[index];
 
 1248   bool ellipsoid_in_use = 
false;
 
 1250   length = strlen( ellipsoidCode );
 
 1253     strcpy( temp_code, ellipsoidCode );
 
 1256     for( i=0;i<length;i++ )
 
 1257       temp_code[i] = ( 
char )toupper( temp_code[i] );
 
 1260     while( pos < length )
 
 1262       if( isspace( temp_code[pos] ) )
 
 1264         for( i=pos; i<=length; i++ )
 
 1265           temp_code[i] = temp_code[i+1];
 
 1274     int numDatums = datumList.size();
 
 1275     while( ( i < numDatums ) && ( !ellipsoid_in_use ) )
 
 1277       if( strcmp( temp_code, datumList[i]->ellipsoidCode() ) == 0 )
 
 1278         ellipsoid_in_use = 
true;
 
 1283   return ellipsoid_in_use;
 
 1289    double *westLongitude,
 
 1290    double *eastLongitude,
 
 1291    double *southLatitude,
 
 1292    double *northLatitude )
 
 1306   if( index < 0 && index >= datumList.size() )
 
 1310     *westLongitude = datumList[index]->westLongitude();
 
 1311     *eastLongitude = datumList[index]->eastLongitude();
 
 1312     *southLatitude = datumList[index]->southLatitude();
 
 1313     *northLatitude = datumList[index]->northLatitude();
 
 1319    const long   sourceIndex,
 
 1320    const double sourceX,
 
 1321    const double sourceY,
 
 1322    const double sourceZ,
 
 1323    const long   targetIndex )
 
 1341   int numDatums = datumList.size();
 
 1343   if( ( sourceIndex < 0 ) || ( sourceIndex >= numDatums ) )
 
 1345   if( ( targetIndex < 0 ) || ( targetIndex >= numDatums ) )
 
 1348   if( sourceIndex == targetIndex )
 
 1356        sourceIndex, sourceX, sourceY, sourceZ );
 
 1359        wgs84CartesianCoordinates->
x(), wgs84CartesianCoordinates->
y(),
 
 1360        wgs84CartesianCoordinates->
z(), targetIndex );
 
 1362     delete wgs84CartesianCoordinates;
 
 1364     return targetCartesianCoordinates;
 
 1370    const double WGS84X,
 
 1371    const double WGS84Y,
 
 1372    const double WGS84Z,
 
 1373    const long targetIndex )
 
 1389   int numDatums = datumList.size();
 
 1391   if( ( targetIndex < 0 ) || ( targetIndex >= numDatums ) )
 
 1394   Datum* localDatum = datumList[targetIndex];
 
 1400          geocentricShiftWGS84ToWGS72( WGS84X, WGS84Y, WGS84Z );
 
 1402       return wgs72CartesianCoordinates;
 
 1414       double targetX = WGS84X - sevenParameterDatum->
deltaX() - sevenParameterDatum->
rotationZ() * WGS84Y
 
 1417       double targetY = WGS84Y - sevenParameterDatum->
deltaY() + sevenParameterDatum->
rotationZ() * WGS84X
 
 1420       double targetZ = WGS84Z - sevenParameterDatum->
deltaZ() - sevenParameterDatum->
rotationY() * WGS84X
 
 1429       double targetX = WGS84X - threeParameterDatum->
deltaX();
 
 1430       double targetY = WGS84Y - threeParameterDatum->
deltaY();
 
 1431       double targetZ = WGS84Z - threeParameterDatum->
deltaZ();
 
 1442    const long sourceIndex,
 
 1443    const double sourceX,
 
 1444    const double sourceY,
 
 1445    const double sourceZ )
 
 1461   int numDatums = datumList.size();
 
 1463   if( ( sourceIndex < 0 ) || (sourceIndex > numDatums ) )
 
 1466   Datum* localDatum = datumList[sourceIndex];
 
 1472          geocentricShiftWGS72ToWGS84( sourceX, sourceY, sourceZ );
 
 1474       return wgs84CartesianCoordinates;
 
 1484       double wgs84X = sourceX + sevenParameterDatum->
deltaX() + sevenParameterDatum->
rotationZ() * sourceY
 
 1487       double wgs84Y = sourceY + sevenParameterDatum->
deltaY() - sevenParameterDatum->
rotationZ() * sourceX
 
 1490       double wgs84Z = sourceZ + sevenParameterDatum->
deltaZ() + sevenParameterDatum->
rotationY() * sourceX
 
 1499       double wgs84X = sourceX + threeParameterDatum->
deltaX();
 
 1500       double wgs84Y = sourceY + threeParameterDatum->
deltaY();
 
 1501       double wgs84Z = sourceZ + threeParameterDatum->
deltaZ();
 
 1512    const long sourceIndex,
 
 1514    const long targetIndex )
 
 1536   double sourceLongitude = sourceCoordinates->
longitude();
 
 1537   double sourceLatitude = sourceCoordinates->
latitude();
 
 1538   double sourceHeight = sourceCoordinates->
height();
 
 1540   int numDatums = datumList.size();
 
 1542   if( sourceIndex < 0 || sourceIndex >= numDatums )
 
 1544   if( targetIndex < 0 || targetIndex >= numDatums )
 
 1550   if( ( sourceLongitude < ( -
PI )) || ( sourceLongitude > 
TWO_PI ) )
 
 1553   Datum* sourceDatum = datumList[sourceIndex];
 
 1554   Datum* targetDatum = datumList[targetIndex];
 
 1556   if ( sourceIndex == targetIndex )
 
 1563     if( _ellipsoidLibraryImplementation )
 
 1580               sourceCartesianCoordinates->
x(),
 
 1581               sourceCartesianCoordinates->
y(),
 
 1582               sourceCartesianCoordinates->
z(), targetIndex );
 
 1592             delete targetCartesianCoordinates;
 
 1593             delete sourceCartesianCoordinates;
 
 1595             return targetGeodeticCoordinates;
 
 1600               sourceIndex, sourceCartesianCoordinates->
x(),
 
 1601               sourceCartesianCoordinates->
y(), sourceCartesianCoordinates->
z() );
 
 1603            long wgs84EllipsoidIndex;
 
 1604            _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WE", &wgs84EllipsoidIndex );
 
 1606               wgs84EllipsoidIndex, &a, &f );
 
 1615            delete wgs84GeodeticCoordinates;
 
 1616            delete wgs84CartesianCoordinates;
 
 1618            return targetGeodeticCoordinates;
 
 1624             sourceIndex, sourceCoordinates );
 
 1626         long wgs84EllipsoidIndex;
 
 1627         _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WE", &wgs84EllipsoidIndex );
 
 1629            wgs84EllipsoidIndex, &a, &f );
 
 1637               wgs84CartesianCoordinates->
x(),
 
 1638               wgs84CartesianCoordinates->
y(),
 
 1639               wgs84CartesianCoordinates->
z(), targetIndex );
 
 1649         delete targetCartesianCoordinates;
 
 1650         delete wgs84CartesianCoordinates;
 
 1651         delete wgs84GeodeticCoordinates;
 
 1653         return targetGeodeticCoordinates;
 
 1658            sourceIndex, sourceCoordinates );
 
 1661            wgs84GeodeticCoordinates, targetIndex );
 
 1663         delete wgs84GeodeticCoordinates;
 
 1665         return targetGeodeticCoordinates;
 
 1702   double WGS84Longitude = sourceCoordinates->
longitude();
 
 1703   double WGS84Latitude = sourceCoordinates->
latitude();
 
 1704   double WGS84Height = sourceCoordinates->
height();
 
 1706   if( ( targetIndex < 0) || (targetIndex >= datumList.size() ) )
 
 1711   if( ( WGS84Longitude < ( -
PI ) ) || ( WGS84Longitude > 
TWO_PI ) )
 
 1714   Datum* localDatum = datumList[targetIndex];
 
 1719       GeodeticCoordinates* targetGeodeticCoordinates = geodeticShiftWGS84ToWGS72( WGS84Longitude, WGS84Latitude, WGS84Height );
 
 1720       return targetGeodeticCoordinates;
 
 1729       if( _ellipsoidLibraryImplementation )
 
 1734         long wgs84EllipsoidIndex;
 
 1735         _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WE", &wgs84EllipsoidIndex );
 
 1736         _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &WGS84_a, &WGS84_f );
 
 1742           Geocentric geocentricFromGeodetic( WGS84_a, WGS84_f );
 
 1746                 wgs84CartesianCoordinates->
z(), targetIndex );
 
 1749           GeodeticCoordinates* targetGeodeticCoordinates = geocentricToGeodetic.convertToGeodetic( localCartesianCoordinates );
 
 1751           delete localCartesianCoordinates;
 
 1752           delete wgs84CartesianCoordinates;
 
 1754           return targetGeodeticCoordinates;
 
 1760           dx = -( localDatum->
deltaX() );
 
 1761           dy = -( localDatum->
deltaY() );
 
 1762           dz = -( localDatum->
deltaZ() );
 
 1765                            WGS84Longitude, WGS84Latitude, WGS84Height );
 
 1767           return targetGeodeticCoordinates;
 
 1804   double sourceLongitude = sourceCoordinates->
longitude();
 
 1805   double sourceLatitude = sourceCoordinates->
latitude(); 
 
 1806   double sourceHeight = sourceCoordinates->
height();
 
 1808   if( ( sourceIndex < 0 ) || ( sourceIndex >= datumList.size() ) )
 
 1813   if( ( sourceLongitude < ( -
PI ) ) || ( sourceLongitude > 
TWO_PI ) )
 
 1816   Datum* localDatum = datumList[sourceIndex];
 
 1821       return geodeticShiftWGS72ToWGS84( sourceLongitude, sourceLatitude, sourceHeight );
 
 1830       if( _ellipsoidLibraryImplementation )
 
 1845             long wgs84EllipsoidIndex;
 
 1846             _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WE", &wgs84EllipsoidIndex );
 
 1847             _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &WGS84_a, &WGS84_f );
 
 1849             Geocentric geocentricToGeodetic( WGS84_a, WGS84_f );
 
 1852             delete wgs84CartesianCoordinates;
 
 1853             delete localCartesianCoordinates;
 
 1855             return wgs84GeodeticCoordinates;
 
 1859             long wgs84EllipsoidIndex;
 
 1860             _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WE", &wgs84EllipsoidIndex );
 
 1861             _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &WGS84_a, &WGS84_f );
 
 1865             dx = localDatum->
deltaX();
 
 1866             dy = localDatum->
deltaY();
 
 1867             dz = localDatum->
deltaZ();
 
 1871             return wgs84GeodeticCoordinates;
 
 1894   if( index < 0 || index >= datumList.size() )
 
 1897     *datumType = datumList[index]->datumType();
 
 1920   if( ( index < 0 ) || ( index >= datumList.size() ) )
 
 1927   Datum* datum = datumList[index];
 
 1940   if( ( west_longitude < 0 ) || ( east_longitude < 0 ) )
 
 1942     if( west_longitude > east_longitude )
 
 1944       if( west_longitude < 0 )
 
 1945         west_longitude += 
TWO_PI;
 
 1946       if( east_longitude < 0 )
 
 1947         east_longitude += 
TWO_PI;
 
 1952   else if( ( west_longitude > 
PI ) || ( east_longitude > 
PI ) )
 
 1954     if( west_longitude > east_longitude )
 
 1956       if( west_longitude > 
PI )
 
 1957         west_longitude -= 
TWO_PI;
 
 1958       if( east_longitude > 
PI )
 
 1959         east_longitude -= 
TWO_PI;
 
 1969       ( latitude <= datum->northLatitude() ) &&
 
 1970       ( west_longitude <= longitude ) &&
 
 1971       ( longitude <= east_longitude ) )
 
 1993   _ellipsoidLibraryImplementation = __ellipsoidLibraryImplementation;
 
 2002 void DatumLibraryImplementation::loadDatums()
 
 2011   long index = 0, i = 0;
 
 2012   char *PathName = NULL;
 
 2013   char* FileName7 = 0;
 
 2014   FILE *fp_7param = NULL;
 
 2015   FILE *fp_3param = NULL;
 
 2016   char* FileName3 = 0;
 
 2017   const int file_name_length = 23;
 
 2025   PathName = 
"/data/data/com.baesystems.msp.geotrans/lib/";
 
 2026   FileName7 = 
new char[ 80 ];
 
 2027   strcpy( FileName7, PathName );
 
 2028   strcat( FileName7, 
"lib7paramdat.so" );
 
 2030   PathName = getenv( 
"MSPCCS_DATA" );
 
 2031   if (PathName != NULL)
 
 2033     FileName7 = 
new char[ strlen( PathName ) + 13 ];
 
 2034     strcpy( FileName7, PathName );
 
 2035     strcat( FileName7, 
"/" );
 
 2039     FileName7 = 
new char[ file_name_length ];
 
 2040     strcpy( FileName7, 
"../../data/" );
 
 2042   strcat( FileName7, 
"7_param.dat" );
 
 2047   if (( fp_7param = fopen( FileName7, 
"r" ) ) == NULL)
 
 2049     delete [] FileName7;
 
 2052     char message[256] = 
"";
 
 2053     if (NULL == PathName)
 
 2055       strcpy( message, 
"Environment variable undefined: MSPCCS_DATA." );
 
 2060       strcat( message, 
": 7_param.dat\n" );
 
 2068   datumList.push_back( 
new Datum(
 
 2070      0.0, 0.0, 0.0, -
PI, +
PI, -
PI / 2.0, +
PI / 2.0, 
false ) );
 
 2075   datumList.push_back( 
new Datum(
 
 2077      0.0, 0.0, 0.0, -
PI, +
PI, -
PI / 2.0, +
PI / 2.0, 
false ) );
 
 2081     datum7ParamCount = 0;
 
 2083     while ( !feof(fp_7param ) )
 
 2087         bool userDefined = 
false;
 
 2089         if (fscanf(fp_7param, 
"%s ", code) <= 0)
 
 2091            fclose( fp_7param );
 
 2096           if( code[0] == 
'*' )
 
 2100               code[i] = code[i+1];
 
 2105         if (fscanf(fp_7param, 
"\"%32[^\"]\"", name) <= 0)
 
 2117         if( fscanf( fp_7param, 
" %s %lf %lf %lf %lf %lf %lf %lf ",
 
 2118            ellipsoidCode,  &deltaX, &deltaY, &deltaZ,
 
 2119            &rotationX, &rotationY, &rotationZ,  &scaleFactor ) <= 0 )
 
 2121            fclose( fp_7param );
 
 2133              deltaX, deltaY, deltaZ, -
PI, +
PI, -
PI / 2.0, +
PI / 2.0,
 
 2134              rotationX, rotationY, rotationZ, scaleFactor, userDefined ) );
 
 2139     fclose( fp_7param );
 
 2142   PathName = 
"/data/data/com.baesystems.msp.geotrans/lib/";
 
 2143   FileName3 = 
new char[ 80 ];
 
 2144   strcpy( FileName3, PathName );
 
 2145   strcat( FileName3, 
"lib3paramdat.so" );
 
 2147     if (PathName != NULL)
 
 2149        FileName3 = 
new char[ strlen( PathName ) + 13 ];
 
 2150        strcpy( FileName3, PathName );
 
 2151        strcat( FileName3, 
"/" );
 
 2155        FileName3 = 
new char[ file_name_length ];
 
 2156        strcpy( FileName3, 
"../../data/" );
 
 2158     strcat( FileName3, 
"3_param.dat" );
 
 2161     if (( fp_3param = fopen( FileName3, 
"r" ) ) == NULL)
 
 2163        delete [] FileName7;
 
 2165        delete [] FileName3;
 
 2168        char message[256] = 
"";
 
 2170        strcat( message, 
": 3_param.dat\n" );
 
 2174     datum3ParamCount = 0;
 
 2177     while( !feof( fp_3param ) )
 
 2181         bool userDefined = 
false;
 
 2183         if( fscanf( fp_3param, 
"%s ", code ) <= 0 )
 
 2185            fclose( fp_3param );
 
 2190           if( code[0] == 
'*' )
 
 2194               code[i] = code[i+1];
 
 2199         if( fscanf( fp_3param, 
"\"%32[^\"]\"", name) <= 0 )
 
 2209         double eastLongitude;
 
 2210         double westLongitude;
 
 2211         double northLatitude;
 
 2212         double southLatitude;
 
 2214         if( fscanf( fp_3param, 
" %s %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf ",
 
 2215            ellipsoidCode, &deltaX, &sigmaX, &deltaY, &sigmaY, &deltaZ, &sigmaZ, 
 
 2216            &southLatitude, &northLatitude, &westLongitude, &eastLongitude ) <= 0 )
 
 2218            fclose( fp_3param );
 
 2230              deltaX, deltaY, deltaZ, westLongitude, eastLongitude,
 
 2231              southLatitude, northLatitude, sigmaX, sigmaY, sigmaZ,
 
 2238     fclose( fp_3param );
 
 2240   delete [] FileName7;
 
 2242   delete [] FileName3;
 
 2247 void DatumLibraryImplementation::write3ParamFile()
 
 2255   char *PathName = NULL;
 
 2257   FILE *fp_3param = NULL;
 
 2262   PathName = getenv( 
"MSPCCS_DATA" );
 
 2263   if (PathName != NULL)
 
 2265     strcpy( FileName, PathName );
 
 2266     strcat( FileName, 
"/" );
 
 2270     strcpy( FileName, 
"../../data/" );
 
 2272   strcat( FileName, 
"3_param.dat" );
 
 2274   if ((fp_3param = fopen(FileName, 
"w")) == NULL)
 
 2276     char message[256] = 
"";
 
 2277     if (NULL == PathName)
 
 2279       strcpy( message, 
"Environment variable undefined: MSPCCS_DATA." );
 
 2284       strcat( message, 
": 3_param.dat\n" );
 
 2290   long index = 
MAX_WGS + datum7ParamCount;
 
 2291   int size = datumList.size();
 
 2292   while( index < size )
 
 2295     if( _3parameterDatum )
 
 2297       strcpy( datum_name, 
"\"" );
 
 2298       strcat( datum_name, datumList[index]->name());
 
 2299       strcat( datum_name, 
"\"" );
 
 2301         fprintf( fp_3param, 
"*");
 
 2303       fprintf( fp_3param, 
"%-6s  %-33s%-2s %4.0f %4.0f %4.0f %4.0f %5.0f %4.0f %4.0f %4.0f %4.0f %4.0f \n",
 
 2304                _3parameterDatum->
code(),
 
 2307                _3parameterDatum->
deltaX(),
 
 2308                _3parameterDatum->
sigmaX(),
 
 2309                _3parameterDatum->
deltaY(),
 
 2310                _3parameterDatum->
sigmaY(),
 
 2311                _3parameterDatum->
deltaZ(),
 
 2312                _3parameterDatum->
sigmaZ(),
 
 2322   fclose( fp_3param );
 
 2327 void DatumLibraryImplementation::write7ParamFile()
 
 2335   char *PathName = NULL;
 
 2337   FILE *fp_7param = NULL;
 
 2342   PathName = getenv( 
"MSPCCS_DATA" );
 
 2343   if (PathName != NULL)
 
 2345     strcpy( FileName, PathName );
 
 2346     strcat( FileName, 
"/" );
 
 2350     strcpy( FileName, 
"../../data/" );
 
 2352   strcat( FileName, 
"7_param.dat" );
 
 2354   if ((fp_7param = fopen(FileName, 
"w")) == NULL)
 
 2356     char message[256] = 
"";
 
 2357     if (NULL == PathName)
 
 2359       strcpy( message, 
"Environment variable undefined: MSPCCS_DATA." );
 
 2364       strcat( message, 
": 7_param.dat\n" );
 
 2371   int endIndex = datum7ParamCount + 
MAX_WGS;
 
 2372   while( index < endIndex )
 
 2375     if( _7parameterDatum )
 
 2377       strcpy( datum_name, 
"\"" );
 
 2378       strcat( datum_name, datumList[index]->name());
 
 2379       strcat( datum_name, 
"\"" );
 
 2381         fprintf( fp_7param, 
"*");
 
 2383       fprintf( fp_7param, 
"%-6s  %-33s%-2s  %4.0f  %4.0f  %4.0f % 4.3f % 4.3f % 4.3f   % 4.10f \n",
 
 2384                _7parameterDatum->
code(),
 
 2387                _7parameterDatum->
deltaX(),
 
 2388                _7parameterDatum->
deltaY(),
 
 2389                _7parameterDatum->
deltaZ(),
 
 2399   fclose( fp_7param );
 
 2403 GeodeticCoordinates* DatumLibraryImplementation::geodeticShiftWGS84ToWGS72( 
const double WGS84Longitude, 
const double WGS84Latitude, 
const double WGS84Height )
 
 2431   long wgs84EllipsoidIndex;
 
 2432   _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WE", &wgs84EllipsoidIndex );
 
 2433   _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &WGS84_a, &WGS84_f );
 
 2435   long wgs72EllipsoidIndex;
 
 2436   _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WD", &wgs72EllipsoidIndex );
 
 2437   _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs72EllipsoidIndex, &WGS72_a, &WGS72_f );
 
 2439   da = WGS72_a - WGS84_a;
 
 2440   df = WGS72_f - WGS84_f;
 
 2442   sin_Lat = sin(WGS84Latitude);
 
 2443   sin2_Lat = sin_Lat * sin_Lat;
 
 2445   Delta_Lat = (-4.5 * cos(WGS84Latitude)) / (WGS84_a*Q)
 
 2446               + (df * sin(2*WGS84Latitude)) / Q;
 
 2449   Delta_Hgt = -4.5 * sin_Lat + WGS84_a * df * sin2_Lat - da - 1.4;
 
 2451   double wgs72Latitude = WGS84Latitude + Delta_Lat;
 
 2452   double wgs72Longitude = WGS84Longitude + Delta_Lon;
 
 2453   double wgs72Height = WGS84Height + Delta_Hgt;
 
 2460   if (wgs72Longitude > 
PI)
 
 2461     wgs72Longitude -= 
TWO_PI;
 
 2462   if (wgs72Longitude < -
PI)
 
 2463     wgs72Longitude += 
TWO_PI;
 
 2469 GeodeticCoordinates* DatumLibraryImplementation::geodeticShiftWGS72ToWGS84( 
const double WGS72Longitude, 
const double WGS72Latitude, 
const double WGS72Height  )
 
 2497   long wgs84EllipsoidIndex;
 
 2498   _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WE", &wgs84EllipsoidIndex );
 
 2499   _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &WGS84_a, &WGS84_f );
 
 2501   long wgs72EllipsoidIndex;
 
 2502   _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WD", &wgs72EllipsoidIndex );
 
 2503   _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs72EllipsoidIndex, &WGS72_a, &WGS72_f );
 
 2505   da = WGS84_a - WGS72_a;
 
 2506   df = WGS84_f - WGS72_f;
 
 2508   sin_Lat = sin(WGS72Latitude);
 
 2509   sin2_Lat = sin_Lat * sin_Lat;
 
 2511   Delta_Lat = (4.5 * cos(WGS72Latitude)) / (WGS72_a*Q) + (df * sin(2*WGS72Latitude)) / Q;
 
 2514   Delta_Hgt = 4.5 * sin_Lat + WGS72_a * df * sin2_Lat - da + 1.4;
 
 2516   double wgs84Latitude = WGS72Latitude + Delta_Lat;
 
 2517   double wgs84Longitude = WGS72Longitude + Delta_Lon;
 
 2518   double wgs84Height = WGS72Height + Delta_Hgt;
 
 2525   if (wgs84Longitude > 
PI)
 
 2526     wgs84Longitude -= 
TWO_PI;
 
 2527   if (wgs84Longitude < -
PI)
 
 2528     wgs84Longitude += 
TWO_PI;
 
 2534 CartesianCoordinates* DatumLibraryImplementation::geocentricShiftWGS84ToWGS72( 
const double X_WGS84, 
const double Y_WGS84, 
const double Z_WGS84 )
 
 2554   long wgs84EllipsoidIndex;
 
 2555   _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WE", &wgs84EllipsoidIndex );
 
 2556   _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &a_84, &f_84 );
 
 2565   long wgs72EllipsoidIndex;
 
 2566   _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WD", &wgs72EllipsoidIndex );
 
 2567   _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs72EllipsoidIndex, &a_72, &f_72 );
 
 2571   CartesianCoordinates* wgs72GeocentricCoordinates = geocentric72.convertFromGeodetic( wgs72GeodeticCoordinates );
 
 2573   delete wgs72GeodeticCoordinates;
 
 2574   delete wgs84GeodeticCoordinates;
 
 2576   return wgs72GeocentricCoordinates;
 
 2580 CartesianCoordinates* DatumLibraryImplementation::geocentricShiftWGS72ToWGS84( 
const double X, 
const double Y, 
const double Z )
 
 2600   long wgs72EllipsoidIndex;
 
 2601   _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WD", &wgs72EllipsoidIndex );
 
 2602   _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs72EllipsoidIndex, &a_72, &f_72 );
 
 2610   long wgs84EllipsoidIndex;
 
 2611   _ellipsoidLibraryImplementation->
ellipsoidIndex( 
"WE", &wgs84EllipsoidIndex );
 
 2612   _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &a_84, &f_84 );
 
 2615   CartesianCoordinates* wgs84GeocentricCoordinates = geocentric84.convertFromGeodetic( wgs84GeodeticCoordinates );
 
 2617   delete wgs84GeodeticCoordinates;
 
 2618   delete wgs72GeodeticCoordinates;
 
 2620   return wgs84GeocentricCoordinates;