#' Create a grid GVector
#'
#' @description This function creates a `GVector` of "wall-to-wall" cells (like a lattice). The input can be a `GVector` or `GRaster`, which provides the extent of the output.
#'
#' @param x A `GRaster` or `GVector`.
#'
#' @param nx,ny Integer or numeric:
#' * If `use` is `"number"`, then these values represent the number of rows and columns in the grid.
#' * If `use` is `size`, then these values represent the size of the cells in the x- and y-dimensions.
# In either case, either `nx` or `ny` can be left `NULL` if the other value is defined. In this case, then the size of the cells in the opposing direction will be the same as the size in the direction that is defined. For example, if `nx` is 10 and `use` is `number`, then the size of the cells in the y-dimension will be the same as the size in the x-dimension. The extent of the output will be expanded in the eastward and southward directions to accommodate an integer number of cells in the desired direction.
#'
#' @param use Character: How to generate the grid. If this is `number` (default), then `nx` and `ny` are taken to be the number of grid cells. If `size`, then `nx` and `ny` are taken to be the size of the grid cells.
#'
#' @param angle Numeric: Degrees by which to rotate grid (from north, clockwise).
#'
#' @returns A `GVector`.
#'
#' @example man/examples/ex_grid_hexagons.r
#'
#' @seealso [hexagons()], module `v.mkgrid` in **GRASS**
#'
#' @aliases grid
#' @rdname grid
#' @exportMethod grid
methods::setMethod(
f = "grid",
signature = c(x = "GRaster"),
function(x, nx = NULL, ny = NULL, use = "number", angle = 0) .grid(x, nx = nx, ny = ny, use = use, angle = angle)
)
#' @aliases grid
#' @rdname grid
#' @exportMethod grid
methods::setMethod(
f = "grid",
signature = c(x = "GVector"),
function(x, nx = NULL, ny = NULL, use = "number", angle = 0) .grid(x, nx = nx, ny = ny, use = use, angle = angle)
)
#' @noRd
.grid <- function(x, nx, ny, use, angle) {
.locationRestore(x)
.region(x)
use <- omnibus::pmatchSafe(use, c("number", "size"), nmax = 1L)
extent <- ext(x, vector = TRUE)
# calculate cell number and re-calibrate GRASS region
if (is.null(nx) & is.null(ny)) {
stop("At least one of `nx` or `ny` must be defined.")
} else if (!is.null(nx) & is.null(ny)) {
if (use == "number") {
dim <- extent[2L] - extent[1L]
xsize <- ysize <- dim / nx
} else if (use == "size") {
xsize <- ysize <- nx
}
ycellsFract <- (extent[4L] - extent[3L]) / ysize
ycells <- ceiling(ycellsFract)
delta <- 0.5 * (ycells - ycellsFract)
newNorth <- extent[4L] + delta * ysize
newSouth <- extent[3L] - delta * ysize
.regionExt(c(extent[1L], extent[2L], newSouth, newNorth), respect = "dimensions")
} else if (is.null(nx) & !is.null(ny)) {
if (use == "number") {
dim <- extent[4L] - extent[3L]
xsize <- ysize <- dim / ny
} else if (use == "size") {
xsize <- ysize <- ny
}
xcellsFract <- (extent[2L] - extent[1L]) / xsize
xcells <- ceiling(xcellsFract)
delta <- 0.5 * (xcells - xcellsFract)
newWest <- extent[1L] - delta * xsize
newEast <- extent[2L] + delta * xsize
.regionExt(c(newWest, newEast, extent[3L], extent[4L]), respect = "dimensions")
} else {
if (use == "number") {
xsize <- (extent[2L] - extent[1L]) / nx
ysize <- (extent[4L] - extent[3L]) / ny
} else if (use == "size") {
xsize <- nx
ysize <- ny
xcellsFract <- (extent[2L] - extent[1L]) / xsize
ycellsFract <- (extent[4L] - extent[3L]) / ysize
xcells <- ceiling(xcellsFract)
ycells <- ceiling(ycellsFract)
xdelta <- 0.5 * (xcells - xcellsFract)
ydelta <- 0.5 * (ycells - ycellsFract)
newWest <- extent[1L] - xdelta * xsize
newEast <- extent[2L] + xdelta * xsize
newNorth <- extent[4L] + ydelta * ysize
newSouth <- extent[3L] - ydelta * ysize
.regionExt(c(newWest, newEast, newSouth, newNorth), respect = "dimensions")
}
}
src <- .makeSourceName("v_mkgrid", "vector")
args <- list(
cmd = "v.mkgrid",
map = src,
position = "region",
box = c(xsize, ysize),
flags = c(.quiet(), "overwrite")
)
angle <- 360 - angle
if (!(angle %in% c(0, 360))) args$angle <- angle
do.call(rgrass::execGRASS, args = args)
.makeGVector(src)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.