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;