|
Isis 3.0 Object Programmers' Reference |
Home |
00001 00022 #include "ProcessImportPds.h" 00023 00024 #include <QString> 00025 00026 #include <iostream> 00027 #include <QString> 00028 #include <sstream> 00029 00030 #include "IException.h" 00031 #include "ImportPdsTable.h" 00032 #include "IString.h" 00033 #include "LineManager.h" 00034 #include "OriginalLabel.h" 00035 #include "PixelType.h" 00036 #include "Preference.h" 00037 #include "Projection.h" 00038 #include "Pvl.h" 00039 #include "PvlObject.h" 00040 #include "PvlTokenizer.h" 00041 #include "PvlTranslationManager.h" 00042 #include "SpecialPixel.h" 00043 #include "Table.h" 00044 #include "UserInterface.h" 00045 00046 using namespace std; 00047 namespace Isis { 00048 00052 ProcessImportPds::ProcessImportPds() { 00053 p_keepOriginalLabel = true; 00054 p_encodingType = NONE; 00055 p_jp2File.clear(); 00056 00057 // Set up a translater for PDS file of type IMAGE 00058 Isis::PvlGroup &dataDir = Isis::Preference::Preferences().FindGroup("DataDirectory"); 00059 p_transDir = (QString) dataDir["Base"]; 00060 } 00061 00062 00063 ProcessImportPds::~ProcessImportPds() { 00064 } 00065 00066 00084 void ProcessImportPds::SetPdsFile(const QString &pdsLabelFile, 00085 const QString &pdsDataFile, 00086 Isis::Pvl &pdsLabel) { 00087 00088 // Internalize the PDS label in the PVL that was passed in 00089 try { 00090 pdsLabel.Read(pdsLabelFile); 00091 } 00092 catch (IException &e) { 00093 throw IException(e, IException::User, 00094 QObject::tr("This image does not contain a pds label. You will need an " 00095 "image with a PDS label or a detached PDS label for this " 00096 "image."), _FILEINFO_); 00097 } 00098 00099 // Save the label and file for future use 00100 p_pdsLabel = pdsLabel; 00101 p_labelFile = pdsLabelFile; 00102 00103 // Create a temporary Isis::PvlTranslationManager so we can find out what 00104 // type of PDS file this is (i.e., Qube or Image or SpectralQube) 00105 stringstream trnsStrm; 00106 trnsStrm << "Group = PdsTypeImage" << endl; 00107 trnsStrm << " InputPosition = ROOT" << endl; 00108 trnsStrm << " InputPosition = FILE" << endl; 00109 trnsStrm << " InputPosition = UNCOMPRESSED_FILE" << endl; 00110 trnsStrm << " InputKey = ^IMAGE" << endl; 00111 trnsStrm << "EndGroup" << endl; 00112 trnsStrm << "Group = PdsTypeQube" << endl; 00113 trnsStrm << " InputKey = ^QUBE" << endl; 00114 trnsStrm << "EndGroup" << endl; 00115 trnsStrm << "Group = PdsTypeSpectralQube" << endl; 00116 trnsStrm << " InputKey = ^SPECTRAL_QUBE" << endl; 00117 trnsStrm << "EndGroup" << endl; 00118 trnsStrm << "Group = PdsEncodingType" << endl; 00119 trnsStrm << " InputPosition = COMPRESSED_FILE" << endl; 00120 trnsStrm << " InputKey = ENCODING_TYPE" << endl; 00121 trnsStrm << " Translation = (*,*)" << endl; 00122 trnsStrm << "EndGroup" << endl; 00123 trnsStrm << "Group = PdsCompressedFile" << endl; 00124 trnsStrm << " InputPosition = COMPRESSED_FILE" << endl; 00125 trnsStrm << " InputKey = FILE_NAME" << endl; 00126 trnsStrm << " Translation = (*,*)" << endl; 00127 trnsStrm << "EndGroup" << endl; 00128 trnsStrm << "END"; 00129 00130 Isis::PvlTranslationManager pdsXlater(p_pdsLabel, trnsStrm); 00131 00132 // Check to see if we are dealing with a JPEG2000 file 00133 QString str; 00134 if(pdsXlater.InputHasKeyword("PdsEncodingType")) { 00135 str = pdsXlater.Translate("PdsEncodingType"); 00136 if(str == "JP2") { 00137 p_encodingType = JP2; 00138 str = pdsXlater.Translate("PdsCompressedFile"); 00139 if(pdsDataFile.isEmpty()) { 00140 Isis::FileName lfile(p_labelFile); 00141 Isis::FileName ifile(lfile.path() + "/" + str); 00142 if(ifile.fileExists()) { 00143 p_jp2File = ifile.expanded(); 00144 } 00145 else { 00146 QString tmp = ifile.expanded(); 00147 str = str.toLower(); 00148 ifile = lfile.path() + "/" + str; 00149 if(ifile.fileExists()) { 00150 p_jp2File = ifile.expanded(); 00151 } 00152 else { 00153 QString msg = "Unable to find input file [" + tmp + "] or [" + 00154 ifile.expanded() + "]"; 00155 throw IException(IException::Io, msg, _FILEINFO_); 00156 } 00157 } 00158 } 00159 } 00160 else { 00161 QString msg = "Unsupported encoding type in [" + p_labelFile + "]"; 00162 throw IException(IException::Io, msg, _FILEINFO_); 00163 } 00164 } 00165 00166 // Call the correct label processing 00167 if(pdsXlater.InputHasKeyword("PdsTypeImage")) { 00168 ProcessPdsImageLabel(pdsDataFile); 00169 } 00170 else if(pdsXlater.InputHasKeyword("PdsTypeQube")) { 00171 ProcessPdsQubeLabel(pdsDataFile, "pdsQube.trn"); 00172 } 00173 else if(pdsXlater.InputHasKeyword("PdsTypeSpectralQube")) { 00174 ProcessPdsQubeLabel(pdsDataFile, "pdsSpectralQube.trn"); 00175 } 00176 else { 00177 QString msg = "Unknown label type in [" + p_labelFile + "]"; 00178 throw IException(IException::Io, msg, _FILEINFO_); 00179 } 00180 00181 // Find out if this is a PDS file or an ISIS2 file 00182 IdentifySource(p_pdsLabel); 00183 00184 return; 00185 } 00186 00193 void ProcessImportPds::ProcessDataFilePointer(Isis::PvlTranslationManager & pdsXlater, const bool & calcOffsetOnly) { 00194 const PvlKeyword & dataFilePointer = pdsXlater.InputKeyword("DataFilePointer"); 00195 00196 QString dataFileName; 00197 QString units; 00198 QString str; 00199 int offset = -1; 00200 00201 // If only size 1, we either have a file name or an offset 00202 // Either way, when we're done with these two ifs, variables offset and 00203 // dataFileName will be set. 00204 if (dataFilePointer.Size() == 1) { 00205 try { 00206 str = pdsXlater.Translate("DataFilePointer"); 00207 offset = toInt(str); 00208 units = dataFilePointer.Unit(); 00209 // Successful? we have an offset, means current, p_labelFile 00210 // is the location of the data as well 00211 dataFileName = FileName(p_labelFile).name(); 00212 } 00213 catch(IException &e) { 00214 // Failed to parse to an int, means we have a file name 00215 // No offset given, so we use 1, offsets are 1 based 00216 offset = 1; 00217 units = "BYTES"; 00218 dataFileName = str; 00219 } 00220 } 00221 // We must have a filename and an offset, in that order 00222 // Expection ("filname", <offset>) 00223 else if (dataFilePointer.Size() == 2) { 00224 dataFileName = pdsXlater.Translate("DataFilePointer", 0); 00225 offset = IString(pdsXlater.Translate("DataFilePointer", 1)).ToInteger(); 00226 units = dataFilePointer.Unit(1); 00227 } 00228 // Error, no value 00229 else if (dataFilePointer.Size() == 0) { 00230 QString msg = "Data file pointer ^IMAGE or ^QUBE has no value, must" 00231 "have either file name or offset or both, in [" + 00232 p_labelFile + "]"; 00233 throw IException(IException::Unknown, msg, _FILEINFO_); 00234 } 00235 // Error, more than two values 00236 else { 00237 QString msg = "Improperly formatted data file pointer keyword ^IMAGE or " 00238 "^QUBE, in [" + p_labelFile + "], must contain filename " 00239 " or offset or both"; 00240 throw IException(IException::Unknown, msg, _FILEINFO_); 00241 } 00242 00243 // Now, to handle the values we found 00244 // the filename first, only do so if calcOffsetOnly is false 00245 if (!calcOffsetOnly) { 00246 Isis::FileName labelFile(p_labelFile); 00247 00248 // If dataFileName isn't empty, and does start at the root, use it 00249 Isis::FileName dataFile; 00250 if (dataFileName.size() != 0 && dataFileName.at(0) == '/') 00251 dataFile = FileName(dataFileName); 00252 // Otherwise, use the path to it and its name 00253 else 00254 dataFile = FileName(labelFile.path() + "/" + dataFileName); 00255 00256 // If it exists, use it 00257 if (dataFile.fileExists()) { 00258 SetInputFile(dataFile.expanded()); 00259 } 00260 // Retry with downcased name, if still no luck, fail 00261 else { 00262 QString tmp = dataFile.expanded(); 00263 dataFileName = dataFileName.toLower(); 00264 dataFile = FileName(labelFile.path() + "/" + dataFileName); 00265 if (dataFile.fileExists()) { 00266 SetInputFile(dataFile.expanded()); 00267 } 00268 else { 00269 QString msg = "Unable to find input file [" + tmp + "] or [" + 00270 dataFile.expanded() + "]"; 00271 throw IException(IException::Io, msg, _FILEINFO_); 00272 } 00273 } 00274 } 00275 00276 // Now, to handle the offset 00277 units = units.trimmed(); 00278 if (units == "BYTES" || units == "B") { 00279 SetFileHeaderBytes(offset - 1); 00280 } 00281 else { 00282 QString recSize = pdsXlater.Translate("DataFileRecordBytes"); 00283 SetFileHeaderBytes((offset - 1) * toInt(recSize)); 00284 } 00285 } 00286 00291 void ProcessImportPds::ProcessPixelBitandType(Isis::PvlTranslationManager & pdsXlater) { 00292 QString str; 00293 str = pdsXlater.Translate("CoreBitsPerPixel"); 00294 int bitsPerPixel = toInt(str); 00295 str = pdsXlater.Translate("CorePixelType"); 00296 if((str == "Real") && (bitsPerPixel == 32)) { 00297 SetPixelType(Isis::Real); 00298 } 00299 else if((str == "Integer") && (bitsPerPixel == 8)) { 00300 SetPixelType(Isis::UnsignedByte); 00301 } 00302 else if((str == "Integer") && (bitsPerPixel == 16)) { 00303 SetPixelType(Isis::SignedWord); 00304 } 00305 else if((str == "Integer") && (bitsPerPixel == 32)) { 00306 SetPixelType(Isis::SignedInteger); 00307 } 00308 else if((str == "Natural") && (bitsPerPixel == 8)) { 00309 SetPixelType(Isis::UnsignedByte); 00310 } 00311 else if((str == "Natural") && (bitsPerPixel == 16)) { 00312 SetPixelType(Isis::UnsignedWord); 00313 } 00314 else if((str == "Natural") && (bitsPerPixel == 16)) { 00315 SetPixelType(Isis::SignedWord); 00316 } 00317 else if((str == "Natural") && (bitsPerPixel == 32)) { 00318 SetPixelType(Isis::UnsignedInteger); 00319 } 00320 else { 00321 QString msg = "Invalid PixelType and BitsPerPixel combination [" + str + 00322 ", " + toString(bitsPerPixel) + "]"; 00323 throw IException(IException::Io, msg, _FILEINFO_); 00324 } 00325 } 00326 00330 void ProcessImportPds::ProcessSpecialPixels(Isis::PvlTranslationManager & pdsXlater, const bool & isQube) { 00331 QString str; 00332 // Set any special pixel values 00333 double pdsNull = Isis::NULL8; 00334 if(pdsXlater.InputHasKeyword("CoreNull")) { 00335 str = pdsXlater.Translate("CoreNull"); 00336 if(str != "NULL") { 00337 pdsNull = toDouble(str); 00338 } 00339 } 00340 else if(!isQube && pdsXlater.InputHasKeyword("CoreNull2")) { 00341 str = pdsXlater.Translate("CoreNull2"); 00342 if(str != "NULL") { 00343 pdsNull = toDouble(str); 00344 } 00345 } 00346 00347 double pdsLrs = Isis::Lrs; 00348 if(pdsXlater.InputHasKeyword("CoreLrs")) { 00349 str = pdsXlater.Translate("CoreLrs"); 00350 if(str != "NULL") { 00351 pdsLrs = toDouble(str); 00352 } 00353 } 00354 else if(!isQube && pdsXlater.InputHasKeyword("CoreLrs2")) { 00355 str = pdsXlater.Translate("CoreLrs2"); 00356 if(str != "NULL") { 00357 pdsLrs = toDouble(str); 00358 } 00359 } 00360 00361 double pdsLis = Isis::Lis; 00362 if(pdsXlater.InputHasKeyword("CoreLis")) { 00363 str = pdsXlater.Translate("CoreLis"); 00364 if(str != "NULL") { 00365 pdsLis = toDouble(str); 00366 } 00367 } 00368 else if(!isQube && pdsXlater.InputHasKeyword("CoreLis2")) { 00369 str = pdsXlater.Translate("CoreLis2"); 00370 if(str != "NULL") { 00371 pdsLis = toDouble(str); 00372 } 00373 } 00374 00375 double pdsHrs = Isis::Hrs; 00376 if(pdsXlater.InputHasKeyword("CoreHrs")) { 00377 str = pdsXlater.Translate("CoreHrs"); 00378 if(str != "NULL") { 00379 pdsHrs = toDouble(str); 00380 } 00381 } 00382 else if(!isQube && pdsXlater.InputHasKeyword("CoreHrs2")) { 00383 str = pdsXlater.Translate("CoreHrs2"); 00384 if(str != "NULL") { 00385 pdsHrs = toDouble(str); 00386 } 00387 } 00388 00389 double pdsHis = Isis::His; 00390 if(pdsXlater.InputHasKeyword("CoreHis")) { 00391 str = pdsXlater.Translate("CoreHis"); 00392 if(str != "NULL") { 00393 pdsHis = toDouble(str); 00394 } 00395 } 00396 else if(!isQube && pdsXlater.InputHasKeyword("CoreHis2")) { 00397 str = pdsXlater.Translate("CoreHis2"); 00398 if(str != "NULL") { 00399 pdsHis = toDouble(str); 00400 } 00401 } 00402 00403 SetSpecialValues(pdsNull, pdsLrs, pdsLis, pdsHrs, pdsHis); 00404 } 00405 00417 void ProcessImportPds::ProcessPdsImageLabel(const QString &pdsDataFile) { 00418 Isis::FileName transFile(p_transDir + "/translations/pdsImage.trn"); 00419 Isis::PvlTranslationManager pdsXlater(p_pdsLabel, transFile.expanded()); 00420 00421 QString str; 00422 00423 str = pdsXlater.Translate("CoreLinePrefixBytes"); 00424 SetDataPrefixBytes(toInt(str)); 00425 00426 str = pdsXlater.Translate("CoreLineSuffixBytes"); 00427 SetDataSuffixBytes(toInt(str)); 00428 00429 ProcessPixelBitandType(pdsXlater); 00430 00431 str = pdsXlater.Translate("CoreByteOrder"); 00432 SetByteOrder(Isis::ByteOrderEnumeration(str)); 00433 00434 str = pdsXlater.Translate("CoreSamples"); 00435 int ns = toInt(str); 00436 str = pdsXlater.Translate("CoreLines"); 00437 int nl = toInt(str); 00438 str = pdsXlater.Translate("CoreBands"); 00439 int nb = toInt(str); 00440 SetDimensions(ns, nl, nb); 00441 00442 // Set any special pixel values, not qube, so use false 00443 ProcessSpecialPixels(pdsXlater, false); 00444 00445 //----------------------------------------------------------------- 00446 // Find the data filename it may be the same as the label file 00447 // OR the label file may contain a pointer to the data 00448 //----------------------------------------------------------------- 00449 00450 // Use the name supplied by the application if it is there 00451 if(pdsDataFile.length() > 0) { 00452 SetInputFile(pdsDataFile); 00453 ProcessDataFilePointer(pdsXlater, true); 00454 } 00455 // If the data is in JPEG 2000 format, then use the name of the file 00456 // from the label 00457 else if(p_jp2File.length() > 0) { 00458 SetInputFile(p_jp2File); 00459 ProcessDataFilePointer(pdsXlater, true); 00460 } 00461 // Use the "^IMAGE or ^QUBE" label to get the filename for the image data 00462 // Get the path portion from user entered label file spec 00463 else { 00464 // Handle filename and offset 00465 ProcessDataFilePointer(pdsXlater, false); 00466 } 00467 00468 //------------------------------------------------------------ 00469 // Find the image data base and multiplier 00470 //------------------------------------------------------------ 00471 str = pdsXlater.Translate("CoreBase"); 00472 SetBase(toDouble(str)); 00473 str = pdsXlater.Translate("CoreMultiplier"); 00474 SetMultiplier(toDouble(str)); 00475 00476 // Find the organization of the image data 00477 str = pdsXlater.Translate("CoreOrganization"); 00478 00479 if(p_encodingType == JP2) { 00480 SetOrganization(ProcessImport::JP2); 00481 } 00482 else if(str == "BSQ") { 00483 SetOrganization(ProcessImport::BSQ); 00484 } 00485 else if(str == "BIP") { 00486 SetOrganization(ProcessImport::BIP); 00487 } 00488 else if(str == "BIL") { 00489 SetOrganization(ProcessImport::BIL); 00490 } 00491 else { 00492 QString msg = "Unsupported axis order [" + str + "]"; 00493 throw IException(IException::Programmer, msg, _FILEINFO_); 00494 } 00495 } 00496 00497 00514 void ProcessImportPds::ProcessPdsQubeLabel(const QString &pdsDataFile, 00515 const QString &transFile) { 00516 00517 Isis::FileName tFile(p_transDir + "/translations/" + transFile); 00518 00519 Isis::PvlTranslationManager pdsXlater(p_pdsLabel, tFile.expanded()); 00520 00521 QString str; 00522 00523 // Find the organization of the image data 00524 // Save off which axis the samples, lines and bands are on 00525 int linePos = 0; 00526 int samplePos = 0; 00527 int bandPos = 0; 00528 int val = pdsXlater.InputKeyword("CoreOrganization").Size(); 00529 QString tmp = ""; 00530 for(int i = 0; i < val; i++) { 00531 str = pdsXlater.Translate("CoreOrganization", i); 00532 tmp += str; 00533 if(str == "SAMPLE") { 00534 samplePos = i; 00535 } 00536 else if(str == "LINE") { 00537 linePos = i; 00538 } 00539 else if(str == "BAND") { 00540 bandPos = i; 00541 } 00542 else { 00543 QString message = "Unknown file axis name [" + str + "]"; 00544 throw IException(IException::User, message, _FILEINFO_); 00545 } 00546 } 00547 00548 if(p_encodingType == JP2) { 00549 SetOrganization(ProcessImport::JP2); 00550 } 00551 else if(tmp == "SAMPLELINEBAND") { 00552 SetOrganization(ProcessImport::BSQ); 00553 } 00554 else if(tmp == "BANDSAMPLELINE") { 00555 SetOrganization(ProcessImport::BIP); 00556 } 00557 else if(tmp == "SAMPLEBANDLINE") { 00558 SetOrganization(ProcessImport::BIL); 00559 } 00560 else { 00561 PvlKeyword pdsCoreOrg = p_pdsLabel.FindKeyword(pdsXlater. 00562 InputKeywordName("CoreOrganization"), Pvl::Traverse); 00563 00564 stringstream pdsCoreOrgStream; 00565 pdsCoreOrgStream << pdsCoreOrg; 00566 00567 QString msg = "Unsupported axis order [" + QString(pdsCoreOrgStream.str().c_str()) + "]"; 00568 throw IException(IException::Programmer, msg, _FILEINFO_); 00569 } 00570 00571 00572 // Set the number of byte preceding the second dimension (left side plane) 00573 // There are no capabilities in a PDS QUBE for this 00574 SetDataPrefixBytes(0); 00575 00576 // Set the number of bytes following the second dimension (right side plane) 00577 str = pdsXlater.Translate("SuffixItemSize"); 00578 int suffix = toInt(str); 00579 str = pdsXlater.Translate("AxisSuffixCount", 0); 00580 suffix *= toInt(str); 00581 SetDataSuffixBytes(suffix); 00582 00583 str = pdsXlater.Translate("SuffixItemSize"); 00584 int trailer = toInt(str); 00585 str = pdsXlater.Translate("AxisSuffixCount", 1); 00586 trailer *= toInt(str); 00587 str = pdsXlater.Translate("CoreSamples", samplePos); 00588 trailer *= toInt(str); 00589 trailer += suffix; 00590 SetDataTrailerBytes(trailer); 00591 00592 ProcessPixelBitandType(pdsXlater); 00593 00594 // Set the byte order 00595 str = pdsXlater.Translate("CoreByteOrder"); 00596 SetByteOrder(Isis::ByteOrderEnumeration(str)); 00597 00598 // Set the number of samples, lines and bands 00599 str = pdsXlater.Translate("CoreSamples", samplePos); 00600 int ns = toInt(str); 00601 str = pdsXlater.Translate("CoreLines", linePos); 00602 int nl = toInt(str); 00603 str = pdsXlater.Translate("CoreBands", bandPos); 00604 int nb = toInt(str); 00605 SetDimensions(ns, nl, nb); 00606 00607 // Set any special pixels values, qube, so use true 00608 ProcessSpecialPixels(pdsXlater, true); 00609 00610 //--------------------------------------------------------------- 00611 // Find the data filename, it may be the same as the label file 00612 // Or the label file may contain a pointer to the data 00613 //--------------------------------------------------------------- 00614 00615 // Use the name supplied by the application if it is there 00616 if(pdsDataFile.length() > 0) { 00617 SetInputFile(pdsDataFile); 00618 ProcessDataFilePointer(pdsXlater, true); 00619 } 00620 // If the data is in JPEG 2000 format, then use the name of the file 00621 // from the label 00622 else if(p_jp2File.length() > 0) { 00623 SetInputFile(p_jp2File); 00624 ProcessDataFilePointer(pdsXlater, true); 00625 } 00626 else { 00627 // Handle filename and offset 00628 ProcessDataFilePointer(pdsXlater, false); 00629 } 00630 00631 00632 //------------------------------------------------------------ 00633 // Find the image data base and multiplier 00634 //------------------------------------------------------------ 00635 // First see if there are base and multiplier in the band bin group 00636 if((pdsXlater.InputHasKeyword("BandBase")) && 00637 (pdsXlater.InputHasKeyword("BandMultiplier"))) { 00638 vector<double> bases; 00639 vector<double> mults; 00640 for(int i = 0; i < pdsXlater.InputKeyword("BandBase").Size(); i++) { 00641 str = pdsXlater.Translate("BandBase", i); 00642 bases.push_back(toDouble(str)); 00643 str = pdsXlater.Translate("BandMultiplier", i); 00644 mults.push_back(toDouble(str)); 00645 } 00646 SetBase(bases); 00647 SetMultiplier(mults); 00648 } 00649 else { 00650 str = pdsXlater.Translate("CoreBase"); 00651 SetBase(toDouble(str)); 00652 str = pdsXlater.Translate("CoreMultiplier"); 00653 SetMultiplier(toDouble(str)); 00654 } 00655 } 00656 00668 void ProcessImportPds::TranslatePdsProjection(Isis::Pvl &lab) { 00669 00670 // Create a temporary Isis::PvlTranslationManager so we can find out what 00671 // type of projection labels exist 00672 stringstream trnsStrm; 00673 trnsStrm << "Group = PdsProjectionTypeImage" << endl; 00674 trnsStrm << " InputPosition = IMAGE_MAP_PROJECTION" << endl; 00675 trnsStrm << " InputPosition = IMAGE_MAP_PROJECTION_CATALOG" << endl; 00676 trnsStrm << " InputKey = MAP_PROJECTION_TYPE" << endl; 00677 trnsStrm << "EndGroup" << endl; 00678 trnsStrm << "Group = PdsProjectionTypeQube" << endl; 00679 trnsStrm << " InputPosition = (QUBE,IMAGE_MAP_PROJECTION)" << endl; 00680 trnsStrm << " InputKey = MAP_PROJECTION_TYPE" << endl; 00681 trnsStrm << "EndGroup" << endl; 00682 trnsStrm << "Group = PdsProjectionTypeSpectralQube" << endl; 00683 trnsStrm << " InputPosition = (SPECTRAL_QUBE,IMAGE_MAP_PROJECTION)" << endl; 00684 trnsStrm << " InputKey = MAP_PROJECTION_TYPE" << endl; 00685 trnsStrm << "EndGroup" << endl; 00686 trnsStrm << "END"; 00687 00688 Isis::PvlTranslationManager projType(p_pdsLabel, trnsStrm); 00689 00690 // Set up the correct projection translation table for this label 00691 Isis::PvlGroup &dataDir = Isis::Preference::Preferences().FindGroup("DataDirectory"); 00692 QString transDir = (QString) dataDir["Base"]; 00693 00694 Isis::FileName transFile; 00695 if(projType.InputHasKeyword("PdsProjectionTypeImage")) { 00696 transFile = transDir + "/" + "translations/pdsImageProjection.trn"; 00697 } 00698 else if(projType.InputHasKeyword("PdsProjectionTypeQube")) { 00699 transFile = transDir + "/" + "translations/pdsQubeProjection.trn"; 00700 } 00701 else if(projType.InputHasKeyword("PdsProjectionTypeSpectralQube")) { 00702 transFile = transDir + "/" + "translations/pdsSpectralQubeProjection.trn"; 00703 } 00704 else { 00705 return; 00706 } 00707 00708 Isis::PvlTranslationManager pdsXlater(p_pdsLabel, transFile.expanded()); 00709 00710 ExtractPdsProjection(pdsXlater); 00711 00712 Isis::PvlGroup mapGroup("Mapping"); 00713 mapGroup += Isis::PvlKeyword("ProjectionName", p_projection); 00714 mapGroup += Isis::PvlKeyword("TargetName", p_targetName); 00715 mapGroup += Isis::PvlKeyword("EquatorialRadius", toString(p_equatorialRadius), "meters"); 00716 mapGroup += Isis::PvlKeyword("PolarRadius", toString(p_polarRadius), "meters"); 00717 mapGroup += Isis::PvlKeyword("LongitudeDirection", p_longitudeDirection); 00718 mapGroup += Isis::PvlKeyword("LongitudeDomain", toString(p_longitudeDomain)); 00719 mapGroup += Isis::PvlKeyword("LatitudeType", p_latitudeType); 00720 if(p_minimumLatitude != Isis::NULL8) { 00721 mapGroup += Isis::PvlKeyword("MinimumLatitude", toString(p_minimumLatitude)); 00722 } 00723 if(p_maximumLatitude != Isis::NULL8) { 00724 mapGroup += Isis::PvlKeyword("MaximumLatitude", toString(p_maximumLatitude)); 00725 } 00726 if(p_minimumLongitude != Isis::NULL8) { 00727 mapGroup += Isis::PvlKeyword("MinimumLongitude", toString(p_minimumLongitude)); 00728 } 00729 if(p_maximumLongitude != Isis::NULL8) { 00730 mapGroup += Isis::PvlKeyword("MaximumLongitude", toString(p_maximumLongitude)); 00731 } 00732 00733 // if both longitudes exist, verify they are ordered correctly 00734 if(p_minimumLongitude != Isis::NULL8 && p_maximumLongitude != Isis::NULL8) { 00735 if(p_maximumLongitude <= p_minimumLongitude) { 00736 if(p_longitudeDomain == 180) { 00737 mapGroup["MinimumLongitude"] = toString(-180); 00738 mapGroup["MaximumLongitude"] = toString(180); 00739 } 00740 else { 00741 mapGroup["MinimumLongitude"] = toString(0); 00742 mapGroup["MaximumLongitude"] = toString(360); 00743 } 00744 } 00745 } 00746 00747 mapGroup += Isis::PvlKeyword("PixelResolution", toString(p_pixelResolution), "meters/pixel"); 00748 mapGroup += Isis::PvlKeyword("Scale", toString(p_scaleFactor), "pixels/degree"); 00749 mapGroup += Isis::PvlKeyword("UpperLeftCornerX", toString(p_upperLeftX), "meters"); 00750 mapGroup += Isis::PvlKeyword("UpperLeftCornerY", toString(p_upperLeftY), "meters"); 00751 if(p_rotation != 0.0) { 00752 mapGroup += Isis::PvlKeyword("Rotation", toString(p_rotation)); 00753 } 00754 00755 // To handle new projections without the need to modify source code 00756 // we will construct a filename from the projection. The filename will 00757 // contain the projection specific translations from PDS to ISIS for each 00758 // projection 00759 00760 QString projSpecificFileName = "$base/translations/pdsImport"; 00761 projSpecificFileName += p_projection + ".trn"; 00762 Isis::PvlTranslationManager specificXlater(p_pdsLabel, projSpecificFileName); 00763 00764 lab.AddGroup(mapGroup); 00765 specificXlater.Auto(lab); 00766 00767 if(lab.FindGroup("Mapping").HasKeyword("CenterLongitude")) { 00768 PvlKeyword ¢erLon = lab.FindGroup("Mapping")["CenterLongitude"]; 00769 if(p_longitudeDomain == 180) 00770 centerLon = toString(Projection::To180Domain((double)centerLon)); 00771 else 00772 centerLon = toString(Projection::To360Domain((double)centerLon)); 00773 } 00774 00775 if(lab.FindGroup("Mapping").HasKeyword("PoleLongitude")) { 00776 PvlKeyword &poleLon = lab.FindGroup("Mapping")["PoleLongitude"]; 00777 if(p_longitudeDomain == 180) 00778 poleLon = toString(Projection::To180Domain((double)poleLon)); 00779 else 00780 poleLon = toString(Projection::To360Domain((double)poleLon)); 00781 } 00782 00783 OutputCubes[0]->putGroup(lab.FindGroup("Mapping")); 00784 } 00785 00810 void ProcessImportPds::ExtractPdsProjection(Isis::PvlTranslationManager &pdsXlater) { 00811 00812 QString str; 00813 00814 if(pdsXlater.InputHasKeyword("ProjectionName")) { 00815 p_projection = pdsXlater.Translate("ProjectionName"); 00816 } 00817 else { 00818 QString message = "No projection name in labels"; 00819 throw IException(IException::Unknown, message, _FILEINFO_); 00820 } 00821 00822 if(pdsXlater.InputHasKeyword("TargetName")) { 00823 p_targetName = pdsXlater.Translate("TargetName"); 00824 } 00825 else { 00826 QString message = "No target name in labels"; 00827 throw IException(IException::Unknown, message, _FILEINFO_); 00828 } 00829 00830 if(pdsXlater.InputHasKeyword("EquatorialRadius")) { 00831 str = pdsXlater.Translate("EquatorialRadius"); 00832 p_equatorialRadius = toDouble(str) * 1000.0; 00833 } 00834 else { 00835 QString message = "No equatorial radius name in labels"; 00836 throw IException(IException::User, message, _FILEINFO_); 00837 } 00838 00839 if(pdsXlater.InputHasKeyword("PolarRadius")) { 00840 str = pdsXlater.Translate("PolarRadius"); 00841 p_polarRadius = toDouble(str) * 1000.0; 00842 } 00843 else { 00844 QString message = "No polar radius in labels"; 00845 throw IException(IException::User, message, _FILEINFO_); 00846 } 00847 00848 if(pdsXlater.InputHasKeyword("LongitudeDirection")) { 00849 p_longitudeDirection = pdsXlater.Translate("LongitudeDirection"); 00850 } 00851 else { 00852 p_longitudeDirection = pdsXlater.Translate("LongitudeDirection2"); 00853 } 00854 00855 if(p_polarRadius == p_equatorialRadius) { 00856 p_latitudeType = "Planetocentric"; 00857 } 00858 else if(pdsXlater.InputHasKeyword("LatitudeType2")) { 00859 p_latitudeType = pdsXlater.Translate("LatitudeType2"); 00860 } 00861 else { 00862 p_latitudeType = pdsXlater.Translate("LatitudeType"); 00863 } 00864 00865 if(pdsXlater.InputHasKeyword("MinimumLatitude")) { 00866 str = pdsXlater.Translate("MinimumLatitude"); 00867 try { 00868 p_minimumLatitude = toDouble(str); 00869 } 00870 catch(IException &e) { 00871 p_minimumLatitude = Isis::NULL8; 00872 } 00873 } 00874 else { 00875 p_minimumLatitude = Isis::NULL8; 00876 } 00877 00878 if(pdsXlater.InputHasKeyword("MaximumLatitude")) { 00879 str = pdsXlater.Translate("MaximumLatitude"); 00880 try { 00881 p_maximumLatitude = toDouble(str); 00882 } 00883 catch(IException &e) { 00884 p_maximumLatitude = Isis::NULL8; 00885 } 00886 } 00887 else { 00888 p_maximumLatitude = Isis::NULL8; 00889 } 00890 00891 // This variable represents if the longitudes were read in as 00892 // positive west 00893 bool positiveWest = false; 00894 if(pdsXlater.InputHasKeyword("MinimumLongitude")) { 00895 str = pdsXlater.Translate("MinimumLongitude"); 00896 try { 00897 positiveWest = true; 00898 p_minimumLongitude = toDouble(str); 00899 } 00900 catch(IException &e) { 00901 p_minimumLongitude = Isis::NULL8; 00902 } 00903 } 00904 else if(pdsXlater.InputHasKeyword("MinimumLongitude2")) { 00905 str = pdsXlater.Translate("MinimumLongitude2"); 00906 try { 00907 p_minimumLongitude = toDouble(str); 00908 } 00909 catch(IException &e) { 00910 p_minimumLongitude = Isis::NULL8; 00911 } 00912 } 00913 else { 00914 p_minimumLongitude = Isis::NULL8; 00915 } 00916 00917 if(pdsXlater.InputHasKeyword("MaximumLongitude")) { 00918 str = pdsXlater.Translate("MaximumLongitude"); 00919 try { 00920 positiveWest = true; 00921 p_maximumLongitude = toDouble(str); 00922 } 00923 catch(IException &e) { 00924 p_maximumLongitude = Isis::NULL8; 00925 } 00926 } 00927 else if(pdsXlater.InputHasKeyword("MaximumLongitude2")) { 00928 str = pdsXlater.Translate("MaximumLongitude2"); 00929 try { 00930 p_maximumLongitude = toDouble(str); 00931 } 00932 catch(IException &e) { 00933 p_maximumLongitude = Isis::NULL8; 00934 } 00935 } 00936 else { 00937 p_maximumLongitude = Isis::NULL8; 00938 } 00939 00940 str = pdsXlater.Translate("LongitudeDomain"); 00941 p_longitudeDomain = toInt(str); 00942 00961 if(positiveWest && (p_longitudeDirection.compare("PositiveEast") == 0)) { 00962 double tmp = p_minimumLongitude; 00963 p_minimumLongitude = p_maximumLongitude; 00964 p_maximumLongitude = tmp; 00965 } 00966 00967 if(p_minimumLongitude > p_maximumLongitude) { 00968 // Force the change to 180 00969 p_longitudeDomain = 180; 00970 p_minimumLongitude = Isis::Projection::To180Domain(p_minimumLongitude); 00971 } 00972 00973 // If either the minimumLongitude or maximumLongitude are < 0, change 00974 // longitude Domain to 180. 00975 if(p_minimumLongitude < 0 || p_maximumLongitude < 0) { 00976 p_longitudeDomain = 180; 00977 } 00978 00979 str = pdsXlater.Translate("PixelResolution"); 00980 p_pixelResolution = toDouble(str); 00981 str = pdsXlater.InputKeyword("PixelResolution").Unit().toUpper(); 00982 // Assume KM/PIXEL if the unit doesn't exist or is not METERS/PIXEL 00983 if((str != "METERS/PIXEL") && (str != "M/PIXEL") && (str != "M/PIX")) { 00984 p_pixelResolution *= 1000.0; 00985 } 00986 00987 str = pdsXlater.Translate("Scale"); 00988 p_scaleFactor = toDouble(str); 00989 00990 try { 00991 str = pdsXlater.Translate("Rotation"); 00992 p_rotation = toDouble(str); 00993 } 00994 catch(IException &) { 00995 // assume no rotation if the value isn't a number 00996 p_rotation = 0.0; 00997 } 00998 00999 // Look for projection offsets/mults to convert between line/samp and x/y 01000 double xoff, yoff, xmult, ymult; 01001 GetProjectionOffsetMults(xoff, yoff, xmult, ymult); 01002 01003 if(pdsXlater.InputHasKeyword("LineProjectionOffset")) { 01004 str = pdsXlater.Translate("LineProjectionOffset"); 01005 } 01006 else { 01007 str = pdsXlater.Translate("LineProjectionOffset2"); 01008 } 01009 p_lineProjectionOffset = toDouble(str); 01010 p_upperLeftY = ymult * (p_lineProjectionOffset + yoff) * p_pixelResolution; 01011 01012 if(pdsXlater.InputHasKeyword("SampleProjectionOffset")) { 01013 str = pdsXlater.Translate("SampleProjectionOffset"); 01014 } 01015 else { 01016 str = pdsXlater.Translate("SampleProjectionOffset2"); 01017 } 01018 p_sampleProjectionOffset = toDouble(str); 01019 p_upperLeftX = xmult * (p_sampleProjectionOffset + xoff) * p_pixelResolution; 01020 01021 01022 } 01023 01029 void ProcessImportPds::EndProcess() { 01030 if(p_keepOriginalLabel) { 01031 OriginalLabel ol(p_pdsLabel); 01032 for(unsigned int i = 0; i < OutputCubes.size(); i++) { 01033 OutputCubes[i]->write(ol); 01034 } 01035 } 01036 Process::EndProcess(); 01037 } 01038 01043 void ProcessImportPds::OmitOriginalLabel() { 01044 p_keepOriginalLabel = false; 01045 } 01046 01047 01054 void ProcessImportPds::IdentifySource(Isis::Pvl &inputLabel) { 01055 01056 // Create a temporary Isis::PvlTranslationManager so we can find out what 01057 // type of input file we have 01058 stringstream trnsStrm; 01059 trnsStrm << "Group = PdsFile" << endl; 01060 trnsStrm << " InputPosition = ROOT" << endl; 01061 trnsStrm << " InputKey = PDS_VERSION_ID" << endl; 01062 trnsStrm << "EndGroup" << endl; 01063 trnsStrm << "Group = Isis2File" << endl; 01064 trnsStrm << " InputPosition = ROOT" << endl; 01065 trnsStrm << " InputKey = CCSD3ZF0000100000001NJPL3IF0PDS200000001" << endl; 01066 trnsStrm << "EndGroup" << endl; 01067 trnsStrm << "END"; 01068 01069 Isis::PvlTranslationManager sourceXlater(inputLabel, trnsStrm); 01070 01071 if(sourceXlater.InputHasKeyword("PdsFile")) { 01072 p_source = PDS; 01073 } 01074 else if(sourceXlater.InputHasKeyword("Isis2File")) { 01075 p_source = ISIS2; 01076 } 01077 else { 01078 p_source = NOSOURCE; 01079 } 01080 01081 } 01082 01091 bool ProcessImportPds::IsIsis2() { 01092 01093 if(p_source == ISIS2) { 01094 return true; 01095 } 01096 else { 01097 return false; 01098 } 01099 } 01100 01101 01102 01110 void ProcessImportPds::TranslateIsis2Labels(Isis::Pvl &lab) { 01111 TranslateIsis2BandBin(lab); 01112 TranslateIsis2Instrument(lab); 01113 } 01114 01115 01116 01124 void ProcessImportPds::TranslatePdsLabels(Isis::Pvl &lab) { 01125 TranslatePdsBandBin(lab); 01126 TranslatePdsArchive(lab); 01127 } 01128 01135 void ProcessImportPds::TranslateIsis2BandBin(Isis::Pvl &lab) { 01136 // Set up a translater for Isis2 labels 01137 Isis::PvlGroup &dataDir = Isis::Preference::Preferences().FindGroup("DataDirectory"); 01138 QString transDir = (QString) dataDir["Base"]; 01139 01140 Isis::FileName transFile(transDir + "/" + "translations/isis2bandbin.trn"); 01141 Isis::PvlTranslationManager isis2Xlater(p_pdsLabel, transFile.expanded()); 01142 01143 // Add all the Isis2 keywords that can be translated to the requested label 01144 isis2Xlater.Auto(lab); 01145 } 01146 01153 void ProcessImportPds::TranslateIsis2Instrument(Isis::Pvl &lab) { 01154 // Set up a translater for Isis2 labels 01155 Isis::PvlGroup &dataDir = Isis::Preference::Preferences().FindGroup("DataDirectory"); 01156 QString transDir = (QString) dataDir["Base"]; 01157 Isis::FileName transFile(transDir + "/" + "translations/isis2instrument.trn"); 01158 Isis::PvlTranslationManager isis2Xlater(p_pdsLabel, transFile.expanded()); 01159 01160 // Add all the Isis2 keywords that can be translated to the requested label 01161 isis2Xlater.Auto(lab); 01162 01163 //Check StartTime for appended 'z' (Zulu time) and remove 01164 Isis::PvlGroup &inst = lab.FindGroup("Instrument"); 01165 01166 if(inst.HasKeyword("StartTime")) { 01167 Isis::PvlKeyword &stkey = inst["StartTime"]; 01168 QString stime = stkey[0]; 01169 stime = stime.remove(QRegExp("[Zz]$")); 01170 stkey = stime; 01171 } 01172 } 01173 01180 void ProcessImportPds::TranslatePdsBandBin(Isis::Pvl &lab) { 01181 // Set up a translater for PDS labels 01182 Isis::FileName transFile(p_transDir + "/" + "translations/pdsImageBandBin.trn"); 01183 Isis::PvlTranslationManager isis2Xlater(p_pdsLabel, transFile.expanded()); 01184 01185 // Add all the Isis2 keywords that can be translated to the requested label 01186 isis2Xlater.Auto(lab); 01187 } 01188 01195 void ProcessImportPds::TranslatePdsArchive(Isis::Pvl &lab) { 01196 // Set up a translater for PDS labels 01197 Isis::FileName transFile(p_transDir + "/" + "translations/pdsImageArchive.trn"); 01198 Isis::PvlTranslationManager isis2Xlater(p_pdsLabel, transFile.expanded()); 01199 01200 // Add all the Isis2 keywords that can be translated to the requested label 01201 isis2Xlater.Auto(lab); 01202 } 01203 01216 void ProcessImportPds::GetProjectionOffsetMults(double &xoff, double &yoff, 01217 double &xmult, double &ymult) { 01218 01219 xmult = -1.0; 01220 ymult = 1.0; 01221 xoff = -0.5; 01222 yoff = -0.5; 01223 01224 // Open projectionOffsetMults file 01225 Isis::Pvl p(p_transDir + "/" + "translations/pdsProjectionLineSampToXY.def"); 01226 01227 Isis::PvlObject &projDef = p.FindObject("ProjectionOffsetMults", 01228 Pvl::Traverse); 01229 01230 for(int g = 0; g < projDef.Groups(); g++) { 01231 QString key = projDef.Group(g)["Keyword"]; 01232 if(p_pdsLabel.HasKeyword(key)) { 01233 QString value = p_pdsLabel[key]; 01234 QString pattern = projDef.Group(g)["Pattern"]; 01235 // If value contains pattern, then set the mults to what is in translation file 01236 if(value.contains(pattern)) { 01237 xmult = projDef.Group(g)["xMult"]; 01238 ymult = projDef.Group(g)["yMult"]; 01239 xoff = projDef.Group(g)["xOff"]; 01240 yoff = projDef.Group(g)["yOff"]; 01241 return; 01242 } 01243 } 01244 } 01245 } 01246 01254 void ProcessImportPds::ImportTable(QString pdsTableName) { 01255 // No table file given, let ImportPdsTable find it. 01256 ImportPdsTable pdsTable(p_labelFile, "", pdsTableName); 01257 // reformat the table name. If the name ends with the word "Table", remove 01258 // it. (So, for example, INSTRUMENT_POINTING_TABLE gets formatted to 01259 // InstrumentPointingTable and then to InstrumentPointing) 01260 QString isisTableName = pdsTable.getFormattedName(pdsTableName); 01261 int found = isisTableName.lastIndexOf("Table"); 01262 if (found == isisTableName.length() - 5) { 01263 isisTableName.remove(found, 5); 01264 } 01265 01266 Table isisTable = pdsTable.importTable(isisTableName); 01267 p_tables.push_back(isisTable); 01268 } 01269 01273 void ProcessImportPds::StartProcess() { 01274 ProcessImport::StartProcess(); 01275 for (unsigned int i = 0; i < p_tables.size(); i++) { 01276 OutputCubes[0]->write(p_tables[i]); 01277 } 01278 return; 01279 } 01280 }