
Build a lazy dataset from a STAC source table or raster file(s).
lazy_dataset.RdThe one way into any source. Two input forms:
Usage
lazy_dataset(
sources,
grid = NULL,
assets = NULL,
mask_asset = NULL,
granularity = "day",
sort_field = "datetime",
nodata = NULL,
lon = NULL,
resampling = "near",
scale = FALSE,
offset = NULL,
bands = NULL,
decode = NULL,
time = NULL
)Arguments
- sources
A STAC
doc_items(fromstac_query(), optionally filtered), astac_sources()table, or a character path / vector of paths to (multi-band) raster file(s) – local,/vsicurl/, or barehttp(s)://(prefixed automatically).- grid
Target
GridSpec()for every band. Required for the table form;NULL(the default) keeps the file form on its native grid.- assets
Character vector of value assets to load (table form), or of band names to select (file form, when the file carries band descriptions).
- mask_asset
Optional QA/mask asset (e.g.
"Fmask","SCL"); loaded alongside the value assets and used as the defaultfrominapply_mask().- granularity
Time-slice granularity (see
stac_time_slices()).- sort_field
Index field ordering overlaps within a slice.
- nodata
Nodata handling:
NULL(per-band file metadata), a scalar (applied to every asset), or a named numeric keyed by dataset band name or by asset (a band name wins; unnamed bands fall back to file metadata). An asset key covers every band of a multi-band asset. Reflectance and QA bands usually need different sentinels, so the named form is typical, e.g.c(B04 = -9999, B03 = -9999, Fmask = 255).- lon
Longitude for
granularity = "solar_day"(seestac_time_slices()).- resampling
GDAL resampling for the warp-on-read onto
grid: a scalar (every value band) or a named character keyed by dataset band name or by asset, as fornodata(unnamed bands fall back to"near").mask_assetis always read"near"regardless, since interpolating packed QA bits corrupts them."near"(the default) preserves exact source values; use"bilinear","average","cubic", ... to interpolate. Resample after the fact instead withalign_to().- scale
Apply each value band's scale/offset at read.
FALSE(default) reads raw digital numbers.TRUEdiscovers the affine from the assets' file metadata (the GDAL band scale/offset QGIS applies; one asset per band is probed and the collection is assumed homogeneous) and every read returnsv * scale + offset, applied after the nodata sentinel becomes NaN. A scalar or named numeric (keyed by band name or asset, as fornodata) supplies scales explicitly. Discovery only consults the files themselves: STAC metadata is never read, so collections whose files carry no scaling metadata (e.g. Planetary Computer Sentinel-2 L2A) read raw and scale explicitly instead.mask_assetis never scaled.- offset
Explicit additive offset(s) (scalar or named by asset) used when
scaleis numeric; defaults to 0. Ignored whenscaleis logical.- bands
Source bands to select (default: all). File form: an integer vector of band indices (positions along the band dimension for an N-D array), mutually exclusive with
assets. Table form: a list named by asset, each entry an integer vector of that asset's band indices; names on the indices rename the dataset bands, e.g.list(enclosure_tiff = c(hh = 1, vh = 2, vv = 3)). Assets left out read every band;mask_assetalways reads band 1.- decode
File form: a function decoding the source's 8-bit codes (Byte or Int8), such as
dequantize_aef(). It is evaluated once on every code to make a table. Each source cell's code is decoded through the table first, the nodata code to NaN; resampling then works on the decoded values. Withresampling = "average"onto a grid 3x coarser, each target cell is the mean of the valid decoded values of its 3 x 3 source cells, the order a nonlinear code needs, and a cell whose source cells are all nodata stays NaN. Values are Float32. Reads go through a lookup-table VRT; the source's own grid, a window of its pixels, or an aligned coarser grid read with"near"or"average"read the codes and decode them directly, 2-3x faster.NULL(the default) reads the codes as they are.- time
File form, N-D array: the time slices to build, selected by label as
time_sel()selects them ("2024", or positions).lazy_dataset(src, grid, time = "2024")istime_sel(lazy_dataset(src, grid), "2024")without building the other slices' bands first, which matters for long time series of many bands.NULL(the default) builds every slice.
Details
a STAC
doc_items/stac_sources()table: one band per asset band, each a time-sliced GTI mosaic pinned togrid(mixed source CRS is fine; the GTI driver reprojects per tile). A single-band asset takes the asset's name. Every band of a multi-band asset (e.g. a SAR product packing several polarisations into one COG) becomes its own dataset band, named<asset>_<description>, or<asset>_b<index>when the file carries no band descriptions;bandsselects and renames them.a character path (or vector of same-CRS tile paths, mosaicked): one band per file band, one time slice. This is the multi-band raster entry – geo-embedding stacks (e.g. Alpha Earth's 64-band tiles), Zarr via the GDAL driver, any multi-band file GDAL reads. Each band is its own source, so reads of a band-interleaved file fan out band-by-band across the reader pool (per-band tasks through per-daemon handles: the measured fastest remote shape, design/gdal-multiband-fanout.md). When the bands share storage (a pixel-interleaved file, a Zarr chunk spanning bands),
collect()reads a window's bands in one task instead, so the shared bytes are fetched once. Bands are named by their file band descriptions when present, elseb<index>;grid = NULLstays on the file's native grid, and a suppliedgridinserts analign_to()warp per band. Value transforms (e.g.dequantize_aef()) go downstream aslazy_map()s, which fuse onto the read atcollect().An N-D array with a time dimension, such as a
(time, band, y, x)Zarr array (ZARR:"<store>":/<array>), becomes bands x time slices: GDAL's classic view flattens it to one band per (time, band) pair, and garry reads the dimension tags GDAL puts on each band to rebuild the axes. Bands take the band dimension's coordinate values as names (elseb<index>) and slices take the time coordinate's (e.g. years); pick slices withtime_sel(), or build only some withtime.
All bands share one intermediate representation (IR) graph, so a mask
defined once (see apply_mask()) is computed once and dedup'd across bands, and
collect() plans the whole dataset in one pass.
Examples
f <- system.file("extdata", "garry-example.tif", package = "garry")
ds <- lazy_dataset(f)
names(ds)
#> [1] "red" "green" "nir" "qa"
ds$nir
#> ── <LazyRaster> source 60×40 f32 ──────────────────────────────────────────────
#> grid 60 x 40 • f32
#> crs EPSG:32610
#> graph 4 nodes • lazy
#> ℹ plan_draw(x) to see the pipeline