diff --git a/R/tiles.R b/R/tiles.R index 059dc2363..1a488119e 100644 --- a/R/tiles.R +++ b/R/tiles.R @@ -1,13 +1,16 @@ setMethod("makeTiles", signature(x="SpatRaster"), - function(x, y, filename="tile_.tif", extend=FALSE, na.rm=FALSE, overwrite=FALSE, ...) { + function(x, y, filename="tile_.tif", extend=FALSE, na.rm=FALSE, buffer=0, overwrite=FALSE, ...) { filename <- trimws(filename[1]) filename <- filename[!is.na(filename)] if (filename == "") error("makeTiles", "filename cannot be empty") opt <- spatOptions(filename="", overwrite=overwrite, ...) if (inherits(y, "SpatRaster")) { - ff <- x@cpp$make_tiles(y@cpp, extend[1], na.rm[1], filename, opt) + ff <- x@cpp$make_tiles(y@cpp, extend[1], buffer, na.rm[1], filename, opt) } else if (inherits(y, "SpatVector")) { + if (!all(buffer == 0)) { + warn("makeTiles", "argument 'buffer' is ignored if y is a SpatVector") + } ff <- x@cpp$make_tiles_vect(y@cpp, extend[1], na.rm[1], filename, opt) } else if (is.numeric(y)) { if (length(y) > 2) { @@ -15,9 +18,9 @@ setMethod("makeTiles", signature(x="SpatRaster"), } y <- rep_len(y, 2) y <- aggregate(rast(x), y) - ff <- x@cpp$make_tiles(y@cpp, extend[1], na.rm[1], filename, opt) + ff <- x@cpp$make_tiles(y@cpp, extend[1], buffer, na.rm[1], filename, opt) } else { - error("makeTiles", "y must be a SpatRaster or SpatVector") + error("makeTiles", "y must be numeric or a SpatRaster or SpatVector") } messages(x, "makeTiles") ff diff --git a/man/makeTiles.Rd b/man/makeTiles.Rd index 6e85b68c5..5c3e1e675 100644 --- a/man/makeTiles.Rd +++ b/man/makeTiles.Rd @@ -15,7 +15,7 @@ Divide a SpatRaster into "tiles". The cells of another SpatRaster (normally with } \usage{ -\S4method{makeTiles}{SpatRaster}(x, y, filename="tile_.tif", extend=FALSE, na.rm=FALSE, overwrite=FALSE, ...) +\S4method{makeTiles}{SpatRaster}(x, y, filename="tile_.tif", extend=FALSE, na.rm=FALSE, buffer=0, overwrite=FALSE, ...) } \arguments{ @@ -24,6 +24,7 @@ Divide a SpatRaster into "tiles". The cells of another SpatRaster (normally with \item{filename}{character. Output filename template. Filenames will be altered by adding the tile number for each tile} \item{extend}{logical. If \code{TRUE}, the extent of \code{y} is expanded to assure that it covers all of \code{x}} \item{na.rm}{logical. If \code{TRUE}, tiles with only missing values are ignored} + \item{buffer}{integer. The number of cells to add around each tile. Ignored if \code{y} is a SpatVector. Can be a single number, or two numbers to specify a separate buffer for the rows and for the columns. This allows for creating overlapping tiles that can be used for computing spatial context dependent values with e.g. \code{\link{focal}}. The expansion is only inside \code{x}, no rows or columns outside of \code{x} are added} \item{overwrite}{logical. If \code{TRUE}, existing tiles are overwritten; otherwise they are skipped (without error or warning)} \item{...}{additional arguments for writing files as in \code{\link{writeRaster}}} } diff --git a/src/raster_methods.cpp b/src/raster_methods.cpp index fb55506e0..f10d4ed2a 100644 --- a/src/raster_methods.cpp +++ b/src/raster_methods.cpp @@ -115,15 +115,34 @@ SpatExtent SpatRaster::ext_from_cell(double cell) { } -std::vector SpatRaster::make_tiles(SpatRaster x, bool expand, bool narm, std::string filename, SpatOptions &opt) { +std::vector SpatRaster::make_tiles(SpatRaster x, bool expand, std::vector buffer, bool narm, std::string filename, SpatOptions &opt) { std::vector ff; if (!hasValues()) { setError("input raster has no values"); return ff; } + + x = x.geometry(1, false, false, false); SpatExtent e = getExtent(); + + recycle(buffer, 2); +// if ((buffer[0] < 0) | (buffer[1] < 0)) { +// setError("buffer cannot be negative"); +// return ff; +// } + std::vector ebuf = {buffer[0] * xres(), buffer[1] * yres()}; + +/* + if ((buffer[0] > 0) || (buffer[1] > 0)) { + e.xmin = e.xmin - ebuf[0]; + e.xmax = e.xmax + ebuf[0]; + e.ymin = e.ymin - ebuf[1]; + e.ymax = e.ymax + ebuf[1]; + } +*/ + SpatOptions ops(opt); if (expand) { x = x.extend(e, "out", NAN, ops); @@ -145,6 +164,11 @@ std::vector SpatRaster::make_tiles(SpatRaster x, bool expand, bool continue; } SpatExtent exi = x.ext_from_cell(i); + exi.xmin = exi.xmin - ebuf[0]; + exi.xmax = exi.xmax + ebuf[0]; + exi.ymin = exi.ymin - ebuf[1]; + exi.ymax = exi.ymax + ebuf[1]; + opt.set_filenames({fout}); SpatRaster out = crop(exi, "near", false, opt); if (out.hasError()) { diff --git a/src/spatRaster.h b/src/spatRaster.h index 8fc91d6bf..60145ff8d 100644 --- a/src/spatRaster.h +++ b/src/spatRaster.h @@ -726,7 +726,8 @@ class SpatRaster { SpatExtent ext_from_rc(int_64 r1, int_64 r2, int_64 c1, int_64 c2); SpatExtent ext_from_cell(double cell); - std::vector make_tiles(SpatRaster x, bool expand, bool narm, std::string filename, SpatOptions &opt); + std::vector make_tiles(SpatRaster x, bool expand, std::vector buffer, bool narm, std::string filename, SpatOptions &opt); + std::vector make_tiles_vect(SpatVector x, bool expand, bool narm, std::string filename, SpatOptions &opt); SpatRaster mask(SpatRaster &x, bool inverse, double maskvalue, double updatevalue, SpatOptions &opt);