| Type: | Package |
| Title: | Extract Raster Time Series Values at Points in Space and Time |
| Version: | 0.1.0 |
| Description: | Extract values from a time series of rasters at points that each carry their own date-time. The series is described by a reader function rather than by data held in memory, so only the time slices actually needed are read. Values are taken from the slice nearest in time, or interpolated linearly between the two slices that bracket each point. Derived from the extract() method of package 'raadtools'. |
| Depends: | R (≥ 4.1.0) |
| Imports: | terra (≥ 1.7.0) |
| Suggests: | knitr, mirai (≥ 1.3.0), mori (≥ 0.2.0), rmarkdown, testthat (≥ 3.0.0) |
| License: | GPL-3 |
| Encoding: | UTF-8 |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| Config/roxygen2/version: | 8.1.0 |
| URL: | https://github.com/AustralianAntarcticDivision/xyt, https://australianantarcticdivision.github.io/xyt/ |
| BugReports: | https://github.com/AustralianAntarcticDivision/xyt/issues |
| NeedsCompilation: | no |
| Packaged: | 2026-09-24 08:04:02 UTC; mdsumner |
| Author: | Michael D. Sumner |
| Maintainer: | Michael D. Sumner <mdsumner@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-10-05 16:00:02 UTC |
Extract raster time series values at points in space and time
Description
The package has one job: given a series of rasters that is described by a reader function rather than held in memory, and a set of points that each carry their own date-time, return the value of the series at each point.
Details
The series can be far larger than memory, and can live anywhere the reader can reach, because only the time slices actually needed are read, and each is read exactly once.
The reader contract
A reader is any function supporting two calls.
read(returnfiles = TRUE, ...) # -> data.frame with a `date` column read(date, inputfiles = files, ...) # -> single-layer SpatRaster
The first call is the catalogue: one row per available time slice, in
ascending date order. The second reads one slice. inputfiles is the
catalogue handed back so the reader does not have to rebuild it.
Use xyt_reader_check() to test a function against the contract before
handing it to extract_xyt().
Author(s)
Maintainer: Michael D. Sumner mdsumner@gmail.com (ORCID) [copyright holder]
Authors:
Michael D. Sumner mdsumner@gmail.com (ORCID) [copyright holder]
See Also
extract_xyt(), xyt_reader_check(), synthetic_reader()
Extract values from a raster time series at points in space and time
Description
Each row of xyt is a location and a date-time. The value returned for it
is read from the time slice nearest that date-time, or, with
ctstime = TRUE, interpolated linearly between the two slices that bracket
it.
Usage
extract_xyt(
read,
xyt,
ctstime = FALSE,
when = c("nearest", "previous"),
method = c("simple", "bilinear"),
fact = NULL,
crs = "EPSG:4326",
files = NULL,
share = NULL,
tolerance = NULL,
map = NULL,
verbose = interactive(),
...
)
Arguments
read |
a reader function. See the reader contract in xyt,
|
xyt |
a data.frame or matrix with three columns: x, y and time. Extra columns are ignored. The time column may be POSIXct, Date or character. |
ctstime |
interpolate linearly in time between bracketing slices
( |
when |
which slice a point takes its value from when
|
method |
how the value is taken from the raster: |
fact |
optional aggregation factor applied to each slice before
extraction, as in |
crs |
coordinate reference system of the coordinates in |
files |
the catalogue, if you already have it: a data.frame with a
|
share |
put the catalogue into shared memory with
|
tolerance |
how far, in days, a point may sit from the slice matched
to it before its value is refused and returned as |
map |
how the per-slice reads are run. |
verbose |
report progress as slices are read. |
... |
passed to |
Details
Only the slices that some point actually needs are read, and each of those is read exactly once.
... reaches the reader alone. This is a deliberate departure from the
version of this code that lived in raadtools, where ... was passed to
both the reader and the extraction, so that an argument meant for one was
silently offered to the other. Arguments controlling the extraction are
named here instead.
Value
a numeric vector with one value per row of xyt.
Examples
read <- synthetic_reader()
xyt <- data.frame(x = c(0.5, 2.5), y = c(0.5, 3.5),
t = as.POSIXct(c("2000-01-01", "2000-01-05"), tz = "UTC"))
extract_xyt(read, xyt)
extract_xyt(read, xyt, ctstime = TRUE)
A reader function with no data behind it
Description
Builds a reader that satisfies the contract extract_xyt() expects, over
a small in-memory series whose values are known in closed form. It exists
so the extraction machinery can be exercised, and its answers checked
against arithmetic, without any files, network or credentials.
Usage
synthetic_reader(
n = 10L,
start = "2000-01-01",
by = "1 day",
crs = "EPSG:4326",
extent = c(0, 4, 0, 4),
res = 1
)
Arguments
n |
number of time slices. |
start |
date-time of the first slice. |
by |
spacing between slices, as understood by |
crs |
coordinate reference system of the slices. |
extent |
extent of the slices, as xmin, xmax, ymin, ymax. |
res |
cell size. |
Details
Each slice holds the value
value = 100 * x + y + i
where x and y are the coordinates of the cell centre and i is the
one-based position of the slice in the series. Two properties follow, and
both are used in the tests. The field is linear in x and y, so
method = "bilinear" returns 100 * x + y + i exactly anywhere in the
interior. And it is linear in i, so ctstime = TRUE at a fraction p
between slices i and i + 1 returns exactly 100 * x + y + i + p.
Value
a function of the form read(date, returnfiles = FALSE, inputfiles = NULL, offset = 0, ...). offset is added to every value,
and is there so a test can prove that ... reaches the reader.
Examples
read <- synthetic_reader()
head(read(returnfiles = TRUE))
read(as.POSIXct("2000-01-03", tz = "UTC"))
Value of the synthetic series, computed directly
Description
The closed form of what synthetic_reader() holds, for writing expected
values in tests without going through a raster.
Usage
synthetic_value(
x,
y,
i,
method = c("simple", "bilinear"),
res = 1,
origin = c(0, 0)
)
Arguments
x, y |
coordinates. For |
i |
slice number, one-based. May be fractional, which is what
|
method |
|
res |
cell size of the series. |
origin |
lower left corner of the series. |
Value
a numeric vector.
Examples
synthetic_value(0.7, 2.2, i = 3)
synthetic_value(0.7, 2.2, i = 3, method = "bilinear")
Run the per-slice reads on mirai daemons
Description
The work extract_xyt() does divides cleanly: one slice is read, the
points that want it are extracted, and a plain numeric vector comes back.
Nothing is shared between slices and no SpatRaster crosses a process
boundary, so the reads can be spread over daemons with no change to the
answer.
Usage
xyt_map_mirai(...)
Arguments
... |
passed to |
Details
Start daemons in the usual way and extract_xyt() will use them without
being told to:
mirai::daemons(6)
mirai::everywhere({ library(raadtools) }) # whatever the reader needs
extract_xyt(read, xyt)
mirai::daemons(0)
mirai::everywhere() matters: a daemon runs the reader in a fresh session,
so any package the reader reaches for has to be loaded there. The reader
itself is sent along with the task.
Whether this is faster depends on where the bytes come from. Reading a hundred slices off a remote store is latency bound and parallelises well. Reading ten slices off a local disk that is already saturated will not.
Value
a function of (X, FUN), for extract_xyt()'s map argument.
See Also
Examples
if (requireNamespace("mirai", quietly = TRUE)) {
## a mapper to hand to extract_xyt(map = )
mapper <- xyt_map_mirai()
mapper
}
Check a function against the reader contract
Description
Runs the calls extract_xyt() will make, in the order it will make them,
and reports what came back. Use it when wiring up a new source, so a
mismatch is a sentence about the contract rather than an error from inside
the extraction loop.
Usage
xyt_reader_check(read, error = TRUE, ...)
Arguments
read |
the function to check. |
error |
stop on failure (the default), or return the report quietly. |
... |
passed to |
Value
invisibly, a data.frame with one row per check: check, ok and
note.
Examples
xyt_reader_check(synthetic_reader())
Build a reader from a catalogue and a slice function
Description
The reader contract is one function that does two jobs, switched by
returnfiles. That shape exists so that functions written before this
package, raadtools' read* among them, satisfy it without being touched.
It is not a nice thing to write by hand: the return type depends on the
value of an argument, which is awkward to document and easy to get subtly
wrong.
Usage
xyt_source(slice, catalogue)
Arguments
slice |
a function of |
catalogue |
the catalogue: a data.frame with a |
Details
xyt_source() writes it for you. You supply the two jobs separately, each
as an ordinary function with an ordinary signature, and get back something
extract_xyt() accepts.
Value
a function of class xyt_reader satisfying the reader contract.
See Also
extract_xyt() takes a files argument too, which is the other
way to avoid writing the flag: hand it the catalogue directly and the
returnfiles call is never made.
Examples
## a series of two rasters held in a list
r <- lapply(1:2, function(i) {
x <- terra::rast(terra::ext(0, 4, 0, 4), resolution = 1, crs = "EPSG:4326")
terra::values(x) <- i
x
})
src <- xyt_source(
slice = function(date, files, ...) r[[which(files$date == date)]],
catalogue = data.frame(date = as.POSIXct(c("2000-01-01", "2000-01-02"),
tz = "UTC"))
)
extract_xyt(src, data.frame(x = 1, y = 1,
t = as.POSIXct("2000-01-02", tz = "UTC")))