Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
rhijmans committed Dec 28, 2024
1 parent 98cd4e9 commit 1e1e3dc
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 12 deletions.
8 changes: 8 additions & 0 deletions R/generics.R
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,14 @@ setMethod("cover", signature(x="SpatRaster", y="SpatRaster"),
}
)

setMethod("cover", signature(x="SpatRaster", y="missing"),
function(x, y, values=NA, filename="", ...) {
opt <- spatOptions(filename, ...)
x@pntr <- x@pntr$cover_self(values, opt)
messages(x, "cover")
}
)


setMethod("diff", signature(x="SpatRaster"),
function(x, lag=1, filename="", ...) {
Expand Down
24 changes: 22 additions & 2 deletions R/tiles.R
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,28 @@ setMethod("vrt", signature(x="character"),
writeLines(v, f)
}
}
if (return_filename) return(f)
rast(f)
if (return_filename) {
f
} else {
rast(f)
}
}
)


setMethod("vrt", signature(x="SpatRasterCollection"),
function(x, filename="", options=NULL, overwrite=FALSE, return_filename=FALSE) {
opt <- spatOptions(filename, overwrite=overwrite)
if (is.null(options)) {
options=""[0]
}
f <- x@pntr$make_vrt(options, FALSE, opt)
messages(x, "vrt")
if (return_filename) {
f
} else {
rast(f)
}
}
)

Expand Down
7 changes: 5 additions & 2 deletions man/cover.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

\alias{cover}
\alias{cover,SpatRaster,SpatRaster-method}
\alias{cover,SpatRaster,missing-method}
\alias{cover,SpatVector,SpatVector-method}


\title{Replace values with values from another object}

\description{
Replace \code{NA} or other values in SpatRaster \code{x} with the values of SpatRaster \code{y}
Replace missing (\code{NA}) or other values in SpatRaster \code{x} with the values of SpatRaster \code{y}. Or replace missing values in the first layer with the first value encountered in other layers.

For polygons: areas of \code{x} that overlap with \code{y} are replaced by \code{y} or, if \code{identity=TRUE} intersected with \code{y}.

Expand All @@ -19,12 +20,14 @@ For polygons: areas of \code{x} that overlap with \code{y} are replaced by \code
\usage{
\S4method{cover}{SpatRaster,SpatRaster}(x, y, values=NA, filename="", ...)

\S4method{cover}{SpatRaster,missing}(x, y, values=NA, filename="", ...)

\S4method{cover}{SpatVector,SpatVector}(x, y, identity=FALSE, expand=TRUE)
}

\arguments{
\item{x}{SpatRaster or SpatVector}
\item{y}{Same as \code{x}}
\item{y}{Same as \code{x} or missing if \code{x} is a SpatRaster}
\item{values}{numeric. The cell values in \code{x} to be replaced by the values in \code{y}}
\item{filename}{character. Output filename}
\item{...}{additional arguments for writing files as in \code{\link{writeRaster}}}
Expand Down
4 changes: 3 additions & 1 deletion src/RcppModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,9 @@ RCPP_MODULE(spat){
.method("sort", &SpatRaster::sort)
.method("intersect", &SpatRaster::intersect)

.method("cover", &SpatRaster::cover)
.method("cover", ( SpatRaster (SpatRaster::*)(SpatRaster, std::vector<double>, SpatOptions&) )( &SpatRaster::cover))
.method("cover_self", ( SpatRaster (SpatRaster::*)(std::vector<double>, SpatOptions&) )( &SpatRaster::cover))

.method("crop", &SpatRaster::crop)
.method("crop_mask", &SpatRaster::cropmask)
.method("cum", &SpatRaster::cum)
Expand Down
156 changes: 153 additions & 3 deletions src/raster_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3279,6 +3279,103 @@ SpatRaster SpatRaster::cover(SpatRaster x, std::vector<double> values, SpatOptio
}


SpatRaster SpatRaster::cover(std::vector<double> values, SpatOptions &opt) {

SpatRaster out = geometry(1, true, true, true);
if (!hasValues()) return out;
size_t nl = nlyr();
if (nl == 1) {
return deepCopy();
}
if (!readStart()) {
out.setError(getError());
return out;
}

if (!out.writeStart(opt, filenames())) {
readStop();
return out;
}
if (values.size() == 1) {
double value=values[0];
for (size_t i = 0; i < out.bs.n; i++) {
std::vector<size_t> off(nl);
for (size_t k=1; k < nl; k++) {
off[k] = k * out.bs.nrows[i] * ncol();
}
std::vector<double> v;
readValues(v, out.bs.row[i], out.bs.nrows[i], 0, ncol());
if (std::isnan(value)) {
for (size_t j=0; j < off[1]; j++) {
for (size_t k=1; k < nl; k++) {
if (std::isnan(v[j])) {
v[j] = v[j + off[k]];
} else {
continue;
}
}
}
} else {
for (size_t j=0; j < off[1]; j++) {
for (size_t k=1; k < nl; k++) {
if (v[j] == value) {
v[j] = v[j + off[k]];
} else {
continue;
}
}
}
}
std::vector<double> w = {v.begin(), v.begin()+off[1]};
if (!out.writeBlock(w, i)) return out;
}

} else {

values = vunique(values);
bool hasNA = false;
for (int i = values.size()-1; i>=0; i--) {
if (std::isnan(values[i])) {
hasNA = true;
values.erase(values.begin()+i);
}
}

for (size_t i = 0; i < out.bs.n; i++) {
std::vector<size_t> off(nl);
for (size_t k=1; k < nl; k++) {
off[k] = k * out.bs.nrows[i] * ncol();
}
std::vector<double> v;
readValues(v, out.bs.row[i], out.bs.nrows[i], 0, ncol());
for (size_t j=0; j < off[1]; j++) {
if (hasNA) {
for (size_t k=1; k < nl; k++) {
if (std::isnan(v[j])) {
v[j] = v[j+off[k]];
continue;
}
}
}
for (size_t j=0; j<values.size(); j++) {
for (size_t k=1; k < nl; k++) {
if (v[j] == values[j]) {
v[j] = v[j+off[k]];
continue;
}
}
}
}
std::vector<double> w = {v.begin(), v.begin()+off[1]};
if (!out.writeBlock(w, i)) return out;
}
}

out.writeStop();
readStop();
return(out);
}



SpatRaster SpatRaster::extend(SpatExtent e, std::string snap, double fill, SpatOptions &opt) {
Expand Down Expand Up @@ -3619,6 +3716,8 @@ bool write_part(SpatRaster& out, SpatRaster& r, const double& hxr, size_t& nl, b

SpatRaster SpatRasterCollection::merge(bool first, bool narm, int algo, SpatOptions &opt) {

// narm is not used!

SpatRaster out;
size_t n = size();
if (n == 0) {
Expand Down Expand Up @@ -3797,15 +3896,66 @@ SpatRaster SpatRasterCollection::merge(bool first, bool narm, int algo, SpatOpti
return(out);

} else if (algo==3) {

std::vector<std::string> options;
bool ml = false;
size_t nl = ds[0].nlyr();
for (size_t i=1; i<n; i++) {
if (nl != ds[i].nlyr()) {
options.push_back("-separate");
ml = true;
continue;
}
}
if (ml) {
out.setError("you cannot use this algo with input that has different numbers of layers");
return out;
}

bool wvrt = false;
std::string fout = opt.get_filename();
if (!fout.empty()) {
if (fout.size() > 4) {
std::string ss = fout.substr(fout.size()-4, fout.size());
lowercase(ss);
wvrt = ss == ".vrt";
}
}

if (fout != "") {
std::string fname;
if (opt.names.empty()) {
opt.names = ds[0].getNames();
}
if (wvrt) {
fname = make_vrt(options, first, opt);
} else {
SpatOptions vopt(opt);
fname = make_vrt(options, first, vopt);
}

if (hasError()) {
out.setError(getError());
return out;
}
SpatRaster v(fname, {}, {}, {}, {});
if (wvrt) {
return v;
} else {
return v.writeRaster(opt);
}
}

SpatOptions vopt(opt);
std::string fname = make_vrt({}, !first, vopt);
std::string fname = make_vrt(options, first, vopt);
SpatRaster v(fname, {}, {}, {}, {});
return v.writeRaster(opt);
v.setNames(ds[0].getNames(), false);

return v;

} else {
out.setError("invalid algo (should be 1, 2, or 3)");
return(out);
return out;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/spatRaster.h
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ class SpatRaster {
SpatRaster dropLevels();

SpatRaster cover(SpatRaster x, std::vector<double> value, SpatOptions &opt);
SpatRaster cover(std::vector<double> value, SpatOptions &opt);

SpatRaster crop(SpatExtent e, std::string snap, bool expand, SpatOptions &opt);
SpatRaster cropmask(SpatVector &v, std::string snap, bool touches, bool expand, SpatOptions &opt);
Expand Down
24 changes: 20 additions & 4 deletions src/spatRasterMultiple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,33 @@ void SpatRasterCollection::erase(size_t i) {

std::string SpatRasterCollection::make_vrt(std::vector<std::string> options, bool reverse, SpatOptions &opt) {

std::string outfile = opt.get_filename();
if (outfile.empty()) {
outfile = tempFile(opt.get_tempdir(), opt.tmpfile, ".vrt");
} else if (file_exists(outfile) && (!opt.get_overwrite())) {
setError("output file exists. You can use 'overwrite=TRUE' to overwrite it");
return("");
}
opt.set_filenames({outfile});

std::vector<std::string> ff = filenames();
ff.reserve(size());

SpatOptions xopt(opt);
for (size_t i=0; i<ff.size(); i++) {
if (ff[i] == "") {
ff[i] = tempFile(xopt.get_tempdir(), xopt.tmpfile, "_temp_raster.tif");
xopt.set_filenames({ff[i]});
for (size_t i=0; i<size(); i++) {
// if (!ds[i].hasValues()) continue;
std::vector<std::string> f = ds[i].filenames();
if ((ds[i].nsrc() == 1) && f[0] != "") {
ff.push_back(f[0]);
} else {
std::string tmpf = tempFile(xopt.get_tempdir(), xopt.tmpfile, "_temp_raster.tif");
xopt.set_filenames({tmpf});
SpatRaster out = ds[i].writeRaster(xopt);
if (out.hasError()) {
setError(out.getError());
return "";
}
ff.push_back(tmpf);
}
}
SpatRaster tmp;
Expand Down

0 comments on commit 1e1e3dc

Please sign in to comment.