diff --git a/.Rbuildignore b/.Rbuildignore index 3542c57d..e66ed82d 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -6,7 +6,7 @@ CODE_OF_CONDUCT.md ^cran-comments\.md$ ^fasterRaster.png ^.*\.Rproj$ -^\articles$ +^articles$ ^\.Rproj\.user$ ^\.github ^\.vscode diff --git a/DESCRIPTION b/DESCRIPTION index 868a8138..600cd1e3 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,18 +1,19 @@ Package: fasterRaster Type: Package Title: Faster Raster and Spatial Vector Processing Using 'GRASS GIS' -Version: 8.4.0.0 -Date: 2024-11-20 +Version: 8.4.0.1 +Date: 2024-12-03 Authors@R: c( person( given = c('Adam', 'B.'), family = 'Smith', - role = c('aut', 'cre'), + role = c('cre', 'aut'), email = 'adam.smith@mobot.org', comment = c(ORCID = '0000-0002-6420-1659') ) ) +Maintainer: Adam B. Smith Description: Processing of large-in-memory/large-on disk rasters and spatial vectors using 'GRASS GIS'. Most functions in the 'terra' package are recreated. Processing of medium-sized and smaller spatial objects will diff --git a/NEWS.md b/NEWS.md index 7181ca4e..47facfb1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,7 @@ o `mow()` can delete a single `GRaster` or `GVector`, a list of rasters and/or v o `centroids()` locates the center of `GVector`s. o `coordRef()` returns information about an object's coordinate reference system. o `project()` is now much faster when projecting a `GRaster` using the `terra` or `fallback` values for `res`. +o `spatSample()` is faster. o Support for **GRASS** addons and methods based on them!!! ### Bug and issue fixes diff --git a/R/addons.r b/R/addons.r index 5059a28e..b76d8885 100644 --- a/R/addons.r +++ b/R/addons.r @@ -1,6 +1,6 @@ #' Test if addons directory exists and if an addon is installed #' -#' @description This function tests to see if the "addons" directory specified using [faster()] actually exists, and if a particular **GRASS** `addons module is available. The `addons` folder and module must exists for methods that rely on particular **GRASS** `addons` to work. +#' @description This function tests to see if the "addons" directory specified using [faster()] actually exists, and if a particular **GRASS** `addons module is available. The `addons` folder and module must exists for methods that rely on particular **GRASS** `addons` to work. See `vignette("addons", package = "fasterRaster")`. #' #' @param x Either `NULL` or a character specifying the name of a **GRASS** addons module. If `NULL`, the existence of the `addonsDir` (see [faster()]) will be tested. If the module name is provided, the existence of the folder and module will be tested. #' @@ -12,7 +12,7 @@ #' #' @returns Logical. #' -#' @seealso `vignette("fasterRaster_addons", package = "fasterRaster")` +#' @seealso `vignette("addons", package = "fasterRaster")` #' #' @example man/examples/ex_addons.r #' diff --git a/R/centroids.r b/R/centroids.r index d0f27999..c070ce84 100644 --- a/R/centroids.r +++ b/R/centroids.r @@ -1,6 +1,8 @@ #' Centroid(s) of a vector #' -#' @description This function locates the centroid of each geometry of a `GVector`. **To use this function, you must a) have correctly specified the `addonsDir` option using [faster()], and b) installed the **GRASS** addon `v.centerpoint`.** See [addons()] and `vignette("fasterRaster_addons", package = "fasterRaster")`. +#' @description This function locates the centroid of each geometry of a `GVector`. +#' +#' **To use this function**, you must a) have correctly specified the `addonsDir` option using [faster()], and b) installed the **GRASS** addon `v.centerpoint`. See [addons()] and `vignette("addons", package = "fasterRaster")`. #' #' @param x A `GVector`. #' @param method Character or `NULL` (default): Method used for calculating centroids. The method of calculation depends on whether the input is a `points`, `lines`, or `polygons` `GVector`. If the value is `NULL`, then the default method will be chosen, depending on the geometry type of the `GVector`: diff --git a/R/extract.r b/R/extract.r index f46e5c83..46cc3ee3 100644 --- a/R/extract.r +++ b/R/extract.r @@ -745,7 +745,7 @@ methods::setMethod( vals <- strsplit(vals, split = "\\|") vals <- do.call(rbind, vals) - vals <- vals[ , 4:ncol(vals)] + vals <- vals[ , 4L:ncol(vals)] vals <- data.table::as.data.table(vals) names(vals) <- xNames[index] diff --git a/R/fastData.r b/R/fastData.r index 34df5f2d..244ab4a9 100644 --- a/R/fastData.r +++ b/R/fastData.r @@ -12,17 +12,17 @@ #' #' Rasters (objects of class `SpatRaster` from the **terra** package, saved as GeoTIFF files): #' * [madChelsa]: Bioclimatic variables -#' * [madCover]: Land cover (also see `madCoverCats`) -#' * [madElev]: Elevation +#' * [madCover]: Land cover +#' * [`madElev`][madElev]: Elevation #' * [madForest2000]: Forest cover in year 2000 #' * [madForest2014]: Forest cover in year 2014 #' * [madLANDSAT]: Surface reflectance in 2023 #' * [madPpt], [madTmin], [madTmax]: Rasters of mean monthly precipitation, and minimum and maximum temperature. #' #' Data frames -#' * [appFunsTable]: Table of functions usable by [app()]. -#' * [madCoverCats]: Land cover values and categories. -#' * [vegIndices]: Vegetation indices that can be calculated with [vegIndex()]. +#' * [appFunsTable]: Table of functions usable by [app()] +#' * [madCoverCats]: Land cover values and categories for [madCover] +#' * [vegIndices]: Vegetation indices that can be calculated with [vegIndex()] #' #' @return A `SpatRaster`, `sf` spatial vector, or a `data.frame`. #' diff --git a/R/fasterRaster.r b/R/fasterRaster.r index 6d16ec01..8cb54870 100644 --- a/R/fasterRaster.r +++ b/R/fasterRaster.r @@ -6,12 +6,12 @@ #' * The quick-start guide to getting started with **fasterRaster**: `vignette("fasterRaster", package = "fasterRaster")`: #' * Types of `GRaster`s: `vignette("GRasters", package = "fasterRaster")` #' * How to speed up **fasterRaster**: `vignette("faster_fasterRaster", package = "fasterRaster")` -#' * Using functions that depend on **GRASS** addons: `vignette("fasterRaster_addons", package = "fasterRaster")` +#' * Using functions that depend on **GRASS** addons: `vignette("addons", package = "fasterRaster")` #' * [faster()]: Set the directory where **GRASS** is installed on your system, and set or get other package-wide options. This function must be run once before using most **fasterRaster** functions. #' * [fast()]: Convert a `SpatRaster`, `SpatVector`, or `sf` vector to **fasterRaster**'s raster format (`GRaster`s) or vector format (`GVector`s), or load one from a file #' * [rast()], [vect()], and [st_as_sf()]: Convert `GRaster`s and `GVector`s to `SpatRaster`s, `SpatVector`s, or `sf` vectors #' * [writeRaster()] and [writeVector()]: Save `GRaster`s or `GVector`s to disk -#' * [addons()]: Test to see if the `addons` directory is correct and if a particular addon **GRASS** module is installed. +#' * [addons()]: Test if the `addons` directory is correct and if a particular addon **GRASS** module is installed. #' #' ## Properties of `GRasters` #' * [crs()]: Coordinate reference system @@ -37,8 +37,8 @@ #' * [nrow()]: Number of rows #' * [nlevels()]: Number of categories #' * [res()], [res3d()], [xres()], [yres()], and [zres()]: Spatial resolution -#' * [sources()]: Name of the `GRaster` in **GRASS** -#' * [topology()]: Dimensionality (2D or 3D) +#' * [sources()]: Name of the raster file in the **GRASS** cache +#' * [`topology()`][topology]: Dimensionally (2D or 3D) #' * [zext()]: Vertical extent #' * [zres()]: Vertical resolution #' @@ -136,7 +136,7 @@ #' * [flow()]: Identify watershed basins and direction and accumulation of flow #' * [flowPath()]: Path of water flow across a landscape #' * [geomorphons()]: Identify terrain feature types -#' * [`hillshade()`][shade]: Create a hillshade `GRaster` +#' * [`hillshade()`][hillshade]: Create a hillshade `GRaster` #' * [horizonHeight()]: Horizon height #' * [sun()]: Solar radiance and irradiance #' * [ruggedness()]: Terrain Ruggedness Index @@ -194,9 +194,9 @@ #' * [ncol()]: Number of fields #' * [ngeom()]: Number of geometries (points, lines, polygons) #' * [nrow()]: Number of rows in a vector data table -#' * [nsubgeom()]: Number of subgeometries (points, lines, polygons that make up single- and multipart geometries) -#' * [sources()]: Name of the vector in **GRASS** -#' * [topology()]: Dimensionality (2D or 3D) +#' * [nsubgeom()]: Number of sub-geometries (points, lines, polygons that make up single- and multipart geometries) +#' * [`sources()`][sources]: Name of the vector file in the **GRASS** cache +#' * [`topology()`][topology]: Dimensionally (2D or 3D) #' * [zext()]: Vertical extent #' #' ## Subsetting and assigning geometries or rows and columns of `GVector`s @@ -234,7 +234,7 @@ #' * [intersect()] or `*`: Intersection of two `GVectors` #' * [kernel()]: Kernel density estimator of points #' * [missing.cases()]: Find rows of a `GVector`'s data table that have at least `NA` in them -#' \code{\link[fasterRaster]{names<-}}: Assign names to columns of a `GVector`s data table +#' * \code{\link[fasterRaster]{names<-}}: Assign names to columns of a `GVector`s data table #' * [project()]: Change coordinate reference system #' * [rasterize()]: Convert a `GVector` to a `GRaster` #' * [rbind()]: Combine `GVectors` diff --git a/R/hillshade.r b/R/hillshade.r index e9f6a574..0d0f8ffc 100644 --- a/R/hillshade.r +++ b/R/hillshade.r @@ -12,8 +12,6 @@ #' #' @returns A `GRaster`. #' -#' @seealso [terra::shade()] -#' #' @example man/examples/ex_terrain.r #' #' @aliases hillshade diff --git a/R/spatSample.r b/R/spatSample.r index 731c925c..4a4de6d6 100644 --- a/R/spatSample.r +++ b/R/spatSample.r @@ -56,194 +56,232 @@ methods::setMethod( .locationRestore(x) .region(x) - # fast point location... use R - if (is.null(strata)) { - - # for unprojected, we want to adjust for smaller cells near poles, so we oversample, then subsample - extent <- ext(x, vector = TRUE) - if (is.lonlat(x)) { - - # sampling scheme for latitude: - # divide y extent into large number of bins - # weight each bin by cos(latitude) - # sample with replacement from bin y values - # add a uniform random number +- half bin width - - yres <- yres(x) - yLower <- extent[3L] + 0.5 * yres - yUpper <- extent[4L] - 0.5 * yres - ydim <- dim(x)[2L] - nMarks <- 100 * ydim - halfDelta <- 0.5 * (yUpper - yLower) / (nMarks - 1) - yMarks <- seq(yLower, yUpper, length.out = nMarks) - w <- abs(cos(pi * yMarks / 180)) - ys <- sample(yMarks, size, prob = w, replace = TRUE) - ys <- ys + stats::runif(size, -halfDelta, halfDelta) + # ### fast point location... use R + # ### v.random is REALLY slow for even moderately large sample sizes + # if (is.null(strata)) { + + # # for unprojected, we want to adjust for smaller cells near poles, so we oversample, then subsample + # extent <- ext(x, vector = TRUE) + # if (is.lonlat(x)) { + + # # sampling scheme for latitude: + # # divide y extent into large number of bins + # # weight each bin by cos(latitude) + # # sample with replacement from bin y values + # # add a uniform random number +- half bin width + + # yres <- yres(x) + # yLower <- extent[3L] + 0.5 * yres + # yUpper <- extent[4L] - 0.5 * yres + # ydim <- dim(x)[2L] + # nMarks <- 100 * ydim + # halfDelta <- 0.5 * (yUpper - yLower) / (nMarks - 1) + # yMarks <- seq(yLower, yUpper, length.out = nMarks) + # w <- abs(cos(pi * yMarks / 180)) + # ys <- sample(yMarks, size, prob = w, replace = TRUE) + # ys <- ys + stats::runif(size, -halfDelta, halfDelta) - } else { - # if not long/lat, just sample uniformly - ys <- stats::runif(size, extent[3L], extent[4L]) - } + # } else { + # # if not long/lat, just sample uniformly + # ys <- stats::runif(size, extent[3L], extent[4L]) + # } + + # xs <- stats::runif(size, extent[1L], extent[2L]) + # if (!is.null(zlim)) zs <- stats::runif(size, zlim[1L], zlim[2L]) + + # if (xy) { + # if (is.null(zlim)) { + # out <- data.table::data.table(x = xs, y = ys) + # } else { + # out <- data.table::data.table(x = xs, y = ys, z = zs) + # } + # } + + # ### NB The script below ingests points in chunks bc that has proven faster than doing all at once for larger numbers of points. + + # xs <- round(xs, 7L) + # ys <- round(ys, 7L) + # if (!is.null(zlim)) zs <- round(zs, 7L) + + # xs[xs < extent[1L]] <- extent[1L] + # xs[xs > extent[2L]] <- extent[2L] + # ys[ys < extent[3L]] <- extent[3L] + # ys[ys > extent[4L]] <- extent[4L] + + # ### use v.in.ascii to ingest each subset of points + # ################################################## + + # nAtATime <- 2E5 # optimal-ish size based on manual checks + # sets <- ceiling(size / nAtATime) + # srcs <- .makeSourceName("spatSample_v_in_ascii", "vector", n = sets) + + # if ((verbose | faster("verbose")) & sets > 1) { + # omnibus::say("Ingesting points...") + # pb <- utils::txtProgressBar(min = 0, max = sets, initial = 0, style = 3, width = 30) + # } + + # for (set in seq_len(sets)) { + + # if ((verbose | faster("verbose")) & sets > 1) utils::setTxtProgressBar(pb, set) + + # index <- (nAtATime * (set - 1) + 1):(min(nAtATime * set, size)) + # thisXs <- xs[index] + # thisYs <- ys[index] + # if (!is.null(zlim)) thisZs <- zs[index] + + # if (is.null(zlim)) { + # coords <- data.table::data.table(cat = index, x = thisXs, y = thisYs) + # } else { + # coords <- data.table::data.table(cat = index, x = thisXs, y = thisYs, z = thisZs) + # } + # coords[ , coords := do.call(paste, c(.SD, sep = "|"))] + # coords <- coords[ , "coords", drop = FALSE] + + # tf <- tempfile(fileext = ".txt") + # data.table::fwrite(coords, tf, col.names = FALSE, quote = FALSE, scipen = 20L) + + # args <- list( + # "v.in.ascii", + # input = tf, + # output = srcs[set], + # format = "point", + # separator = "pipe", + # cat = 1, x = 2, y = 3, + # flags = c(.quiet(), "overwrite", "t", "n", "b") # "b" --> no topology + # # flags = c(.quiet(), "overwrite", "t", "n") # "b" --> no topology + # ) + # if (!is.null(zlim)) { + # args$flags <- c(args$flags, "z") + # args$z <- 4 + # } + # do.call(rgrass::execGRASS, args = args) + # unlink(tf) + + # # if (set > 1) { + + # # topCat <- min(nAtATime * set, size) + # # srcs[set] <- .vIncrementCats(srcs[set], add = topCat) - xs <- stats::runif(size, extent[1L], extent[2L]) - if (!is.null(zlim)) zs <- stats::runif(size, zlim[1L], zlim[2L]) + # # } - if (xy) { - if (is.null(zlim)) { - out <- data.table::data.table(x = xs, y = ys) - } else { - out <- data.table::data.table(x = xs, y = ys, z = zs) - } - } + # } # next set - ### NB The script below ingests points in chunks be that has proven faster than doing all at once for larger numbers of points. + # if ((verbose | faster("verbose")) & sets > 1) close(pb) - xs <- round(xs, 7L) - ys <- round(ys, 7L) - if (!is.null(zlim)) zs <- round(zs, 7L) + # ### use v.patch to combine subsets of points + # ############################################ - xs[xs < extent[1L]] <- extent[1L] - xs[xs > extent[2L]] <- extent[2L] - ys[ys < extent[3L]] <- extent[3L] - ys[ys > extent[4L]] <- extent[4L] + # # seems like we can combine at least 11 vectors at a time, but not too many more + # srcsAtATime <- 10L # number of sources to combine at a time (plus the running `x` source) - ### use v.in.ascii to ingest each subset of points - nAtATime <- 2E5 # optimal-ish size based on manual checks - sets <- ceiling(size / nAtATime) - srcs <- .makeSourceName("spatSample_v_in_ascii", "vector", n = sets) + # nSrcs <- length(srcs) + # sets <- ceiling(nSrcs / srcsAtATime) - if ((verbose | faster("verbose")) & sets > 1) { - omnibus::say("Ingesting points...") - pb <- utils::txtProgressBar(min = 0, max = sets, initial = 0, style = 3, width = 30) - } + # if ((verbose | faster("verbose")) & sets > 1) { + # omnibus::say("Collapsing points...") + # pb <- utils::txtProgressBar(min = 0, max = sets, initial = 0, style = 3, width = 30) + # } - for (set in seq_len(sets)) { - - if ((verbose | faster("verbose")) & sets > 1) utils::setTxtProgressBar(pb, set) - - index <- (nAtATime * (set - 1) + 1):(min(nAtATime * set, size)) - thisXs <- xs[index] - thisYs <- ys[index] - if (!is.null(zlim)) thisZs <- zs[index] - - if (is.null(zlim)) { - coords <- data.table::data.table(cat = index, x = thisXs, y = thisYs) - } else { - coords <- data.table::data.table(cat = index, x = thisXs, y = thisYs, z = thisZs) - } - coords[ , coords := do.call(paste, c(.SD, sep = "|"))] - coords <- coords[ , "coords", drop = FALSE] - - tf <- tempfile(fileext = ".txt") - data.table::fwrite(coords, tf, col.names = FALSE, quote = FALSE, scipen = 20L) - - args <- list( - "v.in.ascii", - input = tf, - output = srcs[set], - format = "point", - separator = "pipe", - cat = 1, x = 2, y = 3, - flags = c(.quiet(), "overwrite", "t", "n") - ) - if (!is.null(zlim)) { - args$flags <- c(args$flags, "z") - args$z <- 4 - } - do.call(rgrass::execGRASS, args = args) - - # if (set > 1) { - - # topCat <- min(nAtATime * set, size) - # srcs[set] <- .vIncrementCats(srcs[set], add = topCat) - - # } - - } + # if (nSrcs == 1L) { + # src <- srcs + # } else { + + # for (set in seq_len(sets)) { - if ((verbose | faster("verbose")) & sets > 1) close(pb) + # if ((verbose | faster("verbose")) & sets > 1L) utils::setTxtProgressBar(pb, set) - ### use v.patch to combine subsets of points - # seems like we can combine at least 11 vectors at a time, but not a lot at a time - srcsAtATime <- 10L # number of sources to combine at a time (plus the running `x` source) + # index <- (1 + srcsAtATime * (set - 1)) : min(nSrcs, set * srcsAtATime) + # srcIn <- srcs[index] + # input <- paste(srcIn, collapse = ",") + # if (set > 1) input <- paste0(src, ",", input) + + # src <- .makeSourceName("spatSample_v_patch", "vector") + + # rgrass::execGRASS( + # cmd = "v.patch", + # input = input, + # output = src, + # flags = c(.quiet(), "overwrite", "b", "n") # "n" ==> no topology + # # flags = c(.quiet(), "overwrite") # "n" ==> input has topology, "b" ==> don't build topology + # ) + + # .rm(srcIn, type = "vector", warn = FALSE) - nSrcs <- length(srcs) - sets <- ceiling(nSrcs / srcsAtATime) - - if ((verbose | faster("verbose")) & sets > 1) { - omnibus::say("Collapsing points...") - pb <- utils::txtProgressBar(min = 0, max = sets, initial = 0, style = 3, width = 30) - } + # } - for (set in seq_len(sets)) { + # if ((verbose | faster("verbose")) & sets > 1) close(pb) - if ((verbose | faster("verbose")) & sets > 1) utils::setTxtProgressBar(pb, set) + # } # if > 1 set - index <- (1 + srcsAtATime * (set - 1)) : min(nSrcs, set * srcsAtATime) - srcIn <- srcs[index] - input <- paste(srcIn, collapse = ",") - if (set > 1) input <- paste0(src, ",", input) + # # if strata is not NULL + # } else { - src <- .makeSourceName("spatSample_v_patch", "vector") - - rgrass::execGRASS( - cmd = "v.patch", - input = input, - output = src, - flags = c(.quiet(), "overwrite") - ) - - } + # if (size > 200000) .message("spatSample_strata", "Using `strata` when selecting a large number of points can take a long time.") - .rm(srcs, type = "vector", warn = FALSE) - if ((verbose | faster("verbose")) & sets > 1) close(pb) + # src <- .makeSourceName("spatSample_v_random", "vector") - # if strata is not NULL - } else { - - if (size > 200000) .message("spatSample_strata", "Using `strata` when selecting a large number of points can take a long time.") + # args <- list( + # cmd = "v.random", + # output = src, + # npoints = size, + # flags = c(.quiet(), "overwrite") + # ) - src <- .makeSourceName("spatSample_v_random", "vector") + # if (!is.null(seed)) { + # seed <- round(seed) + # args$seed <- seed + # } - args <- list( - cmd = "v.random", - output = src, - npoints = size, - flags = c(.quiet(), "overwrite") - ) + # if (!is.null(strata)) { + # args$restrict <- sources(strata) + # if (byStratum) args$flags <- c(args$flags, "a") + # } - if (!is.null(seed)) { - seed <- round(seed) - args$seed <- seed - } + # if (!is.null(zlim)) { + # args$zmin <- zlim[1L] + # args$zmax <- zlim[2L] + # args$flags <- c(args$flags, "z") + # } - if (!is.null(strata)) { - args$restrict <- sources(strata) - if (byStratum) args$flags <- c(args$flags, "a") - } + # # if (!is.null(seed)) args$seed <- seed + # args$seed <- round(1E9 * stats::runif(1)) - if (!is.null(zlim)) { - args$zmin <- zlim[1L] - args$zmax <- zlim[2L] - args$flags <- c(args$flags, "z") - } + # # args$flags <- c(args$flags, "b") ### do not create topology... problems? YES! + # do.call(rgrass::execGRASS, args = args) - # if (!is.null(seed)) args$seed <- seed - args$seed <- round(1E9 * stats::runif(1)) + # # return coordinates + # if (xy) { + # out <- .crdsVect(src, z = is.3d(x), gtype = "points") + # } - # args$flags <- c(args$flags, "b") ### do not create topology... problems? YES! - do.call(rgrass::execGRASS, args = args) + # } # if strata is not NULL - # return coordinates - if (xy) { - out <- .crdsVect(src, z = is.3d(x), gtype = "points") - } + if (verbose) omnibus::say("Placing points...") + src <- .makeSourceName("spatSample", "vector") + args <- list( + cmd = "v.random", + output = src, + npoints = size, + flags = c(.quiet(), "overwrite", "b") + ) + + if (!is.null(seed)) { + seed <- round(seed) + args$seed <- seed + } - } # if strata is not NULL + do.call(rgrass::execGRASS, args = args) + if (xy) out <- .crdsVect(src, z = !is.null(zlim), gtype = "points") # extract values from raster if (values | cats) { + # rgrass::execGRASS( + # cmd = "v.build", + # map = src, + # flags = c(.quiet(), "overwrite") + # ) + vals <- .extractFromRasterAtPoints(x = x, y = src, cats = cats, verbose = verbose) if (exists("out", inherits = FALSE)) { @@ -255,13 +293,22 @@ methods::setMethod( } if (as.points) { + + # build topology + rgrass::execGRASS( + "v.build", + map = src, + option = "build", + flags = c(.quiet(), "overwrite") + ) + .vAttachDatabase(src) if (exists("out", inherits = FALSE)) { # info <- .vectInfo(src) # nGeometries <- info$nGeometries # n <- nGeometries / size # out <- .makeGVector(src, table = out, cats = rep(1:size, each = n)) - out <- .makeGVector(src, table = out) + out <- .makeGVector(src, table = out, cats = 1:size) } else { out <- .makeGVector(src, cats = 1:size) } diff --git a/README.md b/README.md index 8abd3fba..c34b1467 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,8 @@ Alternatively, you can install the development version from: To use `fasterRaster` you must install [GRASS version 8.3+](https://grass.osgeo.org/) on your operating system. **You will need to use the stand-alone installer, not the Open Source Geospatial (OS Geo) installer.** +Optional: A few functions in **fasterRaster** require **GRASS** "addon" modules, which do not come bundled with **GRASS**. You do not need to install these addons if you do not use functions that call them. A list of functions that require addons can be seen in the "addons" vignette (in **R**, use `vignette("addons", package = "fasterRaster")`). This vignette also explains how to install addons. + # Vignettes **fasterRaster** comes with four user-oriented vignettes: @@ -47,7 +49,7 @@ To use `fasterRaster` you must install [GRASS version 8.3+](https://grass.osgeo. * ["Getting started"](https://adamlilith.github.io/fasterRaster/articles/fasterRaster.html) * [Types of `GRaster`s](https://adamlilith.github.io/fasterRaster/articles/GRasters.html) * [Making **fasterRaster** faster](https://adamlilith.github.io/fasterRaster/articles/faster_fasterRaster.html) -* [Installing addons](https://adamlilith.github.io/fasterRaster/articles/fasterRaster_addons.html) +* [Installing addons](https://adamlilith.github.io/fasterRaster/articles/addons.html) # An example diff --git a/_pkgdown.yml b/_pkgdown.yml index 63c29ad1..2e102a1a 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -19,7 +19,7 @@ articles: contents: - GRasters - faster_fasterRaster - - fasterRaster_addons + - addons - title: For Developers desc: Vignettes for developers diff --git a/inst/pkgdown.yml b/inst/pkgdown.yml index ea491cd0..214532f0 100644 --- a/inst/pkgdown.yml +++ b/inst/pkgdown.yml @@ -2,14 +2,14 @@ pandoc: 3.1.11 pkgdown: 2.1.1 pkgdown_sha: ~ articles: + addons: addons.html faster_fasterRaster: faster_fasterRaster.html fasterRaster: fasterRaster.html - fasterRaster_addons: fasterRaster_addons.html GRasters: GRasters.html hidden_functions: hidden_functions.html projects_mapsets: projects_mapsets.html regions: regions.html -last_built: 2024-11-21T05:53Z +last_built: 2024-11-25T06:03Z urls: reference: https://github.com/adamlilith/fasterRaster/reference article: https://github.com/adamlilith/fasterRaster/articles diff --git a/man/addons.Rd b/man/addons.Rd index d02f8220..27c5e67f 100644 --- a/man/addons.Rd +++ b/man/addons.Rd @@ -21,7 +21,7 @@ addons(x = NULL, onFail = "fail", verbose = TRUE) Logical. } \description{ -This function tests to see if the "addons" directory specified using \code{\link[=faster]{faster()}} actually exists, and if a particular \strong{GRASS} \verb{addons module is available. The }addons\verb{folder and module must exists for methods that rely on particular **GRASS**}addons` to work. +This function tests to see if the "addons" directory specified using \code{\link[=faster]{faster()}} actually exists, and if a particular \strong{GRASS} \verb{addons module is available. The }addons\verb{folder and module must exists for methods that rely on particular **GRASS**}addons\verb{to work. See}vignette("addons", package = "fasterRaster")`. } \examples{ if (grassStarted()) { @@ -36,3 +36,6 @@ if (exten) print("Extension `v.centerpoints` is installed.") } } +\seealso{ +\code{vignette("addons", package = "fasterRaster")} +} diff --git a/man/centroids.Rd b/man/centroids.Rd index 952671ff..4c3363e8 100644 --- a/man/centroids.Rd +++ b/man/centroids.Rd @@ -38,7 +38,9 @@ Partial matching is used and case is ignored.} A points \code{GVector}. } \description{ -This function locates the centroid of each geometry of a \code{GVector}. \strong{To use this function, you must a) have correctly specified the \code{addonsDir} option using \code{\link[=faster]{faster()}}, and b) installed the \strong{GRASS} addon \code{v.centerpoint}.} See \code{\link[=addons]{addons()}} and \code{vignette("addons", package = "fasterRaster")}. +This function locates the centroid of each geometry of a \code{GVector}. + +\strong{To use this function}, you must a) have correctly specified the \code{addonsDir} option using \code{\link[=faster]{faster()}}, and b) installed the \strong{GRASS} addon \code{v.centerpoint}. See \code{\link[=addons]{addons()}} and \code{vignette("addons", package = "fasterRaster")}. } \examples{ if (grassStarted()) { diff --git a/man/fastData.Rd b/man/fastData.Rd index cb1e224f..bcf1df8e 100644 --- a/man/fastData.Rd +++ b/man/fastData.Rd @@ -20,8 +20,8 @@ Spatial vectors (objects of class \code{sf} from the \strong{sf} package): Rasters (objects of class \code{SpatRaster} from the \strong{terra} package, saved as GeoTIFF files): \itemize{ \item \link{madChelsa}: Bioclimatic variables -\item \link{madCover}: Land cover (also see \code{madCoverCats}) -\item +\item \link{madCover}: Land cover +\item \code{\link{madElev}}: Elevation \item \link{madForest2000}: Forest cover in year 2000 \item \link{madForest2014}: Forest cover in year 2014 \item \link{madLANDSAT}: Surface reflectance in 2023 @@ -30,9 +30,9 @@ Rasters (objects of class \code{SpatRaster} from the \strong{terra} package, sav Data frames \itemize{ -\item \link{appFunsTable}: Table of functions usable by \code{\link[=app]{app()}}. -\item \link{madCoverCats}: Land cover values and categories. -\item \link{vegIndices}: Vegetation indices that can be calculated with \code{\link[=vegIndex]{vegIndex()}}. +\item \link{appFunsTable}: Table of functions usable by \code{\link[=app]{app()}} +\item \link{madCoverCats}: Land cover values and categories for \link{madCover} +\item \link{vegIndices}: Vegetation indices that can be calculated with \code{\link[=vegIndex]{vegIndex()}} }} } \value{ diff --git a/man/fasterRaster.Rd b/man/fasterRaster.Rd index f16337e1..ff6f2442 100644 --- a/man/fasterRaster.Rd +++ b/man/fasterRaster.Rd @@ -17,7 +17,7 @@ \item \code{\link[=fast]{fast()}}: Convert a \code{SpatRaster}, \code{SpatVector}, or \code{sf} vector to \strong{fasterRaster}'s raster format (\code{GRaster}s) or vector format (\code{GVector}s), or load one from a file \item \code{\link[=rast]{rast()}}, \code{\link[=vect]{vect()}}, and \code{\link[=st_as_sf]{st_as_sf()}}: Convert \code{GRaster}s and \code{GVector}s to \code{SpatRaster}s, \code{SpatVector}s, or \code{sf} vectors \item \code{\link[=writeRaster]{writeRaster()}} and \code{\link[=writeVector]{writeVector()}}: Save \code{GRaster}s or \code{GVector}s to disk -\item \code{\link[=addons]{addons()}}: Test to see if the \code{addons} directory is correct and if a particular addon \strong{GRASS} module is installed. +\item \code{\link[=addons]{addons()}}: Test if the \code{addons} directory is correct and if a particular addon \strong{GRASS} module is installed. } } @@ -46,8 +46,8 @@ \item \code{\link[=nrow]{nrow()}}: Number of rows \item \code{\link[=nlevels]{nlevels()}}: Number of categories \item \code{\link[=res]{res()}}, \code{\link[=res3d]{res3d()}}, \code{\link[=xres]{xres()}}, \code{\link[=yres]{yres()}}, and \code{\link[=zres]{zres()}}: Spatial resolution -\item \code{\link[=sources]{sources()}}: Name of the \code{GRaster} in \strong{GRASS} -\item +\item \code{\link[=sources]{sources()}}: Name of the raster file in the \strong{GRASS} cache +\item \code{\link[=topology]{topology()}}: Dimensionally (2D or 3D) \item \code{\link[=zext]{zext()}}: Vertical extent \item \code{\link[=zres]{zres()}}: Vertical resolution } @@ -162,7 +162,7 @@ Operations on \code{GRaster}s \item \code{\link[=flow]{flow()}}: Identify watershed basins and direction and accumulation of flow \item \code{\link[=flowPath]{flowPath()}}: Path of water flow across a landscape \item \code{\link[=geomorphons]{geomorphons()}}: Identify terrain feature types -\item \code{\link[=shade]{hillshade()}}: Create a hillshade \code{GRaster} +\item \code{\link[=hillshade]{hillshade()}}: Create a hillshade \code{GRaster} \item \code{\link[=horizonHeight]{horizonHeight()}}: Horizon height \item \code{\link[=sun]{sun()}}: Solar radiance and irradiance \item \code{\link[=ruggedness]{ruggedness()}}: Terrain Ruggedness Index @@ -232,9 +232,9 @@ Operations on \code{GRaster}s \item \code{\link[=ncol]{ncol()}}: Number of fields \item \code{\link[=ngeom]{ngeom()}}: Number of geometries (points, lines, polygons) \item \code{\link[=nrow]{nrow()}}: Number of rows in a vector data table -\item \code{\link[=nsubgeom]{nsubgeom()}}: Number of subgeometries (points, lines, polygons that make up single- and multipart geometries) -\item \code{\link[=sources]{sources()}}: Name of the vector in \strong{GRASS} -\item +\item \code{\link[=nsubgeom]{nsubgeom()}}: Number of sub-geometries (points, lines, polygons that make up single- and multipart geometries) +\item \code{\link[=sources]{sources()}}: Name of the vector file in the \strong{GRASS} cache +\item \code{\link[=topology]{topology()}}: Dimensionally (2D or 3D) \item \code{\link[=zext]{zext()}}: Vertical extent } } @@ -278,7 +278,7 @@ Operations on \code{GRaster}s \item \code{\link[=intersect]{intersect()}} or \code{*}: Intersection of two \code{GVectors} \item \code{\link[=kernel]{kernel()}}: Kernel density estimator of points \item \code{\link[=missing.cases]{missing.cases()}}: Find rows of a \code{GVector}'s data table that have at least \code{NA} in them -\code{\link[fasterRaster]{names<-}}: Assign names to columns of a \code{GVector}s data table +\item \code{\link[fasterRaster]{names<-}}: Assign names to columns of a \code{GVector}s data table \item \code{\link[=project]{project()}}: Change coordinate reference system \item \code{\link[=rasterize]{rasterize()}}: Convert a \code{GVector} to a \code{GRaster} \item \code{\link[=rbind]{rbind()}}: Combine \code{GVectors} diff --git a/man/hillshade.Rd b/man/hillshade.Rd index e924d47a..ade4ad40 100644 --- a/man/hillshade.Rd +++ b/man/hillshade.Rd @@ -46,6 +46,3 @@ plot(hs) } } -\seealso{ -\code{\link[terra:shade]{terra::shade()}} -} diff --git a/vignettes/fasterRaster_addons.Rmd b/vignettes/addons.Rmd similarity index 84% rename from vignettes/fasterRaster_addons.Rmd rename to vignettes/addons.Rmd index 3cc80677..1e58fc2b 100644 --- a/vignettes/fasterRaster_addons.Rmd +++ b/vignettes/addons.Rmd @@ -20,7 +20,7 @@ fig.path = 'man/figures/' 1. Installing modules: The easiest (only?) way to do this is to start **GRASS** (not in **R** through **fasterRaster**, but actually start **GRASS**), then use the `Settings` menu's `Addon extensions` option, then select `Install extensions from addons [g.extension]`. **GRASS** should display a list of addons you can install. -2. Once you have the desired extension(s) installed, you can use **fasterRaster** functions that call them. To do this, you need to specify the `addons` folder *before* starting **GRASS** (i.e., before the first time you use the [fast()] function to load a raster or vector). Use [faster()] to tell **fasterRaster** where this folder is. The folder will vary by operating system. On a Windows machine, it will be something like: +2. Once you have the desired extension(s) installed, you can use **fasterRaster** functions that call them. To do this, you need to specify the `addons` folder *before* starting **GRASS** (i.e., before the first time you use the `fast()` function to load a raster or vector). Use `faster()` to tell **fasterRaster** where this folder is. The folder will vary by operating system. On a Windows machine, it will be something like: ``` C:/Users/your_windows_user_name/AppData/Roaming/GRASS8/addons @@ -29,14 +29,14 @@ C:/Users/your_windows_user_name/AppData/Roaming/GRASS8/addons You can set the addons folder using `faster(addonsDir = "C:/Users/your_windows_user_name/AppData/Roaming/GRASS8/addons")`. ## Validating addons -You can test to see if the `addons` folder is correct using [addons()]. You can also see if a particular addon module was installed correctly using the same function using, for example, `addons("addon.name")`. +You can test to see if the `addons` folder is correct using `addons()`. You can also see if a particular addon module was installed correctly using the same function using, for example, `addons("v.centerpoint")`. ## **fasterRaster** functions that need addons These functions must have the specified addon to work. | **Function** | **addon** | | --------------------------|--------------------| - | `centroids()` | `v.centerpoints` | + | `centroids()` | `v.centerpoint` | diff --git a/vignettes/fasterRaster.Rmd b/vignettes/fasterRaster.Rmd index bc48822c..8279b2ed 100644 --- a/vignettes/fasterRaster.Rmd +++ b/vignettes/fasterRaster.Rmd @@ -37,7 +37,7 @@ remotes::install_github("adamlilith/fasterRaster", dependencies = TRUE) **fasterRaster** uses **GRASS** to do its operations. You will need to install **GRASS** using the "stand-alone" installer, available through the [GRASS GIS](https://grass.osgeo.org/). *Be sure to use the "stand-alone" installer, not the "OSGeo4W" installer!* -Optional: A few functions in **fasterRaster** require **GRASS** "addon" modules, which do not come bundled with **GRASS**. You do not need to install these addons if you do not use functions that call them. A list of functions that require addons can be seen in the "addons" vignette (in **R**, use `vignette("addons", package = "fasterRaster")). This vignette also explains how to install addons. +Optional: A few functions in **fasterRaster** require **GRASS** "addon" modules, which do not come bundled with **GRASS**. You do not need to install these addons if you do not use functions that call them. A list of functions that require addons can be seen in the "addons" vignette (in **R**, use `vignette("addons", package = "fasterRaster")`). This vignette also explains how to install addons. ## Starting a **fasterRaster** session