//------------------------------------------------------------------------------ // 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; }
//------------------------------------------------------------------------------ // 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; }
//------------------------------------------------------------------------------ // 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; }
//------------------------------------------------------------------------------ // 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; }
//------------------------------------------------------------------------------ // 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; }