SXXXXXXX_GeoElevation/source_c/ElevationReader.h

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