#pragma once #include #include #include // 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> tile_cache_; };