Overviews (image pyramids)¶
Overviews are down-sampled copies of a raster stored alongside the full-resolution data, so a viewer can read a coarse level when zoomed out instead of the whole array — the pyramid the package is named for.
create_overviews— build the pyramid levels.overview_count— how many levels each band has.get_overview— fetch one level as a GDAL band.
Setup¶
In [1]:
Copied!
%matplotlib inline
import shutil
import tempfile
from pathlib import Path
import numpy as np
DATA = Path('../../../examples/data')
WORK = Path(tempfile.mkdtemp(prefix='pyramids-t2-'))
DATA.is_dir(), WORK.is_dir()
%matplotlib inline
import shutil
import tempfile
from pathlib import Path
import numpy as np
DATA = Path('../../../examples/data')
WORK = Path(tempfile.mkdtemp(prefix='pyramids-t2-'))
DATA.is_dir(), WORK.is_dir()
Out[1]:
(True, True)
In [2]:
Copied!
from pyramids.dataset import Dataset
# Copy to scratch first — create_overviews writes the pyramids into the file.
src = WORK / 'dem.tif'
shutil.copy(DATA / 'dem' / 'DEM5km_Rhine_burned_acc.tif', src)
ds = Dataset.read_file(src)
ds.shape, ds.overview_count
from pyramids.dataset import Dataset
# Copy to scratch first — create_overviews writes the pyramids into the file.
src = WORK / 'dem.tif'
shutil.copy(DATA / 'dem' / 'DEM5km_Rhine_burned_acc.tif', src)
ds = Dataset.read_file(src)
ds.shape, ds.overview_count
2026-07-11 14:41:59 | INFO | pyramids.base.config | Logging is configured.
Out[2]:
((1, 125, 93), [0])
The full-resolution DEM — the base level of the pyramid we are about to build.
In [3]:
Copied!
ds.plot(band=0, title="full resolution (125x93)")
ds.plot(band=0, title="full resolution (125x93)")
Out[3]:
<cleopatra.array_glyph.ArrayGlyph at 0x7f6e3df88ad0>
Build the pyramid — create_overviews¶
Pick a resampling method ('average', 'nearest', 'cubic', …).
In [4]:
Copied!
ds.create_overviews(resampling_method='average')
ds.overview_count # levels per band
ds.create_overviews(resampling_method='average')
ds.overview_count # levels per band
Out[4]:
[7]
Read a level — get_overview¶
Level 0 is the coarsest; each level halves the resolution.
In [5]:
Copied!
ov = ds.get_overview(band=0, overview_index=0)
full = ds.shape
full, '->', (ov.XSize, ov.YSize)
ov = ds.get_overview(band=0, overview_index=0)
full = ds.shape
full, '->', (ov.XSize, ov.YSize)
Out[5]:
((1, 125, 93), '->', (47, 63))
A pyramid level is just a down-sampled copy of the base. Resampling the DEM to the coarsest level's cell size shows what that stored overview looks like — the same terrain, far fewer pixels.
In [6]:
Copied!
coarse = ds.resample(cell_size=ds.cell_size * (ds.shape[1] / ov.YSize))
coarse.plot(band=0, title="coarsest level (resampled view)")
coarse = ds.resample(cell_size=ds.cell_size * (ds.shape[1] / ov.YSize))
coarse.plot(band=0, title="coarsest level (resampled view)")
Out[6]:
<cleopatra.array_glyph.ArrayGlyph at 0x7f6e3e0fa350>
Notes¶
- More levels = faster zoomed-out reads, slightly larger files.
- Cloud Optimized GeoTIFFs bake overviews into the file on write — see the COG tutorial.
- See also: Visualization (the
plot(overview=True)option).