{"id":23832001,"url":"https://github.com/csdms/bmi-topography","last_synced_at":"2025-06-30T06:35:02.609Z","repository":{"id":37257356,"uuid":"339495696","full_name":"csdms/bmi-topography","owner":"csdms","description":"Fetch and cache land elevation data from OpenTopography through an API, BMI, or CLI","archived":false,"fork":false,"pushed_at":"2025-06-22T21:03:29.000Z","size":5410,"stargazers_count":11,"open_issues_count":10,"forks_count":4,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-06-22T22:18:52.655Z","etag":null,"topics":["alos","bmi","copernicus","csdms","nasadem","python","srtm","topography","usgs"],"latest_commit_sha":null,"homepage":"https://bmi-topography.csdms.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/csdms.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-02-16T18:42:40.000Z","updated_at":"2025-06-22T21:03:28.000Z","dependencies_parsed_at":"2023-12-18T18:41:38.579Z","dependency_job_id":"28173b3a-9024-4167-a71b-7c4978ff8a62","html_url":"https://github.com/csdms/bmi-topography","commit_stats":{"total_commits":110,"total_committers":2,"mean_commits":55.0,"dds":"0.045454545454545414","last_synced_commit":"4a34cb4155acc8d692bf3f0bc56b671b8eb6c426"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/csdms/bmi-topography","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csdms%2Fbmi-topography","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csdms%2Fbmi-topography/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csdms%2Fbmi-topography/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csdms%2Fbmi-topography/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/csdms","download_url":"https://codeload.github.com/csdms/bmi-topography/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csdms%2Fbmi-topography/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261374945,"owners_count":23149038,"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":["alos","bmi","copernicus","csdms","nasadem","python","srtm","topography","usgs"],"created_at":"2025-01-02T14:16:54.130Z","updated_at":"2025-06-30T06:35:02.590Z","avatar_url":"https://github.com/csdms.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- Links (by alpha) --\u003e\n\n[bmi]: https://bmi.csdms.io\n[bmi-topo-examples]: https://github.com/csdms/bmi-topography/tree/main/examples\n[bmi-topo-repo]: https://github.com/csdms/bmi-topography\n[conda-env]: https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html\n[ot]: https://opentopography.org/\n[ot-api-key]: https://opentopography.org/blog/introducing-api-keys-access-opentopography-global-datasets\n[ot-rest]: https://portal.opentopography.org/apidocs/\n[rioxarray]: https://corteva.github.io/rioxarray/stable/getting_started/getting_started.html\n[xarray]: https://docs.xarray.dev/en/stable/index.html\n[xarray-da]: https://docs.xarray.dev/en/stable/generated/xarray.DataArray.html\n[xarray-plot]: https://docs.xarray.dev/en/stable/generated/xarray.DataArray.plot.html\n\n\u003c!-- Links to datasets on OT --\u003e\n[SRTMGL3]: https://portal.opentopography.org/raster?opentopoID=OTSRTM.042013.4326.1\n[SRTMGL1]: https://portal.opentopography.org/raster?opentopoID=OTSRTM.082015.4326.1\n[SRTMGL1_E]: https://portal.opentopography.org/raster?opentopoID=OTSRTM.082016.4326.1\n[AW3D30]: https://portal.opentopography.org/raster?opentopoID=OTALOS.112016.4326.2\n[AW3D30_E]: https://portal.opentopography.org/raster?opentopoID=OTALOS.082017.4326.1\n[SRTM15Plus]: https://portal.opentopography.org/datasetMetadata?otCollectionID=OT.122019.4326.1\n[NASADEM]: https://doi.org/10.5069/G93T9FD9\n[COP30]: https://portal.opentopography.org/raster?opentopoID=OTSDEM.032021.4326.3\n[COP90]: https://portal.opentopography.org/raster?opentopoID=OTSDEM.032021.4326.1\n[EU_DTM]: https://portal.opentopography.org/datasetMetadata?otCollectionID=OT.092022.3035.1\n[GEDI_L3]: https://portal.opentopography.org/datasetMetadata?otCollectionID=OT.032022.4326.1\n[GEBCOIceTopo]: https://portal.opentopography.org/raster?opentopoID=OTSDEM.122023.4326.1\n[GEBCOSubIceTopo]: https://portal.opentopography.org/raster?opentopoID=OTSDEM.122023.4326.2\n[CA_MRDEM_DSM]: https://doi.org/10.5069/G9N8780J\n[CA_MRDEM_DTM]: https://doi.org/10.5069/G9N8780J\n[USGS30m]: https://portal.opentopography.org/raster?opentopoID=OTNED.012021.4269.2\n[USGS10m]: https://portal.opentopography.org/raster?opentopoID=OTNED.012021.4269.1\n[USGS1m]: https://portal.opentopography.org/raster?opentopoID=OTNED.012021.4269.3\n\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4608652.svg)](https://doi.org/10.5281/zenodo.4608652)\n[![Conda Version](https://img.shields.io/conda/vn/conda-forge/bmi-topography.svg)](https://anaconda.org/conda-forge/bmi-topography)\n[![PyPI](https://img.shields.io/pypi/v/bmi-topography)](https://pypi.org/project/bmi-topography)\n[![Build/Test CI](https://github.com/csdms/bmi-topography/actions/workflows/test.yml/badge.svg)](https://github.com/csdms/bmi-topography/actions/workflows/test.yml)\n[![Coverage Status](https://coveralls.io/repos/github/csdms/bmi-topography/badge.svg?branch=main)](https://coveralls.io/github/csdms/bmi-topography?branch=main)\n[![Documentation Status](https://readthedocs.org/projects/bmi-topography/badge/?version=latest)](https://bmi-topography.csdms.io/en/latest/?badge=latest)\n\n# bmi-topography\n\n*bmi-topography* is a Python library for fetching and caching\nland elevation data\nusing the [OpenTopography][ot] [REST API][ot-rest].\n\nThe *bmi-topography* library provides access to the following global raster datasets:\n\n* [SRTMGL3][SRTMGL3] (SRTM GL3 90m)\n* [SRTMGL1][SRTMGL1] (SRTM GL1 30m)\n* [SRTMGL1_E][SRTMGL1_E] (SRTM GL1 Ellipsoidal 30m)\n* [AW3D30][AW3D30] (ALOS World 3D 30m)\n* [AW3D30_E][AW3D30_E] (ALOS World 3D Ellipsoidal, 30m)\n* [SRTM15Plus][SRTM15Plus] (Global Bathymetry SRTM15+ V2.1)\n* [NASADEM][NASADEM] (NASADEM Global DEM)\n* [COP30][COP30] (Copernicus Global DSM 30m)\n* [COP90][COP90] (Copernicus Global DSM 90m)\n* [EU_DTM][EU_DTM] (DTM 30m)\n* [GEDI_L3][GEDI_L3] (DTM 1000m)\n* [GEBCOIceTopo][GEBCOIceTopo] (Global Bathymetry 500m)\n* [GEBCOSubIceTopo][GEBCOSubIceTopo] (Global Bathymetry 500m)\n* [CA_MRDEM_DSM][CA_MRDEM_DSM] (DSM 30m)\n* [CA_MRDEM_DTM][CA_MRDEM_DTM] (DTM 30m)\n\nas well as these USGS 3DEP raster datasets:\n\n* [USGS30m][USGS30m]\n* [USGS10m][USGS10m]\n* [USGS1m][USGS1m] (limited to academic users)\n\nThe library includes an API and a CLI that accept\nthe dataset type,\na latitude-longitude bounding box, and\nthe output file format.\nData are downloaded from OpenTopography and cached locally.\nThe cache is checked before downloading new data.\nData from a cached file can optionally be loaded into an\n[xarray][xarray] [DataArray][xarray-da]\nthrough [rioxarray][rioxarray].\n\nThe *bmi-topography* API is wrapped with a\n[Basic Model Interface][bmi] (BMI),\nwhich provides a standard set of functions for coupling with data or models\nthat also expose a BMI.\nMore information on the BMI can found in its [documentation][bmi].\n\n## Installation\n\nInstall the latest stable release of *bmi-topography* with `pip`:\n```\npip install bmi-topography\n```\nor with `conda`:\n```\nconda install -c conda-forge bmi-topography\n```\n\nThe *bmi-topography* library can also be built and installed from source.\nThe library uses several other open source libraries,\nso a convenient way of building and installing it is within a\n[conda environment][conda-env].\nAfter cloning or downloading the *bmi-topography*\n[repository][bmi-topo-repo],\nchange into the repository directory\nand set up a conda environment with the included environment file:\n```\nconda env create --file=environment.yml\n```\nThen build and install *bmi-topography* from source with\n```\npip install -e .\n```\n\n## API key\n\nTo better understand usage,\nOpenTopography [requires an API key][ot-api-key] to access datasets they host.\nGetting an API key is easy, and it's free:\njust follow the instructions in the link above.\n\nOnce you have an API key,\nthere are three ways to use it with *bmi-topography*:\n\n1. *parameter*: Pass the API key as a string through the `api_key` parameter.\n2. *environment variable*: In the shell, set the `OPENTOPOGRAPHY_API_KEY` environment variable to the API key value.\n3. *dot file*: Put the API key in the file `.opentopography.txt` in the current directory or in your home directory.\n\nIf you attempt to use *bmi-topography* to access an OpenTopography dataset without an API key,\nyou'll get an error like this:\n```\nrequests.exceptions.HTTPError: 401 Client Error: This dataset requires an API Key for access.\n```\n\n## Examples\n\nA brief example of using the *bmi-topography* API is given in the following steps.\n\nStart a Python session and import the `Topography` class:\n```python\n\u003e\u003e\u003e from bmi_topography import Topography\n```\n\nFor convenience,\na set of default parameter values for `Topography` are included in the class definition.\nCopy these and modify them with custom values:\n```python\n\u003e\u003e\u003e params = Topography.DEFAULT.copy()\n\u003e\u003e\u003e params[\"south\"] = 39.93\n\u003e\u003e\u003e params[\"north\"] = 40.00\n\u003e\u003e\u003e params[\"west\"] = -105.33\n\u003e\u003e\u003e params[\"east\"] = -105.26\n\u003e\u003e\u003e params\n{'dem_type': 'SRTMGL3',\n 'south': 39.93,\n 'north': 40.0,\n 'west': -105.33,\n 'east': -105.26,\n 'output_format': 'GTiff',\n 'cache_dir': '~/.bmi_topography'}\n```\nThese coordinate values represent an area around Boulder, Colorado.\n\nMake an instance of `Topography` with these parameters:\n```python\n\u003e\u003e\u003e boulder = Topography(**params)\n```\nDisplay the download URL:\n```python\n\u003e\u003e\u003e boulder.url\nhttps://portal.opentopography.org/API/globaldem?demtype=SRTMGL3\u0026south=39.93\u0026north=40.0\u0026west=-105.33\u0026east=-105.26\u0026outputFormat=GTiff\u0026API_Key=demoapikeyot2022\n```\nthen fetch the data from OpenTopography:\n```python\n\u003e\u003e\u003e boulder.fetch()\nPosixPath('/Users/mpiper/.bmi_topography/SRTMGL3_39.93_-105.33_40.0_-105.26.tif')\n```\nThis step might take a few moments,\nand the time it takes will increase for requests of larger areas.\nNote that the file has been saved to a local cache directory.\n\nLoad the data into an xarray `DataArray` for further work:\n```python\n\u003e\u003e\u003e boulder.load()\n\u003cxarray.DataArray 'SRTMGL3' (band: 1, y: 84, x: 84)\u003e\narray([[[2052, 2035, ..., 1645, 1643],\n        [2084, 2059, ..., 1643, 1642],\n        ...,\n        [2181, 2170, ..., 1764, 1763],\n        [2184, 2179, ..., 1773, 1769]]], dtype=int16)\nCoordinates:\n  * band         (band) int64 1\n  * x            (x) float64 -105.3 -105.3 -105.3 ... -105.3 -105.3 -105.3\n  * y            (y) float64 40.0 40.0 40.0 40.0 ... 39.93 39.93 39.93 39.93\n    spatial_ref  int64 0\nAttributes:\n    _FillValue:    0.0\n    scale_factor:  1.0\n    add_offset:    0.0\n    units:         meters\n    location:      node\n```\n\nCoordinate reference system (CRS) information is stored in the `spatial_ref` non-dimension coordinate:\n```python\n\u003e\u003e\u003e boulder.da.spatial_ref\n\u003cxarray.DataArray 'spatial_ref' ()\u003e\narray(0)\nCoordinates:\n    spatial_ref  int64 0\nAttributes:\n    crs_wkt:                      GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"...\n    semi_major_axis:              6378137.0\n    semi_minor_axis:              6356752.314245179\n    inverse_flattening:           298.257223563\n    reference_ellipsoid_name:     WGS 84\n    longitude_of_prime_meridian:  0.0\n    prime_meridian_name:          Greenwich\n    geographic_crs_name:          WGS 84\n    grid_mapping_name:            latitude_longitude\n    spatial_ref:                  GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"...\n    GeoTransform:                 -105.33041666668363 0.000833333333333144 0....\n```\n\nDisplay the elevations with the default xarray `DataArray` [plot][xarray-plot] method.\n```python\n\u003e\u003e\u003e import matplotlib.pyplot as plt\n\u003e\u003e\u003e boulder.da.plot()\n\u003e\u003e\u003e plt.show()\n```\n\n![Example elevation data displayed through *xarray*.](./examples/bmi-topography_ex.png)\n\nFor examples with more detail,\nsee the two Jupyter Notebooks,\nPython script, and shell script\nincluded in the [examples][bmi-topo-examples] directory\nof the *bmi-topography* repository.\n\n\u003c!-- skip-docs-link --\u003e\n\nUser and developer documentation for *bmi-topography*\nis available at https://bmi-topography.csdms.io.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsdms%2Fbmi-topography","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcsdms%2Fbmi-topography","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsdms%2Fbmi-topography/lists"}