示例#1
0
std::vector<ImportDescriptor*> VideoImporter::getImportDescriptors(const std::string &filename)
{
   std::vector<ImportDescriptor*> descriptors;
   AVFormatResource pFormatCtx;
   { // scope
      AVFormatContext* pTmp = NULL;
      if (av_open_input_file(&pTmp, filename.c_str(), NULL, 0, NULL) != 0)
      {
         return descriptors;
      }
      pFormatCtx.reset(pTmp);
   }
   if (av_find_stream_info(pFormatCtx) < 0)
   {
      return descriptors;
   }
   for(int streamId = 0; streamId < pFormatCtx->nb_streams; streamId++)
   {
      if(pFormatCtx->streams[streamId]->codec->codec_type == CODEC_TYPE_VIDEO)
      {
         AVCodecContext* pCodecCtx = pFormatCtx->streams[streamId]->codec;
         AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
         VERIFYRV(pCodec != NULL, descriptors);
         if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
         {
            pCodecCtx->flags |= CODEC_FLAG_TRUNCATED;
         }
         if(avcodec_open(pCodecCtx, pCodec) < 0)
         {
            return descriptors;
         }

         ImportDescriptorResource pStreamDescriptor(filename, "VideoStream");
         VERIFYRV(pStreamDescriptor.get() != NULL, descriptors);
         pStreamDescriptor->getDataDescriptor()->setProcessingLocation(ON_DISK_READ_ONLY);
         RasterUtilities::generateAndSetFileDescriptor(pStreamDescriptor->getDataDescriptor(), filename,
            StringUtilities::toDisplayString(streamId), LITTLE_ENDIAN);
         std::string rasterName = filename + QString(":%1").arg(streamId).toStdString();
         ImportDescriptorResource pRasterDescriptor(rasterName,
                                                    TypeConverter::toString<RasterElement>(),
                                                    std::vector<std::string>(1, filename));
         VERIFYRV(pRasterDescriptor.get() != NULL, descriptors);

         RasterDataDescriptor* pDesc = static_cast<RasterDataDescriptor*>(pRasterDescriptor->getDataDescriptor());

         std::vector<DimensionDescriptor> rowDims = RasterUtilities::generateDimensionVector(pCodecCtx->height);
         pDesc->setRows(rowDims);
         std::vector<DimensionDescriptor> colDims = RasterUtilities::generateDimensionVector(pCodecCtx->width);
         pDesc->setColumns(colDims);
         std::vector<DimensionDescriptor> bandDims = RasterUtilities::generateDimensionVector(3);
         pDesc->setBands(bandDims);
         pDesc->setInterleaveFormat(BIP);
         pDesc->setDataType(INT1UBYTE);
         pDesc->setProcessingLocation(IN_MEMORY);
         pDesc->setDisplayMode(RGB_MODE);
         pDesc->setDisplayBand(RED, pDesc->getActiveBand(0));
         pDesc->setDisplayBand(GREEN, pDesc->getActiveBand(1));
         pDesc->setDisplayBand(BLUE, pDesc->getActiveBand(2));
         RasterUtilities::generateAndSetFileDescriptor(pDesc, filename, StringUtilities::toDisplayString(streamId), LITTLE_ENDIAN);

         descriptors.push_back(pStreamDescriptor.release());
         descriptors.push_back(pRasterDescriptor.release());
      }
   }
   return descriptors;
}
示例#2
0
vector<ImportDescriptor*> Nitf::NitfImporterShell::getImportDescriptors(const string &filename)
{
   vector<ImportDescriptor*> retval;

   if (filename.empty())
   {
      return retval;
   }

   Nitf::OssimFileResource pFile(filename);
   if (pFile.get() == NULL)
   {
      return retval;
   }

   Nitf::OssimImageHandlerResource pHandler(filename);
   if (pHandler.get() == NULL || pHandler->canCastTo("ossimNitfTileSource") == false)
   {
      return retval;
   }

   ossimNitfFileHeaderV2_X* pFileHeader =
      PTR_CAST(ossimNitfFileHeaderV2_X, pFile->getHeader().get());
   if (pFileHeader == NULL)
   {
      return retval;
   }

   // Not all segments are importable.  This is generally due to the segment
   // using an unsupported compression format.  Only generate descriptors
   // for the importable segments.
   vector<ossim_uint32> importableImageSegments;
   pHandler->getEntryList(importableImageSegments);

   // Create map of TRE parsers.
   // The sole purpose of this map is to force DLLs to stay loaded while the metadata is being imported.
   std::map<std::string, TrePlugInResource> parsers;

   for (vector<ossim_uint32>::iterator segmentIter = importableImageSegments.begin();
        segmentIter != importableImageSegments.end(); ++segmentIter)
   {
      // Do not call pHandler->setCurrentEntry as it is a very expensive operation
      // which causes up to a several second delay on files with many large images.
      const ossim_uint32& currentIndex = *segmentIter;
      ossimNitfImageHeaderV2_X* pImgHeader =
         PTR_CAST(ossimNitfImageHeaderV2_X, pFile->getNewImageHeader(currentIndex));
      if (pImgHeader == NULL)
      {
         continue;
      }

      EncodingType dataType = ossimImageHeaderToEncodingType(pImgHeader);
      if (dataType.isValid() == false)
      {
         continue;
      }

      stringstream imageNameStream;
      imageNameStream << "I" << currentIndex + 1;
      string imageName = imageNameStream.str();

      ImportDescriptorResource pImportDescriptor(getImportDescriptor(filename, imageName,
         pFile.get(), pFileHeader, pImgHeader));
      if (pImportDescriptor.get() == NULL)
      {
         continue;
      }

      RasterDataDescriptor* pDd = dynamic_cast<RasterDataDescriptor*>(pImportDescriptor->getDataDescriptor());
      VERIFYRV(pDd != NULL, retval);

      vector<DimensionDescriptor> bands = 
         RasterUtilities::generateDimensionVector(pImgHeader->getNumberOfBands(), true, false, true);
      pDd->setBands(bands);

      vector<DimensionDescriptor> rows = 
         RasterUtilities::generateDimensionVector(pImgHeader->getNumberOfRows(), true, false, true);
      pDd->setRows(rows);

      vector<DimensionDescriptor> cols = 
         RasterUtilities::generateDimensionVector(pImgHeader->getNumberOfCols(), true, false, true);
      pDd->setColumns(cols);

      if (pImgHeader->getIMode() == "P")
      {
         pDd->setInterleaveFormat(BIP);
      }
      else if (pImgHeader->getIMode() == "R")
      {
         pDd->setInterleaveFormat(BIL);
      }
      else
      {
         pDd->setInterleaveFormat(BSQ);
      }

      pDd->setDataType(dataType);
      pDd->setValidDataTypes(vector<EncodingType>(1, dataType));
      pDd->setProcessingLocation(IN_MEMORY);

      RasterFileDescriptor* pFd = dynamic_cast<RasterFileDescriptor*>(
         RasterUtilities::generateAndSetFileDescriptor(pDd, filename, imageName, LITTLE_ENDIAN_ORDER));

      string errorMessage;
      if (Nitf::importMetadata(currentIndex + 1, pFile, pFileHeader, pImgHeader, pDd, parsers, errorMessage) == true)
      {
         if (pImgHeader->hasTransparentCode() == true)
         {
            vector<int> badValues;
            badValues.push_back(static_cast<int>(pImgHeader->getTransparentCode()));
            pDd->setBadValues(badValues);
         }

         // If red, green, OR blue bands are valid, set the display mode to RGB.
         if (pDd->getDisplayBand(RED).isValid() == true ||
             pDd->getDisplayBand(GREEN).isValid() == true ||
             pDd->getDisplayBand(BLUE).isValid() == true)
         {
            pDd->setDisplayMode(RGB_MODE);
         }
         // Otherwise, if the gray band is valid, set the display mode to GRAYSCALE.
         else if (pDd->getDisplayBand(GRAY).isValid() == true)
         {
            pDd->setDisplayMode(GRAYSCALE_MODE);
         }
         // Otherwise, if at least 3 bands are available, set the display mode to RGB,
         // and set the first three bands to red, green, and blue respectively.
         else if (bands.size() >= 3)
         {
            pDd->setDisplayBand(RED, bands[0]);
            pDd->setDisplayBand(GREEN, bands[1]);
            pDd->setDisplayBand(BLUE, bands[2]);
            pDd->setDisplayMode(RGB_MODE);
         }
         // Otherwise, if at least 1 band is available, set the display mode to GRAYSCALE,
         // and set the first band to GRAY.
         else if (bands.empty() == false)
         {
            pDd->setDisplayBand(GRAY, bands[0]);
            pDd->setDisplayMode(GRAYSCALE_MODE);
         }
         else
         {
            continue;
         }

         mParseMessages[imageName] = errorMessage;
         retval.push_back(pImportDescriptor.release());
      }
   }

   return retval;
}
示例#3
0
ImportDescriptor* Nitf::NitfImporterShell::getImportDescriptor(const string& filename, ossim_uint32 imageSegment,
                                                               const Nitf::OssimFileResource& pFile,
                                                               const ossimNitfFileHeaderV2_X* pFileHeader,
                                                               const ossimNitfImageHeaderV2_X* pImageSubheader)
{
   if (pImageSubheader == NULL)
   {
      return NULL;
   }

   EncodingType dataType = ossimImageHeaderToEncodingType(pImageSubheader);
   if (dataType.isValid() == false)
   {
      return NULL;
   }

   stringstream imageNameStream;
   imageNameStream << "I" << imageSegment + 1;
   string imageName = imageNameStream.str();

   ImportDescriptorResource pImportDescriptor(filename + "-" + imageName,
      TypeConverter::toString<RasterElement>(), NULL);
   VERIFYRV(pImportDescriptor.get() != NULL, NULL);
   pImportDescriptor->setImported(pImageSubheader->getRepresentation() != "NODISPLY");

   RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pImportDescriptor->getDataDescriptor());
   VERIFYRV(pDescriptor != NULL, NULL);

   vector<DimensionDescriptor> bands =  RasterUtilities::generateDimensionVector(pImageSubheader->getNumberOfBands(),
      true, false, true);
   pDescriptor->setBands(bands);

   vector<DimensionDescriptor> rows = RasterUtilities::generateDimensionVector(pImageSubheader->getNumberOfRows(),
      true, false, true);
   pDescriptor->setRows(rows);

   vector<DimensionDescriptor> cols = RasterUtilities::generateDimensionVector(pImageSubheader->getNumberOfCols(),
      true, false, true);
   pDescriptor->setColumns(cols);

   if (pImageSubheader->getIMode() == "P")
   {
      pDescriptor->setInterleaveFormat(BIP);
   }
   else if (pImageSubheader->getIMode() == "R")
   {
      pDescriptor->setInterleaveFormat(BIL);
   }
   else
   {
      pDescriptor->setInterleaveFormat(BSQ);
   }

   pDescriptor->setDataType(dataType);
   pDescriptor->setValidDataTypes(vector<EncodingType>(1, dataType));
   pDescriptor->setProcessingLocation(IN_MEMORY);

   map<string, TrePlugInResource> parsers;
   string errorMessage;

   // Set the file descriptor
   RasterFileDescriptor* pFileDescriptor = dynamic_cast<RasterFileDescriptor*>(
      RasterUtilities::generateAndSetFileDescriptor(pDescriptor, filename, imageName, LITTLE_ENDIAN_ORDER));
   if (pFileDescriptor == NULL)
   {
      return NULL;
   }

   // Set the bits per element, which may be different than the data type in the data descriptor,
   // using NBPP instead of ABPP as is done in ossimNitfTileSource.cpp.
   unsigned int bitsPerPixel = static_cast<unsigned int>(pImageSubheader->getBitsPerPixelPerBand());
   pFileDescriptor->setBitsPerElement(bitsPerPixel);

   // Populate the metadata and set applicable values in the data descriptor
   if (Nitf::importMetadata(imageSegment + 1, pFile, pFileHeader, pImageSubheader, pDescriptor, parsers,
      errorMessage) == true)
   {
      // Populate specific fields in the data descriptor or file descriptor from the TREs
      const DynamicObject* pMetadata = pDescriptor->getMetadata();
      VERIFYRV(pMetadata, NULL);

      // Pixel size - This info is contained in multiple TREs, but there is no documentation on which
      // TRE contains the more precise value if multiple TREs containing the info are present.  Choosing
      // the order ACFTA, BANDSA, ACFTB, and BANDSB where the later "B" TREs will overwrite the values
      // contained in the earlier "A" TREs.  The BANDSB TRE contains GSD values for each band, which is
      // currently not supported, so only set the pixel size if the values in all bands are the same.
      double xGsd = 1.0;
      double yGsd = 1.0;

      const string acrftaPath[] =
      {
         Nitf::NITF_METADATA,
         Nitf::TRE_METADATA,
         "ACFTA",
         "0",
         END_METADATA_NAME
      };

      const DynamicObject* pAcrftA = dv_cast<DynamicObject>(&pMetadata->getAttributeByPath(acrftaPath));
      if (pAcrftA != NULL)
      {
         // The ACFTA spec calls out specific spacing units for "SAR" and "EO-IR" data, but does not indicate how
         // this is determined.  It seems to be related to the ACFTB SENSOR_ID_TYPE field, but that field is not
         // present in the ACFTA TRE.  So just check for "SAR" data from the ICAT field in the image subheader
         // and assume every other data type is "EO-IR" data.
         const string imageCategory = pImageSubheader->getCategory().trim();

         const DataVariant& rowSpacing = pAcrftA->getAttribute(Nitf::TRE::ACFTA::ROW_SPACING);
         if (rowSpacing.isValid() == true)
         {
            if (imageCategory == "SAR")
            {
               yGsd = getGsd(rowSpacing, "f");     // Feet
            }
            else
            {
               yGsd = getGsd(rowSpacing, "r");     // Micro-radians
            }
         }

         const DataVariant& columnSpacing = pAcrftA->getAttribute(Nitf::TRE::ACFTA::COL_SPACING);
         if (columnSpacing.isValid() == true)
         {
            if (imageCategory == "SAR")
            {
               xGsd = getGsd(columnSpacing, "f");  // Feet
            }
            else
            {
               xGsd = getGsd(columnSpacing, "r");  // Micro-radians
            }
         }
      }

      const string bandsaPath[] =
      {
         Nitf::NITF_METADATA,
         Nitf::TRE_METADATA,
         "BANDSA",
         "0",
         END_METADATA_NAME
      };

      const DynamicObject* pBandsA = dv_cast<DynamicObject>(&pMetadata->getAttributeByPath(bandsaPath));
      if (pBandsA != NULL)
      {
         const DataVariant& rowSpacing = pBandsA->getAttribute(Nitf::TRE::BANDSA::ROW_SPACING);
         if (rowSpacing.isValid() == true)
         {
            const DataVariant& rowSpacingUnits = pBandsA->getAttribute(Nitf::TRE::BANDSA::ROW_SPACING_UNITS);
            if (rowSpacingUnits.isValid() == true)
            {
               yGsd = getGsd(rowSpacing, rowSpacingUnits.toXmlString());
            }
         }

         const DataVariant& columnSpacing = pBandsA->getAttribute(Nitf::TRE::BANDSA::COL_SPACING);
         if (columnSpacing.isValid() == true)
         {
            const DataVariant& columnSpacingUnits = pBandsA->getAttribute(Nitf::TRE::BANDSA::COL_SPACING_UNITS);
            if (columnSpacingUnits.isValid() == true)
            {
               xGsd = getGsd(columnSpacing, columnSpacingUnits.toXmlString());
            }
         }
      }

      const string acrftbPath[] =
      {
         Nitf::NITF_METADATA,
         Nitf::TRE_METADATA,
         "ACFTB",
         "0",
         END_METADATA_NAME
      };

      const DynamicObject* pAcrftB = dv_cast<DynamicObject>(&pMetadata->getAttributeByPath(acrftbPath));
      if (pAcrftB != NULL)
      {
         const DataVariant& rowSpacing = pAcrftB->getAttribute(Nitf::TRE::ACFTB::ROW_SPACING);
         if (rowSpacing.isValid() == true)
         {
            const DataVariant& rowSpacingUnits = pAcrftB->getAttribute(Nitf::TRE::ACFTB::ROW_SPACING_UNITS);
            if (rowSpacingUnits.isValid() == true)
            {
               yGsd = getGsd(rowSpacing, rowSpacingUnits.toXmlString());
            }
         }

         const DataVariant& columnSpacing = pAcrftB->getAttribute(Nitf::TRE::ACFTB::COL_SPACING);
         if (columnSpacing.isValid() == true)
         {
            const DataVariant& columnSpacingUnits = pAcrftB->getAttribute(Nitf::TRE::ACFTB::COL_SPACING_UNITS);
            if (columnSpacingUnits.isValid() == true)
            {
               xGsd = getGsd(columnSpacing, columnSpacingUnits.toXmlString());
            }
         }
      }

      const string bandsbPath[] =
      {
         Nitf::NITF_METADATA,
         Nitf::TRE_METADATA,
         "BANDSB",
         "0",
         END_METADATA_NAME
      };

      const DynamicObject* pBandsB = dv_cast<DynamicObject>(&pMetadata->getAttributeByPath(bandsbPath));
      if (pBandsB != NULL)
      {
         bool validRowGsd = false;

         const DataVariant& rowGsd = pBandsB->getAttribute(Nitf::TRE::BANDSB::ROW_GSD);
         if (rowGsd.isValid() == true)
         {
            const DataVariant& rowGsdUnits = pBandsB->getAttribute(Nitf::TRE::BANDSB::ROW_GSD_UNIT);
            if (rowGsdUnits.isValid() == true)
            {
               yGsd = getGsd(rowGsd, rowGsdUnits.toXmlString());
               validRowGsd = true;
            }
         }

         if (validRowGsd == false)
         {
            if (pBandsB->getAttribute(Nitf::TRE::BANDSB::ROW_GSD + "#0").isValid())
            {
               double commonYGsd = -1.0;

               unsigned int numBands = pDescriptor->getBandCount();
               for (unsigned int i = 0; i < numBands; ++i)
               {
                  double bandYGsd = -1.0;
                  string bandPostfix = "#" + StringUtilities::toDisplayString(i);

                  const DataVariant& bandRowGsd = pBandsB->getAttribute(Nitf::TRE::BANDSB::ROW_GSD + bandPostfix);
                  if (bandRowGsd.isValid() == true)
                  {
                     const DataVariant& bandRowGsdUnits = pBandsB->getAttribute(Nitf::TRE::BANDSB::ROW_GSD_UNIT +
                        bandPostfix);
                     if (bandRowGsdUnits.isValid() == true)
                     {
                        bandYGsd = getGsd(bandRowGsd, bandRowGsdUnits.toXmlString());
                     }
                  }

                  if (bandYGsd == commonYGsd)
                  {
                     continue;
                  }

                  if (commonYGsd != -1.0)
                  {
                     commonYGsd = -1.0;
                     break;
                  }

                  commonYGsd = bandYGsd;
               }

               if (commonYGsd != 1.0)
               {
                  yGsd = commonYGsd;
               }
            }
         }

         bool validColumnGsd = false;

         const DataVariant& columnGsd = pBandsB->getAttribute(Nitf::TRE::BANDSB::COL_GSD);
         if (columnGsd.isValid() == true)
         {
            const DataVariant& columnGsdUnits = pBandsB->getAttribute(Nitf::TRE::BANDSB::COL_GSD_UNITS);
            if (columnGsdUnits.isValid() == true)
            {
               xGsd = getGsd(columnGsd, columnGsdUnits.toXmlString());
               validColumnGsd = true;
            }
         }

         if (validColumnGsd == false)
         {
            if (pBandsB->getAttribute(Nitf::TRE::BANDSB::COL_GSD + "#0").isValid())
            {
               double commonXGsd = -1.0;

               unsigned int numBands = pDescriptor->getBandCount();
               for (unsigned int i = 0; i < numBands; ++i)
               {
                  double bandXGsd = -1.0;
                  string bandPostfix = "#" + StringUtilities::toDisplayString(i);

                  const DataVariant& bandRowGsd = pBandsB->getAttribute(Nitf::TRE::BANDSB::COL_GSD + bandPostfix);
                  if (bandRowGsd.isValid() == true)
                  {
                     const DataVariant& bandRowGsdUnits = pBandsB->getAttribute(Nitf::TRE::BANDSB::COL_GSD_UNIT +
                        bandPostfix);
                     if (bandRowGsdUnits.isValid() == true)
                     {
                        bandXGsd = getGsd(bandRowGsd, bandRowGsdUnits.toXmlString());
                     }
                  }

                  if (bandXGsd == commonXGsd)
                  {
                     continue;
                  }

                  if (commonXGsd != -1.0)
                  {
                     commonXGsd = -1.0;
                     break;
                  }

                  commonXGsd = bandXGsd;
               }

               if (commonXGsd != 1.0)
               {
                  xGsd = commonXGsd;
               }
            }
         }
      }

      double magFactor = 1.0;
      ossimString imag = pImageSubheader->getImageMagnification().trim();
      if (imag.empty() == false)
      {
         // Need to multiply the GSD values by the image magnification (IMAG) value in the image subheader
         if (imag[0] == '/')
         {
            ossimString reciprocal = imag.substr(1);
            magFactor = 1.0 / reciprocal.toDouble();
         }
         else
         {
            magFactor = imag.toDouble();
         }

         xGsd *= magFactor;
         yGsd *= magFactor;
      }

      pDescriptor->setXPixelSize(xGsd);
      pDescriptor->setYPixelSize(yGsd);

      // Higher precision GCPs
      const string blockaPath[] =
      {
         Nitf::NITF_METADATA,
         Nitf::TRE_METADATA,
         "BLOCKA",
         "0",
         END_METADATA_NAME
      };

      const DynamicObject* pBlockA = dv_cast<DynamicObject>(&pMetadata->getAttributeByPath(blockaPath));
      if (pBlockA != NULL)
      {
         const DataVariant& blockLines = pBlockA->getAttribute(Nitf::TRE::BLOCKA::L_LINES);
         if (blockLines.isValid() == true)
         {
            unsigned int numBlockRows = 0;
            if (blockLines.getValue<unsigned int>(numBlockRows) == true)
            {
               // Need to multiply the number of rows by the image magnification (IMAG) value in the image subheader
               numBlockRows = static_cast<unsigned int>(static_cast<double>(numBlockRows) * magFactor);
               if (numBlockRows == pFileDescriptor->getRowCount())
               {
                  list<GcpPoint> updatedGcps;

                  list<GcpPoint> gcps = pFileDescriptor->getGcps();
                  for (list<GcpPoint>::iterator iter = gcps.begin(); iter != gcps.end(); ++iter)
                  {
                     GcpPoint gcp = *iter;
                     string coordinateText;

                     list<GcpPoint>::size_type index = updatedGcps.size();
                     if (index == 0)
                     {
                        const DataVariant& gcp1 = pBlockA->getAttribute(Nitf::TRE::BLOCKA::FRFC_LOC);
                        if (gcp1.isValid() == true)
                        {
                           coordinateText = gcp1.toXmlString();
                        }
                     }
                     else if (index == 1)
                     {
                        const DataVariant& gcp2 = pBlockA->getAttribute(Nitf::TRE::BLOCKA::FRLC_LOC);
                        if (gcp2.isValid() == true)
                        {
                           coordinateText = gcp2.toXmlString();
                        }
                     }
                     else if (index == 2)
                     {
                        const DataVariant& gcp3 = pBlockA->getAttribute(Nitf::TRE::BLOCKA::LRLC_LOC);
                        if (gcp3.isValid() == true)
                        {
                           coordinateText = gcp3.toXmlString();
                        }
                     }
                     else if (index == 3)
                     {
                        const DataVariant& gcp4 = pBlockA->getAttribute(Nitf::TRE::BLOCKA::LRFC_LOC);
                        if (gcp4.isValid() == true)
                        {
                           coordinateText = gcp4.toXmlString();
                        }
                     }

                     if (StringUtilities::isAllBlank(coordinateText) == false)
                     {
                        coordinateText.insert(10, ", ");
                        LatLonPoint latLon(coordinateText);
                        gcp.mCoordinate = latLon.getCoordinates();
                     }

                     updatedGcps.push_back(gcp);
                  }

                  pFileDescriptor->setGcps(updatedGcps);
               }
            }
         }
      }

      // This only checks the first BANDSB. It is possible to have multiple BANDSB TREs.
      // If someone runs across real data where the bad band info is in another BANDSB TRE
      // this code will need to be modified.
      if (pBandsB != NULL && pBandsB->getAttribute(Nitf::TRE::BANDSB::BAD_BAND + "#0").isValid())
      {
         const vector<DimensionDescriptor>& curBands = pDescriptor->getBands();
         vector<DimensionDescriptor> newBands;
         for (size_t idx = 0; idx < curBands.size(); ++idx)
         {
            const int* pVal = dv_cast<int>(&pBandsB->getAttribute(
               Nitf::TRE::BANDSB::BAD_BAND + "#" + StringUtilities::toDisplayString(idx)));
            if (pVal == NULL || *pVal == 1) // 0 == invalid or suspect band, 1 = valid band
            {
               newBands.push_back(curBands[idx]);
            }
         }
         pDescriptor->setBands(newBands);
      }

      // Bad values
      if (pImageSubheader->hasTransparentCode() == true)
      {
         vector<int> badValues;
         badValues.push_back(static_cast<int>(pImageSubheader->getTransparentCode()));
         pDescriptor->setBadValues(badValues);
      }

      // If red, green, OR blue bands are valid, set the display mode to RGB.
      if (pDescriptor->getDisplayBand(RED).isValid() == true ||
         pDescriptor->getDisplayBand(GREEN).isValid() == true ||
         pDescriptor->getDisplayBand(BLUE).isValid() == true)
      {
         pDescriptor->setDisplayMode(RGB_MODE);
      }
      // Otherwise, if the gray band is valid, set the display mode to GRAYSCALE.
      else if (pDescriptor->getDisplayBand(GRAY).isValid() == true)
      {
         pDescriptor->setDisplayMode(GRAYSCALE_MODE);
      }
      // Otherwise, if at least 3 bands are available, set the display mode to RGB,
      // and set the first three bands to red, green, and blue respectively.
      else if (bands.size() >= 3)
      {
         pDescriptor->setDisplayBand(RED, bands[0]);
         pDescriptor->setDisplayBand(GREEN, bands[1]);
         pDescriptor->setDisplayBand(BLUE, bands[2]);
         pDescriptor->setDisplayMode(RGB_MODE);
      }
      // Otherwise, if at least 1 band is available, set the display mode to GRAYSCALE,
      // and set the first band to GRAY.
      else if (bands.empty() == false)
      {
         pDescriptor->setDisplayBand(GRAY, bands[0]);
         pDescriptor->setDisplayMode(GRAYSCALE_MODE);
      }
      else
      {
         return NULL;
      }

      // Special initialization for J2K compressed image segments
      const string compressionPath[] =
      {
         Nitf::NITF_METADATA,
         Nitf::IMAGE_SUBHEADER,
         Nitf::ImageSubheaderFieldNames::COMPRESSION,
         END_METADATA_NAME
      };

      string imageCompression = pMetadata->getAttributeByPath(compressionPath).toDisplayString();
      if ((imageCompression == Nitf::ImageSubheaderFieldValues::IC_C8) ||
         (imageCompression == Nitf::ImageSubheaderFieldValues::IC_M8))
      {
         // Per Section 8.1 of the BIIF Profile for JPEG 2000 Version 01.10 (BPJ2K01.10),
         // if the values in the J2K data differ from the values in the image subheader,
         // the J2K values are given precedence.
         opj_image_t* pImage = getImageInfo(filename, imageSegment, OPJ_CODEC_J2K);
         if (pImage == NULL)
         {
            pImage = getImageInfo(filename, imageSegment, OPJ_CODEC_JP2);
         }

         if (pImage != NULL)
         {
            // Bits per element
            unsigned int bitsPerElement = pImage->comps->prec;
            if (bitsPerElement != pFileDescriptor->getBitsPerElement())
            {
               pFileDescriptor->setBitsPerElement(bitsPerElement);
            }

            // Data type
            EncodingType dataType = INT1UBYTE;
            if (bitsPerElement <= 8)
            {
               if (pImage->comps->sgnd)
               {
                  dataType = INT1SBYTE;
               }
               else
               {
                  dataType = INT1UBYTE;
               }
            }
            else if (bitsPerElement <= 16)
            {
               if (pImage->comps->sgnd)
               {
                  dataType = INT2SBYTES;
               }
               else
               {
                  dataType = INT2UBYTES;
               }
            }
            else if (bitsPerElement <= 32)
            {
               if (pImage->comps->sgnd)
               {
                  dataType = INT4SBYTES;
               }
               else
               {
                  dataType = INT4UBYTES;
               }
            }
            else if (bitsPerElement <= 64)
            {
               dataType = FLT8BYTES;
            }

            if (dataType != pDescriptor->getDataType())
            {
               pDescriptor->setDataType(dataType);
            }

            // Rows
            unsigned int numRows = pImage->comps->h;
            if (numRows != pFileDescriptor->getRowCount())
            {
               vector<DimensionDescriptor> rows = RasterUtilities::generateDimensionVector(numRows, true, false, true);
               pDescriptor->setRows(rows);
               pFileDescriptor->setRows(rows);
            }

            // Columns
            unsigned int numColumns = pImage->comps->w;
            if (numColumns != pFileDescriptor->getColumnCount())
            {
               vector<DimensionDescriptor> columns = RasterUtilities::generateDimensionVector(numColumns, true, false,
                  true);
               pDescriptor->setColumns(columns);
               pFileDescriptor->setColumns(columns);
            }

            // Bands
            unsigned int numBands = pImage->numcomps;
            if (numBands != pFileDescriptor->getBandCount())
            {
               vector<DimensionDescriptor> bands = RasterUtilities::generateDimensionVector(numBands, true, false,
                  true);
               pDescriptor->setBands(bands);
               pFileDescriptor->setBands(bands);
            }

            // Cleanup
            opj_image_destroy(pImage);
         }

         // Set the interleave format as BIP, which is the interleave format for J2K data
         pDescriptor->setInterleaveFormat(BIP);
         pFileDescriptor->setInterleaveFormat(BIP);
      }

      mParseMessages[imageSegment] = errorMessage;
   }

   return pImportDescriptor.release();
}
示例#4
0
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;
}
示例#5
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());
               }
示例#6
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;
}
std::vector<ImportDescriptor*> LandsatGeotiffImporter::createImportDescriptors(const std::string& filename,
   const DynamicObject* pImageMetadata,
   Landsat::LandsatImageType type)
{
   std::string suffix;
   if (type == Landsat::LANDSAT_VNIR)
   {
      suffix = "vnir";
   }
   else if (type == Landsat::LANDSAT_PAN)
   {
      suffix = "pan";
   }
   else if (type == Landsat::LANDSAT_TIR)
   {
      suffix = "tir";
   }
   std::vector<ImportDescriptor*> descriptors;
   std::string spacecraft = dv_cast<std::string>(
      pImageMetadata->getAttributeByPath("LANDSAT_MTL/L1_METADATA_FILE/PRODUCT_METADATA/SPACECRAFT_ID"), "");
   std::vector<std::string> bandNames = Landsat::getSensorBandNames(spacecraft, type);
   if (bandNames.empty())
   {
      //this spacecraft and iamge type
      //isn't meant to have any bands, so terminate early
      //e.g. spacecraft == "Landsat5" && type == Landsat::LANDSAT_PAN
      return descriptors;
   }
   std::vector<unsigned int> validBands;
   std::vector<std::string> bandFiles = Landsat::getGeotiffBandFilenames(
      pImageMetadata, filename, type, validBands);
   if (bandFiles.empty())
   {
      mWarnings.push_back("Unable to locate band files for " + suffix + " product."); 
      return descriptors;
   }
   ImportDescriptorResource pImportDescriptor(filename + "-" + suffix,
      TypeConverter::toString<RasterElement>(), NULL, false);
   if (pImportDescriptor.get() == NULL)
   {
      return descriptors;
   }
   RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pImportDescriptor->getDataDescriptor());
   if (pDescriptor == NULL)
   {
      return descriptors;
   }
   pDescriptor->setProcessingLocation(ON_DISK);
   DynamicObject* pMetadata = pDescriptor->getMetadata();
   pMetadata->merge(pImageMetadata);
   FactoryResource<RasterFileDescriptor> pFileDescriptorRes;
   pDescriptor->setFileDescriptor(pFileDescriptorRes.get());
   RasterFileDescriptor* pFileDescriptor = dynamic_cast<RasterFileDescriptor*>(pDescriptor->getFileDescriptor());
   pFileDescriptor->setFilename(filename);

   std::string tiffFile = bandFiles[0];
   if (!Landsat::parseBasicsFromTiff(tiffFile, pDescriptor))
   {
      mWarnings.push_back("Unable to parse basic information about image from tiff file for " + suffix + " product.");
      return descriptors;
   }
   if (pDescriptor->getBandCount() != 1 || pDescriptor->getDataType() != INT1UBYTE)
   {
      mWarnings.push_back("Improperly formatted tiff file for " + suffix + " product.");
      return descriptors;
   }
   pDescriptor->setInterleaveFormat(BSQ); //one tiff file per band.
   pFileDescriptor->setInterleaveFormat(BSQ);
   std::vector<DimensionDescriptor> bands = RasterUtilities::generateDimensionVector(
      bandFiles.size(), true, false, true);
   pDescriptor->setBands(bands);
   pFileDescriptor->setBands(bands);
   pDescriptor->setBadValues(std::vector<int>(1, 0));
   pFileDescriptor->setDatasetLocation(suffix);

   //special metadata here
   Landsat::fixMtlMetadata(pMetadata, type, validBands);

   std::vector<std::string> defaultImport = OptionsLandsatImport::getSettingDefaultImport();
   bool fallbackToDn = false;
   descriptors.push_back(pImportDescriptor.release());

   if (type == Landsat::LANDSAT_VNIR)
   {
      //attempt to display true-color
      DimensionDescriptor redBand = RasterUtilities::findBandWavelengthMatch(0.630, 0.690, pDescriptor);
      DimensionDescriptor greenBand = RasterUtilities::findBandWavelengthMatch(0.510, 0.590, pDescriptor);
      DimensionDescriptor blueBand = RasterUtilities::findBandWavelengthMatch(0.410, 0.490, pDescriptor);
      if (redBand.isValid() && greenBand.isValid() && blueBand.isValid())
      {
         pDescriptor->setDisplayMode(RGB_MODE);
         pDescriptor->setDisplayBand(RED, redBand);
         pDescriptor->setDisplayBand(GREEN, greenBand);
         pDescriptor->setDisplayBand(BLUE, blueBand);
      }
   }

   std::vector<std::pair<double, double> > radianceFactors = Landsat::determineRadianceConversionFactors(
      pMetadata, type, validBands);
   bool shouldDefaultImportRadiance =
      std::find(defaultImport.begin(), defaultImport.end(), suffix + "-Radiance") != defaultImport.end();
   if (radianceFactors.size() == bandFiles.size())
   {
      //we have enough to create radiance import descriptor
      RasterDataDescriptor* pRadianceDescriptor = dynamic_cast<RasterDataDescriptor*>(
         pDescriptor->copy(filename + "-" + suffix + "-radiance", NULL));
      if (pRadianceDescriptor != NULL)
      {
         pRadianceDescriptor->setDataType(FLT4BYTES);
         pRadianceDescriptor->setValidDataTypes(std::vector<EncodingType>(1, pRadianceDescriptor->getDataType()));
         pRadianceDescriptor->setBadValues(std::vector<int>(1, -100));
         FactoryResource<Units> pUnits;
         pUnits->setUnitType(RADIANCE);
         pUnits->setUnitName("w/(m^2*sr*um)");
         pUnits->setScaleFromStandard(1.0);
         pRadianceDescriptor->setUnits(pUnits.get());
         FileDescriptor* pRadianceFileDescriptor = pRadianceDescriptor->getFileDescriptor();
         if (pRadianceFileDescriptor != NULL)
         {
            pRadianceFileDescriptor->setDatasetLocation(suffix + "-radiance");
            ImportDescriptorResource pRadianceImportDescriptor(pRadianceDescriptor,
               shouldDefaultImportRadiance);
            descriptors.push_back(pRadianceImportDescriptor.release());
         }
      }
   }
   else if (shouldDefaultImportRadiance)
   {
      fallbackToDn = true;
   }

   std::vector<double> reflectanceFactors = Landsat::determineReflectanceConversionFactors(
      pMetadata, type, validBands);
   bool shouldDefaultImportReflectance =
      std::find(defaultImport.begin(), defaultImport.end(), suffix + "-Reflectance") != defaultImport.end();
   if (radianceFactors.size() == bandFiles.size() && reflectanceFactors.size() == bandFiles.size())
   {
      //we have enough to create reflectance import descriptor
      RasterDataDescriptor* pReflectanceDescriptor = dynamic_cast<RasterDataDescriptor*>(
         pDescriptor->copy(filename + "-" + suffix + "-reflectance", NULL));
      if (pReflectanceDescriptor != NULL)
      {
         pReflectanceDescriptor->setDataType(INT2SBYTES);
         pReflectanceDescriptor->setValidDataTypes(
            std::vector<EncodingType>(1, pReflectanceDescriptor->getDataType()));
         pReflectanceDescriptor->setBadValues(std::vector<int>(1, std::numeric_limits<short>::max()));
         FactoryResource<Units> pUnits;
         pUnits->setUnitType(REFLECTANCE);
         pUnits->setUnitName("Reflectance");
         pUnits->setScaleFromStandard(1/10000.0);
         pReflectanceDescriptor->setUnits(pUnits.get());
         FileDescriptor* pReflectanceFileDescriptor = pReflectanceDescriptor->getFileDescriptor();
         if (pReflectanceFileDescriptor != NULL)
         {
            pReflectanceFileDescriptor->setDatasetLocation(suffix + "-reflectance");
            ImportDescriptorResource pReflectanceImportDescriptor(pReflectanceDescriptor,
               shouldDefaultImportReflectance);
            descriptors.push_back(pReflectanceImportDescriptor.release());
         }
      }
   }
   else if (shouldDefaultImportReflectance)
   {
      fallbackToDn = true;
   }

   double K1 = 0.0;
   double K2 = 0.0;
   bool haveTemperatureFactors = Landsat::getTemperatureConstants(pMetadata, type,
      K1, K2);
   bool shouldDefaultImportTemperature =
      std::find(defaultImport.begin(), defaultImport.end(), suffix + "-Temperature") != defaultImport.end();
   if (radianceFactors.size() == bandFiles.size() && haveTemperatureFactors)
   {
      //we have enough to create temperature import descriptor
      RasterDataDescriptor* pTemperatureDescriptor = dynamic_cast<RasterDataDescriptor*>(
         pDescriptor->copy(filename + "-" + suffix + "-temperature", NULL));
      if (pTemperatureDescriptor != NULL)
      {
         pTemperatureDescriptor->setDataType(FLT4BYTES);
         pTemperatureDescriptor->setValidDataTypes(
            std::vector<EncodingType>(1, pTemperatureDescriptor->getDataType()));
         pTemperatureDescriptor->setBadValues(std::vector<int>(1, -1));
         FactoryResource<Units> pUnits;
         pUnits->setUnitType(EMISSIVITY);
         pUnits->setUnitName("K");
         pUnits->setScaleFromStandard(1.0);
         pTemperatureDescriptor->setUnits(pUnits.get());
         FileDescriptor* pTemperatureFileDescriptor = pTemperatureDescriptor->getFileDescriptor();
         if (pTemperatureFileDescriptor != NULL)
         {
            pTemperatureFileDescriptor->setDatasetLocation(suffix + "-temperature");
            ImportDescriptorResource pTemperatureImportDescriptor(pTemperatureDescriptor,
               shouldDefaultImportTemperature);
            descriptors.push_back(pTemperatureImportDescriptor.release());
         }
      }
   }
   else if (shouldDefaultImportTemperature)
   {
      fallbackToDn = true;
   }

   if (fallbackToDn ||
      std::find(defaultImport.begin(), defaultImport.end(), suffix + "-DN") != defaultImport.end())
   {
      pImportDescriptor->setImported(true);
   }

   return descriptors;
}
示例#8
0
bool EditDataDescriptor::execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList)
{
   StepResource pStep("Execute Wizard Item", "app", "055486F4-A9DB-4FDA-9AA7-75D1917E2C87");
   pStep->addProperty("Item", getName());
   mpStep = pStep.get();

   if (extractInputArgs(pInArgList) == false)
   {
      return false;
   }

   // Set the values in the data descriptor
   VERIFY(mpDescriptor != NULL);

   // File descriptor
   if (mpFileDescriptor != NULL)
   {
      mpDescriptor->setFileDescriptor(mpFileDescriptor);
   }

   // Processing location
   if (mpProcessingLocation != NULL)
   {
      mpDescriptor->setProcessingLocation(*mpProcessingLocation);
   }

   RasterDataDescriptor* pRasterDescriptor = dynamic_cast<RasterDataDescriptor*>(mpDescriptor);
   RasterFileDescriptor* pRasterFileDescriptor = dynamic_cast<RasterFileDescriptor*>(mpFileDescriptor);
   SignatureDataDescriptor* pSignatureDescriptor = dynamic_cast<SignatureDataDescriptor*>(mpDescriptor);
   SignatureFileDescriptor* pSignatureFileDescriptor = dynamic_cast<SignatureFileDescriptor*>(mpFileDescriptor);

   if (pRasterDescriptor != NULL)
   {
      if (pRasterFileDescriptor != NULL)
      {
         // Set the rows and columns to match the rows and columns in the file descriptor before creating the subset
         const vector<DimensionDescriptor>& rows = pRasterFileDescriptor->getRows();
         pRasterDescriptor->setRows(rows);

         const vector<DimensionDescriptor>& columns = pRasterFileDescriptor->getColumns();
         pRasterDescriptor->setColumns(columns);

         const vector<DimensionDescriptor>& bands = pRasterFileDescriptor->getBands();
         pRasterDescriptor->setBands(bands);
      }

      // Data type
      if (mpDataType != NULL)
      {
         pRasterDescriptor->setDataType(*mpDataType);
      }

      // InterleaveFormat
      if (mpInterleave != NULL)
      {
         pRasterDescriptor->setInterleaveFormat(*mpInterleave);
      }

      // Bad values
      if (mpBadValues != NULL)
      {
         pRasterDescriptor->setBadValues(*mpBadValues);
      }

      // Rows
      if ((mpStartRow != NULL) || (mpEndRow != NULL) || (mpRowSkipFactor != NULL))
      {
         // We need to obtain this origRows from the FileDescriptor if present since an importer
         // may generate a subset by default in which case the DataDescriptor will not contain all
         // the rows and subsetting will not work correctly. We
         // can't just set mpFileDescriptor = pRasterDescriptor->getFileDescriptor() since we only
         // want to replace the DataDescriptor's row list if one of the subset options is specified
         const RasterFileDescriptor* pFileDesc(pRasterFileDescriptor);
         if (pFileDesc == NULL)
         {
            pFileDesc = dynamic_cast<const RasterFileDescriptor*>(pRasterDescriptor->getFileDescriptor());
         }
         const vector<DimensionDescriptor>& origRows = (pFileDesc != NULL) ?
            pFileDesc->getRows() : pRasterDescriptor->getRows();
         unsigned int startRow = 0;
         if (mpStartRow != NULL)
         {
            startRow = *mpStartRow;
         }
         else if (origRows.empty() == false)
         {
            startRow = origRows.front().getOriginalNumber() + 1;
         }

         unsigned int endRow = 0;
         if (mpEndRow != NULL)
         {
            endRow = *mpEndRow;
         }
         else if (origRows.empty() == false)
         {
            endRow = origRows.back().getOriginalNumber() + 1;
         }

         unsigned int rowSkip = 0;
         if (mpRowSkipFactor != NULL)
         {
            rowSkip = *mpRowSkipFactor;
         }

         vector<DimensionDescriptor> rows;
         for (unsigned int i = 0; i < origRows.size(); ++i)
         {
            DimensionDescriptor rowDim = origRows[i];
            unsigned int originalNumber = rowDim.getOriginalNumber() + 1;
            if ((originalNumber >= startRow) && (originalNumber <= endRow))
            {
               rows.push_back(rowDim);
               i += rowSkip;
            }
         }

         pRasterDescriptor->setRows(rows);
      }

      // Columns
      if ((mpStartColumn != NULL) || (mpEndColumn != NULL) || (mpColumnSkipFactor != NULL))
      {
         // We need to obtain this origColumns from the FileDescriptor if present since an importer
         // may generate a subset by default in which case the DataDescriptor will not contain all
         // the columns and subsetting will not work correctly. We
         // can't just set mpFileDescriptor = pRasterDescriptor->getFileDescriptor() since we only
         // want to replace the DataDescriptor's column list if one of the subset options is specified
         const RasterFileDescriptor* pFileDesc(pRasterFileDescriptor);
         if (pFileDesc == NULL)
         {
            pFileDesc = dynamic_cast<const RasterFileDescriptor*>(pRasterDescriptor->getFileDescriptor());
         }
         const vector<DimensionDescriptor>& origColumns = (pFileDesc != NULL) ?
            pFileDesc->getColumns() : pRasterDescriptor->getColumns();

         unsigned int startColumn = 0;
         if (mpStartColumn != NULL)
         {
            startColumn = *mpStartColumn;
         }
         else if (origColumns.empty() == false)
         {
            startColumn = origColumns.front().getOriginalNumber() + 1;
         }

         unsigned int endColumn = 0;
         if (mpEndColumn != NULL)
         {
            endColumn = *mpEndColumn;
         }
         else if (origColumns.empty() == false)
         {
            endColumn = origColumns.back().getOriginalNumber() + 1;
         }

         unsigned int columnSkip = 0;
         if (mpColumnSkipFactor != NULL)
         {
            columnSkip = *mpColumnSkipFactor;
         }

         vector<DimensionDescriptor> columns;
         for (unsigned int i = 0; i < origColumns.size(); ++i)
         {
            DimensionDescriptor columnDim = origColumns[i];
            unsigned int originalNumber = columnDim.getOriginalNumber() + 1;
            if ((originalNumber >= startColumn) && (originalNumber <= endColumn))
            {
               columns.push_back(columnDim);
               i += columnSkip;
            }
         }

         pRasterDescriptor->setColumns(columns);
      }

      // Bands
      if ((mpStartBand != NULL) || (mpEndBand != NULL) || (mpBandSkipFactor != NULL) || (mpBadBandsFile != NULL))
      {
         // We need to obtain this origBands from the FileDescriptor if present since an importer
         // may generate a subset by default in which case the DataDescriptor will not contain all
         // the bands and subsetting (especially by bad band file) will not work correctly. We
         // can't just set mpFileDescriptor = pRasterDescriptor->getFileDescriptor() since we only
         // want to replace the DataDescriptor's band list if one of the subset options is specified
         const RasterFileDescriptor* pFileDesc(pRasterFileDescriptor);
         if (pFileDesc == NULL)
         {
            pFileDesc = dynamic_cast<const RasterFileDescriptor*>(pRasterDescriptor->getFileDescriptor());
         }
         const vector<DimensionDescriptor>& origBands = (pFileDesc != NULL) ?
            pFileDesc->getBands() : pRasterDescriptor->getBands();

         unsigned int startBand = 0;
         if (mpStartBand != NULL)
         {
            startBand = *mpStartBand;
         }
         else if (origBands.empty() == false)
         {
            startBand = origBands.front().getOriginalNumber() + 1;
         }

         unsigned int endBand = 0;
         if (mpEndBand != NULL)
         {
            endBand = *mpEndBand;
         }
         else if (origBands.empty() == false)
         {
            endBand = origBands.back().getOriginalNumber() + 1;
         }

         unsigned int bandSkip = 0;
         if (mpBandSkipFactor != NULL)
         {
            bandSkip = *mpBandSkipFactor;
         }

         // Get the bad bands from the file
         vector<unsigned int> badBands;
         if (mpBadBandsFile != NULL)
         {
            string filename = *mpBadBandsFile;
            if (filename.empty() == false)
            {
               FILE* pFile = fopen(filename.c_str(), "rb");
               if (pFile != NULL)
               {
                  char line[1024];
                  while (fgets(line, 1024, pFile) != NULL)
                  {
                     unsigned int bandNumber = 0;

                     int iValues = sscanf(line, "%u", &bandNumber);
                     if (iValues == 1)
                     {
                        badBands.push_back(bandNumber);
                     }
                  }

                  fclose(pFile);
               }
            }
         }

         vector<DimensionDescriptor> bands;
         for (unsigned int i = 0; i < origBands.size(); ++i)
         {
            DimensionDescriptor bandDim = origBands[i];
            unsigned int originalNumber = bandDim.getOriginalNumber() + 1;
            if ((originalNumber >= startBand) && (originalNumber <= endBand))
            {
               bool bBad = false;
               for (unsigned int j = 0; j < badBands.size(); ++j)
               {
                  unsigned int badBandNumber = badBands[j];
                  if (originalNumber == badBandNumber)
                  {
                     bBad = true;
                     break;
                  }
               }

               if (bBad == false)
               {
                  bands.push_back(bandDim);
                  i += bandSkip;
               }
            }
         }

         pRasterDescriptor->setBands(bands);
      }

      // X pixel size
      if (mpPixelSizeX != NULL)
      {
         pRasterDescriptor->setXPixelSize(*mpPixelSizeX);
      }

      // Y pixel size
      if (mpPixelSizeY != NULL)
      {
         pRasterDescriptor->setYPixelSize(*mpPixelSizeY);
      }

      // Units
      if ((mpUnitsName != NULL) || (mpUnitsType != NULL) ||
         (mpUnitsScale != NULL) || (mpUnitsRangeMin != NULL) || (mpUnitsRangeMax != NULL))
      {
         const Units* pOrigUnits = pRasterDescriptor->getUnits();

         FactoryResource<Units> pUnits;
         VERIFY(pUnits.get() != NULL);

         // Name
         if (mpUnitsName != NULL)
         {
            pUnits->setUnitName(*mpUnitsName);
         }
         else if (pOrigUnits != NULL)
         {
            pUnits->setUnitName(pOrigUnits->getUnitName());
         }

         // Type
         if (mpUnitsType != NULL)
         {
            pUnits->setUnitType(*mpUnitsType);
         }
         else if (pOrigUnits != NULL)
         {
            pUnits->setUnitType(pOrigUnits->getUnitType());
         }

         // Scale
         if (mpUnitsScale != NULL)
         {
            pUnits->setScaleFromStandard(*mpUnitsScale);
         }
         else if (pOrigUnits != NULL)
         {
            pUnits->setScaleFromStandard(pOrigUnits->getScaleFromStandard());
         }

         // Range minimum
         if (mpUnitsRangeMin != NULL)
         {
            pUnits->setRangeMin(*mpUnitsRangeMin);
         }
         else if (pOrigUnits != NULL)
         {
            pUnits->setRangeMin(pOrigUnits->getRangeMin());
         }

         // Range maximum
         if (mpUnitsRangeMax != NULL)
         {
            pUnits->setRangeMax(*mpUnitsRangeMax);
         }
         else if (pOrigUnits != NULL)
         {
            pUnits->setRangeMax(pOrigUnits->getRangeMax());
         }

         pRasterDescriptor->setUnits(pUnits.get());
      }

      // Display mode
      if (mpDisplayMode != NULL)
      {
         pRasterDescriptor->setDisplayMode(*mpDisplayMode);
      }

      // Display bands
      // Gray
      if (mpGrayBand != NULL)
      {
         DimensionDescriptor band = pRasterDescriptor->getOriginalBand(*mpGrayBand - 1);
         pRasterDescriptor->setDisplayBand(GRAY, band);
      }

      // Red
      if (mpRedBand != NULL)
      {
         DimensionDescriptor band = pRasterDescriptor->getOriginalBand(*mpRedBand - 1);
         pRasterDescriptor->setDisplayBand(RED, band);
      }

      // Green
      if (mpGreenBand != NULL)
      {
         DimensionDescriptor band = pRasterDescriptor->getOriginalBand(*mpGreenBand - 1);
         pRasterDescriptor->setDisplayBand(GREEN, band);
      }

      // Blue
      if (mpBlueBand != NULL)
      {
         DimensionDescriptor band = pRasterDescriptor->getOriginalBand(*mpBlueBand - 1);
         pRasterDescriptor->setDisplayBand(BLUE, band);
      }
   }
   else if (pSignatureDescriptor != NULL)
   {
      if (mpComponentName != NULL)
      {
         const Units* pOrigUnits = pSignatureDescriptor->getUnits(*mpComponentName);
         FactoryResource<Units> pUnits;
         if (pOrigUnits != NULL)
         {
            *pUnits = *pOrigUnits;
         }
         if (mpUnitsName != NULL)
         {
            pUnits->setUnitName(*mpUnitsName);
         }
         if (mpUnitsType != NULL)
         {
            pUnits->setUnitType(*mpUnitsType);
         }
         if (mpUnitsScale != NULL)
         {
            pUnits->setScaleFromStandard(*mpUnitsScale);
         }
         if (mpUnitsRangeMin != NULL)
         {
            pUnits->setRangeMin(*mpUnitsRangeMin);
         }
         if (mpUnitsRangeMax != NULL)
         {
            pUnits->setRangeMax(*mpUnitsRangeMax);
         }
         pSignatureDescriptor->setUnits(*mpComponentName, pUnits.get());
      }
   }

   reportComplete();
   return true;
}