std::vector<ImportDescriptor*> FitsImporter::getImportDescriptors(const std::string& fname) { std::string filename = fname; std::vector<std::vector<std::string> >& errors = mErrors[fname]; std::vector<std::vector<std::string> >& warnings = mWarnings[fname]; errors.clear(); warnings.clear(); int status=0; std::vector<ImportDescriptor*> descriptors; FitsFileResource pFile(filename); if (!pFile.isValid()) { errors.resize(1); errors[0].push_back(pFile.getStatus()); RETURN_DESCRIPTORS; } int hduCnt = 0; int specificHdu = 0; int hdu = 1; if (!splitFilename(filename, hduCnt, specificHdu, hdu, pFile, errors, warnings)) { RETURN_DESCRIPTORS; } errors.resize(hduCnt+1); warnings.resize(hduCnt+1); for(; hdu <= hduCnt; ++hdu) { std::string datasetName = filename + "[" + StringUtilities::toDisplayString(hdu) + "]"; int hduType; CHECK_FITS(fits_movabs_hdu(pFile, hdu, &hduType, &status), hdu, false, continue); ImportDescriptorResource pImportDescriptor(static_cast<ImportDescriptor*>(NULL)); FactoryResource<DynamicObject> pMetadata; VERIFYRV(pMetadata.get() != NULL, descriptors); { // scope std::vector<std::string> comments; char pCard[81]; char pValue[81]; char pComment[81]; int nkeys = 0; CHECK_FITS(fits_get_hdrspace(pFile, &nkeys, NULL, &status), hdu, true, ;); for(int keyidx = 1; keyidx <= nkeys; ++keyidx) { CHECK_FITS(fits_read_keyn(pFile, keyidx, pCard, pValue, pComment, &status), hdu, true, continue); std::string name = StringUtilities::stripWhitespace(std::string(pCard)); std::string val = StringUtilities::stripWhitespace(std::string(pValue)); std::string comment = StringUtilities::stripWhitespace(std::string(pComment)); if (!val.empty()) { pMetadata->setAttributeByPath("FITS/" + name, val); } else if (!comment.empty()) { comments.push_back(comment); } } if (!comments.empty()) { // ideally, this would add a multi-line string but Opticks doesn't display this properly // pMetadata->setAttributeByPath("FITS/COMMENT", StringUtilities::join(comments, "\n")); for(unsigned int idx = 0; idx < comments.size(); ++idx) { pMetadata->setAttributeByPath("FITS/COMMENT/" + StringUtilities::toDisplayString(idx), comments[idx]); } } } switch(hduType) { case IMAGE_HDU: { pImportDescriptor = ImportDescriptorResource(datasetName, TypeConverter::toString<RasterElement>()); VERIFYRV(pImportDescriptor.get() != NULL, descriptors); EncodingType fileEncoding; InterleaveFormatType interleave(BSQ); unsigned int rows=0; unsigned int cols=0; unsigned int bands=1; int bitpix; int naxis; long axes[3]; CHECK_FITS(fits_get_img_param(pFile, 3, &bitpix, &naxis, axes, &status), hdu, false, continue); switch(bitpix) { case BYTE_IMG: fileEncoding = INT1UBYTE; break; case SHORT_IMG: fileEncoding = INT2SBYTES; break; case LONG_IMG: fileEncoding = INT4SBYTES; break; case FLOAT_IMG: fileEncoding = FLT4BYTES; break; case DOUBLE_IMG: fileEncoding = FLT8BYTES; break; default: warnings[hdu].push_back("Unsupported BITPIX value " + StringUtilities::toDisplayString(bitpix) + "."); continue; } EncodingType dataEncoding = checkForOverflow(fileEncoding, pMetadata.get(), hdu, errors, warnings); if (naxis == 1) { // 1-D data is a signature pImportDescriptor = ImportDescriptorResource(datasetName, TypeConverter::toString<Signature>()); pMetadata->setAttributeByPath(METADATA_SIG_ENCODING, dataEncoding); pMetadata->setAttributeByPath(METADATA_SIG_LENGTH, axes[0]); RasterUtilities::generateAndSetFileDescriptor(pImportDescriptor->getDataDescriptor(), filename, StringUtilities::toDisplayString(hdu), BIG_ENDIAN_ORDER); // add units SignatureDataDescriptor* pSigDd = dynamic_cast<SignatureDataDescriptor*>(pImportDescriptor->getDataDescriptor()); if (pSigDd != NULL) { FactoryResource<Units> pUnits; pUnits->setUnitName("Custom"); pUnits->setUnitType(CUSTOM_UNIT); pSigDd->setUnits("Reflectance", pUnits.get()); } break; // leave switch() } else if (naxis == 2) { cols = axes[0]; rows = axes[1]; } else if (naxis == 3) { cols = axes[0]; rows = axes[1]; bands = axes[2]; } else { errors[hdu].push_back(StringUtilities::toDisplayString(naxis) + " axis data not supported."); } RasterDataDescriptor* pDataDesc = RasterUtilities::generateRasterDataDescriptor( datasetName, NULL, rows, cols, bands, interleave, dataEncoding, IN_MEMORY); pImportDescriptor->setDataDescriptor(pDataDesc); if (specificHdu == 0 && hdu == 1 && naxis == 2 && (axes[0] <= 5 || axes[1] <= 5)) { // use 5 as this is a good top end for the number of astronomical band pass filters // in general usage. this is not in a spec anywhere and is derived from various sample // FITS files for different astronomical instruments. // // There's a good chance this is really a spectrum. (0th HDU) // We'll create an import descriptor for the spectrum version of this // And disable the raster descriptor by default pImportDescriptor->setImported(false); ImportDescriptorResource pSigDesc(datasetName, TypeConverter::toString<SignatureLibrary>()); DynamicObject* pSigMetadata = pSigDesc->getDataDescriptor()->getMetadata(); pSigMetadata->merge(pMetadata.get()); std::vector<double> centerWavelengths; unsigned int cnt = (axes[0] <= 5) ? axes[1] : axes[0]; double startVal = StringUtilities::fromDisplayString<double>( dv_cast<std::string>(pMetadata->getAttributeByPath("FITS/MINWAVE"), "0.0")); double endVal = StringUtilities::fromDisplayString<double>( dv_cast<std::string>(pMetadata->getAttributeByPath("FITS/MAXWAVE"), "0.0")); double incr = (endVal == 0.0) ? 1.0 : ((endVal - startVal) / static_cast<double>(cnt)); centerWavelengths.reserve(cnt); for (unsigned int idx = 0; idx < cnt; idx++) { centerWavelengths.push_back(startVal + (idx * incr)); } pSigMetadata->setAttributeByPath(CENTER_WAVELENGTHS_METADATA_PATH, centerWavelengths); // Units std::string unitsName = dv_cast<std::string>(pMetadata->getAttributeByPath("FITS/BUNIT"), std::string()); if (!unitsName.empty()) { FactoryResource<Units> units; units->setUnitName(unitsName); units->setUnitType(RADIANCE); SignatureDataDescriptor* pSigDd = dynamic_cast<SignatureDataDescriptor*>(pSigDesc->getDataDescriptor()); if (pSigDd != NULL) { pSigDd->setUnits("Reflectance", units.get()); } } RasterUtilities::generateAndSetFileDescriptor(pSigDesc->getDataDescriptor(), filename, StringUtilities::toDisplayString(hdu), BIG_ENDIAN_ORDER); // If units are not available, set custom units into the data descriptor so that the user can // modify them - this must occur after the call to RasterUtilities::generateAndSetFileDescriptor() // so that the file descriptor will still display no defined units if (unitsName.empty()) { FactoryResource<Units> units; units->setUnitName("Custom"); units->setUnitType(CUSTOM_UNIT); SignatureDataDescriptor* pSigDd = dynamic_cast<SignatureDataDescriptor*>(pSigDesc->getDataDescriptor()); if (pSigDd != NULL) { pSigDd->setUnits("Reflectance", units.get()); } } descriptors.push_back(pSigDesc.release()); } RasterFileDescriptor* pFileDescriptor = dynamic_cast<RasterFileDescriptor*>( RasterUtilities::generateAndSetFileDescriptor(pDataDesc, filename, StringUtilities::toDisplayString(hdu), BIG_ENDIAN_ORDER)); if (pFileDescriptor != NULL) { unsigned int bitsPerElement = RasterUtilities::bytesInEncoding(fileEncoding) * 8; pFileDescriptor->setBitsPerElement(bitsPerElement); } break; // leave switch() } case ASCII_TBL: case BINARY_TBL: warnings[hdu].push_back("Tables not supported. [HDU " + StringUtilities::toDisplayString(hdu) + "]"); continue; default: warnings[hdu].push_back("HDU " + StringUtilities::toDisplayString(hdu) + " is an unknown type."); continue; } pImportDescriptor->getDataDescriptor()->setMetadata(pMetadata.release()); pImportDescriptor->setImported(errors[hdu].empty()); descriptors.push_back(pImportDescriptor.release()); }
void SpectralLibraryMatchResults::createAverageSignature() { Service<DesktopServices> pDesktop; const RasterElement* pRaster = getRasterElementForCurrentPage(); if (pRaster == NULL) { pDesktop->showMessageBox("Spectral Library Match", "Unable to determine the RasterElement for the current page."); return; } std::vector<Signature*> signatures = getSelectedSignatures(); if (signatures.empty()) { pDesktop->showMessageBox("Spectral Library Match", "No signatures are selected for use in generating an average signature."); return; } // now need to get the resampled sigs from the library SpectralLibraryManager* pLibMgr(NULL); std::vector<PlugIn*> plugIns = Service<PlugInManagerServices>()->getPlugInInstances(SpectralLibraryMatch::getNameLibraryManagerPlugIn()); if (!plugIns.empty()) { pLibMgr = dynamic_cast<SpectralLibraryManager*>(plugIns.front()); } if (pLibMgr == NULL) { pDesktop->showMessageBox("Spectral Library Match", "Unable to access the Spectral Library Manager."); return; } const RasterDataDescriptor* pDesc = dynamic_cast<const RasterDataDescriptor*>(pRaster->getDataDescriptor()); if (pDesc == NULL) { pDesktop->showMessageBox("Spectral Library Match", "Unable to access the RasterDataDescriptor for the RasterElement of the current page."); return; } unsigned int numBands = pDesc->getBandCount(); std::vector<double> averageValues(numBands, 0); std::vector<double> values; for (std::vector<Signature*>::iterator it = signatures.begin(); it != signatures.end(); ++it) { if (pLibMgr->getResampledSignatureValues(pRaster, *it, values) == false) { pDesktop->showMessageBox("Spectral Library Match", "Unable to access the resampled signature values for " + (*it)->getDisplayName(true)); return; } for (unsigned int band = 0; band < numBands; ++band) { averageValues[band] += values[band]; } } unsigned int numSigs = signatures.size(); for (unsigned int band = 0; band < numBands; ++band) { averageValues[band] /= static_cast<double>(numSigs); } QString avgName = QInputDialog::getText(pDesktop->getMainWidget(), "Spectral Library Match", "Enter the name to use for the average signature:"); if (avgName.isEmpty()) { return; } ModelResource<Signature> pAvgSig(avgName.toStdString(), const_cast<RasterElement*>(pRaster)); pAvgSig->setData("Reflectance", averageValues); const DynamicObject* pMetaData = pRaster->getMetadata(); FactoryResource<Wavelengths> pWavelengths; pWavelengths->initializeFromDynamicObject(pMetaData, false); const std::vector<double>& centerValues = pWavelengths->getCenterValues(); pAvgSig->setData("Wavelength", centerValues); SignatureDataDescriptor* pSigDesc = dynamic_cast<SignatureDataDescriptor*>(pAvgSig->getDataDescriptor()); VERIFYNRV(pSigDesc != NULL); FactoryResource<Units> pUnits; const Units* pRasterUnits = pDesc->getUnits(); pUnits->setUnitName(pRasterUnits->getUnitName()); pUnits->setUnitType(pRasterUnits->getUnitType()); pUnits->setScaleFromStandard(1.0); // the rescaled values are already corrected for the original scaling factor pUnits->setRangeMin(pRasterUnits->getRangeMin()); pUnits->setRangeMax(pRasterUnits->getRangeMax()); pSigDesc->setUnits("Reflectance", pUnits.get()); pAvgSig.release(); }
bool SpectralLibraryManager::generateResampledLibrary(const RasterElement* pRaster) { VERIFY(pRaster != NULL); // check that lib sigs are in same units as the raster element const RasterDataDescriptor* pDesc = dynamic_cast<const RasterDataDescriptor*>(pRaster->getDataDescriptor()); VERIFY(pDesc != NULL); const Units* pUnits = pDesc->getUnits(); if (pDesc->getUnits()->getUnitType() != mLibraryUnitType) { if (Service<DesktopServices>()->showMessageBox("Mismatched Units", "The data are not in the " "same units as the spectral library.\n Do you want to continue anyway?", "Yes", "No") == 1) { return false; } } FactoryResource<Wavelengths> pWavelengths; pWavelengths->initializeFromDynamicObject(pRaster->getMetadata(), false); // populate the library with the resampled signatures PlugInResource pPlugIn("Resampler"); Resampler* pResampler = dynamic_cast<Resampler*>(pPlugIn.get()); VERIFY(pResampler != NULL); if (pWavelengths->getNumWavelengths() != pDesc->getBandCount()) { mpProgress->updateProgress("Wavelength information in metadata does not match the number of bands " "in the raster element", 0, ERRORS); return false; } // get resample suitable signatures - leave out signatures that don't cover the spectral range of the data std::vector<std::vector<double> > resampledData; resampledData.reserve(mSignatures.size()); std::vector<Signature*> resampledSignatures; resampledSignatures.reserve(mSignatures.size()); std::vector<std::string> unsuitableSignatures; std::vector<double> sigValues; std::vector<double> sigWaves; std::vector<double> rasterWaves = pWavelengths->getCenterValues(); std::vector<double> rasterFwhm = pWavelengths->getFwhm(); std::vector<double> resampledValues; std::vector<int> bandIndex; DataVariant data; for (std::vector<Signature*>::const_iterator it = mSignatures.begin(); it != mSignatures.end(); ++it) { data = (*it)->getData(SpectralLibraryMatch::getNameSignatureWavelengthData()); VERIFY(data.isValid()); VERIFY(data.getValue(sigWaves)); resampledValues.clear(); data = (*it)->getData(SpectralLibraryMatch::getNameSignatureAmplitudeData()); VERIFY(data.isValid()); VERIFY(data.getValue(sigValues)); double scaleFactor = (*it)->getUnits( SpectralLibraryMatch::getNameSignatureAmplitudeData())->getScaleFromStandard(); for (std::vector<double>::iterator sit = sigValues.begin(); sit != sigValues.end(); ++sit) { *sit *= scaleFactor; } std::string msg; if (pResampler->execute(sigValues, resampledValues, sigWaves, rasterWaves, rasterFwhm, bandIndex, msg) == false || resampledValues.size() != rasterWaves.size()) { unsuitableSignatures.push_back((*it)->getName()); continue; } resampledData.push_back(resampledValues); resampledSignatures.push_back(*it); } if (resampledSignatures.empty()) { std::string errMsg = "None of the signatures in the library cover the spectral range of the data."; if (mpProgress != NULL) { mpProgress->updateProgress(errMsg, 0, ERRORS); return false; } } if (unsuitableSignatures.empty() == false) { std::string warningMsg = "The following library signatures do not cover the spectral range of the data:\n"; for (std::vector<std::string>::iterator it = unsuitableSignatures.begin(); it != unsuitableSignatures.end(); ++it) { warningMsg += *it + "\n"; } warningMsg += "These signatures will not be searched for in the data."; Service<DesktopServices>()->showMessageBox("SpectralLibraryManager", warningMsg); StepResource pStep("Spectral LibraryManager", "spectral", "64B6C87A-A6C3-4378-9B6E-221D89D8707B"); pStep->finalize(Message::Unresolved, warningMsg); } std::string libName = "Resampled Spectral Library"; // Try to get the resampled lib element in case session was restored. If NULL, create a new raster element with // num rows = num valid signatures, num cols = 1, num bands = pRaster num bands RasterElement* pLib = dynamic_cast<RasterElement*>(Service<ModelServices>()->getElement(libName, TypeConverter::toString<RasterElement>(), pRaster)); if (pLib != NULL) { // check that pLib has same number of sigs as SpectralLibraryManager RasterDataDescriptor* pLibDesc = dynamic_cast<RasterDataDescriptor*>(pLib->getDataDescriptor()); VERIFY(pLibDesc != NULL); if (pLibDesc->getRowCount() != mSignatures.size()) { mpProgress->updateProgress("An error occurred during session restore and some signatures were not restored." " Check the spectral library before using.", 0, ERRORS); Service<ModelServices>()->destroyElement(pLib); pLib = NULL; } } bool isNewElement(false); if (pLib == NULL) { pLib = RasterUtilities::createRasterElement(libName, static_cast<unsigned int>(resampledData.size()), 1, pDesc->getBandCount(), FLT8BYTES, BIP, true, const_cast<RasterElement*>(pRaster)); isNewElement = true; } if (pLib == NULL) { mpProgress->updateProgress("Error occurred while trying to create the resampled spectral library", 0, ERRORS); return false; } RasterDataDescriptor* pLibDesc = dynamic_cast<RasterDataDescriptor*>(pLib->getDataDescriptor()); VERIFY(pLibDesc != NULL); // copy resampled data into new element if (isNewElement) { FactoryResource<DataRequest> pRequest; pRequest->setWritable(true); pRequest->setRows(pLibDesc->getActiveRow(0), pLibDesc->getActiveRow(pLibDesc->getRowCount()-1), 1); DataAccessor acc = pLib->getDataAccessor(pRequest.release()); for (std::vector<std::vector<double> >::iterator sit = resampledData.begin(); sit != resampledData.end(); ++sit) { VERIFY(acc->isValid()); void* pData = acc->getColumn(); memcpy(acc->getColumn(), &(sit->begin()[0]), pLibDesc->getBandCount() * sizeof(double)); acc->nextRow(); } // set wavelength info in resampled library pWavelengths->applyToDynamicObject(pLib->getMetadata()); FactoryResource<Units> libUnits; libUnits->setUnitType(mLibraryUnitType); libUnits->setUnitName(StringUtilities::toDisplayString<UnitType>(mLibraryUnitType)); pLibDesc->setUnits(libUnits.get()); } pLib->attach(SIGNAL_NAME(Subject, Deleted), Slot(this, &SpectralLibraryManager::resampledElementDeleted)); mLibraries[pRaster] = pLib; mResampledSignatures[pLib] = resampledSignatures; const_cast<RasterElement*>(pRaster)->attach(SIGNAL_NAME(Subject, Deleted), Slot(this, &SpectralLibraryManager::elementDeleted)); return true; }
vector<ImportDescriptor*> EnviLibraryImporter::getImportDescriptors(const string& filename) { vector<ImportDescriptor*> descriptors; string headerFile = filename; string dataFile; // assume filename is a header file and try to parse bool bSuccess = mFields.populateFromHeader(filename); if (bSuccess == false) { dataFile = filename; // was passed data file name instead of header file name headerFile = findHeaderFile(dataFile); if (headerFile.empty() == false) { bSuccess = mFields.populateFromHeader(headerFile); } } if (bSuccess == true) { if (dataFile.empty()) // was passed header file name and now need to find the data file name { dataFile = findDataFile(headerFile); } if (dataFile.empty()) // no data file found for the header { return descriptors; } EnviField* pField = mFields.find("file type"); if (pField != NULL) { if (pField->mValue == "ENVI Spectral Library" || pField->mValue == "Spectral Library") { // Get the name and dataset from the header values string name; string dataset; EnviField* pBandNamesField = mFields.find("band names"); if (pBandNamesField != NULL) { if (pBandNamesField->mChildren.empty() == false) { EnviField* pNameField = pBandNamesField->mChildren.front(); if (pNameField != NULL) { name = pNameField->mValue; } } } EnviField* pDescriptionField = mFields.find("description"); if (pDescriptionField != NULL) { // Library name if (name.empty() == true) { EnviField* pNameField = pDescriptionField->find("library name"); if (pNameField != NULL) { name = pNameField->mValue; } } // Dataset EnviField* pDatasetField = pDescriptionField->find("dataset"); if (pDatasetField != NULL) { dataset = pDatasetField->mValue; } } // Create the data descriptor Service<ModelServices> pModel; RasterElement* pRasterElement = NULL; if (dataset.empty() == false) { pRasterElement = dynamic_cast<RasterElement*>(pModel->getElement(dataset, "RasterElement", NULL)); } if (name.empty() == true) { // Create a unique default name unsigned int libraryNumber = pModel->getElements(pRasterElement, "SignatureLibrary").size(); DataElement* pSignatureLibrary = NULL; do { char buffer[64]; sprintf(buffer, "%u", ++libraryNumber); name = "Spectral Library " + string(buffer); pSignatureLibrary = pModel->getElement(name, "SignatureLibrary", pRasterElement); } while (pSignatureLibrary != NULL); } ImportDescriptor* pImportDescriptor = pModel->createImportDescriptor(name, "SignatureLibrary", pRasterElement); if (pImportDescriptor != NULL) { SignatureDataDescriptor* pDescriptor = dynamic_cast<SignatureDataDescriptor*>(pImportDescriptor->getDataDescriptor()); if (pDescriptor != NULL) { // Metadata FactoryResource<DynamicObject> pMetadata; if (pDescriptionField != NULL) { vector<EnviField*>& children = pDescriptionField->mChildren; for (vector<EnviField*>::iterator iter = children.begin(); iter != children.end(); ++iter) { EnviField* pField = *iter; if (pField != NULL) { if ((pField->mTag.empty() == false) && (pField->mValue.empty() == false)) { pMetadata->setAttribute(pField->mTag, pField->mValue); } } } } // Signature names EnviField* pSigNamesField = mFields.find("spectra names"); if (pSigNamesField != NULL) { vector<string> sigNames; for (unsigned int i = 0; i < pSigNamesField->mChildren.size(); i++) { EnviField* pField = pSigNamesField->mChildren[i]; if (pField != NULL) { vector<char> bufferVector(pField->mValue.size() + 1); char* pBuffer = &bufferVector.front(); strcpy(pBuffer, pField->mValue.c_str()); char* pPtr = strtok(pBuffer, ","); while (pPtr != NULL) { string sigName = StringUtilities::stripWhitespace(string(pPtr)); sigNames.push_back(sigName); pPtr = strtok(NULL, ","); } } } if (sigNames.empty() == false) { pMetadata->setAttribute("Signature Names", sigNames); } } // Signature units - Set custom units into the data descriptor so that the // user can modify them even though units are not loaded from the file FactoryResource<Units> pUnits; pUnits->setUnitName("Custom"); pUnits->setUnitType(CUSTOM_UNIT); pDescriptor->setUnits("Reflectance", pUnits.get()); // Wavelengths EnviField* pSamplesField = mFields.find("samples"); if (pSamplesField != NULL) { unsigned int numWavelengths = StringUtilities::fromXmlString<unsigned int>(pSamplesField->mValue); vector<double> wavelengths; unsigned int uiNanometerValues = 0; EnviField* pWavelengthField = mFields.find("wavelength"); if (pWavelengthField != NULL) { vector<unsigned int> goodBands; EnviField* pBblField = mFields.find("bbl"); if (pBblField != NULL) { // Parse the bad bands list. This method puts the indices of good bands in ascending order. EnviImporter::parseBbl(pBblField, goodBands); // Sort in descending order so that the last one can be popped later // A pop_back is much faster than an erase on the first element reverse(goodBands.begin(), goodBands.end()); } unsigned int numWavelengthsRead = 0; for (std::vector<EnviField*>::const_iterator iter = pWavelengthField->mChildren.begin(); iter != pWavelengthField->mChildren.end(); ++iter) { EnviField* pField = *iter; if (pField != NULL) { vector<char> bufferVector(pField->mValue.size() + 1); char* pBuffer = &(bufferVector.front()); strcpy(pBuffer, pField->mValue.c_str()); char* pPtr = strtok(pBuffer, ","); while (pPtr != NULL) { double dWavelength = 0.0; if (sscanf(pPtr, "%lf", &dWavelength) == 1) { if (dWavelength > 50.0) // Assumed to be in nanometers { uiNanometerValues++; } // Restrict the number of wavelengths to the number of samples in the header file if (numWavelengthsRead < numWavelengths) { // Only write the wavelength if the value is valid // Since the bands are in descending order, // goodBands.back() always holds the next good band. if (pBblField == NULL || (goodBands.empty() == false && goodBands.back() == numWavelengthsRead)) { if (goodBands.empty() == false) { goodBands.pop_back(); } wavelengths.push_back(dWavelength); } } ++numWavelengthsRead; } pPtr = strtok(NULL, ","); } } } VERIFYNR(goodBands.empty() == true); } // Wavelength units bool bConvertWavelengths = false; bool bDetermineUnits = true; EnviField* pUnitsField = mFields.find("wavelength units"); if (pUnitsField != NULL) { if (pUnitsField->mValue == "Micrometers") { bDetermineUnits = false; } else if (pUnitsField->mValue == "Nanometers") { bDetermineUnits = false; bConvertWavelengths = true; } } if (bDetermineUnits) { if ((uiNanometerValues * 100) / wavelengths.size() > 50) { bConvertWavelengths = true; } } if (bConvertWavelengths == true) { for (vector<double>::size_type i = 0; i < wavelengths.size(); i++) { wavelengths[i] *= 0.001; } } string pCenterPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, CENTER_WAVELENGTHS_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pCenterPath, wavelengths); } if (pMetadata->getNumAttributes() > 0) { pDescriptor->setMetadata(pMetadata.get()); } // Create the file descriptor FactoryResource<SignatureFileDescriptor> pFileDescriptor; if (pFileDescriptor.get() != NULL) { pFileDescriptor->setFilename(dataFile); pDescriptor->setFileDescriptor(pFileDescriptor.get()); } } descriptors.push_back(pImportDescriptor); } } } } return descriptors; }
vector<ImportDescriptor*> SioImporter::getImportDescriptors(const string& filename) { vector<ImportDescriptor*> descriptors; if (filename.empty() == false) { // Read the header values FileResource pFile(filename.c_str(), "rb"); SioFile sioFile; bool bSuccess = sioFile.deserialize(pFile.get()); if (bSuccess == false) { return descriptors; } if (sioFile.mOriginalVersion == 9) { mVersion9Sio = true; } // Create the import descriptor ImportDescriptor* pImportDescriptor = mpModel->createImportDescriptor(filename, "RasterElement", NULL); if (pImportDescriptor != NULL) { RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pImportDescriptor->getDataDescriptor()); if (pDescriptor != NULL) { FactoryResource<RasterFileDescriptor> pFileDescriptor; if (pFileDescriptor.get() != NULL) { // Filename pFileDescriptor->setFilename(filename); // Endian pFileDescriptor->setEndian(sioFile.mEndian); // Rows vector<DimensionDescriptor> rows; for (int i = 0; i < sioFile.mRows; ++i) { DimensionDescriptor rowDim; // Do not set an active number since the user has not selected the rows to load if (static_cast<unsigned int>(i) < sioFile.mOrigRowNumbers.size()) { rowDim.setOriginalNumber(sioFile.mOrigRowNumbers[i]); } else { rowDim.setOriginalNumber(i); } rowDim.setOnDiskNumber(i); rows.push_back(rowDim); } pDescriptor->setRows(rows); pFileDescriptor->setRows(rows); // Columns vector<DimensionDescriptor> columns; for (int i = 0; i < sioFile.mColumns; ++i) { DimensionDescriptor columnDim; // Do not set an active number since the user has not selected the rows to load if (static_cast<unsigned int>(i) < sioFile.mOrigColumnNumbers.size()) { columnDim.setOriginalNumber(sioFile.mOrigColumnNumbers[i]); } else { columnDim.setOriginalNumber(i); } columnDim.setOnDiskNumber(i); columns.push_back(columnDim); } pDescriptor->setColumns(columns); pFileDescriptor->setColumns(columns); // Bands vector<DimensionDescriptor> bands; for (int i = 0; i < (sioFile.mBands - sioFile.mBadBands); ++i) { DimensionDescriptor bandDim; // Do not set an active number since the user has not selected the rows to load if (static_cast<unsigned int>(i) < sioFile.mOrigBandNumbers.size()) { bandDim.setOriginalNumber(sioFile.mOrigBandNumbers[i]); } else { bandDim.setOriginalNumber(i); } bandDim.setOnDiskNumber(i); bands.push_back(bandDim); } pDescriptor->setBands(bands); pFileDescriptor->setBands(bands); // Bits per pixel pFileDescriptor->setBitsPerElement(sioFile.mBitsPerElement); // Data type pDescriptor->setDataType(sioFile.mDataType); pDescriptor->setValidDataTypes(vector<EncodingType>(1, sioFile.mDataType)); // Interleave format pDescriptor->setInterleaveFormat(BIP); pFileDescriptor->setInterleaveFormat(BIP); // Bad values if (sioFile.mBadValues.empty() == true) { if ((sioFile.mDataType != FLT4BYTES) && (sioFile.mDataType != FLT8COMPLEX) && (sioFile.mDataType != FLT8BYTES)) { vector<int> badValues; badValues.push_back(0); pDescriptor->setBadValues(badValues); } } // Header bytes pFileDescriptor->setHeaderBytes(28); // Trailer bytes struct stat statBuffer; if (stat(filename.c_str(), &statBuffer) == 0) { double dataBytes = 28 + (sioFile.mRows * sioFile.mColumns * (sioFile.mBands - sioFile.mBadBands) * (sioFile.mBitsPerElement / 8)); pFileDescriptor->setTrailerBytes(static_cast<unsigned int>(statBuffer.st_size - dataBytes)); } // Units FactoryResource<Units> pUnits; pUnits->setUnitType(sioFile.mUnitType); pUnits->setUnitName(sioFile.mUnitName); pUnits->setRangeMin(sioFile.mRangeMin); pUnits->setRangeMax(sioFile.mRangeMax); pUnits->setScaleFromStandard(sioFile.mScale); pDescriptor->setUnits(pUnits.get()); pFileDescriptor->setUnits(pUnits.get()); // GCPs GcpPoint gcpLowerLeft; gcpLowerLeft.mPixel.mX = 0.0; gcpLowerLeft.mPixel.mY = 0.0; GcpPoint gcpLowerRight; gcpLowerRight.mPixel.mX = sioFile.mColumns - 1.0; gcpLowerRight.mPixel.mY = 0.0; GcpPoint gcpUpperLeft; gcpUpperLeft.mPixel.mX = 0.0; gcpUpperLeft.mPixel.mY = sioFile.mRows - 1.0; GcpPoint gcpUpperRight; gcpUpperRight.mPixel.mX = sioFile.mColumns - 1.0; gcpUpperRight.mPixel.mY = sioFile.mRows - 1.0; GcpPoint gcpCenter; gcpCenter.mPixel.mX = sioFile.mColumns / 2.0 - 0.5; gcpCenter.mPixel.mY = sioFile.mRows / 2.0 - 0.5; bool bValidGcps = false; for (int i = ORIGINAL_SENSOR; i < INVALID_LAST_ENUM_ITEM_FLAG; ++i) { if (sioFile.mParameters[i].eParameter_Initialized == true) { switch (i) { case UPPER_LEFT_CORNER_LAT: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpUpperLeft.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpUpperLeft.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case UPPER_LEFT_CORNER_LONG: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpUpperLeft.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpUpperLeft.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case LOWER_LEFT_CORNER_LAT: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpLowerLeft.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpLowerLeft.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case LOWER_LEFT_CORNER_LONG: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpLowerLeft.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpLowerLeft.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case UPPER_RIGHT_CORNER_LAT: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpUpperRight.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpUpperRight.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case UPPER_RIGHT_CORNER_LONG: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpUpperRight.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpUpperRight.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case LOWER_RIGHT_CORNER_LAT: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpLowerRight.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpLowerRight.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case LOWER_RIGHT_CORNER_LONG: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpLowerRight.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpLowerRight.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case CENTER_LAT: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpCenter.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpCenter.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case CENTER_LONG: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpCenter.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpCenter.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; default: break; } } } if (bValidGcps == true) { list<GcpPoint> gcps; gcps.push_back(gcpLowerLeft); gcps.push_back(gcpLowerRight); gcps.push_back(gcpUpperLeft); gcps.push_back(gcpUpperRight); gcps.push_back(gcpCenter); pFileDescriptor->setGcps(gcps); } // Classification pDescriptor->setClassification(sioFile.mpClassification.get()); // Metadata pDescriptor->setMetadata(sioFile.mpMetadata.get()); DynamicObject* pMetadata = pDescriptor->getMetadata(); if (pMetadata != NULL) { vector<double> startWavelengths(sioFile.mStartWavelengths.size()); copy(sioFile.mStartWavelengths.begin(), sioFile.mStartWavelengths.end(), startWavelengths.begin()); vector<double> endWavelengths(sioFile.mEndWavelengths.size()); copy(sioFile.mEndWavelengths.begin(), sioFile.mEndWavelengths.end(), endWavelengths.begin()); vector<double> centerWavelengths(sioFile.mCenterWavelengths.size()); copy(sioFile.mCenterWavelengths.begin(), sioFile.mCenterWavelengths.end(), centerWavelengths.begin()); string pStartPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, START_WAVELENGTHS_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pStartPath, startWavelengths); string pEndPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, END_WAVELENGTHS_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pEndPath, endWavelengths); string pCenterPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, CENTER_WAVELENGTHS_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pCenterPath, centerWavelengths); } // File descriptor pDescriptor->setFileDescriptor(pFileDescriptor.get()); } } descriptors.push_back(pImportDescriptor); } } return descriptors; }
std::vector<ImportDescriptor*> LandsatGeotiffImporter::createImportDescriptors(const std::string& filename, const DynamicObject* pImageMetadata, Landsat::LandsatImageType type) { std::string suffix; if (type == Landsat::LANDSAT_VNIR) { suffix = "vnir"; } else if (type == Landsat::LANDSAT_PAN) { suffix = "pan"; } else if (type == Landsat::LANDSAT_TIR) { suffix = "tir"; } std::vector<ImportDescriptor*> descriptors; std::string spacecraft = dv_cast<std::string>( pImageMetadata->getAttributeByPath("LANDSAT_MTL/L1_METADATA_FILE/PRODUCT_METADATA/SPACECRAFT_ID"), ""); std::vector<std::string> bandNames = Landsat::getSensorBandNames(spacecraft, type); if (bandNames.empty()) { //this spacecraft and iamge type //isn't meant to have any bands, so terminate early //e.g. spacecraft == "Landsat5" && type == Landsat::LANDSAT_PAN return descriptors; } std::vector<unsigned int> validBands; std::vector<std::string> bandFiles = Landsat::getGeotiffBandFilenames( pImageMetadata, filename, type, validBands); if (bandFiles.empty()) { mWarnings.push_back("Unable to locate band files for " + suffix + " product."); return descriptors; } ImportDescriptorResource pImportDescriptor(filename + "-" + suffix, TypeConverter::toString<RasterElement>(), NULL, false); if (pImportDescriptor.get() == NULL) { return descriptors; } RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pImportDescriptor->getDataDescriptor()); if (pDescriptor == NULL) { return descriptors; } pDescriptor->setProcessingLocation(ON_DISK); DynamicObject* pMetadata = pDescriptor->getMetadata(); pMetadata->merge(pImageMetadata); FactoryResource<RasterFileDescriptor> pFileDescriptorRes; pDescriptor->setFileDescriptor(pFileDescriptorRes.get()); RasterFileDescriptor* pFileDescriptor = dynamic_cast<RasterFileDescriptor*>(pDescriptor->getFileDescriptor()); pFileDescriptor->setFilename(filename); std::string tiffFile = bandFiles[0]; if (!Landsat::parseBasicsFromTiff(tiffFile, pDescriptor)) { mWarnings.push_back("Unable to parse basic information about image from tiff file for " + suffix + " product."); return descriptors; } if (pDescriptor->getBandCount() != 1 || pDescriptor->getDataType() != INT1UBYTE) { mWarnings.push_back("Improperly formatted tiff file for " + suffix + " product."); return descriptors; } pDescriptor->setInterleaveFormat(BSQ); //one tiff file per band. pFileDescriptor->setInterleaveFormat(BSQ); std::vector<DimensionDescriptor> bands = RasterUtilities::generateDimensionVector( bandFiles.size(), true, false, true); pDescriptor->setBands(bands); pFileDescriptor->setBands(bands); pDescriptor->setBadValues(std::vector<int>(1, 0)); pFileDescriptor->setDatasetLocation(suffix); //special metadata here Landsat::fixMtlMetadata(pMetadata, type, validBands); std::vector<std::string> defaultImport = OptionsLandsatImport::getSettingDefaultImport(); bool fallbackToDn = false; descriptors.push_back(pImportDescriptor.release()); if (type == Landsat::LANDSAT_VNIR) { //attempt to display true-color DimensionDescriptor redBand = RasterUtilities::findBandWavelengthMatch(0.630, 0.690, pDescriptor); DimensionDescriptor greenBand = RasterUtilities::findBandWavelengthMatch(0.510, 0.590, pDescriptor); DimensionDescriptor blueBand = RasterUtilities::findBandWavelengthMatch(0.410, 0.490, pDescriptor); if (redBand.isValid() && greenBand.isValid() && blueBand.isValid()) { pDescriptor->setDisplayMode(RGB_MODE); pDescriptor->setDisplayBand(RED, redBand); pDescriptor->setDisplayBand(GREEN, greenBand); pDescriptor->setDisplayBand(BLUE, blueBand); } } std::vector<std::pair<double, double> > radianceFactors = Landsat::determineRadianceConversionFactors( pMetadata, type, validBands); bool shouldDefaultImportRadiance = std::find(defaultImport.begin(), defaultImport.end(), suffix + "-Radiance") != defaultImport.end(); if (radianceFactors.size() == bandFiles.size()) { //we have enough to create radiance import descriptor RasterDataDescriptor* pRadianceDescriptor = dynamic_cast<RasterDataDescriptor*>( pDescriptor->copy(filename + "-" + suffix + "-radiance", NULL)); if (pRadianceDescriptor != NULL) { pRadianceDescriptor->setDataType(FLT4BYTES); pRadianceDescriptor->setValidDataTypes(std::vector<EncodingType>(1, pRadianceDescriptor->getDataType())); pRadianceDescriptor->setBadValues(std::vector<int>(1, -100)); FactoryResource<Units> pUnits; pUnits->setUnitType(RADIANCE); pUnits->setUnitName("w/(m^2*sr*um)"); pUnits->setScaleFromStandard(1.0); pRadianceDescriptor->setUnits(pUnits.get()); FileDescriptor* pRadianceFileDescriptor = pRadianceDescriptor->getFileDescriptor(); if (pRadianceFileDescriptor != NULL) { pRadianceFileDescriptor->setDatasetLocation(suffix + "-radiance"); ImportDescriptorResource pRadianceImportDescriptor(pRadianceDescriptor, shouldDefaultImportRadiance); descriptors.push_back(pRadianceImportDescriptor.release()); } } } else if (shouldDefaultImportRadiance) { fallbackToDn = true; } std::vector<double> reflectanceFactors = Landsat::determineReflectanceConversionFactors( pMetadata, type, validBands); bool shouldDefaultImportReflectance = std::find(defaultImport.begin(), defaultImport.end(), suffix + "-Reflectance") != defaultImport.end(); if (radianceFactors.size() == bandFiles.size() && reflectanceFactors.size() == bandFiles.size()) { //we have enough to create reflectance import descriptor RasterDataDescriptor* pReflectanceDescriptor = dynamic_cast<RasterDataDescriptor*>( pDescriptor->copy(filename + "-" + suffix + "-reflectance", NULL)); if (pReflectanceDescriptor != NULL) { pReflectanceDescriptor->setDataType(INT2SBYTES); pReflectanceDescriptor->setValidDataTypes( std::vector<EncodingType>(1, pReflectanceDescriptor->getDataType())); pReflectanceDescriptor->setBadValues(std::vector<int>(1, std::numeric_limits<short>::max())); FactoryResource<Units> pUnits; pUnits->setUnitType(REFLECTANCE); pUnits->setUnitName("Reflectance"); pUnits->setScaleFromStandard(1/10000.0); pReflectanceDescriptor->setUnits(pUnits.get()); FileDescriptor* pReflectanceFileDescriptor = pReflectanceDescriptor->getFileDescriptor(); if (pReflectanceFileDescriptor != NULL) { pReflectanceFileDescriptor->setDatasetLocation(suffix + "-reflectance"); ImportDescriptorResource pReflectanceImportDescriptor(pReflectanceDescriptor, shouldDefaultImportReflectance); descriptors.push_back(pReflectanceImportDescriptor.release()); } } } else if (shouldDefaultImportReflectance) { fallbackToDn = true; } double K1 = 0.0; double K2 = 0.0; bool haveTemperatureFactors = Landsat::getTemperatureConstants(pMetadata, type, K1, K2); bool shouldDefaultImportTemperature = std::find(defaultImport.begin(), defaultImport.end(), suffix + "-Temperature") != defaultImport.end(); if (radianceFactors.size() == bandFiles.size() && haveTemperatureFactors) { //we have enough to create temperature import descriptor RasterDataDescriptor* pTemperatureDescriptor = dynamic_cast<RasterDataDescriptor*>( pDescriptor->copy(filename + "-" + suffix + "-temperature", NULL)); if (pTemperatureDescriptor != NULL) { pTemperatureDescriptor->setDataType(FLT4BYTES); pTemperatureDescriptor->setValidDataTypes( std::vector<EncodingType>(1, pTemperatureDescriptor->getDataType())); pTemperatureDescriptor->setBadValues(std::vector<int>(1, -1)); FactoryResource<Units> pUnits; pUnits->setUnitType(EMISSIVITY); pUnits->setUnitName("K"); pUnits->setScaleFromStandard(1.0); pTemperatureDescriptor->setUnits(pUnits.get()); FileDescriptor* pTemperatureFileDescriptor = pTemperatureDescriptor->getFileDescriptor(); if (pTemperatureFileDescriptor != NULL) { pTemperatureFileDescriptor->setDatasetLocation(suffix + "-temperature"); ImportDescriptorResource pTemperatureImportDescriptor(pTemperatureDescriptor, shouldDefaultImportTemperature); descriptors.push_back(pTemperatureImportDescriptor.release()); } } } else if (shouldDefaultImportTemperature) { fallbackToDn = true; } if (fallbackToDn || std::find(defaultImport.begin(), defaultImport.end(), suffix + "-DN") != defaultImport.end()) { pImportDescriptor->setImported(true); } return descriptors; }
vector<ImportDescriptor*> SignatureImporter::getImportDescriptors(const string& filename) { vector<ImportDescriptor*> descriptors; if (filename.empty()) { return descriptors; } LargeFileResource pSigFile; if (!pSigFile.open(filename, O_RDONLY | O_BINARY, S_IREAD)) { return descriptors; } // load the data FactoryResource<DynamicObject> pMetadata; VERIFYRV(pMetadata.get() != NULL, descriptors); bool readError = false; string line; string unitName("Reflectance"); UnitType unitType(REFLECTANCE); double unitScale(1.0); // parse the metadata for (line = pSigFile.readLine(&readError); (readError == false) && (line.find('=') != string::npos); line = pSigFile.readLine(&readError)) { vector<string> metadataEntry; trim(line); split(metadataEntry, line, is_any_of("=")); if (metadataEntry.size() == 2) { string key = metadataEntry[0]; string value = metadataEntry[1]; trim(key); trim(value); if (ends_with(key, "Bands") || key == "Pixels") { pMetadata->setAttribute(key, StringUtilities::fromXmlString<unsigned long>(value)); } else if (key == "UnitName") { unitName = value; } else if (key == "UnitType") { unitType = StringUtilities::fromXmlString<UnitType>(value); } else if (key == "UnitScale") { unitScale = StringUtilities::fromXmlString<double>(value); } else { pMetadata->setAttribute(key, value); } } } if ((readError == true) && (pSigFile.eof() != 1)) { return descriptors; } // Verify that the next line contains float float pairs vector<string> dataEntry; trim(line); split(dataEntry, line, is_space()); if (dataEntry.size() != 2) { return descriptors; } bool error = false; StringUtilities::fromXmlString<float>(dataEntry[0], &error); !error && StringUtilities::fromXmlString<float>(dataEntry[1], &error); if (error) { return descriptors; } string datasetName = dv_cast<string>(pMetadata->getAttribute("Name"), filename); ImportDescriptorResource pImportDescriptor(datasetName, "Signature"); VERIFYRV(pImportDescriptor.get() != NULL, descriptors); SignatureDataDescriptor* pDataDescriptor = dynamic_cast<SignatureDataDescriptor*>(pImportDescriptor->getDataDescriptor()); VERIFYRV(pDataDescriptor != NULL, descriptors); FactoryResource<SignatureFileDescriptor> pFileDescriptor; VERIFYRV(pFileDescriptor.get() != NULL, descriptors); pFileDescriptor->setFilename(filename); FactoryResource<Units> pReflectanceUnits; VERIFYRV(pReflectanceUnits.get() != NULL, descriptors); pReflectanceUnits->setUnitName(unitName); pReflectanceUnits->setUnitType(unitType); if (unitScale != 0.0) { pReflectanceUnits->setScaleFromStandard(1.0 / unitScale); } pDataDescriptor->setUnits("Reflectance", pReflectanceUnits.get()); pFileDescriptor->setUnits("Reflectance", pReflectanceUnits.get()); pDataDescriptor->setFileDescriptor(pFileDescriptor.get()); pDataDescriptor->setMetadata(pMetadata.get()); descriptors.push_back(pImportDescriptor.release()); return descriptors; }
bool EditDataDescriptor::execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList) { StepResource pStep("Execute Wizard Item", "app", "055486F4-A9DB-4FDA-9AA7-75D1917E2C87"); pStep->addProperty("Item", getName()); mpStep = pStep.get(); if (extractInputArgs(pInArgList) == false) { return false; } // Set the values in the data descriptor VERIFY(mpDescriptor != NULL); // File descriptor if (mpFileDescriptor != NULL) { mpDescriptor->setFileDescriptor(mpFileDescriptor); } // Processing location if (mpProcessingLocation != NULL) { mpDescriptor->setProcessingLocation(*mpProcessingLocation); } RasterDataDescriptor* pRasterDescriptor = dynamic_cast<RasterDataDescriptor*>(mpDescriptor); RasterFileDescriptor* pRasterFileDescriptor = dynamic_cast<RasterFileDescriptor*>(mpFileDescriptor); SignatureDataDescriptor* pSignatureDescriptor = dynamic_cast<SignatureDataDescriptor*>(mpDescriptor); SignatureFileDescriptor* pSignatureFileDescriptor = dynamic_cast<SignatureFileDescriptor*>(mpFileDescriptor); if (pRasterDescriptor != NULL) { if (pRasterFileDescriptor != NULL) { // Set the rows and columns to match the rows and columns in the file descriptor before creating the subset const vector<DimensionDescriptor>& rows = pRasterFileDescriptor->getRows(); pRasterDescriptor->setRows(rows); const vector<DimensionDescriptor>& columns = pRasterFileDescriptor->getColumns(); pRasterDescriptor->setColumns(columns); const vector<DimensionDescriptor>& bands = pRasterFileDescriptor->getBands(); pRasterDescriptor->setBands(bands); } // Data type if (mpDataType != NULL) { pRasterDescriptor->setDataType(*mpDataType); } // InterleaveFormat if (mpInterleave != NULL) { pRasterDescriptor->setInterleaveFormat(*mpInterleave); } // Bad values if (mpBadValues != NULL) { pRasterDescriptor->setBadValues(*mpBadValues); } // Rows if ((mpStartRow != NULL) || (mpEndRow != NULL) || (mpRowSkipFactor != NULL)) { // We need to obtain this origRows from the FileDescriptor if present since an importer // may generate a subset by default in which case the DataDescriptor will not contain all // the rows and subsetting will not work correctly. We // can't just set mpFileDescriptor = pRasterDescriptor->getFileDescriptor() since we only // want to replace the DataDescriptor's row list if one of the subset options is specified const RasterFileDescriptor* pFileDesc(pRasterFileDescriptor); if (pFileDesc == NULL) { pFileDesc = dynamic_cast<const RasterFileDescriptor*>(pRasterDescriptor->getFileDescriptor()); } const vector<DimensionDescriptor>& origRows = (pFileDesc != NULL) ? pFileDesc->getRows() : pRasterDescriptor->getRows(); unsigned int startRow = 0; if (mpStartRow != NULL) { startRow = *mpStartRow; } else if (origRows.empty() == false) { startRow = origRows.front().getOriginalNumber() + 1; } unsigned int endRow = 0; if (mpEndRow != NULL) { endRow = *mpEndRow; } else if (origRows.empty() == false) { endRow = origRows.back().getOriginalNumber() + 1; } unsigned int rowSkip = 0; if (mpRowSkipFactor != NULL) { rowSkip = *mpRowSkipFactor; } vector<DimensionDescriptor> rows; for (unsigned int i = 0; i < origRows.size(); ++i) { DimensionDescriptor rowDim = origRows[i]; unsigned int originalNumber = rowDim.getOriginalNumber() + 1; if ((originalNumber >= startRow) && (originalNumber <= endRow)) { rows.push_back(rowDim); i += rowSkip; } } pRasterDescriptor->setRows(rows); } // Columns if ((mpStartColumn != NULL) || (mpEndColumn != NULL) || (mpColumnSkipFactor != NULL)) { // We need to obtain this origColumns from the FileDescriptor if present since an importer // may generate a subset by default in which case the DataDescriptor will not contain all // the columns and subsetting will not work correctly. We // can't just set mpFileDescriptor = pRasterDescriptor->getFileDescriptor() since we only // want to replace the DataDescriptor's column list if one of the subset options is specified const RasterFileDescriptor* pFileDesc(pRasterFileDescriptor); if (pFileDesc == NULL) { pFileDesc = dynamic_cast<const RasterFileDescriptor*>(pRasterDescriptor->getFileDescriptor()); } const vector<DimensionDescriptor>& origColumns = (pFileDesc != NULL) ? pFileDesc->getColumns() : pRasterDescriptor->getColumns(); unsigned int startColumn = 0; if (mpStartColumn != NULL) { startColumn = *mpStartColumn; } else if (origColumns.empty() == false) { startColumn = origColumns.front().getOriginalNumber() + 1; } unsigned int endColumn = 0; if (mpEndColumn != NULL) { endColumn = *mpEndColumn; } else if (origColumns.empty() == false) { endColumn = origColumns.back().getOriginalNumber() + 1; } unsigned int columnSkip = 0; if (mpColumnSkipFactor != NULL) { columnSkip = *mpColumnSkipFactor; } vector<DimensionDescriptor> columns; for (unsigned int i = 0; i < origColumns.size(); ++i) { DimensionDescriptor columnDim = origColumns[i]; unsigned int originalNumber = columnDim.getOriginalNumber() + 1; if ((originalNumber >= startColumn) && (originalNumber <= endColumn)) { columns.push_back(columnDim); i += columnSkip; } } pRasterDescriptor->setColumns(columns); } // Bands if ((mpStartBand != NULL) || (mpEndBand != NULL) || (mpBandSkipFactor != NULL) || (mpBadBandsFile != NULL)) { // We need to obtain this origBands from the FileDescriptor if present since an importer // may generate a subset by default in which case the DataDescriptor will not contain all // the bands and subsetting (especially by bad band file) will not work correctly. We // can't just set mpFileDescriptor = pRasterDescriptor->getFileDescriptor() since we only // want to replace the DataDescriptor's band list if one of the subset options is specified const RasterFileDescriptor* pFileDesc(pRasterFileDescriptor); if (pFileDesc == NULL) { pFileDesc = dynamic_cast<const RasterFileDescriptor*>(pRasterDescriptor->getFileDescriptor()); } const vector<DimensionDescriptor>& origBands = (pFileDesc != NULL) ? pFileDesc->getBands() : pRasterDescriptor->getBands(); unsigned int startBand = 0; if (mpStartBand != NULL) { startBand = *mpStartBand; } else if (origBands.empty() == false) { startBand = origBands.front().getOriginalNumber() + 1; } unsigned int endBand = 0; if (mpEndBand != NULL) { endBand = *mpEndBand; } else if (origBands.empty() == false) { endBand = origBands.back().getOriginalNumber() + 1; } unsigned int bandSkip = 0; if (mpBandSkipFactor != NULL) { bandSkip = *mpBandSkipFactor; } // Get the bad bands from the file vector<unsigned int> badBands; if (mpBadBandsFile != NULL) { string filename = *mpBadBandsFile; if (filename.empty() == false) { FILE* pFile = fopen(filename.c_str(), "rb"); if (pFile != NULL) { char line[1024]; while (fgets(line, 1024, pFile) != NULL) { unsigned int bandNumber = 0; int iValues = sscanf(line, "%u", &bandNumber); if (iValues == 1) { badBands.push_back(bandNumber); } } fclose(pFile); } } } vector<DimensionDescriptor> bands; for (unsigned int i = 0; i < origBands.size(); ++i) { DimensionDescriptor bandDim = origBands[i]; unsigned int originalNumber = bandDim.getOriginalNumber() + 1; if ((originalNumber >= startBand) && (originalNumber <= endBand)) { bool bBad = false; for (unsigned int j = 0; j < badBands.size(); ++j) { unsigned int badBandNumber = badBands[j]; if (originalNumber == badBandNumber) { bBad = true; break; } } if (bBad == false) { bands.push_back(bandDim); i += bandSkip; } } } pRasterDescriptor->setBands(bands); } // X pixel size if (mpPixelSizeX != NULL) { pRasterDescriptor->setXPixelSize(*mpPixelSizeX); } // Y pixel size if (mpPixelSizeY != NULL) { pRasterDescriptor->setYPixelSize(*mpPixelSizeY); } // Units if ((mpUnitsName != NULL) || (mpUnitsType != NULL) || (mpUnitsScale != NULL) || (mpUnitsRangeMin != NULL) || (mpUnitsRangeMax != NULL)) { const Units* pOrigUnits = pRasterDescriptor->getUnits(); FactoryResource<Units> pUnits; VERIFY(pUnits.get() != NULL); // Name if (mpUnitsName != NULL) { pUnits->setUnitName(*mpUnitsName); } else if (pOrigUnits != NULL) { pUnits->setUnitName(pOrigUnits->getUnitName()); } // Type if (mpUnitsType != NULL) { pUnits->setUnitType(*mpUnitsType); } else if (pOrigUnits != NULL) { pUnits->setUnitType(pOrigUnits->getUnitType()); } // Scale if (mpUnitsScale != NULL) { pUnits->setScaleFromStandard(*mpUnitsScale); } else if (pOrigUnits != NULL) { pUnits->setScaleFromStandard(pOrigUnits->getScaleFromStandard()); } // Range minimum if (mpUnitsRangeMin != NULL) { pUnits->setRangeMin(*mpUnitsRangeMin); } else if (pOrigUnits != NULL) { pUnits->setRangeMin(pOrigUnits->getRangeMin()); } // Range maximum if (mpUnitsRangeMax != NULL) { pUnits->setRangeMax(*mpUnitsRangeMax); } else if (pOrigUnits != NULL) { pUnits->setRangeMax(pOrigUnits->getRangeMax()); } pRasterDescriptor->setUnits(pUnits.get()); } // Display mode if (mpDisplayMode != NULL) { pRasterDescriptor->setDisplayMode(*mpDisplayMode); } // Display bands // Gray if (mpGrayBand != NULL) { DimensionDescriptor band = pRasterDescriptor->getOriginalBand(*mpGrayBand - 1); pRasterDescriptor->setDisplayBand(GRAY, band); } // Red if (mpRedBand != NULL) { DimensionDescriptor band = pRasterDescriptor->getOriginalBand(*mpRedBand - 1); pRasterDescriptor->setDisplayBand(RED, band); } // Green if (mpGreenBand != NULL) { DimensionDescriptor band = pRasterDescriptor->getOriginalBand(*mpGreenBand - 1); pRasterDescriptor->setDisplayBand(GREEN, band); } // Blue if (mpBlueBand != NULL) { DimensionDescriptor band = pRasterDescriptor->getOriginalBand(*mpBlueBand - 1); pRasterDescriptor->setDisplayBand(BLUE, band); } } else if (pSignatureDescriptor != NULL) { if (mpComponentName != NULL) { const Units* pOrigUnits = pSignatureDescriptor->getUnits(*mpComponentName); FactoryResource<Units> pUnits; if (pOrigUnits != NULL) { *pUnits = *pOrigUnits; } if (mpUnitsName != NULL) { pUnits->setUnitName(*mpUnitsName); } if (mpUnitsType != NULL) { pUnits->setUnitType(*mpUnitsType); } if (mpUnitsScale != NULL) { pUnits->setScaleFromStandard(*mpUnitsScale); } if (mpUnitsRangeMin != NULL) { pUnits->setRangeMin(*mpUnitsRangeMin); } if (mpUnitsRangeMax != NULL) { pUnits->setRangeMax(*mpUnitsRangeMax); } pSignatureDescriptor->setUnits(*mpComponentName, pUnits.get()); } } reportComplete(); return true; }