Copernicus DEM — API reference#
Anonymous Copernicus DEM backend subpackage — earthlens.dem.
Background and usage are covered under the other pages in this section
(Introduction, Usage,
Available datasets); this page is the rendered API. The
buckets are public, so there is no auth module.
earthlens.dem
#
Anonymous Copernicus DEM backend.
Fetches raw Copernicus DEM GLO-30 / GLO-90 COG tiles from the public
AWS Open Data buckets — no account, no SDK login, no key. Cropping,
mosaicking, and reprojection are pyramids' job; this package returns
whole 1° tiles as they came from the bucket. See docs/reference/dem/
for the usage guide and the shipped example notebook for a
mosaic-with-pyramids walkthrough.
Catalog
#
Bases: AbstractCatalog
Dataset catalog for the DEM backend.
Reads the bundled dem_data_catalog.yaml (shipped as package data)
and exposes its datasets: block as a map of :class:DEMDataset
rows keyed by dataset key under the inherited :attr:datasets
field, which supplies the cat["cop-dem-glo-30"] /
"cop-dem-glo-30" in cat / len(cat) dict-like surface and the
did-you-mean error for free. Instantiate with no arguments
(Catalog()); :func:model_post_init loads and validates the YAML
in one pass and caches it by (path, mtime).
Attributes:
| Name | Type | Description |
|---|---|---|
datasets |
dict[str, DEMDataset]
|
Map from dataset key to its :class: |
available_datasets |
list[str]
|
Sorted dataset keys — the curated datasets are the whole dataset universe for this backend. |
Examples:
- List datasets and resolve one:
- An unknown key raises with a did-you-mean hint:
Source code in src/earthlens/dem/catalog.py
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | |
get_catalog()
#
Return the dataset map (satisfies the abstract contract).
Returns:
| Type | Description |
|---|---|
dict[str, DEMDataset]
|
dict[str, DEMDataset]: Same object as :attr: |
load(catalog_path=None)
classmethod
#
Read and validate the DEM catalog from disk (cached).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
catalog_path
|
Path | None
|
Path to the catalog YAML. Defaults to the
module-level :data: |
None
|
Returns:
| Type | Description |
|---|---|
Catalog
|
A fully-populated :class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the file has no |
Source code in src/earthlens/dem/catalog.py
model_post_init(__context)
#
Auto-load the bundled catalog when no datasets were supplied.
Catalog() with no args reads :data:CATALOG_PATH (cached by
(path, mtime)); passing datasets=... skips the disk read
(used in tests). Either way the available_datasets index is
derived from the loaded map.
Raises:
| Type | Description |
|---|---|
ValueError
|
Propagated from :meth: |
Source code in src/earthlens/dem/catalog.py
DEM
#
Bases: AbstractDataSource
Anonymous Copernicus DEM backend (raw COG tiles).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
str | None
|
Advisory start date (parsed with |
None
|
end
|
str | None
|
Advisory end date; defaults to |
None
|
variables
|
list[str] | dict[str, list[str]] | None
|
Ignored — a Copernicus DEM tile carries one
elevation band. Kept in the signature for |
None
|
lat_lim
|
list[float] | None
|
|
None
|
lon_lim
|
list[float] | None
|
|
None
|
temporal_resolution
|
str
|
Advisory label; DEM has no time cadence. |
'static'
|
path
|
Path | str
|
Output directory for the downloaded tiles. |
''
|
fmt
|
str
|
|
'%Y-%m-%d'
|
dataset
|
str
|
Catalog key — |
'cop-dem-glo-30'
|
catalog
|
Catalog | None
|
Optional pre-built :class: |
None
|
Examples:
- Plan the tiles a bbox needs without touching the network:
Source code in src/earthlens/dem/backend.py
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | |
__init__(start=None, end=None, variables=None, lat_lim=None, lon_lim=None, temporal_resolution='static', path='', fmt='%Y-%m-%d', *, dataset='cop-dem-glo-30', catalog=None)
#
Initialise a Copernicus DEM backend instance.
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/earthlens/dem/backend.py
download(progress_bar=True, aggregate=None)
#
Fetch every 1° Copernicus DEM tile the bbox intersects.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
progress_bar
|
bool
|
Show a per-tile progress bar. Defaults to
|
True
|
aggregate
|
Any | None
|
Must be |
None
|
Returns:
| Type | Description |
|---|---|
list[Path]
|
list[Path]: The local paths of the downloaded COG tiles, in bbox row-major order. Empty when every candidate tile is absent from the bucket. |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If |
Source code in src/earthlens/dem/backend.py
tiles()
#
Return the 1° tiles the request bbox intersects.
Pure arithmetic on the integer-degree grid — no network access.
Antimeridian-straddling bboxes (lon_min > lon_max) are
rejected at construction; pass the two halves in separate calls
if you need to span the 180th meridian.
Returns:
| Type | Description |
|---|---|
list[Tile]
|
list[Tile]: One tile per SW-corner integer degree pair in the bbox, in row-major (south → north, west → east) order. |
Source code in src/earthlens/dem/backend.py
DEMDataset
#
Bases: BaseModel
One Copernicus DEM dataset row.
A frozen value object that pins the exact S3 bucket, region, and the
resolution token embedded in every tile key (_10_ for GLO-30 or
_30_ for GLO-90 — the tokens Copernicus uses in the object names,
not the pixel size).
Attributes:
| Name | Type | Description |
|---|---|---|
key |
str
|
Dataset key ( |
long_name |
str
|
Human-readable label used in docs and logs. |
bucket |
str
|
Anonymous S3 bucket that holds the tiles. |
region |
str
|
AWS region of the bucket ( |
resolution_token |
str
|
The |
tile_degrees |
int
|
Edge length of one tile in degrees ( |
native_resolution_m |
int
|
Approximate pixel size in metres (30 / 90). |
vertical_datum |
str
|
Vertical datum of the elevation values. |
horizontal_datum |
str
|
Horizontal datum of the tile grid. |
attribution |
str
|
Required attribution string; surfaced in docs. |
description |
str
|
Human-readable summary of the dataset. |
Examples:
- Load the shipped GLO-30 row:
Source code in src/earthlens/dem/catalog.py
earthlens.dem.backend
#
Copernicus DEM backend — anonymous, no account, raw COG tiles.
DEM(AbstractDataSource) fetches Copernicus DEM GLO-30 / GLO-90 tiles
from the anonymous AWS Open Data buckets copernicus-dem-30m and
copernicus-dem-90m. The backend is unusual on two counts:
- Zero credentials. The buckets are public and unsigned; every
other shipped path to a global DEM (
gee,stac,earthdata) requires an account. This backend earns its place by offering Copernicus DEM without one — the wholeG0justification. - No decode. A request downloads the raw 1° x 1° COG GeoTIFF(s) as
shipped by the bucket and returns their
list[Path]. Cropping, reprojecting, and mosaicking are pyramids' job (its COG reader already reads and mosaics COGs). This module does not importrasterio,gdal,osgeo, orxarray.
Request shape: a dataset key ("cop-dem-glo-30" default, or
"cop-dem-glo-90") and a WGS84 bbox (lat_lim, lon_lim). The
backend is time-invariant — the start / end dates are accepted for
the shared AbstractDataSource signature but are advisory only. Ocean
and outside-coverage tiles are absent from the bucket and are logged
and skipped, never fatal (G6).
DEM
#
Bases: AbstractDataSource
Anonymous Copernicus DEM backend (raw COG tiles).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
str | None
|
Advisory start date (parsed with |
None
|
end
|
str | None
|
Advisory end date; defaults to |
None
|
variables
|
list[str] | dict[str, list[str]] | None
|
Ignored — a Copernicus DEM tile carries one
elevation band. Kept in the signature for |
None
|
lat_lim
|
list[float] | None
|
|
None
|
lon_lim
|
list[float] | None
|
|
None
|
temporal_resolution
|
str
|
Advisory label; DEM has no time cadence. |
'static'
|
path
|
Path | str
|
Output directory for the downloaded tiles. |
''
|
fmt
|
str
|
|
'%Y-%m-%d'
|
dataset
|
str
|
Catalog key — |
'cop-dem-glo-30'
|
catalog
|
Catalog | None
|
Optional pre-built :class: |
None
|
Examples:
- Plan the tiles a bbox needs without touching the network:
Source code in src/earthlens/dem/backend.py
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | |
__init__(start=None, end=None, variables=None, lat_lim=None, lon_lim=None, temporal_resolution='static', path='', fmt='%Y-%m-%d', *, dataset='cop-dem-glo-30', catalog=None)
#
Initialise a Copernicus DEM backend instance.
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/earthlens/dem/backend.py
download(progress_bar=True, aggregate=None)
#
Fetch every 1° Copernicus DEM tile the bbox intersects.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
progress_bar
|
bool
|
Show a per-tile progress bar. Defaults to
|
True
|
aggregate
|
Any | None
|
Must be |
None
|
Returns:
| Type | Description |
|---|---|
list[Path]
|
list[Path]: The local paths of the downloaded COG tiles, in bbox row-major order. Empty when every candidate tile is absent from the bucket. |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If |
Source code in src/earthlens/dem/backend.py
tiles()
#
Return the 1° tiles the request bbox intersects.
Pure arithmetic on the integer-degree grid — no network access.
Antimeridian-straddling bboxes (lon_min > lon_max) are
rejected at construction; pass the two halves in separate calls
if you need to span the 180th meridian.
Returns:
| Type | Description |
|---|---|
list[Tile]
|
list[Tile]: One tile per SW-corner integer degree pair in the bbox, in row-major (south → north, west → east) order. |
Source code in src/earthlens/dem/backend.py
earthlens.dem.catalog
#
Dataset catalog for the Copernicus DEM backend.
Hosts :class:Catalog, the pydantic-backed reader for the bundled
dem_data_catalog.yaml. The catalog is a small single-family map from a
dataset key (cop-dem-glo-30, cop-dem-glo-90) to the anonymous S3
bucket, region, and the resolution token that appears in the tile key.
The DEM backend is one-axis: a request picks one dataset key and a bbox; the tile enumeration is arithmetic on the integer-degree grid. There are no variables (a Copernicus DEM tile is one elevation band), so the catalog has no per-variable sub-block.
:data:CATALOG_PATH is the path to the bundled YAML;
:func:clear_catalog_cache empties the (path, mtime) parse cache.
Catalog
#
Bases: AbstractCatalog
Dataset catalog for the DEM backend.
Reads the bundled dem_data_catalog.yaml (shipped as package data)
and exposes its datasets: block as a map of :class:DEMDataset
rows keyed by dataset key under the inherited :attr:datasets
field, which supplies the cat["cop-dem-glo-30"] /
"cop-dem-glo-30" in cat / len(cat) dict-like surface and the
did-you-mean error for free. Instantiate with no arguments
(Catalog()); :func:model_post_init loads and validates the YAML
in one pass and caches it by (path, mtime).
Attributes:
| Name | Type | Description |
|---|---|---|
datasets |
dict[str, DEMDataset]
|
Map from dataset key to its :class: |
available_datasets |
list[str]
|
Sorted dataset keys — the curated datasets are the whole dataset universe for this backend. |
Examples:
- List datasets and resolve one:
- An unknown key raises with a did-you-mean hint:
Source code in src/earthlens/dem/catalog.py
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | |
get_catalog()
#
Return the dataset map (satisfies the abstract contract).
Returns:
| Type | Description |
|---|---|
dict[str, DEMDataset]
|
dict[str, DEMDataset]: Same object as :attr: |
load(catalog_path=None)
classmethod
#
Read and validate the DEM catalog from disk (cached).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
catalog_path
|
Path | None
|
Path to the catalog YAML. Defaults to the
module-level :data: |
None
|
Returns:
| Type | Description |
|---|---|
Catalog
|
A fully-populated :class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the file has no |
Source code in src/earthlens/dem/catalog.py
model_post_init(__context)
#
Auto-load the bundled catalog when no datasets were supplied.
Catalog() with no args reads :data:CATALOG_PATH (cached by
(path, mtime)); passing datasets=... skips the disk read
(used in tests). Either way the available_datasets index is
derived from the loaded map.
Raises:
| Type | Description |
|---|---|
ValueError
|
Propagated from :meth: |
Source code in src/earthlens/dem/catalog.py
DEMDataset
#
Bases: BaseModel
One Copernicus DEM dataset row.
A frozen value object that pins the exact S3 bucket, region, and the
resolution token embedded in every tile key (_10_ for GLO-30 or
_30_ for GLO-90 — the tokens Copernicus uses in the object names,
not the pixel size).
Attributes:
| Name | Type | Description |
|---|---|---|
key |
str
|
Dataset key ( |
long_name |
str
|
Human-readable label used in docs and logs. |
bucket |
str
|
Anonymous S3 bucket that holds the tiles. |
region |
str
|
AWS region of the bucket ( |
resolution_token |
str
|
The |
tile_degrees |
int
|
Edge length of one tile in degrees ( |
native_resolution_m |
int
|
Approximate pixel size in metres (30 / 90). |
vertical_datum |
str
|
Vertical datum of the elevation values. |
horizontal_datum |
str
|
Horizontal datum of the tile grid. |
attribution |
str
|
Required attribution string; surfaced in docs. |
description |
str
|
Human-readable summary of the dataset. |
Examples:
- Load the shipped GLO-30 row:
Source code in src/earthlens/dem/catalog.py
earthlens.dem._helpers
#
Pure tile-key arithmetic for the Copernicus DEM buckets.
The Copernicus DEM COGs live one per 1° x 1° tile on the anonymous AWS
buckets. Every tile is addressed by its SW-corner integer degrees on a
fixed grid, encoded in the object name as N##/S## for latitude
(2-digit) and E###/W### for longitude (3-digit). This module is the
one place that arithmetic lives, so the backend, the tests, and the
gated e2e all resolve a bbox to the same list of tile keys.
Nothing here touches the network — the enumeration is deterministic integer arithmetic.
Tile
dataclass
#
One Copernicus DEM 1° x 1° tile addressed by its SW corner.
Attributes:
| Name | Type | Description |
|---|---|---|
lat |
int
|
SW-corner latitude in integer degrees, in |
lon |
int
|
SW-corner longitude in integer degrees, in |
Examples:
- Nile Delta cell (30 N, 31 E):
Source code in src/earthlens/dem/_helpers.py
bbox_to_tiles(lat_min, lat_max, lon_min, lon_max)
#
Enumerate every 1° tile whose SW corner lies inside the bbox.
Snaps the bbox to the integer-degree tile grid: for each axis the minimum corner is floored and the maximum corner is included up to (and excluding) the ceiling. A bbox that lies entirely inside a single tile still returns that tile. Latitude and longitude values are clamped to the WGS84 grid range.
Antimeridian-straddling bboxes (lon_min > lon_max) are not
supported in this first cut — pass the two halves in separate calls.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lat_min
|
float
|
Southern edge of the bbox in degrees. |
required |
lat_max
|
float
|
Northern edge of the bbox in degrees. |
required |
lon_min
|
float
|
Western edge of the bbox in degrees. |
required |
lon_max
|
float
|
Eastern edge of the bbox in degrees. |
required |
Returns:
| Type | Description |
|---|---|
list[Tile]
|
list[Tile]: Every 1° tile whose SW corner lies within the bbox, in row-major order (south -> north, then west -> east). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
- A single tile bbox:
Source code in src/earthlens/dem/_helpers.py
tile_key(tile, resolution_token)
#
Return the bucket-relative object key for the tile's DEM COG.
A tile directory in the bucket carries the DEM .tif at
<name>/<name>.tif plus a set of sidecars (AUXFILES/,
PREVIEW/, INFO/) that the DEM backend deliberately ignores.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tile
|
Tile
|
The tile addressed by its SW-corner integer degrees. |
required |
resolution_token
|
str
|
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The bucket-relative key to the DEM COG. |
Examples:
- GLO-30 Nile Delta:
Source code in src/earthlens/dem/_helpers.py
tile_name(tile, resolution_token)
#
Return the tile identifier (also the top-level bucket "folder").
The identifier follows the Copernicus naming convention verified
against the live buckets:
Copernicus_DSM_COG_{token}_{LAT}_00_{LON}_00_DEM, where the
_00_ markers are the arc-minute portion of the corner (always
00 on the 1° grid).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tile
|
Tile
|
The tile addressed by its SW-corner integer degrees. |
required |
resolution_token
|
str
|
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The tile identifier without a trailing suffix. |
Examples:
- GLO-30 Nile Delta (30 N, 31 E):