Beispiel #1
0
vector<ImportDescriptor*> CgmImporter::getImportDescriptors(const string& filename)
{
   vector<ImportDescriptor*> descriptors;
   if (!filename.empty())
   {
      FactoryResource<Filename> pFullFilename;
      pFullFilename->setFullPathAndName(filename);

      ImportDescriptor* pImportDescriptor = mpModel->createImportDescriptor(filename, "AnnotationElement", NULL);
      if (pImportDescriptor != NULL)
      {
         DataDescriptor* pDescriptor = pImportDescriptor->getDataDescriptor();
         if (pDescriptor != NULL)
         {
            FactoryResource<FileDescriptor> pFileDescriptor;
            if (pFileDescriptor.get() != NULL)
            {
               pFileDescriptor->setFilename(filename);
               pDescriptor->setFileDescriptor(pFileDescriptor.get());
            }
         }

         descriptors.push_back(pImportDescriptor);
      }
   }

   return descriptors;
}
Beispiel #2
0
vector<ImportDescriptor*> Jpeg2000Importer::getImportDescriptors(const string& filename)
{
   vector<ImportDescriptor*> descriptors;
   if (filename.empty() == true)
   {
      return descriptors;
   }

   vector<string>& warnings = msWarnings[filename];
   warnings.clear();

   vector<string>& errors = msErrors[filename];
   errors.clear();

   ImportDescriptor* pImportDescriptor = mpModel->createImportDescriptor(filename, "RasterElement", NULL);
   if (pImportDescriptor != NULL)
   {
      RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pImportDescriptor->getDataDescriptor());
      if (pDescriptor != NULL)
      {
         vector<EncodingType> validDataTypes;
         validDataTypes.push_back(INT1UBYTE);
         validDataTypes.push_back(INT1SBYTE);
         validDataTypes.push_back(INT2UBYTES);
         validDataTypes.push_back(INT2SBYTES);
         validDataTypes.push_back(INT4UBYTES);
         validDataTypes.push_back(INT4SBYTES);
         validDataTypes.push_back(FLT4BYTES);
         pDescriptor->setValidDataTypes(validDataTypes);
         pDescriptor->setProcessingLocation(IN_MEMORY);

         // Create and set a file descriptor in the data descriptor
         FactoryResource<RasterFileDescriptor> pFileDescriptor;
         pFileDescriptor->setEndian(BIG_ENDIAN_ORDER);
         if (pFileDescriptor.get() != NULL)
         {
            pFileDescriptor->setFilename(filename);
            pDescriptor->setFileDescriptor(pFileDescriptor.get());
         }

         // Populate the data descriptor from the file
         bool bSuccess = populateDataDescriptor(pDescriptor);
         if (bSuccess == true)
         {
            descriptors.push_back(pImportDescriptor);
         }
         else
         {
            // Delete the import descriptor
            mpModel->destroyImportDescriptor(pImportDescriptor);
         }
      }
   }

   return descriptors;
}
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;
}
Beispiel #4
0
vector<ImportDescriptor*> ShapeFileImporter::getImportDescriptors(const string& filename)
{
   vector<ImportDescriptor*> descriptors;

   if (getFileAffinity(filename) != Importer::CAN_NOT_LOAD)
   {
      Service<ModelServices> pModel;

      ImportDescriptor* pImportDescriptor = pModel->createImportDescriptor(filename, "AnnotationElement", NULL);
      VERIFYRV(pImportDescriptor != NULL, descriptors);

      DataDescriptor* pDescriptor = pImportDescriptor->getDataDescriptor();
      VERIFYRV(pDescriptor != NULL, descriptors);

      FactoryResource<FileDescriptor> pFileDescriptor;
      pFileDescriptor->setFilename(filename);
      pDescriptor->setFileDescriptor(pFileDescriptor.get());

      descriptors.push_back(pImportDescriptor);
   }

   return descriptors;
}
Beispiel #5
0
bool SaveLayer::execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList)
{
   StepResource pStep("Execute Wizard Item", "app", "DCBBB270-9360-4c96-8CE9-A9D414FC68EE");
   pStep->addProperty("Item", getName());
   mpStep = pStep.get();

   if (!extractInputArgs(pInArgList))
   {
      reportError("Unable to extract input arguments.", "CE17C3AD-05BD-4624-A9AD-9694430E1A6C");
      return false;
   }

   // Check for valid input values
   string filename = "";
   if (mpOutputFilename != NULL)
   {
      filename = mpOutputFilename->getFullPathAndName();
   }

   if (filename.empty())
   {
      reportError("The filename input value is invalid!", "2682BD10-8A8E-4aed-B2D8-7F7B4CC857A4");
      return false;
   }

   if (mpStep != NULL)
   {
      mpStep->addProperty("filename", filename);
   }

   if (mpElement == NULL)
   {
      reportError("The data element input value is invalid!", "CC2017C8-FB19-43c0-B1C6-C70625BFE611");
      return false;
   }

   DataElement* pParent = mpElement->getParent();
   if (mpStep != NULL)
   {
      if (pParent != NULL)
      {
         mpStep->addProperty("dataSet", pParent->getName());
      }
      else
      {
         mpStep->addProperty("dataSet", mpElement->getName());
      }
   }

   // Get the Layer
   Layer* pLayer = NULL;

   vector<Window*> windows;
   Service<DesktopServices> pDesktop;
   VERIFY(pDesktop.get() != NULL);
   pDesktop->getWindows(SPATIAL_DATA_WINDOW, windows);

   for (vector<Window*>::iterator iter = windows.begin(); iter != windows.end(); ++iter)
   {
      SpatialDataWindow* pWindow = static_cast<SpatialDataWindow*>(*iter);
      if (pWindow != NULL)
      {
         SpatialDataView* pCurrentView = pWindow->getSpatialDataView();
         if (pCurrentView != NULL)
         {
            LayerList* pLayerList = pCurrentView->getLayerList();
            if (pLayerList != NULL)
            {
               vector<Layer*> layers;
               pLayerList->getLayers(layers);
               vector<Layer*>::iterator layerIter;
               for (layerIter = layers.begin(); layerIter != layers.end(); ++layerIter)
               {
                  Layer* pCurrentLayer = *layerIter;
                  if (pCurrentLayer != NULL)
                  {
                     if (pCurrentLayer->getDataElement() == mpElement)
                     {
                        pLayer = pCurrentLayer;
                        break;
                     }
                  }
               }
            }
         }
      }
   }

   if (pLayer == NULL)
   {
      reportError("Could not get the layer to save!", "37EBD88F-9752-4b52-8A8A-F1BD9A98E608");
      return false;
   }

   // Get the layer type
   LayerType eType = getLayerType();

   // Save the layer
   FactoryResource<FileDescriptor> pFileDescriptor;
   VERIFY(pFileDescriptor.get() != NULL);
   pFileDescriptor->setFilename(filename);
   ExporterResource exporter("Layer Exporter", pLayer, pFileDescriptor.get());
   VERIFY(exporter->getPlugIn() != NULL);
   bool bSaved = exporter->execute();

   if (!bSaved)
   {
      reportError("Could not save the layer to the file: " + filename, "E2F6878E-E462-409b-AE8A-6E1555198316");
      return false;
   }

   reportComplete();
   return true;
}
Beispiel #6
0
bool SaveLayerFromDataSet::execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList)
{
   StepResource pStep("Execute Wizard Item", "app", "A1205468-4950-4c8f-9821-60063CC4B31B");
   pStep->addProperty("Item", getName());
   mpStep = pStep.get();

   if (!extractInputArgs(pInArgList))
   {
      reportError("Unable to extract input arguments.", "9A496CD9-5068-4b12-A4C4-AB561CD49523");
      return false;
   }

   // Check for valid input values
   string filename;
   if (mpOutputFilename != NULL)
   {
      filename = mpOutputFilename->getFullPathAndName();
   }

   if (filename.empty())
   {
      reportError(" The filename input value is invalid!", "DA76EB21-7E5A-45aa-A60D-0B99C72585EC");
      return false;
   }

   if (mpStep != NULL)
   {
      mpStep->addProperty("filename", filename);
   }

   if (mpRasterElement == NULL)
   {
      reportError("The data set input value is invalid!", "E11D0EC5-97E6-41a5-8F1F-937290CA102F");
      return false;
   }

   if (mpStep != NULL)
   {
      mpStep->addProperty("dataSet", mpRasterElement->getName());
   }

   if (mLayerName.empty())
   {
      reportError("The layer name input value is invalid!", "0DF331B8-05FF-4178-82D3-9A9CF2851DCF");
      return false;
   }

   if (mpStep != NULL)
   {
      mpStep->addProperty("layerName", mLayerName);
   }

   // Get the view
   SpatialDataView* pView = NULL;

   vector<Window*> windows;
   Service<DesktopServices> pDesktop;
   if (pDesktop.get() != NULL)
   {
      pDesktop->getWindows(SPATIAL_DATA_WINDOW, windows);
   }

   for (vector<Window*>::iterator iter = windows.begin(); iter != windows.end(); ++iter)
   {
      SpatialDataWindow* pWindow = static_cast<SpatialDataWindow*>(*iter);
      if (pWindow != NULL)
      {
         SpatialDataView* pCurrentView = pWindow->getSpatialDataView();
         if (pCurrentView != NULL)
         {
            LayerList* pLayerList = pCurrentView->getLayerList();
            if (pLayerList != NULL)
            {
               RasterElement* pRasterElement = pLayerList->getPrimaryRasterElement();
               if (pRasterElement == mpRasterElement)
               {
                  pView = pCurrentView;
                  break;
               }
            }
         }
      }
   }

   if (pView == NULL)
   {
      reportError("Could not get the view!", "830E3C55-561A-4c49-8269-06E1E04B1BFA");
      return false;
   }

   // Get the spectral element
   LayerType eType = getLayerType();
   string modelType = getModelType(eType);

   DataElement* pElement = NULL;
   Service<ModelServices> pModel;
   if ((pModel.get() != NULL) && !modelType.empty())
   {
      pElement = pModel->getElement(mLayerName, modelType, mpRasterElement);
   }

   // Save the layer
   bool bSaved = false;

   LayerList* pLayerList = pView->getLayerList();
   if (pLayerList != NULL)
   {
      Layer* pLayer = pLayerList->getLayer(eType, pElement, mLayerName.c_str());
      if (pLayer == NULL)
      {
         reportError("Could not get the layer to save!", "02F03D56-7CA8-4052-894D-BFDDFC3A814F");
         return false;
      }

      FactoryResource<FileDescriptor> pFileDescriptor;
      VERIFY(pFileDescriptor.get() != NULL);
      pFileDescriptor->setFilename(filename);
      ExporterResource exporter("Layer Exporter", pLayer, pFileDescriptor.get());
      VERIFY(exporter->getPlugIn() != NULL);
      bSaved = exporter->execute();
   }

   if (!bSaved)
   {
      reportError("Could not save the layer to the file: " + filename, "CAFF2CD5-E6CB-4e90-80E7-87E094F2CB1C");
      return false;
   }

   reportComplete();
   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*> 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;
}
Beispiel #9
0
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, &centerWavelengths) == 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, &centerWavelengths, &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());
               }
Beispiel #10
0
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;
}
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;
}