Skip to content

Commit

Permalink
Clean up checks, add README
Browse files Browse the repository at this point in the history
  • Loading branch information
mikemahoney218 committed Aug 25, 2023
1 parent 71f9d83 commit 907b046
Show file tree
Hide file tree
Showing 25 changed files with 2,191 additions and 67 deletions.
2 changes: 2 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
^_pkgdown\.yml$
^docs$
^pkgdown$
^README\.Rmd$
^man-roxygen$
23 changes: 15 additions & 8 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
Package: rsi
Title: What the Package Does (One Line, Title Case)
Title: Utilities for Retrieving Satellite Imagery, Calculating Spectral
Indices, and Wrangling the Outputs
Version: 0.0.0.9000
Authors@R:
person("First", "Last", , "[email protected]", role = c("aut", "cre"),
comment = c(ORCID = "YOUR-ORCID-ID"))
Description: What the package does (one paragraph).
Authors@R: c(
person("Michael", "Mahoney", , "[email protected]", role = c("aut", "cre"),
comment = c(ORCID = "0000-0003-2402-304X")),
person("Permian Global", role = c("cph", "fnd"))
)
Description: Tools for downloading spatial data from spatiotemporal asset
catalogs ('STAC') and computing standard spectral indices from raster data.
License: MIT + file LICENSE
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
Depends:
R (>= 2.10)
Imports:
glue,
jsonlite,
proceduralnames,
rlang,
Expand All @@ -23,4 +25,9 @@ Suggests:
testthat (>= 3.0.0),
withr
Config/testthat/edition: 3
Encoding: UTF-8
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
URL: https://github.com/Permian-Global-Research/rsi
BugReports: https://github.com/Permian-Global-Research/rsi/issues
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export(get_sentinel1_imagery)
export(get_sentinel2_imagery)
export(get_stac_data)
export(landsat_mask_function)
export(landsat_platform_filter)
export(query_planetary_computer)
export(sentinel2_mask_function)
export(spectral_indices)
Expand Down
26 changes: 20 additions & 6 deletions R/data.R
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
#' Sentinel-2 band mapping
#'
#' This object is a named list, with names corresponding to Sentinel-2 band
#' names and values corresponding to band names in `spectral_indices`.
#' This object is a named list of character vectors, with names corresponding to
#' Sentinel-2 band names and values corresponding to band names in
#' `spectral_indices`.
#'
#' @template band_mappings
"sentinel2_band_mapping"

#' Sentinel-1 band mapping
#'
#' This object is a named list, with names corresponding to Sentinel-1 band
#' names and values corresponding to band names in `spectral_indices`.
#' This object is a named list of character vectors, with names corresponding to
#' Sentinel-1 band names and values corresponding to band names in
#' `spectral_indices`.
#'
#' @template band_mappings
"sentinel1_band_mapping"

#' Landsat band mapping
#'
#' This object is a named list, with names corresponding to Landsat band
#' names and values corresponding to band names in `spectral_indices`.
#' This object is a named list of character vectors, with names corresponding to
#' Landsat band names and values corresponding to band names in
#' `spectral_indices`.
#'
#' @template band_mappings
"landsat_band_mapping"

#' Landsat band mapping
#'
#' This object is structured slightly differently from other band mapping
#' objects; it is a list of named lists, whose names correspond to DEM
#' collections available within a given STAC catalog. Those named lists are
#' then more standard band mapping objects, containing character vectors with
#' names corresponding to asset names and values equal to `elevation`.
#'
#' @template band_mappings
"dem_band_mapping"
18 changes: 15 additions & 3 deletions R/filters.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
#' @param platforms,bands Names of the instruments (for `platforms`) or spectra
#' (for `bands`) indices must contain.
#' @param indices The data frame to filter. Must contain the relevant column.
#' @param `operand` A function defining how to apply this filter.
#' @param operand A function defining how to apply this filter.
#' For instance, `operand = all` means that the index must contain all the
#' `platforms` or `bands` provided, while `operand = any` means that the index
#' must contain at least one of the `platforms` or `bands` provided.
#' @param type What type of query is this? If `filter`, then indices are
#' returned if all/any the bands they use (depending on `operand`) are in
#' `bands`. If `search`, then indices are returned if all/any of `bands` are in
#' the bands they use.
#'
#' @examples
#' filter_platforms(platforms = "Sentinel-2")
Expand Down Expand Up @@ -36,14 +40,22 @@ filter_platforms <- function(indices = spectral_indices(),
#' @export
filter_bands <- function(indices = spectral_indices(),
bands = unique(unlist(spectral_indices()$bands)),
operand = c("all", "any")) {
operand = c("all", "any"),
type = c("filter", "search")) {
bands <- rlang::arg_match(bands, multiple = TRUE)
type <- rlang::arg_match(type)
if (missing(operand)) {
operand <- rlang::arg_match(operand)
}
ret_indices <- vapply(
indices$bands,
function(x) rlang::exec(operand, bands %in% x),
function(x) {
if (type == "search") {
rlang::exec(operand, bands %in% x)
} else {
rlang::exec(operand, x %in% bands)
}
},
logical(1)
)
indices[ret_indices, , drop = FALSE]
Expand Down
39 changes: 28 additions & 11 deletions R/get_stac_data.R
Original file line number Diff line number Diff line change
Expand Up @@ -90,25 +90,40 @@
#' downloaded data and the final output images; this means that some common
#' options (for instance, `PREDICTOR=3`) may cause errors if bands are of
#' varying data types.
#' @param platforms The names of Landsat satellites to download imagery from.
#' These do not correspond to the `platforms` column in [spectral_indices()];
#' the default argument of `c("landsat-9", "landsat-8")` corresponds to
#' the `Landsat-OLI` value in that column.
#'
#' @returns `output_filename`, unchanged.
#'
#' @examplesIf interactive()
#' aoi <- sf::st_point(c(-74.912131, 44.080410))
#' #' aoi <- sf::st_point(c(-74.912131, 44.080410))
#' aoi <- sf::st_set_crs(sf::st_sfc(aoi), 4326)
#' aoi <- sf::st_buffer(sf::st_transform(aoi, 5070), 100)
#'
#' get_stac_data(aoi,
#' start_date = "2022-06-01",
#' end_date = "2022-06-30",
#' pixel_x_size = 30,
#' pixel_y_size = 30,
#' asset_names = c(
#' "red", "blue", "green"
#' ),
#' stac_source = "https://planetarycomputer.microsoft.com/api/stac/v1/",
#' collection = "landsat-c2-l2",
#' query_function = query_planetary_computer,
#' mask_band = "qa_pixel",
#' mask_function = landsat_mask_function,
#' item_filter_function = landsat_platform_filter,
#' platforms = c("landsat-9", "landsat-8")
#' )
#'
#' # or, mostly equivalently (will download more bands):
#' landsat_image <- get_landsat_imagery(
#' aoi,
#' start_date = "2022-06-01",
#' end_date = "2022-08-30",
#' pixel_x_size = 30,
#' pixel_y_size = 30,
#' asset_names = sentinel2_band_mapping$planetary_computer_v1,
#' stac_source = attr(sentinel2_band_mapping$planetary_computer_v1, "stac_source"),
#' collection = attr(sentinel2_band_mapping$planetary_computer_v1, "collection"),
#' query_function = download_planetary_computer,
#' mask_band = attr(sentinel2_band_mapping$planetary_computer_v1, "mask_band"),
#' mask_function = sentinel2_mask_function
#' end_date = "2022-08-30"
#' )
#'
#' @export
Expand Down Expand Up @@ -181,6 +196,8 @@ get_stac_data <- function(aoi,
items <- item_filter_function(items, ...)
}

if (is.null(names(asset_names))) names(asset_names) <- asset_names

items_urls <- lapply(
names(asset_names),
function(asset_name) suppressWarnings(rstac::assets_url(items, asset_name))
Expand Down Expand Up @@ -278,7 +295,7 @@ get_stac_data <- function(aoi,
out_file <- file.path(download_dir, paste0(toupper(band_name), ".tif"))

do.call(
getFromNamespace(composite_function, "terra"),
utils::getFromNamespace(composite_function, "terra"),
list(
x = terra::rast(downloaded_bands[[band_name]]),
na.rm = TRUE,
Expand Down
8 changes: 8 additions & 0 deletions R/landsat_platform_filter.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
#' Filter Landsat features to only specific platforms
#'
#' @param items A `STACItemCatalog` containing some number of features
#' @param platforms A vector of acceptable platforms, for instance `landsat-9`.
#' Note that this refers to satellite names, and _not_ to platforms in
#' `spectral_indices()`.
#'
#' @export
landsat_platform_filter <- function(items, platforms) {
acceptable_platforms <- vapply(
items$features,
Expand Down
13 changes: 13 additions & 0 deletions R/rsi-package.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#' @keywords internal
"_PACKAGE"

## usethis namespace: start
## usethis namespace: end
NULL

utils::globalVariables(c(
"dem_band_mapping",
"landsat_band_mapping",
"sentinel1_band_mapping",
"sentinel2_band_mapping"
))
20 changes: 10 additions & 10 deletions R/stack_rasters.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
#' as though they were loaded one after another into a GIS. The VRT is fast
#' to create and does not require much space, but does require the input rasters
#' not be moved or altered. Run
#' `sf::gdal_utils("warp", raster_path, some_path.tif)` to turn the output VRT
#' into a standalone TIF file.
#' `sf::gdal_utils("warp", output_filename, "some_path.tif")` to turn the output
#' VRT into a standalone TIF file.
#'
#' @param rasters A list of rasters to combine into a single multi-band raster,
#' either as SpatRaster objects from [terra::rast()] or character file paths
#' to files that can be read by [terra::rast()]. Rasters will be "stacked" upon
#' one another, preserving values. They must share CRS.
#' @param raster_path The location to save the final "stacked" raster. Must be
#' @param output_filename The location to save the final "stacked" raster. Must be
#' a VRT file.
#' @inheritParams rlang::args_dots_empty
#' @param resolution Numeric of length 2, representing the target X and Y
Expand All @@ -30,20 +30,20 @@
#' when given a character vector of band names, returns a character vector of
#' the same length containing new band names.
#'
#' @returns `raster_path`, unchanged.
#' @returns `output_filename`, unchanged.
#'
#' @examples
#' stack_rasters(
#' list(
#' system.file("rasters/ta.tif", package = "lignin"),
#' system.file("rasters/ta.tif", package = "lignin")
#' system.file("rasters/dpdd.tif", package = "rsi"),
#' system.file("rasters/example_sentinel1", package = "rsi")
#' ),
#' tempfile(fileext = ".vrt")
#' )
#'
#' @export
stack_rasters <- function(rasters,
raster_path,
output_filename,
...,
resolution,
extent,
Expand All @@ -52,7 +52,7 @@ stack_rasters <- function(rasters,
band_names) {
rlang::check_dots_empty()

out_dir <- dirname(raster_path)
out_dir <- dirname(output_filename)

if (!(reference_raster %in% seq_along(rasters) ||
reference_raster %in% names(rasters))) {
Expand Down Expand Up @@ -204,7 +204,7 @@ stack_rasters <- function(rasters,
unlist(vrt_bands),
vrt_container[(band_def[[2]] + 1):length(vrt_container)]
),
raster_path
output_filename
)
raster_path
output_filename
}
Loading

0 comments on commit 907b046

Please sign in to comment.