Skip to content

Commit

Permalink
for #1391
Browse files Browse the repository at this point in the history
  • Loading branch information
rhijmans committed Jan 30, 2024
1 parent 8111782 commit 9302a25
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 26 deletions.
2 changes: 1 addition & 1 deletion NAMESPACE
@@ -1,7 +1,7 @@
useDynLib(terra, .registration=TRUE)
import(methods, Rcpp)
exportClasses(SpatExtent, SpatRaster, SpatRasterDataset, SpatRasterCollection, SpatVector, SpatVectorProxy, SpatVectorCollection)
exportMethods("[", "[[", "!", "%in%", activeCat, "activeCat<-", "add<-", addCats, adjacent, all.equal, aggregate, allNA, align, animate, anyNA, app, area, Arith, approximate, as.bool, as.int, as.contour, as.lines, as.points, as.polygons, as.raster, as.array, as.data.frame, as.factor, as.list, as.logical, as.matrix, as.numeric, atan2, atan_2, autocor, barplot, blocks, boundaries, boxplot, buffer, cartogram, categories, cats, catalyze, clamp, clamp_ts, classify, clearance, cellSize, cells, cellFromXY, cellFromRowCol, cellFromRowColCombine, centroids, click, colFromX, colFromCell, colorize, coltab, "coltab<-", combineGeoms, compare, concats, Compare, compareGeom, contour, convHull, countNA, costDist, crds, cover, crop, crosstab, crs, "crs<-", datatype, deepcopy, delaunay, densify, density, depth, "depth<-", describe, diff, disagg, direction, distance, dots, draw, droplevels, elongate, emptyGeoms, erase, extend, ext, "ext<-", extract, extractRange, expanse, fillHoles, fillTime, flip, focal, focal3D, focalCor, focalPairs, focalReg, focalCpp, focalValues, forceCCW, freq, gaps, geom, geomtype, global, gridDist, gridDistance, has.colors, has.RGB, has.time, hasMinMax, hasValues, hist, head, identical, ifel, impose, init, image, inext, interpIDW, interpNear, inMemory, inset, interpolate, intersect, is.bool, is.int, is.lonlat, is.rotated, isTRUE, isFALSE, is.empty, is.factor, is.lines, is.points, is.polygons, is.related, is.valid, k_means, lapp, layerCor, levels, linearUnits, lines, Logic, varnames, "varnames<-", logic, longnames, "longnames<-", makeValid, mask, match, math, Math, Math2, mean, median, meta, merge, mergeLines, mergeTime, minCircle, minmax, minRect, modal, mosaic, na.omit, not.na, NAflag, "NAflag<-", nearby, nearest, ncell, ncol, "ncol<-", nlyr, "nlyr<-", noNA, normalize.longitude, nrow, "nrow<-", nsrc, origin, "origin<-", pairs, panel, patches, perim, persp, plot, plotRGB, plet, prcomp, princomp, RGB, "RGB<-", polys, points, predict, project, quantile, query, rangeFill, rapp, rast, rasterize, rasterizeGeom, rasterizeWin,readStart, readStop, readValues, rectify, regress, relate, removeDupNodes, res, "res<-", resample, rescale, rev, rcl, roll, rotate, rowFromY, rowColCombine, rowColFromCell, rowFromCell, sapp, scale, scoff, "scoff<-", sds, sort, sprc, sel, selectRange, setMinMax, setValues, segregate, selectHighest, set.cats, set.crs, set.ext, set.names, set.RGB, set.values, size, sharedPaths, shift, sieve, simplifyGeom, snap, sources, spatSample, split, spin, stdev, stretch, subset, subst, summary, Summary, svc, symdif, t, metags, "metags<-", tail, tapp, terrain, tighten, makeNodes, makeTiles, time, timeInfo, "time<-", text, trans, trim, units, union, "units<-", unique, unwrap, update, vect, values, "values<-", viewshed, voronoi, vrt, weighted.mean, where.min, where.max, which.lyr, which.min, which.max, which.lyr, width, window, "window<-", writeCDF, writeRaster, wrap, wrapCache, writeStart, writeStop, writeVector, writeValues, xmin, xmax, "xmin<-", "xmax<-", xres, xFromCol, xyFromCell, xFromCell, ymin, ymax, "ymin<-", "ymax<-", yres, yFromCell, yFromRow, zonal, zoom, cbind2, readRDS, saveRDS, unserialize, serialize, xapp)
exportMethods("[", "[[", "!", "%in%", activeCat, "activeCat<-", "add<-", addCats, adjacent, all.equal, aggregate, allNA, align, animate, anyNA, app, area, Arith, approximate, as.bool, as.int, as.contour, as.lines, as.points, as.polygons, as.raster, as.array, as.data.frame, as.factor, as.list, as.logical, as.matrix, as.numeric, atan2, atan_2, autocor, barplot, blocks, boundaries, boxplot, buffer, cartogram, categories, cats, catalyze, clamp, clamp_ts, classify, clearance, cellSize, cells, cellFromXY, cellFromRowCol, cellFromRowColCombine, centroids, click, colFromX, colFromCell, colorize, coltab, "coltab<-", combineGeoms, compare, concats, Compare, compareGeom, contour, convHull, countNA, costDist, crds, cover, crop, crosstab, crs, "crs<-", datatype, deepcopy, delaunay, densify, density, depth, "depth<-", describe, diff, disagg, direction, distance, dots, draw, droplevels, elongate, emptyGeoms, erase, extend, ext, "ext<-", extract, extractRange, expanse, fillHoles, fillTime, flip, focal, focal3D, focalCor, focalPairs, focalReg, focalCpp, focalValues, forceCCW, freq, gaps, geom, geomtype, getTileExtents, global, gridDist, gridDistance, has.colors, has.RGB, has.time, hasMinMax, hasValues, hist, head, identical, ifel, impose, init, image, inext, interpIDW, interpNear, inMemory, inset, interpolate, intersect, is.bool, is.int, is.lonlat, is.rotated, isTRUE, isFALSE, is.empty, is.factor, is.lines, is.points, is.polygons, is.related, is.valid, k_means, lapp, layerCor, levels, linearUnits, lines, Logic, varnames, "varnames<-", logic, longnames, "longnames<-", makeValid, mask, match, math, Math, Math2, mean, median, meta, merge, mergeLines, mergeTime, minCircle, minmax, minRect, modal, mosaic, na.omit, not.na, NAflag, "NAflag<-", nearby, nearest, ncell, ncol, "ncol<-", nlyr, "nlyr<-", noNA, normalize.longitude, nrow, "nrow<-", nsrc, origin, "origin<-", pairs, panel, patches, perim, persp, plot, plotRGB, plet, prcomp, princomp, RGB, "RGB<-", polys, points, predict, project, quantile, query, rangeFill, rapp, rast, rasterize, rasterizeGeom, rasterizeWin,readStart, readStop, readValues, rectify, regress, relate, removeDupNodes, res, "res<-", resample, rescale, rev, rcl, roll, rotate, rowFromY, rowColCombine, rowColFromCell, rowFromCell, sapp, scale, scoff, "scoff<-", sds, sort, sprc, sel, selectRange, setMinMax, setValues, segregate, selectHighest, set.cats, set.crs, set.ext, set.names, set.RGB, set.values, size, sharedPaths, shift, sieve, simplifyGeom, snap, sources, spatSample, split, spin, stdev, stretch, subset, subst, summary, Summary, svc, symdif, t, metags, "metags<-", tail, tapp, terrain, tighten, makeNodes, makeTiles, time, timeInfo, "time<-", text, trans, trim, units, union, "units<-", unique, unwrap, update, vect, values, "values<-", viewshed, voronoi, vrt, weighted.mean, where.min, where.max, which.lyr, which.min, which.max, which.lyr, width, window, "window<-", writeCDF, writeRaster, wrap, wrapCache, writeStart, writeStop, writeVector, writeValues, xmin, xmax, "xmin<-", "xmax<-", xres, xFromCol, xyFromCell, xFromCell, ymin, ymax, "ymin<-", "ymax<-", yres, yFromCell, yFromRow, zonal, zoom, cbind2, readRDS, saveRDS, unserialize, serialize, xapp)

S3method(cbind, SpatVector)
S3method(rbind, SpatVector)
Expand Down
2 changes: 2 additions & 0 deletions R/Agenerics.R
Expand Up @@ -5,6 +5,8 @@ if (!isGeneric("k_means")) {setGeneric("k_means", function(x, ...) standardGener
if (!isGeneric("princomp")) {setGeneric("princomp", function(x, ...) standardGeneric("princomp"))}
if (!isGeneric("extractRange")) { setGeneric("extractRange", function(x, y, ...) standardGeneric("extractRange"))}

if (!isGeneric("getTileExtents")) {setGeneric("getTileExtents", function(x, ...) standardGeneric("getTileExtents"))}

if (!isGeneric("layerCor")) {setGeneric("layerCor", function(x, ...) standardGeneric("layerCor"))}

if (!isGeneric("metags")) {setGeneric("metags", function(x, ...) standardGeneric("metags"))}
Expand Down
30 changes: 26 additions & 4 deletions R/tiles.R
Expand Up @@ -8,10 +8,7 @@ setMethod("makeTiles", signature(x="SpatRaster"),
if (inherits(y, "SpatRaster")) {
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)
ff <- x@cpp$make_tiles_vect(y@cpp, extend[1], buffer, na.rm[1], filename, opt)
} else if (is.numeric(y)) {
if (length(y) > 2) {
error("makeTiles", "expected one or two numbers")
Expand All @@ -28,6 +25,31 @@ setMethod("makeTiles", signature(x="SpatRaster"),
)


setMethod("getTileExtents", signature(x="SpatRaster"),
function(x, y, extend=FALSE, na.rm=FALSE, buffer=0) {

opt <- spatOptions(filename="")
if (inherits(y, "SpatRaster")) {
e <- x@cpp$get_tiles_ext(y@cpp, extend[1], buffer)
} else if (inherits(y, "SpatVector")) {
e <- x@cpp$get_tiles_ext_vect(y@cpp, extend[1], buffer)
} else if (is.numeric(y)) {
if (length(y) > 2) {
error("getTileExtents", "expected one or two numbers")
}
y <- rep_len(y, 2)
y <- aggregate(rast(x), y)
e <- x@cpp$get_tiles_ext(y@cpp, extend[1], buffer)
} else {
error("getTileExtents", "y must be numeric or a SpatRaster or SpatVector")
}
messages(x, "getTileExtents")
e <- matrix(e, ncol=4, byrow=TRUE)
colnames(e) <- c("xmin", "xmax", "ymin", "ymax")
e
}
)



# if (!hasValues(x)) error("makeTiles", "x has no values")
Expand Down
16 changes: 11 additions & 5 deletions man/makeTiles.Rd
Expand Up @@ -2,21 +2,27 @@

\docType{methods}

\alias{tiles}
\alias{tiles,SpatRaster-method}

\alias{getTileExtents}
\alias{getTileExtents,SpatRaster-method}

\alias{makeTiles}
\alias{makeTiles,SpatRaster-method}


\title{Make tiles}
\title{Make tiles or get their extents}

\description{
Divide a SpatRaster into "tiles". The cells of another SpatRaster (normally with a much lower resolution) or a SpatVector with polygon geometry can be used to define the tiles. You can also provide one or two numbers to indicate the number of rows and columns per tile.

\code{getTileExtents} returns the extents of the (virtual) tiles, while \code{makeTiles} creates files for the tiles and returns their filenames.
}

\usage{
\S4method{makeTiles}{SpatRaster}(x, y, filename="tile_.tif", extend=FALSE,
na.rm=FALSE, buffer=0, overwrite=FALSE, ...)

\S4method{getTileExtents}{SpatRaster}(x, y, extend=FALSE, buffer=0)
}

\arguments{
Expand All @@ -25,13 +31,13 @@ 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{buffer}{integer. The number of additional rows and columns added to each tile. Can be a single number, or two numbers to specify a separate number of rows and 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}}}
}

\value{
character (filenames)
character (filenames) or matrix (extents)
}


Expand Down
2 changes: 2 additions & 0 deletions src/RcppModule.cpp
Expand Up @@ -851,6 +851,8 @@ RCPP_MODULE(spat){
.method("costDistance", &SpatRaster::costDistance)
.method("rastDistance", &SpatRaster::distance)
.method("rastDirection", &SpatRaster::direction)
.method("get_tiles_ext", &SpatRaster::get_tiles_extent)
.method("get_tiles_ext_vect", &SpatRaster::get_tiles_extent_vect)
.method("make_tiles", &SpatRaster::make_tiles)
.method("make_tiles_vect", &SpatRaster::make_tiles_vect)
.method("ext_from_rc", &SpatRaster::ext_from_rc)
Expand Down
118 changes: 103 additions & 15 deletions src/raster_methods.cpp
Expand Up @@ -108,13 +108,54 @@ SpatExtent SpatRaster::ext_from_rc(int_64 r1, int_64 r2, int_64 c1, int_64 c2) {
}


SpatExtent SpatRaster::ext_from_cell(double cell) {
SpatExtent SpatRaster::ext_from_cell( double cell) {
std::vector<double> cells = {cell};
std::vector<std::vector<int_64>> rc = rowColFromCell(cells);
return ext_from_rc(rc[0][0], rc[0][0], rc[1][0], rc[1][0]);
}


std::vector<double> SpatRaster::get_tiles_extent(SpatRaster x, bool expand, std::vector<int> buffer) {

std::vector<double> ee;

x = x.geometry(1, false, false, false);
SpatExtent e = getExtent();

recycle(buffer, 2);
std::vector<double> ebuf = {buffer[0] * xres(), buffer[1] * yres()};

SpatOptions opt;
if (expand) {
x = x.extend(e, "out", NAN, opt);
}
x = x.crop(e, "out", false, opt);

std::vector<size_t> d(x.ncell());
std::iota(d.begin(), d.end(), 1);

ee.reserve(d.size()*4);

SpatRaster y = geometry(1, false, false, false);

for (size_t i=0; i<d.size(); i++) {
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];
SpatRaster out = y.crop(exi, "near", false, opt);
SpatExtent ye = out.getExtent();

ee.push_back(ye.xmin);
ee.push_back(ye.xmax);
ee.push_back(ye.ymin);
ee.push_back(ye.ymax);
}
return ee;
}


std::vector<std::string> SpatRaster::make_tiles(SpatRaster x, bool expand, std::vector<int> buffer, bool narm, std::string filename, SpatOptions &opt) {

std::vector<std::string> ff;
Expand All @@ -128,21 +169,8 @@ std::vector<std::string> SpatRaster::make_tiles(SpatRaster x, bool expand, std::
SpatExtent e = getExtent();

recycle(buffer, 2);
// if ((buffer[0] < 0) | (buffer[1] < 0)) {
// setError("buffer cannot be negative");
// return ff;
// }
std::vector<double> 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);
Expand Down Expand Up @@ -195,7 +223,57 @@ std::vector<std::string> SpatRaster::make_tiles(SpatRaster x, bool expand, std::



std::vector<std::string> SpatRaster::make_tiles_vect(SpatVector x, bool expand, bool narm, std::string filename, SpatOptions &opt) {

std::vector<double> SpatRaster::get_tiles_extent_vect(SpatVector x, bool expand, std::vector<int> buffer) {

std::vector<double> ee;

if (x.type() != "polygons") {
setError("The SpatVector must have a polygons geometry");
return ee;
}
SpatExtent e = getExtent();
std::vector<size_t> d(x.size());
std::iota(d.begin(), d.end(), 1);

ee.reserve(d.size() * 4);
SpatOptions opt;
SpatRaster y = geometry(1, false, false, false);

recycle(buffer, 2);
std::vector<double> ebuf = {buffer[0] * xres(), buffer[1] * yres()};

for (size_t i=0; i<d.size(); i++) {
SpatRaster out;
SpatExtent exi = x.geoms[i].extent;
exi.xmin = exi.xmin - ebuf[0];
exi.xmax = exi.xmax + ebuf[0];
exi.ymin = exi.ymin - ebuf[1];
exi.ymax = exi.ymax + ebuf[1];

if (!e.intersects(exi)) continue;
if (expand) {
out = y.crop(exi, "near", false, opt);
out = out.extend(exi, "out", NAN, opt);
} else {
out = y.crop(exi, "near", false, opt);
}
if (out.hasError()) {
setError(out.getError());
return ee;
}
SpatExtent xe = out.getExtent();

ee.push_back(xe.xmin);
ee.push_back(xe.xmax);
ee.push_back(xe.ymin);
ee.push_back(xe.ymax);
}

return ee;
}

std::vector<std::string> SpatRaster::make_tiles_vect(SpatVector x, bool expand, std::vector<int> buffer, bool narm, std::string filename, SpatOptions &opt) {

std::vector<std::string> ff;
if (!hasValues()) {
Expand All @@ -216,6 +294,10 @@ std::vector<std::string> SpatRaster::make_tiles_vect(SpatVector x, bool expand,
ff.reserve(d.size());
size_t nl = nlyr();
bool overwrite = opt.get_overwrite();

recycle(buffer, 2);
std::vector<double> ebuf = {buffer[0] * xres(), buffer[1] * yres()};

for (size_t i=0; i<d.size(); i++) {
std::string fout = f + std::to_string(d[i]) + fext;
if (file_exists(fout) && (!overwrite)) {
Expand All @@ -225,6 +307,12 @@ std::vector<std::string> SpatRaster::make_tiles_vect(SpatVector x, bool expand,
opt.set_filenames( {fout} );
SpatRaster out;
SpatExtent exi = x.geoms[i].extent;
exi.xmin = exi.xmin - ebuf[0];
exi.xmax = exi.xmax + ebuf[0];
exi.ymin = exi.ymin - ebuf[1];
exi.ymax = exi.ymax + ebuf[1];


if (!e.intersects(exi)) continue;
if (expand) {
out = crop(exi, "near", false, ops);
Expand Down
4 changes: 3 additions & 1 deletion src/spatRaster.h
Expand Up @@ -726,9 +726,11 @@ 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<double> get_tiles_extent(SpatRaster x, bool expand, std::vector<int> buffer);
std::vector<std::string> make_tiles(SpatRaster x, bool expand, std::vector<int> buffer, bool narm, std::string filename, SpatOptions &opt);

std::vector<std::string> make_tiles_vect(SpatVector x, bool expand, bool narm, std::string filename, SpatOptions &opt);
std::vector<double> get_tiles_extent_vect(SpatVector x, bool expand, std::vector<int> buffer);
std::vector<std::string> make_tiles_vect(SpatVector x, bool expand, std::vector<int> buffer, bool narm, std::string filename, SpatOptions &opt);

SpatRaster mask(SpatRaster &x, bool inverse, double maskvalue, double updatevalue, SpatOptions &opt);
SpatRaster mask(SpatRaster &x, bool inverse, std::vector<double> maskvalues, double updatevalue, SpatOptions &opt);
Expand Down

0 comments on commit 9302a25

Please sign in to comment.