Exemplo n.º 1
0
//------------------------------------------------------------------------------
// Locates an elevation value (meters) for a given reference point and returns
// it in 'elev'.  Function returns true if successful, otherwise 'elev' is unchanged.
//------------------------------------------------------------------------------
bool QuadMap::getElevation(
      LCreal* const elev,     // The elevation value (meters)
      const double lat,       // Reference latitude (degs)
      const double lon,       // Reference longitude (degs)
      const bool interp       // Interpolate between elevation posts (if true)
   ) const
{

   // Early out tests
   if ( !isDataLoaded() ||          // Not loaded or
        (lat < getLatitudeSW()  ||
         lat > getLatitudeNE()) ||  // wrong latitude or
        (lon < getLongitudeSW() ||
         lon > getLongitudeNE())    // wrong longitude
        ) return false;


   LCreal value = 0.0;              // the elevation (meters)
   bool found = false;
   for (unsigned int i = 0; i < numDataFiles && !found; i++) {
      found = dataFiles[i]->getElevation(&value, lat, lon, interp);
   }

   if (found) {
      *elev = value;
   }
   return found;
}
Exemplo n.º 2
0
//------------------------------------------------------------------------------
// Computes the nearest row index for the latitude (degs).
// Returns true if the index is valid
//------------------------------------------------------------------------------
bool DataFile::computerRowIndex(unsigned int* const irow, const double lat) const
{
   // Early out tests 
   if (  (lat < getLatitudeSW() ||
          lat > getLatitudeNE()) ||    // the latitude's out of range, or
         (irow == 0) ||                // the 'irow' pointer wasn't provided, or
         !isDataLoaded()               // the data isn't loaded
      ) return false;

   // Locate row (latitude) index
   double points = (lat - getLatitudeSW()) / latSpacing;
   if (points < 0) points = 0; 

   unsigned int idx = static_cast<unsigned int>(points + 0.5);
   if (idx >= nptlat) idx = (nptlat-1);

   *irow = idx;
   return true;
}
Exemplo n.º 3
0
//------------------------------------------------------------------------------
// Computes the latitude (degs) for a given row index.
// Returns true if the latitude is valid
//------------------------------------------------------------------------------
bool DataFile::computeLatitude(double* const lat, const unsigned int irow) const
{
   // Early out tests
   if ( (irow >= nptlat) ||   // the index isn't within range, or
         (lat == 0)      ||   // the latitude pointer wasn't provided, or
         !isDataLoaded()      // the data isn't loaded
      ) return false;

   *lat = getLatitudeSW() + static_cast<double>(irow) * latSpacing;
   return true;
}
Exemplo n.º 4
0
//------------------------------------------------------------------------------
// Locates an elevation value (meters) for a given reference point and returns
// it in 'elev'.  Function returns true if successful, otherwise 'elev' is unchanged.
//------------------------------------------------------------------------------
bool DataFile::getElevation(
      LCreal* const elev,     // The elevation value (meters)
      const double lat,       // Reference latitude (degs)
      const double lon,       // Reference longitude (degs)
      const bool interp       // Interpolate between elevation posts (if true)
   ) const
{
   LCreal value = 0;          // the elevation (meters)

   // Early out tests 
   if ( !isDataLoaded() ||          // Not loaded or
        (lat < getLatitudeSW()  ||
         lat > getLatitudeNE()) ||  // wrong latitude or
        (lon < getLongitudeSW() ||
         lon > getLongitudeNE())    // wrong longitude
        ) return false;


   // ---
   // Compute the lat and lon points
   // ---

   double pointsLat = (lat - getLatitudeSW()) / latSpacing;
   if (pointsLat < 0) pointsLat = 0; 

   double pointsLon = (lon - getLongitudeSW()) / lonSpacing;
   if (pointsLon < 0) pointsLon = 0;

   // ---
   // Interpolating between elevation posts?
   // ---
   if (interp) {
      // Yes ---

      // South-west corner post is [icol][irow]
      unsigned int irow = static_cast<unsigned int>(pointsLat);
      unsigned int icol = static_cast<unsigned int>(pointsLon);
      if (irow > (nptlat-2)) irow = (nptlat-2);
      if (icol > (nptlong-2)) icol = (nptlong-2);

      // delta from s-w corner post
      LCreal deltaLat = static_cast<LCreal>(pointsLat - static_cast<double>(irow));
      LCreal deltaLon = static_cast<LCreal>(pointsLon - static_cast<double>(icol));

      // Get the elevations at each corner
      LCreal elevSW = static_cast<LCreal>(columns[icol][irow]);
      LCreal elevNW = static_cast<LCreal>(columns[icol][irow+1]);
      LCreal elevSE = static_cast<LCreal>(columns[icol+1][irow]);
      LCreal elevNE = static_cast<LCreal>(columns[icol+1][irow+1]);

      // Interpolate the west point
      LCreal westPoint = elevSW + (elevNW - elevSW) * deltaLat;

      // Interpolate the east point
      LCreal eastPoint = elevSE + (elevNE - elevSE) * deltaLat;

      // Interpolate between the west and east points
      value = westPoint + (eastPoint - westPoint) * deltaLon;
   }

   else {
      // No -- just use the nearest post

      // Nearest post
      unsigned int irow = static_cast<unsigned int>(pointsLat + 0.5f);
      unsigned int icol = static_cast<unsigned int>(pointsLon + 0.5f);
      if (irow >= nptlat) irow = (nptlat-1);
      if (icol >= nptlong) icol = (nptlong-1);

      // Get the elevation post at the current indices.
      value = static_cast<LCreal>(columns[icol][irow]);
   }

   // ---
   // Return the elevation value to the user
   // ---
   *elev = value;

   return true;
}
Exemplo n.º 5
0
//------------------------------------------------------------------------------
// Locates an array of (at least two) elevation points (and sets valid flags if found)
// returns the number of points found within this DataFile
//------------------------------------------------------------------------------
unsigned int DataFile::getElevations(
      LCreal* const elevations,     // The elevation array (meters)
      bool* const validFlags,       // Valid elevation flag array (true if elevation was found)
      const unsigned int n,         // Size of elevation and valdFlags arrays
      const double lat,             // Starting latitude (degs)
      const double lon,             // Starting longitude (degs)
      const LCreal direction,       // True direction (heading) angle of the data (degs)
      const LCreal maxRng,          // Range to last elevation point (meters)
      const bool interp            // Interpolate between elevation posts (if true)
   ) const
{
   unsigned int num = 0;

   // Early out tests
   if ( elevations == 0 ||             // The elevation array wasn't provided, or
        validFlags == 0 ||             // the valid flag array wasn't provided, or
        n < 2 ||                       // there are too few points, or
        (lat < -89.0 || lat > 89.0) || // and we're not starting at the north or south poles
        maxRng <= 0                    // the max range is less than or equal to zero
      ) return num;


   // Upper limit points
   double maxLatPoint = static_cast<double>(nptlat-1);
   double maxLonPoint = static_cast<double>(nptlong-1);

   // Starting points
   double pointsLat = (lat - getLatitudeSW()) / latSpacing;
   double pointsLon = (lon - getLongitudeSW()) / lonSpacing;

   // Spacing between points (in each direction)
   double deltaPoint = maxRng / (n - 1);
   double dirR = direction * Basic::Angle::D2RCC;
   double deltaNorth = deltaPoint * cos(dirR) * Basic::Distance::M2NM;  // (NM)
   double deltaEast  = deltaPoint * sin(dirR) * Basic::Distance::M2NM;
   double deltaLat = deltaNorth/60.0;
   double deltaLon = deltaEast/(60.0 * cos(lat * Basic::Angle::D2RCC));
   double deltaPointsLat = deltaLat / latSpacing;
   double deltaPointsLon = deltaLon / lonSpacing;

   // ---
   // Loop for the number of points in the arrays;
   // ---
   for (unsigned int i = 0; i < n; i++) {

      if ( !validFlags[i] &&                                // Not already found and
          (pointsLat >= 0 && pointsLat <= maxLatPoint) &&   // and within latitude range and
          (pointsLon >= 0 && pointsLon <= maxLonPoint) ) {  // and within longitude range ...

            // We're within our data limits
            LCreal value = 0;          // the elevation (meters)

            // ---
            // Interpolating between elevation posts?
            // ---
            if (interp) {
               // Yes ---

               // South-west corner post is [icol][irow]
               unsigned int irow = static_cast<unsigned int>(pointsLat);
               unsigned int icol = static_cast<unsigned int>(pointsLon);
               if (irow > (nptlat-2)) irow = (nptlat-2);
               if (icol > (nptlong-2)) icol = (nptlong-2);

               // delta from s-w corner post
               LCreal deltaLat = static_cast<LCreal>(pointsLat - static_cast<double>(irow));
               LCreal deltaLon = static_cast<LCreal>(pointsLon - static_cast<double>(icol));

               // Get the elevations at each corner
               LCreal elevSW = static_cast<LCreal>(columns[icol][irow]);
               LCreal elevNW = static_cast<LCreal>(columns[icol][irow+1]);
               LCreal elevSE = static_cast<LCreal>(columns[icol+1][irow]);
               LCreal elevNE = static_cast<LCreal>(columns[icol+1][irow+1]);

               // Interpolate the west point
               LCreal westPoint = elevSW + (elevNW - elevSW) * deltaLat;

               // Interpolate the east point
               LCreal eastPoint = elevSE + (elevNE - elevSE) * deltaLat;

               // Interpolate between the west and east points
               value = westPoint + (eastPoint - westPoint) * deltaLon;
            }

            else {
               // No -- just use the nearest post

               // Nearest post
               unsigned int irow = static_cast<unsigned int>(pointsLat + 0.5);
               unsigned int icol = static_cast<unsigned int>(pointsLon + 0.5);
               if (irow >= nptlat) irow = (nptlat-1);
               if (icol >= nptlong) icol = (nptlong-1);

               // Get the elevation post at the current indices.
               value = static_cast<LCreal>(columns[icol][irow]);
            }

            // Pass the elevation value and valid flag to the user's arrays
            elevations[i] = value;
            validFlags[i] = true;
            num++;

      } // end lat/lon point checks

      // Update our location within our data array
      pointsLat += deltaPointsLat;
      pointsLon += deltaPointsLon;

   } // end loop

   return num;
}