From 37caef5eea9f450a7eba699157d69edec3440522 Mon Sep 17 00:00:00 2001 From: rhijmans Date: Sun, 29 Dec 2024 12:51:17 -0800 Subject: [PATCH] fx --- R/distance.R | 2 +- R/sample.R | 4 ++++ man/distance.Rd | 2 +- src/sample.cpp | 29 ++++++++++++++++++++++++----- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/R/distance.R b/R/distance.R index 36e60533d..b58cede0f 100644 --- a/R/distance.R +++ b/R/distance.R @@ -115,7 +115,7 @@ mat2wide <- function(m, sym=TRUE, keep=NULL) { } setMethod("distance", signature(x="SpatVector", y="ANY"), - function(x, y, sequential=FALSE, pairs=FALSE, symmetrical=TRUE, unit="m", method="cosine") { + function(x, y, sequential=FALSE, pairs=FALSE, symmetrical=TRUE, unit="m", method="geo") { if (!missing(y)) { error("distance", "If 'x' is a SpatVector, 'y' should be a SpatVector or missing") } diff --git a/R/sample.R b/R/sample.R index c73bc8eab..1d8d56a7c 100644 --- a/R/sample.R +++ b/R/sample.R @@ -434,6 +434,10 @@ sampleRaster <- function(x, size, method, replace, ext=NULL, warn, overview=FALS setMethod("spatSample", signature(x="SpatRaster"), function(x, size, method="random", replace=FALSE, na.rm=FALSE, as.raster=FALSE, as.df=TRUE, as.points=FALSE, values=TRUE, cells=FALSE, xy=FALSE, ext=NULL, warn=TRUE, weights=NULL, exp=5, exhaustive=FALSE) { + + if (method == "display") return(sampleRaster(x, size, "regular", FALSE, ext=ext, warn=FALSE, overview=TRUE)) + + if (!as.points) { if (!(values || cells || xy)) { error("spatSample", "at least one of 'values', 'cells', or 'xy' must be TRUE; or 'as.points' must be TRUE") diff --git a/man/distance.Rd b/man/distance.Rd index 2a78e6096..6591397ce 100644 --- a/man/distance.Rd +++ b/man/distance.Rd @@ -47,7 +47,7 @@ If \code{y} is missing, the distance between each points in \code{x} with all ot \S4method{distance}{SpatRaster,SpatVector}(x, y, unit="m", rasterize=FALSE, method="cosine", filename="", ...) -\S4method{distance}{SpatVector,ANY}(x, y, sequential=FALSE, pairs=FALSE, symmetrical=TRUE, unit="m", method="cosine") +\S4method{distance}{SpatVector,ANY}(x, y, sequential=FALSE, pairs=FALSE, symmetrical=TRUE, unit="m", method="geo") \S4method{distance}{SpatVector,SpatVector}(x, y, pairwise=FALSE, unit="m", method="cosine") diff --git a/src/sample.cpp b/src/sample.cpp index fe02b5c57..393f5a75d 100644 --- a/src/sample.cpp +++ b/src/sample.cpp @@ -24,6 +24,20 @@ #include "string_utils.h" +void get_nx_ny(size_t size, size_t &nx, size_t &ny) { + double nxy = nx * ny; + if (size < nxy) { + double f = sqrt(size / ncell ); + double fnx = nx * f; + double fny = ny * f; + double s = fnx * fny; + f = size / s; + nx = std::max((size_t)1, (size_t) std::ceil(fnx * f)); + ny = std::max((size_t)1, (size_t) std::ceil(fny * f)); + } +} + + void getSampleRowCol(std::vector &oldrow, std::vector &oldcol, size_t nrows, size_t ncols, size_t snrow, size_t sncol) { double rf = nrows / (double)(snrow); @@ -185,24 +199,28 @@ SpatRaster SpatRaster::sampleRowColRaster(size_t nr, size_t nc, bool warn) { } + std::vector> SpatRaster::sampleRegularValues(double size, SpatOptions &opt) { std::vector> out; if (!source[0].hasValues) return (out); - size_t nsize; + size_t nr = nrow(); size_t nc = ncol(); + get_nx_ny(size, nc, nr); +/* if (size < ncell()) { double f = sqrt(size / ncell()); double nr1 = nrow() * f; double nc1 = ncol() * f; - double s = nr1 + nc1; + double s = nr1 * nc1; f = size / s; nr = std::max((size_t)1, (size_t) std::ceil(nr1 * f)); nc = std::max((size_t)1, (size_t) std::ceil(nc1 * f)); } - nsize = nc * nr; +*/ + size_t nsize = nc * nr; std::vector v; if ((size >= ncell()) || ((nc == ncol()) && (nr == nrow()))) { v = getValues(-1, opt) ; @@ -550,11 +568,12 @@ std::vector> SpatExtent::sampleRegular(size_t size, bool lon // beware that -180 is the same as 180; and that latitude can only go from -90:90 therefore: double dx = distance_lonlat(xmin, halfy, xmin + 1, halfy) * std::min(180.0, r1); double dy = distance_lonlat(0, ymin, 0, ymax); + double ratio = dy/dx; double n = sqrt(size); double ny = n * ratio; double nx = n / ratio; - double s = nx + ny; + double s = nx * ny; ratio = size / s; ny = std::max((size_t)1, (size_t) std::ceil(ny * ratio)); nx = std::max((size_t)1, (size_t) std::ceil(nx * ratio)); @@ -609,7 +628,7 @@ std::vector> SpatExtent::sampleRegular(size_t size, bool lon double ratio = r1/r2; double ny = sqrt(size / ratio); double nx = size / ny; - double s = nx + ny; + double s = nx * ny; ratio = size / s; ny = std::max((size_t)1, (size_t) std::ceil(ny * ratio)); nx = std::max((size_t)1, (size_t) std::ceil(nx * ratio));