I want to crop a raster using a bbox or a known extent, i.e., 10 pixels in row and col.
Below you can see a reproducible example:
library(terra)
r <- terra::set.ext(rast(volcano), terra::ext(0, nrow(volcano), 0, ncol(volcano)))
plot(r)
xmin <- xmin(r)
ymax <- ymax(r)
rs <- res(r)
n <- 10 # i.e. of rows and cols size
xmax <- xmin + n * rs[1]
ymin <- ymax - n * rs[2]
x <- crop(r, c(xmin, xmax, ymin, ymax))
plot(x)
The intended loop is to:
r
) length cropping and save each raster piece temporarily into data.frame (or data.table, raster, spatraster, list)It would be useful to have more context about why you would do this. It is also not clear from your question if you want the cropped areas to overlap; I assume you do not want that.
You can probably use terra::makeTiles
but if that does not apply you could so something like:
library(terra)
r <- rast(volcano)
n <- 10
Get the starting cells of interest
rows <- seq(1, nrow(r), by=n)
cols <- seq(1, ncol(r), by=n)
cells <- cellFromRowColCombine(r, rows, cols)
Get the coordinates
# upper-left coordinates of the starting cells
xy <- xyFromCell(r, cells)
rs <- res(r)
xy[,1] <- xy[,1] - rs[1]/2
xy[,2] <- xy[,2] + rs[2]/2
# add the lower-right coordinates of the end cell
xy <- cbind(xy[,1], xy[,1] + n*rs[1], xy[,2] - n*rs[2], xy[,2])
And loop
x <- lapply(1:nrow(xy), function(i) {
crop(r, xy[i,])
})
Verify
e <- lapply(x, \(i) ext(i) |> as.polygons()) |> vect()
plot(r)
lines(e, col="blue", lwd=2)
sapply(x, dim) |> t() |> head()
# [,1] [,2] [,3]
#[1,] 10 10 1
#[2,] 10 10 1
#[3,] 10 10 1
#[4,] 10 10 1
#[5,] 10 10 1
#[6,] 10 10 1
Or use an alternative approach based on the start- and end-cell numbers
srows <- seq(1, nrow(r), by=n)
scols <- seq(1, ncol(r), by=n)
erows <- pmin(nrow(r), srows+n-1)
ecols <- pmin(ncol(r), scols+n-1)
scell <- cellFromRowColCombine(r, srows, scols)
ecell <- cellFromRowColCombine(r, erows, ecols)
cells <- cbind(scell, ecell)
x <- lapply(1:nrow(cells), function(i) {
e <- ext(r, cells[i,])
crop(r, e)
})