| Title: | Fast Multiscale Raster Extraction and Moving Window Analysis with FFT |
|---|---|
| Description: | Provides fast moving-window ("focal") and buffer-based extraction for raster data using the 'terra' package. Automatically selects between a 'C++' backend (via 'terra') and a Fast Fourier Transform (FFT) backend depending on problem size. The FFT backend supports sum and mean, while other statistics (e.g., median, min, max, standard deviation) are handled by the 'terra' backend. Supports multiple kernel types (e.g., circle, rectangle, gaussian), with NA handling consistent with 'terra' via 'na.rm' and 'na.policy'. Operates on 'SpatRaster' objects and returns results with the same geometry. |
| Authors: | Ho Yi Wan [aut, cre] (ORCID: <https://orcid.org/0000-0002-2146-8257>) |
| Maintainer: | Ho Yi Wan <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.4 |
| Built: | 2026-05-22 07:34:07 UTC |
| Source: | https://github.com/hoyiwan/fastfocal |
Extracts summary statistics from a SpatRaster at point locations, optionally using buffered extraction with custom kernel windows.
fastextract(x, y, d = 0, w = "circle", fun = "mean", na.rm = TRUE)fastextract(x, y, d = 0, w = "circle", fun = "mean", na.rm = TRUE)
x |
SpatRaster. Input raster (single- or multi-layer). |
y |
SpatVector. Points or polygons. |
d |
numeric or numeric vector. Buffer radius/radii in map units. |
w |
character. Window type for the buffer kernel when |
fun |
character or function. Summary function: "mean", "sum", "min", "max", "sd", or "median"; or a user function. |
na.rm |
logical. Whether to remove NAs when computing summaries. |
If d > 0, a buffer of radius d (map units) is created around each point
and the summary is computed over raster cells intersecting the buffer.
If d == 0, values are taken at the point locations (no buffering).
If y is a polygon layer, the summary is computed over polygon areas.
A data.frame of extracted values. When d has multiple values,
rows are stacked by scale with a scale_m column indicating the radius.
r <- terra::rast(nrows = 10, ncols = 10, xmin = 0, xmax = 100, ymin = 0, ymax = 100) terra::values(r) <- seq_len(terra::ncell(r)) pts <- terra::vect( matrix(c(10, 10, 50, 50), ncol = 2, byrow = TRUE), type = "points", crs = terra::crs(r) ) # Mean over a 20-unit circular neighborhood around each point res <- fastextract(r, pts, d = 20, w = "circle", fun = "mean") head(res)r <- terra::rast(nrows = 10, ncols = 10, xmin = 0, xmax = 100, ymin = 0, ymax = 100) terra::values(r) <- seq_len(terra::ncell(r)) pts <- terra::vect( matrix(c(10, 10, 50, 50), ncol = 2, byrow = TRUE), type = "points", crs = terra::crs(r) ) # Mean over a 20-unit circular neighborhood around each point res <- fastextract(r, pts, d = 20, w = "circle", fun = "mean") head(res)
Applies a focal operation to a SpatRaster using either a 'C++' backend
(via terra) or an 'FFT' backend. Window types include rectangle, circle,
gaussian, pareto, idw, exponential, triangular, cosine, logistic, cauchy,
quartic, epanechnikov, or you may pass a numeric matrix as the kernel.
fastfocal( x, d, w = "circle", fun = "mean", engine = "auto", na.rm = TRUE, na.policy = c("omit", "all"), pad = c("none", "auto"), ... )fastfocal( x, d, w = "circle", fun = "mean", engine = "auto", na.rm = TRUE, na.policy = c("omit", "all"), pad = c("none", "auto"), ... )
x |
SpatRaster. Input raster (1+ layers). |
d |
numeric. Radius/size in map units (ignored if |
w |
character or numeric matrix. Window type, or a custom kernel matrix. |
fun |
character. One of "mean","sum","min","max","sd","median". |
engine |
character. "auto" (default), "cpp", or "fft". |
na.rm |
logical. Remove NAs before applying the summary function. |
na.policy |
character. "omit" (default) leaves NA centers as NA; "all" fills centers when neighbors exist (FFT path respects this; C++ path emulates center handling after the call). |
pad |
character. "none" or "auto" (pad to next 5-smooth sizes for FFT). |
... |
Extra args to |
The 'FFT' backend uses masked convolution with proper NA semantics and can
pad to "5-smooth" sizes for stable speed. With engine = "auto", the function
chooses between 'C++' and 'FFT' based on a simple window-size heuristic.
terra::SpatRaster with the same geometry as x.
set.seed(1) r <- terra::rast(nrows = 12, ncols = 12, xmin = 0, xmax = 12, ymin = 0, ymax = 12) terra::values(r) <- stats::runif(terra::ncell(r)) # Mean with a small circular window (d is in map units; here res = 1) m_circ <- fastfocal(r, d = 2, w = "circle", fun = "mean") # Same idea using a custom 3x3 box kernel (uniform mean) k3 <- matrix(1, 3, 3) m_box <- fastfocal(r, w = k3, fun = "mean") # Tiny numeric summaries (keeps examples fast & quiet for CRAN) as.numeric(terra::global(m_circ, "mean", na.rm = TRUE)) as.numeric(terra::global(m_box, "mean", na.rm = TRUE))set.seed(1) r <- terra::rast(nrows = 12, ncols = 12, xmin = 0, xmax = 12, ymin = 0, ymax = 12) terra::values(r) <- stats::runif(terra::ncell(r)) # Mean with a small circular window (d is in map units; here res = 1) m_circ <- fastfocal(r, d = 2, w = "circle", fun = "mean") # Same idea using a custom 3x3 box kernel (uniform mean) k3 <- matrix(1, 3, 3) m_box <- fastfocal(r, w = k3, fun = "mean") # Tiny numeric summaries (keeps examples fast & quiet for CRAN) as.numeric(terra::global(m_circ, "mean", na.rm = TRUE)) as.numeric(terra::global(m_box, "mean", na.rm = TRUE))
Builds an unnormalized (or normalized) kernel from map units. Circle uses a center-distance rule (include if center <= d). Gaussian interprets d as sigma in map units and truncates at 3 sigma, matching terra::focalMat(..., type = "Gauss").
fastfocal_weights(x, d, w = "circle", normalize = TRUE, plot = FALSE)fastfocal_weights(x, d, w = "circle", normalize = TRUE, plot = FALSE)
x |
SpatRaster (used for resolution; assumes square pixels). |
d |
numeric. Radius in map units for most kernels; sigma in map units for "gaussian"/"Gauss". |
w |
character. One of: "rectangle","circle","circular","gaussian","Gauss","pareto","idw", "exponential","triangular","cosine","logistic","cauchy","quartic","epanechnikov". |
normalize |
logical. If TRUE (default), scale weights to sum to 1. |
plot |
logical. If TRUE, plots the kernel. |
numeric matrix of weights.
# Small raster (resolution = 1 map unit) r <- terra::rast(nrows = 5, ncols = 5, xmin = 0, xmax = 5, ymin = 0, ymax = 5) # Circle: d is a radius in map units -> here cell_radius = 2 -> 5x5 kernel Kc <- fastfocal_weights(r, d = 2, w = "circle", normalize = TRUE) dim(Kc) # 5 x 5 round(sum(Kc), 6) # ~1 # Gaussian: d is sigma in map units, truncated at 3 sigmas Kg <- fastfocal_weights(r, d = 1, w = "gaussian", normalize = TRUE) dim(Kg) # 7 x 7 (since 2*ceil(3*sigma) + 1) round(sum(Kg), 6) # ~1 # \donttest{ # Quick visualization (kept out of CRAN's main run) fastfocal_weights(r, d = 2, w = "circle", normalize = TRUE, plot = TRUE) # }# Small raster (resolution = 1 map unit) r <- terra::rast(nrows = 5, ncols = 5, xmin = 0, xmax = 5, ymin = 0, ymax = 5) # Circle: d is a radius in map units -> here cell_radius = 2 -> 5x5 kernel Kc <- fastfocal_weights(r, d = 2, w = "circle", normalize = TRUE) dim(Kc) # 5 x 5 round(sum(Kc), 6) # ~1 # Gaussian: d is sigma in map units, truncated at 3 sigmas Kg <- fastfocal_weights(r, d = 1, w = "gaussian", normalize = TRUE) dim(Kg) # 7 x 7 (since 2*ceil(3*sigma) + 1) round(sum(Kg), 6) # ~1 # \donttest{ # Quick visualization (kept out of CRAN's main run) fastfocal_weights(r, d = 2, w = "circle", normalize = TRUE, plot = TRUE) # }