void ossimScaleFilter::runFilterTemplate(T dummy,
                                         const ossimIrect& imageRect,
                                         const ossimIrect& viewRect)
{
   ossimRefPtr<ossimImageData> inputData =
      theInputConnection->getTile(imageRect);

   if(!inputData.valid()   ||
      !inputData->getBuf() ||
      (inputData->getDataObjectStatus() == OSSIM_EMPTY))
   {
      return;
   }

   ossim_int32 h = imageRect.height();
   ossimRefPtr<ossimImageData> tempData =
      ossimImageDataFactory::instance()->create(NULL,
                                                inputData->getScalarType(),
                                                inputData->getNumberOfBands(),
                                                viewRect.width(),
                                                h);
   tempData->setOrigin(ossimIpt(viewRect.ul().x,
                                imageRect.ul().y));
   
   tempData->initialize();
   
   if((m_ScaleFactor.x != 1.0)||
      (m_BlurFactor != 1.0))
   {
      runHorizontalFilterTemplate(dummy,
                                  inputData,
                                  tempData);
      tempData->validate();
   }
   else
   {
      tempData->loadTile(inputData.get());
   }
   
   if((m_ScaleFactor.y != 1.0)||
      (m_BlurFactor != 1.0))
   {
      runVerticalFilterTemplate(dummy,
                                tempData,
                                m_Tile);
   }
   else
   {
      m_Tile->loadTile(tempData.get());
   }
   
   m_Tile->validate();
}
ossimRefPtr<ossimImageData> ossimImageToPlaneNormalFilter::getTile(
   const ossimIrect& tileRect,
   ossim_uint32 resLevel)
{

   if(!isSourceEnabled()||!theInputConnection)
   {
      return ossimImageSourceFilter::getTile(tileRect, resLevel);
   }

   if(!theTile.valid())
   {
      initialize();
   }

   if(!theTile.valid())
   {
      return ossimImageSourceFilter::getTile(tileRect, resLevel);
   }

   theTile->setImageRectangle(tileRect);
   theBlankTile->setImageRectangle(tileRect);

   ossimIrect requestRect(tileRect.ul().x - 1,
                          tileRect.ul().y - 1,
                          tileRect.lr().x + 1,
                          tileRect.lr().y + 1);
   ossimRefPtr<ossimImageData> input =
      theInputConnection->getTile(requestRect, resLevel);

   if(!input||(input->getDataObjectStatus()==OSSIM_EMPTY)||!input->getBuf())
   {
      return theBlankTile;
   }

   double oldScaleX = theXScale;
   double oldScaleY = theYScale;

   if(resLevel > 0)
   {
      ossimDpt scaleFactor;
      theInputConnection->getDecimationFactor(resLevel, scaleFactor);

      if(!scaleFactor.hasNans())
      {
         theXScale *= scaleFactor.x;
         theYScale *= scaleFactor.y;
      }
   }

   computeNormals(input,
                  theTile);

   theXScale = oldScaleX;
   theYScale = oldScaleY;

   theTile->validate();

   return theTile;
}
void ossim::getDims(const ossimIrect& rect, kdu_core::kdu_dims& dims)
{
   dims.pos.x = rect.ul().x;
   dims.pos.y = rect.ul().y;
   dims.size.x = static_cast<int>(rect.width());
   dims.size.y = static_cast<int>(rect.height());
}
//**************************************************************************************************
//! Intercepts the getTile call intended for the adaptee and sets a mutex lock around the
//! adaptee's getTile call.
//**************************************************************************************************
ossimRefPtr<ossimImageData>  
   ossimImageHandlerMtAdaptor::getTile(const ossimIrect& tile_rect, ossim_uint32 rLevel)
{
   if (d_useFauxTile)
   {
      ossimRefPtr<ossimImageData> ftile = new ossimImageData(*(d_fauxTile.get()));
      ftile->setOrigin(tile_rect.ul());
      return ftile;
   }

   if (!m_adaptedHandler.valid())
      return NULL;

   // The sole purpose of the adapter is this mutex lock around the actual handler getTile:
   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(m_mutex);

   ossimRefPtr<ossimImageData> tile = new ossimImageData();
   ossimRefPtr<ossimImageData> temp_tile = 0;
   double dt = ossimTimer::instance()->time_s();
   if (d_useCache)
      temp_tile = m_cache->getTile(tile_rect, rLevel);
   else
      temp_tile = m_adaptedHandler->getTile(tile_rect, rLevel);
   d_getTileT += ossimTimer::instance()->time_s() - dt;

   // We make our own instance of a tile and copy the adaptee's returned tile to it. This avoids
   // the product tile from changing while being processed up the chain. The adaptee's tile can
   // change as soon as the mutex lock is released:
   
   if (temp_tile.valid())
      *tile = *(temp_tile.get());
   else
      tile = NULL;
   return tile;
}
Beispiel #5
0
ossimRefPtr<ossimImageData> ossimFftFilter::getTile(const ossimIrect& rect,
                                                    ossim_uint32 resLevel)
{
   if(!isSourceEnabled())
      return ossimImageSourceFilter::getTile(rect, resLevel);
   
   ossimIrect tempRequest = rect;

   ossim_uint32 w = rect.width();
   ossim_uint32 h = rect.height();
   
   if(w & 1)
      ++w;
   if(h&1)
      ++h;

   tempRequest = ossimIrect(rect.ul().x,         rect.ul().y,
                            rect.ul().x + (w-1), rect.ul().y + (h-1));
   
   ossimRefPtr<ossimImageData> inTile = theScalarRemapper->getTile(tempRequest, resLevel);
   if(!inTile.valid())
      return inTile;
   if(!theTile.valid())
      initialize();
   if(!theTile.valid() || !inTile->getBuf())
      return theTile;
   
   theTile->setImageRectangle(rect);
   ossimRefPtr<ossimImageData> tempTile = theTile;
   
   if(rect != tempRequest)
   {
      tempTile = (ossimImageData*)theTile->dup();
      tempTile->setImageRectangle(tempRequest);
   }

   runFft(inTile, tempTile);
          
   if(tempTile != theTile)
   {
      theTile->loadTile(tempTile.get());
   }
   
   theTile->validate();
   return theTile;
}
Beispiel #6
0
ossimPolygon::ossimPolygon(const ossimIrect& rect)
   : theVertexList(4),
     theCurrentVertex(0),
     theOrderingType(OSSIM_CLOCKWISE_ORDER)
{
   theVertexList[0] = rect.ul();
   theVertexList[1] = rect.ur();
   theVertexList[2] = rect.lr();
   theVertexList[3] = rect.ll();
}
void oms::SingleImageChain::setImageCut(const ossimIrect& rect)
{
   std::vector<ossimDpt> pointList(4);
   pointList[0] = rect.ul();
   pointList[1] = rect.ur();
   pointList[2] = rect.lr();
   pointList[3] = rect.ll();
   
   setImageCut(pointList);
}
Beispiel #8
0
//*******************************************************************
// Public Constructor: ossimDrect
//
//*******************************************************************
ossimDrect::ossimDrect(const ossimIrect& rect)
    :
    theUlCorner(rect.ul()),
    theUrCorner(rect.ur()),
    theLrCorner(rect.lr()),
    theLlCorner(rect.ll()),
    theOrientMode(rect.orientMode())
{
    if(rect.isNan())
    {
        makeNan();
    }
}
void ossimImageDataHelper::fill(T /* dummyVariable */,
                                const double* values,
                                const ossimIrect& region)
{
   T* buf = reinterpret_cast<T*>(theImageData->getBuf());
   
   ossim_int32 blockLength=theImageData->getWidth()*theImageData->getHeight();
   ossim_int32 bandOffset = 0;
   ossim_int32 miny,maxy;
   ossim_int32 minx, maxx;
   ossim_int32 y = 0;
   miny = region.ul().y-theOrigin.y;
   maxy = region.lr().y-theOrigin.y;
   minx = region.ul().x-theOrigin.x;
   maxx = region.lr().x-theOrigin.x;
   
   ossim_int32 rowOffset = (miny)*theImageData->getWidth();
   ossim_int32 startX = minx;
   ossim_int32 endX   = maxx;
   ossim_int32 bands  = (ossim_int32)theImageData->getNumberOfBands();

   for (y = miny; (y <= maxy); ++y)
   {
      startX=minx;
      while(startX <= endX)
      {
         bandOffset = 0;
	 int band = 0;
         for(band = 0; band < bands;++band)
         {
            buf[rowOffset+bandOffset+startX] = (T)(values[band]);
            bandOffset += blockLength;
         }
         ++startX;
      }
      rowOffset += theImageData->getWidth();
   }
}
ossimRefPtr<ossimImageData> ossimCFARFilter::getTile(const ossimIrect& tileRect,
        ossim_uint32 resLevel)
{

    if(!isSourceEnabled())
    {
        return ossimImageSourceFilter::getTile(tileRect, resLevel);
    }

    if(!outputTile.valid()) initialize();
    if(!outputTile.valid()) return 0;

    ossimRefPtr<ossimImageData> data = 0;
    if(theInputConnection)
    {
        data  = theInputConnection->getTile(tileRect, resLevel);
    } else {
        return 0;
    }

    if(!data.valid()) return 0;
    if(data->getDataObjectStatus() == OSSIM_NULL ||  data->getDataObjectStatus() == OSSIM_EMPTY)
    {
        return 0;
    }

    outputTile->setImageRectangle(tileRect);
    outputTile->makeBlank();

    outputTile->setOrigin(tileRect.ul());
    runUcharTransformation(data.get());

    if(tileRect.ul().x % 1024 == 0 && tileRect.ul().y % 1024 == 0)
        std::cout << "Processing tile: (" << tileRect.ul().x << "," << tileRect.ul().y << ")" << std::endl;

    return outputTile;

}
void ossimQtRoiRectAnnotator::setRoiRect(const ossimIrect& rect)
{
   if (thePoints.size() != 2)
   {
      thePoints.resize(2);
   }

   thePoints[0] = rect.ul();
   thePoints[1] = rect.lr();

   if (theImageWidget)
   {
      theImageWidget->refreshGraphics();
   }
}
Beispiel #12
0
//**************************************************************************************************
ossimIrect ossimScaleFilter::scaleRect(const ossimIrect input,
                                       const ossimDpt& scaleFactor)const
{
   ossimIpt origin(ossim::round<int>(input.ul().x*scaleFactor.x),
                   ossim::round<int>(input.ul().y*scaleFactor.y));
   ossim_int32 w = ossim::round<int>(input.width()*scaleFactor.x);
   ossim_int32 h = ossim::round<int>(input.height()*scaleFactor.y);

   if(w < 1) w = 1;
   if(h < 1) h = 1;
   
   return ossimIrect(origin.x,
                     origin.y,
                     origin.x + (w-1),
                     origin.y + (h-1));
}
void ossimQtScrollingImageWidget::convertRequest(const ossimIrect& reqRect)
{
   if(theRgbChain->getInput())
   {
      QImage tempImage(theTileSize.x,
                       theTileSize.y,
                       32);
      tempImage.fill(0);
      ossimIrect shiftedCacheRect = theBackingStoreCache.getCacheRect() - theShiftToZeroZero;
      ossimIrect tempRect = getAbsoluteViewportRect();
      
      tempImage.setOffset(QPoint(theShiftToZeroZero.x + reqRect.ul().x,
                                 theShiftToZeroZero.y + reqRect.ul().y));
      
      if(reqRect.intersects(shiftedCacheRect))
      {
         if(reqRect.intersects(theBoundingRect))
         {
            ossimRefPtr<ossimImageData> data = getTile(reqRect);
            
            if(data.valid() && data->getBuf() &&
               (data->getDataObjectStatus()!=OSSIM_EMPTY))
            {
               fillImage(data, &tempImage);
            }
         }
      }
      else
      {
         return;
      }
      theBackingStoreCache.addTile(tempImage);
      ossimIrect viewClip = reqRect.clipToRect(tempRect);
      viewClip  = viewClip + theShiftToZeroZero;
      int xLoc  = viewClip.ul().x;
      int yLoc  = viewClip.ul().y;
      int xSize = theTileSize.x;
      int ySize = theTileSize.y;
      eraseCursor();
      repaintContents(xLoc, yLoc, xSize, ySize, false);
   }
}
ossim_int32 ossimGui::StaticTileImageCache::getTileIndex(const ossimIrect& rect,
                                                      const ossimIpt& numberOfTiles,
                                                      ossim_int32 x,
                                                      ossim_int32 y)const
{
   ossimIpt ul = rect.ul();
   ossimIpt delta = ossimIpt(x,y) - ul;

   if((delta.x < 0) ||
      (delta.y < 0) ||
      (delta.x >= (int)rect.width())||
      (delta.y >= (int)rect.height()))
   {
      return -1;
   }
   delta.x /= m_tileSize.x;
   delta.y /= m_tileSize.y;

   return delta.y*numberOfTiles.x + delta.x;
}
ossimDrect shapefileClip::LineSampleToWorld(ossimIrect rect, ossimRefPtr<ossimImageGeometry> ImageGeom)
{
	ossimGpt gp1;
	ossimGpt gp2;
	ossimGpt gp3;
	ossimGpt gp4;

	ImageGeom->localToWorld(rect.ul(), gp1);
	ImageGeom->localToWorld(rect.ur(), gp2);
	ImageGeom->localToWorld(rect.lr(), gp3);
	ImageGeom->localToWorld(rect.ll(), gp4);
   
	ossimDrect boundsRect(ossimDpt(gp1.lond(), gp1.latd()),
		ossimDpt(gp2.lond(), gp2.latd()),
		ossimDpt(gp3.lond(), gp3.latd()),	
		ossimDpt(gp4.lond(), gp4.latd()),
		OSSIM_RIGHT_HANDED);

	return boundsRect;
}
ossim_int32 ossimGui::StaticTileImageCache::computeTileId(const ossimIpt& origin,
						       const ossimIrect& tileBounderyRect,
						       const ossimIpt&   tileSize)
{
  ossim_uint32 numberOfTilesX = tileBounderyRect.width()/tileSize.x;
  
  ossimIpt ul = tileBounderyRect.ul();
  ossimIpt delta = origin - ul;
  
  if((delta.x < 0) ||
     (delta.y < 0) ||
     (delta.x >= (int)tileBounderyRect.width())||
     (delta.y >= (int)tileBounderyRect.height()))
    {
      return -1;
    }
  delta.x /= tileSize.x;
  delta.y /= tileSize.y;
  
  return delta.y*numberOfTilesX + delta.x;
}
Beispiel #17
0
ossimRefPtr<ossimImageData> ossimImageChain::getTile(
   const ossimIrect& tileRect,
   ossim_uint32 resLevel)
{
   if((theImageChainList.size() > 0)&&(isSourceEnabled()))
   {
      ossimImageSource* interface = PTR_CAST(ossimImageSource,
                                             theImageChainList[0].get());
      
      if(interface)
      {
         // make sure we initialize in reverse order.
         // some source may depend on the initialization of
         // its inputs
         return interface->getTile(tileRect, resLevel);
      }  
   }
   else
   {
      if(getInput(0))
      {
         ossimImageSource* interface = PTR_CAST(ossimImageSource, getInput(0));
         if(interface)
         {
            return interface->getTile(tileRect, resLevel);
         }
      }
   }

   if(theBlankTile.get())
   {
      theBlankTile->setOrigin(tileRect.ul());
      theBlankTile->setWidthHeight(tileRect.width(),
                                   tileRect.height());
   }
   
   return theBlankTile;
}
ossimRefPtr<ossimImageData> ossimClosestToCenterCombiner::getTile(const ossimIrect& rect,
                                                                  ossim_uint32 resLevel)
{
   ossim_uint32 layerIdx = 0;
   if(!isSourceEnabled())
   {
      return ossimImageMosaic::getTile(rect, resLevel);
   }
   if(!theTile.valid())
   {
      allocate();
      if(!theTile.valid())
      {
         return 0;
      }
   }
   theTile->setImageRectangle(rect);
   theTile->makeBlank();
   std::vector<ossimClosestToCenterCombinerInfo > normTileList;
   ossimRefPtr<ossimImageData> currentTile = getNextNormTile(layerIdx, 0, rect);
   while(currentTile.valid())
   {
      normTileList.push_back(ossimClosestToCenterCombinerInfo((ossimImageData*)currentTile->dup(),
                                                              layerIdx));
      currentTile = getNextNormTile(layerIdx, rect, resLevel);
   }

   
   if(normTileList.size() == 1)
   {
      theTile->copyNormalizedBufferToTile((ossim_float32*)normTileList[0].theTile->getBuf());
   }
   else if(normTileList.size() > 1)
   {
      ossimRefPtr<ossimImageData> copyTile    = ossimImageDataFactory::instance()->create(0,
                                                                                          OSSIM_NORMALIZED_FLOAT);
      copyTile->setImageRectangleAndBands(rect,
                                          getNumberOfOutputBands());
      copyTile->initialize();
                                                                                          
      ossim_int32 idx   = 0;
      ossim_uint32 w     = rect.width();
      ossim_uint32 h     = rect.height();
      ossim_uint32 idxW  = 0;
      ossim_uint32 idxH  = 0;
      ossimIpt origin    = rect.ul();
      ossimIpt ulPt      = rect.ul();
      ossim_uint32 band  = 0;
      ossim_uint32 bands = copyTile->getNumberOfBands();
      ossim_uint32 srcBandIdx = 0;
      std::vector<ossim_float32*> bandList(bands);

      for(band = 0; band < bands; ++band)
      {
         bandList[band] = (ossim_float32*)copyTile->getBuf(band);
      }
      ossim_uint32 offset   = 0;
      origin.y = ulPt.y;
      for(idxH = 0; idxH < h; ++idxH)
      {
         origin.x = ulPt.x;
         for(idxW = 0; idxW < w;++idxW)
         {
            idx = findIdx(normTileList, origin, offset);

            if(idx >=0)
            {
               ossim_uint32 tileBands = normTileList[idx].theTile->getNumberOfBands();
               if (tileBands > 0)
               {
                  tileBands -= 1;
                  for(band = 0; band < bands; ++band)
                  {
                     srcBandIdx = ossim::min( tileBands, band );
                     bandList[band][offset] = *(((ossim_float32*)normTileList[idx].theTile->getBuf(srcBandIdx))+offset);
                  }
               }
            }
            ++offset;
            ++origin.x;
         }
         ++origin.y;
      }
      theTile->copyNormalizedBufferToTile((ossim_float32*)copyTile->getBuf());
   }

   theTile->validate();
   
   return theTile;

}
template <class T> void ossimWatermarkFilter::fill(T /* dummy */)
{
   const ossimIrect TILE_RECT = theTile->getImageRectangle();

   // We will only fill data within the input bounding rect.
   const ossimIrect CLIPPED_TILE_RECT =
      TILE_RECT.clipToRect(theInputBoundingRect);

   // Get the bounding rectangles.
   vector<ossimIrect> rects(0);
   getIntersectingRects(rects);

   if (rects.size() == 0)
   {
      return;
   }

   //---
   // Have watermark rectangles that intersect this tile so we need to process.
   //---
   ossim_uint32 band = 0;
   ossim_float64 inputPixWeight = 1.0 - theWatermarkWeight;

   // Get a pointers to the watermark buffers (wmBuf) and nulls wn.
   T** wmBuf = new T*[theWatermarkNumberOfBands];
   for (band = 0; band < theWatermarkNumberOfBands; ++band)
   {
      wmBuf[band] = static_cast<T*>(theWatermark->getBuf(band));
   }
   
   // Get a pointers to the output tile buffers and nulls in.
   T** otBuf = new T*[theInputNumberOfBands];
   for (band = 0; band < theInputNumberOfBands; ++band)
   {
      otBuf[band] = static_cast<T*>(theTile->getBuf(band));
   }

   // Get the width of the buffers for indexing.
   ossim_int32 wmWidth = static_cast<ossim_int32>(theWatermark->getWidth());
   ossim_int32 otWidth = static_cast<ossim_int32>(theTile->getWidth());

   const ossim_float64* wmNull = theWatermark->getNullPix();
   const ossim_float64* otMin  = theTile->getMinPix();
   const ossim_float64* otMax  = theTile->getMaxPix();
   const ossim_float64* otNull = theTile->getNullPix();
   
      
   // Control loop through intersecting rectangles.
   vector<ossimIrect>::const_iterator i = rects.begin();
   while (i != rects.end())
   {
      if ( (*i).intersects(CLIPPED_TILE_RECT) )
      {
         //---
         // This is the rectangle we want to fill relative to requesting
         // image space.
         //---
         const ossimIrect CLIPPED_WATERMARRK_RECT =
            (*i).clipToRect(CLIPPED_TILE_RECT);

         ossim_int32 clipHeight = CLIPPED_WATERMARRK_RECT.height();
         ossim_int32 clipWidth  = CLIPPED_WATERMARRK_RECT.width();

         // Compute the starting offset into the wmBuf and otBuf.
         ossim_int32 wmOffset =
            (CLIPPED_WATERMARRK_RECT.ul().y - (*i).ul().y) * wmWidth +
            CLIPPED_WATERMARRK_RECT.ul().x  - (*i).ul().x;
         ossim_int32 otOffset =
            (CLIPPED_WATERMARRK_RECT.ul().y - TILE_RECT.ul().y)* otWidth +
             CLIPPED_WATERMARRK_RECT.ul().x - TILE_RECT.ul().x;
         
         // Line loop...
         for (ossim_int32 line = 0; line < clipHeight; ++line)
         {
            // Sample loop...
            for (ossim_int32 sample = 0; sample < clipWidth; ++sample)
            {
               // Output band control loop until all output bands are filled.
               ossim_uint32 otBand = 0;
               while (otBand < theInputNumberOfBands)
               {
                  // Band loop through the watermark.
                  for (ossim_uint32 wmBand = 0;
                       wmBand < theWatermarkNumberOfBands;
                       ++wmBand)
                  {
                     if (wmBuf[wmBand][wmOffset+sample] != wmNull[wmBand])
                     {
                        // Apply the weight to the input pixel.
                        ossim_float64 p1 =
                           (otBuf[otBand][otOffset+sample] != otNull[otBand]) ?
                           otBuf[otBand][otOffset+sample] * inputPixWeight :
                           0.0;

                        // Apply the Weight to the watermark pixel.
                        ossim_float64 p2 =
                           wmBuf[wmBand][wmOffset+sample]*theWatermarkWeight;

                        // Add them up.
                        ossim_float64 p3 = p1 + p2;

                        // Cast to output type with range checking.
                        otBuf[otBand][otOffset+sample] = static_cast<T>(
                           ( (p3 >= otMin[otBand]) ?
                             (p3 < otMax[otBand] ? p3 : otMax[otBand]) :
                             otNull[otBand]) );
                     }
                     ++otBand;
                     
                     // We stop when we reach here.  All output bands filled.
                     if (otBand == theInputNumberOfBands)
                     {
                        break;
                     }
                     
                  } // End of band through watermark.
                  
               } // End of outer band loop.
               
            } // End of sample loop.

            wmOffset += wmWidth;
            otOffset += otWidth;
            
         } // End of line loop.

      } // End "if ( (*i).intersects(TILE_RECT) )"
      
      ++i; // Go to next rectangle to fill if any.
      
   } // End of "while (i != rects.end())"

   // Clean up.
   delete [] wmBuf;
   delete [] otBuf;
   
   theTile->validate();
}
bool ossimPointCloudImageHandler::getTile(ossimImageData* result, ossim_uint32 resLevel)
{
   // check for all systems go and valid args:
   if (!m_pch.valid() || !result || (result->getScalarType() != OSSIM_FLOAT32)
       || (result->getDataObjectStatus() == OSSIM_NULL) || m_gsd.hasNans())
   {
      return false;
   }

   // Overviews achieved with GSD setting. This may be too slow.
   ossimDpt gsd (m_gsd);
   if (resLevel > 0)
      getGSD(gsd, resLevel);

   // Establish the ground and image rects for this tile:
   const ossimIrect img_tile_rect = result->getImageRectangle();
   const ossimIpt tile_offset (img_tile_rect.ul());
   const ossim_uint32 tile_width = img_tile_rect.width();
   const ossim_uint32 tile_height = img_tile_rect.height();
   const ossim_uint32 tile_size = img_tile_rect.area();

   ossimGpt gnd_ul, gnd_lr;
   ossimDpt dpt_ul (img_tile_rect.ul().x - 0.5, img_tile_rect.ul().y - 0.5);
   ossimDpt dpt_lr (img_tile_rect.lr().x + 0.5, img_tile_rect.lr().y + 0.5);
   theGeometry->rnToWorld(dpt_ul, resLevel, gnd_ul);
   theGeometry->rnToWorld(dpt_lr, resLevel, gnd_lr);
   const ossimGrect gnd_rect (gnd_ul, gnd_lr);

   // Create array of buckets to store accumulated point data.
   ossim_uint32 numBands = result->getNumberOfBands();
   if (numBands > getNumberOfInputBands())
   {
      // This should never happen;
      ossimNotify(ossimNotifyLevel_FATAL)
            << "ossimPointCloudImageHandler::getTile() ERROR: \n"
            << "More bands were requested than was available from the point cloud source. Returning "
            << "blank tile." << endl;
      result->makeBlank();
      return false;
   }
   std::map<ossim_int32, PcrBucket*> accumulator;

   // initialize a point block with desired fields as requested in the reader properties
   ossimPointBlock pointBlock (this);
   pointBlock.setFieldCode(componentToFieldCode());
   m_pch->rewind();

   ossimDpt ipt;
   ossimGpt pos;

#define USE_GETBLOCK
#ifdef USE_GETBLOCK
   m_pch->getBlock(gnd_rect, pointBlock);
   for (ossim_uint32 id=0; id<pointBlock.size(); ++id)
   {
      pos = pointBlock[id]->getPosition();
      theGeometry->worldToRn(pos, resLevel, ipt);
      ipt.x = ossim::round<double,double>(ipt.x) - tile_offset.x;
      ipt.y = ossim::round<double,double>(ipt.y) - tile_offset.y;

      ossim_int32 bucketIndex = ipt.y*tile_width + ipt.x;
      if ((bucketIndex >= 0) && (bucketIndex < (ossim_int32)tile_size))
         addSample(accumulator, bucketIndex, pointBlock[id]);
   }

#else // using getFileBlock
   ossim_uint32 numPoints = m_pch->getNumPoints();
   if (numPoints > ossimPointCloudHandler::DEFAULT_BLOCK_SIZE)
      numPoints = ossimPointCloudHandler::DEFAULT_BLOCK_SIZE;

   // Loop to read all point blocks:
   do
   {
      pointBlock.clear();
      m_pch->getNextFileBlock(pointBlock, numPoints);
      //m_pch->normalizeBlock(pointBlock);

      for (ossim_uint32 id=0; id<pointBlock.size(); ++id)
      {
         // Check that each point in read block is inside the ROI before accumulating it:
         pos = pointBlock[id]->getPosition();
         if (gnd_rect.pointWithin(pos))
         {
            theGeometry->worldToRn(pos, resLevel, ipt);
            ipt.x = ossim::round<double,double>(ipt.x) - tile_offset.x;
            ipt.y = ossim::round<double,double>(ipt.y) - tile_offset.y;

            ossim_int32 bucketIndex = ipt.y*tile_width + ipt.x;
            if ((bucketIndex >= 0) && (bucketIndex < (ossim_int32)tile_size))
               addSample(accumulator, bucketIndex, pointBlock[id]);
         }
      }
   } while (pointBlock.size() == numPoints);
#endif

   // Finished accumulating, need to normalize and fill the tile.
   // We must always blank out the tile as we may not have a point for every pixel.
   normalize(accumulator);
   ossim_float32** buf = new ossim_float32*[numBands];
   std::map<ossim_int32, PcrBucket*>::iterator accum_iter;
   ossim_float32 null_pixel = OSSIM_DEFAULT_NULL_PIX_FLOAT;
   result->setNullPix(null_pixel);
   for (ossim_uint32 band = 0; band < numBands; band++)
   {
      ossim_uint32 index = 0;
      buf[band] = result->getFloatBuf(band);
      for (ossim_uint32 y = 0; y < tile_height; y++)
      {
         for (ossim_uint32 x = 0; x < tile_width; x++)
         {
            accum_iter = accumulator.find(index);
            if (accum_iter != accumulator.end())
               buf[band][index] = accum_iter->second->m_bucket[band];
            else
               buf[band][index] = null_pixel;
            ++index;
         }
      }
   }

   delete [] buf;
   buf = 0;

   std::map<ossim_int32, PcrBucket*>::iterator pcr_iter = accumulator.begin();
   while (pcr_iter != accumulator.end())
   {
      delete pcr_iter->second;
      pcr_iter++;
   }

   result->validate();
   return true;
}
Beispiel #21
0
//*******************************************************************
// Private Method:
//*******************************************************************
bool ossimAdrgTileSource::fillBuffer(const ossimIrect& /* tile_rect */,
                                     const ossimIrect& clip_rect,
                                     ossimImageData* tile)
{
   //***
   // Shift the upper left corner of the "clip_rect" to the an even chunk
   // boundry.
   //***
   ossimIpt tileOrigin = clip_rect.ul();
   adjustToStartOfTile(tileOrigin);

   //***
   // Calculate the number of tiles needed in the line/sample directions.
   //***
   ossim_int32 size_in_x = clip_rect.lr().x - tileOrigin.x + 1;
   ossim_int32 size_in_y = clip_rect.lr().y - tileOrigin.y + 1;
   
   ossim_int32 tiles_in_x_dir = size_in_x / ADRG_TILE_WIDTH  +
      (size_in_x % ADRG_TILE_WIDTH  ? 1 : 0);
   ossim_int32 tiles_in_y_dir = size_in_y / ADRG_TILE_HEIGHT +
      (size_in_y % ADRG_TILE_HEIGHT ? 1 : 0);


   ossimIpt ulTilePt = tileOrigin;
   
   // Chunk loop in line direction.
   for (ossim_int32 y=0; y<tiles_in_y_dir; y++)
   {
      ulTilePt.x = tileOrigin.x;

      // Tile loop in sample direction.
      for (ossim_int32 x=0; x<tiles_in_x_dir; x++)
      {
         ossimIrect adrg_tile_rect(ulTilePt.x,
                                   ulTilePt.y,
                                   ulTilePt.x + ADRG_TILE_WIDTH- 1,
                                   ulTilePt.y + ADRG_TILE_HEIGHT - 1);

         if (adrg_tile_rect.intersects(clip_rect))
         {
            ossimIrect tile_clip_rect = clip_rect.clipToRect(adrg_tile_rect);
            
            //---
            // Some point in the chip intersect the tile so grab the
            // data.
            //---
            ossim_int32 row = (ossim_int32) ulTilePt.y / ADRG_TILE_HEIGHT; 
            ossim_int32 col = (ossim_int32) ulTilePt.x / ADRG_TILE_WIDTH;
            ossim_int32 tileOffset = m_AdrgHeader->tim(row, col);

            if(tileOffset != 0)
            {
               // Get the data.
               int seek_position = (tileOffset - 1) * 49152 + 2048;
               int band;

               // seek to start of chip
               m_FileStr.seekg(seek_position, ios::beg);
               for (band=0; band<3; band++)
               {
                  //***
                  // Read the chip from the ccf file into the chunk buffer.
                  // This will get all the bands.  Bands are interleaved by
                  // chip.
                  //***
                  if (!m_FileStr.read((char*)m_TileBuffer,
                                       ADRG_TILE_SIZE))
                  {
                     theErrorStatus = ossimErrorCodes::OSSIM_ERROR;
                     return false;
                  }

                  tile->loadBand(m_TileBuffer,
                                 adrg_tile_rect,
                                 tile_clip_rect,
                                 band);

               } // End of band loop.
               
            } // End of if (tileOffset != 0)
            
         } // End of if (adrg_tile_rect.intersects(clip_rect))
         
         ulTilePt.x += ADRG_TILE_WIDTH;
         
      }  // End of tile loop in the sample direction.

      ulTilePt.y += ADRG_TILE_HEIGHT;
      
   }  // End of tile loop in the line direction.

   return true;
}
Beispiel #22
0
bool ossimLasReader::getTile(ossimImageData* result, ossim_uint32 resLevel)
{
   // static const char MODULE[] = "ossimLibLasReader::getTile(ossimImageData*, level)";

   bool status = false;


   if ( m_hdr && result && (result->getScalarType() == OSSIM_FLOAT32) &&
        (result->getDataObjectStatus() != OSSIM_NULL) &&
        !m_ul.hasNans() && !m_scale.hasNans() )
   {
      status = true;
      
      const ossimIrect  TILE_RECT   = result->getImageRectangle();
      const ossim_int32 TILE_HEIGHT = static_cast<ossim_int32>(TILE_RECT.height());
      const ossim_int32 TILE_WIDTH  = static_cast<ossim_int32>(TILE_RECT.width());
      const ossim_int32 TILE_SIZE   = static_cast<ossim_int32>(TILE_RECT.area());

      const ossim_uint16 ENTRY = m_entry+1;

      // Get the scale for this resLevel:
      ossimDpt scale;
      getScale(scale, resLevel);
      
      // Set the starting upper left of upper left pixel for this tile.
      const ossimDpt UL_PROG_PT( m_ul.x - scale.x / 2.0 + TILE_RECT.ul().x * scale.x,
                                 m_ul.y + scale.y / 2.0 - TILE_RECT.ul().y * scale.y);

      //---
      // Set the lower right to the edge of the tile boundary.  This looks like an
      // "off by one" error but it's not.  We want the ossimDrect::pointWithin to
      // catch any points in the last line sample.
      //---
      const ossimDpt LR_PROG_PT( UL_PROG_PT.x + TILE_WIDTH  * scale.x,
                                 UL_PROG_PT.y - TILE_HEIGHT * scale.y);
      
      const ossimDrect PROJ_RECT(UL_PROG_PT, LR_PROG_PT, OSSIM_RIGHT_HANDED);

#if 0  /* Please leave for debug. (drb) */
      cout << "m_ul: " << m_ul
           << "\nm_scale: " << m_scale
           << "\nscale:   " << scale
           << "\nresult->getScalarType(): " << result->getScalarType()
           << "\nresult->getDataObjectStatus(): " << result->getDataObjectStatus()
           << "\nPROJ_RECT: " << PROJ_RECT
           << "\nTILE_RECT: " << TILE_RECT
           << "\nUL_PROG_PT: " << UL_PROG_PT << endl;
#endif

      const ossim_float64 SCALE_X  = m_hdr->getScaleFactorX();
      const ossim_float64 SCALE_Y  = m_hdr->getScaleFactorY();
      const ossim_float64 SCALE_Z  = m_hdr->getScaleFactorZ();
      const ossim_float64 OFFSET_X = m_hdr->getOffsetX();
      const ossim_float64 OFFSET_Y = m_hdr->getOffsetY();
      const ossim_float64 OFFSET_Z = m_hdr->getOffsetZ();

      // Create array of buckets.
      std::vector<ossimLasReader::Bucket> bucket( TILE_SIZE );

      // Loop through the point data.
      ossimLasPointRecordInterface* lasPtRec = getNewPointRecord();
      ossimDpt lasPt;

      m_str.clear();
      m_str.seekg(m_hdr->getOffsetToPointData());

      while ( m_str.good() )
      {
         // m_str.read((char*)lasPtRec, 28);
         lasPtRec->readStream( m_str );

         if ( lasPtRec->getReturnNumber() == ENTRY )
         {
            lasPt.x = lasPtRec->getX() * SCALE_X + OFFSET_X;
            lasPt.y = lasPtRec->getY() * SCALE_Y + OFFSET_Y;
            if ( m_unitConverter )
            {
               convertToMeters(lasPt.x);
               convertToMeters(lasPt.y);
            }
            if ( PROJ_RECT.pointWithin( lasPt ) )
            {
               // Compute the bucket index:
               ossim_int32 line = static_cast<ossim_int32>((UL_PROG_PT.y - lasPt.y) / scale.y);
               ossim_int32 samp = static_cast<ossim_int32>((lasPt.x - UL_PROG_PT.x) / scale.x );
               ossim_int32 bucketIndex = line * TILE_WIDTH + samp;
               
               // Range check and add if in there.
               if ( ( bucketIndex >= 0 ) && ( bucketIndex < TILE_SIZE ) )
               {
                  ossim_float64 z = lasPtRec->getZ() * SCALE_Z + OFFSET_Z;
                  if (  m_unitConverter ) convertToMeters(z);
                  bucket[bucketIndex].add( z ); 
               }
            }
         }
         if ( m_str.eof() ) break;
      }
      delete lasPtRec;
      lasPtRec = 0;

      //---
      // We must always blank out the tile as we may not have a point for every
      // point.
      //---
      result->makeBlank();

      ossim_float32* buf = result->getFloatBuf(); // Tile buffer to fill.
      
      // Fill the tile.  Currently no band loop:
      for (ossim_int32 i = 0; i < TILE_SIZE; ++i)
      {
         buf[i] = bucket[i].getValue();
      }

      // Revalidate.
      result->validate();
   }

   return status;
   
} // End: bool ossimLibLasReader::getTile(ossimImageData* result, ossim_uint32 resLevel)
ossimRefPtr<ossimImageData> ossimAtCorrRemapper::getTile(
   const ossimIrect& tile_rect,
   ossim_uint32 resLevel)
{
#if 0
   if (traceDebug())
   {
      cout << "ossimAtCorrRemapper::getTile DEBUG:"
           << "\ntile_rect:  " << tile_rect << endl;
   }
#endif
   
   if (!isInitialized()||!theInputConnection)
   {
       cerr << "ossimAtCorrRemapper::getTile ERROR:"
            << "\nNot initialized!"
            << endl;
       return ossimRefPtr<ossimImageData>();
   }

   if(!theTile.valid())
   {
      initialize();
      if(!theTile)
      {
         return ossimRefPtr<ossimImageData>();
      }
   }
   
   // Fetch tile from pointer from the input source.
   ossimRefPtr<ossimImageData> inputTile = theInputConnection->getTile(tile_rect,
                                                                       resLevel);

   if (!inputTile.valid())  // Just in case...
   {
      return ossimRefPtr<ossimImageData>();
   }

   // Check for remap bypass or empty / null input tile.
   ossimDataObjectStatus tile_status = inputTile->getDataObjectStatus();
   if (!theEnableFlag || tile_status == OSSIM_NULL ||
       tile_status == OSSIM_EMPTY)
   {
      return inputTile;
   }

   ossim_uint32 w     = tile_rect.width();
   ossim_uint32 h     = tile_rect.height();
   ossim_uint32 tw    = theTile->getWidth();
   ossim_uint32 th    = theTile->getHeight();
   ossim_uint32 bands = theTile->getNumberOfBands();

   // Set the origin of the output tile.
   theTile->setOrigin(tile_rect.ul());

   if(w*h != tw*th)
   {
      theTile->setWidthHeight(w, h);
      theTile->initialize();
      if(theSurfaceReflectance)
      {
         delete [] theSurfaceReflectance;
         theSurfaceReflectance = NULL;
      }
   }
   
   if(!theSurfaceReflectance)
   {
      ossim_uint32 size  = tw*th*bands;
#if 0
      if (traceDebug())
      {
         cout << "ossimAtCorrRemapper::getTile DEBUG:"
              << "\ntile_rect:    " << tile_rect
              << "\ntile width:   " << tw
              << "\ntile height:  " << th
              << "\nbands:        " << bands
              << "\nBuffer size:  " << size << endl;
      }
#endif
      
      theSurfaceReflectance = new double[size];
   }

   ossim_uint32 buffer_index = 0;
   ossimIpt ul = tile_rect.ul();
   ossimIpt lr = tile_rect.lr();
   const double MP = theTile->getMinNormalizedPix(); // Minimum normalized pix.
   double a, b, c;
   buffer_index = 0;

   cout << setprecision(6);
   for (ossim_uint32 band=0; band < bands; ++band)
   {
      for(ossim_sint32 idxy = ul.y; idxy <= lr.y; ++idxy)
      {
         for(ossim_sint32 idxx = ul.x; idxx <= lr.x; ++idxx)
         {
            double p = inputTile->getPix(buffer_index);
            
            if (p>0.0)
            {
               if(!theUseInterpolationFlag)
               {
                  a = theXaArray[band];
                  b = theXbArray[band];
                  c = theXcArray[band];
               }
               else
               {
                  interpolate(ossimDpt(idxx, idxy),
                              band,
                              a,
                              b,
                              c);
               }
               if(theSensorType == "ls7ms")
               {
                  double radiance_at_satellite
                     = (theGainArray[band] * p) + theBiasArray[band];
                  
                  double y =  (radiance_at_satellite * a) -  b;
                  
                  p = (y / (1.0 + (c * y)) );
               }
               else if(theSensorType == "qbms")
               {
                  double radiance_at_satellite
                     = theCalCoefArray[band] * p / theBandWidthArray[band];
                  
                  double y =  (radiance_at_satellite * a) - b;
                  
                  p = (y / (1.0 + (c * y)) );
               }
               else if(theSensorType == "ikms")
               {
                  
                 
                  double radiance_at_satellite
                     =   p  /((theCalCoefArray[band]/1.0)/ theBandWidthArray[band]);
                  double y =  (radiance_at_satellite * a) -  b;
    
                  p = (y / (1.0 + (c * y)) );
     
               }  
                   
               // Note that "p" should now be normalized between 0.0 and 1.0;
               
               // ***
               // Since it wasn't null to start with clip / clamp between minimum
               // normalized pixel and one(max).
               // ***
               p =  ( p > MP ? ( p < 1.0 ? p : 1.0) : MP );
               
               // Scan the new tile and set the min / max.
               if (p < theMinPixelValue[band])
               {
                  theMinPixelValue[band] = p;
               }
               else if (p > theMaxPixelValue[band])
               {
                  theMaxPixelValue[band] = p;
               }
               
               theSurfaceReflectance[buffer_index] = p;
            }
            else
            {
               theSurfaceReflectance[buffer_index] = 0.0;  // pixel was null...
            }
            
            ++buffer_index;
            
         }  // End of sample loop...
         
      } // End of line loop...
      
   } // End of band loop...

   // Copy the buffer to the output tile at the same time unnormalizing it.
   theTile->copyNormalizedBufferToTile(theSurfaceReflectance);
   
   // Validate the output to set the tile status.
   theTile->validate();
   
   return theTile;
}
Beispiel #24
0
ossimRefPtr<ossimImageData> ossimMaskFilter::getTile(const ossimIrect& rect,
                                                     ossim_uint32 resLevel)
{
   ossimImageSource* imageSource = PTR_CAST(ossimImageSource,
                                                     getInput(0));
   
   // we will check to see if it's a fileMaskSource
   //
   ossimImageSource* maskSource = PTR_CAST(ossimImageSource,
                                                    getInput(1));
   
   ossimRefPtr<ossimImageData> imageSourceData;
   ossimRefPtr<ossimImageData> maskSourceData;
   
   if(imageSource)
   {
      imageSourceData = imageSource->getTile(rect, resLevel);
   }

   if(!isSourceEnabled())
   {
      return imageSourceData;
   }
   
   if(maskSource)
   {
      maskSourceData = maskSource->getTile(rect, resLevel);
   }

   if (!theTile.valid())
   {
      allocate();
   }

   if(!imageSourceData.valid() || !theTile.valid())
   {
      return ossimRefPtr<ossimImageData>();
   }
   
   theTile->setOrigin(rect.ul());
   if(theTile->getImageRectangle() != rect)
   {
      theTile->setImageRectangle(rect);
      theTile->initialize();
   }
   if(!imageSourceData.valid())
   {
      return theTile;
   }
   if(!maskSourceData.valid()) 
   {
      return imageSourceData;
   }
   
   if(imageSourceData->getDataObjectStatus() != OSSIM_NULL)
   {
      return executeMaskFilter(imageSourceData, maskSourceData);  
   }
   
   return theTile;
}
Beispiel #25
0
bool ossim_hdf5::crossesDateline( H5::DataSet& dataset, const ossimIrect& validRect )
{
   bool result = false;

   H5::DataSpace dataspace = dataset.getSpace();
         
   // Number of dimensions of the input dataspace:
   const ossim_int32 DIM_COUNT = dataspace.getSimpleExtentNdims();
         
   if ( DIM_COUNT == 2 )
   {
      const ossim_uint32 ROWS = validRect.height();
      const ossim_uint32 COLS = validRect.width();
      
      // Get the extents. Assuming dimensions are same for lat lon dataset. 
      std::vector<hsize_t> dimsOut(DIM_COUNT);
      dataspace.getSimpleExtentDims( &dimsOut.front(), 0 );

      if ( (ROWS <= dimsOut[0]) && (COLS <= dimsOut[1]) )
      {
         std::vector<hsize_t> inputCount(DIM_COUNT);
         std::vector<hsize_t> inputOffset(DIM_COUNT);
         
         inputCount[0] = 1;    // row
         inputCount[1] = COLS; // col
         
         // Output dataspace dimensions.
         const ossim_int32 OUT_DIM_COUNT = 3;
         std::vector<hsize_t> outputCount(OUT_DIM_COUNT);
         outputCount[0] = 1; // single band
         outputCount[1] = 1; // single line
         outputCount[2] = COLS; // single sample
               
         // Output dataspace offset.
         std::vector<hsize_t> outputOffset(OUT_DIM_COUNT);
         outputOffset[0] = 0;
         outputOffset[1] = 0;
         outputOffset[2] = 0;
               
         ossimScalarType scalar = ossim_hdf5::getScalarType( &dataset );
         if ( scalar == OSSIM_FLOAT32 )
         {
            // See if we need to swap bytes:
            ossimEndian* endian = 0;
            if ( ( ossim::byteOrder() != ossim_hdf5::getByteOrder( &dataset ) ) )
            {
               endian = new ossimEndian();
            }

            // Native type:
            H5::DataType datatype = dataset.getDataType();
                  
            // Output dataspace always the same one line.
            H5::DataSpace bufferDataSpace( OUT_DIM_COUNT, &outputCount.front());
            bufferDataSpace.selectHyperslab( H5S_SELECT_SET,
                                             &outputCount.front(),
                                             &outputOffset.front() );

            //---
            // Dataset sample has NULL lines at the end so scan for valid rect.
            // Use "<= -999" for test as per NOAA as it seems the NULL value is
            // fuzzy.  e.g. -999.3.
            //---

            // Buffer to hold a line:
            std::vector<ossim_float32> lineBuffer(validRect.width());

            // Read the first line:
            inputOffset[0] = static_cast<hsize_t>(validRect.ul().y);
            inputOffset[1] = static_cast<hsize_t>(validRect.ul().x);
            dataspace.selectHyperslab( H5S_SELECT_SET,
                                       &inputCount.front(),
                                       &inputOffset.front() );
            dataset.read( &(lineBuffer.front()), datatype, bufferDataSpace, dataspace );

            if ( endian )
            {
               // If the endian pointer is initialized(not zero) swap the bytes.
               endian->swap( &(lineBuffer.front()), COLS );
            }

            // Test the first line:
            result = ossim_hdf5::crossesDateline( lineBuffer );

            if ( !result )
            {
               // Test the last line:
               inputOffset[0] = static_cast<hsize_t>(validRect.ll().y);
               inputOffset[1] = static_cast<hsize_t>(validRect.ll().x);
               dataspace.selectHyperslab( H5S_SELECT_SET,
                                          &inputCount.front(),
                                          &inputOffset.front() );
               dataset.read( &(lineBuffer.front()), datatype, bufferDataSpace, dataspace );

               result = ossim_hdf5::crossesDateline( lineBuffer );
            }

            if ( endian )
            {
               delete endian;
               endian = 0;
            }
         }
         else // Matches: if ( scalar == OSSIM_FLOAT32 ){...}
         {
            ossimNotify(ossimNotifyLevel_WARN)
               << "ossim_hdf5::crossesDateline WARNING!"
               << "\nUnhandled scalar type: "
               << ossimScalarTypeLut::instance()->getEntryString( scalar )
               << std::endl;
         }
         
      } // Matches: if ( dimsOut...
      
   } // Matches: if ( IN_DIM_COUNT == 2 )
   
   dataspace.close();
   
   return result;
   
} // End: ossim_hdf5::crossesDateline(...)
Beispiel #26
0
ossimRefPtr<ossimProjection> ossim_hdf5::getBilinearProjection(
   H5::DataSet& latDataSet, H5::DataSet& lonDataSet, const ossimIrect& validRect )
{
   ossimRefPtr<ossimProjection> proj = 0;

   // Get dataspace of the dataset.
   H5::DataSpace latDataSpace = latDataSet.getSpace();
   H5::DataSpace lonDataSpace = lonDataSet.getSpace();
         
   // Number of dimensions of the input dataspace:
   const ossim_int32 DIM_COUNT = latDataSpace.getSimpleExtentNdims();
         
   if ( DIM_COUNT == 2 )
   {
      // Get the extents. Assuming dimensions are same for lat lon dataset. 
      std::vector<hsize_t> dimsOut(DIM_COUNT);
      latDataSpace.getSimpleExtentDims( &dimsOut.front(), 0 );

      if ( dimsOut[0] && dimsOut[1] )
      {
         std::vector<hsize_t> inputCount(DIM_COUNT);
         std::vector<hsize_t> inputOffset(DIM_COUNT);
               
         inputOffset[0] = 0;
         inputOffset[1] = 0;
               
         inputCount[0] = 1;
         inputCount[1] = 1;
               
         // Output dataspace dimensions.
         const ossim_int32 OUT_DIM_COUNT = 3;
         std::vector<hsize_t> outputCount(OUT_DIM_COUNT);
         outputCount[0] = 1; // single band
         outputCount[1] = 1; // single line
         outputCount[2] = 1; // single sample
               
         // Output dataspace offset.
         std::vector<hsize_t> outputOffset(OUT_DIM_COUNT);
         outputOffset[0] = 0;
         outputOffset[1] = 0;
         outputOffset[2] = 0;
               
         ossimScalarType scalar = ossim_hdf5::getScalarType( &latDataSet );
         if ( scalar == OSSIM_FLOAT32 )
         {
            // See if we need to swap bytes:
            ossimEndian* endian = 0;
            if ( ( ossim::byteOrder() != ossim_hdf5::getByteOrder( &latDataSet ) ) )
            {
               endian = new ossimEndian();
            }

            // Native type:
            H5::DataType latDataType = latDataSet.getDataType();
            H5::DataType lonDataType = lonDataSet.getDataType();
                  
            std::vector<ossimDpt> ipts;
            std::vector<ossimGpt> gpts;
            ossimGpt gpt(0.0, 0.0, 0.0); // Assuming WGS84...
            ossim_float32 latValue = 0.0;
            ossim_float32 lonValue = 0.0;
                  
            // Only grab every 256th value.:
            const ossim_int32 GRID_SIZE = 256;
                  
            // Output dataspace always the same one pixel.
            H5::DataSpace bufferDataSpace( OUT_DIM_COUNT, &outputCount.front());
            bufferDataSpace.selectHyperslab( H5S_SELECT_SET,
                                             &outputCount.front(),
                                             &outputOffset.front() );

            //---
            // Dataset sample has NULL lines at the end so scan for valid rect.
            // Use "<= -999" for test as per NOAA as it seems the NULL value is
            // fuzzy.  e.g. -999.3.
            //---
            const ossim_float32 NULL_VALUE = -999.0;

            //---
            // Get the tie points within the valid rect:
            //---
            ossimDpt ipt = validRect.ul();
            while ( ipt.y <= validRect.lr().y )
            {
               inputOffset[0] = static_cast<hsize_t>(ipt.y);
               
               // Sample loop:
               ipt.x = validRect.ul().x;
               while ( ipt.x <= validRect.lr().x )
               {
                  inputOffset[1] = static_cast<hsize_t>(ipt.x);
                  
                  latDataSpace.selectHyperslab( H5S_SELECT_SET,
                                                &inputCount.front(),
                                                &inputOffset.front() );
                  lonDataSpace.selectHyperslab( H5S_SELECT_SET,
                                                &inputCount.front(),
                                                &inputOffset.front() );
                  
                  // Read data from file into the buffer.
                  latDataSet.read( &latValue, latDataType, bufferDataSpace, latDataSpace );
                  lonDataSet.read( &lonValue, lonDataType, bufferDataSpace, lonDataSpace );
                  
                  if ( endian )
                  {
                     // If the endian pointer is initialized(not zero) swap the bytes.
                     endian->swap( latValue );
                     endian->swap( lonValue );  
                  }
                  
                  if ( ( latValue > NULL_VALUE ) && ( lonValue > NULL_VALUE ) )
                  {
                     gpt.lat = latValue;
                     gpt.lon = lonValue;
                     gpts.push_back( gpt );
                     
                     // Add the image point subtracting the image offset.
                     ossimIpt shiftedIpt = ipt - validRect.ul();
                     ipts.push_back( shiftedIpt );
                  }

                  // Go to next point:
                  if ( ipt.x < validRect.lr().x )
                  {
                     ipt.x += GRID_SIZE;
                     if ( ipt.x > validRect.lr().x )
                     {
                        ipt.x = validRect.lr().x; // Clamp to last sample.
                     }
                  }
                  else
                  {  
                     break; // At the end:
                  }
                  
               } // End sample loop.

               if ( ipt.y < validRect.lr().y )
               {
                  ipt.y += GRID_SIZE;
                  if ( ipt.y > validRect.lr().y )
                  {
                     ipt.y = validRect.lr().y; // Clamp to last line.
                  }
               }
               else
               {  
                  break; // At the end:
               }
               
            } // End line loop.
                  
            if ( ipts.size() )
            {
               // Create the projection:
               ossimRefPtr<ossimBilinearProjection> bp = new ossimBilinearProjection();
                     
               // Add the tie points:
               bp->setTiePoints( ipts, gpts );
                     
               // Assign to output projection:
               proj = bp.get();
            }

            // Cleanup:
            if ( endian )
            {
               delete endian;
               endian = 0;
            }
         }
         else // Matches: if ( scalar == OSSIM_FLOAT32 ){...}
         {
            ossimNotify(ossimNotifyLevel_WARN)
               << "ossim_hdf5::getBilinearProjection WARNING!"
               << "\nUnhandled scalar type: "
               << ossimScalarTypeLut::instance()->getEntryString( scalar )
               << std::endl;
         }
               
      } // Matches: if ( dimsOut...
            
   } // Matches: if ( IN_DIM_COUNT == 2 )
         
   latDataSpace.close();
   lonDataSpace.close();
   
   return proj;
   
} // End: ossim_hdf5::getBilinearProjection()
bool ossimH5GridModel::setGridNodes( H5::DataSet* latDataSet,
                                     H5::DataSet* lonDataSet,
                                     const ossimIrect& validRect )
{
   bool status = false;

   if ( latDataSet && lonDataSet )
   {
      m_crossesDateline = ossim_hdf5::crossesDateline( *lonDataSet, validRect );
      
      if ( m_crossesDateline )
      {
         theLonGrid.setDomainType(ossimDblGrid::WRAP_360);
      }
      else
      {
         theLonGrid.setDomainType(ossimDblGrid::WRAP_180);
      }

      // Get dataspace of the dataset.
      H5::DataSpace latDataSpace = latDataSet->getSpace();
      H5::DataSpace lonDataSpace = lonDataSet->getSpace();
      const ossim_int32 LAT_DIM_COUNT = latDataSpace.getSimpleExtentNdims();
      const ossim_int32 LON_DIM_COUNT = lonDataSpace.getSimpleExtentNdims();
      
      // Number of dimensions of the input dataspace:
      if ( ( LAT_DIM_COUNT == 2 ) && ( LON_DIM_COUNT == 2 ) )
      {
         const ossim_uint32 ROWS = validRect.height();
         const ossim_uint32 COLS = validRect.width();
         const ossim_uint32 GRID_SIZE = 4; // Only grab every 4th value.

         //---
         // Get the extents:
         // dimsOut[0] is height, dimsOut[1] is width:
         //---
         std::vector<hsize_t> latDimsOut(LAT_DIM_COUNT);
         latDataSpace.getSimpleExtentDims( &latDimsOut.front(), 0 );
         std::vector<hsize_t> lonDimsOut(LON_DIM_COUNT);
         lonDataSpace.getSimpleExtentDims( &lonDimsOut.front(), 0 );
         
         // Verify valid rect within our bounds:
         if ( (ROWS <= latDimsOut[0] ) && (ROWS <= lonDimsOut[0] ) &&
              (COLS <= latDimsOut[1] ) && (COLS <= lonDimsOut[1] ) )
         {
            //----
            // Initialize the ossimDblGrids:
            //---
            ossimDpt dspacing (GRID_SIZE, GRID_SIZE);
            
            ossim_uint32 gridRows = ROWS / GRID_SIZE + 1;
            ossim_uint32 gridCols = COLS / GRID_SIZE + 1;
            
            // Round up if size doesn't fall on end pixel.
            if ( ROWS % GRID_SIZE) ++gridRows;
            if ( COLS % GRID_SIZE) ++gridCols;

            ossimIpt gridSize (gridCols, gridRows);
            
            // The grid as used in base class, has UV-space always at 0,0 origin            
            ossimDpt gridOrigin(0.0,0.0);

            const ossim_float64 NULL_VALUE = -999.0;
            
            theLatGrid.setNullValue(ossim::nan());
            theLonGrid.setNullValue(ossim::nan());
            theLatGrid.initialize(gridSize, gridOrigin, dspacing);
            theLonGrid.initialize(gridSize, gridOrigin, dspacing);            
            
            std::vector<hsize_t> inputCount(LAT_DIM_COUNT);
            std::vector<hsize_t> inputOffset(LAT_DIM_COUNT);
            
            inputOffset[0] = 0; // row is set below.
            inputOffset[1] = validRect.ul().x; // col
            
            inputCount[0] = 1; // row
            inputCount[1] = (hsize_t)COLS; // col
            
            // Output dataspace dimensions. Reading a line at a time.
            const ossim_int32 OUT_DIM_COUNT = 3;
            std::vector<hsize_t> outputCount(OUT_DIM_COUNT);
            outputCount[0] = 1;    // band
            outputCount[1] = 1;    // row
            outputCount[2] = COLS; // col
            
            // Output dataspace offset.
            std::vector<hsize_t> outputOffset(OUT_DIM_COUNT);
            outputOffset[0] = 0;
            outputOffset[1] = 0;
            outputOffset[2] = 0;
            
            ossimScalarType scalar = ossim_hdf5::getScalarType( latDataSet );
            if ( scalar == OSSIM_FLOAT32 )
            {
               // Set the return status to true if we get here...
               status = true;
               
               // See if we need to swap bytes:
               ossimEndian* endian = 0;
               if ( ( ossim::byteOrder() != ossim_hdf5::getByteOrder( latDataSet ) ) )
               {
                  endian = new ossimEndian();
               }
               
               // Native type:
               H5::DataType latDataType = latDataSet->getDataType();
               H5::DataType lonDataType = lonDataSet->getDataType();

               // Output dataspace always the same, width of one line.
               H5::DataSpace bufferDataSpace( OUT_DIM_COUNT, &outputCount.front());
               bufferDataSpace.selectHyperslab( H5S_SELECT_SET,
                                                &outputCount.front(),
                                                &outputOffset.front() );

               //  Arrays to hold a single line of latitude longitude values.
               vector<ossim_float32> latValue(COLS);
               vector<ossim_float32> lonValue(COLS);
               hsize_t row = 0;

               // Line loop:
               for ( ossim_uint32 y = 0; y < gridRows; ++y )
               {
                  // row = line in image space
                  row = y*GRID_SIZE;

                  if ( row < ROWS )
                  {
                     inputOffset[0] = row + validRect.ul().y;

                     latDataSpace.selectHyperslab( H5S_SELECT_SET,
                                                   &inputCount.front(),
                                                   &inputOffset.front() );
                     lonDataSpace.selectHyperslab( H5S_SELECT_SET,
                                                   &inputCount.front(),
                                                   &inputOffset.front() );
                  
                     // Read data from file into the buffer.
                     latDataSet->read( &(latValue.front()), latDataType,
                                       bufferDataSpace, latDataSpace );
                     lonDataSet->read( &(lonValue.front()), lonDataType,
                                       bufferDataSpace, lonDataSpace );
                  
                     if ( endian )
                     {
                        // If the endian pointer is initialized(not zero) swap the bytes.
                        endian->swap( &(latValue.front()), COLS );
                        endian->swap( &(lonValue.front()), COLS );  
                     }
                  
                     // Sample loop:
                     hsize_t col = 0;
                     
                     for ( ossim_uint32 x = 0; x < gridCols; ++x )
                     {
                        ossim_float32 lat = ossim::nan();
                        ossim_float32 lon = ossim::nan();
                        
                        // col = sample in image space
                        col = x*GRID_SIZE;

                        if ( col < COLS )
                        {
                           if ( (latValue[col] > NULL_VALUE)&&(lonValue[col] > NULL_VALUE) )
                           {
                              lat = latValue[col];
                              lon = lonValue[col];
                              if ( m_crossesDateline )
                              {
                                 if ( lon < 0.0 ) lon += 360;
                              }
                           }
                           else // Nulls in grid!
                           {
                              std::string errMsg =
                                 "ossimH5GridModel::setGridNodes encountered nans!";
                              throw ossimException(errMsg); 
                           }
                        }
                        else // Last column is outside of image bounds.
                        {
                           // Get the last two latitude values:
                           ossim_float32 lat1 = theLatGrid.getNode( x-2, y );
                           ossim_float32 lat2 = theLatGrid.getNode( x-1, y );

                           // Get the last two longitude values
                           ossim_float32 lon1 = theLonGrid.getNode( x-2, y );
                           ossim_float32 lon2 = theLonGrid.getNode( x-1, y );
                           
                           if ( ( lat1 > NULL_VALUE ) && ( lat2 > NULL_VALUE ) )
                           {
                              // Delta between last two latitude grid values.
                              ossim_float32 latSpacing = lat2 - lat1;
                           
                              // Compute:
                              lat = lat2 + latSpacing;
                           }
                           else // Nulls in grid!
                           {
                              std::string errMsg =
                                 "ossimH5GridModel::setGridNodes encountered nans!";
                              throw ossimException(errMsg);
                           }

                           if ( ( lon1 > NULL_VALUE ) && ( lon2 > NULL_VALUE ) )
                           {
                              // Delta between last two longitude values.
                              ossim_float32 lonSpacing = lon2 - lon1;
                           
                              // Compute:
                              lon = lon2 + lonSpacing;

                              // Check for wrap:
                              if ( !m_crossesDateline && ( lon > 180 ) )
                              {
                                 lon -= 360.0;
                              }
                           }
                           else // Nulls in grid!
                           {
                              std::string errMsg =
                                 "ossimH5GridModel::setGridNodes encountered nans!";
                              throw ossimException(errMsg);
                           }

#if 0 /* Please leave for debug. (drb) */                        
                           cout << "lat1: " << lat1 << " lat2 " << lat2
                                << " lon1 " << lon1  << " lon2 " << lon2
                                << "\n";
#endif
                        }
                        
                        // Assign the latitude and longitude.
                        theLatGrid.setNode( x, y, lat );
                        theLonGrid.setNode( x, y, lon );
                        
#if 0 /* Please leave for debug. (drb) */ 
                        cout << "x,y,col,row,lat,lon:" << x << "," << y << ","
                             << col << "," << row << ","
                             << theLatGrid.getNode(x, y)
                             << "," << theLonGrid.getNode( x, y) << "\n";
#endif
                        
                     } // End sample loop.
                     
                  }
                  else // Row is outside of image bounds:
                  {
                     // Sample loop:
                     for ( ossim_uint32 x = 0; x < gridCols; ++x )
                     {
                        ossim_float32 lat        = ossim::nan();
                        ossim_float32 lon        = ossim::nan();
                        
                        ossim_float32 lat1 = theLatGrid.getNode( x, y-2 );
                        ossim_float32 lat2 = theLatGrid.getNode( x, y-1 );
                        ossim_float32 lon1 = theLonGrid.getNode( x, y-2 );
                        ossim_float32 lon2 = theLonGrid.getNode( x, y-1 );
                        
                        if ( ( lon1 > NULL_VALUE ) && ( lon2 > NULL_VALUE ) )
                        {
                           // Delta between last two longitude values.
                           ossim_float32 lonSpacing = lon2 - lon1;
                           
                           // Compute:
                           lon = lon2 + lonSpacing;
                           
                           // Check for wrap:
                           if ( !m_crossesDateline && ( lon > 180 ) )
                           {
                              lon -= 360.0;
                           }
                        }
                        else // Nulls in grid!
                        {
                           std::string errMsg =
                              "ossimH5GridModel::setGridNodes encountered nans!";
                           throw ossimException(errMsg);
                        }
                        
                        if ( ( lat1 > NULL_VALUE ) && ( lat2 > NULL_VALUE ) )
                        {
                           // Delta between last two latitude values.
                           ossim_float32 latSpacing = lat2 - lat1;

                           lat = lat2 + latSpacing;
                        }
                        else // Nulls in grid!
                        {
                           std::string errMsg =
                              "ossimH5GridModel::setGridNodes encountered nans!";
                           throw ossimException(errMsg);
                        }
                        
#if 0 /* Please leave for debug. (drb) */
                        hsize_t col = x*GRID_SIZE; // Sample in image space
                        cout << "lat1: " << lat1 << " lat2 " << lat2
                             << " lon1 " << lon1  << " lon2 " << lon2
                             << "\nx,y,col,row,lat,lon:" << x << "," << y << ","
                             << col << "," << row << "," << lat << "," << lon << "\n";
#endif
                        // Assign the latitude::
                        theLatGrid.setNode( x, y, lat );

                        // Assign the longitude.
                        theLonGrid.setNode( x, y, lon );
                     
                     } // End sample loop.
                  
                  } // Matches if ( row < imageRows ){...}else{
                  
               } // End line loop.

               latDataSpace.close();
               lonDataSpace.close();

               if ( status )
               {
                  theSeedFunction = ossim_hdf5::getBilinearProjection(
                     *latDataSet,*lonDataSet, validRect );
                  
                  // Bileaner projection to handle
                  ossimDrect imageRect(validRect);
                  initializeModelParams(imageRect);

                  // debugDump();
               }

               if ( endian )
               {
                  delete endian;
                  endian = 0;
               }
               
            } // Matches: if ( scalar == OSSIM_FLOAT32 )
            
         } // Matches: if ( (latDimsOut[0] == imageRows) ...
         
      } // Matches: if ( ( LAT_DIM_COUNT == 2 ) ...

   } // Matches: if ( latDataSet && lonDataSet

   return status;
   
} // End: bool ossimH5GridModel::setGridNodes( H5::DataSet* latDataSet, ... )
ossimRefPtr<ossimImageData> ossimFeatherMosaic::getTile(const ossimIrect& tileRect,
                                            ossim_uint32 resLevel)
{
   long w = tileRect.width();
   long h = tileRect.height();
   ossimIpt origin = tileRect.ul();
   
   if(!isSourceEnabled())
   {
      return ossimImageMosaic::getTile(tileRect, resLevel);
   }
   if(!theTile||!theAlphaSum||!theResult||!theInputFeatherInformation)
   {
      initialize();

      if(!theTile||!theAlphaSum||!theResult||!theInputFeatherInformation)
      {
         return ossimImageMosaic::getTile(tileRect, resLevel);
      }
   }
   ossim_uint32 size = getNumberOfInputs();
   theAlphaSum->setImageRectangle(tileRect);
   theResult->setImageRectangle(tileRect);
   
   if(size == 0)
   {
      return ossimRefPtr<ossimImageData>();
   }

   if(size == 1)
   {
      return ossimImageMosaic::getTile(tileRect, resLevel);
   }

   long tileW = theTile->getWidth();
   long tileH = theTile->getHeight();
   if((w != tileW)||
      (h != tileH))
   {
      theTile->setWidth(w);
      theTile->setHeight(h);
      if((w*h)!=(tileW*tileH))
      {
         theTile->initialize();
      }
   }
   theTile->setOrigin(origin);
   theTile->makeBlank();
      
   switch(theTile->getScalarType())
   {
      case OSSIM_UCHAR:
      {
         return combine(static_cast<ossim_uint8>(0),
                        tileRect, resLevel);
      }
      case OSSIM_USHORT16:
      case OSSIM_USHORT11:
      {
         return combine(static_cast<ossim_uint16>(0),
                        tileRect, resLevel);
      }
      case OSSIM_SSHORT16:
      {
         return combine(static_cast<ossim_sint16>(0),
                        tileRect, resLevel);
      }
      case OSSIM_DOUBLE:
      case OSSIM_NORMALIZED_DOUBLE:
      {
         return combine(static_cast<double>(0),
                        tileRect, resLevel);
      }
      case OSSIM_FLOAT:
      case OSSIM_NORMALIZED_FLOAT:
      {
         return combine(static_cast<float>(0),
                        tileRect, resLevel);
      }
      case OSSIM_SCALAR_UNKNOWN:
      default:
      {
         ossimNotify(ossimNotifyLevel_WARN)
            << "ossimFeatherMosaic::getTile: error, unknown scalar type!!!"
            << std::endl;
      }
   }
   return ossimRefPtr<ossimImageData>();
}
ossimRefPtr<ossimImageData> ossimCFARFilter::getTile(const ossimIrect& tileRect,
                                                     ossim_uint32 resLevel)
{
   if(!theInputConnection)
   {
      return theTile;
   }

   if(!isSourceEnabled())
   {
      return theInputConnection->getTile(tileRect, resLevel);
   }

   //---
   // We have a 5x5 matrix so stretch the rect out to cover
   // the required pixels.  We only need 2 pixels to the left
   // and right of the center pixel.
   //---
   ossimIrect newRect(ossimIpt(tileRect.ul().x - 2,
                               tileRect.ul().y - 2),
                      ossimIpt(tileRect.lr().x + 2,
                               tileRect.lr().y + 2));
   
   ossimRefPtr<ossimImageData> data = theInputConnection->getTile(newRect,
                                                                  resLevel);

   if(!data.valid() || !data->getBuf())
   {
      return data;
   }

    // First time through or after an initialize()...
   if (!theTile.valid())
   {
      allocate();
      if (!theTile.valid()) // Should never happen!
      {
         return data;
      }
   }

   // First time through, after an initialize() or a setKernel()...
   if (!theNullPixValue.size())
   {
      computeNullMinMax();
      if (!theNullPixValue.size()) // Should never happen!
      {
         return data;
      }
   }

   theTile->setImageRectangle(tileRect);
   theTile->makeBlank();
   
   switch(data->getScalarType())
   {
      case OSSIM_UCHAR:
      {
         if(data->getDataObjectStatus() == OSSIM_FULL)
         {
            convolveFull(static_cast<ossim_uint8>(0), data, theTile);
         }
         else
         {
            convolvePartial(static_cast<ossim_uint8>(0), data, theTile);
         }
         break;
      }
      case OSSIM_FLOAT: 
      case OSSIM_NORMALIZED_FLOAT:
      {
         if(data->getDataObjectStatus() == OSSIM_FULL)
         {
            convolveFull(static_cast<float>(0), data, theTile);
         }
         else
         {
            convolvePartial(static_cast<float>(0), data, theTile);
         }
         break;
      }
      case OSSIM_USHORT16:
      case OSSIM_USHORT11:
      {
         if(data->getDataObjectStatus() == OSSIM_FULL)
         {
            convolveFull(static_cast<ossim_uint16>(0), data, theTile);
         }
         else
         {
            convolvePartial(static_cast<ossim_uint16>(0), data, theTile);
         }
         break;
      }
      case OSSIM_SSHORT16:
      {
         if(data->getDataObjectStatus() == OSSIM_FULL)
         {
            convolveFull(static_cast<ossim_sint16>(0), data, theTile);
         }
         else
         {
            convolvePartial(static_cast<ossim_sint16>(0), data, theTile);
         }
         break;
      }
      case OSSIM_DOUBLE:
      case OSSIM_NORMALIZED_DOUBLE:
      {
         if(data->getDataObjectStatus() == OSSIM_FULL)
         {
            convolveFull(static_cast<double>(0), data, theTile);
      }
      else
      {
         convolvePartial(static_cast<double>(0), data, theTile);
      }
         break;
      }
      default:
      {
         ossimNotify(ossimNotifyLevel_WARN)
            << "ossimCFARFilter::getTile WARNING:\n"
            << "Scalar type = " << theTile->getScalarType()
            << " Not supported by ossimCFARFilter" << endl;
         break;
      }
   }
   theTile->validate();
   
   return theTile;
}
Beispiel #30
0
bool ossim_hdf5::getValidBoundingRect( H5::DataSet& dataset,
                                       const std::string& name,
                                       ossimIrect& rect )
{
   bool result = false;
   H5::DataSpace imageDataspace = dataset.getSpace();
   const ossim_int32 IN_DIM_COUNT = imageDataspace.getSimpleExtentNdims();
         
   if ( IN_DIM_COUNT == 2 )
   {
      // Get the extents. Assuming dimensions are same for lat lon dataset. 
      std::vector<hsize_t> dimsOut(IN_DIM_COUNT);
      imageDataspace.getSimpleExtentDims( &dimsOut.front(), 0 );

      if ( dimsOut[0] && dimsOut[1] )
      {
         
         //---
         // Capture the rectangle:
         // dimsOut[0] is height, dimsOut[1] is width:
         //---
         rect = ossimIrect( 0, 0,
                            static_cast<ossim_int32>( dimsOut[1]-1 ),
                            static_cast<ossim_int32>( dimsOut[0]-1 ) );
         
         const ossim_int32 WIDTH  = rect.width();
               
         std::vector<hsize_t> inputCount(IN_DIM_COUNT);
         std::vector<hsize_t> inputOffset(IN_DIM_COUNT);
         
         inputOffset[0] = 0;
         inputOffset[1] = 0;
         
         inputCount[0] = 1;
         inputCount[1] = WIDTH;
         
         // Output dataspace dimensions.
         const ossim_int32 OUT_DIM_COUNT = 3;
         std::vector<hsize_t> outputCount(OUT_DIM_COUNT);
         outputCount[0] = 1;     // single band
         outputCount[1] = 1;     // single line
         outputCount[2] = WIDTH; // whole line
               
         // Output dataspace offset.
         std::vector<hsize_t> outputOffset(OUT_DIM_COUNT);
         outputOffset[0] = 0;
         outputOffset[1] = 0;
         outputOffset[2] = 0;
               
         ossimScalarType scalar = ossim_hdf5::getScalarType( &dataset );
         if ( scalar == OSSIM_FLOAT32 )
         {
            // See if we need to swap bytes:
            ossimEndian* endian = 0;
            if ( ( ossim::byteOrder() != ossim_hdf5::getByteOrder( &dataset ) ) )
            {
               endian = new ossimEndian();
            }

            // Native type:
            H5::DataType datatype = dataset.getDataType();
                  
            // Output dataspace always the same one line.
            H5::DataSpace bufferDataSpace( OUT_DIM_COUNT, &outputCount.front());
            bufferDataSpace.selectHyperslab( H5S_SELECT_SET,
                                             &outputCount.front(),
                                             &outputOffset.front() );

            //---
            // Dataset sample has NULL lines at the end so scan for valid rect.
            // Use "<= -999" for test as per NOAA as it seems the NULL value is
            // fuzzy.  e.g. -999.3.
            //---
            const ossim_float32 NULL_VALUE = -999.0;

            //---
            // VIIRS Radiance data has a -1.5e-9 in the first column.
            // Treat this as a null.
            //---
            const ossim_float32 NULL_VALUE2 = ( name == "/All_Data/VIIRS-DNB-SDR_All/Radiance" )
               ? -1.5e-9 : NULL_VALUE;
            const ossim_float32 TOLERANCE = 0.1e-9; // For ossim::almostEqual()

            // Hold one line:
            std::vector<ossim_float32> values( WIDTH );

            // Find the ul pixel:
            ossimIpt ulIpt = rect.ul();
            bool found = false;
                  
            // Line loop to find upper left pixel:
            while ( ulIpt.y <= rect.lr().y )
            {
               inputOffset[0] = static_cast<hsize_t>(ulIpt.y);
               imageDataspace.selectHyperslab( H5S_SELECT_SET,
                                               &inputCount.front(),
                                               &inputOffset.front() );
               
               // Read data from file into the buffer.
               dataset.read( (void*)&values.front(), datatype, bufferDataSpace, imageDataspace );
               
               if ( endian )
               {
                  // If the endian pointer is initialized(not zero) swap the bytes.
                  endian->swap( scalar, (void*)&values.front(), WIDTH );
               }
               
               // Sample loop:
               ulIpt.x = rect.ul().x;
               ossim_int32 index = 0;
               while ( ulIpt.x <= rect.lr().x )
               {
                  if ( !ossim::almostEqual(values[index], NULL_VALUE2, TOLERANCE) &&
                       ( values[index] > NULL_VALUE ) )
                  {
                     found = true; // Found valid pixel.
                     break;
                  }
                  ++ulIpt.x;
                  ++index;
                     
               } // End: sample loop
                     
               if ( found )
               {
                  break;
               }

               ++ulIpt.y;
                     
            } // End line loop to find ul pixel:

            // Find the lower right pixel:
            ossimIpt lrIpt = rect.lr();
            found = false;
                  
            // Line loop to find last pixel:
            while ( lrIpt.y >= rect.ul().y )
            {
               inputOffset[0] = static_cast<hsize_t>(lrIpt.y);
               imageDataspace.selectHyperslab( H5S_SELECT_SET,
                                               &inputCount.front(),
                                               &inputOffset.front() );
               
               // Read data from file into the buffer.
               dataset.read( (void*)&values.front(), datatype, bufferDataSpace, imageDataspace );

               if ( endian )
               {
                  // If the endian pointer is initialized(not zero) swap the bytes.
                  endian->swap( scalar, (void*)&values.front(), WIDTH );
               }
            
               // Sample loop:
               lrIpt.x = rect.lr().x;
               ossim_int32 index = WIDTH-1;
               
               while ( lrIpt.x >= rect.ul().x )
               {
                  if ( !ossim::almostEqual(values[index], NULL_VALUE2, TOLERANCE) &&
                       ( values[index] > NULL_VALUE ) )
                  {
                     found = true; // Found valid pixel.
                     break;
                  }
                  --lrIpt.x;
                  --index;
                     
               } // End: sample loop
                     
               if ( found )
               {
                  break;
               }

               --lrIpt.y;
                     
            } // End line loop to find lower right pixel.

            rect = ossimIrect( ulIpt, lrIpt );

            // Cleanup:
            if ( endian )
            {
               delete endian;
               endian = 0;
            }

            result = true;
            
         } 
         else // Matches: if ( scalar == OSSIM_FLOAT32 ){...}
         {
            ossimNotify(ossimNotifyLevel_WARN)
               << "ossim_hdf5::getBoundingRect WARNING!"
               << "\nUnhandled scalar type: "
               << ossimScalarTypeLut::instance()->getEntryString( scalar )
               << std::endl;
         }
               
      } // Matches: if ( dimsOut...
            
   } // Matches: if ( IN_DIM_COUNT == 2 )
         
   imageDataspace.close();

   return result;
   
} // End: ossim_hdf5::getBoundingRect(...)