Glaciers — API reference#
Glacier outlines / fluctuations backend subpackage — earthlens.glaciers.
Background and usage are covered under the other pages in this section
(Introduction, Usage,
Available datasets); this page is the rendered API. All three
sources are open, so the backend ships no auth module; vector file I/O goes
through pyramids FeatureCollection.read_file and the WGMS path is pure pandas.
earthlens.glaciers
#
Glacier data backend (earthlens.glaciers).
One mixed backend over three open glacier sources:
- RGI 7.0 (Randolph Glacier Inventory) — global glacier outlines, one
shapefile per GTN-G first-order region, served openly by UNESCO IHP-WINS; the
backend maps the request bbox to the overlapping region(s), downloads + caches
each region ZIP, reads it via pyramids
FeatureCollection.read_file, and clips to the bbox;vector. - GLIMS (Global Land Ice Measurements from Space) — time-series glacier
outlines, queried by bbox through the open GLIMS GeoServer WFS;
vector. - WGMS — Fluctuations of Glaciers database (mass balance, front variation /
length change, glacier state) as tabular CSV tables;
tabular.
Output is per instance: a dataset's output_kind decides whether
:meth:~earthlens.glaciers.backend.Glaciers.download returns a pyramids
:class:~pyramids.feature.collection.FeatureCollection (vector, rgi/glims) or
a :class:pandas.DataFrame (tabular, wgms). All three sources are open, so the
backend ships no auth. Vector file I/O always goes through pyramids
FeatureCollection.read_file — never a bare geopandas file read — and the WGMS
path is pure pandas with no array/NetCDF stack.
The public surface is the :class:Catalog (dataset id -> source + output kind +
request detail, plus the GTN-G :class:Region table) and its :class:Dataset
rows, the backend :class:Glaciers, and the stateless query/read helpers.
Catalog
#
Bases: AbstractCatalog
Dataset + region catalog for the glaciers backend.
Reads the bundled sharded catalog/ directory (shipped as package data) and
exposes its datasets: blocks as a map of :class:Dataset rows keyed by id,
plus the GTN-G regions: table as a map of :class:Region rows.
Instantiate with no arguments (Catalog()). Resolve one row with
:meth:get, list the shipped ids with :meth:available, and read the region
table via :attr:regions.
Attributes:
| Name | Type | Description |
|---|---|---|
datasets |
dict[str, Dataset]
|
Map from dataset id to its :class: |
regions |
dict[str, Region]
|
Map from GTN-G region id to its :class: |
Examples:
- Resolve rows and a region:
- An unknown but close id raises with a did-you-mean hint:
Source code in src/earthlens/glaciers/catalog.py
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 | |
available()
#
Return the sorted list of shipped dataset ids.
Returns:
| Type | Description |
|---|---|
list[str]
|
list[str]: Every catalog key, sorted. |
get(dataset_id)
#
Resolve a dataset id to its :class:Dataset row.
Thin wrapper over the inherited :meth:get_dataset, which raises a
ValueError with a did-you-mean hint on an unknown id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset_id
|
str
|
A shipped dataset id ( |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Dataset |
Dataset
|
The matching catalog row. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/earthlens/glaciers/catalog.py
get_catalog()
#
Return the dataset map (satisfies the abstract contract).
Returns:
| Type | Description |
|---|---|
dict[str, Dataset]
|
dict[str, Dataset]: Same object as :attr: |
load(catalog_path=None)
classmethod
#
Read the glaciers catalog from disk.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
catalog_path
|
Path | None
|
Path to the catalog directory or a single YAML.
Defaults to the module-level :data: |
None
|
Returns:
| Type | Description |
|---|---|
Catalog
|
A fully-populated :class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the catalog has no |
Source code in src/earthlens/glaciers/catalog.py
model_post_init(__context)
#
Auto-load the bundled catalog when no rows were supplied.
Catalog() with no args reads :data:CATALOG_PATH; passing
datasets=... skips the disk read.
Raises:
| Type | Description |
|---|---|
ValueError
|
Propagated from :meth: |
Source code in src/earthlens/glaciers/catalog.py
Dataset
#
Bases: BaseModel
One glaciers catalog row.
The dataset id is the parent key in :attr:Catalog.datasets and is also
stored on the row as :attr:id so a resolved :class:Dataset is
self-describing. Which source-specific fields are populated depends on
:attr:source; a cross-field validator enforces that the right ones are
present.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
The dataset id ( |
source |
Source
|
Which source serves it — |
output_kind |
OutputKind
|
|
long_name |
str
|
Human-readable label. |
citation |
str
|
The source's citation string, logged once on use. |
table |
str | None
|
WGMS only — the CSV table name inside the FoG zip
( |
archive_url |
str | None
|
WGMS only — the FoG database zip download URL. |
wfs_url |
str | None
|
GLIMS only — the GeoServer WFS endpoint URL. |
wfs_typename |
str | None
|
GLIMS only — the WFS feature-type name. |
Examples:
- Build an RGI row directly:
Source code in src/earthlens/glaciers/catalog.py
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 | |
Glaciers
#
Bases: AbstractDataSource
Glacier outlines / fluctuations backend (mixed output).
Resolves one dataset id to its catalog row, routes the request to that row's
source (RGI / GLIMS / WGMS), and returns a pyramids
:class:~pyramids.feature.collection.FeatureCollection (vector) or a
:class:pandas.DataFrame (tabular) per the row's output_kind. The query
is a search/fetch split: :meth:_search pins the products (one per
overlapping RGI region, or a single GLIMS / WGMS product) and :meth:_fetch
downloads + reads each.
All three sources are open, so the backend needs no credentials. aggregate=
is rejected — outlines / fluctuations are pre-computed inventories, not
gridded rasters (G8).
Attributes:
| Name | Type | Description |
|---|---|---|
OUTPUT_KIND |
OutputKind
|
Set per instance in :meth: |
Source code in src/earthlens/glaciers/backend.py
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 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | |
__init__(start=None, end=None, variables=None, lat_lim=None, lon_lim=None, temporal_resolution='annual', path='', fmt='%Y-%m-%d', region=None, max_features=10000, glacier_id=None, glacier_name=None, output_format='csv')
#
Initialise a glaciers backend instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
str | None
|
Inclusive start of an optional window, parsed with |
None
|
end
|
str | None
|
Inclusive end of the optional window; |
None
|
variables
|
list[str] | None
|
A one-element list naming the dataset id
( |
None
|
lat_lim
|
list[float] | None
|
|
None
|
lon_lim
|
list[float] | None
|
|
None
|
temporal_resolution
|
str
|
Recorded as the resolution label only. |
'annual'
|
path
|
Path | str
|
Output directory; also the parent of the download cache. |
''
|
fmt
|
str
|
|
'%Y-%m-%d'
|
region
|
str | list[str] | None
|
RGI only — one GTN-G region id ( |
None
|
max_features
|
int
|
GLIMS only — cap on WFS-returned features. |
10000
|
glacier_id
|
int | str | list | None
|
WGMS only — one glacier id or a list to filter on. |
None
|
glacier_name
|
str | None
|
WGMS only — a case-insensitive substring filter. |
None
|
output_format
|
OutputFormat
|
On-disk format for a written WGMS result — |
'csv'
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
If |
Source code in src/earthlens/glaciers/backend.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 | |
download(progress_bar=True, aggregate=None)
#
Fetch the dataset and return its per-instance shape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
progress_bar
|
bool
|
Accepted for signature parity; the per-region RGI fetch is a small loop, so this is a no-op. |
True
|
aggregate
|
AggregationConfig | None
|
Must be |
None
|
Returns:
| Type | Description |
|---|---|
|
A pyramids :class: |
|
|
( |
|
|
class: |
|
|
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If |
HTTPError
|
If a download / WFS query fails after retries. |
Source code in src/earthlens/glaciers/backend.py
Region
#
Bases: BaseModel
One GTN-G first-order region row (RGI per-region download metadata).
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
The two-digit GTN-G region id ( |
name |
str
|
The region's full name ( |
bboxes |
list[list[float]]
|
One or more |
url |
str
|
The full IHP-WINS resource download URL for this region's outline shapefile zip. |
Examples:
- A region's corners and download URL:
Source code in src/earthlens/glaciers/catalog.py
concat_outlines(fragments)
#
Merge per-region outline fragments into one collection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fragments
|
list[FeatureCollection]
|
One :class: |
required |
Returns:
| Name | Type | Description |
|---|---|---|
FeatureCollection |
FeatureCollection
|
The concatenated collection in EPSG:4326. The first non-empty fragment when only one carries features; an empty collection when every fragment is empty. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/earthlens/glaciers/_helpers.py
download_zip(url, dest_dir, *, session=None, retries=3, backoff=2.0, timeout=180.0, chunk_size=1 << 20)
#
Stream a .zip to dest_dir and return the local path (idempotent).
The glaciers vector / tabular paths read inside the zip (RGI via
/vsizip/, WGMS via pandas), so — unlike the ghsl raster path — the archive
is kept, not extracted. If the file already exists it is returned without
re-downloading. Retries transient HTTP failures with exponential backoff.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
The |
required |
dest_dir
|
Path
|
Directory to cache into (created if absent). |
required |
session
|
Session | None
|
Optional shared |
None
|
retries
|
int
|
Number of attempts before giving up. |
3
|
backoff
|
float
|
Base seconds for exponential backoff between retries. |
2.0
|
timeout
|
float
|
Per-request timeout in seconds. |
180.0
|
chunk_size
|
int
|
Streaming chunk size in bytes. |
1 << 20
|
Returns:
| Type | Description |
|---|---|
Path
|
pathlib.Path: The cached local |
Raises:
| Type | Description |
|---|---|
HTTPError
|
If every attempt fails (the last error is raised). |
Source code in src/earthlens/glaciers/_helpers.py
empty_canonical(columns)
#
Build a schema-only (zero-row) frame with the given columns.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
columns
|
list[str]
|
The column names to materialise. |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
pandas.DataFrame: An empty frame carrying exactly |
Source code in src/earthlens/glaciers/_helpers.py
empty_feature_collection()
#
Build an empty EPSG:4326 :class:FeatureCollection (no features).
Returned by the vector path when a request's bbox overlaps no glacier
region / matches no outline, so download() always yields a collection.
Returns:
| Name | Type | Description |
|---|---|---|
FeatureCollection |
FeatureCollection
|
A zero-feature collection in EPSG:4326. |
Source code in src/earthlens/glaciers/_helpers.py
fetch_glims(wfs_url, typename, bbox, dest_path, *, max_features=10000, session=None, timeout=120.0)
#
Query the GLIMS WFS for a bbox, save the GeoJSON, read + clip it (G3).
Issues a WFS GetFeature bbox query, writes the GeoJSON response to
dest_path, reads it via pyramids FeatureCollection.read_file (not a bare
geopandas file read), and clips to the bbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
wfs_url
|
str
|
The GLIMS GeoServer WFS endpoint. |
required |
typename
|
str
|
The WFS feature-type name. |
required |
bbox
|
list[float]
|
|
required |
dest_path
|
Path
|
Local path to write the GeoJSON cache file. |
required |
max_features
|
int
|
Cap on returned features (the WFS |
10000
|
session
|
Session | None
|
Optional shared |
None
|
timeout
|
float
|
Per-request timeout in seconds. |
120.0
|
Returns:
| Name | Type | Description |
|---|---|---|
FeatureCollection |
FeatureCollection
|
GLIMS outline polygons intersecting the bbox, in EPSG:4326. Empty when the query matched nothing. |
Raises:
| Type | Description |
|---|---|
HTTPError
|
If the WFS returns a non-2xx status. |
Source code in src/earthlens/glaciers/_helpers.py
filter_wgms(df, glaciers=None, *, glacier_id=None, glacier_name=None, region=None, bbox=None)
#
Filter a WGMS fluctuations table by glacier / region / bbox.
glacier_id and glacier_name match the table directly; region and
bbox need the glacier join table (its id == the table's glacier_id,
its gtng_region is id-prefixed like "11_central_europe", and it carries
latitude / longitude).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
A fluctuations table with a |
required |
glaciers
|
DataFrame | None
|
The |
None
|
glacier_id
|
Any
|
One id or a list of ids (matched against |
None
|
glacier_name
|
str | None
|
A case-insensitive substring matched against
|
None
|
region
|
Any
|
One GTN-G region id ( |
None
|
bbox
|
list[float] | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
pandas.DataFrame: The filtered rows, with a reset index. |
Source code in src/earthlens/glaciers/_helpers.py
glims_wfs_url(wfs_url, typename, bbox, max_features)
#
Build the GLIMS WFS GetFeature request (URL + params) for a bbox query.
Axis-order landmine: with the URN CRS urn:ogc:def:crs:EPSG::4326 the WFS
bbox is south,west,north,east (lat,lon); a plain EPSG:4326 srs returns
nothing. This builds the URN form.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
wfs_url
|
str
|
The GLIMS GeoServer WFS endpoint. |
required |
typename
|
str
|
The WFS feature-type name
( |
required |
bbox
|
list[float]
|
|
required |
max_features
|
int
|
Cap on returned features (the WFS |
required |
Returns:
| Type | Description |
|---|---|
tuple[str, dict[str, Any]]
|
A |
Source code in src/earthlens/glaciers/_helpers.py
parse_wgms_csv(zip_path, table)
#
Read one WGMS FoG table out of the cached zip (G8).
The FoG tables are already long-format (glacier_id / year-or-date /
value), so this is a plain pandas.read_csv of the data/<table>.csv
member — no reshaping, no array/NetCDF stack.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zip_path
|
Path
|
The cached WGMS FoG |
required |
table
|
str
|
The table name ( |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
pandas.DataFrame: The table rows. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the zip has no |
Source code in src/earthlens/glaciers/_helpers.py
read_outlines(zip_path, bbox, inner_shp=None)
#
Read RGI outlines from a cached region zip and clip to the bbox (G3/G4).
Reads the shapefile inside the region ZIP via pyramids
FeatureCollection.read_file("/vsizip/<zip>/<shp>") — never a bare geopandas
file read (porting policy) — reprojects to EPSG:4326 if needed, and clips to
the bbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zip_path
|
Path
|
The local RGI region |
required |
bbox
|
list[float]
|
|
required |
inner_shp
|
str | None
|
The inner |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
FeatureCollection |
FeatureCollection
|
Glacier-outline polygons intersecting the bbox, in EPSG:4326. |
Source code in src/earthlens/glaciers/_helpers.py
regions_for_bbox(bbox, regions)
#
Map a request bbox to the overlapping GTN-G region id(s) (G6).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bbox
|
list[float]
|
The request AOI as |
required |
regions
|
dict[str, Any]
|
The catalog region map (id -> a row exposing |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
list[str]: The sorted ids of every region with a bbox intersecting the AOI. Empty when the AOI overlaps no glacier region. |
Source code in src/earthlens/glaciers/_helpers.py
shapely_bbox(space)
#
Build the AOI box a SpatialExtent does not carry (G4).
SpatialExtent exposes only north / south / east / west, so the
bbox intersect-filter needs this small adapter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
space
|
SpatialExtent
|
The request's :class: |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A |
Source code in src/earthlens/glaciers/_helpers.py
wgms_glacier_table(zip_path)
#
Read the WGMS glacier join table (coordinates + region) from the zip.
The glacier table carries id (== the other tables' glacier_id),
latitude / longitude, and gtng_region, so it is the key for a
region / bbox filter over a fluctuations table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zip_path
|
Path
|
The cached WGMS FoG |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
pandas.DataFrame: The |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the zip has no |
Source code in src/earthlens/glaciers/_helpers.py
earthlens.glaciers.backend
#
Backend that fetches glacier outlines / fluctuations from three open sources.
Glaciers(AbstractDataSource) routes one request to whichever of three open
glacier sources the chosen dataset names — RGI 7.0 (per-region outline
shapefiles via UNESCO IHP-WINS), GLIMS (time-series outlines via the GLIMS
GeoServer WFS), or WGMS (Fluctuations of Glaciers tabular CSV tables) — and
returns the result in the shape that dataset declares. A request is one dataset
id (variables=["rgi:outlines"]) plus a bbox (rgi/glims) or an optional
glacier / region selector (wgms).
Three design points carry this backend:
- Per-instance
OUTPUT_KIND(G1). The resolved dataset'soutput_kindis copied ontoself.OUTPUT_KINDin__init__:vectorreturns a pyramids :class:~pyramids.feature.collection.FeatureCollection(rgi/glims outlines),tabularreturns a :class:pandas.DataFrame(wgms fluctuations). The :class:earthlens.earthlens.EarthLensfacade reads the instance attribute to gateaggregate=(rejected for both) and to know the return shape. - Region-download-then-clip (
G6). RGI ships per GTN-G region; the backend maps the request bbox to the overlapping region(s) (aregion=override is accepted), downloads + caches each region ZIP once (the ghsl model), reads it via pyramidsFeatureCollection.read_file, clips to the bbox, and merges. - No auth (
G5). All three sources are open, so the backend ships no auth module and never touches the Earthdata-gated NSIDC host.
Outlines / fluctuations are pre-computed inventories, so aggregate= is rejected
(G8), vector file I/O always goes through pyramids (G3), and the WGMS path is
pure pandas.
Glaciers
#
Bases: AbstractDataSource
Glacier outlines / fluctuations backend (mixed output).
Resolves one dataset id to its catalog row, routes the request to that row's
source (RGI / GLIMS / WGMS), and returns a pyramids
:class:~pyramids.feature.collection.FeatureCollection (vector) or a
:class:pandas.DataFrame (tabular) per the row's output_kind. The query
is a search/fetch split: :meth:_search pins the products (one per
overlapping RGI region, or a single GLIMS / WGMS product) and :meth:_fetch
downloads + reads each.
All three sources are open, so the backend needs no credentials. aggregate=
is rejected — outlines / fluctuations are pre-computed inventories, not
gridded rasters (G8).
Attributes:
| Name | Type | Description |
|---|---|---|
OUTPUT_KIND |
OutputKind
|
Set per instance in :meth: |
Source code in src/earthlens/glaciers/backend.py
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 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | |
__init__(start=None, end=None, variables=None, lat_lim=None, lon_lim=None, temporal_resolution='annual', path='', fmt='%Y-%m-%d', region=None, max_features=10000, glacier_id=None, glacier_name=None, output_format='csv')
#
Initialise a glaciers backend instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
str | None
|
Inclusive start of an optional window, parsed with |
None
|
end
|
str | None
|
Inclusive end of the optional window; |
None
|
variables
|
list[str] | None
|
A one-element list naming the dataset id
( |
None
|
lat_lim
|
list[float] | None
|
|
None
|
lon_lim
|
list[float] | None
|
|
None
|
temporal_resolution
|
str
|
Recorded as the resolution label only. |
'annual'
|
path
|
Path | str
|
Output directory; also the parent of the download cache. |
''
|
fmt
|
str
|
|
'%Y-%m-%d'
|
region
|
str | list[str] | None
|
RGI only — one GTN-G region id ( |
None
|
max_features
|
int
|
GLIMS only — cap on WFS-returned features. |
10000
|
glacier_id
|
int | str | list | None
|
WGMS only — one glacier id or a list to filter on. |
None
|
glacier_name
|
str | None
|
WGMS only — a case-insensitive substring filter. |
None
|
output_format
|
OutputFormat
|
On-disk format for a written WGMS result — |
'csv'
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
If |
Source code in src/earthlens/glaciers/backend.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 | |
download(progress_bar=True, aggregate=None)
#
Fetch the dataset and return its per-instance shape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
progress_bar
|
bool
|
Accepted for signature parity; the per-region RGI fetch is a small loop, so this is a no-op. |
True
|
aggregate
|
AggregationConfig | None
|
Must be |
None
|
Returns:
| Type | Description |
|---|---|
|
A pyramids :class: |
|
|
( |
|
|
class: |
|
|
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If |
HTTPError
|
If a download / WFS query fails after retries. |
Source code in src/earthlens/glaciers/backend.py
earthlens.glaciers.catalog
#
Dataset + GTN-G region catalog for the glaciers backend.
The glaciers backend routes a request to one of three open glacier sources —
the Randolph Glacier Inventory 7.0 (rgi, per-region outline shapefiles), the
GLIMS time-series outline database (glims, WFS bbox query), and the WGMS
Fluctuations of Glaciers database (wgms, tabular CSV tables). This module is
the bridge from a dataset id ("rgi:outlines", "glims:outlines",
"wgms:mass_balance", …) to its source, output kind, and the source-specific
request detail needed to fetch it.
:class:Catalog is a thin :class:earthlens.base.AbstractCatalog subclass that
loads the bundled sharded catalog/ directory (rgi.yaml / glims.yaml /
wgms.yaml + _index.yaml) and exposes each row as a :class:Dataset. The
rgi.yaml file also ships a regions: block — the GTN-G first-order region
table (id → name + bbox(es) + per-region download URL) that drives the
bbox → region(s) mapping — exposed as :attr:Catalog.regions of
:class:Region rows. Resolve one dataset with :meth:Catalog.get (a
did-you-mean hint on an unknown id); list the shipped ids with
:meth:Catalog.available.
:data:CATALOG_PATH is the path to the bundled catalog/ directory; tests may
monkey-patch it at a temporary directory or a single YAML file.
Catalog
#
Bases: AbstractCatalog
Dataset + region catalog for the glaciers backend.
Reads the bundled sharded catalog/ directory (shipped as package data) and
exposes its datasets: blocks as a map of :class:Dataset rows keyed by id,
plus the GTN-G regions: table as a map of :class:Region rows.
Instantiate with no arguments (Catalog()). Resolve one row with
:meth:get, list the shipped ids with :meth:available, and read the region
table via :attr:regions.
Attributes:
| Name | Type | Description |
|---|---|---|
datasets |
dict[str, Dataset]
|
Map from dataset id to its :class: |
regions |
dict[str, Region]
|
Map from GTN-G region id to its :class: |
Examples:
- Resolve rows and a region:
- An unknown but close id raises with a did-you-mean hint:
Source code in src/earthlens/glaciers/catalog.py
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 | |
available()
#
Return the sorted list of shipped dataset ids.
Returns:
| Type | Description |
|---|---|
list[str]
|
list[str]: Every catalog key, sorted. |
get(dataset_id)
#
Resolve a dataset id to its :class:Dataset row.
Thin wrapper over the inherited :meth:get_dataset, which raises a
ValueError with a did-you-mean hint on an unknown id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset_id
|
str
|
A shipped dataset id ( |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Dataset |
Dataset
|
The matching catalog row. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/earthlens/glaciers/catalog.py
get_catalog()
#
Return the dataset map (satisfies the abstract contract).
Returns:
| Type | Description |
|---|---|
dict[str, Dataset]
|
dict[str, Dataset]: Same object as :attr: |
load(catalog_path=None)
classmethod
#
Read the glaciers catalog from disk.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
catalog_path
|
Path | None
|
Path to the catalog directory or a single YAML.
Defaults to the module-level :data: |
None
|
Returns:
| Type | Description |
|---|---|
Catalog
|
A fully-populated :class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the catalog has no |
Source code in src/earthlens/glaciers/catalog.py
model_post_init(__context)
#
Auto-load the bundled catalog when no rows were supplied.
Catalog() with no args reads :data:CATALOG_PATH; passing
datasets=... skips the disk read.
Raises:
| Type | Description |
|---|---|
ValueError
|
Propagated from :meth: |
Source code in src/earthlens/glaciers/catalog.py
Dataset
#
Bases: BaseModel
One glaciers catalog row.
The dataset id is the parent key in :attr:Catalog.datasets and is also
stored on the row as :attr:id so a resolved :class:Dataset is
self-describing. Which source-specific fields are populated depends on
:attr:source; a cross-field validator enforces that the right ones are
present.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
The dataset id ( |
source |
Source
|
Which source serves it — |
output_kind |
OutputKind
|
|
long_name |
str
|
Human-readable label. |
citation |
str
|
The source's citation string, logged once on use. |
table |
str | None
|
WGMS only — the CSV table name inside the FoG zip
( |
archive_url |
str | None
|
WGMS only — the FoG database zip download URL. |
wfs_url |
str | None
|
GLIMS only — the GeoServer WFS endpoint URL. |
wfs_typename |
str | None
|
GLIMS only — the WFS feature-type name. |
Examples:
- Build an RGI row directly:
Source code in src/earthlens/glaciers/catalog.py
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 | |
Region
#
Bases: BaseModel
One GTN-G first-order region row (RGI per-region download metadata).
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
The two-digit GTN-G region id ( |
name |
str
|
The region's full name ( |
bboxes |
list[list[float]]
|
One or more |
url |
str
|
The full IHP-WINS resource download URL for this region's outline shapefile zip. |
Examples:
- A region's corners and download URL:
Source code in src/earthlens/glaciers/catalog.py
clear_catalog_cache()
#
Empty the module-level catalog parse cache.
Useful in tests that rewrite the catalog on disk and want to force a
re-parse. Production callers do not need this — the cache keys include every
contributing file's st_mtime_ns, so any real file mutation invalidates the
entry on its own.
Source code in src/earthlens/glaciers/catalog.py
earthlens.glaciers._helpers
#
Stateless helpers for the glaciers backend.
Grouped by source:
- Spatial / region mapping — :func:
shapely_bboxbuilds the AOI box thatSpatialExtentdoes not carry, and :func:regions_for_bboxmaps a request bbox to the overlapping GTN-G region id(s) (G4/G6). - Vector read (rgi/glims) — :func:
download_zipcaches a region ZIP the ghsl way; :func:read_outlinesreads the inner shapefile via pyramidsFeatureCollection.read_file("/vsizip/<zip>/<shp>")and clips it to the bbox; :func:fetch_glimsissues a GLIMS WFS bbox query, saves the GeoJSON, reads it viaFeatureCollection.read_file, and clips. Vector file I/O always goes through pyramids — never a bare geopandas file read (G3). :func:concat_outlinesmerges per-region fragments. - Tabular read (wgms) — :func:
parse_wgms_csvreads one FoG table out of the cached zip with pandas (G8); :func:wgms_glacier_tablereads theglacierjoin table (coordinates + region); :func:empty_canonicalbuilds a schema-only frame. Pure pandas — no array/NetCDF stack.
concat_outlines(fragments)
#
Merge per-region outline fragments into one collection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fragments
|
list[FeatureCollection]
|
One :class: |
required |
Returns:
| Name | Type | Description |
|---|---|---|
FeatureCollection |
FeatureCollection
|
The concatenated collection in EPSG:4326. The first non-empty fragment when only one carries features; an empty collection when every fragment is empty. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/earthlens/glaciers/_helpers.py
download_zip(url, dest_dir, *, session=None, retries=3, backoff=2.0, timeout=180.0, chunk_size=1 << 20)
#
Stream a .zip to dest_dir and return the local path (idempotent).
The glaciers vector / tabular paths read inside the zip (RGI via
/vsizip/, WGMS via pandas), so — unlike the ghsl raster path — the archive
is kept, not extracted. If the file already exists it is returned without
re-downloading. Retries transient HTTP failures with exponential backoff.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
The |
required |
dest_dir
|
Path
|
Directory to cache into (created if absent). |
required |
session
|
Session | None
|
Optional shared |
None
|
retries
|
int
|
Number of attempts before giving up. |
3
|
backoff
|
float
|
Base seconds for exponential backoff between retries. |
2.0
|
timeout
|
float
|
Per-request timeout in seconds. |
180.0
|
chunk_size
|
int
|
Streaming chunk size in bytes. |
1 << 20
|
Returns:
| Type | Description |
|---|---|
Path
|
pathlib.Path: The cached local |
Raises:
| Type | Description |
|---|---|
HTTPError
|
If every attempt fails (the last error is raised). |
Source code in src/earthlens/glaciers/_helpers.py
empty_canonical(columns)
#
Build a schema-only (zero-row) frame with the given columns.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
columns
|
list[str]
|
The column names to materialise. |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
pandas.DataFrame: An empty frame carrying exactly |
Source code in src/earthlens/glaciers/_helpers.py
empty_feature_collection()
#
Build an empty EPSG:4326 :class:FeatureCollection (no features).
Returned by the vector path when a request's bbox overlaps no glacier
region / matches no outline, so download() always yields a collection.
Returns:
| Name | Type | Description |
|---|---|---|
FeatureCollection |
FeatureCollection
|
A zero-feature collection in EPSG:4326. |
Source code in src/earthlens/glaciers/_helpers.py
fetch_glims(wfs_url, typename, bbox, dest_path, *, max_features=10000, session=None, timeout=120.0)
#
Query the GLIMS WFS for a bbox, save the GeoJSON, read + clip it (G3).
Issues a WFS GetFeature bbox query, writes the GeoJSON response to
dest_path, reads it via pyramids FeatureCollection.read_file (not a bare
geopandas file read), and clips to the bbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
wfs_url
|
str
|
The GLIMS GeoServer WFS endpoint. |
required |
typename
|
str
|
The WFS feature-type name. |
required |
bbox
|
list[float]
|
|
required |
dest_path
|
Path
|
Local path to write the GeoJSON cache file. |
required |
max_features
|
int
|
Cap on returned features (the WFS |
10000
|
session
|
Session | None
|
Optional shared |
None
|
timeout
|
float
|
Per-request timeout in seconds. |
120.0
|
Returns:
| Name | Type | Description |
|---|---|---|
FeatureCollection |
FeatureCollection
|
GLIMS outline polygons intersecting the bbox, in EPSG:4326. Empty when the query matched nothing. |
Raises:
| Type | Description |
|---|---|
HTTPError
|
If the WFS returns a non-2xx status. |
Source code in src/earthlens/glaciers/_helpers.py
filter_wgms(df, glaciers=None, *, glacier_id=None, glacier_name=None, region=None, bbox=None)
#
Filter a WGMS fluctuations table by glacier / region / bbox.
glacier_id and glacier_name match the table directly; region and
bbox need the glacier join table (its id == the table's glacier_id,
its gtng_region is id-prefixed like "11_central_europe", and it carries
latitude / longitude).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
A fluctuations table with a |
required |
glaciers
|
DataFrame | None
|
The |
None
|
glacier_id
|
Any
|
One id or a list of ids (matched against |
None
|
glacier_name
|
str | None
|
A case-insensitive substring matched against
|
None
|
region
|
Any
|
One GTN-G region id ( |
None
|
bbox
|
list[float] | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
pandas.DataFrame: The filtered rows, with a reset index. |
Source code in src/earthlens/glaciers/_helpers.py
glims_wfs_url(wfs_url, typename, bbox, max_features)
#
Build the GLIMS WFS GetFeature request (URL + params) for a bbox query.
Axis-order landmine: with the URN CRS urn:ogc:def:crs:EPSG::4326 the WFS
bbox is south,west,north,east (lat,lon); a plain EPSG:4326 srs returns
nothing. This builds the URN form.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
wfs_url
|
str
|
The GLIMS GeoServer WFS endpoint. |
required |
typename
|
str
|
The WFS feature-type name
( |
required |
bbox
|
list[float]
|
|
required |
max_features
|
int
|
Cap on returned features (the WFS |
required |
Returns:
| Type | Description |
|---|---|
tuple[str, dict[str, Any]]
|
A |
Source code in src/earthlens/glaciers/_helpers.py
parse_wgms_csv(zip_path, table)
#
Read one WGMS FoG table out of the cached zip (G8).
The FoG tables are already long-format (glacier_id / year-or-date /
value), so this is a plain pandas.read_csv of the data/<table>.csv
member — no reshaping, no array/NetCDF stack.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zip_path
|
Path
|
The cached WGMS FoG |
required |
table
|
str
|
The table name ( |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
pandas.DataFrame: The table rows. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the zip has no |
Source code in src/earthlens/glaciers/_helpers.py
read_outlines(zip_path, bbox, inner_shp=None)
#
Read RGI outlines from a cached region zip and clip to the bbox (G3/G4).
Reads the shapefile inside the region ZIP via pyramids
FeatureCollection.read_file("/vsizip/<zip>/<shp>") — never a bare geopandas
file read (porting policy) — reprojects to EPSG:4326 if needed, and clips to
the bbox.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zip_path
|
Path
|
The local RGI region |
required |
bbox
|
list[float]
|
|
required |
inner_shp
|
str | None
|
The inner |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
FeatureCollection |
FeatureCollection
|
Glacier-outline polygons intersecting the bbox, in EPSG:4326. |
Source code in src/earthlens/glaciers/_helpers.py
regions_for_bbox(bbox, regions)
#
Map a request bbox to the overlapping GTN-G region id(s) (G6).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bbox
|
list[float]
|
The request AOI as |
required |
regions
|
dict[str, Any]
|
The catalog region map (id -> a row exposing |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
list[str]: The sorted ids of every region with a bbox intersecting the AOI. Empty when the AOI overlaps no glacier region. |
Source code in src/earthlens/glaciers/_helpers.py
shapely_bbox(space)
#
Build the AOI box a SpatialExtent does not carry (G4).
SpatialExtent exposes only north / south / east / west, so the
bbox intersect-filter needs this small adapter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
space
|
SpatialExtent
|
The request's :class: |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A |
Source code in src/earthlens/glaciers/_helpers.py
wgms_glacier_table(zip_path)
#
Read the WGMS glacier join table (coordinates + region) from the zip.
The glacier table carries id (== the other tables' glacier_id),
latitude / longitude, and gtng_region, so it is the key for a
region / bbox filter over a fluctuations table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zip_path
|
Path
|
The cached WGMS FoG |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
pandas.DataFrame: The |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the zip has no |