.. _program_listing_file_src_navtk_geospatial_sources_GeoidUndulationSource.hpp: Program Listing for File GeoidUndulationSource.hpp ================================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/navtk/geospatial/sources/GeoidUndulationSource.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #pragma once #include #include #include #include #include namespace navtk { namespace geospatial { class GeoidUndulationSource : public SpatialMapDataSource { public: static std::shared_ptr get_shared( const std::string& path = "WW15MGH.GRD"); std::pair lookup_datum(double latitude, double longitude) const override; void set_chunk_size(Size size); Size get_chunk_size() const; private: // private constructor because global instance is implemented via `get_shared()`. GeoidUndulationSource(const std::string& path); GeoidUndulationSource(const GeoidUndulationSource&) = delete; GeoidUndulationSource& operator=(const GeoidUndulationSource&) = delete; GeoidUndulationSource(const GeoidUndulationSource&&) = delete; GeoidUndulationSource& operator=(const GeoidUndulationSource&&) = delete; // Check if either latitude/longitude pair are outside of the current chunk of undulation // values read into memory. bool is_outside_cache_bounds(double lat, double lon) const; // Moves file pointer to the start of a new chunk of data and reads the chunk into memory. void init_coverage(double lat, double lon) const; // Set the bounds for a new square chunk to be pulled into memory. This chunk will be centered // around (lat, lon). Will set internal variables lat_coverage_min, lat_coverage_max, // lon_coverage_min, and lat_coverage_max to reflect the range of latitudes and longitudes that // the Matrix available_undulations contains undulation values for. void set_coverage_bounds(double lat, double lon) const; // Read in a 'box' of undulation data into memory. void read_chunk() const; // Skip a section of the file equivalent to a given number of records. This is called after // resetting the file pointer to the start of the file to move the pointer to the start of the // first record within the coverage bounds. void skip_records(size_t num) const; // Reads one double value from the file and returns it. double read_value() const; // Reads the value from a line in the file with a single element (such as occurs at the end of // each record). Required that the file pointer at the end of block 9 (the last block) in a // given record. This value is the same as the first value in a record, so no need to store it. void ignore_value() const; // Read an entire record (1440 values) starting at the current location of the file pointer. A // record consists of 9 blocks containing 20 lines with 8 values per line (for a total of 160 // values per block). Each block is preceded by an empty line. A record is followed by an empty // line and an additional single value on its own line. void read_record(Size min_lon_idx, Size max_lon_idx, size_t row_idx) const; // Get the record number of a given latitude. Ex: latitude 90 is the first record in the file, // so return 0; latitude 80 is the 40th record, so return 40. size_t get_lat_idx(double lat) const; // Get the element in the available_undulations Matrix corresponding to the given lat and lon. // Assumes lat and lon will be multiples of 0.25 and that the corresponding point will be found // in memory. double get_value(double lat, double lon) const; mutable std::shared_ptr infile; /* 'WW15MGH.GRD' file attributes */ const double min_lat, max_lat, min_lon, max_lon, lat_step, lon_step; /* Chunk attributes */ // chunk_size is the length of a "side" of a chunk square (i.e. the number of latitude points or // the number of longitude points to cover). The latitude or longitude range that a // available_undulations spans in chunk_size/4. Ex: A chunk_size of 40 includes 41x41 // latitude/longitude points and spans 10 degrees of latitude and 10 degrees of longitude. Size chunk_size = 40; // total number of bytes = (chunk_size + 1)^2 * (# of bytes/value) // latitude coverage range is [lat_coverage_min, lat_coverage_max] mutable double lat_coverage_min = -100; mutable double lat_coverage_max = -100; // longitude coverage range is [lon_coverage_min, lon_coverage_max] mutable double lon_coverage_min = -1; mutable double lon_coverage_max = -1; // The chunk of read data stored in memory // NOTE: using xt::xtensor instead of navtk::Matrix as the latter will heap-allocate a // xt::pytensor object when using the python module. This is undesirable as the // GeoidUndulationSource singleton won't be cleaned up until after the python interpreter has // completely shut down, which will trigger a segfault. mutable xt::xtensor available_undulations; }; } // namespace geospatial } // namespace navtk