83 lines
3.3 KiB
C++
83 lines
3.3 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
|
|
// A constant for the expected grid dimension of 1-arc-second NASADEM HGT files.
|
|
constexpr int HGT_GRID_DIMENSION = 3601;
|
|
|
|
// The special value returned to the user when elevation data is not available.
|
|
constexpr double USER_NO_DATA_VALUE = -999.0;
|
|
|
|
/**
|
|
* @class ElevationReader
|
|
* @brief Reads elevation data from .hgt files downloaded by the GeoElevation tool.
|
|
*
|
|
* This class manages the loading, caching, and querying of 1-arc-second NASADEM .hgt files.
|
|
* It is designed to find the correct tile for a given coordinate, handle the binary
|
|
* file reading, and correctly interpret the big-endian data format used in HGT files.
|
|
*/
|
|
class ElevationReader {
|
|
public:
|
|
/**
|
|
* @brief Constructs an ElevationReader.
|
|
* @param hgt_directory The path to the directory containing the .hgt tile files.
|
|
*/
|
|
explicit ElevationReader(const std::string& hgt_directory);
|
|
|
|
/**
|
|
* @brief Gets the elevation for a specific geographic coordinate.
|
|
*
|
|
* This is the main public method of the class. It orchestrates finding the correct
|
|
* tile, loading it if necessary, and calculating the elevation.
|
|
*
|
|
* @param latitude The latitude in decimal degrees (e.g., 45.072).
|
|
* @param longitude The longitude in decimal degrees (e.g., 7.685).
|
|
* @return The elevation in meters as a double. Returns USER_NO_DATA_VALUE (-999.0)
|
|
* if the corresponding .hgt tile is not found, coordinates are invalid,
|
|
* or if the point corresponds to a "no data" value in the file.
|
|
*/
|
|
double get_elevation(double latitude, double longitude);
|
|
|
|
private:
|
|
/**
|
|
* @brief Generates the base filename (e.g., "N45E007") for a given coordinate.
|
|
* @param latitude The latitude of the point.
|
|
* @param longitude The longitude of the point.
|
|
* @return The standard base filename for the tile.
|
|
*/
|
|
std::string get_tile_basename(double latitude, double longitude) const;
|
|
|
|
/**
|
|
* @brief Loads a tile from disk into the cache if it's not already present.
|
|
*
|
|
* This method implements a lazy-loading strategy. A tile is only read from disk
|
|
* the first time it is needed. Subsequent requests for the same tile will use
|
|
* the in-memory cache.
|
|
*
|
|
* @param tile_basename The base name of the tile to load (e.g., "N45E007").
|
|
* @return True if the tile was loaded successfully or was already in the cache, false otherwise.
|
|
*/
|
|
bool ensure_tile_is_loaded(const std::string& tile_basename);
|
|
|
|
/**
|
|
* @brief Converts a 16-bit integer from big-endian to the host system's endianness.
|
|
*
|
|
* HGT files store data in big-endian (network byte order), while most modern CPUs
|
|
* (x86/x64) are little-endian. This byte swap is a critical step to correctly
|
|
* interpret the elevation values.
|
|
*
|
|
* @param value The big-endian short value read from the file.
|
|
* @return The value converted to the host system's native byte order.
|
|
*/
|
|
int16_t byteswap(int16_t value) const;
|
|
|
|
// The path to the directory where .hgt files are stored.
|
|
std::string hgt_dir_path_;
|
|
|
|
// In-memory cache for tile data to avoid repeated, slow file reads from disk.
|
|
// The key is the tile basename (e.g., "N45E007"), the value is the elevation data.
|
|
std::map<std::string, std::vector<int16_t>> tile_cache_;
|
|
}; |