diff --git a/R/copernicus-cds.R b/R/copernicus-cds.R index 3de4052..c568ccf 100644 --- a/R/copernicus-cds.R +++ b/R/copernicus-cds.R @@ -96,19 +96,16 @@ copernicus_cds_parallel <- function( ) { ncores <- parallel::detectCores() - 1 - cl <- parallel::makeCluster(ncores) on.exit(parallel::stopCluster(cl)) - msg <- sprintf( - "Importing %d variable(s) (%s) from Copernicus CDS parallel (ncores = %d)", - length(variables), - kwb.utils::stringList(variables), - ncores - ) - kwb.utils::catAndRun( - messageText = msg, + messageText = sprintf( + "Importing %d variable(s) (%s) from Copernicus CDS parallel (ncores = %d)", + length(variables), + kwb.utils::stringList(variables), + ncores + ), expr = parallel::parLapply(cl, variables, function(variable) { try(copernicus_cds( variable, diff --git a/R/create_periods_in_year.R b/R/create_periods_in_year.R index c969fe4..9afd6a2 100644 --- a/R/create_periods_in_year.R +++ b/R/create_periods_in_year.R @@ -11,25 +11,26 @@ create_periods_in_year <- function(year, n_periods = 4L) { stopifnot(length(n_periods) == 1L, n_periods > 0L) + stopifnot(is.numeric(year), length(year) == 1L) - as_date <- function(x) as.Date(sprintf("%04d-%s", as.integer(year), x)) + year <- as.integer(year) + as_date <- function(x) as.Date(sprintf("%04d-%s", year, x)) n_dates <- n_periods + 1L - current_date <- Sys.Date() - end_date <- if(as.integer(year) != as.integer(format(Sys.Date(), format = "%Y"))) { - "12-31" - } else { - format(current_date, format = "%m-%d") - } + today <- Sys.Date() - dates <- seq.Date(as_date("01-01"), as_date(end_date), length.out = n_dates) + dates <- seq.Date( + from = as_date("01-01"), + to = ifelse(is_this_year(year), today, as_date("12-31")), + length.out = n_dates + ) starts <- dates[-n_dates] + ends <- kwb.utils::startsToEnds(starts, lastStop = dates[n_dates]) data.frame( start = as.character(starts), - end = as.character(kwb.utils::startsToEnds(starts, lastStop = dates[n_dates])) + end = as.character(ends) ) - } diff --git a/R/create_rgee_environment.R b/R/create_rgee_environment.R index 1c6a7aa..e233826 100644 --- a/R/create_rgee_environment.R +++ b/R/create_rgee_environment.R @@ -6,18 +6,20 @@ #' @export #' @importFrom reticulate condaenv_exists #' @importFrom kwb.python conda_py_install -create_ad4gd_env <- function(force = FALSE, debug = FALSE) { +create_ad4gd_env <- function(force = FALSE, debug = FALSE) +{ + if (!reticulate::condaenv_exists("ad4gd") || force) { - if(!reticulate::condaenv_exists("ad4gd") | force) { - kwb.python::conda_py_install(env_name = "ad4gd", - pkgs = list(conda = c("python=3.12.2", - "numpy"), - py = "earthengine-api==0.1.370")) - } else { - if(debug) { - message(paste0("Conda environment 'ad4gd' already exists. Use ", - "'force' = TRUE, to reinstall if required")) - } + kwb.python::conda_py_install(env_name = "ad4gd", pkgs = list( + conda = c("python=3.12.2", "numpy"), + py = "earthengine-api==0.1.370" + )) + + } else if (debug) { + + message( + "Conda environment 'ad4gd' already exists. ", + "Use 'force' = TRUE to reinstall, if required." + ) } } - diff --git a/R/flatten_results.R b/R/flatten_results.R index 7c11cd1..951910f 100644 --- a/R/flatten_results.R +++ b/R/flatten_results.R @@ -10,25 +10,23 @@ #' @importFrom dplyr bind_rows #' @importFrom tidyr unnest #' @importFrom sf st_polygon st_sfc st_set_crs -flatten_results <- function(sat_data_list, - cols_unnest = "satellite_data_metadata") { - - if(sum(c("satellite_data", "satellite_metadata") %in% cols_unnest) == 2) { - names_sep <- "." - } else { - names_sep <- NULL - } +flatten_results <- function( + sat_data_list, + cols_unnest = "satellite_data_metadata" +) +{ + cols_satellite <- c("satellite_data", "satellite_metadata") sat_data_df_nested <- sat_data_list %>% dplyr::bind_rows() - - lapply(seq_len(nrow(sat_data_df_nested)), - function(i) { - sat_data_df_nested[i, ] %>% - tidyr::unnest(tidyselect::all_of(cols_unnest), - names_sep = names_sep) - }) %>% + seq_len(nrow(sat_data_df_nested)) %>% + lapply(function(i) { + tidyr::unnest( + sat_data_df_nested[i, ], + tidyselect::all_of(cols_unnest), + names_sep = if (all(cols_satellite %in% cols_unnest)) "." # else NULL + ) + }) %>% dplyr::bind_rows() - } diff --git a/R/google-earth-engine_copernicus_get-data_parallel.R b/R/gee_get_data_for_years_parallel.R similarity index 55% rename from R/google-earth-engine_copernicus_get-data_parallel.R rename to R/gee_get_data_for_years_parallel.R index 69a159e..c1365a2 100644 --- a/R/google-earth-engine_copernicus_get-data_parallel.R +++ b/R/gee_get_data_for_years_parallel.R @@ -1,38 +1,44 @@ #' Google Earth Engine: get data for years in parallel #' -#' @param years years vector of years for which satellite data should be downloaded +#' @param years years vector of years for which satellite data should be +#' downloaded #' @param lakes lakes sf data frame witch shapes of lakes -#' @param image_collection image collection (default: "COPERNICUS/S2_SR_HARMONIZED") +#' @param image_collection image collection (default: +#' "COPERNICUS/S2_SR_HARMONIZED") #' @param bands bands (defualt: NULL), for selection provide in the following -#' format: as.list(c("QA60", paste0("B", 1:6))) -#' @param point_on_surface use sf::st_point_on_surface or polygon? (default: FALSE) +#' format: as.list(c("QA60", paste0("B", 1:6))) +#' @param point_on_surface use sf::st_point_on_surface or polygon? (default: +#' FALSE) #' @param spatial_fun spatial aggregation function (default: "mean") #' @param scale scale parameter (default: 10), for details, see -#' \url{https://developers.google.com/earth-engine/guides/scale} -#' @param via via (default: "getInfo"), other options use google cloud (google drive -#' or google cloud storage) -#' @param col_lakename col_lakename ("GEWNAME", used by Berlin authority for surface -#' water bodies) use "SEE_NAME" for Brandenburg lakes -#' @param set_lakenames_as_list_indices should lake names of "col_lakename" be used -#' for naming result list? (default: TRUE) +#' \url{https://developers.google.com/earth-engine/guides/scale} +#' @param via via (default: "getInfo"), other options use google cloud (google +#' drive or google cloud storage) +#' @param col_lakename col_lakename ("GEWNAME", used by Berlin authority for +#' surface water bodies) use "SEE_NAME" for Brandenburg lakes +#' @param set_lakenames_as_list_indices should lake names of "col_lakename" be +#' used for naming result list? (default: TRUE) #' @param debug show debug messages (default: TRUE) #' @param debug_dir directory where to save (default: tempdir()) #' @param ee_print show debug messages for "ee" (default: FALSE) #' @param export_rds save sat data into rds object for each lake (default: TRUE) -#' @param export_dir directory where to save data for each lake (default: tempdir()) +#' @param export_dir directory where to save data for each lake (default: +#' tempdir()) #' @param ncores number of cores for parallel processinfg (default: -#' parallel::detectCores() - 1) -#' @param n_year_splits number of year splits per request. Required in case request -#' uses too much images > 400-500 per year (default: NULL, determined automatically within -#' function. In case it should be overwritten by the user provide a meaningful integer number) -#' @param return_list should results be provided as R list? (default: FALSE). If FALSE, -#' the rds_path to the exported data is provided in case export_rds is set to TRUE -#' @return list with data and metadata, each of them tibbles (if return_list = TRUE), -#' If FALSE, the rds_path to the exported data is provided in case export_rds is -#' set to TRUE. In case an error occurs NULL is returned +#' parallel::detectCores() - 1) +#' @param n_year_splits number of year splits per request. Required in case +#' request uses too much images > 400-500 per year (default: NULL, determined +#' automatically within function. In case it should be overwritten by the user +#' provide a meaningful integer number) +#' @param return_list should results be provided as R list? (default: FALSE). If +#' FALSE, the rds_path to the exported data is provided in case export_rds is +#' set to TRUE +#' @return list with data and metadata, each of them tibbles (if return_list = +#' TRUE), If FALSE, the rds_path to the exported data is provided in case +#' export_rds is set to TRUE. In case an error occurs NULL is returned #' @export -#' @importFrom parallel detectCores makeCluster stopCluster parLapply clusterEvalQ -#' clusterExport +#' @importFrom parallel detectCores makeCluster stopCluster parLapply +#' clusterEvalQ clusterExport #' @importFrom reticulate use_condaenv #' @importFrom rgee ee_Initialize #' @importFrom fs path_join @@ -58,16 +64,16 @@ gee_get_data_for_years_parallel <- function( export_dir = tempdir(), ncores = parallel::detectCores() - 1, n_year_splits = NULL, - return_list = FALSE) { - - + return_list = FALSE +) +{ geos <- tolower(sf::st_geometry_type(lakes)) - shape_type <- if(all(geos == "point")) { + shape_type <- if (all(geos == "point")) { "point" - } else if (all(geos == "polygon") & point_on_surface == FALSE) { + } else if (all(geos == "polygon") && isFALSE(point_on_surface)) { "polygon" - } else if (all(geos == "polygon") & point_on_surface == TRUE) { + } else if (all(geos == "polygon") && isTRUE(point_on_surface)) { "point-on-surface" } else { "unclear" @@ -78,26 +84,30 @@ gee_get_data_for_years_parallel <- function( stopifnot(spatial_fun %in% names(rgee::ee$Reducer)) - stopifnot(ncores > 1) + stopifnot(ncores > 1L) stopifnot(ncores <= parallel::detectCores()) - if (ncores > nrow(lakes)) { - ncores <- nrow(lakes) + n_lakes <- nrow(lakes) + + if (ncores > n_lakes) { + ncores <- n_lakes } # Prepare parallel processing - cl <- parallel::makeCluster(ncores, - outfile = fs::path_join(c(debug_dir, - "debug_parallel.txt"))) + cl <- parallel::makeCluster( + ncores, + outfile = fs::path_join(c(debug_dir, "debug_parallel.txt")) + ) + on.exit(parallel::stopCluster(cl)) my_fun <- function(idx) { - if(debug) { + if (debug) { lakename <- lakes[[col_lakename]][idx] - tfile <- fs::path_join(c(debug_dir, - sprintf("debug_parallel_%03d_%s.txt", - idx, - lakename))) + tfile <- fs::path_join(c( + debug_dir, + sprintf("debug_parallel_%03d_%s.txt", idx, lakename)) + ) sink(tfile, append = FALSE) } @@ -113,43 +123,44 @@ gee_get_data_for_years_parallel <- function( col_lakename = col_lakename, debug = debug, ee_print = ee_print, - n_year_splits = n_year_splits) - ) + n_year_splits = n_year_splits + )) - if(any(class(res) == "try-error")) { - not_failed <- FALSE - } else { - not_failed <- TRUE - } + success <- !inherits(res, "try-error") - - if(debug) sink() + if (debug) { + sink() + } return_obj <- NULL - if(export_rds && not_failed) { - rds_name <- sprintf("%s_%s_%s_scale-%dm_%4d-%4d.rds", - lakes[[col_lakename]][idx], - shape_type, - spatial_fun, - scale, - min(years), - max(years)) + if (export_rds && success) { + + rds_name <- sprintf( + "%s_%s_%s_scale-%dm_%4d-%4d.rds", + lakes[[col_lakename]][idx], + shape_type, + spatial_fun, + scale, + min(years), + max(years) + ) rds_path <- fs::path_join(c(export_dir, rds_name)) - kwb.utils::catAndRun(sprintf("Exporting dataset to '%s'", rds_path), - expr = { saveRDS(res, file = rds_path) } + kwb.utils::catAndRun( + sprintf("Exporting dataset to '%s'", rds_path), + expr = saveRDS(res, file = rds_path) ) return_obj <- rds_path } - if(return_list | !(export_rds && not_failed)) { - return_obj <- res - } + if (return_list || !(export_rds && success)) { + return_obj <- res + } - return(return_obj) + return_obj } # Initialize necessary packages and environments on each cluster @@ -164,31 +175,35 @@ gee_get_data_for_years_parallel <- function( # Prepare parallel processing doParallel::registerDoParallel(cl) + library(foreach) # Run the parallel processing - sat_data <- kwb.utils::catAndRun( + kwb.utils::catAndRun( sprintf( "Downloading satellite data for %d lakes in parallel on %d cores", - nrow(lakes), + n_lakes, ncores ), + dbg = debug, expr = { - sat_data <- foreach::foreach(idx = seq_len(nrow(lakes)), - .combine = "c") %dopar% { - my_fun(idx) - } - # Stop parallel processing - doParallel::stopImplicitCluster() + sat_data <- foreach::foreach( + idx = seq_len(n_lakes), + .combine = "c" + ) %dopar% { + my_fun(idx) + } - if(set_lakenames_as_list_indices) { - sat_data <- setNames(sat_data, lakes[[col_lakename]]) - } + # Stop parallel processing + doParallel::stopImplicitCluster() - sat_data - }, - dbg = debug + if (set_lakenames_as_list_indices) { + names(sat_data) <- lakes[[col_lakename]] + } + + sat_data + } ) } diff --git a/R/get_metadata_era5.R b/R/get_metadata_era5.R index 45beecb..e34eff4 100644 --- a/R/get_metadata_era5.R +++ b/R/get_metadata_era5.R @@ -12,28 +12,27 @@ #' @importFrom rlang .data #' @seealso Code taken from https://gis.stackexchange.com/a/360652 #' -get_metadata_era5 <- function(grib_file) { - +get_metadata_era5 <- function(grib_file) +{ ### Code copied from: ### https://gis.stackexchange.com/questions/360547/era5-grib-file-how-to-know-what-each-band-means info <- gdalUtilities::gdalinfo(grib_file) - select_pattern <- paste0(c("Band", - "GRIB_COMMENT", - "GRIB_ELEMENT", - "GRIB_FORECAST_SECONDS", - "GRIB_REF_TIME", - "GRIB_VALID_TIME", - "GRIB_SHORT_NAME", - "GRIB_UNIT"), - collapse = "|") + select_pattern <- paste0(collapse = "|", c( + "Band", + "GRIB_COMMENT", + "GRIB_ELEMENT", + "GRIB_FORECAST_SECONDS", + "GRIB_REF_TIME", + "GRIB_VALID_TIME", + "GRIB_SHORT_NAME", + "GRIB_UNIT" + )) #Filter and retrieve the information of interest (as seen here). grib1 <- as.data.frame(info) - grib1 <- as.data.frame( - grib1[grep(pattern = select_pattern, x = info), ] - ) + grib1 <- as.data.frame(grib1[grep(pattern = select_pattern, x = info), ]) colnames(grib1) <- c('raw_') @@ -62,8 +61,8 @@ get_metadata_era5 <- function(grib_file) { is_grib_v ~ gsub(".*= (.+) sec.*", "\\1", raw_), is_grib_s ~ sub(".*=", "", raw_), is_grib_u ~ sub(".*=", "", raw_) %>% - stringr::str_remove("\\[") %>% - stringr::str_remove("\\]") + stringr::str_remove("\\[") %>% + stringr::str_remove("\\]") ), column = dplyr::case_when( is_band ~ 'band', @@ -92,11 +91,22 @@ get_metadata_era5 <- function(grib_file) { values_from = "content" ) %>% dplyr::mutate( - time_ref = as.POSIXct(as.numeric(.data$time_ref), origin = "1970-01-01", tz = "UTC"), - time_valid = as.POSIXct(as.numeric(.data$time_valid), origin = "1970-01-01", tz = "UTC"), + time_ref = as.POSIXct( + as.numeric(.data$time_ref), + origin = "1970-01-01", + tz = "UTC" + ), + time_valid = as.POSIXct( + as.numeric(.data$time_valid), + origin = "1970-01-01", + tz = "UTC" + ), time_forecast = .data$time_ref + as.numeric(.data$forecast_seconds), - variable = stringr::str_remove(.data$variable_unit, - pattern = "\\s+\\[.*\\]$")) + variable = stringr::str_remove( + .data$variable_unit, + pattern = "\\s+\\[.*\\]$" + ) + ) grib1 <- grib1[, -1] diff --git a/R/get_metadata_gee.R b/R/get_metadata_gee.R index 87df953..7eb55c1 100644 --- a/R/get_metadata_gee.R +++ b/R/get_metadata_gee.R @@ -1,51 +1,47 @@ #' Helper function: convert to list #' -#' @param coords column with satellite metadata coordinates (system:footprint`$coordinates) -#' +#' @param coords column with satellite metadata coordinates +#' (system:footprint`$coordinates) #' @return list of coordinates #' @keywords internal #' -convert_to_list <- function(coords) { - - tmp_mat <- lapply(seq_along(coords), - FUN = function(idx) { - - t(as.matrix(coords[[idx]])) - }) - - list(do.call(rbind, tmp_mat)) +convert_to_list <- function(coords) +{ + lapply(coords, function(x) t(as.matrix(x))) %>% + do.call(what = rbind) %>% + list() } - #' Google Earth Engine: get metadata for collection #' #' @param collection collection -#' #' @return tibble with metadata. In addition also the complex column -#' "geometry_meta_org" is simplified and stored in the new column "geometry_meta_cleaned" +#' "geometry_meta_org" is simplified and stored in the new column +#' "geometry_meta_cleaned" #' @export #' @importFrom tibble as_tibble tibble #' @importFrom dplyr bind_cols bind_rows +#' @importFrom kwb.utils removeColumns #' @importFrom tidyr nest -#' @importFrom tidyselect matches all_of -gee_get_metadata <- function(collection) { - - nImages <- collection$size()$getInfo() +#' @importFrom tidyselect matches +gee_get_metadata <- function(collection) +{ + metadata_list <- collection$size()$getInfo() %>% + collection$toList() %>% + collection$fromImages() - collectionList <- collection$toList(nImages) - - metadata_list <- collection$fromImages(collectionList) metadata_list <- metadata_list$getInfo() - - metadata_features_df <- lapply(seq_along(metadata_list$features), function(idx) { - tibble::as_tibble(metadata_list$features[[idx]]$properties) - }) %>% dplyr::bind_rows() %>% + metadata_features_df <- metadata_list$features %>% + lapply(function(x) tibble::as_tibble(x$properties)) %>% + dplyr::bind_rows() %>% tidyr::nest(geometry_meta_org = tidyselect::matches("system:footprint")) + geometries <- metadata_features_df$geometry_meta_org - coords <- lapply(seq_len(nrow(metadata_features_df)), function(idx) { - convert_to_list(metadata_features_df$geometry_meta_org[[idx]]$`system:footprint`$coordinates) %>% + coords <- lapply(seq_len(nrow(metadata_features_df)), function(i) { + geometries[[i]]$`system:footprint`$coordinates %>% + convert_to_list() %>% sf::st_polygon() %>% sf::st_sfc() %>% sf::st_set_crs(value = 4326) @@ -53,26 +49,24 @@ gee_get_metadata <- function(collection) { metadata_features_df$geometry_meta_cleaned <- coords - metadata_ids <- tibble::tibble( - id = sapply(seq_along(metadata_list$features), function(idx) metadata_list$features[[idx]]$id) - ) - - dplyr::bind_cols(metadata_ids, metadata_features_df) %>% - tidyr::separate(col = "id", - into = c("provider_name", "provider_collection", "id_short"), - sep = "/", - remove = FALSE) %>% + tibble::tibble( + id = sapply(metadata_list$features, function(x) x$id) + ) %>% + dplyr::bind_cols(metadata_features_df) %>% + tidyr::separate( + col = "id", + into = c("provider_name", "provider_collection", "id_short"), + sep = "/", + remove = FALSE + ) %>% tidyr::separate( col = "id_short", - into = c("datetime_start", - "datetime_end", - "tile_id"), + into = c("datetime_start", "datetime_end", "tile_id"), sep = "_" ) %>% dplyr::mutate( datetime_start = lubridate::ymd_hms(datetime_start), datetime_end = lubridate::ymd_hms(datetime_end) ) %>% - dplyr::select(- tidyselect::all_of(c("provider_name","provider_collection"))) - + kwb.utils::removeColumns(c("provider_name", "provider_collection")) } diff --git a/R/google-earth-engine_copernicus_get-data.R b/R/google-earth-engine_copernicus_get-data.R index ed5e3d6..cc7fe71 100644 --- a/R/google-earth-engine_copernicus_get-data.R +++ b/R/google-earth-engine_copernicus_get-data.R @@ -1,23 +1,27 @@ #' Google Earth Engine: get data for years #' -#' @param years years vector of years for which satellite data should be downloaded +#' @param years years vector of years for which satellite data should be +#' downloaded #' @param lakes lakes sf data frame witch shapes of lakes -#' @param image_collection image collection (default: "COPERNICUS/S2_SR_HARMONIZED") +#' @param image_collection image collection (default: +#' "COPERNICUS/S2_SR_HARMONIZED") #' @param bands bands (defualt: NULL), for selection provide in the following -#' format: as.list(c("QA60", paste0("B", 1:6))) -#' @param point_on_surface use sf::st_point_on_surface or polygon? (default: FALSE) +#' format: as.list(c("QA60", paste0("B", 1:6))) +#' @param point_on_surface use sf::st_point_on_surface or polygon? (default: +#' FALSE) #' @param spatial_fun spatial aggregation function (default: "mean") #' @param scale scale parameter (default: 10), for details, see -#' \url{https://developers.google.com/earth-engine/guides/scale} -#' @param via via (default: "getInfo"), other options use google cloud (google drive -#' or google cloud storage) -#' @param col_lakename col_lakename ("GEWNAME", used by Berlin authority for surface -#' water bodies) +#' \url{https://developers.google.com/earth-engine/guides/scale} +#' @param via via (default: "getInfo"), other options use google cloud (google +#' drive or google cloud storage) +#' @param col_lakename col_lakename ("GEWNAME", used by Berlin authority for +#' surface water bodies) #' @param debug print debug messages? (default: TRUE) #' @param ee_print show debug messages for "ee" (default: FALSE) -#' @param n_year_splits number of year splits per request. Required in case request -#' uses too much images > 400-500 per year (default: NULL, determined automatically within -#' function. In case it should be overwritten by the user provide a meaningful integer number) +#' @param n_year_splits number of year splits per request. Required in case +#' request uses too much images > 400-500 per year (default: NULL, determined +#' automatically within function. In case it should be overwritten by the user +#' provide a meaningful integer number) #' @return list with data and metadata, each of them tibbles #' @export #' @importFrom rgee ee sf_as_ee ee_print @@ -26,24 +30,26 @@ #' @importFrom kwb.utils catAndRun #' @importFrom stats setNames #' @importFrom lubridate yday -gee_get_data_for_years <- function(years = 2018, - lakes, - image_collection = "COPERNICUS/S2_SR_HARMONIZED", - bands = NULL, #as.list(c("QA60", paste0("B", 1:6))), - point_on_surface = FALSE, - spatial_fun = "mean", - scale = 10, - via = "getInfo", - col_lakename = "GEWNAME", - debug = TRUE, - ee_print = FALSE, - n_year_splits = NULL) { - +gee_get_data_for_years <- function( + years = 2018, + lakes, + image_collection = "COPERNICUS/S2_SR_HARMONIZED", + bands = NULL, #as.list(c("QA60", paste0("B", 1:6))), + point_on_surface = FALSE, + spatial_fun = "mean", + scale = 10, + via = "getInfo", + col_lakename = "GEWNAME", + debug = TRUE, + ee_print = FALSE, + n_year_splits = NULL +) +{ stopifnot(spatial_fun %in% names(rgee::ee$Reducer)) lakes_obj <- deparse(substitute(lakes)) - if(! "sf" %in% class(lakes)) { + if (!inherits(lakes, "sf")) { message(sprintf("Converting object 'lakes' = '%s'", lakes_obj)) lakes <- sf::st_as_sf(lakes) } @@ -58,92 +64,110 @@ gee_get_data_for_years <- function(years = 2018, collection_year <- rgee::ee$ImageCollection(image_collection) - if(!is.null(bands)) collection_year <- collection_year$select(bands) + if (!is.null(bands)) { + collection_year <- collection_year$select(bands) + } collection_year <- collection_year$ filterBounds(rgee::sf_as_ee(lakes_boundary))$ - filterDate(sprintf("%d-01-01", as.integer(year)), - sprintf("%d-12-31", as.integer(year))) + filterDate( + sprintf("%d-01-01", as.integer(year)), + sprintf("%d-12-31", as.integer(year)) + ) dat_year <- collection_year$getInfo() n_images_year <- length(dat_year$features) n_bands <- length(dat_year$features[[1]]$bands) - if(is.null(n_year_splits)) { - n_periods <- ceiling(n_bands*n_images_year/5000) + 1 - - if(as.integer(year) == as.integer(format(Sys.Date(), format = "%Y"))) - n_periods <- ceiling(n_periods * lubridate::yday(Sys.Date())/365) + if (is.null(n_year_splits)) { + n_periods <- ceiling(n_bands * n_images_year / 5000) + 1L + if (is_this_year(year)) { + n_periods <- ceiling(n_periods * lubridate::yday(Sys.Date()) / 365) + } } dates <- create_periods_in_year(year, n_periods) - sat_dat_year <- kwb.utils::catAndRun( - messageText = sprintf("Available images for year %d: %d", - year, - n_images_year), + kwb.utils::catAndRun( + messageText = sprintf( + "Available images for year %d: %d", + year, + n_images_year + ), + dbg = debug, + newLine = 1L, expr = { - lapply(seq_len(nrow(dates)), function(idx) { - collection_split <- rgee::ee$ImageCollection(image_collection) + lapply(seq_len(nrow(dates)), function(idx) { - if(!is.null(bands)) collection_split <- collection_split$select(bands) + collection_split <- rgee::ee$ImageCollection(image_collection) - collection_split <- collection_split$ - filterBounds(rgee::sf_as_ee(lakes_boundary))$ - filterDate(dates$start[idx], dates$end[idx]) + if (!is.null(bands)) { + collection_split <- collection_split$select(bands) + } - if (debug && ee_print) { - rgee::ee_print(collection_split) # Useful for debugging. - } + collection_split <- collection_split$ + filterBounds(rgee::sf_as_ee(lakes_boundary))$ + filterDate(dates$start[idx], dates$end[idx]) - dat <- collection_split$getInfo() - - n_images <- length(dat$features) - n_bands <- length(dat$features[[1]]$bands) - - stopifnot(n_images > 0) - stopifnot(n_bands > 0) - - msg_txt <- sprintf(paste0("Downloading data for %d lake(s) for year '%d' (%s - %s) and", - " spatial aggregation function '%s' with scale %d m (number_of_images:", - "%d, number_of_bands: %d)"), - nrow(lakes), - year, - dates$start[idx], - dates$end[idx], - spatial_fun, - scale, - n_images, - n_bands) - - kwb.utils::catAndRun(messageText = msg_txt, - expr = { - stopifnot(n_images * n_bands <= 5000) - gee_get_data(collection = collection_split, - lakes = lakes, - point_on_surface = point_on_surface, - spatial_fun = spatial_fun, - scale = scale, - via = via, - col_lakename = col_lakename) %>% - dplyr::bind_cols(tibble::tibble( - year = year, - date_start = dates$start[idx], - date_end = dates$end[idx])) - }, - dbg = debug, - newLine = 1L) - })}, - dbg = debug, - newLine = 1) %>% - dplyr::bind_rows() + if (debug && ee_print) { + rgee::ee_print(collection_split) + } - sat_dat_year -}) %>% - dplyr::bind_rows() + dat <- collection_split$getInfo() + + n_images <- length(dat$features) + n_bands <- length(dat$features[[1]]$bands) + + stopifnot(n_images > 0L) + stopifnot(n_bands > 0L) + + msg_txt <- sprintf( + paste0( + "Downloading data for %d lake(s) for year '%d' (%s - %s) and", + " spatial aggregation function '%s' with scale %d m (number_of_images:", + "%d, number_of_bands: %d)" + ), + nrow(lakes), + year, + dates$start[idx], + dates$end[idx], + spatial_fun, + scale, + n_images, + n_bands + ) + + kwb.utils::catAndRun( + messageText = msg_txt, + dbg = debug, + newLine = 1L, + expr = { + stopifnot(n_images * n_bands <= 5000) + gee_get_data( + collection = collection_split, + lakes = lakes, + point_on_surface = point_on_surface, + spatial_fun = spatial_fun, + scale = scale, + via = via, + col_lakename = col_lakename + ) %>% + dplyr::bind_cols(tibble::tibble( + year = year, + date_start = dates$start[idx], + date_end = dates$end[idx] + )) + }) + + }) + } + ) %>% + dplyr::bind_rows() + }) %>% + dplyr::bind_rows() } @@ -151,13 +175,14 @@ gee_get_data_for_years <- function(years = 2018, #' #' @param collection collection satellite collection #' @param lakes lakes sf data frame witch shapes of lakes -#' @param point_on_surface use sf::st_point_on_surface() or polygon? (default: FALSE) +#' @param point_on_surface use sf::st_point_on_surface() or polygon? (default: +#' FALSE) #' @param spatial_fun spatial aggregation function (default: "mean") #' @param scale scale parameter (default: 10), for details, see -#' \url{https://developers.google.com/earth-engine/guides/scale} +#' \url{https://developers.google.com/earth-engine/guides/scale} #' @param via via (default: "getInfo"), other options use google cloud storage -#' @param col_lakename col_lakename ("GEWNAME", used by Berlin authority for surface -#' water bodies) +#' @param col_lakename col_lakename ("GEWNAME", used by Berlin authority for +#' surface water bodies) #' @param debug print debug messages? (default: TRUE) #' #' @return tibble @@ -171,20 +196,22 @@ gee_get_data_for_years <- function(years = 2018, #' @importFrom tidyselect all_of #' @importFrom lubridate ymd_hms #' @importFrom tidyr pivot_longer separate nest -gee_get_data <- function (collection, - lakes, - point_on_surface = FALSE, - spatial_fun = "mean", - scale = 10, - via = "getInfo", - col_lakename = "GEWNAME", - debug = TRUE) { - +gee_get_data <- function ( + collection, + lakes, + point_on_surface = FALSE, + spatial_fun = "mean", + scale = 10, + via = "getInfo", + col_lakename = "GEWNAME", + debug = TRUE +) +{ stopifnot(spatial_fun %in% names(rgee::ee$Reducer)) lakes_obj <- deparse(substitute(lakes)) - if(! "sf" %in% class(lakes)) { + if (!inherits(lakes, "sf")) { message(sprintf("Converting object 'lakes' = '%s'", lakes_obj)) lakes <- sf::st_as_sf(lakes) } @@ -195,18 +222,23 @@ gee_get_data <- function (collection, shape_type <- tolower(sf::st_geometry_type(lake)) - res <- kwb.utils::catAndRun( + kwb.utils::catAndRun( messageText = sprintf( "Getting data for '%s' (%3d/%3d)", lake[[col_lakename]], idx, nrow(lakes) ), + dbg = debug, + newLine = 1L, expr = { lake_gee <- if (point_on_surface & shape_type != "point") { kwb.utils::catAndRun( - messageText = sprintf("convert '%s' to point with 'sf::st_point_on_surface()'", - shape_type), + messageText = sprintf( + "convert '%s' to point with 'sf::st_point_on_surface()'", + shape_type + ), + dbg = debug, expr = { shape_type <- sprintf("%s_to_point-on-surface", shape_type) x <- lake %>% @@ -216,23 +248,27 @@ gee_get_data <- function (collection, x <- sf::st_bbox(x)[1:2] rgee::sf_as_ee(sf::st_point(x)) - }, - dbg = debug) + } + ) + } else { - message(sprintf("using '%s' geometry provided in 'lakes' argument", - shape_type)) + + message(sprintf( + "using '%s' geometry provided in 'lakes' argument", + shape_type + )) lake %>% sf::st_geometry() %>% rgee::sf_as_ee() } - if(nrow(lakes) > 1) { - collection_lake <- collection$filterBounds(lake_gee) + metadata <- if (nrow(lakes) > 1L) { + collection$filterBounds(lake_gee) } else { - collection_lake <- collection - } - metadata <- gee_get_metadata(collection_lake) + collection + } %>% + gee_get_metadata() image_extract <- rgee::ee_extract( x = collection, @@ -253,56 +289,60 @@ gee_get_data <- function (collection, dplyr::mutate(name = stringr::str_remove(name, "X")) %>% tidyr::separate( name, - into = c("datetime_start", - "datetime_end", - "tile_id", - "band1", - "band2"), + into = c( + "datetime_start", + "datetime_end", + "tile_id", + "band1", + "band2" + ), sep = "_", fill = "right" ) %>% dplyr::mutate( - band = dplyr::if_else(is.na(band2), - band1, - paste0(band1, "_", band2)), + band = dplyr::if_else( + is.na(band2), + band1, + paste0(band1, "_", band2) + ), datetime_start = lubridate::ymd_hms(datetime_start), datetime_end = lubridate::ymd_hms(datetime_end) ) %>% dplyr::select(! tidyselect::all_of(c("band1", "band2"))) %>% dplyr::relocate("band", .before = "value") %>% - dplyr::arrange(datetime_start, - band) + dplyr::arrange(datetime_start, band) band_timeseries_wide <- band_timeseries %>% - tidyr::pivot_wider(names_from = band, - values_from = value) %>% + tidyr::pivot_wider(names_from = band, values_from = value) %>% dplyr::mutate(geometry_filter = rgee::ee_as_sf(lake_gee)) - dat_meta <- dplyr::left_join(band_timeseries_wide, - metadata, - by = c("datetime_start", "datetime_end", "tile_id") + dat_meta <- dplyr::left_join( + band_timeseries_wide, + metadata, + by = c("datetime_start", "datetime_end", "tile_id") ) - - dplyr::bind_cols(lake, - tidyr::nest(dat_meta, - .key = "satellite_data_metadata")) %>% - dplyr::bind_cols(tidyr::nest(band_timeseries_wide, - .key = "satellite_data")) %>% - dplyr::bind_cols(tidyr::nest(metadata, - .key = "satellite_metadata")) %>% - dplyr::bind_cols(tibble::tibble(satellite_data.nrow = nrow(band_timeseries_wide), - satellite_metadata.nrow = nrow(metadata), - shape_type = shape_type, - spatial_fun = spatial_fun, - scale = scale)) - }, - dbg = debug, - newLine = 1L + dplyr::bind_cols(lake, tidyr::nest( + dat_meta, .key = "satellite_data_metadata" + )) %>% + dplyr::bind_cols(tidyr::nest( + band_timeseries_wide, + .key = "satellite_data" + )) %>% + dplyr::bind_cols(tidyr::nest( + metadata, + .key = "satellite_metadata" + )) %>% + dplyr::bind_cols(tibble::tibble( + satellite_data.nrow = nrow(band_timeseries_wide), + satellite_metadata.nrow = nrow(metadata), + shape_type = shape_type, + spatial_fun = spatial_fun, + scale = scale + )) + } ) - return(res) }) %>% - dplyr::bind_rows() - + dplyr::bind_rows() } diff --git a/R/import_rds.R b/R/import_rds.R index e08f266..8955b22 100644 --- a/R/import_rds.R +++ b/R/import_rds.R @@ -1,19 +1,13 @@ #' Helper function: import .rds files from folder #' #' @param rds_dir path to directoy containing .rds files -#' #' @return list with imported #' @export #' @importFrom kwb.utils removeExtension #' @importFrom stats setNames -import_rds <- function(rds_dir) { - -rds_paths <- list.files(rds_dir, pattern = "\\.rds$", full.names = TRUE) - -rds_names <- kwb.utils::removeExtension(basename(rds_paths)) - -stats::setNames(lapply(rds_paths, readRDS), - nm = rds_names) +import_rds <- function(rds_dir) +{ + files <- list.files(rds_dir, pattern = "\\.rds$", full.names = TRUE) + objects <- lapply(files, readRDS) + stats::setNames(objects, kwb.utils::removeExtension(basename(files))) } - - diff --git a/R/utils.R b/R/utils.R new file mode 100644 index 0000000..718e476 --- /dev/null +++ b/R/utils.R @@ -0,0 +1,12 @@ +# is_this_year ----------------------------------------------------------------- +is_this_year <- function(year) +{ + stopifnot(is.numeric(year), length(year) == 1L) + as.integer(year) == this_year() +} + +# this_year -------------------------------------------------------------------- +this_year <- function() +{ + as.integer(format(Sys.Date(), format = "%Y")) +} diff --git a/vignettes/ad4gd_google-earth-engine.Rmd b/vignettes/ad4gd_google-earth-engine.Rmd index 1e3c574..f4b0113 100644 --- a/vignettes/ad4gd_google-earth-engine.Rmd +++ b/vignettes/ad4gd_google-earth-engine.Rmd @@ -23,18 +23,17 @@ is_gh_actions <- identical(Sys.getenv("CI"), "true") pkgs_cran <- c("geojsonsf", "rgee", "reticulate") pkgs_runiverse <- "kwb.python" pkgs <- c(pkgs_cran, pkgs_runiverse) -install.packages(pkgs, repos = c("https://cloud.r-project.org", - "https://kwb-r.r-universe.dev")) +install.packages(pkgs, repos = c( + "https://cloud.r-project.org", + "https://kwb-r.r-universe.dev" +)) ### Downgrade to last one supplied by R package "rgee" -kwb.python::conda_py_install("ad4gd", pkgs = list(conda = c("python=3.12.2", - "numpy"), - py = "earthengine-api==0.1.370")) - - - - +kwb.python::conda_py_install("ad4gd", pkgs = list( + conda = c("python=3.12.2", "numpy"), + py = "earthengine-api==0.1.370" +)) ``` ## Use @@ -47,53 +46,50 @@ kwb.python::conda_py_install("ad4gd", pkgs = list(conda = c("python=3.12.2", library(magrittr) url <- "https://fbinter.stadt-berlin.de/fb/atom/Gewaesserkarte/Gewaesserkarte.zip" -tfile <- basename(url) - -download.file(url, destfile = basename(url)) +destfile <- basename(url) +download.file(url, destfile = destfile) +unzip(zipfile = destfile, exdir = "lakes_berlin") -unzip(zipfile = tfile, - exdir = "lakes_berlin") - -lakes_berlin <- sf::read_sf("lakes_berlin/Gewaesser_Berlin_Flaechen.shp", - options = "ENCODING=WINDOWS-1252") %>% +lakes_berlin <- "lakes_berlin/Gewaesser_Berlin_Flaechen.shp" %>% + sf::read_sf(options = "ENCODING=WINDOWS-1252") %>% dplyr::mutate(area = sf::st_area(.)) %>% dplyr::filter(stringr::str_starts(GEWART, pattern = "Stehendes")) - - ``` #### Lakes Brandenburg ```{r lakes_brandenburg} -archive::archive_extract("https://data.geobasis-bb.de/geofachdaten/Wasser/Hydrologie/seen25.zip", - dir = "lakes_bb") -lakes_bb <- sf::read_sf("lakes_bb/Seen25_20211105/seen25.shp") +url <- "https://data.geobasis-bb.de/geofachdaten/Wasser/Hydrologie/seen25.zip" +archive::archive_extract(url, dir = "lakes_bb") -csv_path <- system.file("extdata/seen25_selected.csv", package = "kwb.satellite") - -lakes_bb_selected <- lakes_bb %>% - dplyr::inner_join(readr::read_csv(csv_path, col_types = "c"), by = "SEE_KZ") +lakes_bb <- "lakes_bb/Seen25_20211105/seen25.shp" %>% + sf::read_sf() +lakes_25 <- "extdata/seen25_selected.csv" %>% + system.file(package = "kwb.satellite") %>% + readr::read_csv(col_types = "c") +lakes_bb_selected <- lakes_bb %>% + dplyr::inner_join(lakes_25, by = "SEE_KZ") ``` ### Get Satellite Data #### Single Core -```{r satellite_data_single, eval = ! is_gh_actions} +```{r satellite_data_single, eval = ! is_gh_actions} plot_solar_azimut_angle <- function(res) { - -res %>% -ggplot2::ggplot(ggplot2::aes(x = datetime_start, - y = MEAN_SOLAR_AZIMUTH_ANGLE, - col = tile_id)) + - ggplot2::geom_point() + - ggplot2::geom_line() + - ggplot2::theme_bw() + res %>% + ggplot2::ggplot(ggplot2::aes( + x = datetime_start, + y = MEAN_SOLAR_AZIMUTH_ANGLE, + col = tile_id + )) + + ggplot2::geom_point() + + ggplot2::geom_line() + + ggplot2::theme_bw() } - reticulate::use_condaenv("ad4gd") library(rgee) @@ -101,31 +97,33 @@ library(rgee) rgee::ee_Initialize() system.time( -lakes_01_ptonsurface <- kwb.satellite::gee_get_data_for_years( - years = 2018, - lakes = lakes_berlin[1, ], - #bands = NULL, - point_on_surface = TRUE) + lakes_01_ptonsurface <- kwb.satellite::gee_get_data_for_years( + years = 2018, + lakes = lakes_berlin[1, ], + #bands = NULL, + point_on_surface = TRUE + ) ) lakes_01_ptonsurface <- kwb.satellite::flatten_results(lakes_01_ptonsurface) plot_solar_azimut_angle(lakes_01_ptonsurface) +selected <- lakes_bb_selected$SEE_NAME == "Senftenberger See" system.time( -lakes_malte_test <- kwb.satellite::gee_get_data_for_years( - years = 2021:2024, - lakes = lakes_bb_selected[lakes_bb_selected$SEE_NAME == "Senftenberger See",], - point_on_surface = FALSE, - scale = 5, - col_lakename = "SEE_NAME", - debug = TRUE) + lakes_malte_test <- kwb.satellite::gee_get_data_for_years( + years = 2021:2024, + lakes = lakes_bb_selected[selected, ], + point_on_surface = FALSE, + scale = 5, + col_lakename = "SEE_NAME", + debug = TRUE + ) ) lakes_malte_test_flatten <- kwb.satellite::flatten_results(lakes_malte_test) plot_solar_azimut_angle(lakes_malte_test_flatten) - ``` #### Multi Core @@ -135,40 +133,43 @@ reticulate::use_condaenv("ad4gd") library(rgee) rgee::ee_Initialize() - -csv_path <- system.file("extdata/lakes_bb_malte.csv", package = "kwb.satellite") - -lakes_malte <- readr::read_csv(csv_path) %>% +lakes_malte <- "extdata/lakes_bb_malte.csv" %>% + system.file(package = "kwb.satellite") %>% + readr::read_csv() %>% sf::st_as_sf(coords = c("long", "lat"), crs = 4326) years <- 2017:2023 #kwb.utils::hsOpenWindowsExplorer(exp_dir) system.time( -lakes_malte_centroid <- kwb.satellite::gee_get_data_for_years( - years = years, - lakes = lakes_malte[2,], - point_on_surface = FALSE, - col_lakename = "SEE_NAME", - debug = TRUE) + lakes_malte_centroid <- kwb.satellite::gee_get_data_for_years( + years = years, + lakes = lakes_malte[2,], + point_on_surface = FALSE, + col_lakename = "SEE_NAME", + debug = TRUE + ) ) exp_dir <- fs::path_join(c(getwd(), "vignettes/gee/malte_point")) system.time( -lakes_malte_points_parallel <- kwb.satellite::gee_get_data_for_years_parallel( - years = years, - lakes = lakes_malte, - point_on_surface = FALSE, - spatial_fun = "mean", - col_lakename = "SEE_NAME", - debug_dir = exp_dir, - export_dir = exp_dir, - debug = TRUE) + lakes_malte_points_parallel <- kwb.satellite::gee_get_data_for_years_parallel( + years = years, + lakes = lakes_malte, + point_on_surface = FALSE, + spatial_fun = "mean", + col_lakename = "SEE_NAME", + debug_dir = exp_dir, + export_dir = exp_dir, + debug = TRUE + ) ) -saveRDS(lakes_malte_points_parallel, - fs::path_join(c(exp_dir, "../malte_point.rds"))) +saveRDS( + lakes_malte_points_parallel, + fs::path_join(c(exp_dir, "../malte_point.rds")) +) lakes_selected <- lakes_bb %>% dplyr::filter(SEE_KZ %in% lakes_malte$SEE_KZ) @@ -176,111 +177,131 @@ lakes_selected <- lakes_bb %>% exp_dir <- fs::path_join(c(getwd(), "vignettes/gee/lakes-bb_point-on-surface")) system.time( -lakes_bb_point_on_surface <- kwb.satellite::gee_get_data_for_years_parallel( - years = years, - lakes = lakes_selected, - point_on_surface = TRUE, - spatial_fun = "mean", - col_lakename = "SEE_NAME", - debug_dir = exp_dir, - export_dir = exp_dir, - debug = TRUE) + lakes_bb_point_on_surface <- kwb.satellite::gee_get_data_for_years_parallel( + years = years, + lakes = lakes_selected, + point_on_surface = TRUE, + spatial_fun = "mean", + col_lakename = "SEE_NAME", + debug_dir = exp_dir, + export_dir = exp_dir, + debug = TRUE + ) ) -saveRDS(lakes_bb_point_on_surface, fs::path_join(c(exp_dir, "../lakes-bb_point-on-surface.rds"))) +saveRDS( + lakes_bb_point_on_surface, + fs::path_join(c(exp_dir, "../lakes-bb_point-on-surface.rds")) +) exp_dir <- fs::path_join(c(getwd(), "vignettes/gee/lakes-bb_polygon")) system.time( -lakes_bb_polygon <- kwb.satellite::gee_get_data_for_years_parallel( - years = years, - lakes = lakes_selected, - point_on_surface = FALSE, - spatial_fun = "mean", - col_lakename = "SEE_NAME", - debug_dir = exp_dir, - export_dir = exp_dir, - debug = TRUE) + lakes_bb_polygon <- kwb.satellite::gee_get_data_for_years_parallel( + years = years, + lakes = lakes_selected, + point_on_surface = FALSE, + spatial_fun = "mean", + col_lakename = "SEE_NAME", + debug_dir = exp_dir, + export_dir = exp_dir, + debug = TRUE + ) ) - exp_dir <- fs::path_join(c(getwd(), "vignettes/gee/berlin_point")) system.time( -lakes_bb_point_on_surface <- kwb.satellite::gee_get_data_for_years_parallel( - years = years, - lakes = lakes_selected, - point_on_surface = TRUE, - spatial_fun = "mean", - col_lakename = "SEE_NAME", - debug_dir = exp_dir, - export_dir = exp_dir, - debug = TRUE) + lakes_bb_point_on_surface <- kwb.satellite::gee_get_data_for_years_parallel( + years = years, + lakes = lakes_selected, + point_on_surface = TRUE, + spatial_fun = "mean", + col_lakename = "SEE_NAME", + debug_dir = exp_dir, + export_dir = exp_dir, + debug = TRUE + ) ) -saveRDS(lakes_berlin_point_on_surface, - fs::path_join(c(exp_dir, "../lakes_berlin_point_on_surface.rds"))) +saveRDS( + lakes_berlin_point_on_surface, + fs::path_join(c(exp_dir, "../lakes_berlin_point_on_surface.rds")) +) exp_dir <- fs::path_join(c(getwd(), "vignettes/gee/berlin_polygon")) system.time( -lakes_bb_polygon <- kwb.satellite::gee_get_data_for_years_parallel( - years = years, - lakes = lakes_selected, - point_on_surface = FALSE, - spatial_fun = "mean", - col_lakename = "SEE_NAME", - debug_dir = exp_dir, - export_dir = exp_dir, - debug = TRUE) + lakes_bb_polygon <- kwb.satellite::gee_get_data_for_years_parallel( + years = years, + lakes = lakes_selected, + point_on_surface = FALSE, + spatial_fun = "mean", + col_lakename = "SEE_NAME", + debug_dir = exp_dir, + export_dir = exp_dir, + debug = TRUE + ) ) -saveRDS(lakes_berlin_polygon, - fs::path_join(c(exp_dir, "../lakes_berlin_polygon.rds"))) - +saveRDS( + lakes_berlin_polygon, + fs::path_join(c(exp_dir, "../lakes_berlin_polygon.rds")) +) exp_dir <- fs::path_join(c(getwd(), "gee/lakes-bb-selected_point-on-surface")) fs::dir_create(exp_dir) -lakes_working <- stringr::str_split_fixed(basename(fs::dir_ls(exp_dir, type = "file",regexp = "\\.rds" )),pattern = "_point_on_surface", n = 2)[,1] +lakes_working <- stringr::str_split_fixed( + basename(fs::dir_ls(exp_dir, type = "file", regexp = "\\.rds" )), + pattern = "_point_on_surface", + n = 2L +)[, 1L] -lakes_bb_selected_failed <- lakes_bb_selected[!lakes_bb_selected$SEE_NAME %in% lakes_working,] +selected <- !lakes_bb_selected$SEE_NAME %in% lakes_working +lakes_bb_selected_failed <- lakes_bb_selected[selected, ] -lakes_bb_selected_failed <- lakes_bb_selected[lakes_bb_selected$SEE_NAME %in% c("Netzowsee", "Petznicksee"),] +selected <- lakes_bb_selected$SEE_NAME %in% c("Netzowsee", "Petznicksee") +lakes_bb_selected_failed <- lakes_bb_selected[selected, ] system.time( -lakes_bb_point_on_surface <- kwb.satellite::gee_get_data_for_years_parallel( - years = 2024, - lakes = lakes_bb_selected[1:7,], - point_on_surface = TRUE, - spatial_fun = "mean", - col_lakename = "SEE_NAME", - debug_dir = exp_dir, - export_dir = exp_dir, - debug = TRUE) + lakes_bb_point_on_surface <- kwb.satellite::gee_get_data_for_years_parallel( + years = 2024, + lakes = lakes_bb_selected[1:7,], + point_on_surface = TRUE, + spatial_fun = "mean", + col_lakename = "SEE_NAME", + debug_dir = exp_dir, + export_dir = exp_dir, + debug = TRUE + ) ) -saveRDS(lakes_bb_point_on_surface, fs::path_join(c(exp_dir, "../lakes_bb_point_on_surface.rds"))) - +saveRDS( + lakes_bb_point_on_surface, + fs::path_join(c(exp_dir, "../lakes_bb_point_on_surface.rds")) +) exp_dir <- fs::path_join(c(getwd(), "gee/lakes_bb_selected_polygon")) - + system.time( -lakes_polygon <- kwb.satellite::gee_get_data_for_years_parallel( - years = years, - lakes = lakes_bb_selected, - point_on_surface = FALSE, - spatial_fun = "mean", - col_lakename = "SEE_NAME", - debug_dir = exp_dir, - export_dir = exp_dir, - debug = TRUE) + lakes_polygon <- kwb.satellite::gee_get_data_for_years_parallel( + years = years, + lakes = lakes_bb_selected, + point_on_surface = FALSE, + spatial_fun = "mean", + col_lakename = "SEE_NAME", + debug_dir = exp_dir, + export_dir = exp_dir, + debug = TRUE + ) ) -saveRDS(lakes_bb_selected_polygon, fs::path_join(c(exp_dir, "../lakes_bb_selected_polygon.rds"))) - - +saveRDS( + lakes_bb_selected_polygon, + file = fs::path_join(c(exp_dir, "../lakes_bb_selected_polygon.rds")) +) ``` ## Info @@ -294,15 +315,11 @@ sessioninfo::session_info() %>% ### Python Info - ```{r reticulate_01, echo = TRUE} env_yml <- kwb.python::conda_export("ad4gd", export_dir = ".") paste0(readLines(env_yml), collapse = "\n") %>% details::details(open = TRUE) - - - ``` You can download the python environment used for this tutorial here: