172 using namespace MSP::CCS;
182 const double PI = 3.14159265358979323e0;
214 const double sourceLongitude,
215 const double sourceLatitude,
216 const double sourceHeight )
259 if (sourceLongitude >
PI)
260 tLon_in = sourceLongitude -
TWO_PI;
262 tLon_in = sourceLongitude;
266 sin_Lat = sin(sourceLatitude);
267 cos_Lat = cos(sourceLatitude);
268 sin_Lon = sin(tLon_in);
269 cos_Lon = cos(tLon_in);
270 sin2_Lat = sin_Lat * sin_Lat;
271 w2 = 1.0 - e2 * sin2_Lat;
274 m = (a * (1.0 - e2)) / w3;
276 dp1 = cos_Lat * dz - sin_Lat * cos_Lon * dx - sin_Lat * sin_Lon * dy;
277 dp2 = ((e2 * sin_Lat * cos_Lat) / w) * da;
278 dp3 = sin_Lat * cos_Lat * (2.0 * n + ep2 * m * sin2_Lat) * (1.0 - f) * df;
279 dp = (dp1 + dp2 + dp3) / (m + sourceHeight);
280 dl = (-sin_Lon * dx + cos_Lon * dy) / ((n + sourceHeight) * cos_Lat);
281 dh1 = (cos_Lat * cos_Lon * dx) + (cos_Lat * sin_Lon * dy) + (sin_Lat * dz);
282 dh2 = -(w * da) + ((a * (1 - f)) / w) * sin2_Lat * df;
285 double targetLatitude = sourceLatitude + dp;
286 double targetLongitude = sourceLongitude + dl;
287 double targetHeight = sourceHeight + dh;
289 if (targetLongitude > TWO_PI)
290 targetLongitude -=
TWO_PI;
291 if (targetLongitude < (-
PI))
292 targetLongitude += TWO_PI;
318 DatumLibraryImplementation::deleteInstance();
328 int DatumLibraryImplementation::instanceCount = 0;
350 if( --instanceCount < 1 )
357 void DatumLibraryImplementation::deleteInstance()
372 _ellipsoidLibraryImplementation( 0 ),
373 datum3ParamCount( 0 ),
374 datum7ParamCount( 0 )
383 int size = dl.datumList.size();
384 for(
int i = 0; i < size; i++ )
386 switch( dl.datumList[i]->datumType() )
398 datumList.push_back(
new Datum( *( dl.datumList[i] ) ) );
403 _ellipsoidLibraryImplementation = dl._ellipsoidLibraryImplementation;
404 datum3ParamCount = dl.datum3ParamCount;
405 datum7ParamCount = dl.datum7ParamCount;
411 std::vector<Datum*>::iterator iter = datumList.begin();
412 while( iter != datumList.end() )
419 _ellipsoidLibraryImplementation = 0;
429 int size = dl.datumList.size();
430 for(
int i = 0; i < size; i++ )
432 switch( dl.datumList[i]->datumType() )
444 datumList.push_back(
new Datum( *( dl.datumList[i] ) ) );
449 _ellipsoidLibraryImplementation = dl._ellipsoidLibraryImplementation;
450 datum3ParamCount = dl.datum3ParamCount;
451 datum7ParamCount = dl.datum7ParamCount;
460 const char *ellipsoidCode,
467 double westLongitude,
468 double eastLongitude,
469 double southLatitude,
470 double northLatitude )
497 long ellipsoid_index = 0;
498 long code_length = 0;
499 char *PathName = NULL;
500 FILE *fp_3param = NULL;
502 if (!(((sigmaX > 0.0) || (sigmaX == -1.0)) &&
503 ((sigmaY > 0.0) || (sigmaY == -1.0)) &&
504 ((sigmaZ > 0.0) || (sigmaZ == -1.0))))
515 if (southLatitude >= northLatitude)
517 if((westLongitude >= eastLongitude) &&
518 (westLongitude >= 0 && westLongitude < 180) &&
519 (eastLongitude >= 0 && eastLongitude < 180))
523 bool isNewDatumCode =
true;
529 isNewDatumCode =
false;
537 if ( !isNewDatumCode )
540 code_length = strlen( code );
545 if( _ellipsoidLibraryImplementation )
548 ellipsoidCode, &ellipsoid_index );
554 strcpy( datum_Code, code );
556 for(
long i = 0; i < code_length; i++ )
557 datum_Code[i] = (
char )toupper( datum_Code[i] );
559 int numDatums = datumList.size();
561 numDatums, (
char* )datum_Code, (
char* )ellipsoidCode,
563 westLongitude, eastLongitude, southLatitude, northLatitude, sigmaX,
564 sigmaY, sigmaZ,
true ) );
574 const char *ellipsoidCode,
582 double westLongitude,
583 double eastLongitude,
584 double southLatitude,
585 double northLatitude )
613 long ellipsoid_index = 0;
614 long code_length = 0;
615 char *PathName = NULL;
616 FILE *fp_7param = NULL;
618 if ((rotationX < -60.0) || (rotationX > 60.0))
620 if ((rotationY < -60.0) || (rotationY > 60.0))
622 if ((rotationZ < -60.0) || (rotationZ > 60.0))
625 if ((scale < -0.001) || (scale > 0.001))
629 bool isNewDatumCode =
true;
635 isNewDatumCode =
false;
643 if ( !isNewDatumCode )
646 code_length = strlen( code );
650 if( _ellipsoidLibraryImplementation )
653 ellipsoidCode, &ellipsoid_index );
659 strcpy( datum_Code, code );
661 for( i = 0; i < code_length; i++ )
662 datum_Code[i] = (
char )toupper( datum_Code[i] );
664 datumList.insert( datumList.begin() +
MAX_WGS + datum7ParamCount,
667 deltaX, deltaY, deltaZ,
668 westLongitude, eastLongitude, southLatitude, northLatitude,
691 char *PathName = NULL;
692 FILE *fp_3param = NULL;
693 FILE *fp_7param = NULL;
695 bool delete_3param_datum =
true;
706 delete_3param_datum =
false;
713 datumList.erase( datumList.begin() + index );
715 if( !delete_3param_datum )
721 else if( delete_3param_datum )
739 *count = datumList.size();
764 length = strlen( code );
769 strcpy( temp_code, code );
772 for( i=0; i < length; i++ )
773 temp_code[i] = (
char )toupper( temp_code[i] );
776 while( pos < length )
778 if( isspace( temp_code[pos] ) )
780 for( i=pos; i < length; i++ )
781 temp_code[i] = temp_code[i+1];
788 int numDatums = datumList.size();
791 while( i < numDatums && strcmp( temp_code, datumList[i]->code() ) )
795 if( i == numDatums || strcmp( temp_code, datumList[i]->code() ) )
813 if( index < 0 || index >= datumList.size() )
816 strcpy( code, datumList[index]->code() );
830 if( index < 0 || index >= datumList.size() )
833 strcpy( name, datumList[index]->name() );
838 const long index,
char *code )
849 if( index < 0 || index >= datumList.size() )
852 strcpy( code, datumList[index]->ellipsoidCode() );
872 if( index < 0 || index >= datumList.size() )
876 Datum* datum = datumList[index];
881 *sigmaX = threeParameterDatum->
sigmaX();
882 *sigmaY = threeParameterDatum->
sigmaY();
883 *sigmaZ = threeParameterDatum->
sigmaZ();
896 double *scaleFactor )
910 if( index < 0 || index >= datumList.size() )
914 Datum* datum = datumList[index];
920 *rotationX = sevenParameterDatum->
rotationX();
921 *rotationY = sevenParameterDatum->
rotationY();
922 *rotationZ = sevenParameterDatum->
rotationZ();
947 if( index < 0 || index >= datumList.size() )
951 Datum* datum = datumList[index];
953 *deltaX = datum->
deltaX();
954 *deltaY = datum->
deltaY();
955 *deltaZ = datum->
deltaZ();
961 const long sourceIndex,
962 const long targetIndex,
968 double sinlat = sin( latitude );
969 double coslat = cos( latitude );
970 double sinlon = sin( longitude );
971 double coslon = cos( longitude );
972 double sigma_delta_lat;
973 double sigma_delta_lon;
974 double sigma_delta_height;
976 double ce90_in = -1.0;
977 double le90_in = -1.0;
978 double se90_in = -1.0;
979 double ce90_out = -1.0;
980 double le90_out = -1.0;
981 double se90_out = -1.0;
986 int numDatums = datumList.size();
988 if( ( sourceIndex < 0 ) || ( sourceIndex >= numDatums ) )
990 if( ( targetIndex < 0 ) || ( targetIndex >= numDatums ) )
995 if( ( longitude < ( -
PI ) ) || ( longitude >
TWO_PI ) )
998 if( sourceIndex == targetIndex )
1000 circularError90 = circularError90;
1001 linearError90 = linearError90;
1002 sphericalError90 = sphericalError90;
1006 Datum* sourceDatum = datumList[sourceIndex];
1007 Datum* targetDatum = datumList[targetIndex];
1026 if( ( sourceThreeParameterDatum->
sigmaX() < 0 )
1027 || ( sourceThreeParameterDatum->
sigmaY() < 0 )
1028 || ( sourceThreeParameterDatum->
sigmaZ() < 0 ) )
1036 sx = sourceThreeParameterDatum->
sigmaX() * sinlat * coslon;
1037 sy = sourceThreeParameterDatum->
sigmaY() * sinlat * sinlon;
1038 sz = sourceThreeParameterDatum->
sigmaZ() * coslat;
1039 sigma_delta_lat = sqrt( ( sx * sx ) + ( sy * sy ) + ( sz * sz ) );
1041 sx = sourceThreeParameterDatum->
sigmaX() * sinlon;
1042 sy = sourceThreeParameterDatum->
sigmaY() * coslon;
1043 sigma_delta_lon = sqrt( ( sx * sx ) + ( sy * sy ) );
1045 sx = sourceThreeParameterDatum->
sigmaX() * coslat * coslon;
1046 sy = sourceThreeParameterDatum->
sigmaY() * coslat * sinlon;
1047 sz = sourceThreeParameterDatum->
sigmaZ() * sinlat;
1048 sigma_delta_height = sqrt( ( sx * sx ) + ( sy * sy ) + ( sz * sz ) );
1050 ce90_in = 2.146 * ( sigma_delta_lat + sigma_delta_lon ) / 2.0;
1051 le90_in = 1.6449 * sigma_delta_height;
1053 ( sourceThreeParameterDatum->
sigmaX() +
1054 sourceThreeParameterDatum->
sigmaY() +
1055 sourceThreeParameterDatum->
sigmaZ() ) / 3.0;
1077 if ((targetThreeParameterDatum->
sigmaX() < 0)
1078 ||(targetThreeParameterDatum->
sigmaY() < 0)
1079 ||(targetThreeParameterDatum->
sigmaZ() < 0))
1087 sx = targetThreeParameterDatum->
sigmaX() * sinlat * coslon;
1088 sy = targetThreeParameterDatum->
sigmaY() * sinlat * sinlon;
1089 sz = targetThreeParameterDatum->
sigmaZ() * coslat;
1090 sigma_delta_lat = sqrt((sx * sx) + (sy * sy) + (sz * sz));
1092 sx = targetThreeParameterDatum->
sigmaX() * sinlon;
1093 sy = targetThreeParameterDatum->
sigmaY() * coslon;
1094 sigma_delta_lon = sqrt( ( sx * sx ) + ( sy * sy ) );
1096 sx = targetThreeParameterDatum->
sigmaX() * coslat * coslon;
1097 sy = targetThreeParameterDatum->
sigmaY() * coslat * sinlon;
1098 sz = targetThreeParameterDatum->
sigmaZ() * sinlat;
1099 sigma_delta_height = sqrt( ( sx * sx ) + ( sy * sy ) + ( sz * sz ) );
1101 ce90_out = 2.146 * ( sigma_delta_lat + sigma_delta_lon ) / 2.0;
1102 le90_out = 1.6449 * sigma_delta_height;
1104 ( targetThreeParameterDatum->
sigmaX() +
1105 targetThreeParameterDatum->
sigmaY() +
1106 targetThreeParameterDatum->
sigmaZ() ) / 3.0;
1113 if( ( circularError90 < 0.0 ) || ( ce90_in < 0.0 ) || ( ce90_out < 0.0 ) )
1115 circularError90 = -1.0;
1116 linearError90 = -1.0;
1117 sphericalError90 = -1.0;
1121 circularError90 = sqrt( ( circularError90 * circularError90 ) +
1122 ( ce90_in * ce90_in ) + ( ce90_out * ce90_out ) );
1123 if( circularError90 < 1.0 )
1125 circularError90 = 1.0;
1128 if( ( linearError90 < 0.0 ) || ( le90_in < 0.0 ) || ( le90_out < 0.0 ) )
1130 linearError90 = -1.0;
1131 sphericalError90 = -1.0;
1135 linearError90 = sqrt( ( linearError90 * linearError90 ) +
1136 ( le90_in * le90_in ) + ( le90_out * le90_out ) );
1137 if( linearError90 < 1.0 )
1139 linearError90 = 1.0;
1142 if( ( sphericalError90 < 0.0 )
1143 || ( se90_in < 0.0 )
1144 || ( se90_out < 0.0 ) )
1145 sphericalError90 = -1.0;
1148 sphericalError90 = sqrt(
1149 ( sphericalError90 * sphericalError90 ) +
1150 ( se90_in * se90_in ) + ( se90_out * se90_out ) );
1151 if( sphericalError90 < 1.0 )
1153 sphericalError90 = 1.0;
1166 if( linearError90 > 0.0 )
1168 double lePrec = 1.6449 * sigma;
1169 linearError90 = sqrt(
1170 linearError90 * linearError90 + lePrec * lePrec);
1174 if( circularError90 > 0.0 )
1176 double cePrec = 2.146 * sigma;
1177 circularError90 = sqrt(
1178 circularError90 * circularError90 + cePrec * cePrec);
1182 if( sphericalError90 > 0.0 )
1185 double sePrec = 2.5003 * sigma;
1186 sphericalError90 = sqrt(
1187 sphericalError90 * sphericalError90 + sePrec * sePrec );
1190 return new Accuracy( circularError90, linearError90, sphericalError90 );
1195 const long index,
long *result )
1210 if( index < 0 || index >= datumList.size() )
1214 Datum* datum = datumList[index];
1249 bool ellipsoid_in_use =
false;
1251 length = strlen( ellipsoidCode );
1254 strcpy( temp_code, ellipsoidCode );
1257 for( i=0;i<length;i++ )
1258 temp_code[i] = (
char )toupper( temp_code[i] );
1261 while( pos < length )
1263 if( isspace( temp_code[pos] ) )
1265 for( i=pos; i<length; i++ )
1266 temp_code[i] = temp_code[i+1];
1275 int numDatums = datumList.size();
1276 while( ( i < numDatums ) && ( !ellipsoid_in_use ) )
1278 if( strcmp( temp_code, datumList[i]->ellipsoidCode() ) == 0 )
1279 ellipsoid_in_use =
true;
1284 return ellipsoid_in_use;
1290 double *westLongitude,
1291 double *eastLongitude,
1292 double *southLatitude,
1293 double *northLatitude )
1307 if( index < 0 && index >= datumList.size() )
1311 *westLongitude = datumList[index]->westLongitude();
1312 *eastLongitude = datumList[index]->eastLongitude();
1313 *southLatitude = datumList[index]->southLatitude();
1314 *northLatitude = datumList[index]->northLatitude();
1320 const long sourceIndex,
1321 const double sourceX,
1322 const double sourceY,
1323 const double sourceZ,
1324 const long targetIndex )
1342 int numDatums = datumList.size();
1344 if( ( sourceIndex < 0 ) || ( sourceIndex >= numDatums ) )
1346 if( ( targetIndex < 0 ) || ( targetIndex >= numDatums ) )
1349 if( sourceIndex == targetIndex )
1357 sourceIndex, sourceX, sourceY, sourceZ );
1360 wgs84CartesianCoordinates->
x(), wgs84CartesianCoordinates->
y(),
1361 wgs84CartesianCoordinates->
z(), targetIndex );
1363 delete wgs84CartesianCoordinates;
1365 return targetCartesianCoordinates;
1371 const double WGS84X,
1372 const double WGS84Y,
1373 const double WGS84Z,
1374 const long targetIndex )
1390 int numDatums = datumList.size();
1392 if( ( targetIndex < 0 ) || ( targetIndex >= numDatums ) )
1395 Datum* localDatum = datumList[targetIndex];
1401 geocentricShiftWGS84ToWGS72( WGS84X, WGS84Y, WGS84Z );
1403 return wgs72CartesianCoordinates;
1415 double targetX = WGS84X - sevenParameterDatum->
deltaX() - sevenParameterDatum->
rotationZ() * WGS84Y
1418 double targetY = WGS84Y - sevenParameterDatum->
deltaY() + sevenParameterDatum->
rotationZ() * WGS84X
1421 double targetZ = WGS84Z - sevenParameterDatum->
deltaZ() - sevenParameterDatum->
rotationY() * WGS84X
1430 double targetX = WGS84X - threeParameterDatum->
deltaX();
1431 double targetY = WGS84Y - threeParameterDatum->
deltaY();
1432 double targetZ = WGS84Z - threeParameterDatum->
deltaZ();
1443 const long sourceIndex,
1444 const double sourceX,
1445 const double sourceY,
1446 const double sourceZ )
1462 int numDatums = datumList.size();
1464 if( ( sourceIndex < 0 ) || (sourceIndex > numDatums ) )
1467 Datum* localDatum = datumList[sourceIndex];
1473 geocentricShiftWGS72ToWGS84( sourceX, sourceY, sourceZ );
1475 return wgs84CartesianCoordinates;
1485 double wgs84X = sourceX + sevenParameterDatum->
deltaX() + sevenParameterDatum->
rotationZ() * sourceY
1488 double wgs84Y = sourceY + sevenParameterDatum->
deltaY() - sevenParameterDatum->
rotationZ() * sourceX
1491 double wgs84Z = sourceZ + sevenParameterDatum->
deltaZ() + sevenParameterDatum->
rotationY() * sourceX
1500 double wgs84X = sourceX + threeParameterDatum->
deltaX();
1501 double wgs84Y = sourceY + threeParameterDatum->
deltaY();
1502 double wgs84Z = sourceZ + threeParameterDatum->
deltaZ();
1513 const long sourceIndex,
1515 const long targetIndex )
1537 double sourceLongitude = sourceCoordinates->
longitude();
1538 double sourceLatitude = sourceCoordinates->
latitude();
1539 double sourceHeight = sourceCoordinates->
height();
1541 int numDatums = datumList.size();
1543 if( sourceIndex < 0 || sourceIndex >= numDatums )
1545 if( targetIndex < 0 || targetIndex >= numDatums )
1551 if( ( sourceLongitude < ( -
PI )) || ( sourceLongitude >
TWO_PI ) )
1554 Datum* sourceDatum = datumList[sourceIndex];
1555 Datum* targetDatum = datumList[targetIndex];
1557 if ( sourceIndex == targetIndex )
1564 if( _ellipsoidLibraryImplementation )
1581 sourceCartesianCoordinates->
x(),
1582 sourceCartesianCoordinates->
y(),
1583 sourceCartesianCoordinates->
z(), targetIndex );
1593 delete targetCartesianCoordinates;
1594 delete sourceCartesianCoordinates;
1596 return targetGeodeticCoordinates;
1601 sourceIndex, sourceCartesianCoordinates->
x(),
1602 sourceCartesianCoordinates->
y(), sourceCartesianCoordinates->
z() );
1604 long wgs84EllipsoidIndex;
1605 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WE", &wgs84EllipsoidIndex );
1607 wgs84EllipsoidIndex, &a, &f );
1616 delete wgs84GeodeticCoordinates;
1617 delete wgs84CartesianCoordinates;
1619 return targetGeodeticCoordinates;
1625 sourceIndex, sourceCoordinates );
1627 long wgs84EllipsoidIndex;
1628 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WE", &wgs84EllipsoidIndex );
1630 wgs84EllipsoidIndex, &a, &f );
1638 wgs84CartesianCoordinates->
x(),
1639 wgs84CartesianCoordinates->
y(),
1640 wgs84CartesianCoordinates->
z(), targetIndex );
1650 delete targetCartesianCoordinates;
1651 delete wgs84CartesianCoordinates;
1652 delete wgs84GeodeticCoordinates;
1654 return targetGeodeticCoordinates;
1659 sourceIndex, sourceCoordinates );
1662 wgs84GeodeticCoordinates, targetIndex );
1664 delete wgs84GeodeticCoordinates;
1666 return targetGeodeticCoordinates;
1703 double WGS84Longitude = sourceCoordinates->
longitude();
1704 double WGS84Latitude = sourceCoordinates->
latitude();
1705 double WGS84Height = sourceCoordinates->
height();
1707 if( ( targetIndex < 0) || (targetIndex >= datumList.size() ) )
1712 if( ( WGS84Longitude < ( -
PI ) ) || ( WGS84Longitude >
TWO_PI ) )
1715 Datum* localDatum = datumList[targetIndex];
1720 GeodeticCoordinates* targetGeodeticCoordinates = geodeticShiftWGS84ToWGS72( WGS84Longitude, WGS84Latitude, WGS84Height );
1721 return targetGeodeticCoordinates;
1730 if( _ellipsoidLibraryImplementation )
1735 long wgs84EllipsoidIndex;
1736 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WE", &wgs84EllipsoidIndex );
1737 _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &WGS84_a, &WGS84_f );
1743 Geocentric geocentricFromGeodetic( WGS84_a, WGS84_f );
1747 wgs84CartesianCoordinates->
z(), targetIndex );
1750 GeodeticCoordinates* targetGeodeticCoordinates = geocentricToGeodetic.convertToGeodetic( localCartesianCoordinates );
1752 delete localCartesianCoordinates;
1753 delete wgs84CartesianCoordinates;
1755 return targetGeodeticCoordinates;
1761 dx = -( localDatum->
deltaX() );
1762 dy = -( localDatum->
deltaY() );
1763 dz = -( localDatum->
deltaZ() );
1766 WGS84Longitude, WGS84Latitude, WGS84Height );
1768 return targetGeodeticCoordinates;
1805 double sourceLongitude = sourceCoordinates->
longitude();
1806 double sourceLatitude = sourceCoordinates->
latitude();
1807 double sourceHeight = sourceCoordinates->
height();
1809 if( ( sourceIndex < 0 ) || ( sourceIndex >= datumList.size() ) )
1814 if( ( sourceLongitude < ( -
PI ) ) || ( sourceLongitude >
TWO_PI ) )
1817 Datum* localDatum = datumList[sourceIndex];
1822 return geodeticShiftWGS72ToWGS84( sourceLongitude, sourceLatitude, sourceHeight );
1831 if( _ellipsoidLibraryImplementation )
1846 long wgs84EllipsoidIndex;
1847 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WE", &wgs84EllipsoidIndex );
1848 _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &WGS84_a, &WGS84_f );
1850 Geocentric geocentricToGeodetic( WGS84_a, WGS84_f );
1853 delete wgs84CartesianCoordinates;
1854 delete localCartesianCoordinates;
1856 return wgs84GeodeticCoordinates;
1860 long wgs84EllipsoidIndex;
1861 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WE", &wgs84EllipsoidIndex );
1862 _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &WGS84_a, &WGS84_f );
1866 dx = localDatum->
deltaX();
1867 dy = localDatum->
deltaY();
1868 dz = localDatum->
deltaZ();
1872 return wgs84GeodeticCoordinates;
1895 if( index < 0 || index >= datumList.size() )
1898 *datumType = datumList[index]->datumType();
1921 if( ( index < 0 ) || ( index >= datumList.size() ) )
1928 Datum* datum = datumList[index];
1941 if( ( west_longitude < 0 ) || ( east_longitude < 0 ) )
1943 if( west_longitude > east_longitude )
1945 if( west_longitude < 0 )
1946 west_longitude +=
TWO_PI;
1947 if( east_longitude < 0 )
1948 east_longitude +=
TWO_PI;
1953 else if( ( west_longitude >
PI ) || ( east_longitude >
PI ) )
1955 if( west_longitude > east_longitude )
1957 if( west_longitude >
PI )
1958 west_longitude -=
TWO_PI;
1959 if( east_longitude >
PI )
1960 east_longitude -=
TWO_PI;
1970 ( latitude <= datum->northLatitude() ) &&
1971 ( west_longitude <= longitude ) &&
1972 ( longitude <= east_longitude ) )
1994 _ellipsoidLibraryImplementation = __ellipsoidLibraryImplementation;
2003 void DatumLibraryImplementation::loadDatums()
2012 long index = 0, i = 0;
2013 char *PathName = NULL;
2014 char* FileName7 = 0;
2015 FILE *fp_7param = NULL;
2016 FILE *fp_3param = NULL;
2017 char* FileName3 = 0;
2018 const int file_name_length = 23;
2026 PathName =
"/data/data/com.baesystems.msp.geotrans/lib/";
2027 FileName7 =
new char[ 80 ];
2028 strcpy( FileName7, PathName );
2029 strcat( FileName7,
"lib7paramdat.so" );
2031 PathName = getenv(
"MSPCCS_DATA" );
2032 if (PathName != NULL)
2034 FileName7 =
new char[ strlen( PathName ) + 13 ];
2035 strcpy( FileName7, PathName );
2036 strcat( FileName7,
"/" );
2040 FileName7 =
new char[ file_name_length ];
2041 strcpy( FileName7,
"../../data/" );
2043 strcat( FileName7,
"7_param.dat" );
2048 if (( fp_7param = fopen( FileName7,
"r" ) ) == NULL)
2050 delete [] FileName7;
2053 char message[256] =
"";
2054 if (NULL == PathName)
2056 strcpy( message,
"Environment variable undefined: MSPCCS_DATA." );
2061 strcat( message,
": 7_param.dat\n" );
2069 datumList.push_back(
new Datum(
2071 0.0, 0.0, 0.0, -
PI, +
PI, -
PI / 2.0, +
PI / 2.0,
false ) );
2076 datumList.push_back(
new Datum(
2078 0.0, 0.0, 0.0, -
PI, +
PI, -
PI / 2.0, +
PI / 2.0,
false ) );
2082 datum7ParamCount = 0;
2084 while ( !feof(fp_7param ) )
2088 bool userDefined =
false;
2090 if (fscanf(fp_7param,
"%s ", code) <= 0)
2092 fclose( fp_7param );
2097 if( code[0] ==
'*' )
2101 code[i] = code[i+1];
2103 code[DATUM_CODE_LENGTH-1] =
'\0';
2108 if (fscanf(fp_7param,
"\"%32[^\"]\"", name) <= 0)
2120 if( fscanf( fp_7param,
" %s %lf %lf %lf %lf %lf %lf %lf ",
2121 ellipsoidCode, &deltaX, &deltaY, &deltaZ,
2122 &rotationX, &rotationY, &rotationZ, &scaleFactor ) <= 0 )
2124 fclose( fp_7param );
2136 deltaX, deltaY, deltaZ, -
PI, +
PI, -
PI / 2.0, +
PI / 2.0,
2137 rotationX, rotationY, rotationZ, scaleFactor, userDefined ) );
2142 fclose( fp_7param );
2145 PathName =
"/data/data/com.baesystems.msp.geotrans/lib/";
2146 FileName3 =
new char[ 80 ];
2147 strcpy( FileName3, PathName );
2148 strcat( FileName3,
"lib3paramdat.so" );
2150 if (PathName != NULL)
2152 FileName3 =
new char[ strlen( PathName ) + 13 ];
2153 strcpy( FileName3, PathName );
2154 strcat( FileName3,
"/" );
2158 FileName3 =
new char[ file_name_length ];
2159 strcpy( FileName3,
"../../data/" );
2161 strcat( FileName3,
"3_param.dat" );
2164 if (( fp_3param = fopen( FileName3,
"r" ) ) == NULL)
2166 delete [] FileName7;
2168 delete [] FileName3;
2171 char message[256] =
"";
2173 strcat( message,
": 3_param.dat\n" );
2177 datum3ParamCount = 0;
2180 while( !feof( fp_3param ) )
2184 bool userDefined =
false;
2186 if( fscanf( fp_3param,
"%s ", code ) <= 0 )
2188 fclose( fp_3param );
2193 if( code[0] ==
'*' )
2197 code[i] = code[i+1];
2199 code[DATUM_CODE_LENGTH-1] =
'\0';
2204 if( fscanf( fp_3param,
"\"%32[^\"]\"", name) <= 0 )
2214 double eastLongitude;
2215 double westLongitude;
2216 double northLatitude;
2217 double southLatitude;
2219 if( fscanf( fp_3param,
" %s %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf ",
2220 ellipsoidCode, &deltaX, &sigmaX, &deltaY, &sigmaY, &deltaZ, &sigmaZ,
2221 &southLatitude, &northLatitude, &westLongitude, &eastLongitude ) <= 0 )
2223 fclose( fp_3param );
2235 deltaX, deltaY, deltaZ, westLongitude, eastLongitude,
2236 southLatitude, northLatitude, sigmaX, sigmaY, sigmaZ,
2243 fclose( fp_3param );
2245 delete [] FileName7;
2247 delete [] FileName3;
2252 void DatumLibraryImplementation::write3ParamFile()
2260 char *PathName = NULL;
2262 FILE *fp_3param = NULL;
2267 PathName = getenv(
"MSPCCS_DATA" );
2268 if (PathName != NULL)
2270 strcpy( FileName, PathName );
2271 strcat( FileName,
"/" );
2275 strcpy( FileName,
"../../data/" );
2277 strcat( FileName,
"3_param.dat" );
2279 if ((fp_3param = fopen(FileName,
"w")) == NULL)
2281 char message[256] =
"";
2282 if (NULL == PathName)
2284 strcpy( message,
"Environment variable undefined: MSPCCS_DATA." );
2289 strcat( message,
": 3_param.dat\n" );
2295 long index =
MAX_WGS + datum7ParamCount;
2296 int size = datumList.size();
2297 while( index < size )
2300 if( _3parameterDatum )
2302 strcpy( datum_name,
"\"" );
2303 strcat( datum_name, datumList[index]->name());
2304 strcat( datum_name,
"\"" );
2306 fprintf( fp_3param,
"*");
2308 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",
2309 _3parameterDatum->
code(),
2312 _3parameterDatum->
deltaX(),
2313 _3parameterDatum->
sigmaX(),
2314 _3parameterDatum->
deltaY(),
2315 _3parameterDatum->
sigmaY(),
2316 _3parameterDatum->
deltaZ(),
2317 _3parameterDatum->
sigmaZ(),
2327 fclose( fp_3param );
2332 void DatumLibraryImplementation::write7ParamFile()
2340 char *PathName = NULL;
2342 FILE *fp_7param = NULL;
2347 PathName = getenv(
"MSPCCS_DATA" );
2348 if (PathName != NULL)
2350 strcpy( FileName, PathName );
2351 strcat( FileName,
"/" );
2355 strcpy( FileName,
"../../data/" );
2357 strcat( FileName,
"7_param.dat" );
2359 if ((fp_7param = fopen(FileName,
"w")) == NULL)
2361 char message[256] =
"";
2362 if (NULL == PathName)
2364 strcpy( message,
"Environment variable undefined: MSPCCS_DATA." );
2369 strcat( message,
": 7_param.dat\n" );
2376 int endIndex = datum7ParamCount +
MAX_WGS;
2377 while( index < endIndex )
2380 if( _7parameterDatum )
2382 strcpy( datum_name,
"\"" );
2383 strcat( datum_name, datumList[index]->name());
2384 strcat( datum_name,
"\"" );
2386 fprintf( fp_7param,
"*");
2388 fprintf( fp_7param,
"%-6s %-33s%-2s %4.0f %4.0f %4.0f % 4.3f % 4.3f % 4.3f % 4.10f \n",
2389 _7parameterDatum->
code(),
2392 _7parameterDatum->
deltaX(),
2393 _7parameterDatum->
deltaY(),
2394 _7parameterDatum->
deltaZ(),
2404 fclose( fp_7param );
2408 GeodeticCoordinates* DatumLibraryImplementation::geodeticShiftWGS84ToWGS72(
const double WGS84Longitude,
const double WGS84Latitude,
const double WGS84Height )
2436 long wgs84EllipsoidIndex;
2437 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WE", &wgs84EllipsoidIndex );
2438 _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &WGS84_a, &WGS84_f );
2440 long wgs72EllipsoidIndex;
2441 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WD", &wgs72EllipsoidIndex );
2442 _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs72EllipsoidIndex, &WGS72_a, &WGS72_f );
2444 da = WGS72_a - WGS84_a;
2445 df = WGS72_f - WGS84_f;
2447 sin_Lat = sin(WGS84Latitude);
2448 sin2_Lat = sin_Lat * sin_Lat;
2450 Delta_Lat = (-4.5 * cos(WGS84Latitude)) / (WGS84_a*Q)
2451 + (df * sin(2*WGS84Latitude)) / Q;
2454 Delta_Hgt = -4.5 * sin_Lat + WGS84_a * df * sin2_Lat - da - 1.4;
2456 double wgs72Latitude = WGS84Latitude + Delta_Lat;
2457 double wgs72Longitude = WGS84Longitude + Delta_Lon;
2458 double wgs72Height = WGS84Height + Delta_Hgt;
2465 if (wgs72Longitude >
PI)
2466 wgs72Longitude -=
TWO_PI;
2467 if (wgs72Longitude < -
PI)
2468 wgs72Longitude +=
TWO_PI;
2474 GeodeticCoordinates* DatumLibraryImplementation::geodeticShiftWGS72ToWGS84(
const double WGS72Longitude,
const double WGS72Latitude,
const double WGS72Height )
2502 long wgs84EllipsoidIndex;
2503 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WE", &wgs84EllipsoidIndex );
2504 _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &WGS84_a, &WGS84_f );
2506 long wgs72EllipsoidIndex;
2507 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WD", &wgs72EllipsoidIndex );
2508 _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs72EllipsoidIndex, &WGS72_a, &WGS72_f );
2510 da = WGS84_a - WGS72_a;
2511 df = WGS84_f - WGS72_f;
2513 sin_Lat = sin(WGS72Latitude);
2514 sin2_Lat = sin_Lat * sin_Lat;
2516 Delta_Lat = (4.5 * cos(WGS72Latitude)) / (WGS72_a*Q) + (df * sin(2*WGS72Latitude)) / Q;
2519 Delta_Hgt = 4.5 * sin_Lat + WGS72_a * df * sin2_Lat - da + 1.4;
2521 double wgs84Latitude = WGS72Latitude + Delta_Lat;
2522 double wgs84Longitude = WGS72Longitude + Delta_Lon;
2523 double wgs84Height = WGS72Height + Delta_Hgt;
2530 if (wgs84Longitude >
PI)
2531 wgs84Longitude -=
TWO_PI;
2532 if (wgs84Longitude < -
PI)
2533 wgs84Longitude +=
TWO_PI;
2539 CartesianCoordinates* DatumLibraryImplementation::geocentricShiftWGS84ToWGS72(
const double X_WGS84,
const double Y_WGS84,
const double Z_WGS84 )
2559 long wgs84EllipsoidIndex;
2560 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WE", &wgs84EllipsoidIndex );
2561 _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &a_84, &f_84 );
2571 long wgs72EllipsoidIndex;
2572 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WD", &wgs72EllipsoidIndex );
2573 _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs72EllipsoidIndex, &a_72, &f_72 );
2577 CartesianCoordinates* wgs72GeocentricCoordinates = geocentric72.convertFromGeodetic( wgs72GeodeticCoordinates );
2579 delete wgs72GeodeticCoordinates;
2580 delete wgs84GeodeticCoordinates;
2582 return wgs72GeocentricCoordinates;
2586 CartesianCoordinates* DatumLibraryImplementation::geocentricShiftWGS72ToWGS84(
const double X,
const double Y,
const double Z )
2606 long wgs72EllipsoidIndex;
2607 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WD", &wgs72EllipsoidIndex );
2608 _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs72EllipsoidIndex, &a_72, &f_72 );
2617 long wgs84EllipsoidIndex;
2618 _ellipsoidLibraryImplementation->
ellipsoidIndex(
"WE", &wgs84EllipsoidIndex );
2619 _ellipsoidLibraryImplementation->
ellipsoidParameters( wgs84EllipsoidIndex, &a_84, &f_84 );
2622 CartesianCoordinates* wgs84GeocentricCoordinates = geocentric84.convertFromGeodetic( wgs84GeodeticCoordinates );
2624 delete wgs84GeodeticCoordinates;
2625 delete wgs72GeodeticCoordinates;
2627 return wgs84GeocentricCoordinates;
static const char * datumRotation
static const char * datumDomain
CartesianCoordinates * geocentricDatumShift(const long sourceIndex, const double sourceX, const double sourceY, const double sourceZ, const long targetIndex)
void datumStandardErrors(const long index, double *sigmaX, double *sigmaY, double *sigmaZ)
void datumName(const long index, char *name)
void datumSevenParameters(const long index, double *rotationX, double *rotationY, double *rotationZ, double *scaleFactor)
CartesianCoordinates * geocentricShiftFromWGS84(const double WGS84X, const double WGS84Y, const double WGS84Z, const long targetIndex)
char * ellipsoidCode() const
GeodeticCoordinates * geodeticShiftToWGS84(const long sourceIndex, const GeodeticCoordinates *sourceCoordinates)
static const char * datumFileParseError
void datumIndex(const char *code, long *index)
void datumUserDefined(const long index, long *result)
const char * WGS84_Datum_Code
~DatumLibraryImplementationCleaner()
const int FILENAME_LENGTH
void retrieveDatumType(const long index, DatumType::Enum *datumType)
static const char * datumType
static const char * datumFileOpenError
double southLatitude() const
static const char * notUserDefined
double northLatitude() const
GeodeticCoordinates * geodeticShiftFromWGS84(const GeodeticCoordinates *sourceCoordinates, const long targetIndex)
CartesianCoordinates * geocentricShiftToWGS84(const long sourceIndex, const double sourceX, const double sourceY, const double sourceZ)
bool datumUsesEllipsoid(const char *ellipsoidCode)
const double MOLODENSKY_MAX
static const char * longitude
void datumEllipsoidCode(const long index, char *code)
DatumType::Enum datumType() const
void define7ParamDatum(const char *code, const char *name, const char *ellipsoidCode, double deltaX, double deltaY, double deltaZ, double rotationX, double rotationY, double rotationZ, double scale, double westLongitude, double eastLongitude, double southLatitude, double northLatitude)
void ellipsoidIndex(const char *code, long *index)
MSP::CCS::GeodeticCoordinates * convertToGeodetic(MSP::CCS::CartesianCoordinates *cartesianCoordinates)
const int DATUM_CODE_LENGTH
void datumTranslationValues(const long index, double *deltaX, double *deltaY, double *deltaZ)
static const char * datumSigma
double eastLongitude() const
static const char * latitude
void ellipsoidParameters(const long index, double *a, double *f)
static DatumLibraryImplementation * getInstance()
DatumLibraryImplementation & operator=(const DatumLibraryImplementation &d)
static const char * invalidIndex
MSP::CCS::CartesianCoordinates * convertFromGeodetic(const MSP::CCS::GeodeticCoordinates *geodeticCoordinates)
static void removeInstance()
void datumCount(long *count)
Accuracy * datumShiftError(const long sourceIndex, const long targetIndex, double longitude, double latitude, Accuracy *sourceAccuracy, Precision::Enum precision)
static const char * scaleFactor
double scaleFactor() const
void validDatum(const long index, double longitude, double latitude, long *result)
const double SECONDS_PER_RADIAN
const double _180_OVER_PI
static const char * invalidDatumCode
void define3ParamDatum(const char *code, const char *name, const char *ellipsoidCode, double deltaX, double deltaY, double deltaZ, double sigmaX, double sigmaY, double sigmaZ, double westLongitude, double eastLongitude, double southLatitude, double northLatitude)
static const char * ellipse
class MSP::CCS::DatumLibraryImplementationCleaner datumLibraryImplementationCleanerInstance
double sphericalError90()
double westLongitude() const
const int DATUM_NAME_LENGTH
const int ELLIPSOID_CODE_LENGTH
void datumValidRectangle(const long index, double *westLongitude, double *eastLongitude, double *southLatitude, double *northLatitude)
GeodeticCoordinates * geodeticDatumShift(const long sourceIndex, const GeodeticCoordinates *sourceCoordinates, const long targetIndex)
void datumCode(const long index, char *code)
const char * WGS72_Datum_Code
DatumLibraryImplementation()
void setEllipsoidLibraryImplementation(EllipsoidLibraryImplementation *__ellipsoidLibraryImplementation)
static double toMeters(const Enum &prec)
~DatumLibraryImplementation(void)
GeodeticCoordinates * molodenskyShift(const double a, const double da, const double f, const double df, const double dx, const double dy, const double dz, const double sourceLongitude, const double sourceLatitude, const double sourceHeight)
void removeDatum(const char *code)