From 5259f43b60e86e8b33cbae2ff93d22507c6cdeed Mon Sep 17 00:00:00 2001 From: Andrew Gene Brown Date: Wed, 2 Nov 2022 12:32:58 -0700 Subject: [PATCH] CRAN Release 0.1.0 (#3) * for CRAN * Add `gd_is_initialized()` * Add CRAN installation instructions * System requirements are Python >=3.6 (for 'geedim') * Spelling * squote * squote (2) * link * docs * fix * docs * donttest: gd_initialize() can take several seconds by itself * refactor ee usage to avoid notes * alt test for geedim presence in tests (does not invoke load of missing module) --- .Rbuildignore | 1 + DESCRIPTION | 10 ++++---- NAMESPACE | 1 + NEWS.md | 2 ++ R/AAAA.R | 6 +---- R/composite.R | 15 +++++++++++- R/download.R | 29 +++++++++++++++++++++++ R/enums.R | 29 +++++++++++++++++++++++ R/from.R | 15 ++++++++++++ R/hello.R | 29 +++++++++++++++-------- R/projection.R | 7 +++++- R/regions.R | 7 ++++++ R/search.R | 45 +++++++++++++++++++++++++++++++++++- README.Rmd | 9 +++++++- README.md | 40 ++++++-------------------------- inst/WORDLIST | 2 +- inst/tinytest/test_rgeedim.R | 4 ++-- man/enum.Rd | 30 ++++++++++++++++++++++++ man/from.Rd | 20 ++++++++++++++++ man/gd_authenticate.Rd | 6 ++++- man/gd_band_names.Rd | 8 +++++++ man/gd_band_properties.Rd | 8 +++++++ man/gd_composite.Rd | 15 ++++++++++++ man/gd_download.Rd | 31 +++++++++++++++++++++++++ man/gd_footprint.Rd | 8 +++++++ man/gd_initialize.Rd | 12 +++++++--- man/gd_projection.Rd | 8 +++++++ man/gd_properties.Rd | 16 +++++++++++++ man/gd_region.Rd | 9 ++++++++ man/gd_search.Rd | 13 +++++++++++ man/rgeedim-package.Rd | 8 +++++-- 31 files changed, 379 insertions(+), 64 deletions(-) diff --git a/.Rbuildignore b/.Rbuildignore index f76d4ac..0412485 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -6,3 +6,4 @@ $\.github/* ^\.github$ ^misc$ ^cran-comments\.md$ +^CRAN-SUBMISSION$ diff --git a/DESCRIPTION b/DESCRIPTION index 9a09fb1..0ba9e12 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,13 +1,15 @@ Package: rgeedim Type: Package -Title: Search, Composite, and Download Google Earth Engine Imagery with the Python Module 'geedim' +Title: Search, Composite, and Download 'Google Earth Engine' Imagery with the 'Python' Module 'geedim' Version: 0.1.0 -Author: Andrew Brown +Authors@R: c(person("Andrew", "Brown", role = c("aut", "cre"), email = "brown.andrewg@gmail.com")) Maintainer: Andrew Brown URL: https://humus.rocks/rgeedim/, https://github.com/brownag/rgeedim, https://geedim.readthedocs.io/ BugReports: https://github.com/brownag/rgeedim/issues -Description: Search, composite, and download Google Earth Engine imagery with 'reticulate' bindings for the Python module 'geedim'. - Wrapper functions are provided to make it more convenient to use 'geedim' to download images larger than the Earth Engine size limit. +Description: Search, composite, and download 'Google Earth Engine' imagery with 'reticulate' bindings for the 'Python' module 'geedim'. Read the 'geedim' documentation here: . + Wrapper functions are provided to make it more convenient to use 'geedim' to download images larger than the 'Google Earth Engine' size limit . + By default the "High Volume" API endpoint is used to download data and this URL can be customized during initialization of the package. +SystemRequirements: Python (>= 3.6.0) Config/reticulate: list( packages = list( diff --git a/NAMESPACE b/NAMESPACE index 46defdb..5e829ef 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -17,6 +17,7 @@ export(gd_enum_names) export(gd_footprint) export(gd_image_from_id) export(gd_initialize) +export(gd_is_initialized) export(gd_mask_clouds) export(gd_projection) export(gd_properties) diff --git a/NEWS.md b/NEWS.md index 4ae4568..0e452d2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,8 @@ * `gd_region()` now supports more complex SpatVector geometries (no longer uses extent to form bounding box if `x` is SpatVector or can be converted to one) +* Add `gd_is_initialized()` and use for examples and other conditional evaluation of code that requires authentication and initialized 'Google Earth Engine' resources + # rgeedim 0.0.0.9008 * Renamed `gd_bandnames()` -> `gd_band_names()` diff --git a/R/AAAA.R b/R/AAAA.R index 6e6512d..3e9c4be 100644 --- a/R/AAAA.R +++ b/R/AAAA.R @@ -1,5 +1,4 @@ gd <- NULL -ee <- NULL collections_module <- NULL #' `Module(geedim)` - Get `geedim` Module Instance @@ -26,7 +25,7 @@ gd_version <- function() { #' #' @export earthengine <- function() { - ee + gd$utils$ee } #' @description `gd_ee_version()` Gets the `ee` version using `importlib.metadata.version()` @@ -51,9 +50,6 @@ gd_ee_version <- function() { if (is.null(gd)) { try(gd <<- reticulate::import("geedim", delay_load = TRUE), silent = TRUE) - if (length(gd) > 0) { - try(ee <<- gd$utils$ee, silent = TRUE) - } } try(reticulate::py_run_string("from importlib.metadata import version"), silent = TRUE) diff --git a/R/composite.R b/R/composite.R index 6965922..0bf32cb 100644 --- a/R/composite.R +++ b/R/composite.R @@ -6,8 +6,21 @@ #' @param ... [additional arguments](https://geedim.readthedocs.io/en/latest/_generated/geedim.collection.MaskedCollection.composite.html) to `geedim.collection.MaskedCollection$composite()` #' @return a composite `geedim.mask.MaskedImage` object #' @export +#' @examplesIf gd_is_initialized() && requireNamespace("terra") +#' @examples +#' \donttest{ +#' b <- terra::vect('POLYGON((-121.355 37.56,-121.355 37.555, +#' -121.35 37.555,-121.35 37.56, +#' -121.355 37.56))', +#' crs = "OGC:CRS84") +#' +#' if (gd_is_initialized()) +#' gd_composite(gd_search(gd_collection_from_name("USGS/3DEP/1m"), +#' region = gd_region(b)), +#' resampling = "bilinear") +#' } gd_composite <- function(x, ...) { - if (!inherits(x, 'geedim.collection.MaskedCollection')){ + if (!inherits(x, 'geedim.collection.MaskedCollection')) { stop("`x` should be a geedim.collection.MaskedCollection", call. = FALSE) } y <- try(x$composite(...), silent = TRUE) diff --git a/R/download.R b/R/download.R index 13f4271..60c7a8b 100644 --- a/R/download.R +++ b/R/download.R @@ -14,6 +14,35 @@ #' @seealso `gd_region()` `gd_bbox()` #' @return Invisible path to downloaded image, or `try-error` on error #' @export +#' @examplesIf gd_is_initialized() +#' @examples +#' \donttest{ +#' r <- gd_bbox( +#' xmin = -121, +#' xmax = -120.5, +#' ymin = 38.5, +#' ymax = 39 +#' ) +#' +#' if (gd_is_initialized()) { +#' x <- gd_image_from_id('CSP/ERGo/1_0/Global/SRTM_topoDiversity') +#' tf <- tempfile(fileext = ".tif") +#' +#' # fast sample download at 10x aggregation (900m v.s. 90m) +#' img <- gd_download(x, filename = tf, +#' region = r, scale = 900, +#' overwrite = TRUE, silent = FALSE) +#' +#' if (requireNamespace("terra")) { +#' library(terra) +#' f <- rast(img) +#' plot(f[[1]]) +#' # inspect object +#' f +#' } +#' unlink(tf) +#' } +#' } gd_download <- function(x, filename = tempfile(fileext = ".tif"), region = NULL, diff --git a/R/enums.R b/R/enums.R index 0ff6992..6f52757 100644 --- a/R/enums.R +++ b/R/enums.R @@ -5,6 +5,11 @@ #' @return `gd_enum_names()`: character vector containing names of Enums #' @export #' @rdname enum +#' @examples +#' \donttest{ +#' if (gd_is_initialized()) +#' gd_enum_names() +#' } gd_enum_names <- function() { n <- names(gd$enums) n[which(n != "Enum")] @@ -13,6 +18,12 @@ gd_enum_names <- function() { #' @return `gd_enum_elements()`: element values of an Enum #' @export #' @rdname enum +#' @examplesIf gd_is_initialized() +#' @examples +#' \donttest{ +#' if (gd_is_initialized()) +#' gd_enum_elements() +#' } gd_enum_elements <- function(enum = gd_enum_names()) { enum <- match.arg(enum, gd_enum_names(), several.ok = TRUE) res <- lapply(enum, \(x) { @@ -26,6 +37,12 @@ gd_enum_elements <- function(enum = gd_enum_names()) { #' @return `gd_resampling_methods()`: character vector of resampling methods (Enum `"ResamplingMethod"`) #' @export #' @rdname enum +#' @examplesIf gd_is_initialized() +#' @examples +#' \donttest{ +#' if (gd_is_initialized()) +#' gd_resampling_methods() +#' } gd_resampling_methods <- function() { gd_enum_elements("ResamplingMethod")[[1]] } @@ -33,6 +50,12 @@ gd_resampling_methods <- function() { #' @return `gd_cloud_mask_methods()`: character vector of cloud mask methods (Enum `"CloudMaskMethod"`) #' @export #' @rdname enum +#' @examplesIf gd_is_initialized() +#' @examples +#' \donttest{ +#' if (gd_is_initialized()) +#' gd_cloud_mask_methods() +#' } gd_cloud_mask_methods <- function() { gd_enum_elements("CloudMaskMethod")[[1]] } @@ -40,6 +63,12 @@ gd_cloud_mask_methods <- function() { #' @return `gd_composite_methods()`: character vector of composite methods (Enum `"CompositeMethod"`) #' @export #' @rdname enum +#' @examplesIf gd_is_initialized() +#' @examples +#' \donttest{ +#' if (gd_is_initialized()) +#' gd_composite_methods() +#' } gd_composite_methods <- function() { gd_enum_elements("CompositeMethod")[[1]] } diff --git a/R/from.R b/R/from.R index 2b92637..15e5a32 100644 --- a/R/from.R +++ b/R/from.R @@ -8,6 +8,11 @@ #' #' @export #' @rdname from +#' @examplesIf gd_is_initialized() +#' \donttest{ +#' if (gd_is_initialized()) +#' gd_image_from_id('CSP/ERGo/1_0/Global/SRTM_topoDiversity') +#' } gd_image_from_id <- function(x) { y <- try(gd$MaskedImage$from_id(x), silent = FALSE) if (inherits(y, 'try-error')) return(invisible(y)) @@ -16,6 +21,11 @@ gd_image_from_id <- function(x) { #' @export #' @rdname from +#' @examplesIf gd_is_initialized() +#' \donttest{ +#' if (gd_is_initialized()) +#' gd_collection_from_name("USGS/3DEP/1m") +#' } gd_collection_from_name <- function(x) { y <- try(gd$MaskedCollection$from_name(x), silent = FALSE) if (inherits(y, 'try-error')) return(invisible(y)) @@ -24,6 +34,11 @@ gd_collection_from_name <- function(x) { #' @export #' @rdname from +#' @examplesIf gd_is_initialized() +#' \donttest{ +#' if (gd_is_initialized()) +#' gd_collection_from_list(c("USGS/3DEP/1m", "USGS/NED")) +#' } gd_collection_from_list <- function(x) { y <- try(gd$MaskedCollection$from_list(x), silent = FALSE) if (inherits(y, 'try-error')) return(invisible(y)) diff --git a/R/hello.R b/R/hello.R index a9a95d5..1006def 100644 --- a/R/hello.R +++ b/R/hello.R @@ -6,16 +6,16 @@ #' @param opt_url Base URL for API requests; defaults to "High Volume": `"https://earthengine-highvolume.googleapis.com"` #' @param quiet Suppress error messages on load? Default: `FALSE` #' -#' @return try-error (invisibly) on error +#' @return `gd_initialize()`: try-error (invisibly) on error. #' @export #' @importFrom reticulate py_run_string #' @importFrom jsonlite read_json #' @seealso `gd_authenticate()` #' @examples -#' \dontrun{ +#' \donttest{ #' gd_initialize() #' } -gd_initialize <- function(private_key_file = NULL, opt_url = 'https://earthengine-highvolume.googleapis.com', quiet = FALSE) { +gd_initialize <- function(private_key_file = NULL, opt_url = 'https://earthengine-highvolume.googleapis.com', quiet = TRUE) { # python 3.10.x compatibility: try(collections_module$Callable <- collections_module$abc$Callable, silent = TRUE) @@ -40,20 +40,29 @@ gd_initialize <- function(private_key_file = NULL, opt_url = 'https://earthengin kd <- jsonlite::parse_json(ek) } - sac <- try(ee$ServiceAccountCredentials(kd[['client_email']], - key_data = kd[['private_key']]), + sac <- try(gd$utils$ee$ServiceAccountCredentials(kd[['client_email']], + key_data = kd[['private_key']]), silent = quiet) if (inherits(sac, 'try-error')) { return(invisible(sac)) } - return(invisible(try(ee$Initialize(sac, opt_url = opt_url), silent = quiet))) + return(invisible(try(gd$utils$ee$Initialize(sac, opt_url = opt_url), silent = quiet))) } else { - return(invisible(try(ee$Initialize(opt_url = opt_url), silent = quiet))) + return(invisible(try(gd$utils$ee$Initialize(opt_url = opt_url), silent = quiet))) } } +#' @export +#' @return `gd_is_initialized()`: logical. `TRUE` if initialized successfully. +#' @rdname gd_initialize +#' @examples +#' gd_is_initialized() +gd_is_initialized <- function() { + return(length(geedim()) > 0 && !inherits(gd_initialize(), "try-error")) +} + #' Authenticate with Google Earth Engine using `gcloud`, "Notebook Authenticator" or other method #' #' Calls `ee.Authenticate(...)` to authenticate with Earth Engine. @@ -62,13 +71,15 @@ gd_initialize <- function(private_key_file = NULL, opt_url = 'https://earthengin #' @param quiet Suppress warnings, errors, messages? Default: `FALSE` #' @param code_verifier Optional code verifier for security Default: `NULL` #' @param auth_mode One of `"notebook"`, `"gcloud"`, `"appdefault"` or (default) `NULL` to guess based on the environment +#' @return This function is primarily used for the side-effect of authentication with the 'Google Earth Engine' servers. Invisibly returns `try-error` on error. #' @export #' @examples #' \dontrun{ -#' gd_authenticate(auth_mode="notebook") +#' # opens web page to complete authentication/provide authorization code +#' gd_authenticate(auth_mode = "notebook") #' } gd_authenticate <- function(authorization_code = NULL, quiet = FALSE, code_verifier = NULL, auth_mode = NULL) { - invisible(try(ee$Authenticate( + invisible(try(gd$utils$Authenticate( authorization_code = authorization_code, quiet = quiet, code_verifier = code_verifier, diff --git a/R/projection.R b/R/projection.R index 75e6d30..c2fa77e 100644 --- a/R/projection.R +++ b/R/projection.R @@ -7,12 +7,17 @@ #' #' @return `ee.Projection` object #' @export +#' @examplesIf gd_is_initialized() +#' \donttest{ +#' if (gd_is_initialized()) +#' gd_projection(gd_image_from_id('CSP/ERGo/1_0/Global/SRTM_topoDiversity')) +#' } gd_projection <- function(x) { if (!inherits(x, "ee.image.Image")) { if (inherits(x, 'geedim.download.BaseImage')) { gd$utils$get_projection(x$ee_image) } else { - gd$utils$get_projection(ee$Image(x)) + gd$utils$get_projection(gd$utils$ee$Image(x)) } } else { gd$utils$get_projection(x) diff --git a/R/regions.R b/R/regions.R index 409a334..96c2298 100644 --- a/R/regions.R +++ b/R/regions.R @@ -57,6 +57,13 @@ gd_bbox <- function(...) { #' @return list representing a GeoJSON extent #' @importFrom methods as #' @export +#' @examplesIf requireNamespace("terra") +#' @examples +#' b <- terra::vect('POLYGON((-121.355 37.56,-121.355 37.555, +#' -121.35 37.555,-121.35 37.56, +#' -121.355 37.56))', +#' crs = "OGC:CRS84") +#' gd_region(b) gd_region <- function(x) { if (is.list(x) && diff --git a/R/search.R b/R/search.R index 58d0e6e..a7de7b9 100644 --- a/R/search.R +++ b/R/search.R @@ -9,9 +9,20 @@ #' @param ... additional arguments to `geedim.MaskedCollection.search()` e.g. `cloudless_portion`, `fill_portion` #' @return `geedim.MaskedCollection` object suitable for querying properties #' @export +#' @examplesIf gd_is_initialized() && requireNamespace("terra") +#' @examples +#' \donttest{ +#' b <- terra::vect('POLYGON((-121.355 37.56,-121.355 37.555, +#' -121.35 37.555,-121.35 37.56, +#' -121.355 37.56))', +#' crs = "OGC:CRS84") +#' if (gd_is_initialized()) +#' gd_search(gd_collection_from_name("USGS/3DEP/1m"), +#' region = gd_region(b)) +#' } gd_search <- function(x, region, start_date = '2000-01-01', end_date = as.character(Sys.Date()), ...) { y <- try(x$search(start_date = start_date, end_date = end_date, region = gd_region(region), ...), silent = TRUE) - if (inherits(y, "try-error")){ + if (inherits(y, "try-error")) { message(y[1]) return(invisible(y)) } @@ -25,6 +36,20 @@ gd_search <- function(x, region, start_date = '2000-01-01', end_date = as.charac #' @return `data.frame` containing properties table from `x`; `NULL` if no properties table. #' @importFrom utils read.table #' @export +#' @examplesIf gd_is_initialized() && requireNamespace("terra") +#' @examples +#' \donttest{ +#' b <- terra::vect('POLYGON((-121.355 37.56,-121.355 37.555, +#' -121.35 37.555,-121.35 37.56, +#' -121.355 37.56))', +#' crs = "OGC:CRS84") +#' +#' if (gd_is_initialized()) { +#' x <- gd_search(gd_collection_from_name("USGS/3DEP/1m"), +#' region = gd_region(b)) +#' gd_properties(x) +#' } +#' } gd_properties <- function(x) { pt <- try(x$properties_table) if (inherits(pt, 'try-error')) { @@ -62,6 +87,12 @@ gd_properties <- function(x) { #' #' @return character. Vector of names of each layer in an image. #' @export +#' @examplesIf gd_is_initialized() +#' @examples +#' \donttest{ +#' if (gd_is_initialized()) +#' gd_band_names(gd_image_from_id("USGS/NED")) +#' } gd_band_names <- function(x) { y <- NULL if (inherits(x, 'geedim.download.BaseImage')) { @@ -82,6 +113,12 @@ gd_band_names <- function(x) { #' #' @return list. Each element is a list that corresponds to a layer in `x`, each with one or more elements for properties of that layer. #' @export +#' @examplesIf gd_is_initialized() +#' @examples +#' \donttest{ +#' if (gd_is_initialized()) +#' gd_band_properties(gd_image_from_id("USGS/NED")) +#' } gd_band_properties <- function(x) { y <- NULL if (inherits(x, 'geedim.download.BaseImage')) { @@ -103,6 +140,12 @@ gd_band_properties <- function(x) { #' @param x a `geedim.mask.MaskedImage` object #' @return list. #' @export +#' @examplesIf gd_is_initialized() +#' @examples +#' \donttest{ +#' if (gd_is_initialized()) +#' gd_footprint(gd_image_from_id("USGS/NED")) +#' } gd_footprint <- function(x) { y <- NULL if (inherits(x, 'geedim.mask.MaskedImage')) { diff --git a/README.Rmd b/README.Rmd index 11dc81e..6bc7057 100644 --- a/README.Rmd +++ b/README.Rmd @@ -6,6 +6,7 @@ output: github_document ```{r, include = FALSE} knitr::opts_chunk$set( + eval = !inherits(rgeedim::gd_version(), 'try-error'), collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", @@ -27,10 +28,16 @@ By using `geedim` images larger than the [`Image.getDownloadURL()` size limit](h ## Installation +{rgeedim} is available on CRAN, and can be installed as follows: + +``` r +install.packages("rgeedim") +``` + You can install the development version of {rgeedim} using {remotes}: ``` r -# install.packages("remotes") +if (!require("remotes")) install.packages("remotes") remotes::install_github("brownag/rgeedim") ``` diff --git a/README.md b/README.md index 366339e..4fb7a17 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,16 @@ single GeoTIFF. ## Installation +{rgeedim} is available on CRAN, and can be installed as follows: + +``` r +install.packages("rgeedim") +``` + You can install the development version of {rgeedim} using {remotes}: ``` r -# install.packages("remotes") +if (!require("remotes")) install.packages("remotes") remotes::install_github("brownag/rgeedim") ``` @@ -85,7 +91,6 @@ expressed in WGS84 decimal degrees (`"OGC:CRS84"`). ``` r library(rgeedim) -#> rgeedim v0.1.0 -- using geedim 1.5.3 w/ earthengine-api 0.1.329 ``` If this is your first time using any Google Earth Engine tools, @@ -145,23 +150,13 @@ where data are available). ``` r library(terra) -#> terra 1.6.17 f <- rast(res) f -#> class : SpatRaster -#> dimensions : 402, 618, 2 (nrow, ncol, nlyr) -#> resolution : 10, 10 (x, y) -#> extent : -2113880, -2107700, 1945580, 1949600 (xmin, xmax, ymin, ymax) -#> coord. ref. : NAD83 / Conus Albers (EPSG:5070) -#> source : image.tif -#> names : constant, FILL_MASK plot(f[[1]]) ``` - - ## Example: Hillshade from DEM This example demonstrates the download of a section of the USGS NED @@ -205,8 +200,6 @@ hsd <- shade(slp, asp) plot(c(dem, hillshade = hsd)) ``` - - ## Example: LiDAR Slope Map This example demonstrates how to access the 1m LiDAR data from USGS. A @@ -242,8 +235,6 @@ plot(terra::terrain(x$elevation)) plot(project(b, x), add = TRUE) ``` - - ## Example: Landsat-7 cloud/shadow-free composite This example demonstrates download of a Landsat-7 cloud/shadow-free @@ -278,16 +269,6 @@ x <- 'LANDSAT/LE07/C02/T1_L2' |> # inspect individual image metadata in the collection gd_properties(x) -#> id date fill -#> 1 LANDSAT/LE07/C02/T1_L2/LE07_043034_20201130 2020-11-29 16:00:00 86.41 -#> 2 LANDSAT/LE07/C02/T1_L2/LE07_043034_20210101 2020-12-31 16:00:00 86.85 -#> 3 LANDSAT/LE07/C02/T1_L2/LE07_043034_20210117 2021-01-16 16:00:00 86.05 -#> 4 LANDSAT/LE07/C02/T1_L2/LE07_043034_20210218 2021-02-17 16:00:00 85.66 -#> cloudless grmse saa sea -#> 1 86.40 4.92 151.45 25.21 -#> 2 85.88 4.79 148.07 22.47 -#> 3 85.99 5.44 145.16 23.71 -#> 4 85.59 5.73 138.46 30.91 # download a single image y <- gd_properties(x)$id[1] |> @@ -302,11 +283,6 @@ y <- gd_properties(x)$id[1] |> silent = FALSE ) plot(rast(y)[[1:4]]) -``` - - - -``` r # create composite landsat image near December 1st, 2020 and download # using q-mosaic method. @@ -327,7 +303,5 @@ z <- x |> plot(rast(z)[[1:4]]) ``` - - The `"q-mosaic"` method produces a composite largely free of artifacts; this is because it prioritizes pixels with higher distance from clouds. diff --git a/inst/WORDLIST b/inst/WORDLIST index 5b6329d..da49f1e 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -30,10 +30,10 @@ SpatVector USGS WGS WKT -artefacts codecov conda edu +enum enums geedim gohlke diff --git a/inst/tinytest/test_rgeedim.R b/inst/tinytest/test_rgeedim.R index 220e372..a0ba2a0 100644 --- a/inst/tinytest/test_rgeedim.R +++ b/inst/tinytest/test_rgeedim.R @@ -1,9 +1,9 @@ -if (length(earthengine()) > 0) { +if (!inherits(gd_version(), 'try-error')) { # we are assuming gd_authenticate() has been called / set up # such that we can init modules and begin using them gi <- gd_initialize() } else { - gi <- try(stop("earthengine-api not available"), silent = TRUE) + gi <- try(stop("geedim/earthengine-api not available"), silent = TRUE) } .testbounds <- c( diff --git a/man/enum.Rd b/man/enum.Rd index 0efa3a5..1c2cf13 100644 --- a/man/enum.Rd +++ b/man/enum.Rd @@ -35,3 +35,33 @@ gd_composite_methods() \description{ \code{geedim} Enums } +\examples{ +\donttest{ +if (gd_is_initialized()) + gd_enum_names() +} +\dontshow{if (gd_is_initialized()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\dontshow{\}) # examplesIf} +\donttest{ +if (gd_is_initialized()) + gd_enum_elements() +} +\dontshow{if (gd_is_initialized()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\dontshow{\}) # examplesIf} +\donttest{ +if (gd_is_initialized()) + gd_resampling_methods() +} +\dontshow{if (gd_is_initialized()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\dontshow{\}) # examplesIf} +\donttest{ +if (gd_is_initialized()) + gd_cloud_mask_methods() +} +\dontshow{if (gd_is_initialized()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\dontshow{\}) # examplesIf} +\donttest{ +if (gd_is_initialized()) + gd_composite_methods() +} +} diff --git a/man/from.Rd b/man/from.Rd index 1cc79fc..857053d 100644 --- a/man/from.Rd +++ b/man/from.Rd @@ -21,3 +21,23 @@ gd_collection_from_list(x) \description{ Create references to a Google Earth Engine Image or Image Collection based on IDs or names, or combine Images into Image Collections. } +\examples{ +\dontshow{if (gd_is_initialized()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\donttest{ +if (gd_is_initialized()) + gd_image_from_id('CSP/ERGo/1_0/Global/SRTM_topoDiversity') +} +\dontshow{\}) # examplesIf} +\dontshow{if (gd_is_initialized()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\donttest{ +if (gd_is_initialized()) + gd_collection_from_name("USGS/3DEP/1m") +} +\dontshow{\}) # examplesIf} +\dontshow{if (gd_is_initialized()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\donttest{ +if (gd_is_initialized()) + gd_collection_from_list(c("USGS/3DEP/1m", "USGS/NED")) +} +\dontshow{\}) # examplesIf} +} diff --git a/man/gd_authenticate.Rd b/man/gd_authenticate.Rd index 44a0d66..f99b1e9 100644 --- a/man/gd_authenticate.Rd +++ b/man/gd_authenticate.Rd @@ -20,6 +20,9 @@ gd_authenticate( \item{auth_mode}{One of \code{"notebook"}, \code{"gcloud"}, \code{"appdefault"} or (default) \code{NULL} to guess based on the environment} } +\value{ +This function is primarily used for the side-effect of authentication with the 'Google Earth Engine' servers. Invisibly returns \code{try-error} on error. +} \description{ Calls \code{ee.Authenticate(...)} to authenticate with Earth Engine. } @@ -28,6 +31,7 @@ This method should be called once to set up a machine/project with a particular } \examples{ \dontrun{ -gd_authenticate(auth_mode="notebook") +# opens web page to complete authentication/provide authorization code +gd_authenticate(auth_mode = "notebook") } } diff --git a/man/gd_band_names.Rd b/man/gd_band_names.Rd index 58797b9..da0e222 100644 --- a/man/gd_band_names.Rd +++ b/man/gd_band_names.Rd @@ -15,3 +15,11 @@ character. Vector of names of each layer in an image. \description{ Calls \code{bandNames()} method from \code{ee.Image} class. } +\examples{ +\dontshow{if (gd_is_initialized()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\dontshow{\}) # examplesIf} +\donttest{ +if (gd_is_initialized()) + gd_band_names(gd_image_from_id("USGS/NED")) +} +} diff --git a/man/gd_band_properties.Rd b/man/gd_band_properties.Rd index 1087f06..62c236c 100644 --- a/man/gd_band_properties.Rd +++ b/man/gd_band_properties.Rd @@ -15,3 +15,11 @@ list. Each element is a list that corresponds to a layer in \code{x}, each with \description{ Gets combined Earth Engine and STAC properties. } +\examples{ +\dontshow{if (gd_is_initialized()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\dontshow{\}) # examplesIf} +\donttest{ +if (gd_is_initialized()) + gd_band_properties(gd_image_from_id("USGS/NED")) +} +} diff --git a/man/gd_composite.Rd b/man/gd_composite.Rd index 084ed17..d5cb627 100644 --- a/man/gd_composite.Rd +++ b/man/gd_composite.Rd @@ -17,3 +17,18 @@ a composite \code{geedim.mask.MaskedImage} object \description{ Create a composite image from elements of an image collection. } +\examples{ +\dontshow{if (gd_is_initialized() && requireNamespace("terra")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\dontshow{\}) # examplesIf} +\donttest{ +b <- terra::vect('POLYGON((-121.355 37.56,-121.355 37.555, + -121.35 37.555,-121.35 37.56, + -121.355 37.56))', + crs = "OGC:CRS84") + +if (gd_is_initialized()) + gd_composite(gd_search(gd_collection_from_name("USGS/3DEP/1m"), + region = gd_region(b)), + resampling = "bilinear") +} +} diff --git a/man/gd_download.Rd b/man/gd_download.Rd index 848ca3c..42c8581 100644 --- a/man/gd_download.Rd +++ b/man/gd_download.Rd @@ -39,6 +39,37 @@ Download a Google Earth Engine Image The \code{region} argument is \emph{optional} for downloading images. When downloading a composite Image Collection, you must specify \code{region}, \code{scale} and \code{crs} arguments. When downloading an image collection as a set of GeoTIFF files (\code{composite=FALSE}), then \code{filename} is the destination directory, and \code{scale} must be specified. The default resampling method in \code{geedim} is \code{resampling="near"} (Nearest Neighbor). Other options for \code{resampling} include: \code{"average"}, \code{"bicubic"}, \code{"bilinear"}. See \code{gd_resampling_methods()}. } +\examples{ +\dontshow{if (gd_is_initialized()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\dontshow{\}) # examplesIf} +\donttest{ + r <- gd_bbox( + xmin = -121, + xmax = -120.5, + ymin = 38.5, + ymax = 39 + ) + +if (gd_is_initialized()) { + x <- gd_image_from_id('CSP/ERGo/1_0/Global/SRTM_topoDiversity') + tf <- tempfile(fileext = ".tif") + + # fast sample download at 10x aggregation (900m v.s. 90m) + img <- gd_download(x, filename = tf, + region = r, scale = 900, + overwrite = TRUE, silent = FALSE) + + if (requireNamespace("terra")) { + library(terra) + f <- rast(img) + plot(f[[1]]) + # inspect object + f + } + unlink(tf) +} +} +} \seealso{ \code{gd_region()} \code{gd_bbox()} } diff --git a/man/gd_footprint.Rd b/man/gd_footprint.Rd index 6fc38e6..4e94e92 100644 --- a/man/gd_footprint.Rd +++ b/man/gd_footprint.Rd @@ -15,3 +15,11 @@ list. \description{ Gets GeoJSON-style list containing footprint of a \code{geedim.mask.MaskedImage} object } +\examples{ +\dontshow{if (gd_is_initialized()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\dontshow{\}) # examplesIf} +\donttest{ +if (gd_is_initialized()) + gd_footprint(gd_image_from_id("USGS/NED")) +} +} diff --git a/man/gd_initialize.Rd b/man/gd_initialize.Rd index b5f2bb0..429ceea 100644 --- a/man/gd_initialize.Rd +++ b/man/gd_initialize.Rd @@ -2,13 +2,16 @@ % Please edit documentation in R/hello.R \name{gd_initialize} \alias{gd_initialize} +\alias{gd_is_initialized} \title{Initialize \code{geedim}} \usage{ gd_initialize( private_key_file = NULL, opt_url = "https://earthengine-highvolume.googleapis.com", - quiet = FALSE + quiet = TRUE ) + +gd_is_initialized() } \arguments{ \item{private_key_file}{Optional: Path to JSON file containing client information and private key.} @@ -18,15 +21,18 @@ gd_initialize( \item{quiet}{Suppress error messages on load? Default: \code{FALSE}} } \value{ -try-error (invisibly) on error +\code{gd_initialize()}: try-error (invisibly) on error. + +\code{gd_is_initialized()}: logical. \code{TRUE} if initialized successfully. } \description{ Calls \code{geedim} \code{Initialize()} method. This method should be called at the beginning of each session. } \examples{ -\dontrun{ +\donttest{ gd_initialize() } +gd_is_initialized() } \seealso{ \code{gd_authenticate()} diff --git a/man/gd_projection.Rd b/man/gd_projection.Rd index 07c6039..5c38e21 100644 --- a/man/gd_projection.Rd +++ b/man/gd_projection.Rd @@ -15,3 +15,11 @@ gd_projection(x) \description{ Get Projection Information from Google Earth Engine Asset } +\examples{ +\dontshow{if (gd_is_initialized()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\donttest{ +if (gd_is_initialized()) + gd_projection(gd_image_from_id('CSP/ERGo/1_0/Global/SRTM_topoDiversity')) +} +\dontshow{\}) # examplesIf} +} diff --git a/man/gd_properties.Rd b/man/gd_properties.Rd index 265d55d..ac1dcb9 100644 --- a/man/gd_properties.Rd +++ b/man/gd_properties.Rd @@ -15,3 +15,19 @@ gd_properties(x) \description{ Get Properties of an Image Collection } +\examples{ +\dontshow{if (gd_is_initialized() && requireNamespace("terra")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\dontshow{\}) # examplesIf} +\donttest{ +b <- terra::vect('POLYGON((-121.355 37.56,-121.355 37.555, + -121.35 37.555,-121.35 37.56, + -121.355 37.56))', + crs = "OGC:CRS84") + +if (gd_is_initialized()) { + x <- gd_search(gd_collection_from_name("USGS/3DEP/1m"), + region = gd_region(b)) + gd_properties(x) +} +} +} diff --git a/man/gd_region.Rd b/man/gd_region.Rd index 7af1e87..ed63506 100644 --- a/man/gd_region.Rd +++ b/man/gd_region.Rd @@ -18,6 +18,15 @@ Creates a suitable input for the \code{region} argument to \verb{gd_download(= "3.4") withAutoprint else force)(\{ # examplesIf} +\dontshow{\}) # examplesIf} +b <- terra::vect('POLYGON((-121.355 37.56,-121.355 37.555, + -121.35 37.555,-121.35 37.56, + -121.355 37.56))', + crs = "OGC:CRS84") +gd_region(b) +} \seealso{ \code{gd_bbox()} } diff --git a/man/gd_search.Rd b/man/gd_search.Rd index cf90852..0356ac9 100644 --- a/man/gd_search.Rd +++ b/man/gd_search.Rd @@ -29,3 +29,16 @@ gd_search( \description{ Search an Image Collection } +\examples{ +\dontshow{if (gd_is_initialized() && requireNamespace("terra")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\dontshow{\}) # examplesIf} +\donttest{ +b <- terra::vect('POLYGON((-121.355 37.56,-121.355 37.555, + -121.35 37.555,-121.35 37.56, + -121.355 37.56))', + crs = "OGC:CRS84") +if (gd_is_initialized()) + gd_search(gd_collection_from_name("USGS/3DEP/1m"), + region = gd_region(b)) +} +} diff --git a/man/rgeedim-package.Rd b/man/rgeedim-package.Rd index 62e84fd..6a139d9 100644 --- a/man/rgeedim-package.Rd +++ b/man/rgeedim-package.Rd @@ -4,9 +4,9 @@ \name{rgeedim-package} \alias{rgeedim} \alias{rgeedim-package} -\title{rgeedim: Search, Composite, and Download Google Earth Engine Imagery with the Python Module 'geedim'} +\title{rgeedim: Search, Composite, and Download 'Google Earth Engine' Imagery with the 'Python' Module 'geedim'} \description{ -Search, composite, and download Google Earth Engine imagery with 'reticulate' bindings for the Python module 'geedim'. Wrapper functions are provided to make it more convenient to use 'geedim' to download images larger than the Earth Engine size limit. +Search, composite, and download 'Google Earth Engine' imagery with 'reticulate' bindings for the 'Python' module 'geedim'. Read the 'geedim' documentation here: \url{https://geedim.readthedocs.io/}. Wrapper functions are provided to make it more convenient to use 'geedim' to download images larger than the 'Google Earth Engine' size limit \url{https://developers.google.com/earth-engine/apidocs/ee-image-getdownloadurl}. By default the "High Volume" API endpoint \url{https://developers.google.com/earth-engine/cloud/highvolume} is used to download data and this URL can be customized during initialization of the package. } \seealso{ Useful links: @@ -17,5 +17,9 @@ Useful links: \item Report bugs at \url{https://github.com/brownag/rgeedim/issues} } +} +\author{ +\strong{Maintainer}: Andrew Brown \email{brown.andrewg@gmail.com} + } \keyword{internal}