#' Remove parts of a GRaster or GVector
#'
#' `crop()` removes parts of a `GRaster` or `GVector` that fall "outside" another raster or vector. You cannot make the `GRaster` or `GVector` larger than it already is (see [extend()]). Rasters may not be cropped to the exact extent, as the extent will be enlarged to encompass an integer number of cells. If you wish to remove certain cells of a raster, see [mask()].
#'
#' @param x A `GRaster` or `GVector` to be cropped.
#' @param y A `GRaster` or `GVector` to serve as a template for cropping.
#' @param extent Logical:
#' * If `y` is a "points" `GVector`: Use the convex hull around `y` to crop `x`.
#' * If `y` is a "lines" or "polygons" `GVector`: If `TRUE`, use the extent of `y` to crop `x`.
#' @param fail Logical: If `TRUE` (default), and the cropped object would have zero extent in at least one dimension, then exit the function with an error. If `FALSE`, then display a warning and return `NULL`.
#'
#' @details Known differences from [terra::crop()]:
#' * If `x` and `y` are "points" vectors, and `extent` is `TRUE`, **terra** removes points that fall on the extent boundary. **fasterRaster** does not remove points on the extent boundary.
#' * If `x` is a "points" vector and `y` is a "lines" vectors, and `extent` is `FALSE`, **terra** uses the extent of `y` to crop the points. **fasterRaster** uses the minimum convex hull of the lines vector.
#'
#' @return A `GRaster` or `GVector` (or `NULL` if `fail` is `FALSE` and the output would have a zero east-west and/or north-south extent).
#'
#' @seealso [terra::crop()], [sf::st_crop()]
#'
#' @example man/examples/ex_crop.r
#'
#' @aliases crop
#' @rdname crop
#' @exportMethod crop
methods::setMethod(
f = "crop",
signature = c(x = "GRaster"),
definition = function(x, y, fail = TRUE) {
if (inherits(y, "GVector")) {
compareGeom(x, y)
} else {
if (crs(x) != crs(y)) stop("Rasters have different coordinate references systems.")
}
.locationRestore(x)
### change region to match the extent of y but have the same resolution and registration as x
if (W(y) <= W(x)) {
w <- W(y)
} else {
cells <- (W(y) - W(x)) / xres(x)
if (!omnibus::is.wholeNumber(cells)) {
cells <- ceiling(cells)
} else {
cells <- round(cells)
}
w <- W(x) + cells * xres(x)
}
if (E(y) >= E(x)) {
e <- E(x)
} else {
cells <- (E(x) - E(y)) / xres(x)
if (inherits(y, "GVector")) {
cells <- floor(cells)
} else if (inherits(y, "GRaster")) {
if (omnibus::is.wholeNumber(cells)) {
cells <- round(cells)
} else {
cells <- floor(cells)
}
}
e <- E(x) - cells * xres(x) # !!!???
}
if (S(y) <= S(x)) {
s <- S(x)
} else {
cells <- (S(y) - S(x)) / yres(x)
if (inherits(y, "GVector")) {
cells <- floor(cells)
} else if (inherits(y, "GRaster")) {
if (omnibus::is.wholeNumber(cells)) {
cells <- round(cells)
} else {
cells <- ceiling(cells)
}
}
s <- S(x) + cells * yres(x) # !!!???
}
if (N(y) >= N(x)) {
n <- N(x)
} else {
cells <- (N(x) - N(y)) / yres(x)
if (inherits(y, "GVector")) {
cells <- floor(cells)
} else if (inherits(y, "GRaster")) {
if (omnibus::is.wholeNumber(cells)) {
cells <- round(cells)
} else {
cells <- ceiling(cells)
}
}
n <- N(x) - cells * yres(x)
}
w <- as.character(w)
e <- as.character(e)
s <- as.character(s)
n <- as.character(n)
ewres <- as.character(xres(x))
nsres <- as.character(yres(x))
rgrass::execGRASS(
cmd = "g.region",
w = w, e = e, s = s, n = n,
ewres = ewres, nsres = nsres,
flags = c(.quiet(), "overwrite")
)
### crop by creating copy of focal raster
srcs <- .copyGSpatial(x, reshapeRegion = FALSE)
.makeGRaster(srcs, names(x), levels = cats(x), ac = activeCats(x), fail = fail)
} # EOF
)
#' @aliases crop
#' @rdname crop
#' @exportMethod crop
methods::setMethod(
f = "crop",
signature = c(x = "GVector"),
definition = function(x, y, extent = FALSE, fail = TRUE) {
compareGeom(x, y)
.locationRestore(x)
### crop
src <- .makeSourceName("crop", "vector")
if (inherits(y, "GVector")) {
xgeom <- geomtype(x, grass = TRUE)
ygeom <- geomtype(y, grass = TRUE)
args <- list(
cmd = "v.clip",
input = sources(x),
output = src,
flags = c(.quiet(), "overwrite"),
intern = TRUE
)
if (extent) {
.regionExt(y, respect = "dim")
args$flags <- c(args$flags, "r")
args$clip <- sources(y)
} else if (ygeom %in% c("point", "line")) {
ch <- convHull(y)
args$clip <- sources(ch)
} else if (ygeom == "area") {
args$clip <- sources(y)
}
} else if (inherits(y, "GRaster")) {
args <- list(
cmd = "v.clip",
input = sources(x),
clip = sources(y),
output = src,
flags = c("r", .quiet(), "overwrite"),
intern = TRUE
)
}
do.call(rgrass::execGRASS, args = args)
.makeGVector(src, fail = fail)
} # EOF
)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.