Пример #1
0
void ossimDtedHandler::readPostsFromFile( DtedHeight &postData, int offset)
{

  OpenThreads::ScopedLock <OpenThreads::Mutex> lock( m_fileStrMutex );
  ossim_sint16 ss;
  ossim_uint16 us;
  int postCount = 0;
  // read the posts in blocks 2x2.
  for ( int column = 0; column < NUM_POSTS_PER_BLOCK ; ++column )
  {
    m_fileStr.seekg( offset, std::ios::beg );
    for ( int row = 0; row < NUM_POSTS_PER_BLOCK ; ++row )
    {
      if ( !m_fileStr.eof() )
      {
        us = 0;
        m_fileStr.read( ( char* ) &us, POST_SIZE );
        // check the read was ok
        if ( m_fileStr.good() )
        {
          postData.m_posts[postCount].m_status = true;
        }
        else
        {
          // reset the goodbit
          m_fileStr.clear();
        }
        ss = convertSignedMagnitude( us );
        postData.m_posts[postCount].m_height = ss;
      }
      postCount++;
    }
    offset += m_dtedRecordSizeInBytes;
  }
}
Пример #2
0
double ossimDtedHandler::getPostValue(const ossimIpt& gridPt) const
{
   static const char MODULE[] = "ossimDtedHandler::getPostValue";
   
   // Do some error checking.
   if ( gridPt.x < 0.0 || gridPt.y < 0.0 ||
        gridPt.x > (m_numLonLines  - 1) ||
        gridPt.y > (m_numLatPoints - 1) )
   {
      if(traceDebug())
      {
         ossimNotify(ossimNotifyLevel_WARN)
            << "WARNING " << MODULE << ": No intersection..." << std::endl;
      }
      return ossim::nan();
   }

   if (!isOpen())
   {
      return ossim::nan();
   }

   int offset =
      m_offsetToFirstDataRecord + gridPt.x * m_dtedRecordSizeInBytes +
      gridPt.y * 2 + DATA_RECORD_OFFSET_TO_POST;
   
   // Put the file pointer at the start of the first elevation post.
   m_fileStr.seekg(offset, std::ios::beg);

   ossim_uint16 us;

   // Get the post.
   m_fileStr.read((char*)&us, POST_SIZE);
   
   return double(convertSignedMagnitude(us));
}
Пример #3
0
void ossimDtedHandler::gatherStatistics()
{
   //***
   // Check to see if there is a statistics file already.  If so; do a lookup
   // for the min and max values.
   //***
   ossimFilename stats_file = theFilename;//theFilename.path();
   stats_file.setExtension("statistics");
   
   if (traceDebug())
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << "DEBUG ossimDtedHandler::gatherStatistics(): Looking for "
         << stats_file << " statistics file..." << std::endl;
   }

   ossimKeywordlist kwl;
   const char* min_str = NULL;
   const char* max_str = NULL;

   if (stats_file.exists())
   {
      if (kwl.addFile(stats_file))
      {
         // Look for the min_pixel_value keyword.
         min_str = kwl.find(ossimKeywordNames::MIN_VALUE_KW);
         max_str = kwl.find(ossimKeywordNames::MAX_VALUE_KW);
      }
   }

   if (min_str && max_str)
   {
      theMinHeightAboveMSL = atoi(min_str);
      theMaxHeightAboveMSL = atoi(max_str);
   }
   else if (theComputeStatsFlag&&!m_memoryMap.size())  // Scan the cell and gather the statistics...
   {
      if(traceDebug())
      {
         ossimNotify(ossimNotifyLevel_NOTICE)
            << "NOTICE ossimDtedHandler::gatherStatistics():"
            << " scanning for min/max"
            << "\nThis may take a while..." << std::endl;
      }
      // Start off with the min and max pegged.
      theMinHeightAboveMSL =  32767;
      theMaxHeightAboveMSL = -32767;
      
      // Put the file pointer at the start of the first elevation post.
      m_fileStr.seekg(m_offsetToFirstDataRecord, std::ios::beg);
      
      //---
      // Loop through all records and scan for lowest min and highest max.
      // Each record contains a row of latitude points for a given longitude.
      // There are eight bytes in front of the post and four checksum bytes at
      // the end so ignore them.
      //---
      for (ossim_int32 i=0; i<m_numLonLines; ++i)  // longitude direction
      {
         m_fileStr.seekg(DATA_RECORD_OFFSET_TO_POST, std::ios::cur);
         
         for (ossim_int32 j=0; j<m_numLatPoints; ++j) // latitude direction
         {
            ossim_uint16 us;
            ossim_sint16 ss;
            m_fileStr.read((char*)&us, POST_SIZE);
            ss = convertSignedMagnitude(us);
            if (ss < theMinHeightAboveMSL && ss != NULL_POST)
            {
               theMinHeightAboveMSL = ss;
            }
            if (ss > theMaxHeightAboveMSL)
            {
               theMaxHeightAboveMSL = ss;
            }
         }
         
         m_fileStr.seekg(DATA_RECORD_CHECKSUM_SIZE, std::ios::cur);
      }
      
      // Add the stats to the keyword list.
      kwl.add(ossimKeywordNames::MIN_VALUE_KW, theMinHeightAboveMSL);
      kwl.add(ossimKeywordNames::MAX_VALUE_KW, theMaxHeightAboveMSL);
      
      // Write out the statistics file.
      kwl.write(stats_file.c_str());
   }

   if (traceDebug())
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << "DEBUG ossimDtedHandler::gatherStatistics:"
         << "\ntheMinHeightAboveMSL:  " << theMinHeightAboveMSL
         << "\ntheMaxHeightAboveMSL:  " << theMaxHeightAboveMSL
         << std::endl;
   }
}
Пример #4
0
double ossimDtedHandler::getHeightAboveMSL(const ossimGpt& gpt, bool readFromFile)
{
   // Establish the grid indexes:
   double xi = (gpt.lon - m_swCornerPost.lon) / m_lonSpacing;
   double yi = (gpt.lat - m_swCornerPost.lat) / m_latSpacing;

   // Check for right edge.
   int x0 = static_cast<int>(xi);
   int y0 = static_cast<int>(yi);

   if(x0 == (m_numLonLines-1))
   {
      --x0; // Move over one post.
   }
   
   // Check for top edge.
   //    if (gpt.lat == theGroundRect.ul().lat)
   if(y0 == (m_numLatPoints-1))
   {
      --y0; // Move down one post.
   }

   // Do some error checking.
   if ( xi < 0.0 || yi < 0.0 ||
        x0 > (m_numLonLines  - 2.0) ||
        y0 > (m_numLatPoints - 2.0) )
   {
      return ossim::nan();
   }

   //***
   // Grab the four points from the dted cell needed.  These are big endian,
   // signed magnitude shorts so they must be interpreted accordingly.
   //***
   int offset = m_offsetToFirstDataRecord + x0 * m_dtedRecordSizeInBytes +
                y0 * 2 + DATA_RECORD_OFFSET_TO_POST;

   /// read the posts from the DTED file.
   DtedHeight postData;
   //
   if ( readFromFile )
   {
     readPostsFromFile( postData, offset );
   }
   else
   {
     ossim_uint8* buf = &m_memoryMap.front();
     {
       ossim_uint16 us;

       memcpy(&us, buf+offset, POST_SIZE);
       postData.m_posts[0].m_height = convertSignedMagnitude(us);
       memcpy(&us, buf+offset+POST_SIZE, POST_SIZE);
       postData.m_posts[1].m_height = convertSignedMagnitude(us);

       // Move over to the next column.
       offset += m_dtedRecordSizeInBytes;
       memcpy(&us, buf+offset, POST_SIZE);
       postData.m_posts[2].m_height = convertSignedMagnitude(us);
       memcpy(&us, buf+offset+POST_SIZE, POST_SIZE);
       postData.m_posts[3].m_height = convertSignedMagnitude(us);
     }
   }
   // Perform bilinear interpolation:
   double wx1 = xi  - x0;
   double wy1 = yi  - y0;
   double wx0 = 1.0 - wx1;
   double wy0 = 1.0 - wy1;
   
   postData.m_posts[0].m_weight = wx0*wy0;
   postData.m_posts[1].m_weight = wx0*wy1;
   postData.m_posts[2].m_weight = wx1*wy0;
   postData.m_posts[3].m_weight = wx1*wy1;

#if 0 /* Serious debug only... */
   postData.debug();
#endif

   return postData.calcHeight();
}
Пример #5
0
double ossimDtedHandler::getHeightAboveMSLMemory(const ossimGpt& gpt)
{
   ossim_uint8* buf = &m_memoryMap.front();
   // Establish the grid indexes:
   double xi = (gpt.lon - m_swCornerPost.lon) / m_lonSpacing;
   double yi = (gpt.lat - m_swCornerPost.lat) / m_latSpacing;

   // Check for right edge.
   int x0 = static_cast<int>(xi);
   int y0 = static_cast<int>(yi);

   // Check for right edge.
//    if (gpt.lon == theGroundRect.lr().lon)
   if(x0 == (m_numLonLines-1))
   {
      --x0; // Move over one post.
   }
   
   // Check for top edge.
//    if (gpt.lat == theGroundRect.ul().lat)
   if(y0 == (m_numLatPoints-1))
   {
      --y0; // Move down one post.
   }

   // Do some error checking.
   if ( xi < 0.0 || yi < 0.0 ||
        x0 > (m_numLonLines  - 2.0) ||
        y0 > (m_numLatPoints - 2.0) )
   {
      return ossim::nan();
   }

   double p00;
   double p01;
   double p10;
   double p11;

   //***
   // Grab the four points from the dted cell needed.  These are big endian,
   // signed magnitude shorts so they must be interpreted accordingly.
   //***
   ossim_uint64 offset = m_offsetToFirstDataRecord + x0 * m_dtedRecordSizeInBytes +
                         y0 * 2 + DATA_RECORD_OFFSET_TO_POST;
   {
      ossim_uint16 us;
      
      memcpy(&us, buf+offset, POST_SIZE); 
      p00 = convertSignedMagnitude(us);
      memcpy(&us, buf+offset+POST_SIZE, POST_SIZE); 
      p01 = convertSignedMagnitude(us);
      
      // Move over to the next column.
      offset += m_dtedRecordSizeInBytes;
      memcpy(&us, buf+offset, POST_SIZE); 
      p10 = convertSignedMagnitude(us);
      memcpy(&us, buf+offset+POST_SIZE, POST_SIZE); 
      p11 = convertSignedMagnitude(us);
   }
    
   // Perform bilinear interpolation:
   double wx1 = xi  - x0;
   double wy1 = yi  - y0;
   double wx0 = 1.0 - wx1;
   double wy0 = 1.0 - wy1;
   
   double w00 = wx0*wy0;
   double w01 = wx0*wy1;
   double w10 = wx1*wy0;
   double w11 = wx1*wy1;

   //***
   // Test for null posts and set the corresponding weights to 0:
   //***
   if (p00 == NULL_POST)
      w00 = 0.0;
   if (p01 == NULL_POST)
      w01 = 0.0;
   if (p10 == NULL_POST)
      w10 = 0.0;
   if (p11 == NULL_POST)
      w11 = 0.0;

#if 0 /* Serious debug only... */
   cout << "\np00:  " << p00
        << "\np01:  " << p01
        << "\np10:  " << p10
        << "\np11:  " << p11
        << "\nw00:  " << w00
        << "\nw01:  " << w01
        << "\nw10:  " << w10
        << "\nw11:  " << w11
        << std::endl;
#endif

   double sum_weights = w00 + w01 + w10 + w11;

   if (sum_weights)
   {
      return (p00*w00 + p01*w01 + p10*w10 + p11*w11) / sum_weights;
   }
   
   return ossim::nan();
}