diff --git a/DESCRIPTION b/DESCRIPTION index 1453ec0..3b6ef20 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: CopernicusMarine Type: Package Title: Search Download and Handle Data from Copernicus Marine Service Information -Version: 0.1.3 -Date: 2023-11-09 +Version: 0.2.0 +Date: 2024-01-01 Authors@R: c(person("Pepijn", "de Vries", role = c("aut", "cre", "dtc"), email = "pepijn.devries@outlook.com", comment = c(ORCID = "0000-0002-7961-6646"))) @@ -22,13 +22,16 @@ Imports: leaflet, purrr, readr, + rlang, rvest, sf, stringr, + tidyr, utils, xml2 Suggests: lifecycle, + ncmeta, stars, testthat (>= 3.0.0) URL: https://github.com/pepijn-devries/CopernicusMarine @@ -39,3 +42,26 @@ LazyData: true RoxygenNote: 7.2.3 Config/testthat/edition: 3 Roxygen: list(markdown = TRUE) +Collate: + 'CopernicusMarine-package.r' + 'cms_cite_product.r' + 'cms_download_stac.r' + 'cms_login.r' + 'cms_download_subset.r' + 'cms_list_stac_files.r' + 'cms_product_details.r' + 'cms_product_metadata.r' + 'cms_product_services.r' + 'cms_products_list.r' + 'cms_stac_properties.r' + 'cms_wmts.r' + 'copernicus_cite_product.r' + 'copernicus_download_motu.r' + 'copernicus_login.r' + 'copernicus_product_details.r' + 'copernicus_product_metadata.r' + 'copernicus_products_list.r' + 'ftp.r' + 'generics.r' + 'import.r' + 'wms.r' diff --git a/NAMESPACE b/NAMESPACE index d52bd2a..059da4e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,19 @@ # Generated by roxygen2: do not edit by hand +export(addCmsWMTSTiles) export(addCopernicusWMSTiles) +export(cms_cite_product) +export(cms_download_stac) +export(cms_download_subset) +export(cms_list_stac_files) +export(cms_login) +export(cms_product_details) +export(cms_product_metadata) +export(cms_product_services) +export(cms_products_list) +export(cms_stac_properties) +export(cms_wmts_details) +export(cms_wmts_get_capabilities) export(copernicus_cite_product) export(copernicus_download_motu) export(copernicus_ftp_get) @@ -12,3 +25,5 @@ export(copernicus_product_services) export(copernicus_products_list) export(copernicus_wms2geotiff) export(copernicus_wms_details) +importFrom(rlang,.data) +importFrom(rlang,`:=`) diff --git a/NEWS.md b/NEWS.md index 2b8a575..79c6643 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,9 @@ -CopernicusMarine v0.1.3 (Release date: 2023-12-24) +CopernicusMarine v0.2.0 (Release date: 2024-01-01) ------------- + * Added functions for new services (subset, STAC and WMTS) + * Added warnings to functions interacting with + deprecated Copernicus Marine services. * Added login function * Switched from `httr` to `httr2` dependency * Switch from `magrittr`'s pipe to R's native pipe operator diff --git a/R/cms_cite_product.r b/R/cms_cite_product.r new file mode 100644 index 0000000..3c76713 --- /dev/null +++ b/R/cms_cite_product.r @@ -0,0 +1,28 @@ +#' How to cite a Copernicus marine product +#' +#' `r lifecycle::badge('stable')` Get details for properly citing a Copernicus product. +#' +#' @inheritParams cms_download_subset +#' @returns Returns a vector of character strings. The first element is always the product title, id and doi. +#' Remaining elements are other associated references. Note that the remaining references are returned as +#' listed at Copernicus. Note that the citing formatting does not appear to be standardised. +#' @rdname cms_cite_product +#' @name cms_cite_product +#' @family product-functions +#' @examples +#' \donttest{ +#' cms_cite_product("SST_MED_PHY_SUBSKIN_L4_NRT_010_036") +#' } +#' @author Pepijn de Vries +#' @export +cms_cite_product <- function(product) { + product_details <- cms_product_details(product) + if (is.null(product_details)) return(NULL) + result <- product_details$refs + result <- c( + doi = with( + product_details, + sprintf("E.U. Copernicus Marine Service Information; %s - %s (%s). DOI:%s", + title, id, creationDate, doi)), result) + return(result) +} \ No newline at end of file diff --git a/R/cms_download_stac.r b/R/cms_download_stac.r new file mode 100644 index 0000000..b07dc42 --- /dev/null +++ b/R/cms_download_stac.r @@ -0,0 +1,71 @@ +#' List and get STAC files for a Copernicus marine product +#' +#' `r lifecycle::badge('stable')` Full marine data sets can be downloaded using the +#' SpatioTemporal Asset Catalogs (STAC). Use these functions to list download locations and get +#' the files. +#' @inheritParams cms_download_subset +#' @param file_tibble A [`dplyr::tibble()`] with in each row the files to be downloaded. +#' Should be created with [`cms_list_stac_files()`]. +#' @param destination A `character` string representing the path location where the downloaded +#' files should be stored. +#' @param show_progress A `logical` value. When `TRUE` (default) the download progress will be shown. +#' This can be useful for large files. +#' @returns In case of `cms_stac_properties` a [`dplyr::tibble()`] is returned with some +#' product properties, It is used as precursor for `cms_list_stac_files`. +#' In case of `cms_list_stac_files` a [`dplyr::tibble()`] is returned containing +#' available URLs (for the specified `product` and `layer`) and some meta information is returned. +#' In case of `cms_download_stac` an invisible `logical` value is returned, indicating whether +#' all requested files are successfully stored at the `destination` path. A `list` of responses +#' (of class [`httr2::response()`]) for all requested download links is included as attribute +#' to the result. +#' @rdname cms_stac +#' @name cms_download_stac +#' @examples +#' \dontrun{ +#' ## List some STAC properties for a specific product and layer +#' cms_stac_properties( +#' product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", +#' layer = "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m" +#' ) +#' +#' ## Get the available files for a specific product and layer: +#' file_tibble <- +#' cms_list_stac_files("GLOBAL_ANALYSISFORECAST_PHY_001_024", +#' "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m") +#' +#' dest <- tempdir() +#' +#' ## download the first file from the file_tibble to 'dest' +#' cms_download_stac(file_tibble[1,, drop = FALSE], dest) +#' } +#' @family stac-functions download-functions +#' @author Pepijn de Vries +#' @export +cms_download_stac <- function(file_tibble, destination, show_progress = TRUE, overwrite = FALSE) { + if (!dir.exists(destination)) + stop(sprintf("The path '%s' is not an existing directory", destination)) + result <- TRUE + responses <- lapply(seq_len(nrow(file_tibble)), function(i) { + dest <- file.path(destination, basename(file_tibble$current_path[[i]])) + if (!overwrite && file.exists(dest)) + stop(sprintf("File '%s' already exists! Use `overwrite=TRUE` to proceed", dest)) + resp <- .try_online({ + req <- + paste( + "https:/", + file_tibble$home[[i]], + file_tibble$native[[i]], + file_tibble$current_path[[i]], + sep = "/" + ) |> + httr2::request() + if (show_progress) req <- req |> httr2::req_progress() + req |> + httr2::req_perform(path = dest) + }, "stac-download") + if (is.null(resp)) result <- FALSE + resp + }) + attr(result, "responses") <- responses + return(invisible(result)) +} \ No newline at end of file diff --git a/R/cms_download_subset.r b/R/cms_download_subset.r new file mode 100644 index 0000000..cb86054 --- /dev/null +++ b/R/cms_download_subset.r @@ -0,0 +1,144 @@ +#' Subset and download a specific marine product from Copernicus +#' +#' `r lifecycle::badge('stable')` Subset and download a specific marine product from Copernicus. +#' You need to register an account +#' at before you can use this function. +#' +#' @include cms_login.r +#' @inheritParams cms_login +#' @param destination File or path where the requested file will be downloaded to. +#' @param product An identifier (type `character`) of the desired Copernicus marine product. +#' Can be obtained with [`cms_products_list`]. +#' @param layer The name of a desired layer within a product (type `character`). Can be obtained with [`cms_product_details`]. +#' @param variable The name of a desired variable in a specific layer of a product (type `character`). +#' Can be obtained with [`copernicus_product_details`]. +#' @param region Specification of the bounding box as a `vector` of `numeric`s WGS84 lat and lon coordinates. +#' Should be in the order of: xmin, ymin, xmax, ymax. +#' @param timerange A `vector` with two elements (lower and upper value) +#' for a requested time range. The `vector` should be coercible to `POSIXct`. +#' @param verticalrange A `vector` with two elements (minimum and maximum) +#' numerical values for the depth of the vertical layers (if any). +#' @param overwrite A `logical` value. When `FALSE` (default), files at the `destination` won't be +#' overwritten when the exist. Instead an error will be thrown if this is the case. When set to +#' `TRUE`, existing files will be overwritten. +#' @returns Returns a `logical` value invisibly indicating whether the requested file was +#' successfully stored at the `destination`. +#' @rdname cms_download_subset +#' @name cms_download_subset +#' @examples +#' \dontrun{ +#' destination <- tempfile("copernicus", fileext = ".nc") +#' +#' ## Assuming that Copernicus account details are provided as `options` +#' cms_download_subset( +#' destination = destination, +#' product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", +#' layer = "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m", +#' variable = "sea_water_velocity", +#' region = c(-1, 50, 10, 55), +#' timerange = c("2021-01-01 UTC", "2021-01-02 UTC"), +#' verticalrange = c(0, 2) +#' ) +#' +#' mydata <- stars::read_stars(destination) +#' +#' plot(mydata["vo"]) +#' } +#' @author Pepijn de Vries +#' @export +cms_download_subset <- function( + username = getOption("CopernicusMarine_uid", ""), + password = getOption("CopernicusMarine_pwd", ""), + destination, + product, + layer, + variable, + region, + timerange, + verticalrange, + overwrite = FALSE) { + + if (!overwrite & file.exists(destination)) + stop("Destination file already exists. Set 'overwrite' to TRUE to proceed.") + + base_url <- "https://data-be-prd.marine.copernicus.eu/api/download/" + + message(crayon::white("Preparing job...")) + + details <- cms_product_details(product, layer, variant = "detailed-v2") + + var_check1 <- names(details) %in% paste0(layer, "/", variable) + var_check2 <- !(paste0(layer, "/", variable) %in% names(details)) + variable <- c( + lapply(details[var_check1], `[[`, "subsetVariableIds") |> unlist() |> unname(), + variable[var_check2] + ) |> unique() + + payload <- c("lonMin", "latMin", "lonMax", "latMax", "timeMin", "timeMax", + "elevationMin", "elevationMax", "extraVariableIds") + payload <- list( + datasetId = product, + subdatasetId = layer, + variableIds = variable, + subsetValues = structure(purrr::map(seq_along(payload), + ~structure(list(), names = character(0))), + names = payload)) + payload[["subsetValues"]][["extraVariableIds"]] <- variable + + if (!missing(region)) { + payload[["subsetValues"]][["lonMin"]] <- region[[1]] + payload[["subsetValues"]][["latMin"]] <- region[[2]] + payload[["subsetValues"]][["lonMax"]] <- region[[3]] + payload[["subsetValues"]][["latMax"]] <- region[[4]] + } + if (!missing(timerange)) { + timerange <- timerange |> + as.POSIXct(tz = "UTC") |> + as.numeric(origin = "1970-01-01 UTC")*1000 + payload[["subsetValues"]][["timeMin"]] <- timerange[[1]] + payload[["subsetValues"]][["timeMax"]] <- timerange[[2]] + } + if (!missing(verticalrange)) { + payload[["subsetValues"]][["elevationMin"]] <- verticalrange[[1]] + payload[["subsetValues"]][["elevationMax"]] <- verticalrange[[2]] + } + + job <- + .try_online({ + base_url |> + httr2::request() |> + httr2::req_auth_basic(username, password) |> + httr2::req_body_json(payload) |> + httr2::req_perform() + }, "subset-job") + if (is.null(job)) return(invisible(FALSE)) + job <- httr2::resp_body_json(job) + + message(crayon::white("Waiting for job to finish...")) + repeat { + job_check <- + .try_online({ + base_url |> + paste0(job$jobId) |> + httr2::request() |> + httr2::req_perform() + }, "job-check") + if (is.null(job_check)) return(invisible(FALSE)) + job_check <- httr2::resp_body_json(job_check) + + if (job_check$finished) break + Sys.sleep(0.5) + } + + message(crayon::white("Downloading file...")) + download <- + .try_online({ + job_check$url |> + httr2::request() |> + httr2::req_perform(destination) + }, "subset-download") + if (is.null(download)) return(invisible(FALSE)) + + message(crayon::green("Done")) + return(invisible(TRUE)) +} \ No newline at end of file diff --git a/R/cms_list_stac_files.r b/R/cms_list_stac_files.r new file mode 100644 index 0000000..083b95f --- /dev/null +++ b/R/cms_list_stac_files.r @@ -0,0 +1,83 @@ +#' @rdname cms_stac +#' @name cms_list_stac_files +#' @export +cms_list_stac_files <- function(product, layer) { + props <- cms_stac_properties(product, layer) + if (length(props) == 0) return(NULL) + assets <- NULL + props <- dplyr::tibble(assets = props$href) |> + dplyr::mutate( + current_path = stringr::str_extract(.data$assets, "/native/.*?$"), + current_path = gsub("^/", "", .data$current_path), + split = strsplit(assets, "/"), + home = purrr::map_chr(split, ~{.x[[3]]}), + native = purrr::map_chr(split, ~{.x[grepl("-native-", .x)]}) + ) |> + dplyr::select(!dplyr::any_of(c("split", "assets"))) + + .list_stac <- function(base_props) { + prep_url <- + "https://%s.%s/?delimiter=%%2F&list-type=2&prefix=" |> + sprintf(base_props$native, base_props$home) |> + paste0(utils::URLencode(base_props$current_path)) + bucket <- + purrr::map( + prep_url, ~{ + result <- + .try_online({ + .x |> + httr2::request() |> + httr2::req_perform() + }, "list-bucket") + if (is.null(result)) return(NULL) + if (is.null(result$headers$`content-type`) || is.na(result$headers$`content-type`)) + result$headers$`content-type` <- "application/xml" + result <- result |> + httr2::resp_body_xml() |> + xml2::as_list() + result <- result$ListBucketResult + c_prefix <- + dplyr::tibble( + Key = result[names(result) == "CommonPrefixes"] |> + unlist() |> + unname() + ) + content <- result[names(result) == "Contents"] |> + purrr::map(dplyr::as_tibble) |> + dplyr::bind_rows() |> + dplyr::mutate(dplyr::across(dplyr::everything(), unlist)) + result <- dplyr::bind_rows(c_prefix, content) + result + }) + bucket <- purrr::imap( + bucket, ~{ + is_file <- if(!"Size" %in% names(.x)) rep(FALSE, nrow(.x)) else !is.na(.x$Size) + new_props <- if (any(is_file)) { + np <- + base_props[.y,, drop = FALSE] |> + dplyr::bind_cols(.x[is_file,,drop = FALSE]) |> + dplyr::select(!dplyr::any_of("current_path")) + if ("Key" %in% names(np)) np <- np |> dplyr::rename(!!"current_path" := "Key") + np + } else { + NULL + } + if (!any(is_file)) { + new_props <- + dplyr::bind_rows( + new_props, + if (nrow(.x) == 0) NULL else { + base_props[rep(.y, length(.x$Key)),, drop = FALSE] |> + dplyr::mutate(!!"current_path" := .x$Key) |> + .list_stac() # call recursively + } + ) + } + return(new_props) + } + ) + return(bucket) + } + bucket <- .list_stac(props) |> dplyr::bind_rows() + return(bucket) +} diff --git a/R/cms_login.r b/R/cms_login.r new file mode 100644 index 0000000..3b22035 --- /dev/null +++ b/R/cms_login.r @@ -0,0 +1,48 @@ +#' Contact Copernicus Marine login page +#' +#' `r lifecycle::badge('stable')` Contact Copernicus Marine login page +#' and check if login is successful. +#' +#' This function will return a logical value indicating if the login is successful. +#' It can be used to test your account details. +#' @param username Your Copernicus marine user name. Can be provided as +#' `options(CopernicusMarine_uid = "my_user_name")`, or as argument here. +#' @param password Your Copernicus marine password. Can be provided as +#' `options(CopernicusMarine_pwd = "my_password")`, or as argument here. +#' @returns Returns a `logical` value indicating if the login is successful. +#' The response from the login page is returned as an attribute named `response`. +#' @author Pepijn de Vries +#' @examples +#' \dontrun{ +#' ## This will return FALSE if you have not set your account details with 'options'. +#' ## If you have specified your account details and there are no other problems, +#' ## it will return TRUE. +#' copernicus_login() +#' } +#' @name cms_login +#' @rdname cms_login +#' @export +cms_login <- function( + username = getOption("CopernicusMarine_uid", ""), + password = getOption("CopernicusMarine_pwd", "")) { + + cookies <- tempfile("cookies", fileext = ".txt") + + resp <- .try_online({ + "https://data-be-prd.marine.copernicus.eu/api/logIn" |> + httr2::request() |> + httr2::req_cookie_preserve(cookies) |> + httr2::req_auth_basic(username = username, password = password) |> + httr2::req_perform() + }, "login-form") + if (is.null(resp)) return(NULL) + + result <- resp |> + httr2::resp_body_json() + + result <- identical(result, structure(list(), names = character())) + + attr(result, "response") <- resp + attr(result, "cookies") <- cookies + return(result) +} \ No newline at end of file diff --git a/R/cms_product_details.r b/R/cms_product_details.r new file mode 100644 index 0000000..65e0258 --- /dev/null +++ b/R/cms_product_details.r @@ -0,0 +1,46 @@ +#' Obtain details for a specific Copernicus marine product +#' +#' `r lifecycle::badge('stable')` Obtain details for a specific Copernicus marine product. This can be +#' narrowed down to specific layers and/or variables within the product. +#' @inheritParams cms_download_subset +#' @param variant A `character` string indicating the type of details that should be returned. +#' Should be one of `""` (default), `"detailed-v2"`, or `"detailed-v3"`. +#' @returns Returns a named `list` with properties of the requested product. +#' @rdname cms_product_details +#' @name cms_product_details +#' @family product-functions +#' @examples +#' \donttest{ +#' cms_product_details("GLOBAL_ANALYSISFORECAST_PHY_001_024") +#' +#' cms_product_details( +#' product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", +#' layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", +#' variable = "thetao" +#' ) +#' } +#' @author Pepijn de Vries +#' @export +cms_product_details <- function(product, layer, variable, + variant = c("", "detailed-v2", "detailed-v3")) { + variant <- match.arg(variant) + if (missing(layer) && !missing(variable)) stop("Variable specified without layer.") + if (missing(product)) product <- "" + result <- .try_online({ + "https://data-be-prd.marine.copernicus.eu/api/dataset/%s?variant=%s" |> + sprintf(product, variant) |> + httr2::request() |> + httr2::req_perform() + }, "Copernicus") + + result <- + result |> + httr2::resp_body_json() + if (!missing(layer)) { + result <- result$layers[names(result$layers) |> startsWith(paste0(layer, "/"))] + } + if (!missing(variable)) { + result <- result[[paste0(c(layer, variable), collapse = "/")]] + } + return(result) +} \ No newline at end of file diff --git a/R/cms_product_metadata.r b/R/cms_product_metadata.r new file mode 100644 index 0000000..3bb1811 --- /dev/null +++ b/R/cms_product_metadata.r @@ -0,0 +1,39 @@ +#' Obtain meta data for a specific Copernicus marine product +#' +#' `r lifecycle::badge('stable')` Collect meta information, such as vocabularies used, +#' for specific Copernicus marine products +#' +#' @include cms_download_subset.r +#' @inheritParams cms_download_subset +#' @param type A `character` string indicating how the data should be returned. Should be one of +#' `"list"` or `"xml"`. +#' @returns Returns a named `list` (when `type = "list"`) with info about the requested `product`. +#' Returns the same info as `xml_document` (see [`xml2::xml_new_document()`]) when `type = "xml"`. +#' Returns `NULL` when contacting Copernicus fails. +#' @rdname cms_product_metadata +#' @name cms_product_metadata +#' @family product-functions +#' @examples +#' \donttest{ +#' cms_product_metadata("GLOBAL_ANALYSISFORECAST_PHY_001_024") +#' } +#' @author Pepijn de Vries +#' @export +cms_product_metadata <- function(product, type = c("list", "xml")) { + type <- match.arg(type) + meta_data <- + .try_online({ + sprintf("https://data-be-prd.marine.copernicus.eu/api/metadata/%s", product) |> + httr2::request() |> + httr2::req_perform() + }, "Copernicus") + if (is.null(meta_data)) return(NULL) + meta_data <- + meta_data |> + httr2::resp_body_xml() + if (type == "list") + meta_data <- + meta_data |> + xml2::as_list() + return(meta_data) +} \ No newline at end of file diff --git a/R/cms_product_services.r b/R/cms_product_services.r new file mode 100644 index 0000000..75537f4 --- /dev/null +++ b/R/cms_product_services.r @@ -0,0 +1,38 @@ +#' Obtain available services for a specific Copernicus marine product +#' +#' `r lifecycle::badge('deprecated')` Obtain an overview of services provided by Copernicus +#' for a specific marine product. +#' +#' @include cms_download_subset.r +#' @inheritParams cms_download_subset +#' @returns Returns a `tibble` with a list of available services for a +#' Copernicus marine `product`. +#' @examples +#' \donttest{ +#' cms_product_services("GLOBAL_ANALYSISFORECAST_PHY_001_024") +#' } +#' @family product-functions +#' @author Pepijn de Vries +#' @export +cms_product_services <- function(product) { + result <- cms_product_metadata(product, "xml") + + result <- + result |> + xml2::xml_find_all("//gmd:CI_OnlineResource") |> + xml2::as_list() |> + lapply(dplyr::as_tibble) |> + dplyr::bind_rows() |> + dplyr::mutate(ext = stringr::str_extract(unlist(.data$linkage), "(?<=--ext--)(.*)(?=/)")) |> + dplyr::mutate( + dplyr::across( + dplyr::everything(), + ~ { lapply(.x, function(y) if (is.null(y)) NA else y[[1]]) |> unlist() }) + ) |> + dplyr::select(dplyr::any_of(c("name", "ext", "linkage", "protocol"))) |> + dplyr::rename(!!"layer" := "name") |> + dplyr::filter(!is.na(.data$protocol) & !is.na(.data$layer)) |> + tidyr::pivot_wider(id_cols = c("layer", "ext"), + names_from = "protocol", values_from = "linkage") + return(result) +} \ No newline at end of file diff --git a/R/cms_products_list.r b/R/cms_products_list.r new file mode 100644 index 0000000..ffd8771 --- /dev/null +++ b/R/cms_products_list.r @@ -0,0 +1,92 @@ +#' List products available from data.marine.copernicus.eu +#' +#' `r lifecycle::badge('stable')` Collect a list of products and some brief +#' descriptions for marine products available from Copernicus +#' +#' @param ... Allows you to pass (search) query parameters to apply to the list. +#' When omitted, the full list of products is returned. +#' @param info_type One of `"list"` (default) or `"meta"`. `"list"` returns the actual list +#' whereas `"meta"` returns meta information for the executed query (e.g. number of hits). +#' @returns Returns a `tibble` of products available from or +#' a named `list` when `info_type = "meta"`. Returns `NULL` in case on-line services are +#' unavailable. +#' @rdname cms_products_list +#' @name cms_products_list +#' @family product-functions +#' @examples +#' \donttest{ +#' cms_products_list() +#' +#' ## Query a specific product: +#' cms_products_list(freeText = "GLOBAL_ANALYSISFORECAST_PHY_001_024") +#' } +#' @author Pepijn de Vries +#' @export +cms_products_list <- function(..., info_type = c("list", "meta")) { + info_type <- match.arg(info_type) + payload <- .payload_data_list + payload_mod <- list(...) + payload[names(payload_mod)] <- payload_mod + result <- .try_online({ + "https://data-be-prd.marine.copernicus.eu/api/datasets" |> + httr2::request() |> + httr2::req_method("POST") |> + httr2::req_body_json(payload) |> + httr2::req_perform() + }, "Copernicus") + if (is.null(result)) return(NULL) + result <- + result |> + httr2::resp_body_json() + switch( + info_type, + meta = { + result[names(result) != "datasets"] + }, + ## default is main data: + { + result[["datasets"]] |> + purrr::map(~purrr::map(.x, list)) |> + purrr::map_dfr(~ .x |> dplyr::as_tibble(), .id = "product_id") |> + dplyr::mutate( + dplyr::across( + dplyr::everything(), + function(x) { + x[unlist(lapply(x, length)) == 0] <- list(NA) + if (all(unlist(lapply(x, length)) == 1)) { + unlist(x) + } else x + } + ) + ) + }) +} + +.payload_data_list <- list( + facets = c("favorites", + "timeRange", + "vertLevels", + "colors", + "mainVariables", + "areas", + "omis", + "indicatorFamilies", + "featureTypes", + "tempResolutions", + "sources", + "processingLevel", + "directives", + "communities", + "originatingCenter"), + facetValues = suppressWarnings(structure(NULL, names = character(0))), + freeText = "", + dateRange = + list( + begin = NA, + end = NA, + coverFull = FALSE), + favoriteIds = list(), + offset = 0, + size = 1000, + variant = "summary", + includeOmis = TRUE) \ No newline at end of file diff --git a/R/cms_stac_properties.r b/R/cms_stac_properties.r new file mode 100644 index 0000000..a7c0756 --- /dev/null +++ b/R/cms_stac_properties.r @@ -0,0 +1,27 @@ +#' @rdname cms_stac +#' @name cms_stac_properties +#' @export +cms_stac_properties <- function(product, layer) { + services <- + cms_product_services(product) |> + dplyr::filter(!is.na(.data$`WWW:STAC`)) + if (!missing(layer)) services <- services |> dplyr::filter(layer == !!layer) + services <- services$`WWW:STAC` + + .props <- function(stac_url) { + x <- .try_online({ + httr2::request(stac_url) |> + httr2::req_perform() + }, "stac-properties") + if (is.null(x)) return(NULL) + if (is.null(x$headers$`content-type`) || is.na(x$headers$`content-type`)) + x$headers$`content-type` <- "application/json" + return(httr2::resp_body_json(x)) + } + props <- purrr::map(services, ~{ + .props(.x)$assets$native |> + dplyr::as_tibble() + }) |> dplyr::bind_rows() + + return(props) +} diff --git a/R/cms_wmts.r b/R/cms_wmts.r new file mode 100644 index 0000000..fa158e8 --- /dev/null +++ b/R/cms_wmts.r @@ -0,0 +1,110 @@ +#' Obtain a WMTS entry for specific Copernicus marine products and add to a leaflet map +#' +#' `r lifecycle::badge('stable')` Functions for retrieving Web Map Tile Services infromation for +#' specific products, layers and variables and add them to a `leaflet` map. +#' @include cms_download_subset.r +#' @inheritParams cms_download_subset +#' @param map A map widget object created from [`leaflet::leaflet()`] +#' @param tilematrixset A `character` string representing the tilematrixset to be used. In +#' many cases `"EPSG:3857"` (Pseudo-Mercator) or `"EPSG:4326"` (World Geodetic System 1984) +#' are available, but should be checked with `cms_wmts_details`. +#' @param options Passed on to [`leaflet::addWMSTiles()`]. +#' @param type A `character` string indicating whether the capabilities should be returned +#' as `"list"` (default) or `"xml"` ([`xml2::xml_new_document()`]). +#' @param ... Passed on to [`leaflet::addWMSTiles()`]. +#' @returns `cms_wmts_details` returns a tibble with detains on the WMTS service. +#' `cms_wmts_getcapabilities` returns either a `list` or `xml_document` depending on the value +#' of `type`. `AddCmsWMTSTiles` returns a `leaflet` `map` updated with the requested tiles. +#' @rdname cms_wmts +#' @name cms_wmts_details +#' @examples +#' \donttest{ +#' cms_wmts_details( +#' product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", +#' layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", +#' variable = "thetao" +#' ) +#' +#' cms_wmts_get_capabilities("GLOBAL_ANALYSISFORECAST_PHY_001_024") +#' +#' if (interactive()) { +#' leaflet::leaflet() |> +#' leaflet::setView(lng = 3, lat = 54, zoom = 4) |> +#' leaflet::addProviderTiles("Esri.WorldImagery") |> +#' addCmsWMTSTiles( +#' product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", +#' layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", +#' variable = "thetao") +#' } +#' } +#' @author Pepijn de Vries +#' @export +cms_wmts_details <- function(product, layer, variable) { + copwmtsinfo <- + sf::gdal_utils( + "info", + "WMTS:https://wmts.marine.copernicus.eu/teroWmts/%s?request=GetCapabilities" |> + sprintf(product), + quiet = TRUE) + desc <- copwmtsinfo |> stringr::str_match_all("SUBDATASET_(\\d)_DESC=(.*?)\n") + if (length(desc) == 0) return(dplyr::tibble(desc = character(0), url = character(0))) + desc <- desc[[1]][,3] + url <- copwmtsinfo |> stringr::str_match_all("SUBDATASET_(\\d)_NAME=(.*?)\n") + url <- url[[1]][,3] + result <- dplyr::bind_cols(desc = desc, url = url) + + if (!missing(layer)) { + result <- result |> dplyr::filter(grepl(layer, url, fixed = TRUE)) + } + if (!missing(variable)) { + result <- result |> dplyr::filter(grepl(paste0("/", variable, ","), url, fixed = TRUE)) + } + return(result) +} + +#' @rdname cms_wmts +#' @name addCmsWMTSTiles +#' @export +addCmsWMTSTiles <- function( + map, product, layer, variable, + tilematrixset = "EPSG:3857", + options = leaflet::WMSTileOptions(format = "image/png", transparent = TRUE), + ...) { + + detail <- cms_wmts_details(product, layer, variable) + detail <- detail$url |> strsplit(",") |> unlist() + detail <- detail[startsWith(detail, "layer=")] + leaflet::addTiles( + map = map, + urlTemplate = + .wmts_base_url |> + paste0( + .wmts_req, + "GetTile&tilematrixset=%s&style=default&tilematrix={z}&tilerow={y}&tilecol={x}&%s") |> + sprintf(tilematrixset, detail), + options = options, + ... + ) +} + +#' @rdname cms_wmts +#' @name cms_wmts_get_capabilities +#' @export +cms_wmts_get_capabilities <- function(product, layer, variable, type = c("list", "xml")) { + type <- match.arg(type) + layer <- if(missing(layer)) NULL else layer + variable <- if(missing(variable)) NULL else variable + set <- c(product, layer, variable) |> + paste0(collapse = "/") + result <- + .wmts_base_url |> + paste0(product, "/", .wmts_req, "GetCapabilities&layer=", set) |> + httr2::request() |> + httr2::req_perform() |> + httr2::resp_body_xml() + if (type == "list") result <- xml2::as_list(result) + return(result) +} + +.wmts_base_url <- "http://wmts.marine.copernicus.eu/teroWmts/" +.wmts_req <- "?service=WMTS&version=1.0.0&request=" \ No newline at end of file diff --git a/R/copernicus_cite_product.r b/R/copernicus_cite_product.r index 832cdfd..62e7f15 100644 --- a/R/copernicus_cite_product.r +++ b/R/copernicus_cite_product.r @@ -1,21 +1,22 @@ #' How to cite a Copernicus marine product #' -#' `r lifecycle::badge('stable')` Get details for properly citing a Copernicus product. +#' `r lifecycle::badge('deprecated')` Get details for properly citing a Copernicus product. #' #' @inheritParams copernicus_download_motu -#' @return Returns a vector of character strings. The first element is always the product title, id and doi. +#' @returns Returns a vector of character strings. The first element is always the product title, id and doi. #' Remaining elements are other associated references. Note that the remaining references are returned as #' listed at Copernicus. Note that the citing formatting does not appear to be standardised. #' @rdname copernicus_cite_product #' @name copernicus_cite_product #' @family product-functions #' @examples -#' \donttest{ +#' \dontrun{ #' copernicus_cite_product("SST_MED_PHY_SUBSKIN_L4_NRT_010_036") #' } #' @author Pepijn de Vries #' @export copernicus_cite_product <- function(product) { + .Deprecated("cms_cite_product") product_details <- copernicus_product_details(product) if (is.null(product_details)) return(NULL) result <- product_details$refs diff --git a/R/copernicus_download_motu.r b/R/copernicus_download_motu.r index 7cdabf2..85ecde7 100644 --- a/R/copernicus_download_motu.r +++ b/R/copernicus_download_motu.r @@ -1,13 +1,10 @@ #' Subset and download a specific marine product from Copernicus #' -#' `r lifecycle::badge('stable')` Subset and download a specific marine product from Copernicus. -#' This particular function uses the MOTU server for this purpose. You need to register an account -#' at before you can use this function. +#' `r lifecycle::badge('deprecated')` The MOTU servers will be discontinued by Copernicus Marine Services. Use [`cms_download_subset()`] +#' instead to download subsets. #' -#' @param username Your Copernicus marine user name. Can be provided as `options(CopernicusMarine_uid = "my_user_name")`, -#' or as argument here. -#' @param password Your Copernicus marine password. Can be provided as `options(CopernicusMarine_pwd = "my_password")`, -#' or as argument here. +#' @include cms_login.r +#' @inheritParams cms_login #' @param destination File or path where the requested file will be downloaded to. #' @param product An identifier (type `character`) of the desired Copernicus marine product. #' Can be obtained with [`copernicus_products_list`]. @@ -25,7 +22,7 @@ #' @param overwrite A `logical` value. When `FALSE` (default), files at the `destination` won't be #' overwritten when the exist. Instead an error will be thrown if this is the case. When set to #' `TRUE`, existing files will be overwritten. -#' @return Returns a `logical` value invisibly indicating whether the requested file was +#' @returns Returns a `logical` value invisibly indicating whether the requested file was #' successfully stored at the `destination`. #' @rdname copernicus_download_motu #' @name copernicus_download_motu @@ -56,6 +53,8 @@ copernicus_download_motu <- function( username = getOption("CopernicusMarine_uid", ""), password = getOption("CopernicusMarine_pwd", ""), destination, product, layer, variable, output, region, timerange, verticalrange, sub_variables, overwrite = FALSE) { + .Deprecated("cms_download_subset") + login <- copernicus_login(username, password) login_result <- attr(login, "response") cookies <- attr(login, "cookies") diff --git a/R/copernicus_login.r b/R/copernicus_login.r index 800558d..a0e6040 100644 --- a/R/copernicus_login.r +++ b/R/copernicus_login.r @@ -1,12 +1,12 @@ #' Contact Copernicus Marine login page #' -#' Contact Copernicus Marine login page and check if login is successful. +#' `r lifecycle::badge('deprecated')` This login method is only used by the +#' download methods that are deprecated by Copernicus Marine Services. Use +#' [`cms_login()`] instead. #' -#' This function will return a logical value indicating if the login is successful. -#' It can be used to test your account details. -#' -#' @inheritParams copernicus_download_motu -#' @return Returns a `logical` value indicating if the login is successful. +#' @include cms_login.r +#' @inheritParams cms_login +#' @returns Returns a `logical` value indicating if the login is successful. #' The response from the login page is returned as an attribute named `response`. #' @author Pepijn de Vries #' @examples @@ -16,6 +16,8 @@ #' ## it will return TRUE. #' copernicus_login() #' } +#' @name copernicus_login +#' @rdname copernicus_login #' @export copernicus_login <- function( username = getOption("CopernicusMarine_uid", ""), diff --git a/R/copernicus_product_details.r b/R/copernicus_product_details.r index 3186742..2db2f85 100644 --- a/R/copernicus_product_details.r +++ b/R/copernicus_product_details.r @@ -1,15 +1,15 @@ #' Obtain details for a specific Copernicus marine product #' -#' `r lifecycle::badge('stable')` Obtain details for a specific Copernicus marine product. This can be +#' `r lifecycle::badge('deprecated')` Obtain details for a specific Copernicus marine product. This can be #' narrowed down to specific layers and/or variables within the product. #' #' @inheritParams copernicus_download_motu -#' @return Returns a named `list` with properties of the requested product. +#' @returns Returns a named `list` with properties of the requested product. #' @rdname copernicus_product_details #' @name copernicus_product_details #' @family product-functions #' @examples -#' \donttest{ +#' \dontrun{ #' copernicus_product_details("GLOBAL_ANALYSISFORECAST_PHY_001_024") #' #' copernicus_product_details( @@ -21,6 +21,7 @@ #' @author Pepijn de Vries #' @export copernicus_product_details <- function(product, layer, variable) { + .Deprecated("cms_product_details") if (missing(layer) && !missing(variable)) stop("Variable specified without layer.") if (missing(product)) product <- "" result <- .try_online({ @@ -44,21 +45,22 @@ copernicus_product_details <- function(product, layer, variable) { #' Obtain available services for a specific Copernicus marine product #' -#' `r lifecycle::badge('stable')` Obtain an overview of services provided by Copernicus +#' `r lifecycle::badge('deprecated')` Obtain an overview of services provided by Copernicus #' for a specific marine product. #' #' @inheritParams copernicus_download_motu -#' @return Returns a `tibble` with a list of available services for a +#' @returns Returns a `tibble` with a list of available services for a #' Copernicus marine product #' @rdname copernicus_product_services #' @name copernicus_product_services #' @examples -#' \donttest{ +#' \dontrun{ #' copernicus_product_services("GLOBAL_ANALYSISFORECAST_PHY_001_024") #' } #' @author Pepijn de Vries #' @export copernicus_product_services <- function(product) { + .Deprecated("cms_product_details") services <- copernicus_product_details(product) services <- services$services |> purrr::map_dfr(dplyr::as_tibble) |> dplyr::mutate(layer = { diff --git a/R/copernicus_product_metadata.r b/R/copernicus_product_metadata.r index 25f7552..16402f4 100644 --- a/R/copernicus_product_metadata.r +++ b/R/copernicus_product_metadata.r @@ -1,6 +1,8 @@ #' Obtain meta data for a specific Copernicus marine product #' -#' `r lifecycle::badge('stable')` Collect meta information, such as vocabularies used, +#' `r lifecycle::badge('deprecated')` Deprecated. Use [`cms_product_metadata()`] instead. +#' +#' Collect meta information, such as vocabularies used, #' for specific Copernicus marine products #' #' @inheritParams copernicus_download_motu @@ -10,22 +12,12 @@ #' @name copernicus_product_metadata #' @family product-functions #' @examples -#' \donttest{ +#' \dontrun{ #' copernicus_product_metadata("GLOBAL_ANALYSISFORECAST_PHY_001_024") #' } #' @author Pepijn de Vries #' @export copernicus_product_metadata <- function(product) { - meta_data <- - .try_online({ - sprintf("https://data-be-prd.marine.copernicus.eu/api/metadata/%s", product) |> - httr2::request() |> - httr2::req_perform() - }, "Copernicus") - if (is.null(meta_data)) return(NULL) - meta_data <- - meta_data |> - httr2::resp_body_xml() |> - xml2::as_list() - return(meta_data) + .Deprecated("cms_product_metadata") + cms_product_metadata(product) } \ No newline at end of file diff --git a/R/copernicus_products_list.r b/R/copernicus_products_list.r index df08c65..1620969 100644 --- a/R/copernicus_products_list.r +++ b/R/copernicus_products_list.r @@ -1,6 +1,6 @@ #' List products available from data.marine.copernicus.eu #' -#' `r lifecycle::badge('stable')` Collect a list of products and some brief +#' `r lifecycle::badge('deprecated')` Collect a list of products and some brief #' descriptions for marine products available from Copernicus #' #' @param ... Allows you to pass (search) query parameters to apply to the list. @@ -14,79 +14,15 @@ #' @name copernicus_products_list #' @family product-functions #' @examples -#' \donttest{ +#' \dontrun{ #' copernicus_products_list() #' #' ## Query a specific product: -#' copernicus_products_list(freeText = "GLOBAL_ANALYSIS_FORECAST_BIO_001_028") +#' copernicus_products_list(freeText = "GLOBAL_ANALYSISFORECAST_PHY_001_024") #' } #' @author Pepijn de Vries #' @export copernicus_products_list <- function(..., info_type = c("list", "meta")) { - info_type <- match.arg(info_type) - payload <- .payload_data_list - payload_mod <- list(...) - payload[names(payload_mod)] <- payload_mod - result <- .try_online({ - "https://data-be-prd.marine.copernicus.eu/api/datasets" |> - httr2::request() |> - httr2::req_method("POST") |> - httr2::req_body_json(payload) |> - httr2::req_perform() - }, "Copernicus") - if (is.null(result)) return(NULL) - result <- - result |> - httr2::resp_body_json() - switch( - info_type, - meta = { - result[names(result) != "datasets"] - }, - ## default is main data: - { - result[["datasets"]] |> - purrr::map(~purrr::map(.x, list)) |> - purrr::map_dfr(~ .x |> dplyr::as_tibble(), .id = "product_id") |> - dplyr::mutate( - dplyr::across( - dplyr::everything(), - function(x) { - x[unlist(lapply(x, length)) == 0] <- list(NA) - if (all(unlist(lapply(x, length)) == 1)) { - unlist(x) - } else x - } - ) - ) - }) -} - -.payload_data_list <- list( - facets = c("favorites", - "timeRange", - "vertLevels", - "colors", - "mainVariables", - "areas", - "omis", - "indicatorFamilies", - "featureTypes", - "tempResolutions", - "sources", - "processingLevel", - "directives", - "communities", - "originatingCenter"), - facetValues = suppressWarnings(structure(NULL, names = character(0))), - freeText = "", - dateRange = - list( - begin = NA, - end = NA, - coverFull = FALSE), - favoriteIds = list(), - offset = 0, - size = 1000, - variant = "summary", - includeOmis = TRUE) \ No newline at end of file + .Deprecated("cms_products_list") + cms_products_list(..., info_type) +} \ No newline at end of file diff --git a/R/ftp.r b/R/ftp.r index 157d779..fb2bc25 100644 --- a/R/ftp.r +++ b/R/ftp.r @@ -1,6 +1,6 @@ #' List and get FTP files for a Copernicus marine product #' -#' `r lifecycle::badge('stable')` Full marine data sets can be downloaded using the +#' `r lifecycle::badge('deprecated')` Full marine data sets can be downloaded using the #' File Transfer Protocol (FTP). Use these functions to list download locations and get #' the files. #' @@ -37,6 +37,7 @@ copernicus_ftp_list <- function( password = getOption("CopernicusMarine_pwd", ""), recursive = TRUE, subdir = NULL) { + .Deprecated("cms_list_stac_files") name <- NULL # workaround for 'no visible binding global for global variable' dirlist <- function(url){ dir_result <- @@ -96,6 +97,7 @@ copernicus_ftp_get <- function( url, destination, show_progress = TRUE, overwrite = FALSE, username = getOption("CopernicusMarine_uid", ""), password = getOption("CopernicusMarine_pwd", "")) { + .Deprecated("cms_download_stac") if (!dir.exists(destination)) stop("'destination' either doesn't exist or is not a directory!") destination <- file.path(destination, basename(url)) diff --git a/R/import.r b/R/import.r new file mode 100644 index 0000000..47fd006 --- /dev/null +++ b/R/import.r @@ -0,0 +1,2 @@ +#' @importFrom rlang `:=` .data +NULL \ No newline at end of file diff --git a/R/wms.r b/R/wms.r index 8f53e97..4c29c34 100644 --- a/R/wms.r +++ b/R/wms.r @@ -1,15 +1,15 @@ #' Obtain a WMS entry for specific Copernicus marine products #' -#' `r lifecycle::badge('experimental')` Web Map Services are not available for all +#' `r lifecycle::badge('deprecated')` Web Map Services are not available for all #' products and layers. Use this function to obtain URLs of WMS services if any. -#' @template wms_template +#' @note WMS functions don't work on systems that don't support GDAL utils #' @inheritParams copernicus_download_motu #' @returns Returns a `tibble` with WMS URLs and descriptors for the specified product. #' @rdname copernicus_wms_details #' @name copernicus_wms_details #' @family wms-functions #' @examples -#' \donttest{ +#' \dontrun{ #' copernicus_wms_details( #' product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", #' layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", @@ -19,6 +19,7 @@ #' @author Pepijn de Vries #' @export copernicus_wms_details <- function(product, layer, variable) { + .Deprecated("cms_get_wmts_details") product_details <- copernicus_product_details(product, layer, variable) if (is.null(product_details)) return(NULL) @@ -34,10 +35,10 @@ copernicus_wms_details <- function(product, layer, variable) { #' Add Copernicus Marine WMS Tiles to a leaflet map #' -#' `r lifecycle::badge('experimental')` Create an interactive map with +#' `r lifecycle::badge('deprecated')` Create an interactive map with #' `leaflet::leaflet()` and add layers of Copernicus marine WMS data #' to it. -#' @template wms_template +#' @note WMS functions don't work on systems that don't support GDAL utils #' @param map A map widget object created from [`leaflet::leaflet()`] #' @inheritParams copernicus_download_motu #' @param options Passed on to [`leaflet::addWMSTiles()`]. @@ -47,7 +48,7 @@ copernicus_wms_details <- function(product, layer, variable) { #' @name addCopernicusWMSTiles #' @family wms-functions #' @examples -#' \donttest{ +#' \dontrun{ #' if (interactive()) { #' leaflet::leaflet() |> #' leaflet::setView(lng = 3, lat = 54, zoom = 4) |> @@ -63,6 +64,7 @@ copernicus_wms_details <- function(product, layer, variable) { addCopernicusWMSTiles <- function(map, product, layer, variable, options = leaflet::WMSTileOptions(format = "image/png", transparent = TRUE), ...) { + .Deprecated("addCmsWMSTTiles") detail <- copernicus_product_details(product, layer, variable) if (is.null(detail)) return(NULL) leaflet::addWMSTiles( @@ -76,14 +78,15 @@ addCopernicusWMSTiles <- function(map, product, layer, variable, #' Extract and store WMS as a geo-referenced TIFF #' -#' `r lifecycle::badge('experimental')` Extract and store imagery from a Copernicus WMS -#' as a geo-referenced TIFF. +#' `r lifecycle::badge('deprecated')` This function interacts with deprecated Copernicus Marine +#' Services. It will become [`.Defunct()`] in future versions. Extract and store imagery from a +#' Copernicus WMS as a geo-referenced TIFF. #' #' A Web Map Service (WMS) cannot be plotted directly (base, ggplot2 and/or lattice). #' For that purpose you need to extract and download a specific region in a format #' that can be handled by plots. You can use this function to store a subset of a #' WMS map as a geo-referenced TIFF file. -#' @template wms_template +#' @note WMS functions don't work on systems that don't support GDAL utils #' @inheritParams copernicus_download_motu #' @param destination File name for the geo-referenced TIFF. #' @param width Width in pixels of the TIFF image. @@ -93,7 +96,7 @@ addCopernicusWMSTiles <- function(map, product, layer, variable, #' @name copernicus_wms2geotiff #' @family wms-functions #' @examples -#' \donttest{ +#' \dontrun{ #' destination <- tempfile("wms", fileext = ".tiff") #' copernicus_wms2geotiff( #' product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", @@ -108,6 +111,7 @@ addCopernicusWMSTiles <- function(map, product, layer, variable, #' @author Pepijn de Vries #' @export copernicus_wms2geotiff <- function(product, layer, variable, region, destination, width, height) { + .Deprecated(msg = "This function interacts with deprecated Copernicus Marine Services, it will be discontinued.") wms_details <- copernicus_wms_details(product, layer, variable) product_details <- copernicus_product_details(product, layer, variable) if (is.null(wms_details) || is.null(product_details)) return(NULL) diff --git a/README.Rmd b/README.Rmd index 9e31325..e0473ba 100644 --- a/README.Rmd +++ b/README.Rmd @@ -30,9 +30,11 @@ retrieval of information from . With the pack ## Why use `{CopernicusMarine}` -Previously, there was only a MOTU client available for Python. Therefore, automating Copernicus downloads in R -used to require installation of python and its [motuclient](https://pypi.org/project/motuclient/) package. The -`{CopernicusMarine}` R package has a much simpler installation procedure (see below) and does not depend on +Copernicus Marine offers access to their data services through a +[Python application interface](https://pypi.org/project/copernicus-marine-client/). +For R users this requires complex installation procedures and is difficult to maintain in +a stable R package. The `{CopernicusMarine}` R package has +a much simpler installation procedure (see below) and does not depend on third party software, other than packages available from [CRAN](https://cran.r-project.org/). ## Installation @@ -53,13 +55,13 @@ services you need an account and have to comply with [specific terms](https://marine.copernicus.eu/user-corner/service-commitments-and-licence). The usage section briefly shows three different ways of obtaining data from Copernicus: - * [Using the MOTU server](#sec-motu) - * [Using the FTP server](#sec-ftp) - * [Using the WMS server](#sec-wms) + * [Downloading a subset](#sec-subset) + * [Downloading a full dataset](#sec-full) + * [Using the WMTS server](#sec-wtms) Please check the manual for complete documentation of the package. -

Subsetting data using MOTU server

+

Downloading a subset

The code below assumes that you have registered your account details using `options(CopernicusMarine_uid = "my_user_name")` and `options(CopernicusMarine_pwd = "my_password")`. If you are comfortable that it is secure enough, you can also store these @@ -67,22 +69,20 @@ options in your `.Rprofile` such that they will be loaded each session. Otherwis as arguments to the functions. The example below demonstrates how to subset a specific layer for a specific product. The subset is constrained by -the `region`, `timerange`, `verticalrange` and `sub_variables` arguments. The subset is downloaded to the temporary +the `region`, `timerange` and `verticalrange` arguments. The subset is downloaded to the temporary file specified with `destination` and can be read using the [`{stars}`](https://r-spatial.github.io/stars/) package. -```{r motu-subset, eval=TRUE} +```{r download-subset, eval=TRUE} destination <- tempfile("copernicus", fileext = ".nc") -copernicus_download_motu( +cms_download_subset( destination = destination, product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", layer = "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m", variable = "sea_water_velocity", - output = "netcdf", region = c(-1, 50, 10, 55), timerange = c("2021-01-01", "2021-01-02"), - verticalrange = c(0, 2), - sub_variables = c("uo", "vo") + verticalrange = c(0, 2) ) mydata <- stars::read_stars(destination) @@ -90,45 +90,44 @@ mydata <- stars::read_stars(destination) plot(mydata["vo"], col = hcl.colors(100), axes = TRUE) ``` -

Downloading a complete Copernicus marine product

+

Downloading a complete Copernicus marine product

-If you don't want to subset the data and want the complete set, you can use the File Transfer Protocol (FTP) if -that service is available for your product. First you can list files available for a specific product: +If you don't want to subset the data and want the complete set, you can use the +SpatioTemporal Asset Catalogs (STAC), if these are available for your product. +First you can list STAC files available for a specific product (and layer): ```{r, eval=TRUE} -cop_ftp_files <- copernicus_ftp_list("GLOBAL_ANALYSISFORECAST_PHY_001_024", "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m") -cop_ftp_files +stac_files <- + cms_list_stac_files( + "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m") +stac_files ``` -Downloading the first file can be done with `copernicus_ftp_get(cop_ftp_files$url[[1]], tempdir())`, where the +Downloading the first file can be done with +`cms_download_stac(stac_files[1,,drop = FALSE], tempdir())`, where the file would be stored in a temporary directory. By default the progress is printed as files can be very large and may take some time to download. -

Copernicus Web Map Services (WMS)

+

Copernicus Web Map Tile Services (WMTS)

-Web Map Services (WMS) allow to quickly plot pre-rendered images onto a map. This may not be useful when +Web Map Tile Services (WMTS) allow to quickly plot pre-rendered images onto a map. This may not be useful when you need the data for analyses but is handy for quick visualisations, inspection or presentation of data. -In R it is very easy to add WMS layers to an interactive map using [leaflet](https://rstudio.github.io/leaflet/) +In R it is very easy to add WMTS layers to an interactive map using [leaflet](https://rstudio.github.io/leaflet/) widgets. This is demonstrated with the example below (note that in the documentation the map is only shown statically and is not interactive). ```{r leaflet, eval=TRUE} -leaflet::leaflet() %>% - leaflet::setView(lng = 3, lat = 54, zoom = 4) %>% - leaflet::addProviderTiles("Esri.WorldImagery") %>% - addCopernicusWMSTiles( +leaflet::leaflet() |> + leaflet::setView(lng = 3, lat = 54, zoom = 4) |> + leaflet::addProviderTiles("Esri.WorldImagery") |> + addCmsWMTSTiles( product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", variable = "thetao" ) ``` -When you want to use WMS tiles in static plots, you could download and store specific regions of the tiles -as a [geo-referenced tiff](https://en.wikipedia.org/wiki/GeoTIFF) file for future use. Use `copernicus_wms2geotiff` -for that purpose. - -Note that the WMS functions may not work on systems that don't support GDAL utils. - ### Citing the data you use A Copernicus account comes with several terms of use. One of these is that you @@ -137,13 +136,34 @@ the data you use in publications. In fact, we also have credit the data used in done with the following code: ```{r, eval=TRUE} -copernicus_cite_product("GLOBAL_ANALYSISFORECAST_PHY_001_024") +cms_cite_product("GLOBAL_ANALYSISFORECAST_PHY_001_024") ``` +

A note to CopernicusMarine ≤0.1.3 users

+ +Older versions of the `CopernicusMarine` package implemented functions that interface with +services that are deprecated by Copernicus Marine. Namely, the MOTU server (for subsetting +and downloading), the FTP server (for downloading full sets) and the WMS server for +adding tiles to maps. + +These services are phased out, and in the latest release of this package, functions that interact +with them are deprecated. They can still be used for as long as these services are provided by +Copernicus Marine. When these services are terminated, the functions will become defunct. + +Please switch to the implementation of the new services at your earliest convenience. Specifically, +this means that you need to use: + + * `cms_download_subset` instead of ~~`copernicus_download_motu`~~; + * `cms_download_stac` instead of ~~`copernicus_download_ftp`~~; + * `addCmsWMTSTiles` instead of ~~`addCopernicusWMSTiles`~~. + +The design of the new functions is very similar to that of +the old ones, so switching should be relatively easy. + ## Resources ```{r, eval=TRUE, echo=FALSE} -cop_det <- copernicus_product_details("GLOBAL_ANALYSISFORECAST_PHY_001_024") +cop_det <- cms_product_details("GLOBAL_ANALYSISFORECAST_PHY_001_024") ``` * [E.U. Copernicus Marine Service Information](https://data.marine.copernicus.eu) diff --git a/README.md b/README.md index cfbb3f7..5cc58b9 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,14 @@ programme and facilitates retrieval of information from ## Why use `{CopernicusMarine}` -Previously, there was only a MOTU client available for Python. -Therefore, automating Copernicus downloads in R used to require -installation of python and its -[motuclient](https://pypi.org/project/motuclient/) package. The -`{CopernicusMarine}` R package has a much simpler installation procedure -(see below) and does not depend on third party software, other than -packages available from [CRAN](https://cran.r-project.org/). +Copernicus Marine offers access to their data services through a [Python +application +interface](https://pypi.org/project/copernicus-marine-client/). For R +users this requires complex installation procedures and is difficult to +maintain in a stable R package. The `{CopernicusMarine}` R package has a +much simpler installation procedure (see below) and does not depend on +third party software, other than packages available from +[CRAN](https://cran.r-project.org/). ## Installation @@ -53,14 +54,14 @@ terms](https://marine.copernicus.eu/user-corner/service-commitments-and-licence) The usage section briefly shows three different ways of obtaining data from Copernicus: -- [Using the MOTU server](#sec-motu) -- [Using the FTP server](#sec-ftp) -- [Using the WMS server](#sec-wms) +- [Downloading a subset](#sec-subset) +- [Downloading a full dataset](#sec-full) +- [Using the WMTS server](#sec-wtms) Please check the manual for complete documentation of the package. -

-Subsetting data using MOTU server +

+Downloading a subset

The code below assumes that you have registered your account details @@ -71,28 +72,25 @@ that it is secure enough, you can also store these options in your can also provide your account details as arguments to the functions. The example below demonstrates how to subset a specific layer for a -specific product. The subset is constrained by the `region`, -`timerange`, `verticalrange` and `sub_variables` arguments. The subset -is downloaded to the temporary file specified with `destination` and can -be read using the [`{stars}`](https://r-spatial.github.io/stars/) -package. +specific product. The subset is constrained by the `region`, `timerange` +and `verticalrange` arguments. The subset is downloaded to the temporary +file specified with `destination` and can be read using the +[`{stars}`](https://r-spatial.github.io/stars/) package. ``` r destination <- tempfile("copernicus", fileext = ".nc") -copernicus_download_motu( +cms_download_subset( destination = destination, product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", layer = "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m", variable = "sea_water_velocity", - output = "netcdf", region = c(-1, 50, 10, 55), timerange = c("2021-01-01", "2021-01-02"), - verticalrange = c(0, 2), - sub_variables = c("uo", "vo") + verticalrange = c(0, 2) ) -#> Logging in onto MOTU server... -#> Preparing download... +#> Preparing job... +#> Waiting for job to finish... #> Downloading file... #> Done @@ -102,57 +100,62 @@ mydata <- stars::read_stars(destination) plot(mydata["vo"], col = hcl.colors(100), axes = TRUE) ``` -![](man/figures/README-motu-subset-1.png) +![](man/figures/README-download-subset-1.png) -

+

Downloading a complete Copernicus marine product

If you don’t want to subset the data and want the complete set, you can -use the File Transfer Protocol (FTP) if that service is available for -your product. First you can list files available for a specific product: +use the SpatioTemporal Asset Catalogs (STAC), if these are available for +your product. First you can list STAC files available for a specific +product (and layer): ``` r -cop_ftp_files <- copernicus_ftp_list("GLOBAL_ANALYSISFORECAST_PHY_001_024", "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m") -cop_ftp_files -#> # A tibble: 1,156 × 8 -#> flags len protocol size month day time url -#> -#> 1 -rw-rw-r-- 1 ftp 1937968861 Oct 14 2022 ftp://nrt.cmems-du.eu… -#> 2 -rw-rw-r-- 1 ftp 1937978851 Oct 14 2022 ftp://nrt.cmems-du.eu… -#> 3 -rw-rw-r-- 1 ftp 1937888467 Oct 14 2022 ftp://nrt.cmems-du.eu… -#> 4 -rw-rw-r-- 1 ftp 1938380754 Oct 14 2022 ftp://nrt.cmems-du.eu… -#> 5 -rw-rw-r-- 1 ftp 1938177028 Oct 14 2022 ftp://nrt.cmems-du.eu… -#> 6 -rw-rw-r-- 1 ftp 1938234339 Oct 14 2022 ftp://nrt.cmems-du.eu… -#> 7 -rw-rw-r-- 1 ftp 1938285902 Oct 14 2022 ftp://nrt.cmems-du.eu… -#> 8 -rw-rw-r-- 1 ftp 1937954892 Oct 14 2022 ftp://nrt.cmems-du.eu… -#> 9 -rw-rw-r-- 1 ftp 1937964478 Oct 14 2022 ftp://nrt.cmems-du.eu… -#> 10 -rw-rw-r-- 1 ftp 1937962443 Oct 14 2022 ftp://nrt.cmems-du.eu… -#> # ℹ 1,146 more rows +stac_files <- + cms_list_stac_files( + "GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m") +stac_files +#> # A tibble: 1,165 × 8 +#> home native current_path LastModified ETag Size StorageClass Type +#> +#> 1 s3.waw3-1.cl… mdl-n… native/GLOB… 2023-11-17T… "\"3… 1937… STANDARD Norm… +#> 2 s3.waw3-1.cl… mdl-n… native/GLOB… 2023-11-17T… "\"a… 1937… STANDARD Norm… +#> 3 s3.waw3-1.cl… mdl-n… native/GLOB… 2023-11-17T… "\"f… 1937… STANDARD Norm… +#> 4 s3.waw3-1.cl… mdl-n… native/GLOB… 2023-11-17T… "\"d… 1938… STANDARD Norm… +#> 5 s3.waw3-1.cl… mdl-n… native/GLOB… 2023-11-17T… "\"e… 1938… STANDARD Norm… +#> 6 s3.waw3-1.cl… mdl-n… native/GLOB… 2023-11-17T… "\"5… 1938… STANDARD Norm… +#> 7 s3.waw3-1.cl… mdl-n… native/GLOB… 2023-11-17T… "\"c… 1938… STANDARD Norm… +#> 8 s3.waw3-1.cl… mdl-n… native/GLOB… 2023-11-17T… "\"6… 1937… STANDARD Norm… +#> 9 s3.waw3-1.cl… mdl-n… native/GLOB… 2023-11-17T… "\"5… 1937… STANDARD Norm… +#> 10 s3.waw3-1.cl… mdl-n… native/GLOB… 2023-11-17T… "\"6… 1937… STANDARD Norm… +#> # ℹ 1,155 more rows ``` Downloading the first file can be done with -`copernicus_ftp_get(cop_ftp_files$url[[1]], tempdir())`, where the file -would be stored in a temporary directory. By default the progress is -printed as files can be very large and may take some time to download. +`cms_download_stac(stac_files[1,,drop = FALSE], tempdir())`, where the +file would be stored in a temporary directory. By default the progress +is printed as files can be very large and may take some time to +download. -

-Copernicus Web Map Services (WMS) +

+Copernicus Web Map Tile Services (WMTS)

-Web Map Services (WMS) allow to quickly plot pre-rendered images onto a -map. This may not be useful when you need the data for analyses but is -handy for quick visualisations, inspection or presentation of data. In R -it is very easy to add WMS layers to an interactive map using -[leaflet](https://rstudio.github.io/leaflet/) widgets. This is +Web Map Tile Services (WMTS) allow to quickly plot pre-rendered images +onto a map. This may not be useful when you need the data for analyses +but is handy for quick visualisations, inspection or presentation of +data. In R it is very easy to add WMTS layers to an interactive map +using [leaflet](https://rstudio.github.io/leaflet/) widgets. This is demonstrated with the example below (note that in the documentation the map is only shown statically and is not interactive). ``` r -leaflet::leaflet() %>% - leaflet::setView(lng = 3, lat = 54, zoom = 4) %>% - leaflet::addProviderTiles("Esri.WorldImagery") %>% - addCopernicusWMSTiles( +leaflet::leaflet() |> + leaflet::setView(lng = 3, lat = 54, zoom = 4) |> + leaflet::addProviderTiles("Esri.WorldImagery") |> + addCmsWMTSTiles( product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", variable = "thetao" @@ -161,14 +164,6 @@ leaflet::leaflet() %>% ![](man/figures/README-leaflet-1.png) -When you want to use WMS tiles in static plots, you could download and -store specific regions of the tiles as a [geo-referenced -tiff](https://en.wikipedia.org/wiki/GeoTIFF) file for future use. Use -`copernicus_wms2geotiff` for that purpose. - -Note that the WMS functions may not work on systems that don’t support -GDAL utils. - ### Citing the data you use A Copernicus account comes with several terms of use. One of these is @@ -179,11 +174,36 @@ used in this documentation, which can be easily done with the following code: ``` r -copernicus_cite_product("GLOBAL_ANALYSISFORECAST_PHY_001_024") +cms_cite_product("GLOBAL_ANALYSISFORECAST_PHY_001_024") #> $doi #> [1] "E.U. Copernicus Marine Service Information; Global Ocean Physics Analysis and Forecast - GLOBAL_ANALYSISFORECAST_PHY_001_024 (2016-10-14). DOI:10.48670/moi-00016" ``` +

+A note to CopernicusMarine ≤0.1.3 users +

+ +Older versions of the `CopernicusMarine` package implemented functions +that interface with services that are deprecated by Copernicus Marine. +Namely, the MOTU server (for subsetting and downloading), the FTP server +(for downloading full sets) and the WMS server for adding tiles to maps. + +These services are phased out, and in the latest release of this +package, functions that interact with them are deprecated. They can +still be used for as long as these services are provided by Copernicus +Marine. When these services are terminated, the functions will become +defunct. + +Please switch to the implementation of the new services at your earliest +convenience. Specifically, this means that you need to use: + +- `cms_download_subset` instead of ~~`copernicus_download_motu`~~; +- `cms_download_stac` instead of ~~`copernicus_download_ftp`~~; +- `addCmsWMTSTiles` instead of ~~`addCopernicusWMSTiles`~~. + +The design of the new functions is very similar to that of the old ones, +so switching should be relatively easy. + ## Resources - [E.U. Copernicus Marine Service diff --git a/man-roxygen/wms_template.r b/man-roxygen/wms_template.r deleted file mode 100644 index d517d10..0000000 --- a/man-roxygen/wms_template.r +++ /dev/null @@ -1,2 +0,0 @@ -#' @note WMS functions don't work on systems that don't support GDAL utils -NULL diff --git a/man/addCopernicusWMSTiles.Rd b/man/addCopernicusWMSTiles.Rd index cb7d83f..b261dee 100644 --- a/man/addCopernicusWMSTiles.Rd +++ b/man/addCopernicusWMSTiles.Rd @@ -32,7 +32,7 @@ Can be obtained with \code{\link{copernicus_product_details}}.} Returns an updated \code{map} } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} Create an interactive map with +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Create an interactive map with \code{leaflet::leaflet()} and add layers of Copernicus marine WMS data to it. } @@ -40,7 +40,7 @@ to it. WMS functions don't work on systems that don't support GDAL utils } \examples{ -\donttest{ +\dontrun{ if (interactive()) { leaflet::leaflet() |> leaflet::setView(lng = 3, lat = 54, zoom = 4) |> diff --git a/man/cms_cite_product.Rd b/man/cms_cite_product.Rd new file mode 100644 index 0000000..ecb2d0e --- /dev/null +++ b/man/cms_cite_product.Rd @@ -0,0 +1,40 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cms_cite_product.r +\name{cms_cite_product} +\alias{cms_cite_product} +\title{How to cite a Copernicus marine product} +\usage{ +cms_cite_product(product) +} +\arguments{ +\item{product}{An identifier (type \code{character}) of the desired Copernicus marine product. +Can be obtained with \code{\link{cms_products_list}}.} +} +\value{ +Returns a vector of character strings. The first element is always the product title, id and doi. +Remaining elements are other associated references. Note that the remaining references are returned as +listed at Copernicus. Note that the citing formatting does not appear to be standardised. +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Get details for properly citing a Copernicus product. +} +\examples{ +\donttest{ +cms_cite_product("SST_MED_PHY_SUBSKIN_L4_NRT_010_036") +} +} +\seealso{ +Other product-functions: +\code{\link{cms_product_details}()}, +\code{\link{cms_product_metadata}()}, +\code{\link{cms_product_services}()}, +\code{\link{cms_products_list}()}, +\code{\link{copernicus_cite_product}()}, +\code{\link{copernicus_product_details}()}, +\code{\link{copernicus_product_metadata}()}, +\code{\link{copernicus_products_list}()} +} +\author{ +Pepijn de Vries +} +\concept{product-functions} diff --git a/man/cms_download_subset.Rd b/man/cms_download_subset.Rd new file mode 100644 index 0000000..1926bfc --- /dev/null +++ b/man/cms_download_subset.Rd @@ -0,0 +1,81 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cms_download_subset.r +\name{cms_download_subset} +\alias{cms_download_subset} +\title{Subset and download a specific marine product from Copernicus} +\usage{ +cms_download_subset( + username = getOption("CopernicusMarine_uid", ""), + password = getOption("CopernicusMarine_pwd", ""), + destination, + product, + layer, + variable, + region, + timerange, + verticalrange, + overwrite = FALSE +) +} +\arguments{ +\item{username}{Your Copernicus marine user name. Can be provided as +\code{options(CopernicusMarine_uid = "my_user_name")}, or as argument here.} + +\item{password}{Your Copernicus marine password. Can be provided as +\code{options(CopernicusMarine_pwd = "my_password")}, or as argument here.} + +\item{destination}{File or path where the requested file will be downloaded to.} + +\item{product}{An identifier (type \code{character}) of the desired Copernicus marine product. +Can be obtained with \code{\link{cms_products_list}}.} + +\item{layer}{The name of a desired layer within a product (type \code{character}). Can be obtained with \code{\link{cms_product_details}}.} + +\item{variable}{The name of a desired variable in a specific layer of a product (type \code{character}). +Can be obtained with \code{\link{copernicus_product_details}}.} + +\item{region}{Specification of the bounding box as a \code{vector} of \code{numeric}s WGS84 lat and lon coordinates. +Should be in the order of: xmin, ymin, xmax, ymax.} + +\item{timerange}{A \code{vector} with two elements (lower and upper value) +for a requested time range. The \code{vector} should be coercible to \code{POSIXct}.} + +\item{verticalrange}{A \code{vector} with two elements (minimum and maximum) +numerical values for the depth of the vertical layers (if any).} + +\item{overwrite}{A \code{logical} value. When \code{FALSE} (default), files at the \code{destination} won't be +overwritten when the exist. Instead an error will be thrown if this is the case. When set to +\code{TRUE}, existing files will be overwritten.} +} +\value{ +Returns a \code{logical} value invisibly indicating whether the requested file was +successfully stored at the \code{destination}. +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Subset and download a specific marine product from Copernicus. +You need to register an account +at \url{https://data.marine.copernicus.eu} before you can use this function. +} +\examples{ +\dontrun{ +destination <- tempfile("copernicus", fileext = ".nc") + +## Assuming that Copernicus account details are provided as `options` +cms_download_subset( + destination = destination, + product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", + layer = "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m", + variable = "sea_water_velocity", + region = c(-1, 50, 10, 55), + timerange = c("2021-01-01 UTC", "2021-01-02 UTC"), + verticalrange = c(0, 2) +) + +mydata <- stars::read_stars(destination) + +plot(mydata["vo"]) +} +} +\author{ +Pepijn de Vries +} diff --git a/man/cms_login.Rd b/man/cms_login.Rd new file mode 100644 index 0000000..8a179a4 --- /dev/null +++ b/man/cms_login.Rd @@ -0,0 +1,41 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cms_login.r +\name{cms_login} +\alias{cms_login} +\title{Contact Copernicus Marine login page} +\usage{ +cms_login( + username = getOption("CopernicusMarine_uid", ""), + password = getOption("CopernicusMarine_pwd", "") +) +} +\arguments{ +\item{username}{Your Copernicus marine user name. Can be provided as +\code{options(CopernicusMarine_uid = "my_user_name")}, or as argument here.} + +\item{password}{Your Copernicus marine password. Can be provided as +\code{options(CopernicusMarine_pwd = "my_password")}, or as argument here.} +} +\value{ +Returns a \code{logical} value indicating if the login is successful. +The response from the login page is returned as an attribute named \code{response}. +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Contact Copernicus Marine login page +and check if login is successful. +} +\details{ +This function will return a logical value indicating if the login is successful. +It can be used to test your account details. +} +\examples{ +\dontrun{ +## This will return FALSE if you have not set your account details with 'options'. +## If you have specified your account details and there are no other problems, +## it will return TRUE. +copernicus_login() +} +} +\author{ +Pepijn de Vries +} diff --git a/man/cms_product_details.Rd b/man/cms_product_details.Rd new file mode 100644 index 0000000..02a3048 --- /dev/null +++ b/man/cms_product_details.Rd @@ -0,0 +1,58 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cms_product_details.r +\name{cms_product_details} +\alias{cms_product_details} +\title{Obtain details for a specific Copernicus marine product} +\usage{ +cms_product_details( + product, + layer, + variable, + variant = c("", "detailed-v2", "detailed-v3") +) +} +\arguments{ +\item{product}{An identifier (type \code{character}) of the desired Copernicus marine product. +Can be obtained with \code{\link{cms_products_list}}.} + +\item{layer}{The name of a desired layer within a product (type \code{character}). Can be obtained with \code{\link{cms_product_details}}.} + +\item{variable}{The name of a desired variable in a specific layer of a product (type \code{character}). +Can be obtained with \code{\link{copernicus_product_details}}.} + +\item{variant}{A \code{character} string indicating the type of details that should be returned. +Should be one of \code{""} (default), \code{"detailed-v2"}, or \code{"detailed-v3"}.} +} +\value{ +Returns a named \code{list} with properties of the requested product. +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Obtain details for a specific Copernicus marine product. This can be +narrowed down to specific layers and/or variables within the product. +} +\examples{ +\donttest{ +cms_product_details("GLOBAL_ANALYSISFORECAST_PHY_001_024") + +cms_product_details( + product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", + layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", + variable = "thetao" +) +} +} +\seealso{ +Other product-functions: +\code{\link{cms_cite_product}()}, +\code{\link{cms_product_metadata}()}, +\code{\link{cms_product_services}()}, +\code{\link{cms_products_list}()}, +\code{\link{copernicus_cite_product}()}, +\code{\link{copernicus_product_details}()}, +\code{\link{copernicus_product_metadata}()}, +\code{\link{copernicus_products_list}()} +} +\author{ +Pepijn de Vries +} +\concept{product-functions} diff --git a/man/cms_product_metadata.Rd b/man/cms_product_metadata.Rd new file mode 100644 index 0000000..8a50cfd --- /dev/null +++ b/man/cms_product_metadata.Rd @@ -0,0 +1,44 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cms_product_metadata.r +\name{cms_product_metadata} +\alias{cms_product_metadata} +\title{Obtain meta data for a specific Copernicus marine product} +\usage{ +cms_product_metadata(product, type = c("list", "xml")) +} +\arguments{ +\item{product}{An identifier (type \code{character}) of the desired Copernicus marine product. +Can be obtained with \code{\link{cms_products_list}}.} + +\item{type}{A \code{character} string indicating how the data should be returned. Should be one of +\code{"list"} or \code{"xml"}.} +} +\value{ +Returns a named \code{list} (when \code{type = "list"}) with info about the requested \code{product}. +Returns the same info as \code{xml_document} (see \code{\link[xml2:xml_new_document]{xml2::xml_new_document()}}) when \code{type = "xml"}. +Returns \code{NULL} when contacting Copernicus fails. +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Collect meta information, such as vocabularies used, +for specific Copernicus marine products +} +\examples{ +\donttest{ +cms_product_metadata("GLOBAL_ANALYSISFORECAST_PHY_001_024") +} +} +\seealso{ +Other product-functions: +\code{\link{cms_cite_product}()}, +\code{\link{cms_product_details}()}, +\code{\link{cms_product_services}()}, +\code{\link{cms_products_list}()}, +\code{\link{copernicus_cite_product}()}, +\code{\link{copernicus_product_details}()}, +\code{\link{copernicus_product_metadata}()}, +\code{\link{copernicus_products_list}()} +} +\author{ +Pepijn de Vries +} +\concept{product-functions} diff --git a/man/cms_product_services.Rd b/man/cms_product_services.Rd new file mode 100644 index 0000000..4a29a31 --- /dev/null +++ b/man/cms_product_services.Rd @@ -0,0 +1,40 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cms_product_services.r +\name{cms_product_services} +\alias{cms_product_services} +\title{Obtain available services for a specific Copernicus marine product} +\usage{ +cms_product_services(product) +} +\arguments{ +\item{product}{An identifier (type \code{character}) of the desired Copernicus marine product. +Can be obtained with \code{\link{cms_products_list}}.} +} +\value{ +Returns a \code{tibble} with a list of available services for a +Copernicus marine \code{product}. +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Obtain an overview of services provided by Copernicus +for a specific marine product. +} +\examples{ +\donttest{ +cms_product_services("GLOBAL_ANALYSISFORECAST_PHY_001_024") +} +} +\seealso{ +Other product-functions: +\code{\link{cms_cite_product}()}, +\code{\link{cms_product_details}()}, +\code{\link{cms_product_metadata}()}, +\code{\link{cms_products_list}()}, +\code{\link{copernicus_cite_product}()}, +\code{\link{copernicus_product_details}()}, +\code{\link{copernicus_product_metadata}()}, +\code{\link{copernicus_products_list}()} +} +\author{ +Pepijn de Vries +} +\concept{product-functions} diff --git a/man/cms_products_list.Rd b/man/cms_products_list.Rd new file mode 100644 index 0000000..b1fa91b --- /dev/null +++ b/man/cms_products_list.Rd @@ -0,0 +1,47 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cms_products_list.r +\name{cms_products_list} +\alias{cms_products_list} +\title{List products available from data.marine.copernicus.eu} +\usage{ +cms_products_list(..., info_type = c("list", "meta")) +} +\arguments{ +\item{...}{Allows you to pass (search) query parameters to apply to the list. +When omitted, the full list of products is returned.} + +\item{info_type}{One of \code{"list"} (default) or \code{"meta"}. \code{"list"} returns the actual list +whereas \code{"meta"} returns meta information for the executed query (e.g. number of hits).} +} +\value{ +Returns a \code{tibble} of products available from \url{https://data.marine.copernicus.eu} or +a named \code{list} when \code{info_type = "meta"}. Returns \code{NULL} in case on-line services are +unavailable. +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Collect a list of products and some brief +descriptions for marine products available from Copernicus +} +\examples{ +\donttest{ +cms_products_list() + +## Query a specific product: +cms_products_list(freeText = "GLOBAL_ANALYSISFORECAST_PHY_001_024") +} +} +\seealso{ +Other product-functions: +\code{\link{cms_cite_product}()}, +\code{\link{cms_product_details}()}, +\code{\link{cms_product_metadata}()}, +\code{\link{cms_product_services}()}, +\code{\link{copernicus_cite_product}()}, +\code{\link{copernicus_product_details}()}, +\code{\link{copernicus_product_metadata}()}, +\code{\link{copernicus_products_list}()} +} +\author{ +Pepijn de Vries +} +\concept{product-functions} diff --git a/man/cms_stac.Rd b/man/cms_stac.Rd new file mode 100644 index 0000000..031bcd2 --- /dev/null +++ b/man/cms_stac.Rd @@ -0,0 +1,77 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cms_download_stac.r, R/cms_list_stac_files.r, +% R/cms_stac_properties.r +\name{cms_download_stac} +\alias{cms_download_stac} +\alias{cms_list_stac_files} +\alias{cms_stac_properties} +\title{List and get STAC files for a Copernicus marine product} +\usage{ +cms_download_stac( + file_tibble, + destination, + show_progress = TRUE, + overwrite = FALSE +) + +cms_list_stac_files(product, layer) + +cms_stac_properties(product, layer) +} +\arguments{ +\item{file_tibble}{A \code{\link[dplyr:reexports]{dplyr::tibble()}} with in each row the files to be downloaded. +Should be created with \code{\link[=cms_list_stac_files]{cms_list_stac_files()}}.} + +\item{destination}{A \code{character} string representing the path location where the downloaded +files should be stored.} + +\item{show_progress}{A \code{logical} value. When \code{TRUE} (default) the download progress will be shown. +This can be useful for large files.} + +\item{overwrite}{A \code{logical} value. When \code{FALSE} (default), files at the \code{destination} won't be +overwritten when the exist. Instead an error will be thrown if this is the case. When set to +\code{TRUE}, existing files will be overwritten.} + +\item{product}{An identifier (type \code{character}) of the desired Copernicus marine product. +Can be obtained with \code{\link{cms_products_list}}.} + +\item{layer}{The name of a desired layer within a product (type \code{character}). Can be obtained with \code{\link{cms_product_details}}.} +} +\value{ +In case of \code{cms_stac_properties} a \code{\link[dplyr:reexports]{dplyr::tibble()}} is returned with some +product properties, It is used as precursor for \code{cms_list_stac_files}. +In case of \code{cms_list_stac_files} a \code{\link[dplyr:reexports]{dplyr::tibble()}} is returned containing +available URLs (for the specified \code{product} and \code{layer}) and some meta information is returned. +In case of \code{cms_download_stac} an invisible \code{logical} value is returned, indicating whether +all requested files are successfully stored at the \code{destination} path. A \code{list} of responses +(of class \code{\link[httr2:response]{httr2::response()}}) for all requested download links is included as attribute +to the result. +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Full marine data sets can be downloaded using the +SpatioTemporal Asset Catalogs (STAC). Use these functions to list download locations and get +the files. +} +\examples{ +\dontrun{ +## List some STAC properties for a specific product and layer +cms_stac_properties( + product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", + layer = "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m" +) + +## Get the available files for a specific product and layer: +file_tibble <- + cms_list_stac_files("GLOBAL_ANALYSISFORECAST_PHY_001_024", + "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m") + +dest <- tempdir() + +## download the first file from the file_tibble to 'dest' +cms_download_stac(file_tibble[1,, drop = FALSE], dest) +} +} +\author{ +Pepijn de Vries +} +\concept{stac-functions download-functions} diff --git a/man/cms_wmts.Rd b/man/cms_wmts.Rd new file mode 100644 index 0000000..b1704ae --- /dev/null +++ b/man/cms_wmts.Rd @@ -0,0 +1,77 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cms_wmts.r +\name{cms_wmts_details} +\alias{cms_wmts_details} +\alias{addCmsWMTSTiles} +\alias{cms_wmts_get_capabilities} +\title{Obtain a WMTS entry for specific Copernicus marine products and add to a leaflet map} +\usage{ +cms_wmts_details(product, layer, variable) + +addCmsWMTSTiles( + map, + product, + layer, + variable, + tilematrixset = "EPSG:3857", + options = leaflet::WMSTileOptions(format = "image/png", transparent = TRUE), + ... +) + +cms_wmts_get_capabilities(product, layer, variable, type = c("list", "xml")) +} +\arguments{ +\item{product}{An identifier (type \code{character}) of the desired Copernicus marine product. +Can be obtained with \code{\link{cms_products_list}}.} + +\item{layer}{The name of a desired layer within a product (type \code{character}). Can be obtained with \code{\link{cms_product_details}}.} + +\item{variable}{The name of a desired variable in a specific layer of a product (type \code{character}). +Can be obtained with \code{\link{copernicus_product_details}}.} + +\item{map}{A map widget object created from \code{\link[leaflet:leaflet]{leaflet::leaflet()}}} + +\item{tilematrixset}{A \code{character} string representing the tilematrixset to be used. In +many cases \code{"EPSG:3857"} (Pseudo-Mercator) or \code{"EPSG:4326"} (World Geodetic System 1984) +are available, but should be checked with \code{cms_wmts_details}.} + +\item{options}{Passed on to \code{\link[leaflet:map-layers]{leaflet::addWMSTiles()}}.} + +\item{...}{Passed on to \code{\link[leaflet:map-layers]{leaflet::addWMSTiles()}}.} + +\item{type}{A \code{character} string indicating whether the capabilities should be returned +as \code{"list"} (default) or \code{"xml"} (\code{\link[xml2:xml_new_document]{xml2::xml_new_document()}}).} +} +\value{ +\code{cms_wmts_details} returns a tibble with detains on the WMTS service. +\code{cms_wmts_getcapabilities} returns either a \code{list} or \code{xml_document} depending on the value +of \code{type}. \code{AddCmsWMTSTiles} returns a \code{leaflet} \code{map} updated with the requested tiles. +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Functions for retrieving Web Map Tile Services infromation for +specific products, layers and variables and add them to a \code{leaflet} map. +} +\examples{ +\donttest{ +cms_wmts_details( + product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", + layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", + variable = "thetao" +) + +cms_wmts_get_capabilities("GLOBAL_ANALYSISFORECAST_PHY_001_024") + +if (interactive()) { + leaflet::leaflet() |> + leaflet::setView(lng = 3, lat = 54, zoom = 4) |> + leaflet::addProviderTiles("Esri.WorldImagery") |> + addCmsWMTSTiles( + product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", + layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", + variable = "thetao") +} +} +} +\author{ +Pepijn de Vries +} diff --git a/man/copernicus_cite_product.Rd b/man/copernicus_cite_product.Rd index 25ee1ea..56bc530 100644 --- a/man/copernicus_cite_product.Rd +++ b/man/copernicus_cite_product.Rd @@ -16,15 +16,20 @@ Remaining elements are other associated references. Note that the remaining refe listed at Copernicus. Note that the citing formatting does not appear to be standardised. } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Get details for properly citing a Copernicus product. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Get details for properly citing a Copernicus product. } \examples{ -\donttest{ +\dontrun{ copernicus_cite_product("SST_MED_PHY_SUBSKIN_L4_NRT_010_036") } } \seealso{ Other product-functions: +\code{\link{cms_cite_product}()}, +\code{\link{cms_product_details}()}, +\code{\link{cms_product_metadata}()}, +\code{\link{cms_product_services}()}, +\code{\link{cms_products_list}()}, \code{\link{copernicus_product_details}()}, \code{\link{copernicus_product_metadata}()}, \code{\link{copernicus_products_list}()} diff --git a/man/copernicus_download_motu.Rd b/man/copernicus_download_motu.Rd index 34bece0..443c810 100644 --- a/man/copernicus_download_motu.Rd +++ b/man/copernicus_download_motu.Rd @@ -20,11 +20,11 @@ copernicus_download_motu( ) } \arguments{ -\item{username}{Your Copernicus marine user name. Can be provided as \code{options(CopernicusMarine_uid = "my_user_name")}, -or as argument here.} +\item{username}{Your Copernicus marine user name. Can be provided as +\code{options(CopernicusMarine_uid = "my_user_name")}, or as argument here.} -\item{password}{Your Copernicus marine password. Can be provided as \code{options(CopernicusMarine_pwd = "my_password")}, -or as argument here.} +\item{password}{Your Copernicus marine password. Can be provided as +\code{options(CopernicusMarine_pwd = "my_password")}, or as argument here.} \item{destination}{File or path where the requested file will be downloaded to.} @@ -58,9 +58,8 @@ Returns a \code{logical} value invisibly indicating whether the requested file w successfully stored at the \code{destination}. } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Subset and download a specific marine product from Copernicus. -This particular function uses the MOTU server for this purpose. You need to register an account -at \url{https://data.marine.copernicus.eu} before you can use this function. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} The MOTU servers will be discontinued by Copernicus Marine Services. Use \code{\link[=cms_download_subset]{cms_download_subset()}} +instead to download subsets. } \examples{ \dontrun{ diff --git a/man/copernicus_ftp.Rd b/man/copernicus_ftp.Rd index c4d4d95..71e707e 100644 --- a/man/copernicus_ftp.Rd +++ b/man/copernicus_ftp.Rd @@ -29,11 +29,11 @@ Can be obtained with \code{\link{copernicus_products_list}}.} \item{layer}{The name of a desired layer within a product (type \code{character}). Can be obtained with \code{\link{copernicus_product_details}}.} -\item{username}{Your Copernicus marine user name. Can be provided as \code{options(CopernicusMarine_uid = "my_user_name")}, -or as argument here.} +\item{username}{Your Copernicus marine user name. Can be provided as +\code{options(CopernicusMarine_uid = "my_user_name")}, or as argument here.} -\item{password}{Your Copernicus marine password. Can be provided as \code{options(CopernicusMarine_pwd = "my_password")}, -or as argument here.} +\item{password}{Your Copernicus marine password. Can be provided as +\code{options(CopernicusMarine_pwd = "my_password")}, or as argument here.} \item{recursive}{A \code{logical} value. When \code{TRUE} all nested files will be listed.} @@ -58,7 +58,7 @@ In case of \code{copernicus_ftp_get} an invisible \code{logical} value is return the requested file is successfully stored at the \code{destination} path. } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Full marine data sets can be downloaded using the +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Full marine data sets can be downloaded using the File Transfer Protocol (FTP). Use these functions to list download locations and get the files. } diff --git a/man/copernicus_login.Rd b/man/copernicus_login.Rd index 9de35cd..8a0eca9 100644 --- a/man/copernicus_login.Rd +++ b/man/copernicus_login.Rd @@ -10,22 +10,20 @@ copernicus_login( ) } \arguments{ -\item{username}{Your Copernicus marine user name. Can be provided as \code{options(CopernicusMarine_uid = "my_user_name")}, -or as argument here.} +\item{username}{Your Copernicus marine user name. Can be provided as +\code{options(CopernicusMarine_uid = "my_user_name")}, or as argument here.} -\item{password}{Your Copernicus marine password. Can be provided as \code{options(CopernicusMarine_pwd = "my_password")}, -or as argument here.} +\item{password}{Your Copernicus marine password. Can be provided as +\code{options(CopernicusMarine_pwd = "my_password")}, or as argument here.} } \value{ Returns a \code{logical} value indicating if the login is successful. The response from the login page is returned as an attribute named \code{response}. } \description{ -Contact Copernicus Marine login page and check if login is successful. -} -\details{ -This function will return a logical value indicating if the login is successful. -It can be used to test your account details. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} This login method is only used by the +download methods that are deprecated by Copernicus Marine Services. Use +\code{\link[=cms_login]{cms_login()}} instead. } \examples{ \dontrun{ diff --git a/man/copernicus_product_details.Rd b/man/copernicus_product_details.Rd index a696070..12df8a6 100644 --- a/man/copernicus_product_details.Rd +++ b/man/copernicus_product_details.Rd @@ -19,11 +19,11 @@ Can be obtained with \code{\link{copernicus_product_details}}.} Returns a named \code{list} with properties of the requested product. } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Obtain details for a specific Copernicus marine product. This can be +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Obtain details for a specific Copernicus marine product. This can be narrowed down to specific layers and/or variables within the product. } \examples{ -\donttest{ +\dontrun{ copernicus_product_details("GLOBAL_ANALYSISFORECAST_PHY_001_024") copernicus_product_details( @@ -35,6 +35,11 @@ copernicus_product_details( } \seealso{ Other product-functions: +\code{\link{cms_cite_product}()}, +\code{\link{cms_product_details}()}, +\code{\link{cms_product_metadata}()}, +\code{\link{cms_product_services}()}, +\code{\link{cms_products_list}()}, \code{\link{copernicus_cite_product}()}, \code{\link{copernicus_product_metadata}()}, \code{\link{copernicus_products_list}()} diff --git a/man/copernicus_product_metadata.Rd b/man/copernicus_product_metadata.Rd index 9d80fe8..83e70eb 100644 --- a/man/copernicus_product_metadata.Rd +++ b/man/copernicus_product_metadata.Rd @@ -15,16 +15,24 @@ Returns a named \code{list} with info about the requested \code{product}. Return when contacting Copernicus fails. } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Collect meta information, such as vocabularies used, +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Deprecated. Use \code{\link[=cms_product_metadata]{cms_product_metadata()}} instead. +} +\details{ +Collect meta information, such as vocabularies used, for specific Copernicus marine products } \examples{ -\donttest{ +\dontrun{ copernicus_product_metadata("GLOBAL_ANALYSISFORECAST_PHY_001_024") } } \seealso{ Other product-functions: +\code{\link{cms_cite_product}()}, +\code{\link{cms_product_details}()}, +\code{\link{cms_product_metadata}()}, +\code{\link{cms_product_services}()}, +\code{\link{cms_products_list}()}, \code{\link{copernicus_cite_product}()}, \code{\link{copernicus_product_details}()}, \code{\link{copernicus_products_list}()} diff --git a/man/copernicus_product_services.Rd b/man/copernicus_product_services.Rd index 64752fe..2c9f1f9 100644 --- a/man/copernicus_product_services.Rd +++ b/man/copernicus_product_services.Rd @@ -15,11 +15,11 @@ Returns a \code{tibble} with a list of available services for a Copernicus marine product } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Obtain an overview of services provided by Copernicus +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Obtain an overview of services provided by Copernicus for a specific marine product. } \examples{ -\donttest{ +\dontrun{ copernicus_product_services("GLOBAL_ANALYSISFORECAST_PHY_001_024") } } diff --git a/man/copernicus_products_list.Rd b/man/copernicus_products_list.Rd index 91ae1c1..83b18b9 100644 --- a/man/copernicus_products_list.Rd +++ b/man/copernicus_products_list.Rd @@ -19,19 +19,24 @@ a named \code{list} when \code{info_type = "meta"}. Returns \code{NULL} in case unavailable. } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} Collect a list of products and some brief +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Collect a list of products and some brief descriptions for marine products available from Copernicus } \examples{ -\donttest{ +\dontrun{ copernicus_products_list() ## Query a specific product: -copernicus_products_list(freeText = "GLOBAL_ANALYSIS_FORECAST_BIO_001_028") +copernicus_products_list(freeText = "GLOBAL_ANALYSISFORECAST_PHY_001_024") } } \seealso{ Other product-functions: +\code{\link{cms_cite_product}()}, +\code{\link{cms_product_details}()}, +\code{\link{cms_product_metadata}()}, +\code{\link{cms_product_services}()}, +\code{\link{cms_products_list}()}, \code{\link{copernicus_cite_product}()}, \code{\link{copernicus_product_details}()}, \code{\link{copernicus_product_metadata}()} diff --git a/man/copernicus_wms2geotiff.Rd b/man/copernicus_wms2geotiff.Rd index 7f3e9b1..7a69b68 100644 --- a/man/copernicus_wms2geotiff.Rd +++ b/man/copernicus_wms2geotiff.Rd @@ -36,8 +36,9 @@ Should be in the order of: xmin, ymin, xmax, ymax.} Stores the file as \code{destination} and returns invisible \code{NULL} } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} Extract and store imagery from a Copernicus WMS -as a geo-referenced TIFF. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} This function interacts with deprecated Copernicus Marine +Services. It will become \code{\link[=.Defunct]{.Defunct()}} in future versions. Extract and store imagery from a +Copernicus WMS as a geo-referenced TIFF. } \details{ A Web Map Service (WMS) cannot be plotted directly (base, ggplot2 and/or lattice). @@ -49,7 +50,7 @@ WMS map as a geo-referenced TIFF file. WMS functions don't work on systems that don't support GDAL utils } \examples{ -\donttest{ +\dontrun{ destination <- tempfile("wms", fileext = ".tiff") copernicus_wms2geotiff( product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", diff --git a/man/copernicus_wms_details.Rd b/man/copernicus_wms_details.Rd index d6eeb08..43d058a 100644 --- a/man/copernicus_wms_details.Rd +++ b/man/copernicus_wms_details.Rd @@ -19,14 +19,14 @@ Can be obtained with \code{\link{copernicus_product_details}}.} Returns a \code{tibble} with WMS URLs and descriptors for the specified product. } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} Web Map Services are not available for all +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Web Map Services are not available for all products and layers. Use this function to obtain URLs of WMS services if any. } \note{ WMS functions don't work on systems that don't support GDAL utils } \examples{ -\donttest{ +\dontrun{ copernicus_wms_details( product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", diff --git a/man/figures/README-download-subset-1.png b/man/figures/README-download-subset-1.png new file mode 100644 index 0000000..e25bdb6 Binary files /dev/null and b/man/figures/README-download-subset-1.png differ diff --git a/man/figures/README-leaflet-1.png b/man/figures/README-leaflet-1.png index 272ff06..5cc5ed4 100644 Binary files a/man/figures/README-leaflet-1.png and b/man/figures/README-leaflet-1.png differ diff --git a/man/figures/README-motu-subset-1.png b/man/figures/README-motu-subset-1.png deleted file mode 100644 index b1fa7d5..0000000 Binary files a/man/figures/README-motu-subset-1.png and /dev/null differ diff --git a/tests/testthat.R b/tests/testthat.R index 985b2a3..af095ef 100644 --- a/tests/testthat.R +++ b/tests/testthat.R @@ -1,4 +1,5 @@ library(testthat) +library(ncmeta) library(CopernicusMarine) test_check("CopernicusMarine") diff --git a/tests/testthat/helper.r b/tests/testthat/helper.r index 060ef14..1581fdc 100644 --- a/tests/testthat/helper.r +++ b/tests/testthat/helper.r @@ -7,7 +7,7 @@ has_account_details <- function() { has_gdal_utils <- function() { result <- tryCatch({ cp <- - copernicus_wms_details( + cms_wmts_details( product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", variable = "thetao" diff --git a/tests/testthat/test_dev.r b/tests/testthat/test_dev.r index 0aa9da4..488a146 100644 --- a/tests/testthat/test_dev.r +++ b/tests/testthat/test_dev.r @@ -1,7 +1,8 @@ test_that("Source code should not have things on TODO list", { expect_false({ files_to_check <- - list.files(pattern = ".r$|NEWS|DESCRIPTION|README", recursive = T, full.names = T) + list.files(system.file(package = "CopernicusMarine"), + pattern = "[.]r$|NEWS|DESCRIPTION|README", recursive = TRUE, full.names = TRUE) files_to_check <- files_to_check[!endsWith(files_to_check, "test_dev.r") & !endsWith(files_to_check, ".png")] any( diff --git a/tests/testthat/test_ftp.r b/tests/testthat/test_ftp.r index 14a6c4b..10cd167 100644 --- a/tests/testthat/test_ftp.r +++ b/tests/testthat/test_ftp.r @@ -3,12 +3,16 @@ test_that("Copernicus files can be downloaded via FTP", { skip_if_offline("data.marine.copernicus.eu") has_account_details() expect_error({ - cop_ftp_files <- copernicus_ftp_list("GLOBAL_OMI_WMHE_heattrp") + suppressWarnings({ + cop_ftp_files <- copernicus_ftp_list("GLOBAL_OMI_WMHE_heattrp") + }) if (!is.data.frame(cop_ftp_files) || nrow(cop_ftp_files) == 0) stop("Couldn't list files") destination <- tempdir() - copernicus_ftp_get(cop_ftp_files$url[[1]], destination, overwrite = TRUE, show_progress = F) + suppressWarnings({ + copernicus_ftp_get(cop_ftp_files$url[[1]], destination, overwrite = TRUE, show_progress = F) + }) suppressWarnings( suppressMessages( obj <- stars::read_ncdf(file.path(destination, basename(cop_ftp_files$url[[1]]))) diff --git a/tests/testthat/test_motu.r b/tests/testthat/test_motu.r index 7021e2e..0e0b30f 100644 --- a/tests/testthat/test_motu.r +++ b/tests/testthat/test_motu.r @@ -3,7 +3,9 @@ test_that("Products can be listed", { has_account_details() skip_if_offline("data.marine.copernicus.eu") expect_true({ - pds <- copernicus_products_list() + suppressWarnings({ + pds <- copernicus_products_list() + }) is.data.frame(pds) && nrow(pds) > 0 }) }) @@ -14,7 +16,9 @@ test_that("Product details make sence", { skip_if_offline("data.marine.copernicus.eu") id <- "GLOBAL_ANALYSISFORECAST_PHY_001_024" expect_true({ - pd <- copernicus_product_details(id) + suppressWarnings({ + pd <- copernicus_product_details(id) + }) is.list(pd) && length(pd) > 0 && pd$id == id }) }) @@ -24,7 +28,9 @@ test_that("Product details can't have variable without layer", { has_account_details() skip_if_offline("data.marine.copernicus.eu") expect_error({ - copernicus_product_details("GLOBAL_ANALYSISFORECAST_PHY_001_024", variable = "thetao") + suppressWarnings({ + copernicus_product_details("GLOBAL_ANALYSISFORECAST_PHY_001_024", variable = "thetao") + }) }) }) @@ -34,7 +40,9 @@ test_that("Product meta info make sence", { skip_if_offline("data.marine.copernicus.eu") id <- "GLOBAL_ANALYSISFORECAST_PHY_001_024" expect_true({ - pd <- copernicus_product_metadata(id) + suppressWarnings({ + pd <- copernicus_product_metadata(id) + }) is.list(pd) && length(pd) > 0 }) }) @@ -46,17 +54,19 @@ test_that("Motu download produces valid ncdf file", { expect_true({ destination <- tempfile("copernicus", fileext = ".nc") suppressMessages({ - copernicus_download_motu( - destination = destination, - product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", - layer = "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m", - variable = "sea_water_velocity", - output = "netcdf", - region = c(-1, 50, 10, 55), - timerange = c("2021-01-01", "2021-01-02"), - verticalrange = c(0, 2), - sub_variables = c("uo", "vo") - ) + suppressWarnings({ + copernicus_download_motu( + destination = destination, + product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", + layer = "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m", + variable = "sea_water_velocity", + output = "netcdf", + region = c(-1, 50, 10, 55), + timerange = c("2021-01-01", "2021-01-02"), + verticalrange = c(0, 2), + sub_variables = c("uo", "vo") + ) + }) capture.output(test_file <- stars::read_stars(destination)) "stars" %in% class(test_file) }) diff --git a/tests/testthat/test_stac.r b/tests/testthat/test_stac.r new file mode 100644 index 0000000..51397f5 --- /dev/null +++ b/tests/testthat/test_stac.r @@ -0,0 +1,17 @@ +test_that("Copernicus files can be downloaded via STAC", { + skip_on_cran() + skip_if_offline("data.marine.copernicus.eu") + expect_no_error({ + stac_files <- cms_list_stac_files("GLOBAL_OMI_WMHE_heattrp") + if (!is.data.frame(stac_files) || nrow(stac_files) == 0) + stop("Couldn't list files") + destination <- tempdir() + + suppressWarnings({ + suppressMessages({ + cms_download_stac(stac_files[1,], destination, overwrite = TRUE, show_progress = FALSE) + obj <- stars::read_ncdf(file.path(destination, basename(stac_files$current_path[[1]]))) + }) + }) + }) +}) diff --git a/tests/testthat/test_subset.r b/tests/testthat/test_subset.r new file mode 100644 index 0000000..90f053b --- /dev/null +++ b/tests/testthat/test_subset.r @@ -0,0 +1,62 @@ +test_that("Products can be listed", { + skip_on_cran() + has_account_details() + skip_if_offline("data.marine.copernicus.eu") + expect_true({ + pds <- cms_products_list() + is.data.frame(pds) && nrow(pds) > 0 + }) +}) + +test_that("Product details make sence", { + skip_on_cran() + has_account_details() + skip_if_offline("data.marine.copernicus.eu") + id <- "GLOBAL_ANALYSISFORECAST_PHY_001_024" + expect_true({ + pd <- cms_product_details(id) + is.list(pd) && length(pd) > 0 && pd$id == id + }) +}) + +test_that("Product details can't have variable without layer", { + skip_on_cran() + has_account_details() + skip_if_offline("data.marine.copernicus.eu") + expect_error({ + cms_product_details("GLOBAL_ANALYSISFORECAST_PHY_001_024", variable = "thetao") + }) +}) + +test_that("Product meta info make sence", { + skip_on_cran() + has_account_details() + skip_if_offline("data.marine.copernicus.eu") + id <- "GLOBAL_ANALYSISFORECAST_PHY_001_024" + expect_true({ + pd <- cms_product_metadata(id) + is.list(pd) && length(pd) > 0 + }) +}) + +test_that("Subset download produces valid ncdf file", { + skip_on_cran() + has_account_details() + skip_if_offline("data.marine.copernicus.eu") + expect_true({ + destination <- tempfile("copernicus", fileext = ".nc") + suppressMessages({ + cms_download_subset( + destination = destination, + product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", + layer = "cmems_mod_glo_phy-cur_anfc_0.083deg_P1D-m", + variable = "sea_water_velocity", + region = c(-1, 50, 10, 55), + timerange = c("2021-01-01", "2021-01-02"), + verticalrange = c(0, 2) + ) + capture.output(test_file <- stars::read_stars(destination)) + "stars" %in% class(test_file) + }) + }) +}) diff --git a/tests/testthat/test_wms.r b/tests/testthat/test_wms.r index 2c3f48e..b743055 100644 --- a/tests/testthat/test_wms.r +++ b/tests/testthat/test_wms.r @@ -3,12 +3,14 @@ test_that("Copernicus WMS tile can be added to a map", { skip_if_offline("data.marine.copernicus.eu") has_gdal_utils() testthat::expect_error({ - leaflet::leaflet() |> - addCopernicusWMSTiles( - product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", - layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", - variable = "thetao" - ) + suppressWarnings({ + leaflet::leaflet() |> + addCopernicusWMSTiles( + product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", + layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", + variable = "thetao" + ) + }) }, NA) }) @@ -18,15 +20,17 @@ test_that("Copernicus WMS tile can be stored as valid geoTIFF", { has_gdal_utils() expect_error({ destination <- tempfile("wms", fileext = ".tiff") - copernicus_wms2geotiff( - product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", - layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", - variable = "thetao", - region = c(-1, 50, 7, 60), - destination = destination, - width = 1920, - height = 1080 - ) + suppressWarnings({ + copernicus_wms2geotiff( + product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", + layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", + variable = "thetao", + region = c(-1, 50, 7, 60), + destination = destination, + width = 1920, + height = 1080 + ) + }) obj <- stars::read_stars(destination) }, NA) }) \ No newline at end of file diff --git a/tests/testthat/test_wmts.r b/tests/testthat/test_wmts.r new file mode 100644 index 0000000..06697c0 --- /dev/null +++ b/tests/testthat/test_wmts.r @@ -0,0 +1,13 @@ +test_that("Copernicus WMTS tile can be added to a map", { + skip_on_cran() + skip_if_offline("data.marine.copernicus.eu") + has_gdal_utils() + testthat::expect_no_error({ + leaflet::leaflet() |> + addCmsWMTSTiles( + product = "GLOBAL_ANALYSISFORECAST_PHY_001_024", + layer = "cmems_mod_glo_phy-thetao_anfc_0.083deg_P1D-m", + variable = "thetao" + ) + }) +}) \ No newline at end of file