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 Nitf::importMetadata(const unsigned int& currentImage, const Nitf::OssimFileResource& pFile, const ossimNitfFileHeaderV2_X* pFileHeader, const ossimNitfImageHeaderV2_X* pImageSubheader, RasterDataDescriptor* pDescriptor, map<string, TrePlugInResource>& parsers, string& errorMessage) { //#pragma message(__FILE__ "(" STRING(__LINE__) ") : warning : Separate the file header parsing " \ // "from the subheader parsing (dadkins)") VERIFY(pFileHeader != NULL && pImageSubheader != NULL && pDescriptor != NULL); // Add metadata for the NITF File Header and the supported subheaders const string fileVersion = pFileHeader->getVersion(); Nitf::FileHeader fileHeader(fileVersion); if (fileHeader.importMetadata(pFileHeader, pDescriptor) == false) { errorMessage += "Unable to import metadata from the file header.\n"; return false; } unsigned int numDes = pFileHeader->getNumberOfDataExtSegments(); for (unsigned int i = 0; i < numDes; ++i) { auto_ptr<ossimNitfDataExtensionSegment> pDes(pFile->getNewDataExtensionSegment(i)); if (pDes.get() != NULL) { Nitf::DesSubheader desSubheader(fileVersion, i); if (desSubheader.importMetadata(pDes.get(), pDescriptor) == false) { stringstream errorStream; errorStream << "Unable to retrieve DES subheader #" << i << "." << endl; errorMessage += errorStream.str(); } } } Nitf::ImageSubheader imageSubheader(fileVersion); if (imageSubheader.importMetadata(pImageSubheader, pDescriptor) == false) { errorMessage += "Unable to import metadata from the image subheader.\n"; return false; } // Now do the TREs FactoryResource<DynamicObject> pTres; FactoryResource<DynamicObject> pTreInfo; const unsigned int numImageTags = pImageSubheader->getNumberOfTags(); for (unsigned int imageTag = 0; imageTag < numImageTags; ++imageTag) { ossimNitfTagInformation tagInfo; if (pImageSubheader->getTagInformation(tagInfo, imageTag) == false) { stringstream errorStream; errorStream << "Unable to retrieve tag #" << imageTag << " from the image subheader." << endl; errorMessage += errorStream.str(); } else { addTagToMetadata(currentImage, tagInfo, pDescriptor, pTres.get(), pTreInfo.get(), parsers, errorMessage); } } const unsigned int numFileTags = pFileHeader->getNumberOfTags(); for (unsigned int fileTag = 0; fileTag < numFileTags; ++fileTag) { ossimNitfTagInformation tagInfo; if (pFileHeader->getTagInformation(tagInfo, fileTag) == false) { stringstream errorStream; errorStream << "Unable to retrieve tag #" << fileTag << " from the file header." << endl; errorMessage += errorStream.str(); } else { // For file headers, currentImage is always 0. addTagToMetadata(0, tagInfo, pDescriptor, pTres.get(), pTreInfo.get(), parsers, errorMessage); } } // FTITLE parsing requires the metadata object to be populated first DynamicObject* pMetadata = pDescriptor->getMetadata(); VERIFY(pMetadata != NULL); pMetadata->setAttributeByPath(Nitf::NITF_METADATA + "/" + Nitf::TRE_METADATA, *pTres.get()); pMetadata->setAttributeByPath(Nitf::NITF_METADATA + "/" + Nitf::TRE_INFO_METADATA, *pTreInfo.get()); //#pragma message(__FILE__ "(" STRING(__LINE__) ") : warning : Consider moving this into ChipConverter (leckels)") // We have two equations of the form: // FI_x = a*OP_x + b*OP_y + c and // FI_y = d*OP_x + e*OP_y + f // // The coefficients a-f are as follows (from Todd's implementation of FTITLE -> ICHIPB Coefficients // a = 1.0; // b = 0.0 // c = (row-1)*x_pixel_block_size, where row comes from FTITLE // d = 0.0 // e = 1.0 // f = (column-1)*y_pixel_block_size, where column comes from FTITLE // // Solving for OP_x, OP_y, and substituting for a-f, we get: // FI_x - c = OP_x // FI_y - f = OP_y // Building the ICHIPB requires solving for OP_x and OP_y, since a-f can be derived from the FTITLE // Special case if NTM: build and insert an ICHIPB if it is missing // trust the ICHIPB more than the other tags; only create an ICHIPB if none exist if (pTres->getAttribute("STDIDB").isValid() == true && pTres->getAttribute("ICHIPB").isValid() == false) { int x_pixel_block_size = pImageSubheader->getNumberOfPixelsPerBlockHoriz(); int y_pixel_block_size = pImageSubheader->getNumberOfPixelsPerBlockVert(); unsigned int imgRows = pImageSubheader->getNumberOfRows(); unsigned int imgCols = pImageSubheader->getNumberOfCols(); int blockRow = 1; int blockCol = 1; //the ftitle we only need a small portion of, we can extract //the displayed blocks included in this image from a properly //named ftitle. string ftitle = pFileHeader->getTitle(); string::size_type index = ftitle.find_first_of('_'); if (index != string::npos) { string fubstring = ftitle.substr(index+1); if (fubstring.size() > 16) { char tempRow[3] = {0}; char tempCol[6] = {0}; istringstream strm(fubstring); if (strm.good()) { strm.read(tempRow, 2); } stringstream t(tempRow); t >> blockRow; if (strm.good()) { strm.read(tempCol, 5); } t.clear(); t << tempCol; t >> blockCol; }