{"id":20286346,"url":"https://github.com/poseidon-code/gdem","last_synced_at":"2025-10-16T21:46:20.409Z","repository":{"id":246250027,"uuid":"820508101","full_name":"poseidon-code/GDEM","owner":"poseidon-code","description":"C++ wrapper over GDAL for working with DEM data.","archived":false,"fork":false,"pushed_at":"2024-09-17T19:04:16.000Z","size":561,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-14T08:13:56.103Z","etag":null,"topics":["cpp","dem","digital-elevation-model","gdal"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/poseidon-code.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-26T15:53:24.000Z","updated_at":"2024-09-17T19:04:20.000Z","dependencies_parsed_at":"2024-11-14T14:37:24.011Z","dependency_job_id":"fce198ff-7f6c-478c-97f6-bf94a6bf1d7a","html_url":"https://github.com/poseidon-code/GDEM","commit_stats":null,"previous_names":["poseidon-code/gdem"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/poseidon-code%2FGDEM","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/poseidon-code%2FGDEM/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/poseidon-code%2FGDEM/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/poseidon-code%2FGDEM/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/poseidon-code","download_url":"https://codeload.github.com/poseidon-code/GDEM/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241780500,"owners_count":20019061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","dem","digital-elevation-model","gdal"],"created_at":"2024-11-14T14:33:39.330Z","updated_at":"2025-10-16T21:46:20.303Z","avatar_url":"https://github.com/poseidon-code.png","language":"C++","readme":"# GDEM\nGDEM is a simple header only C++ wrapper library over GDAL for specifically working with GeoTiff DEM data.\nIt provides basic DEM related functionality like getting the altitude. It also provides some pretty\nGeoTiff dataset related functions like getting the metadata of the GeoTiff file.\nUtility functions like merge, reproject, clip, resample, etc. are also provided.\n\n\n## Project Setup (CMake)\n\n\u003e Make sure that `GDAL` libraries are installed on the system _(or is available in `PATH`)_ and that CMake can find it with\n\u003e `find_package(GDAL)`.\n\n**Prerequisites**\n1. CMake _(version 3.25 or above)_\n2. GDAL development libraries\n3. C++ compiler with support for C++ 20 standard (or above)\n\n\n```cmake\n# CMakeLists.txt (at the root of your project)\n\ncmake_minimum_required(VERSION 3.25)\nproject(Test LANGUAGES C CXX)\n\nset(CMAKE_CXX_STANDARD 20) # C++ standard 20 or above\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\n# including the downloaded GDEM library (\u003cproject_root\u003e/external/GDEM)\nadd_subdirectory(external/GDEM)\n\nadd_executable(${PROJECT_NAME} main.cpp)\ntarget_include_directories(${PROJECT_NAME} PUBLIC ${LIBGDEM_INCLUDE_DIRECTORIES}) # include GDEM headers\ntarget_link_libraries(${PROJECT_NAME} PUBLIC GDEM) # links GDEM\n```\n\n\n## DEM Usage\n\nBasic functionality regarding DEM, like getting the altitude. The dataset is automatically closed on\ndestruction when DEM object is initialized with DEM file path.\n\n```cpp\n#include \u003ccstdint\u003e\n#include \u003cfilesystem\u003e\n#include \u003cstring\u003e\n\n#include \"GDEM/DEM.hpp\"\n\n\nint main() {\n    // initialising DEM\n    DEM\u003cint16_t\u003e dem_1(std::filesystem::path(\"/workspace/data/XYZ.tif\"));\n    DEM\u003cfloat, 2\u003e dem_2(std::string(\"/workspace/data/XYZ.tif\"));\n\n    GDALRegister_GTiff();\n    GDALDataset* dataset = static_cast\u003cGDALDataset*\u003e(GDALOpen(\"/workspace/data/XYZ.tif\", GA_ReadOnly));\n    DEM\u003cint32_t, 3, std::numeric_limits\u003cint32_t\u003e::max()\u003e dem_3(dataset);\n\n\n    // finding altitude\n    float latitude = 14.347826, longitude = 76.567238;\n    std::cout \u003c\u003c dem_1.altitude(latitude, longitude) \u003c\u003c std::endl;\n    std::cout \u003c\u003c dem_3.interpolated_altitude(latitude, longitude) \u003c\u003c std::endl;\n\n    GDALClose(dataset);\n\n    return 0;\n}\n```\n\n\n## Utility Usage\n\n1.  **Metadata** \\\n    **`static void Metadata(GDALDataset* dataset)`** \\\n    **`static void Metadata(const std::string\u0026 file_path)`** \\\n    **`static void Metadata(const std::filesystem::path\u0026 file_path)`**\n\n    Prints the metadata of the input dataset. Usefull when thge underlying data type or the number of raster bands are unknown.\n    Takes input dataset as `std::string|std::filesystem::path|GDALDataset*` and prints the relevant DEM metadata.\n\n    ```cpp\n    #include \u003cfilesystem\u003e\n    #include \u003cstring\u003e\n\n    #include \"GDEM/Utility.hpp\"\n\n    int main() {\n        // source dataset file paths\n        std::filesystem::path f_1 = \"/workspace/data/XYZ.tif\";\n        std::string f_2 = \"/workspace/data/XYZ.tif\";\n\n        GDALRegister_GTiff();\n        GDALDataset* f_3 = static_cast\u003cGDALDataset*\u003e(GDALOpen(\"/workspace/data/XYZ.tif\", GA_ReadOnly));\n\n\n        // Metadata\n        GDEM::Utility::Metadata(f_1);\n        GDEM::Utility::Metadata(f_2);\n        GDEM::Utility::Metadata(f_3);\n\n\n        GDALClose(f_3);\n        return 0;\n    }\n    ```\n\n\n2.  **Reproject** \\\n    **`static void Reproject(GDALDataset* source_dataset, const std::string\u0026 destination_filepath, int16_t nodata_value)`** \\\n    **`static void Reproject(const std::string\u0026 source_filepath, const std::string\u0026 destination_filepath, int16_t nodata_value)`** \\\n    **`static void Reproject(const std::filesystem::path\u0026 source_filepath, const std::string\u0026 destination_filepath, int16_t nodata_value)`** \\\n    **`static void Reproject(const std::string\u0026 source_filepath, const std::filesystem::path\u0026 destination_filepath, int16_t nodata_value)`** \\\n    **`static void Reproject(const std::filesystem::path\u0026 source_filepath, const std::filesystem::path\u0026 destination_filepath, int16_t nodata_value)`**\n\n    Reprojects the dataset from its current Spatial Reference System to a `WGS84/EPSG:4326` Spatial Reference System.\n    Takes the input dataset as `std::string|std::filesystem::path|GDALDataset*` with a destination file path of the\n    reprojected dataset as `std::string|std::filesystem::path` and the `NODATA` value. \\\n    It creates a new file with the passed in destination file path as path for output.\n\n    ```cpp\n    #include \u003cfilesystem\u003e\n    #include \u003cstring\u003e\n\n    #include \"GDEM/Utility.hpp\"\n\n    int main() {\n        // source dataset file paths\n        std::filesystem::path f_1 = \"/workspace/data/XYZ.tif\";\n        std::string f_2 = \"/workspace/data/XYZ.tif\";\n\n        GDALRegister_GTiff();\n        GDALDataset* f_3 = static_cast\u003cGDALDataset*\u003e(GDALOpen(\"/workspace/data/XYZ.tif\", GA_ReadOnly));\n\n        // destination file paths\n        std::filesystem::path d_1 = \"/workspace/data/XYZ_reprojected.tif\";\n        std::string d_2 = \"/workspace/data/XYZ_reprojected.tif\";\n\n\n        // Reprojection\n        GDEM::Utility::Reproject(f_2, d_1, INT16_MIN);\n        GDEM::Utility::Reproject(f_1, d_2, 0);\n        GDEM::Utility::Reproject(f_3, d_2, INT16_MAX);\n\n\n        GDALClose(f_3);\n        return 0;\n    }\n    ```\n\n\n3.  **Merge** \\\n    **`static void Merge(const std::vector\u003cGDALDataset*\u003e\u0026 source_datasets, const std::string\u0026 destination_filepath, int16_t nodata_value)`** \\\n    **`static void Merge(const std::vector\u003cstd::string\u003e\u0026 source_filepaths, const std::string\u0026 destination_filepath, int16_t nodata_value)`** \\\n    **`static void Merge(const std::vector\u003cstd::filesystem::path\u003e\u0026 source_filepaths, const std::filesystem::path\u0026 destination_filepath, int16_t nodata_value)`** \\\n    **`static void Merge(const std::vector\u003cstd::filesystem::path\u003e\u0026 source_filepaths, const std::string\u0026 destination_filepath, int16_t nodata_value)`** \\\n    **`static void Merge(const std::vector\u003cstd::string\u003e\u0026 source_filepaths, const std::filesystem::path\u0026 destination_filepath, int16_t nodata_value)`**\n\n    Merges multiple datasets together with median values approach.\n    Takes an input of a `std::vector\u003cstd::string|std::filesystem::path|GDALDataset*\u003e` along with a destination\n    file path of the merged dataset as `std::string|std::filesystem::path` and the `NODATA` value. \\\n    It creates a new file with the passed in destination file path as path for output.\n\n    ```cpp\n    #include \u003cfilesystem\u003e\n    #include \u003cstring\u003e\n\n    #include \"GDEM/Utility.hpp\"\n\n    int main() {\n        // source dataset file paths\n        std::vector\u003cstd::filesystem::path\u003e f_1 = {\"/workspace/data/ABC.tif\", \"/workspace/data/PQR.tif\", \"/workspace/data/XYZ.tif\"};\n        std::vector\u003cstd::string\u003e f_2 = {\"/workspace/data/ABC.tif\", \"/workspace/data/PQR.tif\", \"/workspace/data/XYZ.tif\"};\n\n        std::vector\u003cGDALDataset*\u003e f_3\n        GDALRegister_GTiff();\n        for (const auto\u0026 path : f_2) {\n            f_3.push_back(static_cast\u003cGDALDataset*\u003e(GDALOpen(path.c_str(), GA_ReadOnly)));\n        }\n\n        // destination file paths\n        std::filesystem::path d_1 = \"/workspace/data/ABC_PQR_XYZ_merged.tif\";\n        std::string d_2 = \"/workspace/data/ABC_PQR_XYZ_merged.tif\";\n\n\n        // Merging\n        GDEM::Utility::Merge(f_2, d_1, INT16_MIN);\n        GDEM::Utility::Merge(f_1, d_2, 0);\n        GDEM::Utility::Merge(f_3, d_2, INT16_MAX);\n\n\n        for (auto\u0026 dataset : f_3) {\n            GDALClose(dataset);\n        }\n        return 0;\n    }\n    ```\n\n\n4.  **Clip** \\\n    **`static void Clip(GDALDataset* source_dataset, const std::string\u0026 destination_filepath, double top_left_x, double top_left_y, double bottom_right_x, double bottom_right_y)`** \\\n    **`static void Clip(const std::string\u0026 source_filepath, const std::string\u0026 destination_filepath, double top_left_x, double top_left_y, double bottom_right_x, double bottom_right_y)`** \\\n    **`static void Clip(const std::filesystem::path\u0026 source_filepath, const std::string\u0026 destination_filepath, double top_left_x, double top_left_y, double bottom_right_x, double bottom_right_y)`** \\\n    **`static void Clip(const std::string\u0026 source_filepath, const std::filesystem::path\u0026 destination_filepath, double top_left_x, double top_left_y, double bottom_right_x, double bottom_right_y)`** \\\n    **`static void Clip(const std::filesystem::path\u0026 source_filepath, const std::filesystem::path\u0026 destination_filepath, double top_left_x, double top_left_y, double bottom_right_x, double bottom_right_y)`**\n\n    Clips (crops) a dataset with 4 bounding coordinates. If the bounding coordinates doesn't lies within the\n    dataset's bounds, it will just crop upto the maximum bounded area of the input datset.\n    Takes an input of source dataset as `std::string|std::filesystem::path|GDALDataset*` along with destination\n    file path of the clipped dataset as `std::string|std::filesystem::path` and 4  coordinate bounds of the\n    bounded region. \\\n    It creates a new file with the passed in destination file path as path for output.\n\n\n    ```cpp\n    #include \u003cfilesystem\u003e\n    #include \u003cstring\u003e\n\n    #include \"GDEM/Utility.hpp\"\n\n    int main() {\n        // source dataset file paths\n        std::filesystem::path f_1 = \"/workspace/data/XYZ.tif\";\n        std::string f_2 = \"/workspace/data/XYZ.tif\";\n\n        GDALRegister_GTiff();\n        GDALDataset* f_3 = static_cast\u003cGDALDataset*\u003e(GDALOpen(\"/workspace/data/XYZ.tif\", GA_ReadOnly));\n\n        // destination file paths\n        std::filesystem::path d_1 = \"/workspace/data/XYZ_clipped.tif\";\n        std::string d_2 = \"/workspace/data/XYZ_clipped.tif\";\n\n\n        // Clipping\n        double top_left_x = 75.4, top_left_y = 14.4, bottom_right_x = 75.6, bottom_right_y = 14.2;\n        GDEM::Utility::Clip(f_2, d_1, top_left_x, top_left_y, bottom_right_x, bottom_right_y);\n        GDEM::Utility::Clip(f_1, d_2, top_left_x, top_left_y, bottom_right_x, bottom_right_y);\n        GDEM::Utility::Clip(f_3, d_2, top_left_x, top_left_y, bottom_right_x, bottom_right_y);\n\n\n        GDALClose(f_3);\n        return 0;\n    }\n    ```\n\n\n5.  **Resample** \\\n    **`static void Resample(GDALDataset* source_dataset, const std::string\u0026 destination_filepath, unsigned int output_width, unsigned int output_height)`** \\\n    **`static void Resample(const std::string\u0026 source_filepath, const std::string\u0026 destination_filepath, unsigned int output_width, unsigned int output_height)`** \\\n    **`static void Resample(const std::filesystem::path\u0026 source_filepath, const std::string\u0026 destination_filepath, unsigned int output_width, unsigned int output_height)`** \\\n    **`static void Resample(const std::string\u0026 source_filepath, const std::filesystem::path\u0026 destination_filepath, unsigned int output_width, unsigned int output_height)`** \\\n    **`static void Resample(const std::filesystem::path\u0026 source_filepath, const std::filesystem::path\u0026 destination_filepath, unsigned int output_width, unsigned int output_height)`**\n\n    Resamples the input dataset to a new dataset with given width and height, preserving the projections\n    of the source dataset.\n    Takes an input of source dataset as `std::string|std::filesystem::path|GDALDataset*` along with destination\n    file path of the clipped dataset as `std::string|std::filesystem::path` and the width \u0026 height of the\n    output dataset. \\\n    It creates a new file with the passed in destination file path as path for output.\n\n\n    ```cpp\n    #include \u003cfilesystem\u003e\n    #include \u003cstring\u003e\n\n    #include \"GDEM/Utility.hpp\"\n\n    int main() {\n        // source dataset file paths\n        std::filesystem::path f_1 = \"/workspace/data/XYZ.tif\";\n        std::string f_2 = \"/workspace/data/XYZ.tif\";\n\n        GDALRegister_GTiff();\n        GDALDataset* f_3 = static_cast\u003cGDALDataset*\u003e(GDALOpen(\"/workspace/data/XYZ.tif\", GA_ReadOnly));\n\n        // destination file paths\n        std::filesystem::path d_1 = \"/workspace/data/XYZ_resampled.tif\";\n        std::string d_2 = \"/workspace/data/XYZ_resampled.tif\";\n\n\n        // Clipping\n        unsigned int width = 2000, height = 2000;\n        GDEM::Utility::Resample(f_2, d_1, width, height);\n        GDEM::Utility::Resample(f_1, d_2, width, height);\n        GDEM::Utility::Resample(f_3, d_2, width, height);\n\n\n        GDALClose(f_3);\n        return 0;\n    }\n    ```\n\n\n6.  **Coverage** \\\n    **`static std::vector\u003cstd::filesystem::path\u003e Coverage(const std::vector\u003cstd::string\u003e\u0026 filepaths, double top_left_x, double top_left_y, double bottom_right_x, double bottom_right_y)`** \\\n    **`static std::vector\u003cstd::filesystem::path\u003e Coverage(const std::vector\u003cstd::filesystem::path\u003e\u0026 filepaths, double top_left_x, double top_left_y, double bottom_right_x, double bottom_right_y)`**\n\n    Provides a list of file paths from a list of input file paths which covers a region bounded by 4 coordinates.\n    Takes an input of a `std::vector\u003cstd::string|std::filesystem::path\u003e` and 4  coordinate bounds of the bounded region\n    and returns a `std::vector\u003cstd::string|std::filesystem::path\u003e` of file paths covering the bounded region.\n\n    ```cpp\n    #include \u003cfilesystem\u003e\n    #include \u003cstring\u003e\n\n    #include \"GDEM/Utility.hpp\"\n\n    int main() {\n        // searching file paths\n        std::vector\u003cstd::filesystem::path\u003e f_1 = {\"/workspace/data/ABC.tif\", \"/workspace/data/PQR.tif\", \"/workspace/data/XYZ.tif\"};\n        std::vector\u003cstd::string\u003e f_2 = {\"/workspace/data/ABC.tif\", \"/workspace/data/PQR.tif\", \"/workspace/data/XYZ.tif\"};\n\n        // Coverage\n        double top_left_x = 75.4, top_left_y = 14.4, bottom_right_x = 75.6, bottom_right_y = 14.2;\n        std::vector\u003cstd::filesystem::path\u003e o_1 = GDEM::Utility::Coverage(f_1, top_left_x, top_left_y, bottom_right_x, bottom_right_y);\n        std::vector\u003cstd::filesystem::path\u003e o_2 = GDEM::Utility::Coverage(f_2, top_left_x, top_left_y, bottom_right_x, bottom_right_y);\n\n\n        // list of files covering the bounded region\n        for (const auto\u0026 path : o_1) {\n            std::cout \u003c\u003c path.string() \u003c\u003c std::endl;\n        }\n\n        return 0;\n    }\n    ```\n\n\n7.  **CoordinatesAlongPolygon** \\\n    **`static std::vector\u003cstd::pair\u003cfloat, float\u003e\u003e CoordinatesAlongPolygon(const std::vector\u003cstd::pair\u003cfloat, float\u003e\u003e\u0026 polygon_points, float interval_arcseconds = 1.0)`**\n\n    Generates coordinates between 2 or more coordinate points with an interval on passed in arcseconds.\n    Takes input of a list of coordinate points (latitude \u0026 longitude) as `std::vector\u003cstd::pair\u003cfloat, float\u003e\u003e` with\n    intervals (in arcseconds) as `float` (default: 1.0 arcsecond) and returns a list of all the coordinates between those\n    passed in points as `std::vector\u003cstd::pair\u003cfloat, float\u003e\u003e` (`first`=latitude \u0026 `second`=longitude).\n\n    ```cpp\n    #include \u003cfilesystem\u003e\n    #include \u003cstring\u003e\n\n    #include \"GDEM/Utility.hpp\"\n\n    int main() {\n        // points of the polygon\n        std::vector\u003cstd::pair\u003cfloat, float\u003e\u003e points = {\n            {14.51, 75.31},\n            {14.52, 75.32},\n            {14.53, 75.33}\n        };\n        float interval_arcseconds = 0.3;\n\n        // generating points in-between\n        std::vector\u003cstd::pair\u003cfloat, float\u003e\u003e generated_points = GDEM::Utility::CoordinatesAlongPolygon(points, interval_arcseconds);\n        for (auto point : generated_points) {\n            std::cout \u003c\u003c point.first \u003c\u003c \", \" \u003c\u003c point.second \u003c\u003c std::endl;\n        }\n\n        return 0;\n    }\n    ```\n\n\n# [GPL v3 License](./LICENSE)\n\nGDEM : C++ wrapper over GDAL for working with DEM data. \\\nCopyright (C) 2024  Pritam Halder\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program.  If not, see \u003chttps://www.gnu.org/licenses/\u003e.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposeidon-code%2Fgdem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fposeidon-code%2Fgdem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposeidon-code%2Fgdem/lists"}