Skip to content

Commit

Permalink
add padding methods to window_time() [experimental]
Browse files Browse the repository at this point in the history
  • Loading branch information
appelmar committed Feb 22, 2024
1 parent 600cbc7 commit 9181420
Show file tree
Hide file tree
Showing 8 changed files with 497 additions and 41 deletions.
8 changes: 4 additions & 4 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,12 @@ gc_create_window_time_cube_kernel <- function(pin, window, kernel) {
.Call('_gdalcubes_gc_create_window_time_cube_kernel', PACKAGE = 'gdalcubes', pin, window, kernel)
}

gc_create_window_space_cube_reduce <- function(pin, reducers, bands, win_size_y, win_size_x, keep_bands) {
.Call('_gdalcubes_gc_create_window_space_cube_reduce', PACKAGE = 'gdalcubes', pin, reducers, bands, win_size_y, win_size_x, keep_bands)
gc_create_window_space_cube_reduce <- function(pin, reducers, bands, win_size_y, win_size_x, keep_bands, pad_mode, pad_fill) {
.Call('_gdalcubes_gc_create_window_space_cube_reduce', PACKAGE = 'gdalcubes', pin, reducers, bands, win_size_y, win_size_x, keep_bands, pad_mode, pad_fill)
}

gc_create_window_space_cube_kernel <- function(pin, kernel, win_size_y, win_size_x, keep_bands) {
.Call('_gdalcubes_gc_create_window_space_cube_kernel', PACKAGE = 'gdalcubes', pin, kernel, win_size_y, win_size_x, keep_bands)
gc_create_window_space_cube_kernel <- function(pin, kernel, win_size_y, win_size_x, keep_bands, pad_mode, pad_fill) {
.Call('_gdalcubes_gc_create_window_space_cube_kernel', PACKAGE = 'gdalcubes', pin, kernel, win_size_y, win_size_x, keep_bands, pad_mode, pad_fill)
}

gc_create_join_bands_cube <- function(pin_list, cube_names) {
Expand Down
40 changes: 35 additions & 5 deletions R/window.R
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ is.window_time_cube <- function(obj) {
#' @param expr either a single string, or a vector of strings, defining which reducers will be applied over which bands of the input cube
#' @param window integer vector with two elements defining the size of the window before and after a cell, the total size of the window is window[1] + 1 + window[2]
#' @param keep_bands logical; if FALSE (the default), original data cube bands will be dropped.
#' @param pad Padding method applied to the borders; use NULL for no padding, a numeric a fill value, or one of "REPLICATE", "REFLECT", "REFLECT_PIXEL"
#' @param ... optional additional expressions (if expr is not a vector)
#' @return proxy data cube object
#' @note Implemented reducers will ignore any NAN values (as \code{na.rm = TRUE} does).
#' @note THIS FUNCTION IS STILL EXPERIMENTAL: The current implementation does not yet support any special edge handling.
#' @note THIS FUNCTION IS STILL EXPERIMENTAL: The current implementation will simply ignore NA values during the convolution, i.e. the sum will not be updated for NA pixels.
#' @note THIS FUNCTION IS STILL EXPERIMENTAL.
#' @examples
#' # create image collection from example Landsat data only
#' # if not already done in other examples
Expand Down Expand Up @@ -165,9 +165,39 @@ is.window_time_cube <- function(obj) {
#' more complex functions or arguments. Possible reducers currently include "min", "max", "sum", "prod", "count", "mean", "median", "var", and "sd".
#'
#' @export
window_space <- function(x, expr, ..., kernel, window, keep_bands = FALSE) {
window_space <- function(x, expr, ..., kernel, window, keep_bands = FALSE, pad = NA) {
stopifnot(is.cube(x))


pad_fill = as.numeric(0)
pad_mode = ""
if (is.na(pad)) {
pad_mode = ""
}
else if (is.numeric(pad)) {
pad_fill = pad[1]
pad_mode = "CONSTANT"
}
else if (is.character(pad)) {
if (any(c("REPLICATE","replicate","edge") %in% pad)){
pad_mode = "REPLICATE"
}
else if (any(c("REFLECT","reflect","symmetric") %in% pad)){
pad_mode = "REFLECT"
}
else if (any(c("REFLECT_PIXEL","reflect_pixel") %in% pad)){
pad_mode = "REFLECT_PIXEL"
}
else {
warning("Unknown padding method (argument pad) provided: falling back to default method (no padding)")
pad_mode = ""
}
}
else {
warning("Invalid padding method (argument pad) provided: falling back to default method (no padding)")
pad_mode = ""
}

if (!missing(kernel)) {
if (!missing(expr)) {
warning("argument expr will be ignored, applying kernel convolution")
Expand All @@ -178,7 +208,7 @@ window_space <- function(x, expr, ..., kernel, window, keep_bands = FALSE) {
if (!is.matrix(kernel)) {
stop("Kernel must be provided as a matrix")
}
x = gc_create_window_space_cube_kernel(x, as.double(kernel), as.integer(nrow(kernel)), as.integer(ncol(kernel)), keep_bands)
x = gc_create_window_space_cube_kernel(x, as.double(kernel), as.integer(nrow(kernel)), as.integer(ncol(kernel)), keep_bands, as.character(pad_mode), as.double(pad_fill))
}
else {
stopifnot(is.character(expr))
Expand All @@ -198,7 +228,7 @@ window_space <- function(x, expr, ..., kernel, window, keep_bands = FALSE) {
reducers = gsub("\\(.*\\)", "", expr)
bands = gsub("[\\(\\)]", "", regmatches(expr, gregexpr("\\(.*?\\)", expr)))
stopifnot(length(reducers) == length(bands))
x = gc_create_window_space_cube_reduce(x, reducers, bands, as.integer(window[1]), as.integer(window[2]), keep_bands)
x = gc_create_window_space_cube_reduce(x, reducers, bands, as.integer(window[1]), as.integer(window[2]), keep_bands, as.character(pad_mode), as.double(pad_fill))
}
class(x) <- c("window_space_cube", "cube", "xptr")
return(x)
Expand Down
8 changes: 4 additions & 4 deletions man/window_space.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 12 additions & 8 deletions src/RcppExports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,8 @@ BEGIN_RCPP
END_RCPP
}
// gc_create_window_space_cube_reduce
SEXP gc_create_window_space_cube_reduce(SEXP pin, std::vector<std::string> reducers, std::vector<std::string> bands, int win_size_y, int win_size_x, bool keep_bands);
RcppExport SEXP _gdalcubes_gc_create_window_space_cube_reduce(SEXP pinSEXP, SEXP reducersSEXP, SEXP bandsSEXP, SEXP win_size_ySEXP, SEXP win_size_xSEXP, SEXP keep_bandsSEXP) {
SEXP gc_create_window_space_cube_reduce(SEXP pin, std::vector<std::string> reducers, std::vector<std::string> bands, int win_size_y, int win_size_x, bool keep_bands, std::string pad_mode, double pad_fill);
RcppExport SEXP _gdalcubes_gc_create_window_space_cube_reduce(SEXP pinSEXP, SEXP reducersSEXP, SEXP bandsSEXP, SEXP win_size_ySEXP, SEXP win_size_xSEXP, SEXP keep_bandsSEXP, SEXP pad_modeSEXP, SEXP pad_fillSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Expand All @@ -459,13 +459,15 @@ BEGIN_RCPP
Rcpp::traits::input_parameter< int >::type win_size_y(win_size_ySEXP);
Rcpp::traits::input_parameter< int >::type win_size_x(win_size_xSEXP);
Rcpp::traits::input_parameter< bool >::type keep_bands(keep_bandsSEXP);
rcpp_result_gen = Rcpp::wrap(gc_create_window_space_cube_reduce(pin, reducers, bands, win_size_y, win_size_x, keep_bands));
Rcpp::traits::input_parameter< std::string >::type pad_mode(pad_modeSEXP);
Rcpp::traits::input_parameter< double >::type pad_fill(pad_fillSEXP);
rcpp_result_gen = Rcpp::wrap(gc_create_window_space_cube_reduce(pin, reducers, bands, win_size_y, win_size_x, keep_bands, pad_mode, pad_fill));
return rcpp_result_gen;
END_RCPP
}
// gc_create_window_space_cube_kernel
SEXP gc_create_window_space_cube_kernel(SEXP pin, std::vector<double> kernel, int win_size_y, int win_size_x, bool keep_bands);
RcppExport SEXP _gdalcubes_gc_create_window_space_cube_kernel(SEXP pinSEXP, SEXP kernelSEXP, SEXP win_size_ySEXP, SEXP win_size_xSEXP, SEXP keep_bandsSEXP) {
SEXP gc_create_window_space_cube_kernel(SEXP pin, std::vector<double> kernel, int win_size_y, int win_size_x, bool keep_bands, std::string pad_mode, double pad_fill);
RcppExport SEXP _gdalcubes_gc_create_window_space_cube_kernel(SEXP pinSEXP, SEXP kernelSEXP, SEXP win_size_ySEXP, SEXP win_size_xSEXP, SEXP keep_bandsSEXP, SEXP pad_modeSEXP, SEXP pad_fillSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Expand All @@ -474,7 +476,9 @@ BEGIN_RCPP
Rcpp::traits::input_parameter< int >::type win_size_y(win_size_ySEXP);
Rcpp::traits::input_parameter< int >::type win_size_x(win_size_xSEXP);
Rcpp::traits::input_parameter< bool >::type keep_bands(keep_bandsSEXP);
rcpp_result_gen = Rcpp::wrap(gc_create_window_space_cube_kernel(pin, kernel, win_size_y, win_size_x, keep_bands));
Rcpp::traits::input_parameter< std::string >::type pad_mode(pad_modeSEXP);
Rcpp::traits::input_parameter< double >::type pad_fill(pad_fillSEXP);
rcpp_result_gen = Rcpp::wrap(gc_create_window_space_cube_kernel(pin, kernel, win_size_y, win_size_x, keep_bands, pad_mode, pad_fill));
return rcpp_result_gen;
END_RCPP
}
Expand Down Expand Up @@ -885,8 +889,8 @@ static const R_CallMethodDef CallEntries[] = {
{"_gdalcubes_gc_create_reduce_space_cube", (DL_FUNC) &_gdalcubes_gc_create_reduce_space_cube, 4},
{"_gdalcubes_gc_create_window_time_cube_reduce", (DL_FUNC) &_gdalcubes_gc_create_window_time_cube_reduce, 4},
{"_gdalcubes_gc_create_window_time_cube_kernel", (DL_FUNC) &_gdalcubes_gc_create_window_time_cube_kernel, 3},
{"_gdalcubes_gc_create_window_space_cube_reduce", (DL_FUNC) &_gdalcubes_gc_create_window_space_cube_reduce, 6},
{"_gdalcubes_gc_create_window_space_cube_kernel", (DL_FUNC) &_gdalcubes_gc_create_window_space_cube_kernel, 5},
{"_gdalcubes_gc_create_window_space_cube_reduce", (DL_FUNC) &_gdalcubes_gc_create_window_space_cube_reduce, 8},
{"_gdalcubes_gc_create_window_space_cube_kernel", (DL_FUNC) &_gdalcubes_gc_create_window_space_cube_kernel, 7},
{"_gdalcubes_gc_create_join_bands_cube", (DL_FUNC) &_gdalcubes_gc_create_join_bands_cube, 2},
{"_gdalcubes_gc_create_select_bands_cube", (DL_FUNC) &_gdalcubes_gc_create_select_bands_cube, 2},
{"_gdalcubes_gc_create_select_time_cube", (DL_FUNC) &_gdalcubes_gc_create_select_time_cube, 2},
Expand Down
8 changes: 4 additions & 4 deletions src/gdalcubes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1144,7 +1144,7 @@ SEXP gc_create_window_time_cube_kernel(SEXP pin, std::vector<int> window, std::v
}

// [[Rcpp::export]]
SEXP gc_create_window_space_cube_reduce(SEXP pin, std::vector<std::string> reducers, std::vector<std::string> bands, int win_size_y, int win_size_x, bool keep_bands) {
SEXP gc_create_window_space_cube_reduce(SEXP pin, std::vector<std::string> reducers, std::vector<std::string> bands, int win_size_y, int win_size_x, bool keep_bands, std::string pad_mode, double pad_fill) {
try {
Rcpp::XPtr< std::shared_ptr<cube> > aa = Rcpp::as<Rcpp::XPtr<std::shared_ptr<cube>>>(pin);

Expand All @@ -1154,7 +1154,7 @@ SEXP gc_create_window_space_cube_reduce(SEXP pin, std::vector<std::string> reduc
reducer_bands.push_back(std::make_pair(reducers[i], bands[i]));
}

std::shared_ptr<window_space_cube>* x = new std::shared_ptr<window_space_cube>(window_space_cube::create(*aa, reducer_bands, win_size_y, win_size_x, keep_bands));
std::shared_ptr<window_space_cube>* x = new std::shared_ptr<window_space_cube>(window_space_cube::create(*aa, reducer_bands, win_size_y, win_size_x, keep_bands, pad_mode, pad_fill));
Rcpp::XPtr< std::shared_ptr<window_space_cube> > p(x, true) ;

return p;
Expand All @@ -1166,11 +1166,11 @@ SEXP gc_create_window_space_cube_reduce(SEXP pin, std::vector<std::string> reduc
}

// [[Rcpp::export]]
SEXP gc_create_window_space_cube_kernel(SEXP pin, std::vector<double> kernel, int win_size_y, int win_size_x, bool keep_bands) {
SEXP gc_create_window_space_cube_kernel(SEXP pin, std::vector<double> kernel, int win_size_y, int win_size_x, bool keep_bands, std::string pad_mode, double pad_fill) {
try {
Rcpp::XPtr< std::shared_ptr<cube> > aa = Rcpp::as<Rcpp::XPtr<std::shared_ptr<cube>>>(pin);

std::shared_ptr<window_space_cube>* x = new std::shared_ptr<window_space_cube>(window_space_cube::create(*aa, kernel, win_size_y, win_size_x, keep_bands));
std::shared_ptr<window_space_cube>* x = new std::shared_ptr<window_space_cube>(window_space_cube::create(*aa, kernel, win_size_y, win_size_x, keep_bands, pad_mode, pad_fill));
Rcpp::XPtr< std::shared_ptr<window_space_cube> > p(x, true) ;
return p;

Expand Down
4 changes: 2 additions & 2 deletions src/gdalcubes/src/cube_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ void cube_factory::register_default() {
}
return window_space_cube::create(instance()->create_from_json(j["in_cube"]), kernel,
j["win_size_y"].int_value(), j["win_size_x"].int_value(),
j["keep_bands"].bool_value());
j["keep_bands"].bool_value(), j["pad_str"].string_value(), j["pad_fill"].number_value());
}
else {
std::vector<std::pair<std::string, std::string>> band_reducers;
Expand All @@ -162,7 +162,7 @@ void cube_factory::register_default() {
}
return window_space_cube::create(instance()->create_from_json(j["in_cube"]), band_reducers,
j["win_size_y"].int_value(), j["win_size_x"].int_value(),
j["keep_bands"].bool_value());
j["keep_bands"].bool_value(), j["pad_str"].string_value(), j["pad_fill"].number_value());
}
}));
cube_generators.insert(std::make_pair<std::string, std::function<std::shared_ptr<cube>(json11::Json&)>>(
Expand Down
Loading

0 comments on commit 9181420

Please sign in to comment.