FactoryResource<DynamicObject> Nitf::DesSubheader::createDefaultsDynamicObject( const RasterDataDescriptor *pDescriptor) { FactoryResource<DynamicObject> pDesSubheader; // Per the NITF spec, the field "DE" must contain the value "DE". pDesSubheader->setAttribute(DE, DE); return pDesSubheader; }
DynamicObject *QueryOptions::toDynamicObject() const { FactoryResource<DynamicObject> pDynObj; VERIFYRV(pDynObj.get() != NULL, NULL); pDynObj->setAttribute(QUERY_NAME, mQueryName); pDynObj->setAttribute(FORMAT_STRING, mFormatString); pDynObj->setAttribute(QUERY_STRING, mQueryString); pDynObj->setAttribute(SYMBOL_NAME, mSymbolName); pDynObj->setAttribute(SYMBOL_SIZE, mSymbolSize); pDynObj->setAttribute(LINE_STATE, mLineState); pDynObj->setAttribute(LINE_STYLE, mLineStyle); pDynObj->setAttribute(LINE_WIDTH, mLineWidth); pDynObj->setAttribute(LINE_COLOR, mLineColor); pDynObj->setAttribute(LINE_SCALED, mLineScaled); pDynObj->setAttribute(FILL_COLOR, mFillColor); pDynObj->setAttribute(FILL_STYLE, mFillStyle); pDynObj->setAttribute(HATCH_STYLE, mHatchStyle); return pDynObj.release(); }
vector<ImportDescriptor*> SignatureSetImporter::createImportDescriptors(DOMTreeWalker* pTree, vector<string> &datasetPath) { vector<ImportDescriptor*> descriptors; FactoryResource<DynamicObject> pMetadata; VERIFYRV(pMetadata.get() != NULL, descriptors); string datasetName = StringUtilities::toDisplayString(mDatasetNumber++); for (DOMNode* pChld = pTree->firstChild(); pChld != NULL; pChld = pTree->nextSibling()) { if (XMLString::equals(pChld->getNodeName(), X("metadata"))) { DOMElement* pElmnt = static_cast<DOMElement*>(pChld); string name = A(pElmnt->getAttribute(X("name"))); string val = A(pElmnt->getAttribute(X("value"))); pMetadata->setAttribute(name, val); if (name == "Name") { datasetName = val; } } else if (XMLString::equals(pChld->getNodeName(), X("signature_set"))) { datasetPath.push_back(datasetName); vector<ImportDescriptor*> sub = createImportDescriptors(pTree, datasetPath); datasetPath.pop_back(); descriptors.insert(descriptors.end(), sub.begin(), sub.end()); pTree->parentNode(); } } ImportDescriptorResource pImportDescriptor(datasetName, "SignatureSet", datasetPath); VERIFYRV(pImportDescriptor.get() != NULL, descriptors); DataDescriptor* pDataDescriptor = pImportDescriptor->getDataDescriptor(); VERIFYRV(pDataDescriptor != NULL, descriptors); FactoryResource<SignatureFileDescriptor> pFileDescriptor; VERIFYRV(pFileDescriptor.get() != NULL, descriptors); pFileDescriptor->setFilename(mFilename); datasetPath.push_back(datasetName); string loc = "/" + StringUtilities::join(datasetPath, "/"); datasetPath.pop_back(); pFileDescriptor->setDatasetLocation(loc); pDataDescriptor->setFileDescriptor(pFileDescriptor.get()); pDataDescriptor->setMetadata(pMetadata.get()); descriptors.push_back(pImportDescriptor.release()); return descriptors; }
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*> SampleHdf4Importer::getImportDescriptors(const string& filename) { vector<ImportDescriptor*> descriptors; Hdf4File parsedFile(filename); bool bSuccess = getFileData(parsedFile); if (bSuccess == true) { const Hdf4Dataset* pDataset = dynamic_cast<const Hdf4Dataset*>(parsedFile.getRootGroup()->getElement("EV_500_RefSB")); if ((pDataset != NULL) && (mpModel.get() != NULL)) { Hdf4FileResource pFile(filename.c_str()); if (pFile.get() != NULL) { 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) { int32 numDims = 0; int32 dataType = 0; int32 numAttr = 0; pFileDescriptor->setFilename(filename); Hdf4DatasetResource pDataHandle(*pFile, pDataset->getName().c_str()); int32 dimSizes[MAX_VAR_DIMS] = {0}; if (pDataHandle != NULL && *pDataHandle != FAIL) { pFileDescriptor->setDatasetLocation(pDataset->getName()); int32 success = SDgetinfo(*pDataHandle, const_cast<char*>(pDataset->getName().c_str()), &numDims, dimSizes, &dataType, &numAttr); // find out what type this Dataset is string strDataType = hdf4TypeToString(dataType, 1); if (success == SUCCEED && numDims == 3 && strDataType == "unsigned short") { // Bands vector<DimensionDescriptor> bands = RasterUtilities::generateDimensionVector(dimSizes[0], true, false, true); pDescriptor->setBands(bands); pFileDescriptor->setBands(bands); // Rows vector<DimensionDescriptor> rows = RasterUtilities::generateDimensionVector(dimSizes[1], true, false, true); pDescriptor->setRows(rows); pFileDescriptor->setRows(rows); // Columns vector<DimensionDescriptor> columns = RasterUtilities::generateDimensionVector(dimSizes[2], true, false, true); pDescriptor->setColumns(columns); pFileDescriptor->setColumns(columns); } } // Data type EncodingType e; pDataset->getDataEncoding(e); pDescriptor->setDataType(e); pFileDescriptor->setBitsPerElement(pDescriptor->getBytesPerElement() * 8); // Interleave format pDescriptor->setInterleaveFormat(BSQ); pFileDescriptor->setInterleaveFormat(BSQ); // Metadata FactoryResource<DynamicObject> pMetadata; if (pMetadata.get() != NULL) { const Hdf4Dataset::AttributeContainer& attributes = pDataset->getAttributes(); for (Hdf4Dataset::AttributeContainer::const_iterator it = attributes.begin(); it != attributes.end(); ++it) { Hdf4Attribute* pAttribute = it->second; if (pAttribute != NULL) { const string& name = pAttribute->getName(); const DataVariant& var = pAttribute->getVariant(); const unsigned short* pValue = var.getPointerToValue<unsigned short>(); if (name == "_FillValue" && pValue != NULL) { // Bad values vector<int> badValues; badValues.push_back(*pValue); pDescriptor->setBadValues(badValues); } else { pMetadata->setAttribute(name, var); } } } pDescriptor->setMetadata(pMetadata.get()); } pDescriptor->setFileDescriptor(pFileDescriptor.get()); } } descriptors.push_back(pImportDescriptor); } } } } return descriptors; }
vector<ImportDescriptor*> EnviImporter::getImportDescriptors(const string& filename) { string headerFile = filename; string dataFile; bool bSuccess = parseHeader(headerFile); if (bSuccess == false) { dataFile = filename; // was passed data file name instead of header file name headerFile = findHeaderFile(headerFile); if (headerFile.empty() == false) { bSuccess = parseHeader(headerFile); } } EnviField* pField = NULL; vector<ImportDescriptor*> descriptors; if (bSuccess == true) { if (dataFile.empty() == true) // was passed header file name and now need to find the data file name { dataFile = findDataFile(headerFile); } if (dataFile.empty() == false) { ImportDescriptor* pImportDescriptor = mpModel->createImportDescriptor(dataFile, "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(dataFile); // Coordinate offset int columnOffset = 0; int rowOffset = 0; pField = mFields.find("x start"); if (pField != NULL) { // ENVI numbers are 1 based vs Opticks being 0 based columnOffset = atoi(pField->mValue.c_str()) - 1; } pField = mFields.find("y start"); if (pField != NULL) { rowOffset = atoi(pField->mValue.c_str()) - 1; // ENVI numbers are 1 based vs Opticks being 0 based } // Rows vector<DimensionDescriptor> rows; pField = mFields.find("lines"); if (pField != NULL) { int numRows = atoi(pField->mValue.c_str()); for (int i = 0; i < numRows; ++i) { DimensionDescriptor rowDim; rowDim.setOriginalNumber(static_cast<unsigned int>(rowOffset + i)); rowDim.setOnDiskNumber(static_cast<unsigned int>(i)); rows.push_back(rowDim); } pDescriptor->setRows(rows); pFileDescriptor->setRows(rows); } string samplesStr = "samples"; string bandsStr = "bands"; // Special case: if the file type is an ENVI Spectral Library, then swap samples with bands // If no file type field exists, assume this is a normal ENVI header (not a Spectral Library) EnviField* pFileTypeField = mFields.find("file type"); if (pFileTypeField != NULL && (pFileTypeField->mValue == "ENVI Spectral Library" || pFileTypeField->mValue == "Spectral Library")) { samplesStr = "bands"; bandsStr = "samples"; // Since bands and samples are swapped, force the interleave to BIP pField = mFields.find("interleave"); if (pField != NULL) { pField->mValue = "bip"; } } // Columns vector<DimensionDescriptor> columns; pField = mFields.find(samplesStr); if (pField != NULL) { int numColumns = atoi(pField->mValue.c_str()); for (int i = 0; i < numColumns; ++i) { DimensionDescriptor columnDim; columnDim.setOriginalNumber(static_cast<unsigned int>(columnOffset + i)); columnDim.setOnDiskNumber(static_cast<unsigned int>(i)); columns.push_back(columnDim); } pDescriptor->setColumns(columns); pFileDescriptor->setColumns(columns); } // Bands vector<DimensionDescriptor> bands; pField = mFields.find(bandsStr); if (pField != NULL) { int numBands = atoi(pField->mValue.c_str()); bands = RasterUtilities::generateDimensionVector(numBands, true, false, true); pDescriptor->setBands(bands); pFileDescriptor->setBands(bands); } // Description list<GcpPoint> gcps; pField = mFields.find("description"); if (pField != NULL) { // Metadata if (pField->mChildren.empty() == false) { FactoryResource<DynamicObject> pMetadata; for (unsigned int i = 0; i < pField->mChildren.size(); ++i) { EnviField* pChild = pField->mChildren[i]; if (pChild != NULL) { if (pChild->mTag == "classification") { // Classification FactoryResource<Classification> pClassification; if (pClassification.get() != NULL) { string classLevel; classLevel.append(1, *(pChild->mValue.data())); pClassification->setLevel(classLevel); pDescriptor->setClassification(pClassification.get()); } } else if ((pChild->mTag == "ll") || (pChild->mTag == "lr") || (pChild->mTag == "ul") || (pChild->mTag == "ur") || (pChild->mTag == "center")) { GcpPoint gcp; bool dmsFormat = false; char ns; char ew; sscanf(pChild->mValue.c_str(), "%lg%c %lg%c", &gcp.mCoordinate.mY, &ew, &gcp.mCoordinate.mX, &ns); if (fabs(gcp.mCoordinate.mY) > 180.0 || fabs(gcp.mCoordinate.mX) > 90.0) { dmsFormat = true; } double deg; double min; double sec; if (dmsFormat == true) { deg = static_cast<int>(gcp.mCoordinate.mY / 10000.0); min = static_cast<int>((gcp.mCoordinate.mY - 10000.0 * deg) / 100.0); sec = gcp.mCoordinate.mY - 10000.0 * deg - 100.0 * min; gcp.mCoordinate.mY = deg + (min / 60.0) + (sec / 3600.0); } if (ew == 'W' || ew == 'w') { gcp.mCoordinate.mY = -gcp.mCoordinate.mY; } if (dmsFormat) { deg = static_cast<int>(gcp.mCoordinate.mX / 10000.0); min = static_cast<int>((gcp.mCoordinate.mX - 10000.0 * deg) / 100.0); sec = gcp.mCoordinate.mX - 10000.0 * deg - 100.0 * min; gcp.mCoordinate.mX = deg + (min / 60.0) + (sec / 3600.0); } if (ns == 'S' || ns == 's') { gcp.mCoordinate.mX = -gcp.mCoordinate.mX; } // ENVI uses a 1-based pixel coordinate system, with each coordinate referring // to the top-left corner of the pixel, e.g. (1,1) is the top-left // corner of the pixel in the top-left of the raster cube // The ENVI pixel coordinate format is described on p. 1126 of the ENVI 4.2 User's Guide if (pChild->mTag == "ll") { gcp.mPixel.mX = 0.0; gcp.mPixel.mY = 0.0; } else if (pChild->mTag == "lr") { gcp.mPixel.mX = columns.size() - 1.0; gcp.mPixel.mY = 0.0; } else if (pChild->mTag == "ul") { gcp.mPixel.mX = 0.0; gcp.mPixel.mY = rows.size() - 1.0; } else if (pChild->mTag == "ur") { gcp.mPixel.mX = columns.size() - 1.0; gcp.mPixel.mY = rows.size() - 1.0; } else if (pChild->mTag == "center") { gcp.mPixel.mX = floor((columns.size() - 1.0) / 2.0); gcp.mPixel.mY = floor((rows.size() - 1.0) / 2.0); } gcps.push_back(gcp); } else if (pChild->mTag.empty() == false) { pMetadata->setAttribute(pChild->mTag, pChild->mValue); } } } if (pMetadata->getNumAttributes() > 0) { pDescriptor->setMetadata(pMetadata.get()); } } } if (gcps.empty()) // not in description, check for geo points keyword { pField = mFields.find("geo points"); if (pField != NULL) { vector<double> geoValues; const int expectedNumValues = 16; // 4 values for each of the 4 corners geoValues.reserve(expectedNumValues); for (unsigned int i = 0; i < pField->mChildren.size(); i++) { vectorFromField(pField->mChildren.at(i), geoValues, "%lf"); } if (geoValues.size() == expectedNumValues) { vector<double>::iterator iter = geoValues.begin(); GcpPoint gcp; while (iter != geoValues.end()) { gcp.mPixel.mX = *iter++ - 1.0; // adjust ref point for ENVI's use of gcp.mPixel.mY = *iter++ - 1.0; // upper left corner and one-based first pixel gcp.mCoordinate.mX = *iter++; // GcpPoint has lat as mX and Lon as mY gcp.mCoordinate.mY = *iter++; // geo point field has lat then lon value gcps.push_back(gcp); } } } } // GCPs if (gcps.empty() == false) { pFileDescriptor->setGcps(gcps); } // Header bytes pField = mFields.find("header offset"); if (pField != NULL) { int headerBytes = atoi(pField->mValue.c_str()); pFileDescriptor->setHeaderBytes(static_cast<unsigned int>(headerBytes)); } // Data type pField = mFields.find("data type"); if (pField != NULL) { vector<EncodingType> validDataTypes; switch (atoi(pField->mValue.c_str())) { case 1: // char pDescriptor->setDataType(INT1UBYTE); pFileDescriptor->setBitsPerElement(8); // signed char cannot be represented in ENVI header so use the closest thing validDataTypes.push_back(INT1SBYTE); break; case 2: // short pDescriptor->setDataType(INT2SBYTES); pFileDescriptor->setBitsPerElement(16); break; case 3: // int pDescriptor->setDataType(INT4SBYTES); pFileDescriptor->setBitsPerElement(32); break; case 4: // float pDescriptor->setDataType(FLT4BYTES); pFileDescriptor->setBitsPerElement(32); break; case 5: // double pDescriptor->setDataType(FLT8BYTES); pFileDescriptor->setBitsPerElement(64); break; case 6: // float complex pDescriptor->setDataType(FLT8COMPLEX); pFileDescriptor->setBitsPerElement(64); break; case 9: // double complex // not supported break; case 12: // unsigned short pDescriptor->setDataType(INT2UBYTES); pFileDescriptor->setBitsPerElement(16); break; case 13: // unsigned int pDescriptor->setDataType(INT4UBYTES); pFileDescriptor->setBitsPerElement(32); break; case 14: // 64-bit int case 15: // unsigned 64-bit int // not supported break; case 99: // integer complex (recognized only by this application) pDescriptor->setDataType(INT4SCOMPLEX); pFileDescriptor->setBitsPerElement(32); break; default: break; } // Bad values EncodingType dataType = pDescriptor->getDataType(); if ((dataType != FLT4BYTES) && (dataType != FLT8COMPLEX) && (dataType != FLT8BYTES)) { vector<int> badValues; badValues.push_back(0); pDescriptor->setBadValues(badValues); } validDataTypes.push_back(dataType); pDescriptor->setValidDataTypes(validDataTypes); } // Interleave format pField = mFields.find("interleave"); if (pField != NULL) { string interleave = StringUtilities::toLower(pField->mValue); if (interleave == "bip") { pDescriptor->setInterleaveFormat(BIP); pFileDescriptor->setInterleaveFormat(BIP); } else if (interleave == "bil") { pDescriptor->setInterleaveFormat(BIL); pFileDescriptor->setInterleaveFormat(BIL); } else if (interleave == "bsq") { pDescriptor->setInterleaveFormat(BSQ); pFileDescriptor->setInterleaveFormat(BSQ); } } // Endian pField = mFields.find("byte order"); if (pField != NULL) { int byteOrder = atoi(pField->mValue.c_str()); if (byteOrder == 0) { pFileDescriptor->setEndian(LITTLE_ENDIAN_ORDER); } else if (byteOrder == 1) { pFileDescriptor->setEndian(BIG_ENDIAN_ORDER); } } // check for scaling factor pField = mFields.find("reflectance scale factor"); if (pField != NULL) { double scalingFactor = 0.0; stringstream scaleStream(pField->mValue); scaleStream >> scalingFactor; if (!scaleStream.fail() && scalingFactor != 0.0) { Units* pUnits = pDescriptor->getUnits(); if (pUnits != NULL) { pUnits->setScaleFromStandard(1.0 / scalingFactor); pUnits->setUnitName("Reflectance"); pUnits->setUnitType(REFLECTANCE); } } } // Pixel size pField = mFields.find("pixel size"); if (pField != NULL) { if (pField->mChildren.size() == 2) { pField = pField->mChildren[0]; if (pField != NULL) { double pixelSize = 1.0; if (sscanf(pField->mValue.c_str(), "%g", &pixelSize) == 1) { pDescriptor->setXPixelSize(pixelSize); pFileDescriptor->setXPixelSize(pixelSize); } } pField = pField->mChildren[1]; if (pField != NULL) { double pixelSize = 1.0; if (sscanf(pField->mValue.c_str(), "%g", &pixelSize) == 1) { pDescriptor->setYPixelSize(pixelSize); pFileDescriptor->setYPixelSize(pixelSize); } } } } // Default bands pField = mFields.find("default bands"); if (pField != NULL) { vector<unsigned int> displayBands; parseDefaultBands(pField, &displayBands); if (displayBands.size() == 1) { DimensionDescriptor grayBand = pFileDescriptor->getOriginalBand(displayBands[0]); pDescriptor->setDisplayBand(GRAY, grayBand); pDescriptor->setDisplayMode(GRAYSCALE_MODE); } else if (displayBands.size() == 3) { DimensionDescriptor redBand = pFileDescriptor->getOriginalBand(displayBands[0]); DimensionDescriptor greenBand = pFileDescriptor->getOriginalBand(displayBands[1]); DimensionDescriptor blueBand = pFileDescriptor->getOriginalBand(displayBands[2]); pDescriptor->setDisplayBand(RED, redBand); pDescriptor->setDisplayBand(GREEN, greenBand); pDescriptor->setDisplayBand(BLUE, blueBand); pDescriptor->setDisplayMode(RGB_MODE); } } // Bad bands pField = mFields.find("bbl"); if (pField != NULL) { vector<unsigned int> validBands; parseBbl(pField, validBands); vector<DimensionDescriptor> bandsToLoad; for (vector<unsigned int>::const_iterator iter = validBands.begin(); iter != validBands.end(); ++iter) { const unsigned int onDiskNumber = *iter; const DimensionDescriptor dim = pFileDescriptor->getOnDiskBand(onDiskNumber); if (dim.isValid()) { bandsToLoad.push_back(dim); } } pDescriptor->setBands(bandsToLoad); } DynamicObject* pMetadata = pDescriptor->getMetadata(); // Band names pField = mFields.find("band names"); if (pField != NULL) { vector<string> bandNames; bandNames.reserve(bands.size()); vector<string> strNames; for (vector<EnviField*>::size_type i = 0; i < pField->mChildren.size(); ++i) { strNames = StringUtilities::split(pField->mChildren[i]->mValue, ','); copy(strNames.begin(), strNames.end(), back_inserter(bandNames)); } vector<string>::iterator it; for (it = bandNames.begin(); it != bandNames.end(); ++it) { *it = StringUtilities::stripWhitespace(*it); } if (pMetadata != NULL) { string pNamesPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, NAMES_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pNamesPath, bandNames); } } // wavelength units pField = mFields.find("wavelength units"); if (pField != NULL) { mWavelengthUnits = strToType(pField->mValue); } // Wavelengths vector<double> centerWavelengths; pField = mFields.find("wavelength"); if (pField != NULL) { if ((parseWavelengths(pField, ¢erWavelengths) == true) && (pMetadata != NULL)) { string pCenterPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, CENTER_WAVELENGTHS_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pCenterPath, centerWavelengths); } } // FWHM pField = mFields.find("fwhm"); if (pField != NULL) { vector<double> startWavelengths; vector<double> endWavelengths; if ((parseFwhm(pField, &startWavelengths, ¢erWavelengths, &endWavelengths) == true) && (pMetadata != NULL)) { 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); } } // File descriptor pDescriptor->setFileDescriptor(pFileDescriptor.get()); }
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; }