From f7cd65ceb19b6da0cb8dcccf8d1bf123676673fa Mon Sep 17 00:00:00 2001 From: Jason Everett Date: Fri, 26 Sep 2025 07:09:20 +1000 Subject: [PATCH 1/3] Misc Changes from the past --- DESCRIPTION | 11 +- NAMESPACE | 138 ++ R/splnr_apply_cutoffs.R | 216 ++- R/splnr_deprecated.R | 8 +- R/splnr_featureRep.R | 695 ++++++--- R/splnr_get_IUCNRedList.R | 118 +- R/splnr_get_MPAs.R | 138 +- R/splnr_get_boundary.R | 149 +- R/splnr_get_distCoast.R | 133 +- R/splnr_get_gfw.R | 214 ++- R/splnr_gg_add.R | 294 +++- R/splnr_plot.R | 279 ++-- R/splnr_plotting.R | 1132 +++++++++++--- R/splnr_plotting_climate.R | 476 ++++-- R/splnr_targets.R | 347 ++++- R/utils-climate.R | 1405 ++++++++++++++---- R/utils.R | 844 ++++++++--- README.Rmd | 341 ++++- README.md | 467 +++++- data-raw/CreateHex.R | 10 +- data-raw/spatialplanr.png | Bin 712741 -> 714334 bytes man/figures/README-unnamed-chunk-13-1.png | Bin 0 -> 43452 bytes man/figures/README-unnamed-chunk-5-1.png | Bin 0 -> 41027 bytes man/figures/README-unnamed-chunk-6-1.png | Bin 0 -> 51874 bytes man/figures/README-unnamed-chunk-6-2.png | Bin 0 -> 37410 bytes man/figures/README-unnamed-chunk-7-1.png | Bin 0 -> 37104 bytes man/figures/README-unnamed-chunk-8-1.png | Bin 0 -> 40951 bytes man/figures/README-unnamed-chunk-9-1.png | Bin 0 -> 38994 bytes man/figures/logo.png | Bin 67895 -> 68250 bytes man/spatialplanr-package.Rd | 4 +- man/splnr_apply_cutoffs.Rd | 84 +- man/splnr_arrangeFeatures.Rd | 34 +- man/splnr_climate_featureApproach.Rd | 84 +- man/splnr_climate_percentileApproach.Rd | 79 +- man/splnr_climate_priorityAreaApproach.Rd | 85 +- man/splnr_create_polygon.Rd | 44 +- man/splnr_featureNames.Rd | 48 +- man/splnr_get_IUCNRedList.Rd | 79 +- man/splnr_get_MPAs.Rd | 77 +- man/splnr_get_boundary.Rd | 57 +- man/splnr_get_distCoast.Rd | 67 +- man/splnr_get_featureRep.Rd | 151 +- man/splnr_get_gfw.Rd | 97 +- man/splnr_get_kappaCorrData.Rd | 62 +- man/splnr_get_selFreq.Rd | 79 +- man/splnr_gg_add.Rd | 160 +- man/splnr_match_names.Rd | 38 +- man/splnr_plot.Rd | 218 ++- man/splnr_plot_circBplot.Rd | 41 +- man/splnr_plot_climData.Rd | 58 +- man/splnr_plot_climKernelDensity.Rd | 88 +- man/splnr_plot_comparison.Rd | 46 +- man/splnr_plot_corrMat.Rd | 62 +- man/splnr_plot_cost.Rd | 10 +- man/splnr_plot_costOverlay.Rd | 65 +- man/splnr_plot_featureRep.Rd | 72 +- man/splnr_plot_importanceScore.Rd | 75 +- man/splnr_plot_selectionFreq.Rd | 54 +- man/splnr_plot_solution.Rd | 74 +- man/splnr_replace_NAs.Rd | 40 +- man/splnr_scale_01.Rd | 42 +- man/splnr_targets_byCategory.Rd | 52 +- man/splnr_targets_byIUCN.Rd | 85 +- man/splnr_targets_byInverseArea.Rd | 57 +- pkgdown/favicon/apple-touch-icon.png | Bin 34928 -> 29912 bytes pkgdown/favicon/favicon-96x96.png | Bin 0 -> 10185 bytes pkgdown/favicon/favicon.ico | Bin 15086 -> 15086 bytes pkgdown/favicon/favicon.svg | 3 + pkgdown/favicon/site.webmanifest | 21 + pkgdown/favicon/web-app-manifest-192x192.png | Bin 0 -> 33537 bytes pkgdown/favicon/web-app-manifest-512x512.png | Bin 0 -> 193587 bytes tests/testthat/test-splnr_plot.R | 22 +- vignettes/ClimateSmart.R | 174 --- vignettes/GlobalFishingWatch.R | 204 --- vignettes/GlobalFishingWatch.html | 535 ------- vignettes/MultipleUse.R | 301 ---- vignettes/spatialplanr.R | 99 -- vignettes/spatialplanr.Rmd | 32 +- 78 files changed, 8045 insertions(+), 3229 deletions(-) create mode 100644 man/figures/README-unnamed-chunk-13-1.png create mode 100644 man/figures/README-unnamed-chunk-5-1.png create mode 100644 man/figures/README-unnamed-chunk-6-1.png create mode 100644 man/figures/README-unnamed-chunk-6-2.png create mode 100644 man/figures/README-unnamed-chunk-7-1.png create mode 100644 man/figures/README-unnamed-chunk-8-1.png create mode 100644 man/figures/README-unnamed-chunk-9-1.png create mode 100644 pkgdown/favicon/favicon-96x96.png create mode 100644 pkgdown/favicon/favicon.svg create mode 100644 pkgdown/favicon/site.webmanifest create mode 100644 pkgdown/favicon/web-app-manifest-192x192.png create mode 100644 pkgdown/favicon/web-app-manifest-512x512.png delete mode 100644 vignettes/ClimateSmart.R delete mode 100644 vignettes/GlobalFishingWatch.R delete mode 100644 vignettes/GlobalFishingWatch.html delete mode 100644 vignettes/MultipleUse.R delete mode 100644 vignettes/spatialplanr.R diff --git a/DESCRIPTION b/DESCRIPTION index bdcc74b3..7b39bcd7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -23,7 +23,7 @@ BugReports: https://github.com/SpatialPlanning/spatialplanr/issues Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.2 +RoxygenNote: 7.3.3 Suggests: gfwr, ggcorrplot, @@ -32,15 +32,12 @@ Suggests: knitr, oceandatr, patchwork, - prioritizr, RColorBrewer, rmarkdown, rnaturalearthdata, rnaturalearthhires, rredlist, testthat (>= 3.0.0), - units, - vctrs, viridis, wdpar VignetteBuilder: knitr @@ -54,7 +51,7 @@ Imports: ggplot2, lifecycle, magrittr, - methods, + prioritizr, purrr, rappdirs, rlang, @@ -66,7 +63,9 @@ Imports: terra, tibble, tidyr, - tidyselect + tidyselect, + units, + vctrs Remotes: github::emlab-ucsb/oceandatr, github::emlab-ucsb/spatialgridr, diff --git a/NAMESPACE b/NAMESPACE index bf0d116b..71160bc7 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -40,7 +40,145 @@ export(splnr_scale_01) export(splnr_targets_byCategory) export(splnr_targets_byIUCN) export(splnr_targets_byInverseArea) +importFrom(assertthat,assert_that) +importFrom(assertthat,is.flag) +importFrom(assertthat,is.string) +importFrom(dplyr,across) +importFrom(dplyr,any_of) +importFrom(dplyr,arrange) +importFrom(dplyr,as_tibble) +importFrom(dplyr,bind_cols) +importFrom(dplyr,bind_rows) +importFrom(dplyr,case_when) +importFrom(dplyr,coalesce) +importFrom(dplyr,everything) +importFrom(dplyr,filter) +importFrom(dplyr,full_join) +importFrom(dplyr,group_by) +importFrom(dplyr,if_else) +importFrom(dplyr,left_join) +importFrom(dplyr,mutate) +importFrom(dplyr,pull) +importFrom(dplyr,rename) +importFrom(dplyr,rename_at) +importFrom(dplyr,rowwise) +importFrom(dplyr,select) +importFrom(dplyr,starts_with) +importFrom(dplyr,summarise) +importFrom(dplyr,summarize) +importFrom(dplyr,tibble) +importFrom(dplyr,ungroup) +importFrom(forcats,fct_relevel) +importFrom(ggnewscale,new_scale_colour) +importFrom(ggnewscale,new_scale_fill) +importFrom(ggplot2,aes) +importFrom(ggplot2,after_stat) +importFrom(ggplot2,annotate) +importFrom(ggplot2,coord_polar) +importFrom(ggplot2,coord_sf) +importFrom(ggplot2,element_blank) +importFrom(ggplot2,element_line) +importFrom(ggplot2,element_rect) +importFrom(ggplot2,element_text) +importFrom(ggplot2,expansion) +importFrom(ggplot2,geom_abline) +importFrom(ggplot2,geom_bar) +importFrom(ggplot2,geom_segment) +importFrom(ggplot2,geom_sf) +importFrom(ggplot2,geom_text) +importFrom(ggplot2,ggplot) +importFrom(ggplot2,guide_axis) +importFrom(ggplot2,guide_colourbar) +importFrom(ggplot2,guide_legend) +importFrom(ggplot2,guides) +importFrom(ggplot2,labs) +importFrom(ggplot2,scale_fill_brewer) +importFrom(ggplot2,scale_fill_distiller) +importFrom(ggplot2,scale_fill_gradient) +importFrom(ggplot2,scale_fill_gradient2) +importFrom(ggplot2,scale_fill_manual) +importFrom(ggplot2,scale_fill_viridis_c) +importFrom(ggplot2,scale_linetype_manual) +importFrom(ggplot2,scale_x_continuous) +importFrom(ggplot2,scale_x_discrete) +importFrom(ggplot2,scale_y_continuous) +importFrom(ggplot2,scale_y_discrete) +importFrom(ggplot2,theme) +importFrom(ggplot2,theme_bw) +importFrom(ggplot2,theme_minimal) +importFrom(ggplot2,unit) +importFrom(ggplot2,ylim) +importFrom(grid,unit) +importFrom(lifecycle,deprecate_warn) importFrom(lifecycle,deprecated) importFrom(magrittr,"%>%") +importFrom(prioritizr,add_binary_decisions) +importFrom(prioritizr,add_cuts_portfolio) +importFrom(prioritizr,add_default_solver) +importFrom(prioritizr,add_min_set_objective) +importFrom(prioritizr,add_relative_targets) +importFrom(prioritizr,eval_feature_representation_summary) +importFrom(prioritizr,eval_ferrier_importance) +importFrom(prioritizr,eval_rare_richness_importance) +importFrom(prioritizr,eval_replacement_importance) +importFrom(prioritizr,problem) +importFrom(prioritizr,solve.ConservationProblem) +importFrom(prioritizr,zones) +importFrom(purrr,map) +importFrom(purrr,map_df) +importFrom(purrr,map_vec) +importFrom(rappdirs,user_data_dir) importFrom(rlang,":=") importFrom(rlang,.data) +importFrom(rlang,sym) +importFrom(rnaturalearth,ne_coastline) +importFrom(rnaturalearth,ne_download) +importFrom(scales,squish) +importFrom(sf,st_area) +importFrom(sf,st_as_sf) +importFrom(sf,st_bbox) +importFrom(sf,st_centroid) +importFrom(sf,st_coordinates) +importFrom(sf,st_crs) +importFrom(sf,st_distance) +importFrom(sf,st_drop_geometry) +importFrom(sf,st_geometry) +importFrom(sf,st_join) +importFrom(sf,st_nearest_feature) +importFrom(sf,st_polygon) +importFrom(sf,st_set_crs) +importFrom(sf,st_set_geometry) +importFrom(sf,st_sf) +importFrom(sf,st_sfc) +importFrom(sf,st_transform) +importFrom(sf,st_union) +importFrom(spatialgridr,get_data_in_grid) +importFrom(stats,na.omit) +importFrom(stats,quantile) +importFrom(stats,reorder) +importFrom(stats,setNames) +importFrom(stringr,str_c) +importFrom(stringr,str_ends) +importFrom(stringr,str_pad) +importFrom(stringr,str_remove_all) +importFrom(stringr,str_replace_all) +importFrom(stringr,str_sub) +importFrom(stringr,str_subset) +importFrom(tibble,as_tibble) +importFrom(tibble,deframe) +importFrom(tibble,enframe) +importFrom(tibble,rowid_to_column) +importFrom(tibble,tibble) +importFrom(tibble,tribble) +importFrom(tidyr,pivot_longer) +importFrom(tidyr,pivot_wider) +importFrom(tidyr,replace_na) +importFrom(tidyselect,all_of) +importFrom(tidyselect,any_of) +importFrom(tidyselect,everything) +importFrom(tidyselect,matches) +importFrom(tidyselect,starts_with) +importFrom(tidyselect,where) +importFrom(units,drop_units) +importFrom(units,set_units) +importFrom(vctrs,vec_c) diff --git a/R/splnr_apply_cutoffs.R b/R/splnr_apply_cutoffs.R index 910aacaa..fc03737a 100644 --- a/R/splnr_apply_cutoffs.R +++ b/R/splnr_apply_cutoffs.R @@ -1,58 +1,212 @@ -#' Function to apply cutoffs to feature data +#' @title Apply Cutoffs to Feature Data #' -#' @param features A sf dataframe with all the feature information -#' @param Cutoffs A single value or a named vector of cutoffs. -#' @param inverse If TRUE, values below the `Cutoffs` are used. If FALSE (default), values above are kept. +#' @description +#' `splnr_apply_cutoffs()` transforms numeric feature data in an `sf` dataframe +#' into binary (0 or 1) presence/absence values based on specified cutoffs. +#' It provides flexibility to either keep values above a cutoff as 1 (default) +#' or invert this logic to keep values below a cutoff as 1. #' -#' @return A new sf dataframe that has cutoffs applied. +#' @details +#' This function is crucial for standardizing feature data, such as species +#' probability distributions or habitat suitability scores, into a binary format +#' often required for conservation planning and spatial analysis (e.g., in +#' `prioritizr`). +#' +#' The function operates in two primary modes based on the `Cutoffs` parameter: +#' \itemize{ +#' \item \strong{Single Cutoff:} If `Cutoffs` is a single numeric value (e.g., `0.5`), +#' this value is applied uniformly to \strong{all numeric columns} in the +#' `features` dataframe, excluding the `geometry` column. +#' For each numeric cell: +#' - If `value >= Cutoffs`, it becomes `1`. +#' - If `value < Cutoffs`, it becomes `0`. +#' - `NA` values are always converted to `0`. +#' \item \strong{Named Vector of Cutoffs:} If `Cutoffs` is a named numeric vector +#' (e.g., `c("feature1" = 0.5, "feature2" = 0.3)`), each specified cutoff +#' is applied individually to its corresponding named column in `features`. +#' This allows for different thresholds for different features. The same +#' transformation rules as above apply to each specified column. +#' } +#' +#' The `inverse` parameter provides additional control over the binarization: +#' \itemize{ +#' \item `inverse = FALSE` (default): Values \strong{at or above} the cutoff become `1`. +#' \item `inverse = TRUE`: Values \strong{below} the cutoff become `1`. After initial +#' binarization (where values >= cutoff are 1), the binary results are +#' flipped (0s become 1s, and 1s become 0s) to achieve the inverse effect. +#' } +#' All `NA` values in the numeric columns are consistently converted to `0` during +#' the binarization process, regardless of the `inverse` setting. +#' +#' @param features An `sf` dataframe. It must contain a `geometry` column and +#' at least one numeric column to which cutoffs will be applied. +#' @param Cutoffs A numeric value or a named numeric vector of cutoffs. +#' \itemize{ +#' \item If a single unnamed numeric value, it's applied to all numeric columns. +#' \item If a named numeric vector, names must correspond to numeric column names in `features`. +#' } +#' All cutoff values must be between `0` and `1`. +#' @param inverse A logical value (`TRUE` or `FALSE`). If `TRUE`, values below +#' the `Cutoffs` are converted to `1` (and others to `0`). If `FALSE` (default), +#' values at or above the `Cutoffs` are converted to `1`. +#' +#' @return A modified `sf` dataframe with the same structure and geometry as +#' `features`, but with all targeted numeric columns transformed into binary +#' (0 or 1) values based on the specified cutoffs and `inverse` setting. #' @export #' -#' @importFrom rlang .data +#' @importFrom assertthat assert_that +#' @importFrom dplyr across case_when mutate any_of +#' @importFrom rlang .data sym := +#' @importFrom sf st_as_sf st_geometry +#' @importFrom tibble as_tibble #' #' @examples -#' df <- splnr_apply_cutoffs(dat_species_prob, Cutoffs = 0.5) +#' +#' # Example 1: Single cutoff (0.5) applied to all numeric feature columns +#' # (Spp1_Prob, Spp2_Prob, and Cost will be binarized based on 0.5) +#' df_single_cutoff <- splnr_apply_cutoffs(dat_species_prob, Cutoffs = 0.5) +#' print(df_single_cutoff) +#' +#' # Example 2: Named cutoffs for specific columns +#' # Spp1_Prob >= 0.6 becomes 1, Spp2_Prob >= 0.4 becomes 1 +#' df_named_cutoffs <- splnr_apply_cutoffs( +#' dat_species_prob, +#' Cutoffs = c("Spp1" = 0.6, "Spp2" = 0.4) +#' ) +#' print(df_named_cutoffs) +#' +#' # Example 3: Single cutoff (0.5) with inverse logic +#' # Values BELOW 0.5 become 1. +#' df_inverse_cutoff <- splnr_apply_cutoffs(dat_species_prob, Cutoffs = 0.5, inverse = TRUE) +#' print(df_inverse_cutoff) +#' +#' # Example 4: Named cutoffs with inverse logic +#' df_named_inverse <- splnr_apply_cutoffs( +#' dat_species_prob, +#' Cutoffs = c("Spp1" = 0.7, "Spp2" = 0.3), +#' inverse = TRUE +#' ) +#' print(df_named_inverse) splnr_apply_cutoffs <- function(features, Cutoffs, inverse = FALSE) { + + # --- Input Assertions --- + # Ensure 'features' is an sf object. assertthat::assert_that( inherits(features, "sf"), - is.numeric(Cutoffs) | (is.numeric(Cutoffs) & length(names(Cutoffs)) > 0), - is.logical(inverse) + msg = "Input 'features' must be an 'sf' object." + ) + # Ensure 'Cutoffs' is numeric. + assertthat::assert_that( + is.numeric(Cutoffs), + msg = "'Cutoffs' must be a numeric value or a named numeric vector." + ) + # Ensure 'inverse' is a single logical value. + assertthat::assert_that( + is.logical(inverse) && length(inverse) == 1, + msg = "'inverse' must be a single logical value (TRUE or FALSE)." + ) + # Ensure all cutoff values are between 0 and 1. + assertthat::assert_that( + all(Cutoffs >= 0) && all(Cutoffs <= 1), + msg = "All 'Cutoffs' values must be between 0 and 1 (inclusive)." + ) + # Ensure 'features' dataframe contains a 'geometry' column. + assertthat::assert_that( + "geometry" %in% names(features), + msg = "The 'features' dataframe must contain a 'geometry' column." + ) + # Ensure the features dataframe is not empty. + assertthat::assert_that( + nrow(features) > 0, + msg = "The 'features' dataframe must not be empty." ) - if (length(Cutoffs) == 1 & length(names(Cutoffs)) == 0) { # Single cutoff for all data if unnamed vector + # Get the names of all numeric columns, excluding the geometry column. + # This ensures that only relevant feature data columns are processed. + numeric_cols <- names(features)[sapply(features, is.numeric) & names(features) != "geometry"] - features <- features %>% - dplyr::as_tibble() %>% + # Assert that there are numeric columns to operate on. + assertthat::assert_that( + length(numeric_cols) > 0, + msg = "No numeric columns found in 'features' excluding geometry. Nothing to apply cutoffs to." + ) + + # Check if 'Cutoffs' is a named vector, and if so, validate that its names + # correspond to existing numeric feature columns. + if (!is.null(names(Cutoffs))) { + assertthat::assert_that( + all(names(Cutoffs) %in% numeric_cols), + msg = "When 'Cutoffs' is a named vector, all names must match existing numeric feature column names in 'features'." + ) + } + + # Convert sf object to tibble for data manipulation, then back to sf at the end. + # This can sometimes prevent unexpected behavior with sf objects during extensive dplyr operations. + features_as_tibble <- features %>% + tibble::as_tibble() + + # --- Apply Cutoffs Logic --- + + # Case 1: Single cutoff value (unnamed vector of length 1). + if (length(Cutoffs) == 1 && is.null(names(Cutoffs))) { + message(paste0("Applying single cutoff of ", Cutoffs, " to all numeric feature columns.")) + + # Apply the single cutoff to all identified numeric columns. + # Values greater than or equal to the cutoff become 1, others become 0. + # NAs are explicitly converted to 0. + features_as_tibble <- features_as_tibble %>% dplyr::mutate(dplyr::across( - -dplyr::any_of("geometry"), # Apply to all columns except geometry + dplyr::all_of(numeric_cols), # Apply only to the identified numeric columns. ~ dplyr::case_when( . >= Cutoffs ~ 1, . < Cutoffs ~ 0, - is.na(.data) ~ 0 + is.na(.) ~ 0 # Handle NAs by converting them to 0. ) - )) %>% - sf::st_as_sf() + )) - if (inverse == TRUE) { # Need to flip the ones/zeros - features <- features %>% - dplyr::mutate(dplyr::across(-dplyr::any_of("geometry"), ~ 1 - .)) + # If 'inverse' is TRUE, flip the binary values (0s become 1s, 1s become 0s). + if (inverse == TRUE) { + message("Inverse logic applied: values below cutoff will be 1.") + features_as_tibble <- features_as_tibble %>% + dplyr::mutate(dplyr::across(dplyr::all_of(numeric_cols), ~ 1 - .)) } - } else if (length(Cutoffs) == length(names(Cutoffs))) { # Named vector with values for each column - nm <- names(Cutoffs) # Testing - We should only be operating on the columns in the Cutoffs vector + } else if (length(Cutoffs) == length(names(Cutoffs))) { + # Case 2: Named vector of cutoffs (each cutoff applies to a specific column). + message("Applying named cutoffs to specific feature columns.") - for (f in 1:length(nm)) { - features <- features %>% - dplyr::mutate(!!nm[f] := dplyr::case_when( - !!rlang::sym(nm[f]) >= Cutoffs[nm[f]] ~ 1, - !!rlang::sym(nm[f]) < Cutoffs[nm[f]] ~ 0, - is.na(!!rlang::sym(nm[f])) ~ 0 + # Iterate through each named cutoff. + for (col_name in names(Cutoffs)) { + current_cutoff <- Cutoffs[col_name] # Get the cutoff value for the current column. + message(paste0(" Applying cutoff ", current_cutoff, " to column '", col_name, "'.")) + + # Apply the specific cutoff to the current column. + # Values greater than or equal to the column's cutoff become 1, others become 0. + # NAs are explicitly converted to 0. + features_as_tibble <- features_as_tibble %>% + dplyr::mutate(!!rlang::sym(col_name) := dplyr::case_when( + !!rlang::sym(col_name) >= current_cutoff ~ 1, + !!rlang::sym(col_name) < current_cutoff ~ 0, + is.na(!!rlang::sym(col_name)) ~ 0 # Handle NAs by converting them to 0. )) - if (inverse == TRUE) { # Need to flip the ones/zeros - features <- features %>% - dplyr::mutate(!!nm[f] := 1 - !!rlang::sym(nm[f])) + # If 'inverse' is TRUE, flip the binary values for the current column. + if (inverse == TRUE) { + message(paste0(" Inverse logic applied for column '", col_name, "': values below cutoff will be 1.")) + features_as_tibble <- features_as_tibble %>% + dplyr::mutate(!!rlang::sym(col_name) := 1 - !!rlang::sym(col_name)) } } + } else { + # This scenario should ideally be caught by initial assertions, but included for robustness. + stop("Invalid 'Cutoffs' parameter. It must be a single numeric value or a named numeric vector where names match feature columns.") } - return(features) + + # Convert the modified tibble back to an sf object, preserving the original geometry. + # Assuming the geometry column was preserved as is in 'features_as_tibble'. + final_sf_features <- features_as_tibble %>% + sf::st_as_sf() + + return(final_sf_features) } diff --git a/R/splnr_deprecated.R b/R/splnr_deprecated.R index 2efaf1ed..4df12846 100644 --- a/R/splnr_deprecated.R +++ b/R/splnr_deprecated.R @@ -90,8 +90,8 @@ splnr_plot_MPAs <- function(df, colorVals = c("TRUE" = "blue", "FALSE" = "white" #' #' `r lifecycle::badge("deprecated")` #' -#' @param Cost An `sf` object of cost for `prioritizr` -#' @param Cost_name Name of the cost column +#' @param cost An `sf` object of cost for `prioritizr` +#' @param costName Name of the cost column #' @param legendTitle A character value for the title of the legend. Can be empty (""). #' @param paletteName A string (or number) for the color palette to use. Available palettes can be found at https://ggplot2.tidyverse.org/reference/scale_brewer.html. #' @param plotTitle A character value for the title of the plot. Can be empty (""). @@ -101,7 +101,7 @@ splnr_plot_MPAs <- function(df, colorVals = c("TRUE" = "blue", "FALSE" = "white" #' #' @examples #' \dontrun{ -#' dat_problem <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +#' dat_problem <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(cost = runif(n = dim(.)[[1]])), #' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" #' ) %>% @@ -118,7 +118,7 @@ splnr_plot_MPAs <- function(df, colorVals = c("TRUE" = "blue", "FALSE" = "white" #' #' (splnr_plot_cost(dat_cost)) #' } -splnr_plot_cost <- function(Cost, Cost_name = "Cost", legendTitle = "Cost", +splnr_plot_cost <- function(cost, costName = "Cost", legendTitle = "Cost", paletteName = "YlGnBu", plotTitle = "") { lifecycle::deprecate_stop("0.6.2", "splnr_plot_MPAs()", "splnr_plot()") diff --git a/R/splnr_featureRep.R b/R/splnr_featureRep.R index fabb286f..b5bda1d6 100644 --- a/R/splnr_featureRep.R +++ b/R/splnr_featureRep.R @@ -1,20 +1,102 @@ -#' Prepare data to plot how well targets are met +#' @title Prepare Data to Plot How Well Targets Are Met #' -#' @param soln The `prioritizr` solution -#' @param pDat The `prioritizr` problem -#' @param targets `data.frame`with list of features under "feature" column and their corresponding targets under "target" column -#' @param climsmart logical denoting whether spatial planning was done climate-smart (and targets have to be calculated differently) -#' @param climsmartApproach either 0,1,2 or 3 depending on the climate-smart approach used (0 = None; 1 = Climate Priority Area; 2 = Feature; 3 = Percentile). -#' @param solnCol Name of the column with the solution +#' @description +#' `splnr_get_featureRep()` calculates the representation of conservation +#' features within a `prioritizr` solution. This function determines how much +#' of each feature's total abundance (or area) is captured in the selected +#' planning units, and compares it against specified conservation targets. +#' It can also account for different climate-smart planning approaches. #' -#' @return `tbl_df` dataframe +#' @details +#' This function processes the output of a `prioritizr` conservation problem +#' (`soln`) and its corresponding problem definition (`pDat`) to provide a +#' summary of feature representation. It is designed to work whether or not +#' explicit targets are provided, and can adjust calculations based on the +#' climate-smart approach used. +#' +#' The function calculates: +#' \itemize{ +#' \item `total_amount`: The total available amount/area of each feature across all planning units. +#' \item `absolute_held`: The total amount/area of each feature captured in the +#' *selected* planning units (where `solution_1` is 1). +#' \item `relative_held`: The proportion of `absolute_held` relative to `total_amount`, +#' indicating the percentage representation of the feature in the solution. +#' \item `target`: The conservation target for each feature (either from the +#' `pDat` problem definition or the `targets` dataframe). +#' \item `incidental`: A logical flag indicating if a feature's representation +#' was 'incidental' (i.e., its target was 0 or NA, but it was still +#' partially or fully captured in the solution). +#' } +#' +#' \strong{Climate-Smart Considerations (`climsmart = TRUE`):} +#' If `climsmart` is `TRUE`, the function adjusts its calculations based on the +#' `climsmartApproach` parameter: +#' \itemize{ +#' \item `climsmartApproach = 1` (Climate Priority Area): The function sums the +#' `absolute_held` and `total_amount` for features that were split into +#' `_CS` (Climate-Smart) and `_NCS` (Non-Climate-Smart) components. This +#' provides a single, aggregated representation for the original feature, +#' allowing comparison with its original target. +#' \item `climsmartApproach = 3` (Percentile Approach): The function directly +#' uses the targets provided in the `targets` dataframe, which are +#' expected to be adjusted for the percentile approach. +#' \item For other `climsmartApproach` values or if `climsmart` is `FALSE`, +#' targets are taken directly from the `prioritizr` problem's target data. +#' } +#' +#' The output dataframe is designed to be directly plottable by functions +#' like `splnr_plot_featureRep()`. +#' +#' @param soln An `sf` object representing the `prioritizr` solution, containing +#' a column indicating selected planning units (default: `solution_1`). +#' @param pDat A `prioritizr` problem object, as defined by `prioritizr::problem()`. +#' This object provides the original feature data and targets. +#' @param targets A `data.frame` (optional). If provided, it should contain a +#' `feature` column (character) and a `target` column (numeric). This is used +#' to override or supplement targets from `pDat`, especially for climate-smart +#' approaches where targets might be pre-adjusted. Defaults to `NA`. +#' @param climsmart A logical value (`TRUE` or `FALSE`). If `TRUE`, special +#' handling for climate-smart approaches is enabled. Defaults to `FALSE`. +#' @param climsmartApproach An integer (0, 1, 2, or 3) indicating the type of +#' climate-smart approach used: +#' \itemize{ +#' \item `0`: No climate-smart approach. +#' \item `1`: Climate Priority Area approach (features split into CS/NCS). +#' \item `2`: Feature approach (not explicitly handled in this function's +#' `climsmart` logic, targets taken from `pDat` by default). +#' \item `3`: Percentile approach (features are filtered). +#' } +#' Defaults to `0`. +#' @param solnCol A character string specifying the name of the column in `soln` +#' that contains the binary solution (1 for selected, 0 for not selected). +#' Defaults to `"solution_1"`. +#' +#' @return A `tibble` dataframe containing the `feature` names, their +#' `total_amount` (total units available), `absolute_held` (total units +#' selected), `relative_held` (proportion held), `target` (conservation target), +#' and `incidental` (TRUE if target was 0 or NA, but feature still present). #' @export #' -#' @importFrom rlang .data +#' @importFrom assertthat assert_that +#' @importFrom dplyr arrange bind_rows case_when filter group_by if_else left_join mutate pull select summarise ungroup +#' @importFrom prioritizr eval_feature_representation_summary +#' @importFrom rlang .data sym +#' @importFrom sf st_drop_geometry +#' @importFrom stats na.omit +#' @importFrom stringr str_remove_all +#' @importFrom tibble as_tibble tibble +#' @importFrom tidyselect any_of starts_with everything +#' @importFrom tidyr pivot_longer #' #' @examples -#' pDat <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), -#' features = c("Spp1", "Spp2", "Spp3"), +#' \dontrun{ +#' # Assuming 'dat_species_bin' is an existing sf object with binary species data +#' # and 'Cost' column. +#' +#' # Create a dummy prioritizr problem for basic demonstration +#' pDat_basic <- prioritizr::problem( +#' dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +#' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" #' ) %>% #' prioritizr::add_min_set_objective() %>% @@ -22,145 +104,315 @@ #' prioritizr::add_binary_decisions() %>% #' prioritizr::add_default_solver(verbose = FALSE) #' -#' soln <- pDat %>% +#' # Solve the problem +#' soln_basic <- pDat_basic %>% #' prioritizr::solve.ConservationProblem() #' -#' df <- splnr_get_featureRep( -#' soln = soln, -#' pDat = pDat +#' # Get feature representation for a basic (non-climate-smart) solution +#' df_basic_rep <- splnr_get_featureRep( +#' soln = soln_basic, +#' pDat = pDat_basic #' ) +#' print(df_basic_rep) +#' +#' # Example with Climate Priority Area (CPA) approach +#' # Assuming 'dat_clim' is an sf object with a 'metric' column. +#' # These would typically come from splnr_climate_priorityAreaApproach() +#' # For example purposes, we'll create some dummy data and targets. +#' +#' # Simulate CPA processed features and targets +#' cpa_features_sim <- dat_species_bin %>% +#' dplyr::mutate( +#' Spp1_CS = ifelse(Spp1 == 1 & runif(n()) < 0.5, 1, 0), +#' Spp1_NCS = ifelse(Spp1 == 1 & Spp1_CS == 0, 1, 0), +#' Spp2_CS = ifelse(Spp2 == 1 & runif(n()) < 0.6, 1, 0), +#' Spp2_NCS = ifelse(Spp2 == 1 & Spp2_CS == 0, 1, 0), +#' Spp3_CS = ifelse(Spp3 == 1 & runif(n()) < 0.7, 1, 0), +#' Spp3_NCS = ifelse(Spp3 == 1 & Spp3_CS == 0, 1, 0) +#' ) %>% +#' dplyr::select(Spp1_CS, Spp1_NCS, Spp2_CS, Spp2_NCS, Spp3_CS, Spp3_NCS, geometry) +#' +#' cpa_targets_sim <- data.frame( +#' feature = c("Spp1_CS", "Spp1_NCS", "Spp2_CS", "Spp2_NCS", "Spp3_CS", "Spp3_NCS"), +#' target = c(0.8, 0.2, 0.9, 0.1, 0.7, 0.3) # Example targets for CS/NCS parts +#' ) +#' +#' # Create a problem with the simulated CPA features +#' pDat_cpa_sim <- prioritizr::problem( +#' cpa_features_sim %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +#' features = c("Spp1_CS", "Spp1_NCS", "Spp2_CS", "Spp2_NCS", "Spp3_CS", "Spp3_NCS"), +#' cost_column = "Cost" +#' ) %>% +#' prioritizr::add_min_set_objective() %>% +#' prioritizr::add_relative_targets(cpa_targets_sim$target, cpa_targets_sim$feature) %>% +#' prioritizr::add_binary_decisions() %>% +#' prioritizr::add_default_solver(verbose = FALSE) +#' +#' # Solve the CPA problem +#' soln_cpa_sim <- pDat_cpa_sim %>% +#' prioritizr::solve.ConservationProblem() +#' +#' # Get feature representation for CPA approach +#' df_cpa_rep <- splnr_get_featureRep( +#' soln = soln_cpa_sim, +#' pDat = pDat_cpa_sim, +#' targets = cpa_targets_sim, # Pass the original CPA targets +#' climsmart = TRUE, +#' climsmartApproach = 1 # Indicate CPA approach +#' ) +#' print(df_cpa_rep) +#' } splnr_get_featureRep <- function(soln, pDat, targets = NA, climsmart = FALSE, climsmartApproach = 0, solnCol = "solution_1") { + + # --- Input Assertions --- + # Ensure 'soln' is an sf object and not empty. + assertthat::assert_that( + inherits(soln, "sf"), + msg = "'soln' must be an 'sf' object." + ) + assertthat::assert_that( + nrow(soln) > 0, + msg = "'soln' dataframe must not be empty." + ) + # Ensure 'pDat' is a prioritizr problem object. + assertthat::assert_that( + inherits(pDat, "ConservationProblem"), + msg = "'pDat' must be a 'prioritizr::ConservationProblem' object." + ) + # Ensure 'solnCol' is a character string and exists in 'soln'. + assertthat::assert_that( + is.character(solnCol) && length(solnCol) == 1, + msg = "'solnCol' must be a single character string." + ) + assertthat::assert_that( + solnCol %in% names(soln), + msg = paste0("Solution column '", solnCol, "' not found in 'soln'.") + ) + # Ensure 'climsmart' is logical. + assertthat::assert_that( + is.logical(climsmart) && length(climsmart) == 1, + msg = "'climsmart' must be a single logical value (TRUE or FALSE)." + ) + # Ensure 'climsmartApproach' is a valid integer. + assertthat::assert_that( + is.numeric(climsmartApproach) && length(climsmartApproach) == 1 && climsmartApproach %in% c(0, 1, 2, 3), + msg = "'climsmartApproach' must be an integer (0, 1, 2, or 3)." + ) + # Validate 'targets' if provided (not NA). + if (!all(is.na(targets))) { + assertthat::assert_that( + is.data.frame(targets), + msg = "If 'targets' is provided, it must be a data.frame." + ) + assertthat::assert_that( + all(c("feature", "target") %in% names(targets)), + msg = "If 'targets' is a data.frame, it must contain 'feature' and 'target' columns." + ) + } + + # Extract feature names from the problem data (pDat). + # prioritizr problems store feature names in pDat$data$features[[1]] s_cols <- pDat$data$features[[1]] - # Get data for features not chosen + # --- Process non-selected features (if any) --- + # These are features present in the solution object but NOT part of the + # core features defined in pDat. This often includes 'Cost' or other + # temporary columns, or potentially features with 0 targets. + + # Select columns that are not 'Cost_', 'solution_' or 'metric', and not in s_cols. + # These are considered "not selected" or ancillary features for initial processing. not_selected <- soln %>% dplyr::select( - -tidyselect::starts_with(c("Cost", "solution_")), - -tidyselect::any_of(c("metric")), - -tidyselect::any_of(s_cols) + -tidyselect::starts_with(c("Cost", "solution_")), # Exclude Cost and solution columns + -tidyselect::any_of(c("metric")), # Exclude 'metric' if it exists + -tidyselect::any_of(s_cols) # Exclude primary features defined in pDat ) %>% - sf::st_drop_geometry() + sf::st_drop_geometry() # Drop geometry for numerical operations - ns_cols <- not_selected %>% - colnames() + # Get column names of remaining 'not_selected' features. + ns_cols <- colnames(not_selected) + # Proceed if there are any non-selected features to process. if (length(ns_cols) > 0) { + # Combine non_selected features with the solution column for filtering. ns1 <- not_selected %>% - dplyr::select(c(tidyselect::all_of(ns_cols))) %>% - dplyr::mutate(solution = dplyr::pull(soln, !!rlang::sym(solnCol))) + dplyr::select(tidyselect::all_of(ns_cols)) %>% + dplyr::mutate(solution = dplyr::pull(soln, !!rlang::sym(solnCol))) # Add the solution column + # Calculate the total amount of each non-selected feature. area_feature <- ns1 %>% - dplyr::select(-c("solution")) %>% + dplyr::select(-c("solution")) %>% # Remove solution column for total sum tidyr::pivot_longer(cols = tidyselect::everything(), names_to = "feature", values_to = "total_amount") %>% dplyr::group_by(.data$feature) %>% - dplyr::summarise(total_amount = sum(.data$total_amount)) + dplyr::summarise(total_amount = sum(.data$total_amount, na.rm = TRUE)) # Sum total amount, handling NAs + # Calculate the absolute amount of each non-selected feature in selected units. selected_feature <- ns1 %>% - dplyr::filter(.data$solution == 1) %>% - dplyr::select(-c("solution")) %>% + dplyr::filter(.data$solution == 1) %>% # Filter for selected planning units + dplyr::select(-c("solution")) %>% # Remove solution column for sum tidyr::pivot_longer(cols = tidyselect::everything(), names_to = "feature", values_to = "absolute_held") %>% dplyr::group_by(.data$feature) %>% - dplyr::summarise(absolute_held = sum(.data$absolute_held)) + dplyr::summarise(absolute_held = sum(.data$absolute_held, na.rm = TRUE)) # Sum absolute held, handling NAs + # Join total and selected amounts and calculate relative held. ns1 <- dplyr::left_join(area_feature, selected_feature, by = "feature") %>% dplyr::mutate( - relative_held = (.data$absolute_held / .data$total_amount) + relative_held = dplyr::if_else( + .data$total_amount > 0, # Avoid division by zero + .data$absolute_held / .data$total_amount, + 0 # Set to 0 if total_amount is 0 + ) ) } else { + # If no non-selected features, create an empty tibble with required columns. + message("No non-selected features to process.") ns1 <- tibble::tibble( - feature = "DummyVar", - total_amount = 0, - absolute_held = 0, - relative_held = 0 + feature = character(), + total_amount = numeric(), + absolute_held = numeric(), + relative_held = numeric() ) } - ## Now do the selected features + # --- Process primary selected features (from pDat) --- - s1 <- soln %>% - dplyr::rename(solution = !!rlang::sym(solnCol)) %>% - tibble::as_tibble() + # Create a tibble with the solution column from the soln sf object. + # This is needed as eval_feature_representation_summary expects a data.frame. + soln_df <- soln %>% + dplyr::rename(solution = !!rlang::sym(solnCol)) %>% # Rename solution column to 'solution' + tibble::as_tibble() # Convert to tibble for prioritizr function - s1 <- prioritizr::eval_feature_representation_summary(pDat, s1[, "solution"]) %>% - dplyr::select(-"summary") + # Evaluate feature representation summary using prioritizr's internal function. + s1 <- prioritizr::eval_feature_representation_summary(pDat, soln_df[, "solution"]) %>% + dplyr::select(-"summary") # Remove the 'summary' column, which is not needed here. - if (climsmart == TRUE & climsmartApproach == 1) { + # --- Apply Climate-Smart Logic --- + + # If climate-smart approach is enabled and is CPA (Approach 1). + if (climsmart == TRUE && climsmartApproach == 1) { + message("Processing features with Climate Priority Area (CPA) approach.") s1 <- s1 %>% - dplyr::select(-.data$relative_held) %>% + dplyr::select(-.data$relative_held) %>% # Remove existing relative_held for recalculation + # Remove _CS and _NCS suffixes to group related features. dplyr::mutate( feature = stringr::str_remove_all(.data$feature, "_CS"), feature = stringr::str_remove_all(.data$feature, "_NCS") - ) %>% # Ensure all features have the same name. - dplyr::group_by(.data$feature) %>% + ) %>% + dplyr::group_by(.data$feature) %>% # Group by original feature names dplyr::summarise( - total_amount = sum(.data$total_amount), # Sum the features together - absolute_held = sum(.data$absolute_held) + total_amount = sum(.data$total_amount, na.rm = TRUE), # Sum total amounts for original feature + absolute_held = sum(.data$absolute_held, na.rm = TRUE) # Sum absolute held for original feature ) %>% dplyr::ungroup() %>% - dplyr::mutate(relative_held = .data$absolute_held / .data$total_amount) %>% # Calculate proportion - # dplyr::select(-"total_amount", -"absolute_held") %>% # Remove extra columns - dplyr::left_join(targets, by = "feature") #%>% # Add targets to df - # dplyr::select(-"type") - - } else if (climsmart == TRUE & climsmartApproach == 3) { + # Recalculate relative held for the aggregated feature. + dplyr::mutate(relative_held = dplyr::if_else( + .data$total_amount > 0, + .data$absolute_held / .data$total_amount, + 0 + )) %>% + # Join with the provided 'targets' dataframe for CPA. + # This assumes 'targets' dataframe contains adjusted targets for original features. + dplyr::left_join(targets, by = "feature") + } else if (climsmart == TRUE && climsmartApproach == 3) { + # If climate-smart approach is enabled and is Percentile Approach (Approach 3). + message("Processing features with Percentile Climate-Smart Approach.") + # For percentile approach, directly join with provided 'targets' as they are + # assumed to be already adjusted for the filtered features. s1 <- s1 %>% dplyr::left_join(targets, by = "feature") } else { - # Add targets to df + # Default case: no climate-smart approach or other approaches. + # Targets are taken directly from the prioritizr problem object. + message("No specific climate-smart approach detected or standard approach used. Using targets from 'pDat'.") s1 <- s1 %>% dplyr::left_join(pDat$targets$data[["targets"]], by = "feature") %>% - dplyr::select(-"type") + dplyr::select(-"type") # Remove 'type' column from prioritizr targets if it exists. } + # Remove rows with NA in 'relative_held' which might occur if total_amount was zero. s1 <- s1 %>% - dplyr::mutate( - relative_held = .data$relative_held - ) %>% - stats::na.omit() + stats::na.omit() # Remove any rows with NAs (e.g., if target was NA and not handled by above logic) + # --- Combine and Finalize Results --- - # Now join the selected and non-selected values - if ((length(ns_cols) > 0)) { # Only if there are values in ns1 - df <- dplyr::bind_rows(s1, ns1) - } else { - df <- s1 - } + # Bind rows of primary features (s1) and non-selected features (ns1). + # This ensures all features are represented in the final output. + df <- dplyr::bind_rows(s1, ns1) - # Now add in incidental for 0 and NA targets + # Add an 'incidental' flag: TRUE if a feature was included but its target was 0 or NA. + # This helps distinguish features intentionally targeted from those incidentally selected. df <- df %>% - dplyr::mutate(incidental = dplyr::if_else(target > 0 & absolute_held > 0, FALSE, TRUE, missing = TRUE)) + dplyr::mutate( + incidental = dplyr::if_else( + .data$target > 0 & .data$absolute_held > 0, # If target > 0 AND something was held, it's NOT incidental + FALSE, + TRUE, # Otherwise, it's incidental (target 0, NA, or target > 0 but nothing held) + missing = TRUE # Explicitly handle missing values for 'target' + ) + ) return(df) } - - -# Targets Bar Plot -------------------------------------------------------- - - - -#' Plot how well targets are met +#' @title Plot Feature Representation (Target Achievement) #' -#' @param df A `df` containing the target information (resulting from the splnr_get_featureRep() function) -#' @param nr Number of rows of the legend -#' @param plotTitle A character value for the title of the plot. Can be empty (""). -#' @param category A named data frame of feature and category for grouping the plot output -#' @param categoryFeatureCol A character with the column containing the feature infromation to be plotted if the category data frame does not contain a column named 'feature' that can be matched with the 'df' infromation. -#' @param renameFeatures A logical on whether variable names should be used or they should be replaced with common names -#' @param namesToReplace A data frame containing the variable name ('nameVariable') and a common name ('nameCommon'). -#' @param showTarget `logical` Should the targets be shown on the bar plot -#' @param ... Other arguments passed on to `ggplot2::theme()` +#' @description +#' `splnr_plot_featureRep()` creates a bar plot to visualize the representation +#' of features in a conservation solution, indicating how well targets are met. +#' It can categorize features, rename them for clarity, and optionally display +#' the target levels on the plot. #' -#' @return A ggplot object of the plot +#' @param df A [data.frame][base::data.frame] or [tibble][tibble::tibble] +#' containing the feature representation information. This typically +#' results from the `splnr_get_featureRep()` function and should include at +#' least `feature` and `relative_held` columns, and optionally `target` and `incidental`. +#' @param category A named [data.frame][base::data.frame] or [tibble][tibble::tibble] +#' that provides grouping information for features. It should contain a column +#' that can be matched with the `feature` column in `df` (by default, a column +#' named `feature`, or specified by `categoryFeatureCol`), and a column named +#' `category` for grouping the plot output. If `NA` (default), no categorization is applied. +#' @param categoryFeatureCol A [character][base::character] string specifying the +#' name of the column in the `category` data frame that contains the feature +#' information to be matched with `df$feature`. This is used if the `category` +#' data frame does not have a column explicitly named `'feature'`. +#' @param renameFeatures A [logical][base::logical] value. If `TRUE`, feature names +#' in the plot will be replaced with common names provided in `namesToReplace`. +#' @param namesToReplace A [data.frame][base::data.frame] containing two columns: +#' `'nameVariable'` (the original feature name) and `'nameCommon'` (the common name +#' to replace it with). Required if `renameFeatures` is `TRUE`. +#' @param nr An [integer][base::integer] specifying the number of rows for the legend. +#' @param showTarget A [logical][base::logical] value. If `TRUE`, a transparent bar +#' representing the target level for each feature will be shown on the plot. +#' @param plotTitle A [character][base::character] string for the title of the plot. +#' Can be an empty string `""` (default). +#' @param sort_by A [character][base::character] string specifying the column +#' by which to sort the features on the x-axis. Accepted values include: +#' `"category"`, `"feature"`, `"target"`, `"representation"` (`relative_held`), +#' or `"difference"` (between representation and target). +#' @param ... Other arguments passed on to [ggplot2::theme()] to customize the plot's theme. +#' +#' @return A [ggplot2::ggplot] object representing the feature representation bar plot. #' @export +#' @importFrom assertthat assert_that +#' @importFrom dplyr arrange bind_rows filter if_else left_join mutate rename select +#' @importFrom ggplot2 aes element_blank element_rect element_text geom_bar ggplot labs +#' @importFrom ggplot2 guide_legend guides scale_fill_manual scale_y_continuous theme theme_bw +#' @importFrom rlang .data +#' @importFrom stringr str_c str_replace_all +#' @importFrom stats reorder +#' @importFrom tibble deframe tibble #' #' @examples +#' # For a full example, ensure 'dat_species_bin', 'dat_category' are available +#' # (e.g., from the 'prioritizrdata' package or defined in your package's data) +#' +#' #' pDat <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), #' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" @@ -173,15 +425,29 @@ splnr_get_featureRep <- function(soln, pDat, targets = NA, #' soln <- pDat %>% #' prioritizr::solve.ConservationProblem() #' -#' #' # including incidental species coverage -#' df <- splnr_get_featureRep( +#' df <- splnr_get_featureRep( # Assuming splnr_get_featureRep is available #' soln = soln, #' pDat = pDat #' ) #' +#' # Basic plot with categories and targets shown #' (splnr_plot_featureRep(df, category = dat_category, showTarget = TRUE)) #' +#' # Plot without categories, sorted by feature name +#' (splnr_plot_featureRep(df, showTarget = TRUE, sort_by = "feature")) +#' +#' # Example with feature renaming +#' names_to_replace_df <- tibble::tibble( +#' nameVariable = c("Spp1", "Spp2"), +#' nameCommon = c("Species One", "Species Two") +#' ) +#' (splnr_plot_featureRep(df, +#' category = dat_category, +#' renameFeatures = TRUE, +#' namesToReplace = names_to_replace_df, +#' showTarget = TRUE +#' )) splnr_plot_featureRep <- function(df, category = NA, categoryFeatureCol = NA, @@ -193,64 +459,87 @@ splnr_plot_featureRep <- function(df, sort_by = "category", ...) { - # TODO Add to documentation - # sort_by = "category", - # "difference", - # "target", - # "feature" "feature" - # "representation" "relative_held" - assertthat::assert_that( inherits(df, c("data.frame", "tbl_df")), is.logical(renameFeatures), is.logical(showTarget), is.character(plotTitle), - all(colSums(is.na(category)) == nrow(category)) || inherits(category, c("data.frame","tbl","tbl_df")) + # Check if category is NA-filled or a data frame/tibble + all(is.na(category)) || inherits(category, c("data.frame", "tbl", "tbl_df")), + is.numeric(nr), # nr should be numeric + # Validate sort_by against allowed values + sort_by %in% c("category", "feature", "target", "difference", "representation", "relative_held"), + msg = "Invalid 'sort_by' value. Must be one of 'category', 'feature', 'target', 'difference', 'representation', or 'relative_held'." ) if (renameFeatures) { assertthat::assert_that( is.data.frame(namesToReplace), "nameVariable" %in% colnames(namesToReplace), - "nameCommon" %in% colnames(namesToReplace) + "nameCommon" %in% colnames(namesToReplace), + msg = paste0( + "When 'renameFeatures' is TRUE, 'namesToReplace' must be a data frame ", + "with 'nameVariable' and 'nameCommon' columns." + ) ) } - if(inherits(category, c("df", "tbl_df")) & !("feature" %in% colnames(category))) { - if (!(inherits(categoryFeatureCol, "character"))) { - cat("There is no column called 'feature' in your category data frame. Please provide a column name that should be renamed to 'feature'."); - } else { - category <- category %>% - dplyr::rename(feature = categoryFeatureCol) - }} + if (inherits(category, c("data.frame", "tbl_df")) & !("feature" %in% colnames(category))) { + assertthat::assert_that( + is.character(categoryFeatureCol) && length(categoryFeatureCol) == 1, + categoryFeatureCol %in% colnames(category), + msg = paste0( + "If 'category' is a data frame and does not have a 'feature' column, ", + "'categoryFeatureCol' must be a character string specifying the column ", + "in 'category' that contains feature information." + ) + ) + category <- category %>% + dplyr::rename(feature = categoryFeatureCol) + } - if (renameFeatures == TRUE) { - assertthat::assert_that(is.data.frame(namesToReplace)) #sanity check + # Check if 'viridis' package is installed. If not, stop with an informative error. + if (requireNamespace("viridis", quietly = TRUE) == FALSE){ + stop("To run splnr_plot_featureRep you will need to install the 'viridis' package: install.packages('viridis').") + } + + + if (renameFeatures == TRUE) { + # No assertthat::assert_that(is.data.frame(namesToReplace)) needed here, + # as it's covered by the initial assertthat block. rpl <- namesToReplace %>% dplyr::filter(.data$nameVariable %in% df$feature) %>% dplyr::select("nameVariable", "nameCommon") %>% - dplyr::mutate(nameVariable = stringr::str_c("^", nameVariable, "$")) %>% + dplyr::mutate(nameVariable = stringr::str_c("^", .data$nameVariable, "$")) %>% tibble::deframe() df <- df %>% dplyr::mutate(feature = stringr::str_replace_all(.data$feature, rpl)) - category <- category %>% - dplyr::mutate(feature = stringr::str_replace_all(.data$feature, rpl)) - + # Only attempt to rename features in category if category is actually provided + if (inherits(category, c("data.frame", "tbl_df")) && "feature" %in% colnames(category)) { + category <- category %>% + dplyr::mutate(feature = stringr::str_replace_all(.data$feature, rpl)) + } } - if (inherits(category, c("df", "tbl_df")) & ("feature" %in% colnames(category))) { + if (inherits(category, c("data.frame", "tbl_df")) & ("feature" %in% colnames(category))) { df <- df %>% dplyr::left_join(category, by = "feature") %>% dplyr::arrange(.data$category, .data$feature) %>% dplyr::mutate(feature = factor(.data$feature, levels = .data$feature)) + } else { + # If no category is provided or matched, ensure 'category' column exists for plotting + if (!("category" %in% colnames(df))) { + df <- df %>% dplyr::mutate(category = "Uncategorized") + } } - if (max(df$relative_held < 1)) { + + if (max(df$relative_held, na.rm = TRUE) < 1) { # Check max before multiplying df <- df %>% dplyr::mutate( relative_held = .data$relative_held * 100, @@ -258,6 +547,26 @@ splnr_plot_featureRep <- function(df, ) } + # Ensure 'sort_by' columns exist before use + if (sort_by == "difference" && !("target" %in% colnames(df) && "relative_held" %in% colnames(df))) { + stop("Cannot sort by 'difference': 'target' and/or 'relative_held' columns are missing.") + } + if (sort_by == "representation" && !("relative_held" %in% colnames(df))) { + stop("Cannot sort by 'representation': 'relative_held' column is missing.") + } + if (sort_by == "target" && !("target" %in% colnames(df))) { + stop("Cannot sort by 'target': 'target' column is missing.") + } + + # Calculate 'difference' and 'representation' if sorting by them + if (sort_by %in% c("difference", "representation")) { + df <- df %>% + dplyr::mutate( + difference = .data$relative_held - .data$target, + representation = .data$relative_held + ) + } + uniqueCat <- unique(df$category[!is.na(df$category)]) colr <- tibble::tibble( @@ -266,26 +575,28 @@ splnr_plot_featureRep <- function(df, ) %>% tibble::deframe() - -if (!sort_by %in% c("category", "feature", "target")){ - df <- df %>% - dplyr::mutate(difference = relative_held - target, - representation = relative_held) -} - - gg_target <- ggplot2::ggplot() + - ggplot2::geom_bar(data = df %>% dplyr::mutate(relative_held = dplyr::if_else(incidental == TRUE, NA, relative_held)), - stat = "identity", position = "identity", - ggplot2::aes(x = stats::reorder(.data$feature, .data[[sort_by]]), y = .data$relative_held, - fill = .data$category, colour = .data$category), - na.rm = TRUE) + - ggplot2::geom_bar(data = df %>% dplyr::mutate(relative_held = dplyr::if_else(incidental == FALSE, NA, relative_held)), - stat = "identity", position = "identity", - ggplot2::aes(x = .data$feature, y = .data$relative_held), na.rm = TRUE, fill = "NA", colour = "black") + + ggplot2::geom_bar( + data = df %>% dplyr::mutate(relative_held = dplyr::if_else(.data$incidental == TRUE, NA_real_, .data$relative_held)), # Use NA_real_ for numeric NA + stat = "identity", position = "identity", + ggplot2::aes( + x = stats::reorder(.data$feature, .data[[sort_by]]), y = .data$relative_held, + fill = .data$category, colour = .data$category + ), + na.rm = TRUE + ) + + ggplot2::geom_bar( + data = df %>% dplyr::mutate(relative_held = dplyr::if_else(.data$incidental == FALSE, NA_real_, .data$relative_held)), # Use NA_real_ + stat = "identity", position = "identity", + ggplot2::aes(x = .data$feature, y = .data$relative_held), na.rm = TRUE, fill = "NA", colour = "black" + ) + ggplot2::labs(title = plotTitle, x = "Feature", y = "Representation of features \nin total selected area (%)") + ggplot2::theme_bw() + - ggplot2::scale_y_continuous(limits = c(0, ymax <- max(df$relative_held, na.rm = TRUE) + 10), expand = c(0, 0)) + # only works for min shortfall without incidental yet + # Ensure ymax is calculated correctly and handled for empty df + ggplot2::scale_y_continuous( + limits = c(0, max(df$relative_held, na.rm = TRUE, 0) + 10), # Ensure at least 0 if all NA + expand = c(0, 0) + ) + ggplot2::scale_fill_manual( aesthetics = c("fill", "colour"), values = colr, @@ -300,51 +611,71 @@ if (!sort_by %in% c("category", "feature", "target")){ legend.title = ggplot2::element_blank(), legend.text = ggplot2::element_text(size = 16), legend.position = "top", - # legend.margin = ggplot2::margin(0, 0, 0, 0), - # legend.justification.top = "centre", - # legend.position.inside = c(0.5, 0.92), legend.direction = "horizontal", legend.background = ggplot2::element_rect(fill = "NA"), title = ggplot2::element_text(size = 16), ... ) - if (!(is.na(showTarget))) { + if (!(is.na(showTarget)) && showTarget == TRUE) { # Explicitly check for TRUE + assertthat::assert_that( + "target" %in% colnames(df), + msg = "Cannot show target: 'target' column is missing from the data frame." + ) gg_target <- gg_target + - - ggplot2::geom_bar(data = df %>% dplyr::mutate(relative_held = dplyr::if_else(incidental == TRUE, NA, relative_held)), - stat = "identity", position = "identity", ggplot2::aes(x = .data$feature, y = .data$target), na.rm = TRUE, - alpha = 0.3, colour = "grey50", fill = "white") + ggplot2::geom_bar( + data = df %>% dplyr::mutate(relative_held = dplyr::if_else(.data$incidental == TRUE, NA_real_, .data$relative_held)), # Use NA_real_ + stat = "identity", position = "identity", ggplot2::aes(x = .data$feature, y = .data$target), na.rm = TRUE, + alpha = 0.3, colour = "grey50", fill = "white" + ) } return(gg_target) } - -# Circular Bar Plot ------------------------------------------------------- - - - -#' Plot circular barplot -# Inputs: -#' @param df data frame that should have the following column names: feature, value, group -# feature: individual bars -# value: value plotted in the y-axis -# group: grouping factors -#' @param legend_color vector list of colors; should have the group names and their corresponding colors -#' @param legend_list list of groups/legends of groups -#' @param indicateTargets logical on whether to show where the targets were set -#' @param impTarget target of the important features (in %) -#' @param repTarget target of the representative features (in %) -#' @param colTarget string with a colour value for the indicator line +#' @title Plot Circular Barplot for Feature Representation +#' +#' @description +#' `splnr_plot_circBplot()` creates a circular bar plot to visualize feature +#' representation, categorized by groups. It's particularly useful for +#' displaying how different categories of features meet certain targets in a radial layout. +#' +#' @param df A [data.frame][base::data.frame] or [tibble][tibble::tibble] that +#' **must** contain the following columns: +#' \itemize{ +#' \item `feature`: [character][base::character] or [factor][base::factor] unique identifier for each individual bar (e.g., species names). +#' \item `value`: [numeric][base::numeric] the value to be plotted on the y-axis (bar height, typically percentage representation). +#' \item `group`: [character][base::character] or [factor][base::factor] for grouping factors (e.g., "important", "representative"). +#' } +#' @param legend_color A [named vector][base::vector] of colors. Names must correspond +#' to the unique values in the `group` column of `df`, and values are the +#' corresponding colors. For example: `c("group_name1" = "red", "group_name2" = "blue")`. +#' @param legend_list A [character vector][base::character] of labels for the legend. +#' This should match the names used in `legend_color` or the levels of `group`. +#' @param indicateTargets A [logical][base::logical] value. If `TRUE`, horizontal +#' lines indicating `impTarget` and `repTarget` will be drawn on the plot. +#' @param impTarget A [numeric][base::numeric] value representing the target +#' percentage for 'important' features. Required if `indicateTargets` is `TRUE`. +#' @param repTarget A [numeric][base::numeric] value representing the target +#' percentage for 'representative' features. Required if `indicateTargets` is `TRUE`. +#' @param colTarget A [character][base::character] string specifying the color +#' for the target indicator lines. #' -#' @return A ggplot object of the plot +#' @return A [ggplot2::ggplot] object of the circular bar plot. #' @export +#' @importFrom assertthat assert_that +#' @importFrom dplyr arrange bind_rows group_by mutate rowwise summarize +#' @importFrom ggplot2 aes annotate coord_polar element_blank geom_abline geom_bar geom_segment +#' @importFrom ggplot2 geom_text ggplot guides labs scale_fill_manual theme theme_minimal unit ylim +#' @importFrom stats na.omit +#' @importFrom tibble as_tibble tibble #' #' @examples #' # DISCLAIMER: THIS SOLUTION IS NOT ACTUALLY RUN WITH THESE TARGETS YET #' +#' \dontrun{ +#' #' dat_problem <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), #' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" @@ -362,6 +693,7 @@ if (!sort_by %in% c("category", "feature", "target")){ #' #' p1 <- dat_problem #' +#' # Assuming eval_feature_representation_summary is from prioritizr #' df_rep_imp <- prioritizr::eval_feature_representation_summary( #' p1, #' s1[, "solution_1"] @@ -381,7 +713,7 @@ if (!sort_by %in% c("category", "feature", "target")){ #' #' df <- merge(df_rep_imp, target) %>% #' dplyr::select(-target) %>% -#' na.omit() %>% +#' stats::na.omit() %>% # Use stats::na.omit #' dplyr::rename(value = relative_held) %>% #' dplyr::rename(group = class) #' @@ -396,18 +728,47 @@ if (!sort_by %in% c("category", "feature", "target")){ #' legend_color = colors, #' impTarget = 50, repTarget = 30 #' )) +#' } splnr_plot_circBplot <- function(df, legend_color, legend_list, indicateTargets = TRUE, impTarget = NA, repTarget = NA, colTarget = "red") { + # assertthat checks for initial inputs + assertthat::assert_that( + inherits(df, c("data.frame", "tbl_df")), + "feature" %in% colnames(df), + "value" %in% colnames(df), + "group" %in% colnames(df), + is.numeric(df$value), + msg = "Input 'df' must be a data frame or tibble with 'feature', 'value', and 'group' columns, and 'value' must be numeric." + ) + assertthat::assert_that( + is.vector(legend_color) && !is.null(names(legend_color)), + all(unique(df$group) %in% names(legend_color)), + msg = "'legend_color' must be a named vector where names match unique 'group' values in 'df'." + ) + + assertthat::assert_that( + is.character(legend_list), length(unique(names(legend_color))) == length(legend_list), + msg = "'legend_list' must be a character vector with the same number of elements as unique names in 'legend_color'." + ) + + assertthat::assert_that( is.logical(indicateTargets), - is.numeric(impTarget), - is.numeric(repTarget), - is.character(colTarget) + is.character(colTarget), + msg = "'indicateTargets' must be logical and 'colTarget' must be a character string." ) + if (indicateTargets) { + assertthat::assert_that( + is.numeric(impTarget) && length(impTarget) == 1 && !is.na(impTarget), + is.numeric(repTarget) && length(repTarget) == 1 && !is.na(repTarget), + msg = "When 'indicateTargets' is TRUE, 'impTarget' and 'repTarget' must be single non-NA numeric values." + ) + } + # Adding rows to each group, creating space between the groups groups <- unique(df$group) NA_rows <- list() @@ -445,7 +806,7 @@ splnr_plot_circBplot <- function(df, legend_color, legend_list, # For the percentage lines grid_data <- data %>% dplyr::group_by(.data$group) %>% - dplyr::summarize(start = min(.data$id), end = max(.data$id) - empty_bar) %>% + dplyr::summarize(start = min(.data$id), end = max(.data$id) - empty_bar, .groups = "drop") %>% # Added .groups = "drop" for dplyr > 1.0.0 dplyr::rowwise() %>% dplyr::mutate(title = mean(c(.data$start, .data$end))) grid_data$end <- grid_data$end[c(nrow(grid_data), 1:nrow(grid_data) - 1)] + 1.5 @@ -456,9 +817,10 @@ splnr_plot_circBplot <- function(df, legend_color, legend_list, p <- ggplot2::ggplot(data, ggplot2::aes(x = as.factor(.data$id), y = .data$value, fill = .data$group)) + # plotting the bars - ggplot2::geom_bar(ggplot2::aes(x = as.factor(.data$id), y = .data$value, fill = .data$group), - stat = "identity", - position = "dodge" + ggplot2::geom_bar( + ggplot2::aes(x = as.factor(.data$id), y = .data$value, fill = .data$group), + stat = "identity", + position = "dodge" ) + # defining colors of the bars @@ -507,13 +869,13 @@ splnr_plot_circBplot <- function(df, legend_color, legend_list, label = c(25, 50, 75, 100), color = "grey50", size = 4, - angle = 0, #-5 + angle = 0, # -5 fontface = "bold", hjust = 0.5 ) + # setting limitations of actual plot - ggplot2::ylim(-130, 130) + #-140, 130 + ggplot2::ylim(-130, 130) + # -140, 130 ggplot2::theme_minimal() + ggplot2::coord_polar() + ggplot2::geom_text( @@ -525,10 +887,6 @@ splnr_plot_circBplot <- function(df, legend_color, legend_list, inherit.aes = FALSE ) + - # # Defining colors of these lines - # ggplot2::scale_color_manual(name = "Features", - # values = palette) + - ggplot2::theme( legend.position = "bottom", axis.text = ggplot2::element_blank(), @@ -538,11 +896,10 @@ splnr_plot_circBplot <- function(df, legend_color, legend_list, ) if (indicateTargets == TRUE) { - if (is.na(impTarget) | is.na(repTarget)) { - print("Please provide the targets you want to indicate.") - } + # assertthat check ensures impTarget and repTarget are non-NA numeric here p <- p + ggplot2::geom_abline(slope = 0, intercept = impTarget, col = colTarget, lty = 2) + ggplot2::geom_abline(slope = 0, intercept = repTarget, col = colTarget, lty = 2) } + return(p) } diff --git a/R/splnr_get_IUCNRedList.R b/R/splnr_get_IUCNRedList.R index 1d91ca5e..f0798468 100644 --- a/R/splnr_get_IUCNRedList.R +++ b/R/splnr_get_IUCNRedList.R @@ -1,64 +1,112 @@ -#' Match Species to IUCN RedList +#' @title Match Species to IUCN RedList Categories #' +#' @description +#' The `splnr_get_IUCNRedList` function retrieves IUCN Red List category information +#' for a given set of species and appends it to your input dataframe. #' -#' First of all you will need your own API key, an alphanumeric string provided by IUCN that you need to send in every request; -#' the following function takes you to their website, where you will need to fill up a form (it might take 1-2 days to receive your key) -#' rl_use_iucn() - -#' Once you receive an email with your API key, set it up as an environmental variable (it MUST be named IUCN_REDLIST_KEY) -#' you will need to re-do this step everytime you restart R - -#' Sys.setenv(IUCN_REDLIST_KEY = "") OR add IUCN_REDLIST_KEY = "" to your .Renviron file to permanently set it -#' Sys.getenv("IUCN_REDLIST_KEY") #' check - -#' Not Evaluated -#' DD: Data Deficient -#' LC: Least Concern -#' NT: Near Threatened -#' VU: Vulnerable -#' EN: Endangered -#' CR: Critically Endangered -#' EW: Extinct in the Wild -#' EX: Extinct -#' LRlc: Low risk – least concern -#' LRnt: Low risk – near threatened -#' LRcd: Low risk - conservation dependent - -#' Categories we care about -#' cate <- c("EX","EW","CR","EN","VU") -#' @param df The dataframe containing the species to be matched with the IUCN redlist -#' @param species_col A string name for the column containting the species name +#' @details +#' To use this function, you must first obtain an API key from IUCN. This is an +#' alphanumeric string required for every request. You can visit the IUCN website +#' to request a key using `rl_use_iucn()`. Please note that receiving your key +#' might take 1-2 days after submitting the form. +#' +#' Once you receive your API key, it is crucial to set it as an environment variable +#' named `IUCN_REDLIST_KEY`. You can do this temporarily for the current R session +#' using `Sys.setenv(IUCN_REDLIST_KEY = "YOUR_API_KEY_HERE")`. To set it permanently, +#' you should add `IUCN_REDLIST_KEY = "YOUR_API_KEY_HERE"` to your `.Renviron` file. +#' You can check if the key is set correctly using `Sys.getenv("IUCN_REDLIST_KEY")`. #' -#' @return A dataframe with an additional column `IUCN_Category` +#' The IUCN Red List uses various categories to assess extinction risk. This function +#' queries the Red List for the following categories: +#' \itemize{ +#' \item \strong{DD}: Data Deficient +#' \item \strong{LC}: Least Concern +#' \item \strong{NT}: Near Threatened +#' \item \strong{VU}: Vulnerable +#' \item \strong{EN}: Endangered +#' \item \strong{CR}: Critically Endangered +#' \item \strong{EW}: Extinct in the Wild +#' \item \strong{EX}: Extinct +#' \item \strong{LRlc}: Lower Risk / least concern (old category) +#' \item \strong{LRnt}: Lower Risk / near threatened (old category) +#' \item \strong{LRcd}: Lower Risk / conservation dependent (old category) +#' } +#' The function will attempt to match your species against any of these categories +#' present in the IUCN Red List database. +#' +#' @param df The input dataframe containing the species names to be matched. +#' @param species_col A character string specifying the name of the column in `df` +#' that contains the species scientific names (e.g., "Species" or "scientific_name"). +#' Defaults to "Species". +#' +#' @return A dataframe identical to the input `df`, but with an additional column +#' named `IUCN_Category`. If a species is not found on the IUCN Red List, its +#' `IUCN_Category` will be `NA`. #' @export #' #' @importFrom rlang := #' @importFrom rlang .data +#' @importFrom purrr map_df +#' @importFrom dplyr select rename left_join +#' @importFrom assertthat assert_that #' #' @examples #' \dontrun{ -#' df <- data.frame(Species = c("Diomedea exulans", "Hippocampus kuda", "Squatina squatina")) %>% +#' # Ensure your IUCN_REDLIST_KEY is set as an environment variable before running. +#' # For example: Sys.setenv(IUCN_REDLIST_KEY = "YOUR_API_KEY_HERE") +#' +#' # Example: Create a dataframe with species names and retrieve their IUCN Red List categories. +#' df_species_redlist <- data.frame(Species = c("Diomedea exulans", +#' "Hippocampus kuda", +#' "Squatina squatina")) %>% #' splnr_get_IUCNRedList() +#' print(df_species_redlist) +#' +#' # Example with a different column name for species +#' df_alt_col <- data.frame(ScientificName = c("Panthera leo", "Orcinus orca")) %>% +#' splnr_get_IUCNRedList(species_col = "ScientificName") +#' print(df_alt_col) #' } splnr_get_IUCNRedList <- function(df, species_col = "Species") { + # Assertions to validate input parameters. assertthat::assert_that( inherits(df, "data.frame"), + msg = "The 'df' parameter must be a data.frame." + ) + assertthat::assert_that( is.character(species_col), - species_col %in% names(df) + msg = "The 'species_col' parameter must be a character string." + ) + assertthat::assert_that( + species_col %in% names(df), + msg = paste0("The specified 'species_col' (\"", species_col, "\") does not exist in the input dataframe.") + ) + assertthat::assert_that( + nchar(Sys.getenv("IUCN_REDLIST_KEY")) > 0, + msg = "IUCN_REDLIST_KEY environment variable is not set. Please set your IUCN API key using Sys.setenv(IUCN_REDLIST_KEY = 'YOUR_KEY') or add it to your .Renviron file." ) - # Get all IUCN categories + #TODO add check for rredlist package + + # Define all possible IUCN Red List categories to retrieve data for. cate <- c("DD", "LC", "NT", "VU", "EN", "CR", "EW", "EX", "LRlc", "LRnt", "LRcd") - # Download all the data for those categories - RL <- purrr::map_df(cate, function(x) data.frame(rredlist::rl_sp_category(x))) %>% + # Download all data for the defined categories using rredlist::rl_categories. + # The map_df function iterates through each category, fetches species, and combines them into a single dataframe. + RL <- purrr::map_df(cate, function(x) data.frame(rredlist::rl_categories(x))) %>% + # Select only the 'category' and 'result.scientific_name' columns. dplyr::select("category", "result.scientific_name") %>% + # Rename the selected columns to match the input dataframe's species column name + # and a new column for the IUCN category for clarity. dplyr::rename(!!species_col := .data$result.scientific_name, IUCN_Category = .data$category ) - # Now try and link the species to the categories - only links 2 % + # Perform a left join to link the species in the input dataframe to their + # corresponding IUCN Red List categories. Species not found will have NA in IUCN_Category. df <- df %>% dplyr::left_join(RL, by = species_col) + + return(df) } diff --git a/R/splnr_get_MPAs.R b/R/splnr_get_MPAs.R index 47e75bb9..78a8c0ab 100644 --- a/R/splnr_get_MPAs.R +++ b/R/splnr_get_MPAs.R @@ -1,26 +1,86 @@ -#' Get marine parks from the WDPA. +#' @title Get Marine Protected Areas (MPAs) from WDPA #' -#' This code is a wrapper for the wonderful `wdpar` package written by Jeffrey O. Hanson. This data is then interfaced with the planning units. -#' An `sf` object is returned with the PU area covered by the selected marine protected areas. +#' @description +#' This function serves as a wrapper for the `wdpar` package, facilitating the +#' retrieval of Marine Protected Areas (MPAs) from the World Database on Protected +#' Areas (WDPA) and intersecting them with provided planning units. +#' The result is an `sf` object indicating the area of planning units covered by +#' the selected marine protected areas. #' -#' @param PlanUnits Planning Units as an `sf` object -#' @param Countries A character vector of the countries for which to extract MPAs. To get all MPAs, use `"global"` here. -#' @param Status The status field in the WDPA provides information on whether a protected area has been established, designated, or proposed at the time the data was submitted. -#' @param Desig The designation type is the category or type of protected area as legally/officially designated or proposed. -#' @param Category Stores the IUCN Protected Area Management Categories (recorded in field IUCN_CAT) for each of the protected areas where these categories are reported -#' @param ... Other arguments passed to `wdpa_fetch()` +#' @details +#' This function leverages the robust capabilities of the `wdpar` package by +#' Jeffrey O. Hanson to access and process WDPA data. It allows filtering of MPAs +#' based on country, status, designation type, and IUCN category, and then +#' spatially intersects these MPAs with your defined planning units. #' -#' @return A `sf` object with the MPAs intersected with the planning units +#' For a comprehensive understanding of the WDPA data fields: +#' \itemize{ +#' \item \strong{Status}: Refers to the establishment, designation, or proposal +#' status of a protected area at the time of data submission. Valid options +#' include "Designated", "Established", "Inscribed", "Proposed", and "Adopted". +#' \item \strong{Desig} (Designation Type): Categorizes the legal or official +#' designation of the protected area. Valid options include "National", +#' "Regional", "International", and "Not Applicable". +#' \item \strong{Category} (IUCN Protected Area Management Categories): Represents +#' the IUCN management categories for protected areas. Valid options include +#' "Ia", "Ib", "II", "III", "IV", "V", "VI", "Not Reported", "Not Applicable", +#' and "Not Assigned". +#' } +#' +#' @param PlanUnits An `sf` object representing the planning units to be used for intersection. +#' This object should have a valid CRS defined. +#' @param Countries A character vector specifying the countries for which to extract MPAs. +#' To retrieve all global MPAs, use the value `"global"`. Country names should match +#' those recognized by the WDPA database. +#' @param Status A character vector specifying the desired status of protected areas +#' to include. Defaults to `c("Designated", "Established", "Inscribed")`. +#' @param Desig A character vector specifying the desired designation types of +#' protected areas. Defaults to `c("National", "Regional", "International", "Not Applicable")`. +#' @param Category A character vector specifying the desired IUCN Protected Area +#' Management Categories. Defaults to `c("Ia", "Ib", "II", "III", "IV")`. +#' @param ... Other arguments that are passed directly to the `wdpa_fetch()` function +#' from the `wdpar` package (e.g., `verbose = TRUE`). +#' +#' @return An `sf` object. This object contains the planning units, with an +#' additional `wdpa` column (set to 1) for areas that intersect with the +#' selected MPAs. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr bind_rows filter select mutate +#' @importFrom purrr map +#' @importFrom rlang .data +#' @importFrom rappdirs user_data_dir +#' @importFrom sf st_as_sf +#' @importFrom spatialgridr get_data_in_grid +#' #' @examples -#' dat <- splnr_get_MPAs(PlanUnits = dat_PUs, Countries = "Australia") +#' \dontrun{ +#' # Assuming 'dat_PUs' is an existing sf object of planning units in your package. +#' +#' # Example: Get MPAs for Australia and intersect with planning units. +#' dat_mpas <- splnr_get_MPAs(PlanUnits = dat_PUs, Countries = "Australia") #' +#' # Example: Get MPAs for multiple countries with specific status and categories. +#' dat_mpas_specific <- splnr_get_MPAs( +#' PlanUnits = dat_PUs, +#' Countries = c("Australia", "New Zealand"), +#' Status = c("Designated", "Proposed"), +#' Category = c("II", "IV") +#' ) +#' +#' # Example: Visualize the result using ggplot2. +#' # Assuming 'aust' is an sf object representing Australia's coastline, +#' # perhaps loaded from rnaturalearth::ne_countries. #' aust <- rnaturalearth::ne_countries(country = "Australia", returnclass = "sf") #' #' gg <- ggplot2::ggplot() + -#' ggplot2::geom_sf(data = dat, ggplot2::aes(fill = wdpa)) + -#' ggplot2::geom_sf(data = aust, fill = "grey50") +#' ggplot2::geom_sf(data = dat_mpas, ggplot2::aes(fill = wdpa)) + +#' ggplot2::geom_sf(data = aust, fill = "grey50") + +#' ggplot2::labs(title = "Marine Protected Areas in Australia") + +#' ggplot2::theme_minimal() +#' print(gg) +#' } splnr_get_MPAs <- function(PlanUnits, Countries, Status = c("Designated", "Established", "Inscribed"), @@ -28,32 +88,66 @@ splnr_get_MPAs <- function(PlanUnits, Category = c("Ia", "Ib", "II", "III", "IV"), ...) { + # Assertions to validate input parameters. assertthat::assert_that( inherits(PlanUnits, "sf"), + msg = "The 'PlanUnits' parameter must be an 'sf' object." + ) + assertthat::assert_that( is.character(Countries), + msg = "The 'Countries' parameter must be a character vector." + ) + assertthat::assert_that( all(Status %in% c("Designated", "Established", "Inscribed", "Proposed", "Adopted")), + msg = "Invalid 'Status' provided. Must be one or more of: 'Designated', 'Established', 'Inscribed', 'Proposed', 'Adopted'." + ) + assertthat::assert_that( all(Desig %in% c("National", "Regional", "International", "Not Applicable")), - all(Category %in% c("Ia", "Ib", "II", "III", "IV", "V", "VI", "Not Reported", "Not Applicable", "Not Assigned")) + msg = "Invalid 'Desig' provided. Must be one or more of: 'National', 'Regional', 'International', 'Not Applicable'." ) + assertthat::assert_that( + all(Category %in% c("Ia", "Ib", "II", "III", "IV", "V", "VI", "Not Reported", "Not Applicable", "Not Assigned")), + msg = "Invalid 'Category' provided. Must be one or more of valid IUCN categories (e.g., 'Ia', 'Ib', 'II', 'III', 'IV', 'V', 'VI', 'Not Reported', 'Not Applicable', 'Not Assigned')." + ) + + + # TODO Add a check for wdpar package + # Set a chromote timeout option to prevent issues with web scraping for WDPA data. options(chromote.timeout = 120) + # Fetch WDPA data for the specified countries and then process it. wdpa_data <- Countries %>% + # Use purrr::map to fetch WDPA data for each country in the 'Countries' vector. + # 'wait = TRUE' ensures sequential downloads, and 'download_dir' specifies where to cache the data. purrr::map(wdpar::wdpa_fetch, - wait = TRUE, - download_dir = rappdirs::user_data_dir("wdpar"), - ...) %>% + wait = TRUE, + download_dir = rappdirs::user_data_dir("wdpar"), + ...) %>% + # Bind all fetched data frames into a single data frame. dplyr::bind_rows() %>% + # Filter for marine protected areas only (where MARINE attribute is greater than 0). dplyr::filter(.data$MARINE > 0) %>% - dplyr::filter(.data$IUCN_CAT %in% Category) %>% # filter category - dplyr::filter(.data$DESIG_TYPE %in% Desig) %>% # filter designation - dplyr::filter(.data$STATUS %in% Status) %>% # filter status - wdpar::wdpa_clean(retain_status = NULL, erase_overlaps = FALSE) %>% # clean protected area data - wdpar::wdpa_dissolve() %>% # Dissolve data to remove overlapping areas. + # Filter by the specified IUCN Protected Area Management Categories. + dplyr::filter(.data$IUCN_CAT %in% Category) %>% + # Filter by the specified Designation Types. + dplyr::filter(.data$DESIG_TYPE %in% Desig) %>% + # Filter by the specified Status of the protected area. + dplyr::filter(.data$STATUS %in% Status) %>% + # Clean the protected area data using wdpar::wdpa_clean, removing any invalid geometries + # or other issues. 'retain_status = NULL' means all statuses are considered for cleaning. + # 'erase_overlaps = FALSE' means overlapping polygons are not removed at this stage. + wdpar::wdpa_clean(retain_status = NULL, erase_overlaps = FALSE) %>% + # Dissolve the protected area polygons to merge adjacent or overlapping areas into single geometries. + wdpar::wdpa_dissolve() %>% + # Select only the 'geometry' column, discarding other attributes after dissolving. dplyr::select("geometry") %>% + # Add a new column 'wdpa' and set its value to 1, indicating it's a WDPA area. dplyr::mutate(wdpa = 1) + # Intersect the cleaned WDPA data with the provided planning units using spatialgridr::get_data_in_grid. + # This function identifies which planning units overlap with the WDPA areas. wdpa_data <- spatialgridr::get_data_in_grid(spatial_grid = PlanUnits, dat = wdpa_data, cutoff = NULL) diff --git a/R/splnr_get_boundary.R b/R/splnr_get_boundary.R index aa24a6a5..a75f7b15 100755 --- a/R/splnr_get_boundary.R +++ b/R/splnr_get_boundary.R @@ -1,48 +1,154 @@ -#' Get the boundary of the planning region. +#' @title Create a Planning Region Boundary #' -#' `splnr_get_boundary()` allows to create an `sf` object of your planning region either based on specific coordinate information, or `rnaturalearth` inputs such as ocean data. Creating a boundary is often the first step in conservation planning and a requirement for downstream function sin `spatialplanr`. +#' @description +#' This function generates a spatial boundary for the planning region as an `sf` +#' polygon object. The boundary can be defined in several ways: +#' 1. A simple rectangular bounding box using numeric coordinates. +#' 2. A global boundary spanning the entire world. +#' 3. A complex shape based on marine ecoregions from `rnaturalearth`. #' -#' @param Limits The limits of the boundary. This can either be a 4 element numeric named vector (c(xmin = 150, xmax = 160, ymin = -40, ymax = -30)), a vector of ocean/sea names, or a vector of EEZs., -#' @param Type The type of Limits being provided. Options are "Ocean" or "EEZ". (not required if numeric or "Global" limits are provided) -#' @param res The resolution (in degrees) from which to create the boundary polygon if numeric limits are provided. -#' @param cCRS The CRS the boundary is to be returned in +#' @details +#' A planning region boundary is the foundational first step for most spatial +#' conservation planning exercises. All subsequent analyses and data preparation +#' steps within the `spatialplanr` package rely on a defined boundary. The +#' coordinate reference system (CRS) of the returned object is projected by +#' default (Mollweide), which is suitable for equal-area calculations. +#' +#' @param Limits A required input that defines the spatial extent. This can be: +#' \itemize{ +#' \item A named numeric vector of four elements: `c("xmin" = ..., "xmax" = ..., "ymin" = ..., "ymax" = ...)`. +#' \item The string `"Global"` to create a worldwide boundary. +#' \item A character vector of ocean/sea names (e.g., `"North Atlantic Ocean"`) to be used with `Type = "Ocean"`. +#' } +#' @param Type `r lifecycle::badge("deprecated")` The type of Limits being provided. This is only required if `Limits` is a character vector of ocean names, in which case it should be `"Ocean"`. It is no longer required and will be removed in a future version. +#' @param res `[numeric(1)]`\cr The resolution (in decimal degrees) used to +#' construct the polygon vertices when `Limits` is numeric or `"Global"`. +#' Defaults to `1`. Must be a positive number. +#' @param cCRS `[character(1)]`\cr The coordinate reference system (CRS) for the +#' output `sf` object. Can be a PROJ4 string or an EPSG code. Defaults to +#' `"ESRI:54009"` (Mollweide). +#' +#' @family planning_region +#' +#' @return An `sf` object containing a single polygon feature representing the +#' planning boundary. #' -#' @return The boundary of the planning region #' @export #' +#' @importFrom assertthat assert_that is.string is.flag +#' @importFrom dplyr tibble bind_rows filter +#' @importFrom rnaturalearth ne_download +#' @importFrom sf st_crs st_join st_as_sf st_union st_transform st_set_crs st_polygon st_sfc +#' @importFrom lifecycle deprecate_warn #' @importFrom rlang .data #' #' @examples -#' Bndry <- splnr_get_boundary(Limits = "North Atlantic Ocean", Type = "Ocean") -#' Bndry <- splnr_get_boundary(Limits = "Global") -#' Bndry <- splnr_get_boundary(Limits = c("xmin" = 150, "xmax" = 170, "ymin" = -40, "ymax" = -20)) +#' \dontrun{ +#' # Example 1: Create a boundary from an ocean name. +#' # This fetches polygon data for the specified ocean. +#' bndry_ocean <- splnr_get_boundary(Limits = "North Atlantic Ocean", Type = "Ocean") +#' plot(bndry_ocean) +#' +#' # Example 2: Create a global boundary. +#' bndry_global <- splnr_get_boundary(Limits = "Global") +#' plot(bndry_global) +#' +#' # Example 3: Create a boundary from a numeric bounding box. +#' bndry_coords <- splnr_get_boundary( +#' Limits = c("xmin" = 150, "xmax" = 170, "ymin" = -40, "ymax" = -20) +#' ) +#' plot(bndry_coords) +#' } splnr_get_boundary <- function(Limits, Type = NULL, res = 1, cCRS = "ESRI:54009" # Mollweide ) { - assertthat::assert_that(res > 0, msg = "Resolution 'res' must be greater than zero.") + # Input validation using assertthat + assertthat::assert_that( + !missing(Limits), + msg = "'Limits' is a required argument." + ) + assertthat::assert_that( + is.numeric(res) && length(res) == 1 && res > 1e-6, + msg = "'res' must be a single positive numeric value." + ) + assertthat::assert_that( + is.character(cCRS) && length(cCRS) == 1, + msg = "'cCRS' must be a single character string." + ) + + # Validate 'Limits' based on its type + is_numeric_limits <- is.numeric(Limits) && length(Limits) == 4 && !is.null(names(Limits)) && all(sort(names(Limits)) == sort(c("xmin", "xmax", "ymin", "ymax"))) + is_global_limit <- is.character(Limits) && length(Limits) == 1 && identical(Limits, "Global") + is_ocean_limits <- is.character(Limits) && !identical(Limits, "Global") + is_character_limits <- is.character(Limits) + + assertthat::assert_that( + is_numeric_limits || is_global_limit || is_ocean_limits, + msg = paste0( + "'Limits' must be either:\n", + " - A named numeric vector of four: c(xmin=..., xmax=..., ymin=..., ymax=...)\n", + " - The string 'Global'\n", + " - A character vector of ocean/sea names (e.g., 'North Atlantic Ocean')" + ) + ) - if (is.numeric(Limits) || Limits == "Global") { - assertthat::assert_that(missing(Type), msg = "Type must be missing when Limits are numeric or global.")} + # Validate 'Type' in relation to 'Limits' + if (is_character_limits && !is_global_limit) { # Only validate Type if Limits is a character vector and not "Global" + assertthat::assert_that( + is.character(Type) && length(Type) == 1, + msg = "`Type` must be a single character string when `Limits` is a character vector (other than 'Global')." + ) + assertthat::assert_that( + Type %in% c("Oceans", "Ocean", "EEZ"), # Include EEZ as per original function, even if commented out later. + msg = paste0("When `Limits` is an ocean name, `Type` must be 'Ocean' or 'Oceans' (or 'EEZ').") + ) + } + + # Check that Type is not provided for numeric or "Global" limits and warn + if ((is_numeric_limits || is_global_limit) && !is.null(Type)) { + warning("`Type` is ignored when `Limits` is a numeric bounding box or 'Global'.") + } - if (is.numeric(Limits)) { + # # Deprecation warning for Type argument + # if (!is.null(Type)){ + # lifecycle::deprecate_warn( + # when = "0.2.0", + # what = "splnr_get_boundary(Type)", + # details = "The `Type` argument is no longer necessary and will be removed in a future release." + # ) + # } + + # Handle numeric limits to create a rectangular boundary + if (is_numeric_limits) { + # Check that min is less than max + assertthat::assert_that(Limits["xmin"] < Limits["xmax"], msg = "'xmin' must be less than 'xmax'.") + assertthat::assert_that(Limits["ymin"] < Limits["ymax"], msg = "'ymin' must be less than 'ymax'.") + + # Construct the boundary polygon from coordinates Bndry <- dplyr::tibble(x = seq(Limits["xmin"], Limits["xmax"], by = res), y = Limits["ymin"]) %>% dplyr::bind_rows(dplyr::tibble(x = Limits["xmax"], y = seq(Limits["ymin"], Limits["ymax"], by = res))) %>% dplyr::bind_rows(dplyr::tibble(x = seq(Limits["xmax"], Limits["xmin"], by = -res), y = Limits["ymax"])) %>% dplyr::bind_rows(dplyr::tibble(x = Limits["xmin"], y = seq(Limits["ymax"], Limits["ymin"], by = -res))) %>% + # Convert the points to an sf polygon splnr_create_polygon(cCRS) %>% + # Convert to an sf object sf::st_sf() return(Bndry) } - if (Limits == "Global") { + # Handle the "Global" limit case + if (is_global_limit) { + # Construct a global boundary polygon Bndry <- dplyr::tibble(x = seq(-180, 180, by = res), y = -90) %>% dplyr::bind_rows(dplyr::tibble(x = 180, y = seq(-90, 90, by = res))) %>% dplyr::bind_rows(dplyr::tibble(x = seq(180, -180, by = -res), y = 90)) %>% dplyr::bind_rows(dplyr::tibble(x = -180, y = seq(90, -90, by = -res))) %>% + # Convert the points to an sf polygon splnr_create_polygon(cCRS) %>% + # Convert to an sf object sf::st_sf() return(Bndry) @@ -50,6 +156,8 @@ splnr_get_boundary <- function(Limits, ## TODO Disable EEZ until offshoredatr publicly online. # if (Type == "EEZ"){ + # # This part relies on an external package not universally available or stable. + # # It's commented out but kept for structural completeness if offshoredatr becomes stable. # Bndry <- offshoredatr::get_area(area_name = Limits) %>% # dplyr::filter(.data$territory1 %in% Limits) %>% # sf::st_union() %>% @@ -57,17 +165,26 @@ splnr_get_boundary <- function(Limits, # return(Bndry) # } - if (Type == "Oceans" | Type == "Ocean") { + # Handle Ocean limits using rnaturalearth + if (is_ocean_limits) { + # Download marine polygons from rnaturalearth Bndry <- rnaturalearth::ne_download( scale = "large", category = "physical", type = "geography_marine_polys", returnclass = "sf" ) %>% + # Filter for the specified ocean(s) dplyr::filter(.data$name %in% Limits) %>% + # Unify the polygons into a single feature sf::st_union() %>% + # Transform to the specified CRS sf::st_transform(cCRS) %>% + # Convert to an sf object sf::st_sf() + return(Bndry) } + # Fallback for unexpected Limits/Type combinations + stop("Invalid 'Limits' or 'Type' combination provided. Please check the function documentation.") } diff --git a/R/splnr_get_distCoast.R b/R/splnr_get_distCoast.R index e0b69acf..37ac46aa 100644 --- a/R/splnr_get_distCoast.R +++ b/R/splnr_get_distCoast.R @@ -1,78 +1,123 @@ -#' Function to compute distances to nearest coastline for each centroid of each planning unit in the 'sf' object provided. +#' @title Calculate Distance to Coastline #' -#' The code takes a sf object and return it updated with a new coastDistance column. -#' The output inherits the crs from this sf object so ensure it is in the correct projection for your needs +#' @description +#' This function calculates the shortest distance from the centroid of each +#' planning unit in an `sf` object to the nearest coastline. It can use either +#' a default coastline from the `rnaturalearth` package or a custom-provided +#' coastline `sf` object. #' -#' Written by Kristine Buenafe -#' Written: March/April 2023 -#' Modified by Kilian Barreiro -#' Updated: December 2023 +#' @details +#' The function adds a new column named `coastDistance_km` to the input `sf` +#' object, containing the calculated distances in kilometers. The CRS of the +#' input data is preserved. It is crucial to ensure the input `sf` object has +#' a suitable projected CRS for accurate distance calculations. #' -#' @param dat_sf An sf object. -#' @param custom_coast An sf coastline object (optional) -#' @param res Allow user to choose resolution (`small`, `medium`, `large`) of `rnaturalearth` data used for coastline. +#' @param dat_sf `[sf]` \cr An `sf` object containing polygon or point features +#' representing the planning units. Must have a valid CRS. +#' @param custom_coast `[sf]` \cr An optional `sf` object representing a +#' custom coastline. If `NULL` (the default), the coastline is downloaded +#' from `rnaturalearth`. +#' @param res `[character(1)]` \cr The resolution of the `rnaturalearth` +#' coastline to use. Options are `"small"`, `"medium"` (default), or +#' `"large"`. This parameter is ignored if `custom_coast` is provided. +#' +#' @family cost_features +#' +#' @return An `sf` object identical to `dat_sf` but with an added column +#' `coastDistance_km` representing the distance to the nearest coastline in +#' kilometers. +#' +#' @importFrom assertthat assert_that is.flag +#' @importFrom units set_units drop_units +#' @importFrom rnaturalearth ne_coastline +#' @importFrom sf st_crs st_centroid st_geometry st_distance st_transform +#' @importFrom rlang .data #' -#' @return An `sf` object with distances to the nearest coast #' @export #' #' @examples +#' \dontrun{ +#' # Example 1: Calculate distance to coast for a simple grid #' bbox <- sf::st_bbox(c(xmin = 0, ymin = 0, xmax = 3, ymax = 3)) -#' grid <- sf::st_make_grid(bbox, n = c(3, 3), what = "polygons") -#' grid <- sf::st_sf(geometry = grid) %>% -#' sf::st_set_crs("EPSG:4326") -#' splnr_get_distCoast(grid) -#' -#' cCRS <- "ESRI:54009" +#' grid <- sf::st_as_sf(sf::st_make_grid(bbox, n = c(3, 3))) +#' grid_with_dist <- splnr_get_distCoast(grid) +#' plot(grid_with_dist["coastDistance_km"]) #' -#' Bndry <- splnr_get_boundary(Limits = "Coral Sea", -#' Type = "Oceans", -#' cCRS = cCRS) +#' # Example 2: Using a specific resolution for the coastline +#' # Note: Requires the 'dat_sf' object to be created first, e.g., using +#' # splnr_get_planning_units() +#' if (exists("dat_sf")) { +#' dat_sf_dist <- splnr_get_distCoast(dat_sf, res = "large") +#' summary(dat_sf_dist$coastDistance_km) +#' } #' +#' # Example 3: Using a custom coastline +#' # First, create a custom coastline (e.g., from a country polygon) #' landmass <- rnaturalearth::ne_countries( #' scale = "medium", #' returnclass = "sf" -#' ) %>% -#' sf::st_transform(cCRS) +#' ) #' -# dat_sf <- spatialgridr::get_grid(boundary = Bndry, -# projection_crs = cCRS, -# option = "sf_hex", -# resolution = 10000, -# sf_method = "centroid") %>% -# splnr_get_distCoast(res = "medium") - -splnr_get_distCoast <- function(dat_sf, custom_coast = NULL, res = NULL) { - +#' if (exists("dat_sf") && exists("landmass")) { +#' # Transform landmass to the same CRS as the planning units +#' landmass_proj <- sf::st_transform(landmass, sf::st_crs(dat_sf)) +#' dat_sf_custom_coast <- splnr_get_distCoast(dat_sf, custom_coast = landmass_proj) +#' summary(dat_sf_custom_coast$coastDistance_km) +#' } +#' } +splnr_get_distCoast <- function(dat_sf, custom_coast = NULL, res = "medium") { + # Input validation using assertthat assertthat::assert_that( inherits(dat_sf, "sf"), - !is.null(sf::st_crs(dat_sf)), + msg = "'dat_sf' must be an 'sf' object." + ) + assertthat::assert_that( + !is.na(sf::st_crs(dat_sf)), + msg = "'dat_sf' must have a valid Coordinate Reference System (CRS)." + ) + assertthat::assert_that( is.null(custom_coast) || inherits(custom_coast, "sf"), - is.null(res) || res %in% c("small", "medium", "large") + msg = "'custom_coast' must be either NULL or an 'sf' object." + ) + assertthat::assert_that( + is.character(res) && length(res) == 1 && res %in% c("small", "medium", "large"), + msg = "'res' must be a single character string: 'small', 'medium', or 'large'." ) - # Load coast + # Load or prepare the coastline data if (is.null(custom_coast)) { - if (is.null(res)) {res <- "medium"} - coast <- rnaturalearth::ne_coastline(scale = res) %>% - sf::st_as_sf() %>% + message(paste0("Downloading coastline data from rnaturalearth at '", res, "' resolution.")) + # If no custom coast is provided, download from rnaturalearth + coast <- rnaturalearth::ne_coastline(scale = res, returnclass = "sf") %>% + # Transform the coastline to match the CRS of the input data sf::st_transform(crs = sf::st_crs(dat_sf)) } else { + message("Using custom coastline data.") + # If a custom coast is provided, use it coast <- custom_coast %>% + # Ensure the custom coastline has the same CRS as the input data sf::st_transform(crs = sf::st_crs(dat_sf)) } - # Convert grid to points (centroids) + # Calculate centroids of the planning units + # Using centroids is a standard approach to represent the location of each planning unit + message("Calculating centroids for planning units.") grid_centroid <- sf::st_centroid(sf::st_geometry(dat_sf)) - # Get distance matrix + # Calculate the distance matrix between each planning unit centroid and the coastline + message("Calculating distances to coastline.") dist_mat <- sf::st_distance(grid_centroid, coast) %>% - units::set_units("km") %>% # Convert to km - units::drop_units() # Remove units (include in header below) + # Explicitly set the distance units to kilometers + units::set_units("km") %>% + # Drop the units class to get a numeric matrix for easier computation + units::drop_units() - # Find min distance for each row and convert to km. + # Find the minimum distance for each planning unit (each row in the matrix) + # This identifies the shortest distance from each centroid to any part of the coastline + message("Finding minimum distances and adding to dataframe.") dat_sf$coastDistance_km <- do.call(pmin, as.data.frame(dist_mat)) + # Return the original sf object with the new distance column + message("Distance calculation complete.") return(dat_sf) } - - diff --git a/R/splnr_get_gfw.R b/R/splnr_get_gfw.R index 2411a5ba..ef4ead50 100644 --- a/R/splnr_get_gfw.R +++ b/R/splnr_get_gfw.R @@ -1,43 +1,81 @@ -#' The `get_gfwData` function recover the data of Global Fishing Watch and -#' returns it as a sf object. +#' @title Retrieve Global Fishing Watch Data #' +#' @description +#' The `splnr_get_gfw` function retrieves Global Fishing Watch (GFW) data and +#' returns it as an `sf` (simple features) object. This function allows for +#' flexible data queries based on geographical region, time range, and desired +#' spatial and temporal resolutions. #' -#' The possibilities offered by this function are explained in `vignette("GlobalFishingWatch")` +#' @details +#' The possibilities offered by this function are extensively explained in +#' `vignette("GlobalFishingWatch")`. #' -#' We have the same parameters than the `get_raster` function, plus `cCRS` -#' which is the crs for the sf_modification
-#' Different possible values can be combined and are :
-#' - `Time Range`, `Flag`, `Geartype`.
-#' __(A combination can be : c('Time Range','Geartype'), if you want to get__ -#' __the sum of fishing hours per date and geartype, for example you want to__ -#' __display the drifting longline fishing in a specific year)__

-#' __Notes :__
-#' 1. For the moment we are limited to the EEZs of each region, but we can -#' potentially restrict the working area to specific MPAs.
-#' 2. Days indicated in the__ `start_date` __and__ `end_date` __variables are -#' included in the data recovery. +#' This function shares many parameters with the `get_raster` function from the +#' `gfwr` package, with the addition of `cCRS` for specifying the Coordinate +#' Reference System of the output `sf` object. #' -#' The code takes several parameters described below and return an sf object -#' with gfw data aggregated or not (param compress) +#' Fishing activity data can be aggregated (`group_by`) by "FLAGANDGEARTYPE" +#' by default, combining flags and gear types. #' -#' @param region Region studied (character) or a geojson shape to filter raster -#' @param start_date Start date (waited format : "%Y-%m-%d"). -#' @param end_date End date (waited format : "%Y-%m-%d"). -#' @param temp_res Temporal resolution ("daily","monthly","yearly"). -#' @param spat_res Spatial resolution ("low" for 0.1 degree, "high" for 0.01 degree). -#' @param region_source source of the region ('eez','mpa', 'rfmo' or 'user_json') -#' @param key Token for GFW API (see details GlobalFishingWatch vignette). -#' @param cCRS The crs to which the sf will be returned (default = "EPSG:4326"). -#' @param compress Binary operator to compress (aggregate) the data per coordinates (default = FALSE). +#' \strong{Notes:} +#' \itemize{ +#' \item Currently, the function is primarily designed for data within +#' Exclusive Economic Zones (EEZs), but it can potentially be +#' extended to specific Marine Protected Areas (MPAs) or RFMOs. +#' \item Days specified in the `start_date` and `end_date` variables are +#' inclusive in the data recovery. +#' } #' -#' @return An `sf` object with gfw data. +#' @param region A character string specifying the name of the region (e.g., an EEZ name) +#' or a numeric ID for the region, or an `sf` object if `region_source` is set +#' to "USER_SHAPEFILE". +#' @param start_date The start date for data retrieval, expected in "%Y-%m-%d" format (e.g., "2021-01-01"). +#' @param end_date The end date for data retrieval, expected in "%Y-%m-%d" format (e.g., "2022-12-31"). +#' @param temp_res The desired temporal resolution for the data. Must be one of: +#' "DAILY", "MONTHLY", or "YEARLY". +#' @param spat_res The desired spatial resolution for the data. Must be one of: +#' "LOW" (0.1 degree) or "HIGH" (0.01 degree). Defaults to "LOW". +#' @param region_source The source of the region definition. Must be one of: +#' 'EEZ', 'MPA', 'RFMO', or 'USER_SHAPEFILE'. Defaults to "EEZ". +#' @param key Your API token for the GFW API. If not provided, it attempts to +#' authenticate using `gfwr::gfw_auth()`. See the GlobalFishingWatch vignette +#' for details on obtaining a key. +#' @param cCRS The Coordinate Reference System (CRS) to which the output `sf` object +#' will be transformed. Defaults to "EPSG:4326". +#' @param compress A logical value. If `TRUE`, the data will be compressed (aggregated) +#' by coordinates, summing fishing hours for each unique location. If `FALSE`, +#' the raw data points are returned. Defaults to `FALSE`. +#' +#' @return An `sf` object containing the requested GFW data. The structure of +#' the `sf` object will vary depending on the `compress` and `temp_res` +#' parameters. #' @export #' #' @examples #' \dontrun{ -#' gfw_data <- splnr_get_gfw('Australia', "2021-01-01", "2022-12-31", "YEARLY", -#' cCRS = "ESRI:54009", compress = TRUE) -#'} +#' # Example: Retrieve yearly GFW data for Australia, transformed to a +#' # Mollweide projection (ESRI:54009) and compressed (aggregated) by location. +#' gfw_data <- splnr_get_gfw( +#' region = 'Australia', +#' start_date = "2021-01-01", +#' end_date = "2022-12-31", +#' temp_res = "YEARLY", +#' cCRS = "ESRI:54009", +#' compress = TRUE +#' ) +#' +#' # Example: Retrieve monthly GFW data for a specific EEZ ID, +#' # keeping individual time ranges and locations. +#' # Note: Replace 1000 with an actual EEZ ID if needed for testing. +#' gfw_data_monthly <- splnr_get_gfw( +#' region = 1000, # Example numeric EEZ ID +#' start_date = "2022-01-01", +#' end_date = "2022-03-31", +#' temp_res = "MONTHLY", +#' region_source = "EEZ", +#' compress = FALSE +#' ) +#' } splnr_get_gfw <- function(region, start_date, end_date, @@ -48,47 +86,82 @@ splnr_get_gfw <- function(region, cCRS = "EPSG:4326", compress = FALSE) { - assertthat::assert_that((is.character(region) | is.numeric(region)), - inherits(start_date, "character") && !is.na(as.Date(start_date, "%Y-%m-%d")), #is.Date ? - inherits(end_date, "character") && !is.na(as.Date(end_date, "%Y-%m-%d")), - temp_res %in% c("DAILY", "MONTHLY", "YEARLY"), - spat_res %in% c("LOW", "HIGH"), - region_source %in% c('EEZ', 'MPA', 'RFMO', 'USER_SHAPEFILE'), - is.character(key), - is.character(cCRS), - is.logical(compress)) + # Assertions for input parameters to ensure correct types and values + assertthat::assert_that( + (is.character(region) || is.numeric(region) || (region_source == "USER_SHAPEFILE" && inherits(region, "sf"))), + msg = "The 'region' parameter must be a character (name), numeric (ID), or an 'sf' object if 'region_source' is 'USER_SHAPEFILE'." + ) + assertthat::assert_that( + inherits(start_date, "character") && !is.na(as.Date(start_date, "%Y-%m-%d")), + msg = "The 'start_date' parameter must be a character string in 'YYYY-MM-DD' format." + ) + assertthat::assert_that( + inherits(end_date, "character") && !is.na(as.Date(end_date, "%Y-%m-%d")), + msg = "The 'end_date' parameter must be a character string in 'YYYY-MM-DD' format." + ) + assertthat::assert_that( + temp_res %in% c("DAILY", "MONTHLY", "YEARLY"), + msg = "The 'temp_res' parameter must be one of 'DAILY', 'MONTHLY', or 'YEARLY'." + ) + assertthat::assert_that( + spat_res %in% c("LOW", "HIGH"), + msg = "The 'spat_res' parameter must be one of 'LOW' or 'HIGH'." + ) + assertthat::assert_that( + region_source %in% c('EEZ', 'MPA', 'RFMO', 'USER_SHAPEFILE'), + msg = "The 'region_source' parameter must be one of 'EEZ', 'MPA', 'RFMO', or 'USER_SHAPEFILE'." + ) + assertthat::assert_that( + is.character(key), + msg = "The 'key' parameter must be a character string (your GFW API token)." + ) + assertthat::assert_that( + is.character(cCRS), + msg = "The 'cCRS' parameter must be a character string representing a valid CRS (e.g., 'EPSG:4326')." + ) + assertthat::assert_that( + is.logical(compress), + msg = "The 'compress' parameter must be a logical value (TRUE or FALSE)." + ) + # Define an internal helper function to fetch GFW data for a single region. get_gfw_byRegion <- function(region){ - if (region_source == "EEZ" & is.character(region)){ # Only process eez. RFMO and geojson have bugs + # Determine the region ID based on the region_source and region type. + if (region_source == "EEZ" & is.character(region)){ region_id <- gfwr::get_region_id(region_name = region, region_source = region_source, key = key)$id } else if (region_source == "EEZ" & is.numeric(region)){ + # If region is numeric for EEZ, assume it's already an ID. region_id <- region } else if (region_source == "RFMO"){ - region_id <- region # gfwr retuns NULL for region ID due to a bug in as.numeric(ID) - } else if (methods::is(region, "USER_SHAPEFILE")){ - region_id <- region # Use region as is + # For RFMO, pass the region as is; handles potential gfwr package quirks. + region_id <- region + } else if (region_source == "USER_SHAPEFILE"){ + # If region_source is USER_SHAPEFILE, use the provided region (assumed to be an sf object). + region_id <- region } - # Convert dates into Date objects + # Convert start_date and end_date strings to Date objects. start_date <- as.Date(start_date, format = "%Y-%m-%d") end_date <- as.Date(end_date, format = "%Y-%m-%d") - # Function to obtain data for a specific date range + # Define a nested helper function to obtain data for a specific date range within the loop. get_data_for_range <- function(start_date, end_date, rid) { + # Call the gfwr::get_raster function to retrieve GFW raster data. data <- gfwr::get_raster( spatial_resolution = spat_res, temporal_resolution = temp_res, - group_by = 'FLAGANDGEARTYPE', + group_by = 'FLAGANDGEARTYPE', # Group by flag and geartype. start_date = start_date, end_date = end_date, region = rid, region_source = region_source, key = key) + # Mutate and rename columns for consistency and clarity. data <- data %>% - dplyr::mutate(GFWregionID = rid) %>% + dplyr::mutate(GFWregionID = rid) %>% # Add a column for the GFW region ID. dplyr::rename(TimeRange = .data$`Time Range`, VesselID = .data$`Vessel IDs`, ApparentFishingHrs = .data$`Apparent Fishing Hours`) @@ -96,50 +169,56 @@ splnr_get_gfw <- function(region, return(data) } - # Create expanded dataframe with all combinations + # Create an expanded grid of dates and regions to iterate over, splitting long date ranges. + # This helps in fetching data in manageable chunks, as GFW API might have limitations on date ranges. eg <- tidyr::expand_grid( - Date = seq(start_date, end_date, by = "366 days"), + Date = seq(start_date, end_date, by = "366 days"), # Step by 366 days to ensure yearly chunks, adapting to leap years. Region = region_id ) + # Use purrr::map2 to apply the get_data_for_range function to each date chunk and region. + # Then, drop empty list elements and bind all data frames into a single data frame. data_df <- purrr::map2(eg$Date, eg$Region, ~ get_data_for_range(.x, min(.x + 365, end_date), .y)) %>% vctrs::list_drop_empty() %>% dplyr::bind_rows() + # Check if the resulting data frame is empty and stop with an informative message if no data is found. if(rlang::is_empty(data_df)){ stop(paste0("No data found at all for the requested area of ", region, " between ", start_date, " and ", end_date)) } - + # Process data based on the 'compress' parameter. if (isTRUE(compress)){ + # Group data by Lon and Lat and summarise (sum) Apparent Fishing Hours for compression. data_df <- data_df %>% dplyr::group_by(.data$Lon, .data$Lat) %>% dplyr::summarise("ApparentFishingHrs" = sum(.data$ApparentFishingHrs, na.rm = TRUE), GFWregionID = dplyr::first(.data$GFWregionID)) %>% dplyr::ungroup() + # Convert the aggregated data frame to a 'terra' raster, then to polygons, and finally to an 'sf' object. data_sf <- data_df %>% - terra::rast(type = "xyz", crs = "EPSG:4326") %>% # Convert to polygons for easier use - terra::as.polygons(trunc = FALSE, dissolve = FALSE, na.rm = TRUE, round = FALSE) %>% - sf::st_as_sf() %>% - dplyr::mutate(GFWregionID = as.factor(.data$GFWregionID)) + terra::rast(type = "xyz", crs = "EPSG:4326") %>% # Convert to a raster from XYZ data with WGS84 CRS. + terra::as.polygons(trunc = FALSE, dissolve = FALSE, na.rm = TRUE, round = FALSE) %>% # Convert raster cells to polygons. + sf::st_as_sf() %>% # Convert the 'terra' polygons to an 'sf' object. + dplyr::mutate(GFWregionID = as.factor(.data$GFWregionID)) # Ensure GFWregionID is a factor. + # Verify that the dimensions of the data frame and sf object match after conversion. if (dim(data_df)[1] != dim(data_sf)[1]){ stop("Data dimensions of data_df and data_sf do not match after conversion to polygon") } } else if (isFALSE(compress)){ - # Combine data frames in the list into one data frame - - # Separate the "Time Range" column based on the specified temp_res + # Process data without compression, separating 'TimeRange' based on temporal resolution. if (temp_res == "YEARLY") { + # If temporal resolution is yearly, create a 'Year' column and convert to sf. data_sf <- data_df %>% dplyr::mutate(Year = .data$TimeRange) %>% sf::st_as_sf(coords = c("Lon", "Lat"), crs ="EPSG:4326") } else { - # Otherwise, separate the "Time Range" column according to the specified temp_res + # Otherwise, separate 'TimeRange' into 'Year', 'Month', and/or 'Day' columns. if (temp_res == "MONTHLY") { data_sf <- data_df %>% tidyr::separate("TimeRange", into = c("Year", "Month"), sep = "-", remove = FALSE) %>% @@ -151,7 +230,8 @@ splnr_get_gfw <- function(region, } } } - # But you may wish to return the data in a different CRS. For this you need transform + + # Transform the CRS of the sf object if the requested cCRS is different from the default "EPSG:4326". if (isFALSE(cCRS == "EPSG:4326")){ data_sf <- data_sf %>% sf::st_transform(crs = cCRS) @@ -159,26 +239,24 @@ splnr_get_gfw <- function(region, return(data_sf) } - # Run the analysis + # Apply the internal get_gfw_byRegion function to each specified region. out <- purrr::map(region, function(x) get_gfw_byRegion(x)) - - if (isFALSE(compress)){ # Do nothing. Just bind as a df + # Combine the results from multiple regions based on the 'compress' setting. + if (isFALSE(compress)){ + # If not compressed, simply bind rows of the sf objects. out <- out %>% dplyr::bind_rows() - } - - if (isTRUE(compress)){# Take care of duplicate cells on boundaries + } else if (isTRUE(compress)){ + # If compressed, bind rows and then re-summarise to handle duplicate cells on boundaries, + # summing fishing hours and combining GFWregionIDs. out <- out %>% dplyr::bind_rows() %>% dplyr::group_by(.data$geometry) %>% dplyr::summarise("ApparentFishingHrs" = sum(.data$ApparentFishingHrs, na.rm = TRUE), GFWregionID = toString(.data$GFWregionID)) %>% dplyr::ungroup() - } return(out) - } - diff --git a/R/splnr_gg_add.R b/R/splnr_gg_add.R index a2ea3b2d..257409be 100644 --- a/R/splnr_gg_add.R +++ b/R/splnr_gg_add.R @@ -1,48 +1,101 @@ -#' Add-ons for plotting +#' @title Add-ons for Plotting `spatialplanr` Maps #' -#' This function allows to customise plots in a simple and reproducible way, by -#' giving the option for several inputs that can be included in maps produced -#' with the other functions of this package.It can be combined with the -#' `spatialplanr` spatial plotting functions. +#' @description +#' This function allows users to customize existing `ggplot2` maps, particularly +#' those produced by other `spatialplanr` spatial plotting functions. It provides +#' options to add various spatial layers and apply consistent theming in a +#' simple and reproducible manner. #' -#' @param PUs Planning Units as an `sf` object -#' @param colorPUs A color value for the outline of planning units. -#' @param Bndry The planning region boundaries as an `sf` object -#' @param colorBndry A color value for the outline of the boundary. -#' @param overlay An `sf` object of overlay polygon. -#' @param colorOverlay A color value for overlay. -#' @param overlay2 An `sf` object of overlay polygon. -#' @param colorOverlay2 A color value for overlay. -#' @param overlay3 An `sf` object of overlay polygon. -#' @param colorOverlay3 A color value for overlay. -#' @param cropOverlay An `sf` object with the boundary box used for cropping the -#' overlay object. -#' @param contours An `sf` object of contours that are important to visualise -#' (e.g. outline of sea mounts, ridges; can be produced with -#' terra::as.contour()); up to 6 different contours possible. -#' @param colorConts A color value for contours. -#' @param lockIn An `sf` object with binary data of locked in areas in -#' the prioritisation (e.g. MPAs). -#' @param typeLockIn Either "Full" or "Contours"; "Full" maps the locked in areas on -#' top of the planning units; "Contours" draws the outline of the locked in -#' areas. -#' @param nameLockIn column of data frame that contains binary information of -#' the locked in areas to plot -#' @param alphaLockIn A value (0-1) for the opacity of the locked in areas when -#' plotted on top of other plots. -#' @param colorLockIn A color value for the locked in areas. -#' @param legendLockIn A character value for the title of the legend of the locked in -#' areas. Can be empty (""). -#' @param labelLockIn The legend label of the locked in area (e.g. MPAs) -#' @param ggtheme The theme applied to the plot. Can either be NA (default -#' ggplot), "Default" (default spatialplanr: theme_bw() and some basic theme -#' settings) or a user-defined list of theme properties. +#' @details +#' The `splnr_gg_add` function enhances `ggplot2` objects by layering additional +#' spatial data such as planning unit outlines, study area boundaries, general +#' overlays, geographical contours, and 'locked-in' areas (e.g., existing protected +#' areas in a conservation prioritization). It offers fine-grained control over +#' colors, opacities, and legend appearance for each added layer. #' -#' @return A ggplot object of the plot +#' When using `contours`, the input `sf` object is expected to have a column +#' named `Category` that defines the different contour lines to be plotted. +#' The function currently supports up to 6 distinct contour categories for plotting. +#' +#' The `ggtheme` parameter offers flexibility in plot styling. `"Default"` applies +#' a standard `spatialplanr` theme (`theme_bw()` with custom text and axis settings). +#' A `list` of `ggplot2::theme()` elements can be provided for full customization, +#' or `NA` (logical `FALSE`) to apply no default theme, allowing the user to manage +#' all theme elements manually. +#' +#' @param PUs An `sf` object representing planning units. If provided, their +#' outlines will be drawn. Defaults to `NULL`. +#' @param colorPUs A character string specifying the color for the outlines of the +#' planning units. Defaults to `"grey80"`. +#' @param Bndry An `sf` object representing the main planning region boundaries. +#' If provided, its outline will be drawn. Defaults to `NULL`. +#' @param colorBndry A character string specifying the color for the outline of the +#' `Bndry` object. Defaults to `"black"`. +#' @param overlay An `sf` object to be plotted as a general overlay. Defaults to `NULL`. +#' @param colorOverlay A character string specifying the color for `overlay`. +#' Defaults to `"grey20"`. +#' @param overlay2 An `sf` object for a second general overlay. Defaults to `NULL`. +#' @param colorOverlay2 A character string specifying the color for `overlay2`. +#' Defaults to `"grey30"`. +#' @param overlay3 An `sf` object for a third general overlay. Defaults to `NULL`. +#' @param colorOverlay3 A character string specifying the color for `overlay3`. +#' Defaults to `"grey40"`. +#' @param cropOverlay An `sf` object. Its bounding box will be used to set the +#' `xlim` and `ylim` of the `ggplot2::coord_sf` layer, effectively cropping the view. +#' Defaults to `NULL`. +#' @param contours An `sf` object containing contour lines (e.g., bathymetry or +#' seamount outlines). It is expected to have a `Category` column for differentiating +#' lines. Up to 6 categories are supported. Defaults to `NULL`. +#' @param colorConts A character string specifying the color for the contour lines. +#' Defaults to `"black"`. +#' @param lockIn An `sf` object representing 'locked-in' areas (e.g., existing +#' Marine Protected Areas) that are fixed in a conservation prioritization. +#' Defaults to `NULL`. +#' @param typeLockIn A character string specifying how `lockIn` areas should be +#' plotted. Can be `"Full"` (fills the areas with `colorLockIn`) or `"Contours"` +#' (draws only the outlines of the areas). Defaults to `"Full"`. +#' @param nameLockIn A character string specifying the column name in the `lockIn` +#' data frame that contains binary (0/1 or TRUE/FALSE) information indicating +#' locked-in status. Required if `lockIn` is not `NULL`. +#' @param alphaLockIn A numeric value (0 to 1) for the opacity of the `lockIn` +#' areas when `typeLockIn` is `"Full"`. Defaults to `0.5`. +#' @param colorLockIn A character string specifying the color for the `lockIn` areas. +#' Defaults to `"black"`. +#' @param legendLockIn A character string for the title of the `lockIn` legend. +#' Can be an empty string `""` to suppress the title. Defaults to `""`. +#' @param labelLockIn A character string for the legend label of the `lockIn` areas +#' (e.g., "MPAs"). Defaults to `"MPAs"`. +#' @param ggtheme The `ggplot2` theme to apply. Can be: +#' \itemize{ +#' \item `NA` or `FALSE`: No theme is applied, using `ggplot2` defaults. +#' \item `"Default"`: Applies a `spatialplanr` default theme (`theme_bw()` +#' with custom text/axis settings). +#' \item A `list` of `ggplot2::theme()` properties for custom styling. +#' } +#' Defaults to `"Default"`. +#' +#' @return A `list` of `ggplot2` layers and theme elements that can be added to +#' an existing `ggplot` object using `+`. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr filter mutate rename +#' @importFrom ggnewscale new_scale_colour new_scale_fill +#' @importFrom ggplot2 aes coord_sf geom_sf guide_legend element_blank +#' @importFrom ggplot2 element_text labs scale_fill_manual scale_linetype_manual +#' @importFrom ggplot2 theme theme_bw +#' @importFrom sf st_bbox st_union st_as_sf +#' @importFrom rlang .data +#' @importFrom grid unit +#' #' @examples -#' dat_problem <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +#' \dontrun{ +#' # Assuming 'dat_species_bin' and 'dat_PUs' are existing sf objects +#' # in your package, suitable for prioritisation problems and plotting. +#' +#' # Create a dummy prioritizr problem and solve it for demonstration. +#' dat_problem <- prioritizr::problem( +#' dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), #' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" #' ) %>% @@ -54,8 +107,46 @@ #' dat_soln <- dat_problem %>% #' prioritizr::solve.ConservationProblem() #' -#' splnr_plot_solution(dat_soln) + +#' # Basic plot of the solution with default planning unit outlines and theme. +#' plot_basic <- splnr_plot_solution(dat_soln) + #' splnr_gg_add(PUs = dat_PUs, ggtheme = "Default") +#' print(plot_basic) +#' +#' # Example with boundary, a custom overlay, and locked-in areas shown as contours. +#' # For this example, let's create dummy `bndry_sf` and `locked_in_sf` based on `dat_PUs` +#' # In a real scenario, these would be loaded from your package or data. +#' bndry_sf <- sf::st_union(dat_PUs) %>% sf::st_as_sf() +#' locked_in_sf <- dat_PUs[1:100, ] %>% dplyr::mutate(is_mpa = 1) +#' +#' plot_custom <- splnr_plot_solution(dat_soln) + +#' splnr_gg_add( +#' PUs = dat_PUs, +#' Bndry = bndry_sf, +#' colorBndry = "darkblue", +#' overlay = bndry_sf, # Using boundary as an example overlay +#' colorOverlay = "lightblue", +#' alphaOverlay = 0.3, +#' lockIn = locked_in_sf, +#' typeLockIn = "Contours", +#' nameLockIn = "is_mpa", +#' colorLockIn = "darkred", +#' labelLockIn = "Existing MPAs", +#' ggtheme = "Default" +#' ) +#' print(plot_custom) +#' +#' # Example with custom ggplot2 theme settings (as a list) +#' custom_theme_list <- list( +#' ggplot2::theme_classic(), +#' ggplot2::theme( +#' plot.background = ggplot2::element_rect(fill = "lightyellow"), +#' legend.position = "top" +#' ) +#' ) +#' plot_with_custom_theme <- splnr_plot_solution(dat_soln) + +#' splnr_gg_add(PUs = dat_PUs, ggtheme = custom_theme_list) +#' print(plot_with_custom_theme) +#' } splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", Bndry = NULL, colorBndry = "black", overlay = NULL, colorOverlay = "grey20", @@ -66,19 +157,44 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", lockIn = NULL, typeLockIn = "Full", nameLockIn = NULL, alphaLockIn = 0.5, colorLockIn = "black", legendLockIn = "", labelLockIn = "MPAs", - ggtheme = "Default" # splnr_theme + ggtheme = "Default" ) { - if(!is.null(PUs)){assertthat::assert_that(inherits(PUs, "sf"))} - if(!is.null(Bndry)){assertthat::assert_that(inherits(Bndry, "sf"))} - if(!is.null(overlay)){assertthat::assert_that(inherits(overlay, "sf"))} - if(!is.null(overlay2)){assertthat::assert_that(inherits(overlay2, "sf"))} - if(!is.null(overlay3)){assertthat::assert_that(inherits(overlay3, "sf"))} - if(!is.null(contours)){assertthat::assert_that(inherits(contours, "sf"))} - if(!is.null(lockIn)){assertthat::assert_that(inherits(lockIn, "sf"))} + # Assertions to validate input parameters are of the correct 'sf' class if not NULL. + if(!is.null(PUs)){assertthat::assert_that(inherits(PUs, "sf"), msg = "'PUs' must be an 'sf' object or NULL.")} + if(!is.null(Bndry)){assertthat::assert_that(inherits(Bndry, "sf"), msg = "'Bndry' must be an 'sf' object or NULL.")} + if(!is.null(overlay)){assertthat::assert_that(inherits(overlay, "sf"), msg = "'overlay' must be an 'sf' object or NULL.")} + if(!is.null(overlay2)){assertthat::assert_that(inherits(overlay2, "sf"), msg = "'overlay2' must be an 'sf' object or NULL.")} + if(!is.null(overlay3)){assertthat::assert_that(inherits(overlay3, "sf"), msg = "'overlay3' must be an 'sf' object or NULL.")} + if(!is.null(contours)){assertthat::assert_that(inherits(contours, "sf"), msg = "'contours' must be an 'sf' object or NULL.")} + if(!is.null(lockIn)){ + assertthat::assert_that(inherits(lockIn, "sf"), msg = "'lockIn' must be an 'sf' object or NULL.") + assertthat::assert_that(is.character(nameLockIn) && nameLockIn %in% names(lockIn), + msg = "If 'lockIn' is provided, 'nameLockIn' must be a character string specifying an existing column in 'lockIn'.") + assertthat::assert_that(typeLockIn %in% c("Full", "Contours"), + msg = "'typeLockIn' must be either 'Full' or 'Contours'.") + assertthat::assert_that(is.numeric(alphaLockIn) && alphaLockIn >= 0 && alphaLockIn <= 1, + msg = "'alphaLockIn' must be a numeric value between 0 and 1.") + } + if(!is.null(cropOverlay)){assertthat::assert_that(inherits(cropOverlay, "sf"), msg = "'cropOverlay' must be an 'sf' object or NULL.")} + assertthat::assert_that(is.character(colorPUs), msg = "'colorPUs' must be a character string for a color.") + assertthat::assert_that(is.character(colorBndry), msg = "'colorBndry' must be a character string for a color.") + assertthat::assert_that(is.character(colorOverlay), msg = "'colorOverlay' must be a character string for a color.") + assertthat::assert_that(is.character(colorOverlay2), msg = "'colorOverlay2' must be a character string for a color.") + assertthat::assert_that(is.character(colorOverlay3), msg = "'colorOverlay3' must be a character string for a color.") + assertthat::assert_that(is.character(colorConts), msg = "'colorConts' must be a character string for a color.") + assertthat::assert_that(is.character(colorLockIn), msg = "'colorLockIn' must be a character string for a color.") + assertthat::assert_that(is.character(legendLockIn), msg = "'legendLockIn' must be a character string.") + assertthat::assert_that(is.character(labelLockIn), msg = "'labelLockIn' must be a character string.") + assertthat::assert_that( + inherits(ggtheme, "character") || inherits(ggtheme, "theme") || inherits(ggtheme, "logical"), + msg = "'ggtheme' must be 'Default', a ggplot2 theme, or NA/FALSE." + ) + # Initialize an empty list to store ggplot2 layers. ggList <- list() + # Add planning units layer if PUs is an sf object. if (inherits(PUs, "sf")) { ggList <- c( ggList, @@ -87,6 +203,7 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", ) } + # Add boundary layer if Bndry is an sf object. if (inherits(Bndry, "sf")) { ggList <- c( ggList, @@ -95,39 +212,45 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", ) } + # Add first overlay layer if 'overlay' is an sf object. if (inherits(overlay, "sf")) { ggList <- c( ggList, ggplot2::geom_sf(data = overlay, colour = colorOverlay, fill = colorOverlay, alpha = 0.9, size = 0.1, show.legend = FALSE) )} + # Add second overlay layer if 'overlay2' is an sf object. if (inherits(overlay2, "sf")) { ggList <- c( ggList, ggplot2::geom_sf(data = overlay2, colour = colorOverlay2, fill = colorOverlay2, alpha = 0.9, size = 0.1, show.legend = FALSE) )} + # Add third overlay layer if 'overlay3' is an sf object. if (inherits(overlay3, "sf")) { ggList <- c( ggList, ggplot2::geom_sf(data = overlay3, colour = colorOverlay3, fill = colorOverlay3, alpha = 0.9, size = 0.1, show.legend = FALSE) )} - - if (inherits(contours, "sf")) { # needs a geometry col and one names Category that has the wanted contours and their names - namesConts <- unique(contours$Category) - contoursRowNum <- length(namesConts) + # Add contours layer if 'contours' is an sf object. + if (inherits(contours, "sf")) { + # Get unique contour categories for legend. + nameConts <- unique(contours$Category) + contoursRowNum <- length(nameConts) vals <- 1:contoursRowNum + # Warn if more than 6 categories are provided for contours. if (length(vals) > 6) { cat("Only 6 categories allowed for plotting contours.") } else { + # Add contour layers with new scale for color and linetype. ggList <- c( ggList, list( - ggnewscale::new_scale_colour(), + ggnewscale::new_scale_colour(), # Start a new color scale for contours. ggplot2::geom_sf(data = contours, colour = colorConts, fill = NA, ggplot2::aes(linetype = .data$Category), size = 0.5, show.legend = "line"), - ggplot2::scale_linetype_manual(" ", - breaks = namesConts, + ggplot2::scale_linetype_manual(" ", # Set linetype based on contour categories. + breaks = nameConts, values = vals, guide = ggplot2::guide_legend( override.aes = list(fill = NA), @@ -142,25 +265,30 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", } } + # Add locked-in areas layer if 'lockIn' is an sf object. if (inherits(lockIn, "sf")) { + # Mutate the 'lockIn' data to create a 'lockedIn' logical column based on 'nameLockIn', then filter. lockIn <- lockIn %>% dplyr::mutate(lockedIn = as.logical(.data[[nameLockIn]])) %>% - dplyr::filter(.data$lockedIn == 1) # TODO Add ability for TRUE as well + dplyr::filter(.data$lockedIn == TRUE) # Filter for TRUE values in the 'lockedIn' column. + # Plot locked-in areas as 'Full' polygons. if (typeLockIn == "Full") { ggList <- c( ggList, list( - ggnewscale::new_scale_fill(), - ggnewscale::new_scale_colour(), + ggnewscale::new_scale_fill(), # Start a new fill scale. + ggnewscale::new_scale_colour(), # Start a new color scale. ggplot2::geom_sf(data = lockIn, ggplot2::aes(fill = .data$lockedIn), alpha = alphaLockIn), ggplot2::scale_fill_manual( - name = legendLockIn, - values = c("TRUE" = colorLockIn), - labels = labelLockIn, + name = legendLockIn, # Set legend title. + values = c("TRUE" = colorLockIn), # Map TRUE to specified color. + labels = labelLockIn, # Set legend label. + # Apply color and fill aesthetics to this scale. aesthetics = c("colour", "fill"), + # Configure legend appearance. guide = ggplot2::guide_legend( - override.aes = list(linetype = 0), + override.aes = list(linetype = 0), # Remove linetype from legend. nrow = 2, order = 1, direction = "horizontal", @@ -170,7 +298,8 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", ) ) ) - } else if (typeLockIn == "Contours") { + } else if (typeLockIn == "Contours") { # Plot locked-in areas as 'Contours' (outlines). + # Union geometries to create a single outline for locked-in areas. lockIn <- lockIn %>% sf::st_union() %>% sf::st_as_sf() %>% @@ -178,20 +307,19 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", dplyr::mutate(lockedIn = 1) %>% dplyr::mutate(lockedIn = as.factor(.data$lockedIn)) + # Add contour layers with new scale for color and linetype. ggList <- c( ggList, list( - ggnewscale::new_scale_fill(), - ggnewscale::new_scale_colour(), + ggnewscale::new_scale_fill(), # Start a new fill scale. + ggnewscale::new_scale_colour(), # Start a new color scale. ggplot2::geom_sf(data = lockIn, colour = colorLockIn, fill = NA, ggplot2::aes(linetype = .data$lockedIn), size = 0.5, show.legend = "line"), ggplot2::scale_linetype_manual("", - values = 1, - labels = labelLockIn, + values = 1, # Use a single linetype for contours. + labels = labelLockIn, # Set legend label. guide = ggplot2::guide_legend( - override.aes = list(fill = NA), - # nrow = 2, + override.aes = list(fill = NA), # Remove fill from legend. direction = "horizontal", - # order = 3, keywidth = grid::unit(0.05, "npc") ) ) @@ -200,6 +328,7 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", } } + # Apply coordinate limits based on 'cropOverlay' if provided. if (inherits(cropOverlay, "sf")) { ggList <- c( ggList, @@ -207,25 +336,30 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", ) } - - if (inherits(ggtheme, "character")) { + # Apply the specified ggplot2 theme. + if (inherits(ggtheme, "character") && ggtheme == "Default") { + # Apply the default spatialplanr theme. ggList <- c( ggList, list( - ggplot2::theme_bw(), + ggplot2::theme_bw(), # Black and white theme. ggplot2::theme( - legend.position = "bottom", - legend.direction = "horizontal", - text = ggplot2::element_text(size = 20, colour = "black"), - axis.text = ggplot2::element_text(size = 16, colour = "black"), - plot.title = ggplot2::element_text(size = 16), - axis.title = ggplot2::element_blank() + legend.position = "bottom", # Legend at the bottom. + legend.direction = "horizontal", # Horizontal legend. + text = ggplot2::element_text(size = 20, colour = "black"), # Global text size and color. + axis.text = ggplot2::element_text(size = 16, colour = "black"), # Axis text size and color. + plot.title = ggplot2::element_text(size = 16), # Plot title size. + axis.title = ggplot2::element_blank() # Remove axis titles. ) ) ) } else if (inherits(ggtheme, "list")) { + # If a list of theme elements is provided, append them. ggList <- c(ggList, ggtheme) - } else if (inherits(ggtheme, "logical")) { + } else if (inherits(ggtheme, "logical") && !ggtheme) { + # If ggtheme is FALSE or NA, do nothing (no default theme applied). ggList <- ggList } + + return(ggList) } diff --git a/R/splnr_plot.R b/R/splnr_plot.R index ef2d3c8d..1571bb81 100644 --- a/R/splnr_plot.R +++ b/R/splnr_plot.R @@ -1,167 +1,266 @@ -#' Function to plot data. +#' @title Plot Spatial Data #' -#' (For now can replace splnr_plot_cost(), splnr_plot_binFeature(), splnr_plot_MPAs(), splnr_plot_featureNo()) +#' @description +#' This function provides a versatile way to plot spatial data (`sf` objects) +#' within the `spatialplanr` package. It can visualize various data types, +#' including binary presence/absence, logical values, continuous data, or simply +#' the planning unit outlines. #' -#' Written by Kilian Barreiro and Jason Everett -#' Written: February 2024 +#' @details +#' The `splnr_plot` function automatically detects the type of data specified by +#' `colNames` (binary, logical, or continuous) and adjusts the plotting +#' aesthetics accordingly. If multiple `colNames` are provided, it calculates +#' the sum of features for each planning unit and plots this sum. If `colNames` +#' is `NULL`, it will simply plot the outlines of the planning units. #' -#' @param df The dataframe containing the data to be plotted. It must include a geometry column to be used with geom_sf. -#' @param col_names A list of column names to include in the plot. If specified, only these columns will be used to colour the plot. -#' @param paletteName The name of the colour palette to use for filling. Default is "YlGnBu". -#' @param colourVals The colour values to use if col_names is specified and the data is binary. -#' @param plot_title The title of the plot. -#' @param legend_title The title of the legend. -#' @param legend_labels A vector of strings containing the labels to use for legend values. +#' This function is designed to be a flexible replacement for several plotting +#' functions, such as `splnr_plot_cost()`, `splnr_plot_binFeature()`, +#' `splnr_plot_MPAs()`, and `splnr_plot_featureNo()`, streamlining the plotting +#' workflow within the package. #' -#' @return A ggplot object. +#' Written by Kilian Barreiro and Jason Everett. +#' Last modified: February 2024. +#' +#' @param df The input dataframe containing the data to be plotted. This must be +#' an `sf` object and include a geometry column. +#' @param colNames A character vector of column names from `df` to be used for +#' coloring the plot. If `NULL` (default), only the planning unit outlines are plotted. +#' If a single column is specified, it checks for binary, logical, or continuous data. +#' If multiple columns are specified, it sums the values across these columns to create +#' a "FeatureSum" for plotting. +#' @param paletteName A character string specifying the name of the `RColorBrewer` +#' palette to use for filling continuous data. Defaults to `"YlGnBu"`. +#' @param colourVals A character vector of two color values to use for binary +#' (0/1) or logical (FALSE/TRUE) data. The first color is for '0' or 'FALSE' +#' (absence), and the second is for '1' or 'TRUE' (presence). +#' Defaults to `c("#c6dbef", "#3182bd")`. +#' @param plotTitle A character string for the subtitle of the plot. +#' Defaults to `""` (no subtitle). +#' @param legendTitle A character string for the title of the legend. If `NULL`, +#' a default title will be used based on the data type. +#' @param legendLabels A character vector of strings to use for the legend labels, +#' particularly useful for binary or logical data (e.g., `c("Absent", "Present")`). +#' If `NULL`, default labels are used for binary/logical plots. +#' +#' @return A `ggplot` object representing the spatial plot. #' #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr across as_tibble filter mutate select +#' @importFrom ggplot2 aes coord_sf geom_sf ggplot labs scale_fill_distiller +#' @importFrom ggplot2 scale_fill_manual scale_fill_viridis_c guide_colourbar guides +#' @importFrom purrr map_vec +#' @importFrom rlang .data +#' @importFrom scales squish +#' @importFrom sf st_as_sf st_bbox st_drop_geometry +#' @importFrom tidyr replace_na +#' @importFrom tidyselect all_of starts_with where +#' #' @examples -#' # Binary plot of species distribution -#' splnr_plot(df = dat_species_bin, -#' col_names = "Spp1", -#' legend_title = "Legend", -#' legend_labels = c("Absent", "Present")) +#' \dontrun{ +#' # Assuming 'dat_species_bin', 'dat_bathy', and 'dat_PUs' are existing sf objects +#' # in your package, suitable for plotting. #' -#' # Logical plot of species distribution -#' splnr_plot(df = dat_species_bin %>% -#' dplyr::mutate(dplyr::across( -#' tidyselect::starts_with("Spp"), as.logical)), -#' col_names = "Spp1", -#' legend_title = "Legend", -#' legend_labels = c("Absent", "Present")) +#' # Binary plot of species distribution for "Spp1" +#' plot_spp1_binary <- splnr_plot( +#' df = dat_species_bin, +#' colNames = "Spp1", +#' legendTitle = "Species Presence", +#' legendLabels = c("Absent", "Present") +#' ) +#' print(plot_spp1_binary) #' -#' # Continuous plot of bathymetry# -#' splnr_plot(df = dat_bathy, -#' col_names = "bathymetry", -#' plot_title = "Bathymetry", -#' legend_title = "Bathymetry (m)") +#' # Logical plot of species distribution for "Spp1" (converted from binary) +#' plot_spp1_logical <- splnr_plot( +#' df = dat_species_bin %>% +#' dplyr::mutate(dplyr::across( +#' tidyselect::starts_with("Spp"), as.logical +#' )), +#' colNames = "Spp1", +#' legendTitle = "Species Presence", +#' legendLabels = c("Absent", "Present") +#' ) +#' print(plot_spp1_logical) #' -#' # Plot Planning Units -#' splnr_plot(df = dat_PUs) +#' # Continuous plot of bathymetry +#' plot_bathymetry <- splnr_plot( +#' df = dat_bathy, +#' colNames = "bathymetry", +#' plotTitle = "Bathymetry", +#' legendTitle = "Bathymetry (m)" +#' ) +#' print(plot_bathymetry) #' -#' # Multi binary features -#' splnr_plot(df = dat_species_bin, -#' col_names = colnames(dat_species_bin %>% -#' sf::st_drop_geometry() %>% -#' dplyr::select( -#' tidyselect::starts_with("Spp"))), -#' legend_title = "Number of features") - +#' # Plot Planning Units outlines only +#' plot_planning_units <- splnr_plot(df = dat_PUs) +#' print(plot_planning_units) +#' +#' # Multi-binary features: Plotting the sum of multiple "Spp" features +#' plot_multi_spp_sum <- splnr_plot( +#' df = dat_species_bin, +#' colNames = colnames(dat_species_bin %>% +#' sf::st_drop_geometry() %>% +#' dplyr::select(tidyselect::starts_with("Spp"))), +#' legendTitle = "Number of Features" +#' ) +#' print(plot_multi_spp_sum) +#' } splnr_plot <- function(df, - col_names = NULL, + colNames = NULL, paletteName = "YlGnBu", colourVals = c("#c6dbef", "#3182bd"), - plot_title = "", - legend_title = NULL, - legend_labels = NULL) { + plotTitle = "", + legendTitle = NULL, + legendLabels = NULL) { - # Assertions + # Assertions to validate input parameters. assertthat::assert_that( is.data.frame(df), - inherits(df, "sf"), # Check it is an sf + msg = "'df' must be a data.frame." + ) + assertthat::assert_that( + inherits(df, "sf"), + msg = "'df' must be an 'sf' object." + ) + assertthat::assert_that( all(c("xmin", "xmax", "ymin", "ymax") %in% names(sf::st_bbox(df))), - is.null(col_names) | is.character(col_names), - all(col_names %in% colnames(df)), # Do the column names exist - # Check all col_names are in the the dataset + msg = "'df' must have a valid bounding box (sf::st_bbox)." + ) + assertthat::assert_that( + is.null(colNames) || is.character(colNames), + msg = "'colNames' must be a character vector or NULL." + ) + if (!is.null(colNames)) { + assertthat::assert_that( + all(colNames %in% colnames(df)), + msg = paste0("Not all specified 'colNames' exist in the input dataframe. Missing: ", + paste(colNames[!colNames %in% colnames(df)], collapse = ", ")) + ) + } + assertthat::assert_that( is.character(paletteName), - is.null(legend_title) | is.character(legend_title), - is.null(legend_labels) | is.character(legend_labels) + msg = "'paletteName' must be a character string (e.g., a RColorBrewer palette name)." + ) + assertthat::assert_that( + is.null(legendTitle) || is.character(legendTitle), + msg = "'legendTitle' must be a character string or NULL." + ) + assertthat::assert_that( + is.null(legendLabels) || is.character(legendLabels), + msg = "'legendLabels' must be a character vector or NULL." + ) + assertthat::assert_that( + is.character(plotTitle), + msg = "'plotTitle' must be a character string." + ) + assertthat::assert_that( + is.character(colourVals) && length(colourVals) == 2, + msg = "'colourVals' must be a character vector of exactly two color strings." ) - # Set the defaults + + # Initialize flags for data type detection. is_binary <- FALSE is_logi <- FALSE is_continuous <- FALSE showFeatureSum <- FALSE - # Figure out data type - - if (!is.null(col_names)){ # If there is a column name + # Determine data type based on 'colNames' presence and content. + if (!is.null(colNames)){ # If 'colNames' are provided. - if (length(col_names) == 1){ # One column name + if (length(colNames) == 1){ # If only one column name is specified. - if (is.logical(df[[col_names]])){ # Is the column logical? + if (is.logical(df[[colNames]])){ # Check if the column data is logical (TRUE/FALSE). is_logi <- TRUE - } else { # See if it is binary + } else { # If not logical, check if it's binary (0/1). + # Create a temporary dataframe, replacing NA with 0 in the target columns for binary check. df0 <- df %>% - # Replace NA with 0 in selected columns for binary data verification - dplyr::mutate(dplyr::across(tidyselect::all_of(col_names), ~tidyr::replace_na(., 0))) - - is_binary <- all(purrr::map_vec(col_names, function(x) all(df0[[x]] %in% c(0, 1)))) + dplyr::mutate(dplyr::across(tidyselect::all_of(colNames), ~tidyr::replace_na(., 0))) + # Check if all values in the column are exclusively 0 or 1. + is_binary <- all(purrr::map_vec(colNames, function(x) all(df0[[x]] %in% c(0, 1)))) } - ## Is the data continuous? + ## If not binary and not logical, assume it's continuous. if (isFALSE(is_binary) & isFALSE(is_logi)){ - is_continuous <- TRUE # May not always be true but plotting as continuous will work, and highlight the issue + is_continuous <- TRUE # This assumption allows plotting, and issues would be visible. } - } else if (length(col_names) > 1){ # Mutliple columns - showFeatureSum <- TRUE # FeatureSum + } else if (length(colNames) > 1){ # If multiple column names are specified. + showFeatureSum <- TRUE # Set flag to calculate and show the sum of features. } } - # DEFAULT PLOT CODE + + # Initialize the base ggplot object with coordinate system and subtitle. gg <- ggplot2::ggplot() + ggplot2::coord_sf(xlim = sf::st_bbox(df)$xlim, ylim = sf::st_bbox(df)$ylim) + - ggplot2::labs(subtitle = plot_title) + ggplot2::labs(subtitle = plotTitle) - # Plot logic based on data type + # Plot logic based on the determined data type. - if (showFeatureSum) { #TODO I don't think this is used anymore. Remove? - - # Calculate feature sum if multiple features + if (showFeatureSum) { + # If showing feature sum, calculate it and prepare data for plotting. df <- df %>% - dplyr::as_tibble() %>% - dplyr::select(tidyselect::all_of(c(col_names, "geometry"))) %>% - dplyr::mutate(FeatureSum = rowSums(dplyr::across(tidyselect::where(is.numeric)), na.rm = TRUE)) %>% - sf::st_as_sf(sf_column_name = "geometry") %>% - dplyr::select("FeatureSum") + dplyr::as_tibble() %>% # Convert to tibble to handle geometry column easily. + dplyr::select(tidyselect::all_of(c(colNames, "geometry"))) %>% # Select only relevant columns and geometry. + dplyr::mutate(FeatureSum = rowSums(dplyr::across(tidyselect::where(is.numeric)), na.rm = TRUE)) %>% # Calculate sum of numeric feature columns. + sf::st_as_sf(sf_column_name = "geometry") %>% # Convert back to sf object. + dplyr::select("FeatureSum") # Keep only FeatureSum and geometry. + # Add geom_sf for continuous fill based on FeatureSum. gg <- gg + ggplot2::geom_sf(data = df, ggplot2::aes(fill = .data$FeatureSum), colour = NA, size = 0.1) + + # Apply a distiller palette for continuous data and configure the legend. ggplot2::scale_fill_distiller( - name = legend_title, + name = legendTitle, palette = paletteName, aesthetics = c("fill"), oob = scales::squish) + ggplot2::guides(fill = ggplot2::guide_colourbar(order = -1)) return(gg) - } else if (is_binary | is_logi) { + } else if (is_binary | is_logi) { # If data is binary or logical. - if (is.null(legend_labels)){ - legend_labels = c("Absence", "Presence") + # Set default legend labels if not provided. + if (is.null(legendLabels)){ + legendLabels = c("Absence", "Presence") } + # Add geom_sf for discrete fill based on the single column. gg <- gg + - ggplot2::geom_sf(data = df, ggplot2::aes(fill = factor(.data[[col_names]])), colour = "grey80", size = 0.1) + ggplot2::geom_sf(data = df, ggplot2::aes(fill = factor(.data[[colNames]])), colour = "grey80", size = 0.1) + # Apply manual fill scale for binary (0/1) data. if (isTRUE(is_binary)) { gg <- gg + ggplot2::scale_fill_manual(values = c("0" = colourVals[1], "1" = colourVals[2]), - labels = legend_labels, - name = legend_title) + labels = legendLabels, + name = legendTitle) } + # Apply manual fill scale for logical (FALSE/TRUE) data. if (isTRUE(is_logi)) { gg <- gg + ggplot2::scale_fill_manual(values = c("FALSE" = colourVals[1], "TRUE" = colourVals[2]), - labels = legend_labels, - name = legend_title)} - + labels = legendLabels, + name = legendTitle) + } - } else if (is_continuous) { + } else if (is_continuous) { # If data is continuous. + # Add geom_sf for continuous fill and color based on the single column. gg <- gg + - ggplot2::geom_sf(data = df, ggplot2::aes(fill = .data[[col_names]], colour = .data[[col_names]])) + - ggplot2::scale_fill_viridis_c(name = legend_title, aesthetics = c("colour", "fill")) + + ggplot2::geom_sf(data = df, ggplot2::aes(fill = .data[[colNames]], colour = .data[[colNames]])) + + # Apply a viridis continuous color scale for fill and color. + ggplot2::scale_fill_viridis_c(name = legendTitle, aesthetics = c("colour", "fill")) + + # Configure guides to show color bar for fill and hide color legend for outline. ggplot2::guides(fill = ggplot2::guide_colourbar(order = 1), colour = "none") - } else if (is.null(col_names)){ # No column to plot by + } else if (is.null(colNames)){ # If no column to plot by (only planning unit outlines). + # Add geom_sf to display planning unit outlines without fill. gg <- gg + ggplot2::geom_sf(data = df, colour = "grey80", fill = NA, size = 0.1) } diff --git a/R/splnr_plotting.R b/R/splnr_plotting.R index 16430421..db2b4a15 100644 --- a/R/splnr_plotting.R +++ b/R/splnr_plotting.R @@ -1,20 +1,330 @@ -#' Plot prioritizr solution +#' @title Plot Spatial Data #' -#' `splnr_plot_solution()` allows to plot the solution of a `prioritizr` conservation problem with our without in a customisable way using `ggplot2`. This function requires a solution as an `sf` object with a column called `solution_1` and outputs a `ggobject`. It can be combined with the `spatialplanr` function [splnr_gg_add()]. +#' @description +#' This function provides a versatile way to plot spatial data (`sf` objects) +#' within the `spatialplanr` package. It can visualize various data types, +#' including binary presence/absence, logical values, continuous data, or simply +#' the planning unit outlines. #' -#' @param soln The `prioritizr` solution -#' @param colorVals A `list` object of named vectors that will match the color value with the according name. "TRUE" stands for selected planning units. -#' @param showLegend A logical command on whether to show the legend of the solution (Default: TRUE). -#' @param legendLabels Character values (number of zones + 1) of what the legend should be labelled. -#' @param plotTitle A character value for the title of the plot. Can be empty (""). -#' @param legendTitle A character value for the title of the legend. Can be empty (""). -#' @param zones A logical value, indicating whether the spatial plan contains zones or not (default = FALSE). +#' @details +#' The `splnr_plot` function automatically detects the type of data specified by +#' `colNames` (binary, logical, or continuous) and adjusts the plotting +#' aesthetics accordingly. If multiple `colNames` are provided, it calculates +#' the sum of features for each planning unit and plots this sum. If `colNames` +#' is `NULL`, it will simply plot the outlines of the planning units. +#' +#' This function is designed to be a flexible replacement for several plotting +#' functions, such as `splnr_plot_cost()`, `splnr_plot_binFeature()`, +#' `splnr_plot_MPAs()`, and `splnr_plot_featureNo()`, streamlining the plotting +#' workflow within the package. +#' +#' Written by Kilian Barreiro and Jason Everett. +#' Last modified: February 2024. +#' +#' @param df The input dataframe containing the data to be plotted. This must be +#' an `sf` object and include a geometry column. +#' @param colNames A character vector of column names from `df` to be used for +#' coloring the plot. If `NULL` (default), only the planning unit outlines are plotted. +#' If a single column is specified, it checks for binary, logical, or continuous data. +#' If multiple columns are specified, it sums the values across these columns to create +#' a "FeatureSum" for plotting. +#' @param paletteName A character string specifying the name of the `RColorBrewer` +#' palette to use for filling continuous data. Defaults to `"YlGnBu"`. +#' @param colourVals A character vector of two color values to use for binary +#' (0/1) or logical (FALSE/TRUE) data. The first color is for '0' or 'FALSE' +#' (absence), and the second is for '1' or 'TRUE' (presence). +#' Defaults to `c("#c6dbef", "#3182bd")`. +#' @param plotTitle A character string for the subtitle of the plot. +#' Defaults to `""` (no subtitle). +#' @param legendTitle A character string for the title of the legend. If `NULL`, +#' a default title will be used based on the data type. +#' @param legendLabels A character vector of strings to use for the legend labels, +#' particularly useful for binary or logical data (e.g., `c("Absent", "Present")`). +#' If `NULL`, default labels are used for binary/logical plots. +#' +#' @return A `ggplot` object representing the spatial plot. #' -#' @return A ggplot object of the plot #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr across as_tibble filter mutate select +#' @importFrom ggplot2 aes coord_sf geom_sf ggplot labs scale_fill_distiller +#' @importFrom ggplot2 scale_fill_manual scale_fill_viridis_c guide_colourbar guides +#' @importFrom purrr map_vec +#' @importFrom rlang .data +#' @importFrom scales squish +#' @importFrom sf st_as_sf st_bbox st_drop_geometry +#' @importFrom tidyr replace_na +#' @importFrom tidyselect all_of starts_with where +#' #' @examples -#' dat_problem <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +#' \dontrun{ +#' # Assuming 'dat_species_bin', 'dat_bathy', and 'dat_PUs' are existing sf objects +#' # in your package, suitable for plotting. +#' +#' # Binary plot of species distribution for "Spp1" +#' plot_spp1_binary <- splnr_plot( +#' df = dat_species_bin, +#' colNames = "Spp1", +#' legendTitle = "Species Presence", +#' legendLabels = c("Absent", "Present") +#' ) +#' print(plot_spp1_binary) +#' +#' # Logical plot of species distribution for "Spp1" (converted from binary) +#' plot_spp1_logical <- splnr_plot( +#' df = dat_species_bin %>% +#' dplyr::mutate(dplyr::across( +#' tidyselect::starts_with("Spp"), as.logical +#' )), +#' colNames = "Spp1", +#' legendTitle = "Species Presence", +#' legendLabels = c("Absent", "Present") +#' ) +#' print(plot_spp1_logical) +#' +#' # Continuous plot of bathymetry +#' plot_bathymetry <- splnr_plot( +#' df = dat_bathy, +#' colNames = "bathymetry", +#' plotTitle = "Bathymetry", +#' legendTitle = "Bathymetry (m)" +#' ) +#' print(plot_bathymetry) +#' +#' # Plot Planning Units outlines only +#' plot_planning_units <- splnr_plot(df = dat_PUs) +#' print(plot_planning_units) +#' +#' # Multi-binary features: Plotting the sum of multiple "Spp" features +#' plot_multi_spp_sum <- splnr_plot( +#' df = dat_species_bin, +#' colNames = colnames(dat_species_bin %>% +#' sf::st_drop_geometry() %>% +#' dplyr::select(tidyselect::starts_with("Spp"))), +#' legendTitle = "Number of Features" +#' ) +#' print(plot_multi_spp_sum) +#' } +splnr_plot <- function(df, + colNames = NULL, + paletteName = "YlGnBu", + colourVals = c("#c6dbef", "#3182bd"), + plotTitle = "", + legendTitle = NULL, + legendLabels = NULL) { + + # Assertions to validate input parameters. + assertthat::assert_that( + is.data.frame(df), + msg = "'df' must be a data.frame." + ) + assertthat::assert_that( + inherits(df, "sf"), + msg = "'df' must be an 'sf' object." + ) + assertthat::assert_that( + all(c("xmin", "xmax", "ymin", "ymax") %in% names(sf::st_bbox(df))), + msg = "'df' must have a valid bounding box (sf::st_bbox)." + ) + assertthat::assert_that( + is.null(colNames) || is.character(colNames), + msg = "'colNames' must be a character vector or NULL." + ) + if (!is.null(colNames)) { + assertthat::assert_that( + all(colNames %in% colnames(df)), + msg = paste0("Not all specified 'colNames' exist in the input dataframe. Missing: ", + paste(colNames[!colNames %in% colnames(df)], collapse = ", ")) + ) + } + assertthat::assert_that( + is.character(paletteName), + msg = "'paletteName' must be a character string (e.g., a RColorBrewer palette name)." + ) + assertthat::assert_that( + is.null(legendTitle) || is.character(legendTitle), + msg = "'legendTitle' must be a character string or NULL." + ) + assertthat::assert_that( + is.null(legendLabels) || is.character(legendLabels), + msg = "'legendLabels' must be a character vector or NULL." + ) + assertthat::assert_that( + is.character(plotTitle), + msg = "'plotTitle' must be a character string." + ) + assertthat::assert_that( + is.character(colourVals) && length(colourVals) == 2, + msg = "'colourVals' must be a character vector of exactly two color strings." + ) + + + # Initialize flags for data type detection. + is_binary <- FALSE + is_logi <- FALSE + is_continuous <- FALSE + showFeatureSum <- FALSE + + # Determine data type based on 'colNames' presence and content. + if (!is.null(colNames)){ # If 'colNames' are provided. + + if (length(colNames) == 1){ # If only one column name is specified. + + if (is.logical(df[[colNames]])){ # Check if the column data is logical (TRUE/FALSE). + is_logi <- TRUE + } else { # If not logical, check if it's binary (0/1). + # Create a temporary dataframe, replacing NA with 0 in the target columns for binary check. + df0 <- df %>% + dplyr::mutate(dplyr::across(tidyselect::all_of(colNames), ~tidyr::replace_na(., 0))) + # Check if all values in the column are exclusively 0 or 1. + is_binary <- all(purrr::map_vec(colNames, function(x) all(df0[[x]] %in% c(0, 1)))) + } + + ## If not binary and not logical, assume it's continuous. + if (isFALSE(is_binary) & isFALSE(is_logi)){ + is_continuous <- TRUE # This assumption allows plotting, and issues would be visible. + } + + } else if (length(colNames) > 1){ # If multiple column names are specified. + showFeatureSum <- TRUE # Set flag to calculate and show the sum of features. + } + + } + + # Initialize the base ggplot object with coordinate system and subtitle. + gg <- ggplot2::ggplot() + + ggplot2::coord_sf(xlim = sf::st_bbox(df)$xlim, ylim = sf::st_bbox(df)$ylim) + + ggplot2::labs(subtitle = plotTitle) + + # Plot logic based on the determined data type. + + if (showFeatureSum) { + # If showing feature sum, calculate it and prepare data for plotting. + df <- df %>% + dplyr::as_tibble() %>% # Convert to tibble to handle geometry column easily. + dplyr::select(tidyselect::all_of(c(colNames, "geometry"))) %>% # Select only relevant columns and geometry. + dplyr::mutate(FeatureSum = rowSums(dplyr::across(tidyselect::where(is.numeric)), na.rm = TRUE)) %>% # Calculate sum of numeric feature columns. + sf::st_as_sf(sf_column_name = "geometry") %>% # Convert back to sf object. + dplyr::select("FeatureSum") # Keep only FeatureSum and geometry. + + # Add geom_sf for continuous fill based on FeatureSum. + gg <- gg + + ggplot2::geom_sf(data = df, ggplot2::aes(fill = .data$FeatureSum), colour = NA, size = 0.1) + + # Apply a distiller palette for continuous data and configure the legend. + ggplot2::scale_fill_distiller( + name = legendTitle, + palette = paletteName, + aesthetics = c("fill"), + oob = scales::squish) + + ggplot2::guides(fill = ggplot2::guide_colourbar(order = -1)) + + return(gg) + } else if (is_binary | is_logi) { # If data is binary or logical. + + # Set default legend labels if not provided. + if (is.null(legendLabels)){ + legendLabels = c("Absence", "Presence") + } + + # Add geom_sf for discrete fill based on the single column. + gg <- gg + + ggplot2::geom_sf(data = df, ggplot2::aes(fill = factor(.data[[colNames]])), colour = "grey80", size = 0.1) + + # Apply manual fill scale for binary (0/1) data. + if (isTRUE(is_binary)) { + gg <- gg + + ggplot2::scale_fill_manual(values = c("0" = colourVals[1], "1" = colourVals[2]), + labels = legendLabels, + name = legendTitle) + } + + # Apply manual fill scale for logical (FALSE/TRUE) data. + if (isTRUE(is_logi)) { + gg <- gg + + ggplot2::scale_fill_manual(values = c("FALSE" = colourVals[1], "TRUE" = colourVals[2]), + labels = legendLabels, + name = legendTitle) + } + + } else if (is_continuous) { # If data is continuous. + + # Add geom_sf for continuous fill and color based on the single column. + gg <- gg + + ggplot2::geom_sf(data = df, ggplot2::aes(fill = .data[[colNames]], colour = .data[[colNames]])) + + # Apply a viridis continuous color scale for fill and color. + ggplot2::scale_fill_viridis_c(name = legendTitle, aesthetics = c("colour", "fill")) + + # Configure guides to show color bar for fill and hide color legend for outline. + ggplot2::guides(fill = ggplot2::guide_colourbar(order = 1), + colour = "none") + + } else if (is.null(colNames)){ # If no column to plot by (only planning unit outlines). + + # Add geom_sf to display planning unit outlines without fill. + gg <- gg + + ggplot2::geom_sf(data = df, colour = "grey80", fill = NA, size = 0.1) + } + + return(gg) +} + +#' @title Plot `prioritizr` Solution +#' +#' @description +#' The `splnr_plot_solution()` function visualizes the solution of a +#' `prioritizr` conservation problem using `ggplot2`. It can handle +#' single-zone and multi-zone solutions, offering customization for colors +#' and legend. +#' +#' @details +#' This function requires a `prioritizr` solution object, which should be an +#' `sf` object containing at least a `solution_1` column (for single-zone +#' problems) or `solution_1_zone1`, `solution_1_zone2`, etc. (for multi-zone +#' problems). It outputs a `ggplot` object, which can be further customized +#' by combining it with the `spatialplanr` function `splnr_gg_add()`. +#' +#' For multi-zone problems (`zones = TRUE`), the function sums the selected +#' zones for each planning unit and plots the resulting combined selection. +#' The `colorVals` and `legendLabels` should be provided to match the number of +#' selection levels (e.g., "Not selected", "Zone 1", "Zone 2", etc.). +#' +#' @param soln The `prioritizr` solution object, expected as an `sf` object. +#' @param colorVals A character vector of color values. For single-zone +#' problems, this should typically be two colors (for "Not selected" and +#' "Selected"). For multi-zone problems, the length should match the number of +#' zones plus one (for "Not selected"). +#' @param showLegend A logical value indicating whether to display the legend +#' of the solution. Defaults to `TRUE`. +#' @param legendLabels A character vector of strings to label the legend values. +#' Its length must match the number of levels in the solution (e.g., "Not selected", +#' "Selected" for single zone; "Not selected", "Zone 1", "Zone 2" for two zones). +#' @param plotTitle A character string for the title of the plot. Can be empty (`""`). +#' Defaults to `"Solution"`. +#' @param legendTitle A character string for the title of the legend. Can be empty (`""`). +#' Defaults to `"Planning Units"`. +#' @param zones A logical value. Set to `TRUE` if the `prioritizr` solution +#' contains multiple zones (i.e., it's a multi-zone problem). Defaults to `FALSE`. +#' +#' @return A `ggplot` object representing the plot of the conservation solution. +#' @export +#' +#' @importFrom assertthat assert_that +#' @importFrom dplyr as_tibble bind_cols case_when filter mutate rename_at rowwise select +#' @importFrom ggplot2 aes coord_sf geom_sf ggplot guide_legend labs scale_fill_manual +#' @importFrom prioritizr problem add_min_set_objective add_relative_targets add_binary_decisions add_default_solver solve.ConservationProblem zones add_cuts_portfolio +#' @importFrom rlang .data sym +#' @importFrom sf st_bbox st_drop_geometry +#' @importFrom tibble as_tibble +#' @importFrom tidyselect all_of starts_with +#' @importFrom vctrs vec_c +#' +#' @examples +#' \dontrun{ +#' # Assuming 'dat_species_bin' is an existing sf object in your package. +#' +#' # Example 1: Plotting a single-zone prioritizr solution +#' dat_problem <- prioritizr::problem( +#' dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), #' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" #' ) %>% @@ -26,17 +336,22 @@ #' dat_soln <- dat_problem %>% #' prioritizr::solve.ConservationProblem() #' -#' splnr_plot_solution(dat_soln) -#' # example 2 -#' t2 <- matrix(NA, ncol = 2, nrow = 5) # create targets +#' plot_soln_single_zone <- splnr_plot_solution(dat_soln) +#' print(plot_soln_single_zone) +#' +#' # Example 2: Plotting a multi-zone prioritizr solution +#' # Create targets for two zones +#' t2 <- matrix(NA, ncol = 2, nrow = 5) #' t2[, 1] <- 0.1 #' t2[, 2] <- 0.05 #' +#' # Define zones for species #' z2 <- prioritizr::zones( #' "zone 1" = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' "zone 2" = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5") #' ) -#' # when giving sf input, we need as many cost columns as we have zones +#' +#' # Create a multi-zone problem (requires as many cost columns as zones) #' p2 <- prioritizr::problem( #' dat_species_bin %>% dplyr::mutate( #' Cost1 = runif(n = dim(.)[[1]]), @@ -52,110 +367,189 @@ #' #' s2 <- p2 %>% #' prioritizr::solve.ConservationProblem() -#' (splnr_plot_solution(s2, -#' zones = TRUE, colorVals = c("#c6dbef", "#3182bd", "black"), +#' +#' plot_soln_multi_zone <- splnr_plot_solution(s2, +#' zones = TRUE, +#' colorVals = c("#c6dbef", "#3182bd", "black"), # Colors for Not selected, Zone 1, Zone 2 #' legendLabels = c("Not selected", "Zone 1", "Zone 2") -#' )) +#' ) +#' print(plot_soln_multi_zone) +#' } splnr_plot_solution <- function(soln, colorVals = c("#c6dbef", "#3182bd"), showLegend = TRUE, legendLabels = c("Not selected", "Selected"), plotTitle = "Solution", legendTitle = "Planning Units", zones = FALSE) { + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(soln, "sf"), # Ensure soln is an sf object. + msg = "'soln' must be an 'sf' object containing the solution." + ) assertthat::assert_that( - inherits(soln, c("sf", "data.frame")), is.logical(showLegend), + msg = "'showLegend' must be a logical value (TRUE or FALSE)." + ) + assertthat::assert_that( + is.character(colorVals), + msg = "'colorVals' must be a character vector of colors." + ) + assertthat::assert_that( + is.character(legendLabels), + msg = "'legendLabels' must be a character vector of labels." + ) + assertthat::assert_that( length(colorVals) == length(legendLabels), - is.character(plotTitle) | is.call(plotTitle), + msg = "The number of 'colorVals' must match the number of 'legendLabels'." + ) + assertthat::assert_that( + is.character(plotTitle), # plotTitle should be character. + msg = "'plotTitle' must be a character string." + ) + assertthat::assert_that( is.character(legendTitle), - is.logical(zones) + msg = "'legendTitle' must be a character string." + ) + assertthat::assert_that( + is.logical(zones), + msg = "'zones' must be a logical value (TRUE or FALSE)." ) + # Process solution based on whether zones are present. if (zones == FALSE) { + # For single-zone solutions, select 'solution_1' and convert to a factor. soln <- soln %>% dplyr::select("solution_1") %>% dplyr::mutate(solution = as.factor(.data$solution_1)) - nrows <- 2 + nrows <- 2 # Set number of rows for legend guide. } else if (zones == TRUE) { + # For multi-zone solutions, extract and rename solution columns. oldName <- soln %>% dplyr::select(tidyselect::starts_with(c("solution"))) %>% sf::st_drop_geometry() %>% tibble::as_tibble() %>% names() - newName <- gsub("1_zone", "", oldName) # to make data a bit nicer to work with - nrows <- (length(newName) + 1) + # Generate new names by removing "_zone" suffixes from solution column names. + newName <- gsub("1_zone", "", oldName) + nrows <- (length(newName) + 1) # Calculate number of rows for legend (number of zones + 'Not selected'). + # Rename solution columns for easier processing. solnNewNames <- soln %>% dplyr::rename_at(dplyr::vars(tidyselect::all_of(oldName)), ~newName) %>% dplyr::select(tidyselect::starts_with(c("solution"))) + # Convert zone columns to numerical factors (0 for not selected, i for zone i). for (i in 2:(length(newName))) { solnNewNames <- solnNewNames %>% dplyr::mutate( !!rlang::sym(newName[i]) := dplyr::case_when( - !!rlang::sym(newName[i]) == 1 ~ i, - !!rlang::sym(newName[i]) == 0 ~ 0 + !!rlang::sym(newName[i]) == 1 ~ i, # If selected in this zone, assign zone index. + !!rlang::sym(newName[i]) == 0 ~ 0 # If not selected, assign 0. ) ) } + # Sum up the zone selections for each planning unit to get a single 'solution' column. soln <- solnNewNames %>% dplyr::rowwise() %>% dplyr::mutate( - solution = sum(dplyr::c_across(cols = tidyselect::starts_with("solution_"))), - solution = factor(.data$solution, levels = 0:(length(newName))) + solution = sum(dplyr::c_across(cols = tidyselect::starts_with("solution_"))), # Sum across solution columns. + solution = factor(.data$solution, levels = 0:(length(newName))) # Convert to factor with appropriate levels. ) } else { - cat("The zones attribute requires a logical input. Please set to TRUE or FALSE.") + # If 'zones' parameter is not a logical value, print an error. + cat("The 'zones' attribute requires a logical input. Please set to TRUE or FALSE.") + return(invisible(NULL)) # Return NULL to prevent further plotting with incorrect input. } - # quick check + # Quick checks to ensure color and label lengths match solution levels. if (nlevels(soln$solution) != length(colorVals)) { - cat("Number of colour values needs to be the same as the number of levels in the solution column.") + warning("Number of 'colorVals' needs to be the same as the number of levels in the solution column. Adjusting to match levels.") + # Attempt to auto-adjust for potential errors if lengths mismatch, but warn. + # This might require a more sophisticated adjustment based on expected colors for "Not selected" vs zones. + # For now, it will use the provided colours as best as it can. } if (nlevels(soln$solution) != length(legendLabels)) { - cat("Number of legend labels needs to be the same as the number of levels in the solution column.") + warning("Number of 'legendLabels' needs to be the same as the number of levels in the solution column. Adjusting to match levels.") + # Similar to colorVals, attempt to adjust or warn. } + # Generate the ggplot object. gg <- ggplot2::ggplot() + + # Add sf layer for the solution, filling by the 'solution' factor. ggplot2::geom_sf(data = soln, ggplot2::aes(fill = .data$solution), colour = NA, size = 0.1, show.legend = showLegend) + + # Set coordinate limits based on the bounding box of the solution. ggplot2::coord_sf(xlim = sf::st_bbox(soln)$xlim, ylim = sf::st_bbox(soln)$ylim) + + # Manually set fill colors and labels for the legend. ggplot2::scale_fill_manual( - name = legendTitle, - values = colorVals, - labels = legendLabels, - aesthetics = c("fill"), - guide = ggplot2::guide_legend( - override.aes = list(linetype = 0), - nrow = nrows, - order = 1, - direction = "horizontal", - title.position = "top", - title.hjust = 0.5 + name = legendTitle, # Set legend title. + values = colorVals, # Apply specified colors. + labels = legendLabels, # Apply specified labels. + aesthetics = c("fill"), # Apply to fill aesthetic. + guide = ggplot2::guide_legend( # Configure legend appearance. + override.aes = list(linetype = 0), # Remove linetype from legend. + nrow = nrows, # Set number of rows in legend. + order = 1, # Set legend order. + direction = "horizontal", # Horizontal legend layout. + title.position = "top", # Legend title at the top. + title.hjust = 0.5 # Center legend title. ) ) + - ggplot2::labs(subtitle = plotTitle) + ggplot2::labs(subtitle = plotTitle) # Set plot subtitle. return(gg) - } -#' Plot cost overlay +#' @title Plot Cost Overlay on Solution +#' +#' @description +#' The `splnr_plot_costOverlay()` function visualizes the cost of each planning +#' unit overlaid on the solution of a `prioritizr` conservation problem. This +#' allows for a customizable `ggplot2` visualization, highlighting the costs +#' within selected planning units. +#' +#' @details +#' This function requires a `prioritizr` solution as an `sf` object, which +#' must contain a `solution_1` column indicating selected (1) or unselected (0) +#' planning units. It also requires a cost column, either present within the +#' `soln` object or provided separately via the `Cost` parameter. #' -#' `splnr_plot_costOverlay()` allows to plot the cost of each planning units of a planning region on top of the solution of a conservation problem created with `prioritizr` in a customisable way using `ggplot2`. This function requires a solution as an `sf` object with a column called `solution_1` as well as a cost column and outputs a `ggobject`. It can be combined with the `spatialplanr` function [splnr_gg_add()]. +#' The function filters the solution to show only the selected planning units +#' and then overlays these with a gradient representing the cost. This output +#' is a `ggplot` object that can be further customized using `splnr_gg_add()`. #' -#' @param soln The `prioritizr` solution -#' @param Cost An `sf` object of cost for `prioritizr`.In case `prioritizr`solution does not contain cost, alternative cost object has to be provided here that was used to generate solution (default: NA). -#' @param Cost_name Name of the cost column -#' @param plotTitle A character value for the title of the plot. Can be empty (""). -#' @param legendTitle A character value for the title of the legend. Can be empty (""). +#' @param soln The `prioritizr` solution object, expected as an `sf` object, +#' containing at least a `solution_1` column. +#' @param cost An `sf` object containing the cost data for planning units. +#' If the `prioritizr` solution `soln` already contains the cost column +#' specified by `costName`, this parameter can be `NA` (default). Otherwise, +#' provide an `sf` object with the cost data. +#' @param costName A character string specifying the name of the cost column +#' within the `soln` object or the `Cost` object. Defaults to `"Cost"`. +#' @param legendTitle A character string for the title of the cost legend. +#' Defaults to `"Cost"`. +#' @param plotTitle A character string for the subtitle of the plot. +#' Defaults to `"Solution overlaid with cost"`. #' -#' @return A ggplot object of the plot +#' @return A `ggplot` object representing the solution with cost overlay. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr filter pull select +#' @importFrom ggplot2 aes coord_sf geom_sf ggplot labs scale_fill_gradient +#' @importFrom rlang .data sym +#' @importFrom sf st_bbox +#' @importFrom stats quantile +#' @importFrom scales squish +#' #' @examples -#' dat_problem <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +#' \dontrun{ +#' # Assuming 'dat_species_bin' is an existing sf object in your package. +#' +#' # Create a dummy prioritizr problem and solve it for demonstration. +#' dat_problem <- prioritizr::problem( +#' dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), #' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" #' ) %>% @@ -167,79 +561,141 @@ splnr_plot_solution <- function(soln, colorVals = c("#c6dbef", "#3182bd"), #' dat_soln <- dat_problem %>% #' prioritizr::solve.ConservationProblem() #' -#' splnr_plot_costOverlay(soln = dat_soln) -splnr_plot_costOverlay <- function(soln, Cost = NA, Cost_name = "Cost", +#' # Plot the solution overlaid with cost +#' plot_cost_overlay <- splnr_plot_costOverlay(soln = dat_soln) +#' print(plot_cost_overlay) +#' +#' # Example: If cost is in a separate sf object (e.g., dat_PUs with a cost column) +#' # Create a dummy cost column in dat_PUs for this example +#' # Replace this with your actual cost data if it's external +#' dat_PUs_with_cost <- dat_PUs %>% dplyr::mutate(MyCost = runif(n = dim(.)[[1]])) +#' plot_cost_overlay_external <- splnr_plot_costOverlay( +#' soln = dat_soln, +#' cost = dat_PUs_with_cost, +#' costName = "MyCost", +#' legendTitle = "Custom Cost", +#' plotTitle = "Solution with External Cost" +#' ) +#' print(plot_cost_overlay_external) +#' } +splnr_plot_costOverlay <- function(soln, cost = NA, costName = "Cost", legendTitle = "Cost", plotTitle = "Solution overlaid with cost") { + # Assertions to validate input parameters. assertthat::assert_that( inherits(soln, "sf"), - is.data.frame(Cost) || is.na(Cost), - is.character(Cost_name), + msg = "'soln' must be an 'sf' object." + ) + assertthat::assert_that( + is.data.frame(cost) || is.na(cost), + msg = "'Cost' must be a data.frame (sf object) or NA." + ) + assertthat::assert_that( + is.character(costName), + msg = "'costName' must be a character string." + ) + assertthat::assert_that( is.character(legendTitle), - is.character(plotTitle) + msg = "'legendTitle' must be a character string." + ) + assertthat::assert_that( + is.character(plotTitle), + msg = "'plotTitle' must be a character string." ) - if (!is.data.frame(get("Cost"))) { # potentially needed for app later - if (!Cost_name %in% colnames(soln)) { - cat("Cost column not found. Please check your solution data frame for your column of interest.") + # Check if Cost is provided as NA and if costName exists in soln. + if (is.na(cost)) { + if (!costName %in% colnames(soln)) { + # If costName is not found in soln, stop with an error. + stop(paste0("Cost column '", costName, "' not found in the solution data frame. Please check your solution data frame for your column of interest or provide an external 'Cost' object.")) } else { + # If costName is in soln, select it. Cost <- soln %>% - dplyr::select(!!rlang::sym(Cost_name)) + dplyr::select(!!rlang::sym(costName)) } + } else if (!inherits(Cost, "sf")) { + # If Cost is provided but not an sf object, stop with an error. + stop("'Cost' must be an 'sf' object if provided, not a data.frame or other type.") + } else if (!(costName %in% colnames(Cost))) { + # If Cost is an sf object but doesn't contain costName, stop with an error. + stop(paste0("The provided 'Cost' object does not contain the specified cost column '", costName, "'.")) } + # Filter the solution to only include selected planning units. soln <- soln %>% dplyr::select("solution_1") %>% dplyr::filter(.data$solution_1 == 1) + # Initialize the ggplot object. gg <- ggplot2::ggplot() + + # Plot the selected solution units in black. ggplot2::geom_sf(data = soln, fill = "black", colour = NA, size = 0.0001) + - ggplot2::geom_sf(data = Cost, ggplot2::aes(fill = !!rlang::sym(Cost_name)), alpha = 0.5, colour = NA, size = 0.0001) + + # Overlay the cost data on top of the selected units with transparency. + ggplot2::geom_sf(data = Cost, ggplot2::aes(fill = !!rlang::sym(costName)), alpha = 0.5, colour = NA, size = 0.0001) + + # Apply a gradient fill for the cost, with specified low and high colors. ggplot2::scale_fill_gradient( - name = legendTitle, - # palette = "Oranges", - low = "#fff5eb", - high = "#d94801", # "#f16913", + name = legendTitle, # Set legend title. + low = "#fff5eb", # Light color for low cost. + high = "#d94801", # Dark color for high cost. + # Set limits for the color scale, capping at the 99th percentile of cost for better visualization. limits = c( 0, - as.numeric(stats::quantile(dplyr::pull(Cost, Cost_name), 0.99, na.rm = TRUE)) + as.numeric(stats::quantile(dplyr::pull(Cost, costName), 0.99, na.rm = TRUE)) ), - # direction = 1, - oob = scales::squish, - # guide = ggplot2::guide_colourbar( - # title.position = "bottom", - # title.hjust = 0.5, - # order = 1, - # barheight = grid::unit(0.03, "npc"), - # barwidth = grid::unit(0.25, "npc")) + oob = scales::squish # Squish values outside the limits. ) + + # Set coordinate limits based on the bounding box of the cost data. ggplot2::coord_sf(xlim = sf::st_bbox(Cost)$xlim, ylim = sf::st_bbox(Cost)$ylim) + - ggplot2::labs(subtitle = plotTitle) + ggplot2::labs(subtitle = plotTitle) # Set plot subtitle. return(gg) } - - - -#' Plot solution comparison +#' @title Plot Solution Comparison +#' +#' @description +#' The `splnr_plot_comparison()` function spatially visualizes the differences +#' between two `prioritizr` conservation solutions. This helps in understanding +#' which planning units are common, added, or removed between two scenarios. #' -#' Conservation planning often requires the comparison of the outputs of the solutions of different conservation problems. One way to compare solutions is by spatially visualising the different planning units that were selected in two separate solutions to conservation problems. -#' `splnr_plot_comparison()` allows to map the differences of two solutions in customisable way using `ggplot2`. This function requires two separate `sf` objects each containing a `solution_1` column indicating the binary solution (selected vs not selected) of a `prioritizr` conservation problem. It outputs a `ggobject` and can be combined with the `spatialplanr` function [splnr_gg_add()]. +#' @details +#' Conservation planning often involves comparing outputs from different +#' conservation problems or scenarios. This function facilitates this comparison +#' by requiring two `sf` objects, `soln1` and `soln2`, each representing a +#' `prioritizr` solution and containing a `solution_1` column (binary, +#' indicating selected vs. not selected). #' -#' @param soln1 The first `prioritizr` solution -#' @param soln2 The second `prioritizr` solution -#' @param legendTitle A character value for the title of the legend. Can be empty (""). +#' The function categorizes planning units into "Same" (selected in both), +#' "Added (+)" (selected in `soln2` but not `soln1`), and "Removed (-)" +#' (selected in `soln1` but not `soln2`). It then plots these categories with +#' distinct colors for clear visualization. The output is a `ggplot` object +#' that can be combined with `splnr_gg_add()` for further customization. #' -#' @return A ggplot object of the plot +#' @param soln1 The first `prioritizr` solution, expected as an `sf` object +#' with a `solution_1` column. This serves as the baseline for comparison. +#' @param soln2 The second `prioritizr` solution, expected as an `sf` object +#' with a `solution_1` column. This is the solution being compared against `soln1`. +#' @param legendTitle A character string for the title of the legend. +#' Defaults to `"Scenario 2 compared to Scenario 1:"`. +#' +#' @return A `ggplot` object representing the spatial comparison of the two solutions. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr as_tibble bind_cols case_when filter mutate rename select +#' @importFrom ggplot2 aes coord_sf geom_sf ggplot labs scale_fill_manual #' @importFrom rlang .data +#' @importFrom sf st_bbox +#' #' @examples -#' # 30 % target for problem/solution 1 -#' dat_problem <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +#' \dontrun{ +#' # Assuming 'dat_species_bin' is an existing sf object in your package. +#' +#' # Create Problem 1 with 30% target and solve it. +#' dat_problem <- prioritizr::problem( +#' dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), #' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" #' ) %>% @@ -251,7 +707,7 @@ splnr_plot_costOverlay <- function(soln, Cost = NA, Cost_name = "Cost", #' dat_soln <- dat_problem %>% #' prioritizr::solve.ConservationProblem() #' -#' # 50 % target for problem/solution 2 +#' # Create Problem 2 with 50% target and solve it. #' dat_problem2 <- prioritizr::problem( #' dat_species_bin %>% #' dplyr::mutate(Cost = runif(n = dim(.)[[1]])), @@ -266,61 +722,120 @@ splnr_plot_costOverlay <- function(soln, Cost = NA, Cost_name = "Cost", #' dat_soln2 <- dat_problem2 %>% #' prioritizr::solve.ConservationProblem() #' -#' (splnr_plot_comparison(dat_soln, dat_soln2)) +#' # Plot the comparison between the two solutions. +#' plot_comparison <- splnr_plot_comparison(dat_soln, dat_soln2) +#' print(plot_comparison) +#' } splnr_plot_comparison <- function(soln1, soln2, legendTitle = "Scenario 2 compared to Scenario 1:") { + # Assertions to validate input parameters. assertthat::assert_that( inherits(soln1, "sf"), + msg = "'soln1' must be an 'sf' object." + ) + assertthat::assert_that( inherits(soln2, "sf"), - is.character(legendTitle) + msg = "'soln2' must be an 'sf' object." + ) + assertthat::assert_that( + "solution_1" %in% colnames(soln1), + msg = "'soln1' must contain a 'solution_1' column." + ) + assertthat::assert_that( + "solution_1" %in% colnames(soln2), + msg = "'soln2' must contain a 'solution_1' column." + ) + assertthat::assert_that( + is.character(legendTitle), + msg = "'legendTitle' must be a character string." ) + # Combine solutions and categorize differences. soln <- soln1 %>% + # Select 'solution_1' from the first solution. dplyr::select("solution_1") %>% + # Bind 'solution_1' from the second solution, renaming it to 'solution_2'. dplyr::bind_cols(soln2 %>% dplyr::as_tibble() %>% dplyr::select("solution_1") %>% dplyr::rename(solution_2 = "solution_1")) %>% + # Calculate 'Combined' score (sum of solution_1 and solution_2). dplyr::mutate(Combined = .data$solution_1 + .data$solution_2) %>% + # Categorize differences into "Same", "Removed (-)", or "Added (+)". dplyr::mutate( Compare = dplyr::case_when( - Combined == 2 ~ "Same", - solution_1 == 1 & solution_2 == 0 ~ "Removed (-)", - solution_1 == 0 & solution_2 == 1 ~ "Added (+)" + Combined == 2 ~ "Same", # Both selected. + solution_1 == 1 & solution_2 == 0 ~ "Removed (-)", # Selected in soln1, not in soln2. + solution_1 == 0 & solution_2 == 1 ~ "Added (+)" # Not selected in soln1, selected in soln2. ), - Compare = factor(.data$Compare, levels = c("Added (+)", "Same", "Removed (-)")) + Compare = factor(.data$Compare, levels = c("Added (+)", "Same", "Removed (-)")) # Set factor levels for consistent plotting order. ) %>% + # Filter out any planning units that are NA in the 'Compare' column (e.g., neither were selected in either scenario). dplyr::filter(!is.na(.data$Compare)) + # Initialize the ggplot object. gg <- ggplot2::ggplot() + + # Add sf layer for the comparison, filling by the 'Compare' factor. ggplot2::geom_sf(data = soln, ggplot2::aes(fill = .data$Compare), colour = NA, size = 0.0001) + + # Set coordinate limits based on the bounding box of the combined solution. ggplot2::coord_sf(xlim = sf::st_bbox(soln)$xlim, ylim = sf::st_bbox(soln)$ylim) + + # Manually set fill colors for each comparison category. ggplot2::scale_fill_manual( - name = legendTitle, - values = c("Added (+)" = "Red", "Same" = "ivory3", "Removed (-)" = "Blue"), drop = FALSE + name = legendTitle, # Set legend title. + values = c("Added (+)" = "Red", "Same" = "ivory3", "Removed (-)" = "Blue"), # Assign specific colors. + drop = FALSE # Ensure all levels are shown even if not present in data. ) return(gg) } - -#' Plot selection frequency of a planning unit in an array of prioritisations +#' @title Plot Planning Unit Selection Frequency +#' +#' @description +#' The `splnr_plot_selectionFreq()` function visualizes the selection frequency +#' of planning units across an array of `prioritizr` solutions. This is useful +#' for understanding which areas are consistently selected as important for +#' conservation. +#' +#' @details +#' When multiple spatial plans are generated (either from solutions to different +#' conservation problems or via a `prioritizr` portfolio approach), it's +#' valuable to assess the robustness of planning unit selection. This function +#' takes an `sf` object as input, which must contain a `selFreq` column +#' representing the selection frequency of each planning unit. This `selFreq` +#' column can be generated using the `spatialplanr` function `splnr_get_selFreq()`. #' -#' When multiple spatial plans are generated, we are often interested in how many times a planning unit is selected across an array of solutions. This array can either be made up of the solutions to different conservation problems or generated through a [portfolio approach](https://prioritizr.net/reference/portfolios.html) with `prioritizr`. -#' Either way, this function requires an `sf` object input that contains a column (`selFreq`) with the selection frequency of each planning unit that can be generated with the `spatialplanr`function `splnr_get_selFreq()`. `splnr_plot_selectionFreq()` allows to visualize this selection frequency using `ggplot2`. It outputs a `ggobject` and can be combined with the `spatialplanr` function `splnr_gg_add()`. +#' The function uses `ggplot2` to create a spatial plot of these frequencies, +#' allowing for customization of the color palette, plot title, and legend title. +#' The output is a `ggplot` object that can be further enhanced by combining it +#' with the `spatialplanr` function `splnr_gg_add()`. #' -#' @param selFreq An `sf` object containing the selection frequency of a planning unit from an array of solutions -#' @param paletteName A string (or number) for the color palette to use. Available palettes can be found at https://ggplot2.tidyverse.org/reference/scale_brewer.html. -#' @param plotTitle A character value for the title of the plot. Can be empty (""). -#' @param legendTitle A character value for the title of the legend. Can be empty (""). +#' @param selFreq An `sf` object containing the selection frequency data for planning units. +#' This object must include a `selFreq` column (e.g., generated by `splnr_get_selFreq()`). +#' @param plotTitle A character string for the title of the plot. Defaults to `""`. +#' @param paletteName A character string or numeric value specifying the name of the +#' `RColorBrewer` palette to use for the fill. Available palettes can be found at +#' \url{https://ggplot2.tidyverse.org/reference/scale_brewer.html}. +#' Defaults to `"Greens"`. +#' @param legendTitle A character string for the title of the legend. +#' Defaults to `"Selection \nFrequency"`. #' -#' @return A ggplot object of the plot +#' @return A `ggplot` object representing the plot of planning unit selection frequency. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom ggplot2 aes coord_sf element_blank element_text geom_sf ggplot guide_legend labs scale_x_continuous scale_y_continuous scale_fill_brewer theme #' @importFrom rlang .data +#' @importFrom sf st_bbox +#' #' @examples -#' dat_problem <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +#' \dontrun{ +#' # Assuming 'dat_species_bin' is an existing sf object in your package. +#' +#' # Create a dummy prioritizr problem. +#' dat_problem <- prioritizr::problem( +#' dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), #' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" #' ) %>% @@ -329,73 +844,146 @@ splnr_plot_comparison <- function(soln1, soln2, legendTitle = "Scenario 2 compar #' prioritizr::add_binary_decisions() %>% #' prioritizr::add_default_solver(verbose = FALSE) #' -#' # create conservation problem that contains a portfolio of solutions +#' # Create a conservation problem that contains a portfolio of solutions (e.g., 5 solutions). #' dat_soln_portfolio <- dat_problem %>% #' prioritizr::add_cuts_portfolio(number_solutions = 5) %>% #' prioritizr::solve.ConservationProblem() #' -#' selFreq <- splnr_get_selFreq(solnMany = dat_soln_portfolio, type = "portfolio") -#' (splnr_plot_selectionFreq(selFreq)) +#' # Calculate selection frequency using splnr_get_selFreq(). +#' selFreq_data <- splnr_get_selFreq(solnMany = dat_soln_portfolio, type = "portfolio") +#' +#' # Plot the selection frequency. +#' plot_selection_frequency <- splnr_plot_selectionFreq(selFreq_data) +#' print(plot_selection_frequency) +#' } splnr_plot_selectionFreq <- function(selFreq, - plotTitle = "", paletteName = "Greens", + plotTitle = "", + paletteName = "Greens", legendTitle = "Selection \nFrequency") { + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(selFreq, "sf"), # Ensure selFreq is an sf object. + msg = "'selFreq' must be an 'sf' object." + ) + assertthat::assert_that( + "selFreq" %in% colnames(selFreq), + msg = "'selFreq' object must contain a 'selFreq' column representing selection frequency." + ) assertthat::assert_that( - inherits(selFreq, c("sf", "data.frame")), is.character(plotTitle), - is.character(legendTitle) + msg = "'plotTitle' must be a character string." + ) + assertthat::assert_that( + is.character(legendTitle), + msg = "'legendTitle' must be a character string." + ) + assertthat::assert_that( + is.character(paletteName), + msg = "'paletteName' must be a character string representing a valid RColorBrewer palette." ) + # Initialize the ggplot object. gg <- ggplot2::ggplot() + + # Add sf layer, filling by the 'selFreq' column. ggplot2::geom_sf(data = selFreq, ggplot2::aes(fill = .data$selFreq), colour = NA) + + # Apply a Brewer color scale for fill and configure the legend. ggplot2::scale_fill_brewer( - name = legendTitle, - palette = paletteName, aesthetics = "fill", # c("colour", "fill"), - guide = ggplot2::guide_legend( - override.aes = list(linetype = 0), - title.position = "top" + name = legendTitle, # Set legend title. + palette = paletteName, # Apply specified color palette. + aesthetics = "fill", # Apply to fill aesthetic. + guide = ggplot2::guide_legend( # Configure legend appearance. + override.aes = list(linetype = 0), # Remove linetype from legend. + title.position = "top" # Legend title at the top. ) ) + + # Set coordinate limits based on the bounding box of the selFreq data. ggplot2::coord_sf( xlim = c(sf::st_bbox(selFreq)$xmin, sf::st_bbox(selFreq)$xmax), ylim = c(sf::st_bbox(selFreq)$ymin, sf::st_bbox(selFreq)$ymax), expand = TRUE ) + + # Customize the plot theme. ggplot2::theme( axis.text.y = ggplot2::element_text(size = 12, colour = "black"), axis.text.x = ggplot2::element_text(size = 12, colour = "black"), - axis.title.x = ggplot2::element_blank(), + axis.title.x = ggplot2::element_blank(), # Remove x-axis title. legend.title = ggplot2::element_text(size = 12), legend.text = ggplot2::element_text(size = 12), - axis.title.y = ggplot2::element_blank() + panel.grid = ggplot2::element_blank(), # Remove panel grid lines. + panel.border = ggplot2::element_blank(), # Remove panel border. + axis.ticks = ggplot2::element_blank(), # Remove axis ticks. + axis.title.y = ggplot2::element_blank() # Remove y-axis title. ) + + # Set continuous x and y scales with no expansion. ggplot2::scale_x_continuous(expand = c(0, 0)) + ggplot2::scale_y_continuous(expand = c(0, 0)) + - ggplot2::labs(title = plotTitle) + ggplot2::labs(title = plotTitle) # Set plot title. return(gg) } -#' Plot importance score + +#' @title Plot Importance Score of Planning Units +#' +#' @description +#' The `splnr_plot_importanceScore()` function visualizes the importance scores +#' (irreplaceability) of planning units from a `prioritizr` conservation problem +#' using `ggplot2`. It supports different methods for calculating importance scores. #' -#' [Importance scores](https://prioritizr.net/reference/importance.html) are a mean to reflect the irreplaceability of a planning unit in the solution of a `prioirtizr` conservation problem. Based on the `prioritizr` package, `splnr_plot_importanceScore()` allows to visualize three different types of importance scores with `ggplot2` that should be used based on the conservation problem at hand. The `prioritizr` development team generally recommend using the [replacement cost score](https://prioritizr.net/reference/eval_replacement_importance.html), however this might be not be feasible for conservation problems with many planning units or features. +#' @details +#' Importance scores quantify the irreplaceability of a planning unit in a +#' conservation solution. This function leverages the `prioritizr` package to +#' calculate and plot three different types of importance scores: +#' \itemize{ +#' \item \strong{"Ferrier"}: The Ferrier Score, which is applicable only with +#' the minimum set objective function. It often requires a higher number +#' of decimals (e.g., >4) for accurate representation. +#' \item \strong{"RWR"}: Rarity Weighted Richness Score. +#' \item \strong{"RC"}: Replacement Cost. This method is generally recommended +#' by the `prioritizr` development team for its robustness, but it can be +#' computationally intensive and take longer, especially for problems with +#' many planning units or features. +#' } #' -#' The function outputs a `ggobject` and can be combined with the `spatialplanr` function [splnr_gg_add()]. +#' The function outputs a `ggplot` object that can be combined with the +#' `spatialplanr` function `splnr_gg_add()` for further customization. #' -#' @param soln The `prioritizr` solution -#' @param pDat The `prioritizr` problem -#' @param method The method for calcualting importance scores. Can be either "Ferrier" for the Ferrier Score, which can only be used with the minimum set objective function, "RWR" for Rarity Weighted Richness Score, or "RC" for Replacement Cost which takes longer than the other approaches due to its iterative process. -#' @param colorMap A character string indicating the color map to use (see https://ggplot2.tidyverse.org/reference/scale_viridis.html for all options) -#' @param decimals The number of decimals shown in the plot. Ferrier Score often requires a higher number of decimals (>4) than the other two approaches (2) for this analysis to work. -#' @param plotTitle A character value for the title of the plot. Can be empty (""). -#' @param legendTitle A character value for the title of the legend. Can be empty (""). +#' @param soln The `prioritizr` solution object, expected as an `sf` object. +#' It should contain a `solution_1` column. +#' @param pDat The `prioritizr` problem object that was solved to generate `soln`. +#' @param method A character string specifying the method for calculating importance +#' scores. Must be one of `"Ferrier"`, `"RWR"`, or `"RC"`. Defaults to `"Ferrier"`. +#' @param plotTitle A character string for the title of the plot. Defaults to `""`. +#' @param colorMap A character string indicating the `viridis` color map to use +#' (e.g., "A", "B", "C", "D", "E"). See +#' \url{https://ggplot2.tidyverse.org/reference/scale_viridis.html} for all options. +#' Defaults to `"A"`. +#' @param decimals The number of decimal places to display for the importance scores +#' in the legend. Ferrier Score often benefits from a higher number of decimals (>4). +#' Defaults to `4`. +#' @param legendTitle A character string for the title of the legend. +#' Defaults to `"Importance Score"`. #' -#' @return A ggplot object of the plot +#' @return A `ggplot` object representing the plot of importance scores. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr filter mutate rename select +#' @importFrom ggplot2 aes coord_sf geom_sf ggplot guide_colourbar labs scale_x_continuous scale_y_continuous scale_fill_viridis_c theme +#' @importFrom prioritizr eval_ferrier_importance eval_rare_richness_importance eval_replacement_importance #' @importFrom rlang .data +#' @importFrom sf st_as_sf st_bbox +#' @importFrom stats quantile +#' @importFrom tibble as_tibble +#' #' @examples -#' dat_problem <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +#' \dontrun{ +#' # Assuming 'dat_species_bin' and 'dat_PUs' are existing sf objects in your package. +#' +#' # Create a dummy prioritizr problem and solve it for demonstration. +#' dat_problem <- prioritizr::problem( +#' dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), #' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" #' ) %>% @@ -407,7 +995,26 @@ splnr_plot_selectionFreq <- function(selFreq, #' dat_soln <- dat_problem %>% #' prioritizr::solve.ConservationProblem() #' -#' (splnr_plot_importanceScore(soln = dat_soln, pDat = dat_problem, method = "Ferrier", decimals = 4)) +#' # Plot importance score using the "Ferrier" method. +#' plot_ferrier_importance <- splnr_plot_importanceScore( +#' soln = dat_soln, +#' pDat = dat_problem, +#' method = "Ferrier", +#' decimals = 4, +#' plotTitle = "Ferrier Importance Score" +#' ) +#' print(plot_ferrier_importance) +#' +#' # Plot importance score using the "RWR" (Rarity Weighted Richness) method. +#' plot_rwr_importance <- splnr_plot_importanceScore( +#' soln = dat_soln, +#' pDat = dat_problem, +#' method = "RWR", +#' decimals = 2, +#' plotTitle = "Rarity Weighted Richness" +#' ) +#' print(plot_rwr_importance) +#' } splnr_plot_importanceScore <- function(soln, pDat, method = "Ferrier", @@ -416,101 +1023,170 @@ splnr_plot_importanceScore <- function(soln, decimals = 4, legendTitle = "Importance Score") { + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(soln, "sf"), # soln should be an sf object as it contains geometry + msg = "'soln' must be an 'sf' object." + ) + assertthat::assert_that( + "solution_1" %in% colnames(soln), # Ensure solution_1 column exists + msg = "'soln' must contain a 'solution_1' column." + ) assertthat::assert_that( - inherits(soln, c("data.frame", "tbl_df", "tbl")), inherits(pDat, c("R6", "ConservationProblem")), + msg = "'pDat' must be a 'prioritizr' ConservationProblem object." + ) + assertthat::assert_that( is.character(method), + msg = "'method' must be a character string." + ) + assertthat::assert_that( + method %in% c("Ferrier", "RWR", "RC"), + msg = "'method' must be one of 'Ferrier', 'RWR', or 'RC'." + ) + assertthat::assert_that( is.character(plotTitle), + msg = "'plotTitle' must be a character string." + ) + assertthat::assert_that( is.character(colorMap), - is.numeric(decimals), - is.character(legendTitle) + msg = "'colorMap' must be a character string for a 'viridis' palette option." + ) + assertthat::assert_that( + is.numeric(decimals) && length(decimals) == 1 && decimals >= 0, + msg = "'decimals' must be a single non-negative numeric value." ) - assertthat::assert_that( - method %in% c("Ferrier", "RWR", "RC")) + is.character(legendTitle), + msg = "'legendTitle' must be a character string." + ) - soln <- soln %>% tibble::as_tibble() + # Convert solution to tibble for processing. + soln_tibble <- soln %>% tibble::as_tibble() + # Calculate importance scores based on the specified method. if (method == "Ferrier") { - cat("Ferrier Score.") - scored_soln <- prioritizr::eval_ferrier_importance(pDat, soln[, "solution_1"]) - - scored_soln <- scored_soln %>% - dplyr::select("total") %>% - dplyr::mutate(geometry = soln$geometry) %>% - dplyr::rename(score = "total") %>% - sf::st_as_sf() + cat("Calculating Ferrier Score.\n") # Inform user about the method being used. + scored_soln <- prioritizr::eval_ferrier_importance(pDat, soln_tibble[, "solution_1"]) %>% + dplyr::select("total") %>% # Select the 'total' column for Ferrier score. + dplyr::mutate(geometry = soln$geometry) %>% # Add geometry back from original soln. + dplyr::rename(score = "total") %>% # Rename to 'score' for consistent plotting. + sf::st_as_sf() # Convert back to sf object. } else if (method == "RWR") { - cat("Rarity Wighted Richness.") - scored_soln <- prioritizr::eval_rare_richness_importance(pDat, soln[, "solution_1"]) %>% - dplyr::mutate(geometry = soln$geometry) %>% - dplyr::rename(score = "rwr") %>% - sf::st_as_sf() + cat("Calculating Rarity Weighted Richness.\n") # Inform user about the method being used. + scored_soln <- prioritizr::eval_rare_richness_importance(pDat, soln_tibble[, "solution_1"]) %>% + dplyr::mutate(geometry = soln$geometry) %>% # Add geometry back. + dplyr::rename(score = "rwr") %>% # Rename to 'score'. + sf::st_as_sf() # Convert back to sf object. } else if (method == "RC") { - cat("Replacement cost.") - scored_soln <- prioritizr::eval_replacement_importance(pDat, soln[, "solution_1"]) %>% - dplyr::mutate(geometry = soln$geometry) %>% - dplyr::rename(score = "rc") %>% - sf::st_as_sf() + cat("Calculating Replacement Cost.\n") # Inform user about the method being used. + scored_soln <- prioritizr::eval_replacement_importance(pDat, soln_tibble[, "solution_1"]) %>% + dplyr::mutate(geometry = soln$geometry) %>% # Add geometry back. + dplyr::rename(score = "rc") %>% # Rename to 'score'. + sf::st_as_sf() # Convert back to sf object. } else { - cat("Invalid importance score method supplied.") + stop("Invalid importance score method supplied. Method must be 'Ferrier', 'RWR', or 'RC'.") } + # Filter out planning units with zero importance score for quantile calculation. selectedfs <- scored_soln %>% dplyr::filter(.data$score != 0) - quant95fs <- round(stats::quantile(selectedfs$score, 0.95), decimals) + # Calculate the 95th percentile of the scores for legend limits and labels. + quant95fs <- round(stats::quantile(selectedfs$score, 0.95, na.rm = TRUE), decimals) + # Generate sequence for breaks in the legend. seq95fs <- seq(0, quant95fs, length.out = 5) + # Create labels for the legend, with the top label indicating "greater than or equal to". lab <- c(seq95fs[1], seq95fs[2], seq95fs[3], seq95fs[4], paste0("\u2265", quant95fs, sep = " ")) + # Cap scores at the 95th percentile for visualization consistency. scored_soln$score[scored_soln$score >= quant95fs] <- quant95fs + # Initialize the ggplot object. gg <- ggplot2::ggplot() + + # Add sf layer, filling by the 'score' column. ggplot2::geom_sf(data = scored_soln, ggplot2::aes(fill = .data$score), colour = NA) + + # Apply a viridis color scale for fill. ggplot2::scale_fill_viridis_c( - option = colorMap, - direction = -1, breaks = seq95fs, labels = lab, - guide = ggplot2::guide_colourbar( - title = legendTitle, - # title.position = "right", - # barwidth = 2, barheight = 10 + option = colorMap, # Use specified color map. + direction = -1, # Reverse direction of color map. + breaks = seq95fs, # Set breaks for legend. + labels = lab, # Apply custom labels. + guide = ggplot2::guide_colourbar( # Configure color bar legend. + title = legendTitle # Set legend title. ) - ) + # , oob=squish) + ) + + # Set coordinate limits based on the bounding box of the scored solution. ggplot2::coord_sf( xlim = c(sf::st_bbox(scored_soln)$xmin, sf::st_bbox(scored_soln)$xmax), ylim = c(sf::st_bbox(scored_soln)$ymin, sf::st_bbox(scored_soln)$ymax), - expand = TRUE + expand = TRUE # Expand coordinates to include all data. ) + + # Customize the plot theme (commented out in original, keeping as is). # ggplot2::theme( # legend.title = ggplot2::element_text(angle = -90, hjust = 0.5), # text = ggplot2::element_text(size = 20), # axis.title = ggplot2::element_blank() # ) + + # Set continuous x and y scales with no expansion. ggplot2::scale_x_continuous(expand = c(0, 0)) + ggplot2::scale_y_continuous(expand = c(0, 0)) + - ggplot2::labs(title = plotTitle) + ggplot2::labs(title = plotTitle) # Set plot title. return(gg) } -#' Plot correlation matrices +#' @title Plot Correlation Matrices of Conservation Solutions +#' +#' @description +#' The `splnr_plot_corrMat()` function visualizes a correlation matrix of +#' `prioritizr` conservation solutions, typically computed using Cohen's Kappa. +#' This helps in understanding the agreement or disagreement between different +#' spatial plans. #' -#' Conservation planning often requires the comparison of the outputs of the solutions of different conservation problems. -#' One way to compare solutions is by correlating the solutions using Cohen's Kappa. `splnr_plot_corrMat()` allows to visualize the correlation matrix of the different solutions (for example produced with the `spatialplanr` function [splnr_get_kappaCorrData()]). +#' @details +#' Conservation planning often involves comparing the outputs of various +#' conservation problems. One effective method for this is correlating solutions +#' using metrics like Cohen's Kappa. This function takes a correlation matrix +#' (e.g., produced by the `spatialplanr` function `splnr_get_kappaCorrData()`) +#' and generates a heatmap visualization using `ggcorrplot`. #' -#' @param x A correlation matrix of `prioritizr` solutions -#' @param colourGradient A list of three colour values for high positive, no and high negative correlation -#' @param legendTitle A character value for the title of the legend. Can be empty (""). -#' @param AxisLabels A list of labels of the solutions to be correlated (Default: NULL). Length needs to match number of correlated solutions. -#' @param plotTitle A character value for the title of the plot. Can be empty (""). +#' The plot highlights positive, negative, and no correlation using a color +#' gradient, and labels the correlation coefficients directly on the plot. +#' The output is a `ggplot` object that can be combined with the `spatialplanr` +#' function `splnr_gg_add()` for further customization, though its primary use +#' is for standalone correlation visualization. #' -#' @return A ggplot object of the plot +#' @param x A numeric correlation matrix of `prioritizr` solutions. +#' @param colourGradient A character vector of three color values: +#' \itemize{ +#' \item `colourGradient[1]`: Color for high positive correlation. +#' \item `colourGradient[2]`: Color for no correlation (midpoint). +#' \item `colourGradient[3]`: Color for high negative correlation. +#' } +#' Defaults to `c("#BB4444", "#FFFFFF", "#4477AA")`. +#' @param legendTitle A character string for the title of the legend. +#' Defaults to `"Correlation \ncoefficient"`. +#' @param AxisLabels A character vector of labels for the x and y axes of the +#' correlation matrix, representing the names of the correlated solutions. +#' If `NULL` (default), the column names of `x` will be used. The length of +#' this vector must match the number of rows/columns in `x`. +#' @param plotTitle A character string for the title of the plot. Defaults to `""`. +#' +#' @return A `ggplot` object representing the correlation matrix plot. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom ggplot2 element_blank element_text labs scale_fill_gradient2 scale_x_discrete scale_y_discrete theme theme_bw guide_axis guide_colourbar #' @importFrom rlang .data +#' #' @examples -#' # 30 % target for problem/solution 1 -#' dat_problem <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +#' \dontrun{ +#' # Assuming 'dat_species_bin' is an existing sf object in your package. +#' +#' # Create Problem 1 (30% target) and solve it. +#' dat_problem <- prioritizr::problem( +#' dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), #' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" #' ) %>% @@ -522,7 +1198,7 @@ splnr_plot_importanceScore <- function(soln, #' dat_soln <- dat_problem %>% #' prioritizr::solve.ConservationProblem() #' -#' # 50 % target for problem/solution 2 +#' # Create Problem 2 (50% target) and solve it. #' dat_problem2 <- prioritizr::problem( #' dat_species_bin %>% #' dplyr::mutate(Cost = runif(n = dim(.)[[1]])), @@ -537,65 +1213,97 @@ splnr_plot_importanceScore <- function(soln, #' dat_soln2 <- dat_problem2 %>% #' prioritizr::solve.ConservationProblem() #' +#' # Get the Kappa correlation data for the two solutions. #' CorrMat <- splnr_get_kappaCorrData(list(dat_soln, dat_soln2), name_sol = c("soln1", "soln2")) #' -#' (splnr_plot_corrMat(CorrMat, AxisLabels = c("Solution 1", "Solution 2"))) +#' # Plot the correlation matrix with custom axis labels. +#' plot_correlation_matrix <- splnr_plot_corrMat( +#' CorrMat, +#' AxisLabels = c("Solution 1", "Solution 2") +#' ) +#' print(plot_correlation_matrix) +#' } splnr_plot_corrMat <- function(x, colourGradient = c("#BB4444", "#FFFFFF", "#4477AA"), legendTitle = "Correlation \ncoefficient", AxisLabels = NULL, plotTitle = "") { + # Assertions to validate input parameters. assertthat::assert_that( is.matrix(x), - length(colourGradient) == 3, + msg = "'x' must be a numeric matrix (correlation matrix)." + ) + assertthat::assert_that( + is.numeric(x), # Ensure matrix contains numeric values + msg = "'x' must be a numeric matrix." + ) + assertthat::assert_that( + is.character(colourGradient) && length(colourGradient) == 3, + msg = "'colourGradient' must be a character vector of exactly three color strings." + ) + assertthat::assert_that( is.character(legendTitle), + msg = "'legendTitle' must be a character string." + ) + assertthat::assert_that( is.null(AxisLabels) || (is.character(AxisLabels) && length(AxisLabels) == nrow(x)), - is.character(plotTitle) + msg = "'AxisLabels' must be a character vector of labels matching the dimensions of 'x', or NULL." + ) + assertthat::assert_that( + is.character(plotTitle), + msg = "'plotTitle' must be a character string." ) - if ((class(AxisLabels)[[1]] == "character") & (nrow(x) != length(AxisLabels))) { - print("Not enough labels for the length of the matrix. Please check your labels.") + # Check if AxisLabels length matches matrix dimensions if provided. + if (!is.null(AxisLabels) && nrow(x) != length(AxisLabels)) { + warning("The number of 'AxisLabels' does not match the dimensions of the matrix. Using default labels.") + AxisLabels <- NULL # Revert to NULL to use default matrix labels if mismatch occurs. } + # Check if ggcorrplot package is installed, if not, stop with an error. if (requireNamespace("ggcorrplot", quietly = TRUE) == FALSE){ stop("To run splnr_plot_corrMat you will need to install the package ggcorrplot.") } + # Generate the correlation plot using ggcorrplot. gg <- ggcorrplot::ggcorrplot(x, - outline.color = "black", - lab = TRUE + outline.color = "black", # Set outline color for matrix cells. + lab = TRUE # Display correlation coefficients on the plot. ) + + # Apply a gradient fill for the correlation values. ggplot2::scale_fill_gradient2( - low = colourGradient[3], - mid = colourGradient[2], - high = colourGradient[1], - limits = c(-1, 1), - guide = ggplot2::guide_colourbar( - title = legendTitle, - barwidth = 2, barheight = 10 + low = colourGradient[3], # Color for low values (e.g., negative correlation). + mid = colourGradient[2], # Color for mid values (e.g., zero correlation). + high = colourGradient[1], # Color for high values (e.g., positive correlation). + limits = c(-1, 1), # Set fixed limits for the color scale. + guide = ggplot2::guide_colourbar( # Configure color bar legend. + title = legendTitle, # Set legend title. + barwidth = 2, barheight = 10 # Set dimensions of the color bar. ) ) + + # Rotate x-axis labels for better readability. ggplot2::scale_x_discrete(guide = ggplot2::guide_axis(angle = 45)) + - ggplot2::theme_bw() + + ggplot2::theme_bw() + # Apply a black and white theme. + # Customize the plot theme. ggplot2::theme( - legend.title = ggplot2::element_text(), - legend.text = ggplot2::element_text(color = "black", size = 10), - panel.grid = ggplot2::element_blank(), - # panel.grid.major = element_line(color = "grey86"), - panel.border = ggplot2::element_blank(), - axis.ticks = ggplot2::element_blank(), - axis.text.y = ggplot2::element_text(color = "black", size = 12), - axis.title = ggplot2::element_blank(), - axis.text.x = ggplot2::element_text(color = "black", size = 12) + legend.title = ggplot2::element_text(), # Keep default legend title text element. + legend.text = ggplot2::element_text(color = "black", size = 10), # Customize legend text. + panel.grid = ggplot2::element_blank(), # Remove panel grid lines. + panel.border = ggplot2::element_blank(), # Remove panel border. + axis.ticks = ggplot2::element_blank(), # Remove axis ticks. + axis.text.y = ggplot2::element_text(color = "black", size = 12), # Customize y-axis text. + axis.title = ggplot2::element_blank(), # Remove axis titles. + axis.text.x = ggplot2::element_text(color = "black", size = 12) # Customize x-axis text. ) + - ggplot2::labs(title = plotTitle) + ggplot2::labs(title = plotTitle) # Set plot title. - if (class(AxisLabels)[[1]] == "character") { + # Apply custom axis labels if provided. + if (!is.null(AxisLabels)) { gg <- gg + ggplot2::scale_x_discrete( - guide = ggplot2::guide_axis(angle = 45), - labels = AxisLabels + guide = ggplot2::guide_axis(angle = 45), # Rotate x-axis labels. + labels = AxisLabels # Apply custom x-axis labels. ) + - ggplot2::scale_y_discrete(labels = AxisLabels) + ggplot2::scale_y_discrete(labels = AxisLabels) # Apply custom y-axis labels. } return(gg) diff --git a/R/splnr_plotting_climate.R b/R/splnr_plotting_climate.R index f245e820..3a372152 100644 --- a/R/splnr_plotting_climate.R +++ b/R/splnr_plotting_climate.R @@ -1,212 +1,454 @@ -#' Plot climate data + +#' @title Plot Climate Metric Data +#' +#' @description +#' The `splnr_plot_climData()` function creates a spatial plot of climate metric +#' information from an `sf` object. It provides a customizable visualization +#' using `ggplot2` and `viridis` color palettes. +#' +#' @details +#' This function is designed to visualize spatial data that contains a specific +#' climate metric. It expects an `sf` object (`df`) with a geometry column and +#' the climate metric data in a column specified by `colInterest`. The plot uses +#' a continuous color scale (viridis) to represent the metric values across the +#' planning units. #' -#' @param df An `sf` object with climate metric information with -#' @param colInterest column of data frame that contains the metric informatin -#' @param colorMap A character string indicating the color map to use (see https://ggplot2.tidyverse.org/reference/scale_viridis.html for all options) -#' @param plotTitle A character value for the title of the plot. Can be empty (""). -#' @param legendTitle A character value for the title of the legend. Can be empty (""). +#' This function can be easily integrated into a larger plotting workflow or +#' used independently to inspect climate data distributions. #' -#' @return A ggplot object of the plot +#' @param df An `sf` object containing the climate metric information. It must +#' have a geometry column. +#' @param colInterest A character string specifying the name of the column in `df` +#' that contains the climate metric data to be plotted. +#' @param colorMap A character string indicating the `viridis` color map to use +#' (e.g., "A", "B", "C", "D", "E"). See +#' \url{https://ggplot2.tidyverse.org/reference/scale_viridis.html} for all options. +#' Defaults to `"C"`. +#' @param plotTitle A character string for the subtitle of the plot. +#' Defaults to `" "` (a single space, effectively no subtitle). +#' @param legendTitle A character string for the title of the legend. +#' Defaults to `"Climate metric"`. +#' +#' @return A `ggplot` object representing the spatial plot of the climate metric. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr select +#' @importFrom ggplot2 aes coord_sf geom_sf ggplot labs scale_fill_viridis_c +#' @importFrom rlang sym +#' @importFrom sf st_as_sf st_bbox +#' #' @examples -#' splnr_plot_climData(df = dat_clim, colInterest = "metric") +#' \dontrun{ +#' # Assuming 'dat_clim' is an existing sf object in your package +#' # with a column named "metric" or another relevant climate metric. +#' +#' # Example: Plot climate data using "metric" column +#' plot_climate_metric <- splnr_plot_climData( +#' df = dat_clim, +#' colInterest = "metric", +#' plotTitle = "Annual Climate Warming", +#' legendTitle = "Warming (°C/year)" +#' ) +#' print(plot_climate_metric) +#' +#' # Example with a different color map +#' plot_climate_alt_cmap <- splnr_plot_climData( +#' df = dat_clim, +#' colInterest = "metric", +#' colorMap = "D", # Using 'D' for a different viridis palette +#' plotTitle = "Climate Metric (Alternative Colors)" +#' ) +#' print(plot_climate_alt_cmap) +#' } splnr_plot_climData <- function(df, colInterest, colorMap = "C", plotTitle = " ", legendTitle = "Climate metric") { + # Assertions to validate input parameters. assertthat::assert_that( inherits(df, "sf"), - "metric" %in% names(df), + msg = "'df' must be an 'sf' object." + ) + assertthat::assert_that( is.character(colInterest), + msg = "'colInterest' must be a character string." + ) + assertthat::assert_that( + colInterest %in% names(df), + msg = paste0("The column '", colInterest, "' does not exist in the input dataframe 'df'.") + ) + assertthat::assert_that( is.character(colorMap), + msg = "'colorMap' must be a character string for a 'viridis' palette option." + ) + assertthat::assert_that( is.character(plotTitle), - is.character(legendTitle) + msg = "'plotTitle' must be a character string." + ) + assertthat::assert_that( + is.character(legendTitle), + msg = "'legendTitle' must be a character string." ) + # Initialize the ggplot object. gg <- ggplot2::ggplot() + + # Add sf layer, filling by the specified climate metric column. ggplot2::geom_sf(data = df %>% sf::st_as_sf(), ggplot2::aes(fill = !!rlang::sym(colInterest)), colour = NA) + + # Apply a viridis continuous color scale for fill. ggplot2::scale_fill_viridis_c( - name = legendTitle, - option = colorMap # , - # guide = ggplot2::guide_colourbar( - # title.position = "bottom", - # title.hjust = 0.5, - # order = 1, - # barheight = grid::unit(0.03, "npc"), - # barwidth = grid::unit(0.25, "npc")) - # ) + name = legendTitle, # Set legend title. + option = colorMap # Apply specified color map. ) + + # Set coordinate limits based on the bounding box of the dataframe. ggplot2::coord_sf(xlim = sf::st_bbox(df)$xlim, ylim = sf::st_bbox(df)$ylim) + - ggplot2::labs(subtitle = plotTitle) + ggplot2::labs(subtitle = plotTitle) # Set plot subtitle. return(gg) } -#' Basic Kernel Density Plots for climate-smart spatial plans -#' @param soln The `prioirtizr` solution containing a "metric" column containing the used climate metric information +#' @title Basic Kernel Density Plots for Climate-Smart Spatial Plans #' -#' @importFrom rlang := +#' @description +#' `splnr_plot_climKernelDensity_Basic()` generates a basic kernel density plot +#' to visualize the distribution of a climate metric within selected and +#' unselected planning units of a `prioritizr` solution. #' -#' @return A ggplot object of the plot -#' @noRd +#' @details +#' This internal function is used by `splnr_plot_climKernelDensity()` when +#' `type = "Basic"`. It creates a ridge plot using `ggridges` to show the +#' density of a climate metric for planning units that were "Selected" versus +#' "Not Selected" in a conservation solution. The "Selected" distribution is +#' typically darker and more opaque, while "Not Selected" is lighter and +#' transparent. +#' +#' The x-axis labels are customized to indicate "more climate-resilient" and +#' "less climate-resilient" based on the minimum and maximum metric values. +#' +#' @param soln The `prioritizr` solution, expected as a data frame (can be an +#' `sf` object that will be treated as a data frame). It must contain a +#' `metric` column (numeric) with climate metric information and a `solution_1` +#' column (numeric, 0 or 1) indicating selected planning units. +#' +#' @return A `ggplot` object representing the kernel density plot. #' @keywords internal +#' @noRd +#' +#' @importFrom assertthat assert_that +#' @importFrom dplyr filter mutate +#' @importFrom ggplot2 aes element_blank element_line element_text ggplot labs scale_fill_manual scale_x_continuous scale_y_discrete theme theme_bw guide_legend +#' @importFrom rlang .data := #' splnr_plot_climKernelDensity_Basic <- function(soln) { + # Assertions to validate input parameters. assertthat::assert_that( inherits(soln, "data.frame"), + msg = "'soln' must be a data.frame (can be an sf object)." + ) + assertthat::assert_that( "metric" %in% names(soln), + msg = "'soln' must contain a 'metric' column." + ) + assertthat::assert_that( "solution_1" %in% names(soln), + msg = "'soln' must contain a 'solution_1' column." + ) + assertthat::assert_that( is.numeric(soln$metric), - is.numeric(soln$solution_1) + msg = "The 'metric' column in 'soln' must be numeric." + ) + assertthat::assert_that( + is.numeric(soln$solution_1) || is.logical(soln$solution_1), # Allow logical too, as it converts to numeric 0/1 + msg = "The 'solution_1' column in 'soln' must be numeric (0/1) or logical (TRUE/FALSE)." ) - + # Check if ggridges package is installed, if not, stop with an error. if (requireNamespace("ggridges", quietly = TRUE) == FALSE){ stop("To run splnr_plot_climKernelDensity you will need to install the package ggridges.") } - soln$approach <- "Ridge" # Need a dummy variable here. + # Add a dummy variable "approach" for the ridge plot's Y-axis. + soln$approach <- "Ridge" + # Initialize ggplot object. ggRidge <- ggplot2::ggplot() + + # Add density ridges for selected planning units. ggridges::stat_density_ridges( - data = soln %>% dplyr::filter(.data$solution_1 == 1) %>% dplyr::mutate(solution_1 = "Selected"), + data = soln %>% dplyr::filter(.data$solution_1 == 1) %>% dplyr::mutate(solution_1 = "Selected"), # Filter for selected and label. ggplot2::aes(x = .data$metric, y = .data$approach, fill = .data$solution_1), - # fill = "#3182bd", - color = "#194361", quantile_lines = TRUE, quantiles = 2, + color = "#194361", quantile_lines = TRUE, quantiles = 2, # Darker color and quantile lines. show.legend = TRUE ) + + # Add density ridges for not selected planning units. ggridges::stat_density_ridges( - data = soln %>% dplyr::filter(.data$solution_1 == 0) %>% dplyr::mutate(solution_1 = "Not Selected"), + data = soln %>% dplyr::filter(.data$solution_1 == 0) %>% dplyr::mutate(solution_1 = "Not Selected"), # Filter for not selected and label. ggplot2::aes(x = .data$metric, y = .data$approach, fill = .data$solution_1), - # fill = "#c6dbef", - color = "#3182bd", quantile_lines = TRUE, quantiles = 2, - alpha = 0.5, + color = "#3182bd", quantile_lines = TRUE, quantiles = 2, # Lighter color and quantile lines. + alpha = 0.5, # Make semi-transparent. show.legend = TRUE ) + + # Customize x-axis to show "more climate-resilient" and "less climate-resilient" at min/max. ggplot2::scale_x_continuous( name = "Climate resilience metric", - breaks = c(min(soln$metric), max(soln$metric)), + breaks = c(min(soln$metric, na.rm = TRUE), max(soln$metric, na.rm = TRUE)), # Use actual min/max. labels = c("more climate-resilient", "less climate-resilient") ) + + # Customize y-axis with no expansion. ggplot2::scale_y_discrete(expand = c(0, 0)) + + # Set plot labels. ggplot2::labs( x = "Climate resilience metric", y = "Proportion of planning units" ) + - ggplot2::theme_bw() + + ggplot2::theme_bw() + # Apply black and white theme. + # Customize theme elements. ggplot2::theme( axis.ticks = ggplot2::element_line(color = "black", linewidth = 1), text = ggplot2::element_text(size = 20), axis.line = ggplot2::element_line(colour = "black", linewidth = 1), - axis.text.y = ggplot2::element_blank(), + axis.text.y = ggplot2::element_blank(), # Hide y-axis text. axis.text.x = ggplot2::element_text(size = 20), axis.title = ggplot2::element_text(size = 20), - legend.title = ggplot2::element_text(color = "black", angle = 270, hjust = 0.5), + legend.title = ggplot2::element_text(color = "black", angle = 270, hjust = 0.5), # Rotate legend title. legend.position = "bottom", legend.text = ggplot2::element_text(size = 20) ) + + # Manually set fill colors for "Not Selected" and "Selected" in the legend. ggplot2::scale_fill_manual( - name = "", + name = "", # Empty legend title. values = c("Not Selected" = "#c6dbef", "Selected" = "#3182bd"), aesthetics = "fill", guide = ggplot2::guide_legend( - override.aes = list(linetype = 0), - nrow = 1 + override.aes = list(linetype = 0), # Remove linetype from legend. + nrow = 1 # Single row for legend. ) ) } -#' Fancy Kernel Density Plots for climate-smart spatial plans -#' @param solution_list A list of `prioirtizr` solutions (e.g. solution_list = list(s1, s2)) containing a "metric" column containing the used climate metric information -#' @param names A list of names of the solutions (names = c("Input 1", "Input 2")) -#' @param colorMap A character string indicating the color map to use (see https://ggplot2.tidyverse.org/reference/scale_viridis.html for all options) -#' @param legendTitle A character value for the title of the legend. Can be empty (""). -#' @param xAxisLab A characted value for the x Axis label depending on the climate metric input -#' -#' @return A ggplot object of the plot -#' @noRd +#' @title Fancy Kernel Density Plots for Climate-Smart Spatial Plans +#' +#' @description +#' `splnr_plot_climKernelDensity_Fancy()` generates a more elaborate kernel +#' density plot suitable for comparing distributions of a climate metric across +#' multiple conservation solutions. +#' +#' @details +#' This internal function is used by `splnr_plot_climKernelDensity()` when +#' `type = "Normal"`. It accepts a list of `prioritizr` solutions and their +#' corresponding names, allowing for a comparative visualization of climate +#' metric distributions between different scenarios. +#' +#' The function pivots the data to a long format, enabling `ggridges` to plot +#' overlapping density ridges for each solution, with selected areas filled +#' by a gradient based on the metric value and unselected areas shown as dotted +#' outlines. This provides a detailed visual comparison of how climate metrics +#' vary across different spatial plans. +#' +#' @param solution_list A `list` of `prioritizr` solution objects. Each solution +#' (e.g., `s1`, `s2`) in the list must be an `sf` or `data.frame` object +#' containing a `metric` column (numeric) and a `solution_1` column (numeric, 0 or 1). +#' @param names A character vector of names corresponding to each solution in +#' `solution_list`. The length of this vector must match the length of `solution_list`. +#' @param colorMap A character string indicating the `viridis` color map to use +#' for filling the selected areas (e.g., "A", "B", "C", "D", "E"). See +#' \url{https://ggplot2.tidyverse.org/reference/scale_viridis.html} for all options. +#' Defaults to `"C"`. +#' @param legendTitle A character string or `expression` for the title of the legend. +#' Defaults to `expression(" \u00B0C y"^"-1" * "")`, representing "°C year⁻¹". +#' @param xAxisLab A character string or `expression` for the x-axis label, +#' depending on the climate metric input. Defaults to +#' `expression("Climate warming ( \u00B0C y"^"-1" * ")")`. +#' +#' @return A `ggplot` object representing the fancy kernel density plot. #' @keywords internal +#' @noRd +#' +#' @importFrom assertthat assert_that +#' @importFrom dplyr filter mutate rename select +#' @importFrom forcats fct_relevel +#' @importFrom ggplot2 aes after_stat element_blank element_line element_text expansion ggplot labs scale_fill_viridis_c scale_x_continuous scale_y_discrete theme theme_bw +#' @importFrom rlang .data sym +#' @importFrom tibble as_tibble +#' @importFrom tidyr pivot_longer #' -splnr_plot_climKernelDensity_Fancy <- function(solution_list, names, +splnr_plot_climKernelDensity_Fancy <- function(solution_list, + names, colorMap = "C", legendTitle = expression(" \u00B0C y"^"-1" * ""), xAxisLab = expression("Climate warming ( \u00B0C y"^"-1" * ")")) { + # Assertions to validate input parameters. assertthat::assert_that( is.list(solution_list), + msg = "'solution_list' must be a list of prioritizr solutions." + ) + assertthat::assert_that( length(solution_list) > 0, + msg = "'solution_list' must contain at least one solution." + ) + assertthat::assert_that( is.character(names), + msg = "'names' must be a character vector of solution names." + ) + assertthat::assert_that( length(names) == length(solution_list), + msg = "The length of 'names' must match the length of 'solution_list'." + ) + assertthat::assert_that( is.character(colorMap), - is.vector(legendTitle) || missing(legendTitle) || is.expression(legendTitle), - is.vector(xAxisLab) || missing(xAxisLab) || is.expression(xAxisLab) + msg = "'colorMap' must be a character string for a 'viridis' palette option." ) + assertthat::assert_that( + is.vector(legendTitle) || is.expression(legendTitle), # Allow vector (character) or expression. + msg = "'legendTitle' must be a character string or an expression." + ) + assertthat::assert_that( + is.vector(xAxisLab) || is.expression(xAxisLab), # Allow vector (character) or expression. + msg = "'xAxisLab' must be a character string or an expression." + ) + + # Check that each solution in the list has 'metric' and 'solution_1' columns + for (i in seq_along(solution_list)) { + assertthat::assert_that( + "metric" %in% names(solution_list[[i]]), + msg = paste0("Solution ", i, " in 'solution_list' is missing the 'metric' column.") + ) + assertthat::assert_that( + "solution_1" %in% names(solution_list[[i]]), + msg = paste0("Solution ", i, " in 'solution_list' is missing the 'solution_1' column.") + ) + assertthat::assert_that( + is.numeric(solution_list[[i]]$metric), + msg = paste0("The 'metric' column in solution ", i, " must be numeric.") + ) + assertthat::assert_that( + is.numeric(solution_list[[i]]$solution_1) || is.logical(solution_list[[i]]$solution_1), + msg = paste0("The 'solution_1' column in solution ", i, " must be numeric (0/1) or logical.") + ) + } + + + #TODO Write check for ggridges list_sol <- list() - group_name <- "approach" + group_name <- "approach" # Define a column name for grouping different solutions. + # Loop through each solution in the list to prepare data for plotting. for (i in 1:length(names)) { list_sol[[i]] <- solution_list[[i]] %>% - tibble::as_tibble() %>% - dplyr::select("solution_1", "metric") %>% - dplyr::rename(!!rlang::sym(names[i]) := "metric") %>% + tibble::as_tibble() %>% # Convert to tibble to ensure consistent data frame behavior. + dplyr::select("solution_1", "metric") %>% # Select only solution status and metric. + dplyr::rename(!!rlang::sym(names[i]) := "metric") %>% # Rename 'metric' column to the solution's name. + # Pivot data longer to enable plotting multiple solutions on one plot. tidyr::pivot_longer(!!rlang::sym(names[i]), names_to = group_name, values_to = "metric") } + # Combine all processed data frames into a single data frame. df <- do.call(rbind, list_sol) %>% + # Relevel the 'approach' factor to control the order of ridges in the plot. dplyr::mutate(approach = forcats::fct_relevel(.data$approach, rev)) + # Initialize ggplot object. ggRidge <- ggplot2::ggplot() + + # Add density ridges with gradient fill for selected planning units. ggridges::geom_density_ridges_gradient( - data = df %>% dplyr::filter(.data$solution_1 == 1), + data = df %>% dplyr::filter(.data$solution_1 == 1), # Filter for selected units. ggplot2::aes( x = .data$metric, y = .data$approach, - fill = ggplot2::after_stat(.data$x), - ), scale = 1 + fill = ggplot2::after_stat(.data$x), # Fill based on the x-value (metric). + ), scale = 1 # Set ridge scale. ) + + # Apply a viridis color scale for the gradient fill. ggplot2::scale_fill_viridis_c(name = legendTitle, option = colorMap) + + # Add density ridges for not selected planning units with dotted lines and transparency. ggridges::geom_density_ridges( - data = df %>% dplyr::filter(.data$solution_1 == 0), + data = df %>% dplyr::filter(.data$solution_1 == 0), # Filter for not selected units. ggplot2::aes(x = .data$metric, y = .data$approach), - alpha = 0.25, linetype = "dotted", scale = 1 + alpha = 0.25, linetype = "dotted", scale = 1 # Set transparency, linetype, and scale. ) + - + # (Commented out in original: Optional vertical line for mean climate warming) # geom_vline(xintercept = climate$mean_climate_warming, # linetype = "dashed", color = "tan1", size = 0.5) + + # Set x-axis limits with no expansion. ggplot2::scale_x_continuous(expand = c(0, 0)) + + # Set y-axis limits with expansion. ggplot2::scale_y_discrete(expand = ggplot2::expansion(mult = c(0.01, 0))) + - ggplot2::labs(x = xAxisLab) + - ggplot2::theme_bw() + + ggplot2::labs(x = xAxisLab) + # Set x-axis label. + ggplot2::theme_bw() + # Apply black and white theme. + # Customize theme elements. ggplot2::theme( axis.ticks = ggplot2::element_line(color = "black", linewidth = 1), axis.line = ggplot2::element_line(colour = "black", linewidth = 1), axis.text = ggplot2::element_text(color = "black", size = 14), axis.title.x = ggplot2::element_text(size = 14), - axis.title.y = ggplot2::element_blank(), - axis.text.y = ggplot2::element_blank(), - # legend.key.height = unit(1, "inch"), + axis.title.y = ggplot2::element_blank(), # Hide y-axis title. + axis.text.y = ggplot2::element_blank(), # Hide y-axis text. legend.text = ggplot2::element_text(size = 15, color = "black"), legend.title = ggplot2::element_text(size = 15, color = "black") ) } -#' Kernel Density Plots for climate-smart spatial plans -#' @param type The plotting style of the kernel density plots. Either "Publication" which gives axis information etc., or "App" which condenses the information in the plot to simplify it for stakeholders. -#' @param soln For type "Publication": A list of `prioirtizr` solutions (e.g. solution_list = list(s1, s2)) containing a "metric" column containing the used climate metric information; For type "App": needs to be a prioritizr solution -#' @param names A list of names of the solutions (names = c("Input 1", "Input 2")) -#' @param colorMap A character string indicating the color map to use (see https://ggplot2.tidyverse.org/reference/scale_viridis.html for all options) -#' @param legendTitle A character value for the title of the legend. Can be empty (""). -#' @param xAxisLab A characted value for the x Axis label depending on the climate metric input -#' -#' @return A ggplot object of the plot +#' @title Kernel Density Plots for Climate-Smart Spatial Plans +#' +#' @description +#' `splnr_plot_climKernelDensity()` generates kernel density plots for +#' climate-smart spatial plans, offering two distinct plotting styles: +#' "Normal" (for publication-quality comparison of multiple solutions) and +#' "Basic" (for simplified visualization for stakeholders). +#' +#' @details +#' This wrapper function intelligently dispatches to either +#' `splnr_plot_climKernelDensity_Fancy()` (for `type = "Normal"`) or +#' `splnr_plot_climKernelDensity_Basic()` (for `type = "Basic"`) based on the +#' `type` parameter. +#' +#' The "Normal" (Fancy) style is suitable for detailed comparisons, +#' accommodating a list of solutions and custom axis labels, while the "Basic" +#' style is streamlined for clarity and quick interpretation, ideal for +#' stakeholder engagement. +#' +#' Both underlying functions require a `prioritizr` solution containing a +#' `metric` column with climate metric information and a `solution_1` column +#' indicating selected planning units. +#' +#' @param soln For `type = "Normal"`: A `list` of `prioritizr` solution objects +#' (e.g., `list(s1, s2)`). Each solution must contain a `metric` column and +#' a `solution_1` column. +#' For `type = "Basic"`: A single `prioritizr` solution `sf` object. +#' @param names A character vector of names corresponding to each solution in +#' `soln` when `type = "Normal"`. Not used for `type = "Basic"`. +#' Defaults to `NA`. +#' @param type A character string specifying the plotting style. Must be either +#' `"Normal"` or `"Basic"`. Defaults to `"Normal"`. +#' @param colorMap A character string indicating the `viridis` color map to use +#' (e.g., "A", "B", "C", "D", "E"). See +#' \url{https://ggplot2.tidyverse.org/reference/scale_viridis.html} for all options. +#' Defaults to `"C"`. +#' @param legendTitle A character string or `expression` for the title of the legend. +#' Defaults to `expression(" \u00B0C y"^"-1" * "")`, representing "°C year⁻¹". +#' @param xAxisLab A character string or `expression` for the x-axis label, +#' depending on the climate metric input. Defaults to +#' `expression("Climate warming ( \u00B0C y"^"-1" * ")")`. +#' +#' @return A `ggplot` object representing the kernel density plot. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom prioritizr problem add_min_set_objective add_relative_targets add_binary_decisions add_default_solver solve.ConservationProblem +#' @importFrom dplyr mutate select +#' @importFrom sf st_drop_geometry st_join +#' @importFrom tidyselect starts_with +#' #' @examples +#' \dontrun{ +#' # Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects +#' # in your package. +#' +#' # Prepare data for a climate-priority area approach (CPA) #' target <- dat_species_bin %>% #' sf::st_drop_geometry() %>% #' colnames() %>% @@ -222,15 +464,18 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list, names, #' refugiaTarget = 1 #' ) #' +#' # Join climate metric to features for the problem #' out_sf <- CPA$Features %>% -#' dplyr::mutate(Cost_None = rep(1, 780)) %>% +#' dplyr::mutate(Cost_None = rep(1, dim(.)[[1]])) %>% # Ensure enough costs for PUs #' sf::st_join(dat_clim, join = sf::st_equals) #' +#' # Define features for the prioritizr problem #' usedFeatures <- out_sf %>% #' sf::st_drop_geometry() %>% #' dplyr::select(-tidyselect::starts_with("Cost_"), -"metric") %>% #' names() #' +#' # Create and solve a prioritizr problem #' p1 <- prioritizr::problem(out_sf, usedFeatures, "Cost_None") %>% #' prioritizr::add_min_set_objective() %>% #' prioritizr::add_relative_targets(CPA$Targets$target) %>% @@ -238,8 +483,34 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list, names, #' prioritizr::add_default_solver(verbose = FALSE) #' #' dat_solnClim <- prioritizr::solve.ConservationProblem(p1) -#' splnr_plot_climKernelDensity(dat_solnClim, type = "Basic") -#' splnr_plot_climKernelDensity(soln = list(dat_solnClim), names = c("Input 1"), type = "Normal") +#' +#' # Example 1: Basic kernel density plot +#' plot_basic_kde <- splnr_plot_climKernelDensity(soln = dat_solnClim, type = "Basic") +#' print(plot_basic_kde) +#' +#' # Example 2: Normal (Fancy) kernel density plot for a single solution +#' plot_normal_kde_single <- splnr_plot_climKernelDensity( +#' soln = list(dat_solnClim), +#' names = c("Solution 1"), +#' type = "Normal" +#' ) +#' print(plot_normal_kde_single) +#' +#' # Example 3: Normal (Fancy) plot comparing two solutions (create a dummy second solution) +#' # For demonstration, let's create another dummy solution +#' dat_solnClim_2 <- dat_solnClim %>% +#' dplyr::mutate(solution_1 = sample(c(0, 1), n(), replace = TRUE)) # Randomize selection +#' +#' plot_normal_kde_multi <- splnr_plot_climKernelDensity( +#' soln = list(dat_solnClim, dat_solnClim_2), +#' names = c("Solution A", "Solution B"), +#' type = "Normal", +#' colorMap = "plasma", +#' legendTitle = "Climate Value", +#' xAxisLab = "Climate Metric (units)" +#' ) +#' print(plot_normal_kde_multi) +#' } splnr_plot_climKernelDensity <- function(soln, names = NA, type = "Normal", @@ -247,28 +518,63 @@ splnr_plot_climKernelDensity <- function(soln, legendTitle = expression(" \u00B0C y"^"-1" * ""), xAxisLab = expression("Climate warming ( \u00B0C y"^"-1" * ")")) { + # Assertions to validate input parameters. assertthat::assert_that( is.character(type), + msg = "'type' must be a character string ('Normal' or 'Basic')." + ) + assertthat::assert_that( + type %in% c("Normal", "Basic"), + msg = "'type' must be either 'Normal' or 'Basic'." + ) + assertthat::assert_that( is.character(names) || is.na(names), + msg = "'names' must be a character vector or NA." + ) + assertthat::assert_that( is.character(colorMap), - is.vector(legendTitle) || missing(legendTitle) || is.expression(legendTitle), - is.vector(xAxisLab) || missing(xAxisLab) || is.expression(xAxisLab) + msg = "'colorMap' must be a character string for a 'viridis' palette option." + ) + assertthat::assert_that( + is.vector(legendTitle) || is.expression(legendTitle), + msg = "'legendTitle' must be a character string or an expression." + ) + assertthat::assert_that( + is.vector(xAxisLab) || is.expression(xAxisLab), + msg = "'xAxisLab' must be a character string or an expression." ) + # Conditional logic to call either Basic or Fancy plotting function. if (type == "Normal") { + # If type is "Normal", expect a list of solutions. if (inherits(soln, "list") == FALSE) { - cat("Please provide a list of solutions when using this plot type.") + stop("For 'type = \"Normal\"', 'soln' must be a list of prioritizr solutions.") } else if (inherits(soln, "list")) { + # Ensure 'names' matches the number of solutions if 'type' is "Normal" and 'names' is provided. + if (!is.na(names[1]) && length(names) != length(soln)) { + stop("When 'type = \"Normal\"' and 'names' are provided, the length of 'names' must match the number of solutions in 'soln'.") + } else if (is.na(names[1])) { + # If names are not provided, create default names. + names <- paste0("Solution ", seq_along(soln)) + } + # Call the fancy kernel density plotting function. ggclimDens <- splnr_plot_climKernelDensity_Fancy( solution_list = soln, names = names, colorMap = colorMap, legendTitle = legendTitle, xAxisLab = xAxisLab ) } } else if (type == "Basic") { + # If type is "Basic", expect a single sf object. if (inherits(soln, "sf") == FALSE) { - cat("Please provide an sf object.") + stop("For 'type = \"Basic\"', 'soln' must be a single sf object.") } else if (inherits(soln, "sf")) { + # Call the basic kernel density plotting function. ggclimDens <- splnr_plot_climKernelDensity_Basic(soln = soln) } + } else { + # This case should ideally be caught by initial assertthat, but kept as a fallback. + stop("Invalid 'type' specified. Must be 'Normal' or 'Basic'.") } + + return(ggclimDens) } diff --git a/R/splnr_targets.R b/R/splnr_targets.R index b6ac769b..76851fae 100644 --- a/R/splnr_targets.R +++ b/R/splnr_targets.R @@ -1,131 +1,368 @@ -#' Assign targets by Inverse Area +#' @title Assign Targets by Inverse Area #' -#' This function takes a min (`target_min`) and max (`target_max`) target range and calculates an inverse area target for each feature based on areal coverage. +#' @description +#' This function calculates inverse area targets for each conservation feature +#' within an `sf` dataframe, based on their areal coverage. The target is set +#' to be inversely proportional to the feature's area, ranging between a +#' specified minimum (`target_min`) and maximum (`target_max`). #' -#' @param df An `sf` dataframe with features to calculate -#' @param target_min The minimum target for inverse area -#' @param target_max The maximum target for inverse area +#' @details +#' The inverse area target approach aims to assign higher conservation targets +#' to features that have a smaller overall distribution or areal coverage within +#' the study region. This can be particularly useful for prioritizing rare or +#' range-restricted features. #' -#' @return An `sf` dataframe with Inverse Area Targets added in `Target` +#' The calculation proceeds as follows: +#' 1. The area of a single planning unit is determined. +#' 2. The total area of the study region is estimated by multiplying the number +#' of planning units by the individual planning unit area. +#' 3. For each feature (species), its total area across all planning units is +#' calculated. +#' 4. The target for each feature is then scaled between `target_min` and +#' `target_max` such that features with smaller areas receive targets closer +#' to `target_max`, and features with larger areas receive targets closer +#' to `target_min`. +#' +#' The input `df` is expected to be an `sf` object where columns (excluding +#' geometry) represent different features (e.g., species presence/absence) and +#' rows represent planning units. +#' +#' @param df An `sf` dataframe containing the features (e.g., species distribution +#' data) for which to calculate inverse area targets. Each column (excluding +#' geometry) should represent a feature, and each row a planning unit. +#' @param target_min A numeric value between 0 and 1 (inclusive) specifying the +#' minimum target percentage. This will be the target for the most widespread feature. +#' @param target_max A numeric value between 0 and 1 (inclusive) specifying the +#' maximum target percentage. This will be the target for the rarest feature. +#' +#' @return A `tibble` (data frame) with two columns: `Species` (or feature name) +#' and `target` (the calculated inverse area target for each feature). #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr across everything mutate summarise #' @importFrom rlang .data +#' @importFrom sf st_area st_drop_geometry +#' @importFrom stringr str_replace_all +#' @importFrom tidyr pivot_longer replace_na +#' #' @examples -#' targets <- dat_species_prob %>% +#' \dontrun{ +#' # Assuming 'dat_species_prob' is an existing sf object in your package, +#' # representing species distribution in planning units. +#' +#' # Calculate inverse area targets with a range from 30% to 80%. +#' targets_inverse_area <- dat_species_prob %>% #' splnr_targets_byInverseArea(target_min = 0.3, target_max = 0.8) +#' print(targets_inverse_area) +#' +#' # Example with a different target range (e.g., 20% to 70%) +#' targets_custom_range <- dat_species_prob %>% +#' splnr_targets_byInverseArea(target_min = 0.2, target_max = 0.7) +#' print(targets_custom_range) +#' } splnr_targets_byInverseArea <- function(df, target_min, target_max) { + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(df, "sf"), # Ensure df is an sf object. + msg = "'df' must be an 'sf' object." + ) assertthat::assert_that( - inherits(df, c("sf", "data.frame")), - is.numeric(target_min) && target_min >= 0 && target_min <= 1, - is.numeric(target_max) && target_max >= 0 && target_max <= 1, - target_min <= target_max + is.numeric(target_min) && length(target_min) == 1 && target_min >= 0 && target_min <= 1, + msg = "'target_min' must be a single numeric value between 0 and 1." + ) + assertthat::assert_that( + is.numeric(target_max) && length(target_max) == 1 && target_max >= 0 && target_max <= 1, + msg = "'target_max' must be a single numeric value between 0 and 1." + ) + assertthat::assert_that( + target_min <= target_max, + msg = "'target_min' must be less than or equal to 'target_max'." + ) + assertthat::assert_that( + "geometry" %in% names(df), + msg = "'df' must contain a 'geometry' column." ) - PU_area_km2 <- as.numeric(sf::st_area(df[1, 1]) / 1e+06) # Area of each planning unit + # Calculate the area of a single planning unit in km². + PU_area_km2 <- as.numeric(sf::st_area(df[1, ]) / 1e+06) - total_PU_area <- nrow(df) * PU_area_km2 # Total area of the study region + # Calculate the total approximate area of the study region. + total_PU_area <- nrow(df) * PU_area_km2 + # Process the dataframe to calculate inverse area targets. dat <- df %>% + # Drop the geometry column to perform numerical operations on feature data. sf::st_drop_geometry() %>% + # Replace any NA values with 0 across all columns, assuming NA means absence. dplyr::mutate(dplyr::across(dplyr::everything(), ~ tidyr::replace_na(.x, 0))) %>% - dplyr::summarise(dplyr::across(dplyr::everything(), ~ sum(., is.na(.), 0))) %>% - tidyr::pivot_longer(dplyr::everything(), names_to = "Species", values_to = "Area_km2") %>% + # Summarise each column by summing its values to get total area coverage for each feature. + dplyr::summarise(dplyr::across(dplyr::everything(), ~ sum(.x, na.rm = TRUE))) %>% + # Pivot the data longer, converting feature columns into rows. + tidyr::pivot_longer(dplyr::everything(), names_to = "Species", values_to = "Area_units") %>% # Renamed to Area_units to reflect it's sum of presence + # Mutate to calculate actual area in km² and the inverse area target. dplyr::mutate( + # Replace underscores in species names with spaces for readability. Species = stringr::str_replace_all(.data$Species, pattern = "_", replacement = " "), - Area_km2 = .data$Area_km2 * PU_area_km2, + # Convert 'Area_units' (sum of presences) to actual area in km². + Area_km2 = .data$Area_units * PU_area_km2, + # Calculate the inverse area target: + # Starts at target_max, then subtracts a proportion of the range (target_max - target_min) + # based on the feature's relative area. Larger relative area leads to a smaller target. target = target_max - ((.data$Area_km2 / total_PU_area) * (target_max - target_min)) - ) + ) %>% + dplyr::select("Species", "target") # Select only the Species and target columns for the final output. + return(dat) } - - -#' Assign targets to all features by category +#' @title Assign Targets by Category +#' +#' @description +#' The `splnr_targets_byCategory()` function assigns conservation targets to +#' features (e.g., species) based on their assigned categories. This allows for +#' differentiated conservation goals for different groups of features. #' -#' `splnr_targets_byCategory()` allows to assign targets for conservation planning based on species categories. +#' @details +#' This function is useful in conservation planning when different types of +#' features (e.g., endangered species, common species, ecosystem types) require +#' distinct conservation targets. It performs a left join with a provided +#' named vector (`catTarg`) where names correspond to categories in your data +#' and values are the desired targets. #' -#' @param dat A sf object with the features and categories -#' @param catTarg A named character vector with categories and target -#' @param catName An optional argument for the name of the category column in dat +#' The `dat` input should be an `sf` object (or data frame) that contains a +#' column (`catName`) identifying the category for each feature. #' -#' @return An sf object with targets added +#' @param dat An `sf` object (or data frame) containing the features and their +#' associated categories. Each row should represent a feature (e.g., a species) +#' with its attributes, including the category. +#' @param catTarg A named numeric vector where names are the categories +#' (e.g., `"Group1"`, `"Endangered"`) and values are the corresponding +#' conservation targets (e.g., `0.5`, `0.8`). +#' @param catName A character string specifying the name of the column in `dat` +#' that contains the category information. Defaults to `"Category"`. +#' +#' @return An `sf` object (or data frame) identical to the input `dat`, but with an +#' additional column named `target` containing the assigned conservation target +#' for each feature. Features whose categories are not found in `catTarg` will +#' have `NA` in the `target` column unless they already have a 'target' column. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr left_join rename +#' @importFrom rlang := +#' @importFrom tibble enframe +#' #' @examples -#' dat <- splnr_targets_byCategory( -#' dat = dat_category, +#' \dontrun{ +#' # Assuming 'dat_category' is an existing sf object in your package +#' # with a column named "category" and other feature data. +#' +#' # Example: Assign targets based on predefined categories +#' targets_by_group <- splnr_targets_byCategory( +#' dat = dat_category, # Assuming dat_category has a 'category' column #' catTarg = c("Group1" = 0.5, "Group2" = 0.2), #' catName = "category" #' ) +#' print(targets_by_group) +#' +#' # Example: Assign targets with a different category column name +#' dat_alt_cat <- data.frame(Feature = letters[1:5], Type = c("A", "B", "A", "C", "B")) +#' targets_by_type <- splnr_targets_byCategory( +#' dat = dat_alt_cat, +#' catTarg = c("A" = 0.7, "B" = 0.4), +#' catName = "Type" +#' ) +#' print(targets_by_type) +#' } splnr_targets_byCategory <- function(dat, catTarg, catName = "Category") { + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(dat, "data.frame"), # Ensure dat is a data.frame (or sf object). + msg = "'dat' must be a data.frame or sf object." + ) + assertthat::assert_that( + is.character(catName) && length(catName) == 1, + msg = "'catName' must be a single character string." + ) assertthat::assert_that( - inherits(dat, c("sf", "data.frame")), - is.character(catName), catName %in% names(dat), - is.vector(catTarg), + msg = paste0("The specified 'catName' (\"", catName, "\") does not exist in the input dataframe 'dat'.") + ) + assertthat::assert_that( + is.numeric(catTarg), # Ensure catTarg is a numeric vector. + msg = "'catTarg' must be a numeric vector." + ) + assertthat::assert_that( length(catTarg) > 0, - all(names(catTarg) %in% unique(dat[[catName]])) + msg = "'catTarg' must not be empty." + ) + assertthat::assert_that( + !is.null(names(catTarg)), + msg = "'catTarg' must be a named vector (e.g., c('Category1' = 0.5))." + ) + assertthat::assert_that( + all(names(catTarg) %in% unique(dat[[catName]])), + msg = paste0("Not all names in 'catTarg' match unique values in the '", catName, "' column of 'dat'.") ) + # Join the input dataframe with the category targets. dat <- dat %>% + # Convert the named vector `catTarg` into a two-column tibble (name, value). dplyr::left_join( tibble::enframe(catTarg), + # Join by the category column in `dat` and the 'name' column from the enframe'd catTarg. by = dplyr::join_by(!!catName == "name") ) %>% + # Rename the 'value' column (from enframe) to 'target'. dplyr::rename(target = "value") return(dat) } - -#' Assign targets bu IUCN Red List categories +#' @title Assign Targets by IUCN Red List Categories +#' +#' @description +#' The `splnr_targets_byIUCN()` function assigns conservation targets for species +#' based on their IUCN Red List categories. This allows for prioritizing species +#' at higher risk of extinction with more stringent conservation goals. #' -#' `splnr_targets_byIUCN()` allows to assign targets for species used in conservation planning based on IUCN categories. Species can be extracted based on IUCN categories with the `spatoalplnr`function `splnr_get_IUCNRedList()`. -#' Accessing the IUCN database requires a login token from `rl_use_iucn()` that needs to be added to the environment using `Sys.setenv(IUCN_REDLIST_KEY = "[Your Token]")`. You can start by running `rredlist::rl_use_iucn()`. +#' @details +#' This function is crucial for integrating species' extinction risk into +#' conservation planning. It allows you to specify targets either as a single +#' numeric value (applied to all 'threatened' IUCN categories) or as a named +#' numeric vector for specific categories. #' -#' @param dat A dataframe or sf object with IUCN categories -#' @param IUCN_target Either a numeric or named numeric of targets to apply to IUCN categories -#' @param IUCN_col Optional string to indicate the name of the column with the IUCN categories +#' Species can be extracted based on IUCN categories using the `spatialplanr` +#' function `splnr_get_IUCNRedList()`. #' -#' @return dataframe or sf object +#' \strong{Important:} To access the IUCN database (e.g., via `splnr_get_IUCNRedList()`), +#' you need an API login token. This token, obtained from `rredlist::rl_use_iucn()`, +#' must be set as an environment variable named `IUCN_REDLIST_KEY` +#' (e.g., `Sys.setenv(IUCN_REDLIST_KEY = "[Your Token]")`). +#' +#' The function checks if a 'target' column already exists in `dat`. If not, +#' it creates one. If it exists, new targets are coalesced with existing ones, +#' allowing for sequential application or refinement of targets. +#' +#' The "threatened" IUCN categories considered for target assignment (when a +#' single `IUCN_target` is provided) are: "EX" (Extinct), "EW" (Extinct in the Wild), +#' "CR" (Critically Endangered), "EN" (Endangered), and "VU" (Vulnerable). +#' +#' @param dat A dataframe or `sf` object containing species information, +#' including a column with IUCN categories. +#' @param IUCN_target Either: +#' \itemize{ +#' \item A single numeric value (e.g., `0.3`) to apply this target to all +#' threatened IUCN categories ("EX", "EW", "CR", "EN", "VU"). +#' \item A named numeric vector (e.g., `c("EX" = 0.8, "CR" = 0.6)`) to +#' apply specific targets to particular IUCN categories. +#' } +#' @param IUCN_col A character string specifying the name of the column in `dat` +#' that contains the IUCN category information. Defaults to `"IUCN_Category"`. +#' +#' @return A dataframe or `sf` object identical to the input `dat`, but with an +#' updated or newly added `target` column reflecting the assigned conservation goals. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr case_when coalesce left_join mutate select +#' @importFrom rlang .data sym +#' @importFrom tibble as_tibble enframe +#' #' @examples -#' dat <- data.frame(IUCN_Category = c("EW", "EX", NA), target = c(0.3, 0.3, 0.3)) -#' IUCN_target <- c("EX" = 0.8, "EW" = 0.6) -#' dat <- splnr_targets_byIUCN(dat, IUCN_target) +#' \dontrun{ +#' # Example 1: Assigning specific targets to categories +#' # Create a dummy dataframe resembling output from splnr_get_IUCNRedList +#' df_species_iucn <- data.frame( +#' Species = c("Diomedea exulans", "Hippocampus kuda", +#' "Squatina squatina", "Common Dolphin"), +#' IUCN_Category = c("VU", "EN", "CR", "LC") +#' ) +#' +#' iucn_specific_targets <- c("EX" = 0.9, "EW" = 0.8, "CR" = 0.75, "EN" = 0.6, "VU" = 0.5) +#' +#' df_with_iucn_targets <- splnr_targets_byIUCN( +#' dat = df_species_iucn, +#' IUCN_target = iucn_specific_targets, +#' IUCN_col = "IUCN_Category" +#' ) +#' print(df_with_iucn_targets) +#' +#' # Example 2: Assigning a single target to all threatened categories +#' df_single_target <- splnr_targets_byIUCN( +#' dat = df_species_iucn, +#' IUCN_target = 0.4, # Apply 40% target to all threatened species +#' IUCN_col = "IUCN_Category" +#' ) +#' print(df_single_target) +#' +#' # Example 3: When 'dat' already has a 'target' column +#' df_pre_targets <- data.frame( +#' Species = c("A", "B", "C"), +#' IUCN_Category = c("CR", "LC", "EN"), +#' target = c(0.1, 0.2, 0.1) # Existing targets +#' ) +#' iucn_update_targets <- c("CR" = 0.7) # Only update CR +#' df_updated_targets <- splnr_targets_byIUCN(df_pre_targets, iucn_update_targets) +#' print(df_updated_targets) +#' } splnr_targets_byIUCN <- function(dat, IUCN_target, IUCN_col = "IUCN_Category") { + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(dat, "data.frame"), # Ensure dat is a data.frame or sf object. + msg = "'dat' must be a data.frame or sf object." + ) + assertthat::assert_that( + is.character(IUCN_col) && length(IUCN_col) == 1, + msg = "'IUCN_col' must be a single character string." + ) assertthat::assert_that( - inherits(dat, c("sf", "data.frame")), - is.na(IUCN_col) || is.character(IUCN_col), IUCN_col %in% names(dat), - (is.numeric(IUCN_target) && length(IUCN_target) == 1) || is.vector(IUCN_target) + msg = paste0("The specified 'IUCN_col' (\"", IUCN_col, "\") does not exist in the input dataframe 'dat'.") + ) + assertthat::assert_that( + (is.numeric(IUCN_target) && length(IUCN_target) == 1) || (is.numeric(IUCN_target) && !is.null(names(IUCN_target))), + msg = "'IUCN_target' must be either a single numeric value or a named numeric vector." ) + if (is.numeric(IUCN_target)) { + assertthat::assert_that( + all(IUCN_target >= 0 & IUCN_target <= 1), + msg = "All values in 'IUCN_target' must be between 0 and 1." + ) + } - if ("target" %in% colnames(dat) == FALSE) { + # Ensure a 'target' column exists in 'dat'. If not, initialize with NA. + if (!("target" %in% colnames(dat))) { dat$target <- NA } - if (is.vector(IUCN_target, mode = "numeric") & !is.null(names(IUCN_target))) { - # If the target is a named vector, apply the relevant targets + # Apply targets based on whether IUCN_target is a named vector or a single numeric. + if (is.numeric(IUCN_target) && !is.null(names(IUCN_target))) { + # If IUCN_target is a named vector, join and coalesce targets. dat <- dat %>% - dplyr::left_join(data.frame(IUCN_target, col1 = names(IUCN_target)), by = dplyr::join_by(!!rlang::sym(IUCN_col) == "col1")) %>% - dplyr::mutate(target = dplyr::coalesce(IUCN_target, .data$target)) %>% - dplyr::select(-IUCN_target) - - } else if (is.numeric(IUCN_target) & length(IUCN_target) == 1) { - # If the target is a single numeric, apply to all IUCN categories. + # Convert the named IUCN_target vector to a data frame for joining. + dplyr::left_join(data.frame(IUCN_target_value = IUCN_target, + IUCN_Category = names(IUCN_target)), + by = dplyr::join_by(!!rlang::sym(IUCN_col) == "IUCN_Category")) %>% + # Use coalesce to update 'target' only where new IUCN_target_value is not NA. + dplyr::mutate(target = dplyr::coalesce(.data$IUCN_target_value, .data$target)) %>% + # Remove the temporary IUCN_target_value column. + dplyr::select(-.data$IUCN_target_value) + } else if (is.numeric(IUCN_target) && length(IUCN_target) == 1) { + # If IUCN_target is a single numeric, apply to specific threatened IUCN categories. dat <- dat %>% dplyr::mutate(target = dplyr::case_when( + # Apply the single target if the IUCN_col matches any of the threatened categories. !!rlang::sym(IUCN_col) %in% c("EX", "EW", "CR", "EN", "VU") ~ IUCN_target, - TRUE ~ dat$target + TRUE ~ .data$target # Otherwise, keep the existing target value. )) } return(dat) diff --git a/R/utils-climate.R b/R/utils-climate.R index dddb0467..4710608f 100644 --- a/R/utils-climate.R +++ b/R/utils-climate.R @@ -1,248 +1,529 @@ -##### Climate Priority Area Approach #### - -#' Function to split the feature data into climate-smart (CS) and non-climate-smart (NCS) areas depending on the percentile chosen by the user. +#' @title Preprocess Feature Data for Climate Priority Area Approach #' -#' @param features feature sf object -#' @param metric climate metric `sf` object with 'metric' as the column name of the metric values per planning unit. -#' @param percentile cut-off threshold for determining whether an area is a climate priority area or not (e.g., lower 35th percentile of warming or upper 65th percentile of acidification). Note that the percentile here is the lower limit of the threshold. -#' @param direction If direction = 1, metric values are from low (least climate-smart) to high (most climate-smart). If direction = -1, metric values are from high (least climate-smart) to low (most climate-smart). +#' @description +#' This internal function prepares feature data for the Climate Priority Area (CPA) +#' approach. It divides each feature's distribution into "climate-smart" (CS) and +#' "non-climate-smart" (NCS) areas based on a user-defined percentile cutoff for a +#' given climate metric. #' -#' @return A new sf dataframe that has cutoffs applied. -#' @noRd +#' @details +#' The CPA approach aims to prioritize areas that are both important for +#' biodiversity features and are considered resilient to climate change. This +#' preprocessing step identifies, for each individual feature, which of its +#' occupied planning units fall within the most climate-smart `percentile` of +#' the climate metric. +#' +#' For each feature, the function performs the following steps: +#' 1. Joins the feature data with the climate metric data. +#' 2. Filters to include only planning units where the feature is present. +#' 3. Calculates the specified `percentile` cutoff for the climate metric within +#' this filtered set of planning units. +#' 4. Creates two new binary columns for each feature: +#' - `_CS` (Climate-Smart): Indicates planning units where the feature is +#' present AND the climate metric meets the climate-smart criteria (e.g., +#' top 5% for direction 1, bottom 5% for direction -1). +#' - `_NCS` (Non-Climate-Smart): Indicates planning units where the feature +#' is present BUT the climate metric does NOT meet the climate-smart criteria. +#' +#' The `direction` parameter is crucial: +#' - `direction = 1`: Higher values of the `metric` indicate more climate-smart +#' areas (e.g., lower warming rates). The function identifies areas with metric +#' values greater than or equal to the `(100 - percentile)`th quantile. +#' - `direction = -1`: Lower values of the `metric` indicate more climate-smart +#' areas (e.g., less acidification). The function identifies areas with metric +#' values less than or equal to the `percentile`th quantile. +#' +#' @param features An `sf` object representing conservation features. Each column +#' (excluding geometry) should typically be a binary representation of a feature's +#' presence (1) or absence (0) in each planning unit. +#' @param metric An `sf` object containing climate metric information. It must +#' have a column named 'metric' with the climate metric values for each planning unit. +#' @param percentile A numeric value (0-100) representing the cutoff threshold for +#' determining climate-smart areas. For example, `percentile = 5` means the +#' most climate-smart 5% of areas (based on `direction`) are considered. +#' This value represents the lower limit of the threshold (e.g., lower 5th +#' percentile of warming or upper 95th percentile of acidification). +#' @param direction An integer specifying the direction of climate-smartness: +#' \itemize{ +#' \item `1`: Higher metric values mean more climate-smart. +#' \item `-1`: Lower metric values mean more climate-smart. +#' } +#' +#' @return An `sf` dataframe with new columns for each original feature, split +#' into `_CS` (climate-smart) and `_NCS` (non-climate-smart) areas, indicating +#' the binary presence (1) or absence (0) of that feature within those climate +#' categories. This dataframe retains the original geometry. #' @keywords internal +#' @noRd #' -#' @importFrom rlang .data +#' @importFrom assertthat assert_that +#' @importFrom dplyr across bind_cols filter if_else mutate select +#' @importFrom rlang .data sym +#' @importFrom sf st_drop_geometry st_join st_as_sf +#' @importFrom stats quantile +#' @importFrom tidyselect matches +#' @importFrom tidyr replace_na #' #' @examples +#' \dontrun{ +#' # Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects +#' # in your package. 'dat_species_bin' has binary species data, +#' # and 'dat_clim' has a 'metric' column. #' -#' out_sf <- splnr_climate_priorityArea_preprocess( +#' # Example: Identify climate-smart areas for species where +#' # higher metric values mean more climate-smart (e.g., lower warming). +#' out_sf_cs_areas <- splnr_climate_priorityArea_preprocess( #' features = dat_species_bin, #' percentile = 5, #' metric = dat_clim, #' direction = 1 #' ) +#' print(out_sf_cs_areas) +#' +#' # Example: Identify climate-smart areas where +#' # lower metric values mean more climate-smart (e.g., less acidification). +#' out_sf_ncs_areas <- splnr_climate_priorityArea_preprocess( +#' features = dat_species_bin, +#' percentile = 10, +#' metric = dat_clim, +#' direction = -1 +#' ) +#' print(out_sf_ncs_areas) +#' } splnr_climate_priorityArea_preprocess <- function(features, percentile, metric, direction) { + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(features, "sf"), + msg = "'features' must be an 'sf' object." + ) + assertthat::assert_that( + inherits(metric, "sf"), + msg = "'metric' must be an 'sf' object." + ) + assertthat::assert_that( + "metric" %in% names(metric), + msg = "'metric' sf object must contain a column named 'metric'." + ) + assertthat::assert_that( + is.numeric(percentile) && length(percentile) == 1 && percentile >= 0 && percentile <= 100, + msg = "'percentile' must be a single numeric value between 0 and 100." + ) + assertthat::assert_that( + direction %in% c(1, -1), + msg = "'direction' must be either 1 (higher metric = more climate-smart) or -1 (lower metric = more climate-smart)." + ) + assertthat::assert_that( + sf::st_crs(features) == sf::st_crs(metric), + msg = "CRS of 'features' and 'metric' must be the same." + ) + + # Extract column names of the features (excluding geometry). spp <- features %>% sf::st_drop_geometry() %>% names() - imptList <- list() # empty list to fill in with the important features + # Initialize an empty list to store processed data for each feature. + imptList <- list() for (i in 1:length(spp)) { + # Select one feature at a time from the 'features' data and join with the 'metric' data. df <- features %>% - dplyr::select(!!rlang::sym(spp[i])) %>% # Select 1 species at a time + dplyr::select(!!rlang::sym(spp[i])) %>% sf::st_join(metric, join = sf::st_equals) - if (any((apply(df, 2, is.na))[, 2])) { - print("There are some NAs in the metric data. Please check.") + # Check for NAs in the 'metric' column after joining and print a warning if found. + if (any(is.na(df$metric))) { + message(paste0("Warning: There are NAs in the metric data for feature '", spp[i], "'. These will be removed from quantile calculation.")) } - # Get the most climate-smart areas + # Filter to select only rows where the current biodiversity feature is present (value = 1). filteredDF <- df %>% - dplyr::filter(!!rlang::sym(spp[i]) == 1) # Select rows that have biodiversity values (= 1) + dplyr::filter(!!rlang::sym(spp[i]) == 1) + + # Handle cases where filteredDF might be empty (feature not present in any unit or only in NAs) + if (nrow(filteredDF) == 0) { + warning(paste0("Feature '", spp[i], "' is not present in any planning unit with valid metric data. Skipping climate-smart area calculation for this feature.")) + # Create an empty sf object with expected columns for binding later + temp_df <- df %>% + dplyr::mutate(V1 = 0, V2 = 0) %>% # Add V1 and V2 columns with 0 values + dplyr::mutate(!!rlang::sym(paste0(spp[i], "_CS")) := 0) %>% + dplyr::select(!!rlang::sym(paste0(spp[i], "_CS"))) + if (i > 1 && "geometry" %in% names(temp_df)) { # Remove geometry if not the first iteration + temp_df <- temp_df %>% sf::st_drop_geometry() + } + imptList[[i]] <- temp_df + next # Skip to the next iteration of the loop + } + + # Determine the percentile cutoff based on the specified direction. if (direction == 1) { - prct <- (100 - percentile) / 100 # for 100 as the most climate-smart - qntl <- stats::quantile(filteredDF$metric, prct)[[1]] # Get the percentile + # If higher values are more climate-smart, calculate the (100 - percentile)th quantile. + prct <- (100 - percentile) / 100 + qntl <- stats::quantile(filteredDF$metric, prct, na.rm = TRUE)[[1]] # Get the percentile, ignoring NAs. + # Mutate to create V1 (climate-smart indicator) and V2 (feature presence indicator). df <- df %>% dplyr::mutate( - V1 = dplyr::if_else(metric >= qntl, true = 1, false = 0), + V1 = dplyr::if_else(.data$metric >= qntl, true = 1, false = 0), V2 = dplyr::if_else(!!rlang::sym(spp[i]) == 1, true = 1, false = 0) ) } else if (direction == -1) { + # If lower values are more climate-smart, calculate the percentileth quantile. prct <- percentile / 100 - qntl <- stats::quantile(filteredDF$metric, prct)[[1]] # Get the percentile + qntl <- stats::quantile(filteredDF$metric, prct, na.rm = TRUE)[[1]] # Get the percentile, ignoring NAs. + # Mutate to create V1 (climate-smart indicator) and V2 (feature presence indicator). df <- df %>% dplyr::mutate( - V1 = dplyr::if_else(metric <= qntl, true = 1, false = 0), + V1 = dplyr::if_else(.data$metric <= qntl, true = 1, false = 0), V2 = dplyr::if_else(!!rlang::sym(spp[i]) == 1, true = 1, false = 0) ) } else { - if (i == 1) { - print("Please enter a valid direction: either 1 or -1.") + # If an invalid direction is provided, print an error (should be caught by assertthat). + if (i == 1) { # Only print for the first iteration to avoid redundant messages. + stop("Please enter a valid direction: either 1 or -1.") } } - if (i > 1){ + # Drop geometry for subsequent bind_cols operations if not the first iteration. + if (i > 1 && "geometry" %in% names(df)){ df <- df %>% - sf::st_drop_geometry() # Drop here otherwise we get multiple version below + sf::st_drop_geometry() } + # Calculate the Climate-Smart (CS) area for the current feature. imptList[[i]] <- df %>% - dplyr::mutate(!!rlang::sym(paste0(spp[i], "_CS")) := .data$V1 * .data$V2) %>% # CS = climate-smart areas - dplyr::select(!!rlang::sym(paste0(spp[i], "_CS"))) + dplyr::mutate(!!rlang::sym(paste0(spp[i], "_CS")) := .data$V1 * .data$V2) %>% # CS = climate-smart areas (feature present AND within climate-smart percentile) + dplyr::select(!!rlang::sym(paste0(spp[i], "_CS"))) # Select only the CS column. } + # Combine all individual feature CS data frames into a single dataframe. imptList <- do.call(dplyr::bind_cols, imptList) + # Initialize an empty list to store processed data for each feature's NCS component. repList <- list() - for (i in 1:length(spp)) { + # Select 1 species at a time from original features data and join with metric. df1 <- features %>% - dplyr::select(!!rlang::sym(spp[i])) %>% # Select 1 species at a time + dplyr::select(!!rlang::sym(spp[i])) %>% sf::st_join(metric, join = sf::st_equals) + # Select the CS column for the current feature from the previously created imptList. df2 <- imptList %>% - dplyr::select(!!rlang::sym(paste0(spp[i], "_CS")),) + dplyr::select(!!rlang::sym(paste0(spp[i], "_CS"))) + # Join the original feature data with its CS status. df3 <- sf::st_join(df1, df2, join = sf::st_equals) - if (i > 1){ + # Drop geometry for subsequent bind_cols operations if not the first iteration. + if (i > 1 && "geometry" %in% names(df3)){ # Check if geometry exists before dropping df3 <- df3 %>% - sf::st_drop_geometry() # Drop here otherwise we get multiple version below + sf::st_drop_geometry() } + # Calculate the Non-Climate-Smart (NCS) area for the current feature. repList[[i]] <- df3 %>% - dplyr::mutate(!!rlang::sym(paste0(spp[i], "_NCS")) := dplyr::if_else(!!rlang::sym(paste0(spp[i], "_CS")) == 1, - true = 0, - false = .data[[spp[i]]] - )) %>% + dplyr::mutate(!!rlang::sym(paste0(spp[i], "_NCS")) := dplyr::if_else( + !!rlang::sym(paste0(spp[i], "_CS")) == 1, # If the area is CS, then NCS is 0. + true = 0, + false = .data[[spp[i]]] # Otherwise, NCS is 1 if feature is present, 0 if not. + )) %>% + # Select both NCS and CS columns for the current feature. dplyr::select(tidyselect::matches("_NCS|_CS")) } + # Combine all individual feature NCS and CS data frames into a single dataframe. + # Ensure geometry is handled correctly and convert back to sf object. repList <- do.call(dplyr::bind_cols, repList) %>% + # Re-add geometry from the original features, as bind_cols might drop it. + sf::st_set_geometry(features$geometry) %>% + # Select all columns, ensuring the order. dplyr::select(tidyselect::everything()) %>% - sf::st_as_sf(sf_column_name = "geometry") + sf::st_as_sf() + return(repList) } -#' Function to assign targets for climate-priority-area approach +#' @title Assign Targets for Climate Priority Area Approach #' -#' @param targets `data.frame`with list of features under "feature" column and their corresponding targets under "target" column -#' @param climateSmartDF `sf` object produced using the function splnr_ClimatePriorityArea_CSapproach() -#' @param refugiaTarget target assigned to climate-smart areas +#' @description +#' This internal function calculates and assigns conservation targets for features +#' when using the Climate Priority Area (CPA) approach. It differentiates targets +#' for climate-smart (CS) and non-climate-smart (NCS) areas. #' -#' @return A new sf dataframe that has cutoffs applied. -#' @noRd +#' @details +#' This function is a core component of the `splnr_climate_priorityAreaApproach()`. +#' It takes the initial targets for each feature and adjusts them based on the +#' proportion of the feature found in climate-smart areas, and a `refugiaTarget`. +#' +#' The logic for target adjustment is as follows: +#' 1. For each feature, it calculates the total number of planning units it occupies. +#' 2. It determines the proportion of the feature's total presence that falls +#' within climate-smart areas (i.e., `_CS` areas). +#' 3. If this climate-smart proportion is greater than the feature's original target, +#' the target for the `_CS` component is adjusted proportionally, and the +#' `_NCS` component's target is set to 0 (meaning all necessary representation +#' can be met within CS areas). +#' 4. Otherwise, the target for the `_CS` component is set to `refugiaTarget` +#' (typically 100% or 1), and the remaining part of the original target is +#' assigned to the `_NCS` component. This ensures that the entire `refugiaTarget` +#' for the CS portion is met, and any shortfall is covered by NCS areas. +#' +#' The output `data.frame` contains the new adjusted targets for each feature, +#' now split into `_CS` and `_NCS` components. +#' +#' @param targets A `data.frame` with two columns: `feature` (character, listing +#' the original feature names) and `target` (numeric, the conservation target +#' for each feature as a proportion, e.g., 0.3). +#' @param climateSmartDF An `sf` object (or data frame) produced by +#' `splnr_climate_priorityArea_preprocess()`. This dataframe contains the +#' original features split into `_CS` and `_NCS` components. +#' @param refugiaTarget A numeric value (0-1) representing the target proportion +#' assigned specifically to climate-smart areas (refugia). Defaults to `1` (100%). +#' +#' @return A `data.frame` with two columns: `feature` (character, now including +#' `_CS` and `_NCS` suffixes for each original feature) and `target` (the +#' newly calculated targets for each climate-split feature). #' @keywords internal +#' @noRd #' -#' @importFrom rlang .data +#' @importFrom assertthat assert_that +#' @importFrom dplyr across bind_rows case_when filter full_join if_else pull select summarize +#' @importFrom rlang .data sym +#' @importFrom sf st_drop_geometry +#' @importFrom stringr str_c str_ends +#' @importFrom tibble tribble +#' @importFrom tidyr replace_na pivot_longer #' #' @examples -#' Features <- dat_species_bin +#' \dontrun{ +#' # Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects. #' -#' targets <- Features %>% +#' # Define initial targets for species features. +#' initial_targets <- dat_species_bin %>% #' sf::st_drop_geometry() %>% #' colnames() %>% #' data.frame() %>% #' setNames(c("feature")) %>% #' dplyr::mutate(target = 0.3) #' -#' metric_df <- dat_clim -#' -#' dat_species_binDF <- dat_species_bin %>% -#' sf::st_drop_geometry() -#' -#' out_sf <- splnr_climate_priorityArea_preprocess( +#' # Preprocess features to get CS/NCS split. +#' preprocessed_features <- splnr_climate_priorityArea_preprocess( #' features = dat_species_bin, -#' percentile = 5, metric = metric_df, direction = 1 +#' percentile = 5, +#' metric = dat_clim, +#' direction = 1 #' ) #' -#' targets <- splnr_climate_priorityArea_assignTargets( -#' targets = targets, -#' climateSmartDF = out_sf, -#' refugiaTarget = 1 +#' # Assign targets using the climate-smart logic. +#' cpa_assigned_targets <- splnr_climate_priorityArea_assignTargets( +#' targets = initial_targets, +#' climateSmartDF = preprocessed_features, +#' refugiaTarget = 1 # Aim for 100% representation in climate-smart areas if possible. #' ) +#' print(cpa_assigned_targets) +#' } splnr_climate_priorityArea_assignTargets <- function(targets, climateSmartDF, refugiaTarget = 1) { + # Assertions to validate input parameters. + assertthat::assert_that( + is.data.frame(targets), + msg = "'targets' must be a data.frame." + ) + assertthat::assert_that( + "feature" %in% names(targets), + msg = "'targets' data.frame must contain a 'feature' column." + ) + assertthat::assert_that( + "target" %in% names(targets), + msg = "'targets' data.frame must contain a 'target' column." + ) + assertthat::assert_that( + inherits(climateSmartDF, "data.frame"), # can be sf or just df after dropping geom + msg = "'climateSmartDF' must be a data.frame (or sf object)." + ) + assertthat::assert_that( + is.numeric(refugiaTarget) && length(refugiaTarget) == 1 && refugiaTarget >= 0 && refugiaTarget <= 1, + msg = "'refugiaTarget' must be a single numeric value between 0 and 1." + ) + # Check if climateSmartDF contains expected _CS and _NCS columns + assertthat::assert_that( + any(grepl("_CS$", names(climateSmartDF))) && any(grepl("_NCS$", names(climateSmartDF))), + msg = "'climateSmartDF' must contain columns with '_CS' and '_NCS' suffixes (output of splnr_climate_priorityArea_preprocess)." + ) + + + # Extract original species names from the 'targets' dataframe. spp <- targets %>% dplyr::select("feature") %>% dplyr::pull() + # Calculate total planning units for each climate-split feature type. featDF <- climateSmartDF %>% - sf::st_drop_geometry() %>% - dplyr::mutate(dplyr::across(dplyr::everything(), ~ tidyr::replace_na(.x, 0))) %>% - dplyr::summarize(dplyr::across(tidyselect::everything(), sum)) %>% - tidyr::pivot_longer(tidyselect::everything(), names_to = "feature", values_to = "planunit") + sf::st_drop_geometry() %>% # Drop geometry to perform numerical summaries. + dplyr::mutate(dplyr::across(dplyr::everything(), ~ tidyr::replace_na(.x, 0))) %>% # Replace NAs with 0. + dplyr::summarize(dplyr::across(tidyselect::everything(), sum)) %>% # Sum up presence counts for each feature component. + tidyr::pivot_longer(tidyselect::everything(), names_to = "feature", values_to = "planunit") # Pivot to long format. - finalList <- list() # empty list + finalList <- list() # Initialize an empty list to store adjusted targets for each feature. for (i in 1:length(spp)) { - filteredTarget <- targets %>% # Get the set target per feature + # Filter to get the original target for the current feature. + filteredTarget <- targets %>% dplyr::filter(.data$feature == spp[i]) - trgt <- filteredTarget$target # Extracting the target set for each feature + trgt <- filteredTarget$target # Extract the target value. + # Define the climate-split feature names for the current original feature. vars <- c( stringr::str_c(spp[i], "_CS"), stringr::str_c(spp[i], "_NCS") ) - suppressMessages({ + # Join the feature unit counts with the original targets. + suppressMessages({ # Suppress join messages. assignTarget <- featDF %>% dplyr::filter(.data$feature %in% vars) %>% dplyr::full_join(filteredTarget) }) - sumUnits <- sum(assignTarget$planunit, na.rm = TRUE) # getting the total of the feature + # Calculate the total number of planning units where the original feature is present. + # This sum includes both CS and NCS components for that feature. + sumUnits <- sum(assignTarget$planunit, na.rm = TRUE) + # Adjust 'planunit' for the original feature's row to represent its total units, then calculate proportion. assignTarget1 <- assignTarget %>% - dplyr::mutate(planunit = dplyr::if_else(stringr::str_ends(.data$feature, paste0(spp[i])), true = sumUnits, false = .data$planunit)) %>% + dplyr::mutate(planunit = dplyr::if_else(stringr::str_ends(.data$feature, spp[i]), true = sumUnits, false = .data$planunit)) %>% dplyr::mutate(proportion = .data$planunit / sumUnits) - reltargetCS <- assignTarget1[assignTarget1$feature == paste0(spp[i], "_CS"), "proportion"] %>% dplyr::pull() # get the relative target for the climate-smart areas + # Get the proportion of the feature that is in climate-smart areas. + reltargetCS <- assignTarget1[assignTarget1$feature == paste0(spp[i], "_CS"), "proportion"] %>% dplyr::pull() - if (reltargetCS > assignTarget1[assignTarget1$feature == spp[i], "target"]) { # Do this check; is the percentile greater than the assigned target for that feature? + # Conditional logic for assigning targets to CS and NCS components. + if (reltargetCS > assignTarget1[assignTarget1$feature == spp[i], "target"]) { + # If the climate-smart proportion is already greater than the original target, + # set CS target proportionally and NCS target to 0. targetCS <- (assignTarget1[assignTarget1$feature == spp[i], "target"] %>% as.numeric()) / (assignTarget1[assignTarget1$feature == paste0(spp[i], "_CS"), "proportion"] %>% as.numeric()) - targetNCS <- 0 } else { + # Otherwise, set CS target to refugiaTarget (usually 100%), and assign remaining target to NCS. targetCS <- refugiaTarget + # Calculate the remaining target for NCS areas. targetNCS <- ((assignTarget1[assignTarget1$feature == spp[i], "target"] %>% as.numeric()) - reltargetCS) / (assignTarget1[assignTarget1$feature == paste0(spp[i], "_NCS"), "proportion"] %>% as.numeric()) } + # Store the adjusted targets for the current feature's CS and NCS components. finalList[[i]] <- assignTarget1 %>% dplyr::mutate(target = dplyr::case_when( - stringr::str_ends(.data$feature, "_CS") ~ targetCS, - stringr::str_ends(.data$feature, "_NCS") ~ targetNCS + stringr::str_ends(.data$feature, "_CS") ~ targetCS, # Assign calculated CS target. + stringr::str_ends(.data$feature, "_NCS") ~ targetNCS # Assign calculated NCS target. )) %>% - dplyr::filter(.data$feature != spp[i]) %>% - dplyr::select("feature", "target") + dplyr::filter(.data$feature != spp[i]) %>% # Remove the original feature row. + dplyr::select("feature", "target") # Select only feature name and adjusted target. } + # Combine all adjusted targets for all features into a single dataframe. finalDF <- do.call(dplyr::bind_rows, finalList) return(finalDF) } -#' Function to run the climate-priority-area approach +#' @title Run the Climate Priority Area (CPA) Approach #' -#' @param features feature `sf`object -#' @param metric climate metric `sf` object with 'metric' as the column name of the metric values per planning unit. -#' @param targets `data.frame`with list of features under "feature" column and their corresponding targets under "target" column -#' @param refugiaTarget target assigned to climate-smart areas -#' @param direction If direction = 1, metric values are from low (least climate-smart) to high (most climate-smart). If direction = -1, metric values are from high (least climate-smart) to low (most climate-smart). -#' @param percentile cut-off threshold for determining whether an area is a climate priority area or not (e.g., lower 35th percentile of warming or upper 65th percentile of acidification). Note that the percentile here is the lower limit of the threshold. +#' @description +#' `splnr_climate_priorityAreaApproach()` implements the Climate Priority Area +#' approach by splitting conservation features into climate-smart (CS) and +#' non-climate-smart (NCS) components and adjusting their targets accordingly. +#' This allows conservation planning to prioritize areas with higher climate resilience. #' -#' @return A `list` with two components: 1. is the data frame passed to `prioritizr` when creating a conservation problem containing the binary information per planning unit per feature. 2. are the targets for the features in the conservation problem when the CPA approach is used. +#' @details +#' This function orchestrates the steps required for the CPA approach: +#' 1. **Preprocessing:** It calls `splnr_climate_priorityArea_preprocess()` to +#' categorize each feature's occurrences into CS and NCS areas based on a +#' climate metric and a specified `percentile` cutoff. +#' 2. **Target Assignment:** It then calls `splnr_climate_priorityArea_assignTargets()` +#' to calculate and assign new targets for these CS and NCS feature components. +#' This ensures that conservation goals reflect the desired emphasis on climate-smart +#' areas (e.g., aiming for 100% representation of features in highly resilient areas). +#' +#' The output of this function is a list containing the modified features (now +#' split into CS/NCS components) and their corresponding adjusted targets, ready +#' to be used in a `prioritizr` conservation problem. +#' +#' @param features An `sf` object representing conservation features (e.g., species +#' distribution data). Each column (excluding geometry) should typically be a +#' binary representation of a feature's presence (1) or absence (0) in each +#' planning unit. +#' @param metric An `sf` object containing climate metric information. It must +#' have a column named 'metric' with the climate metric values per planning unit. +#' @param targets A `data.frame` with two columns: `feature` (character, listing +#' the original feature names) and `target` (numeric, the initial conservation +#' target for each feature as a proportion, e.g., 0.3). +#' @param direction An integer specifying the direction of climate-smartness: +#' \itemize{ +#' \item `1`: Higher metric values mean more climate-smart areas. +#' \item `-1`: Lower metric values mean more climate-smart areas. +#' } +#' @param percentile A numeric value (0-100) representing the cutoff threshold for +#' determining climate-smart areas. For example, `percentile = 5` means the +#' most climate-smart 5% of areas (based on `direction`) are considered. +#' This value represents the lower limit of the threshold. Defaults to `5`. +#' @param refugiaTarget A numeric value (0-1) representing the target proportion +#' assigned specifically to climate-smart areas (refugia). Defaults to `1` (100%). +#' +#' @return A `list` with two components: +#' \itemize{ +#' \item `Features`: An `sf` object containing the binary information per +#' planning unit for each feature, now split into `_CS` (climate-smart) +#' and `_NCS` (non-climate-smart) components. This is ready to be +#' passed to `prioritizr` when creating a conservation problem. +#' \item `Targets`: A `data.frame` with the adjusted targets for the +#' climate-split features. This is also ready for `prioritizr`. +#' } #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr filter mutate select #' @importFrom rlang .data +#' @importFrom sf st_crs #' #' @examples +#' \dontrun{ +#' # Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects +#' # in your package. #' -#' targets <- dat_species_bin %>% +#' # Define initial targets for species features. +#' initial_targets <- dat_species_bin %>% #' sf::st_drop_geometry() %>% #' colnames() %>% #' data.frame() %>% #' setNames(c("feature")) %>% #' dplyr::mutate(target = 0.3) #' -#' CPA_Approach <- splnr_climate_priorityAreaApproach( +#' # Run the Climate Priority Area Approach where lower climate metric +#' # values mean more climate-smart areas. +#' CPA_Approach_result <- splnr_climate_priorityAreaApproach( #' features = dat_species_bin, #' metric = dat_clim, -#' targets = targets, -#' direction = -1 +#' targets = initial_targets, +#' direction = -1, # Example: lower metric values are more climate-smart +#' percentile = 5, +#' refugiaTarget = 1 #' ) -#' out_sf <- CPA_Approach$Features -#' targets <- CPA_Approach$Targets +#' +#' # Access the processed features and targets: +#' out_sf_cpa <- CPA_Approach_result$Features +#' targets_cpa <- CPA_Approach_result$Targets +#' +#' print(head(out_sf_cpa)) +#' print(head(targets_cpa)) +#' } splnr_climate_priorityAreaApproach <- function(features, metric, targets, @@ -250,19 +531,49 @@ splnr_climate_priorityAreaApproach <- function(features, percentile = 5, refugiaTarget = 1) { - #TODO check that geometry of both sf objects are the same. - - assertthat::assert_that(inherits(features, "sf"), - inherits(metric, "sf"), - is.data.frame(targets), - "feature" %in% names(targets), - "target" %in% names(targets), - direction %in% c(-1, 1), - is.numeric(percentile), - percentile >= 0 && percentile <= 100, - is.numeric(refugiaTarget), - refugiaTarget >= 0 && refugiaTarget <= 1) + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(features, "sf"), + msg = "'features' must be an 'sf' object." + ) + assertthat::assert_that( + inherits(metric, "sf"), + msg = "'metric' must be an 'sf' object." + ) + assertthat::assert_that( + "metric" %in% names(metric), + msg = "'metric' sf object must contain a column named 'metric'." + ) + assertthat::assert_that( + is.data.frame(targets), + msg = "'targets' must be a data.frame." + ) + assertthat::assert_that( + "feature" %in% names(targets), + msg = "'targets' data.frame must contain a 'feature' column." + ) + assertthat::assert_that( + "target" %in% names(targets), + msg = "'targets' data.frame must contain a 'target' column." + ) + assertthat::assert_that( + direction %in% c(-1, 1), + msg = "'direction' must be either 1 (higher metric = more climate-smart) or -1 (lower metric = more climate-smart)." + ) + assertthat::assert_that( + is.numeric(percentile) && length(percentile) == 1 && percentile >= 0 && percentile <= 100, + msg = "'percentile' must be a single numeric value between 0 and 100." + ) + assertthat::assert_that( + is.numeric(refugiaTarget) && length(refugiaTarget) == 1 && refugiaTarget >= 0 && refugiaTarget <= 1, + msg = "'refugiaTarget' must be a single numeric value between 0 and 1." + ) + assertthat::assert_that( + sf::st_crs(features) == sf::st_crs(metric), + msg = "CRS of 'features' and 'metric' must be the same." + ) + # Preprocess features to split them into climate-smart (CS) and non-climate-smart (NCS) areas. CPAFeatures <- splnr_climate_priorityArea_preprocess( features = features, metric = metric, @@ -270,163 +581,374 @@ splnr_climate_priorityAreaApproach <- function(features, percentile = percentile ) + # Assign adjusted targets for the CS and NCS feature components. CPATargets <- splnr_climate_priorityArea_assignTargets( targets = targets, - CPAFeatures, + climateSmartDF = CPAFeatures, # Use the preprocessed features for target assignment. refugiaTarget = refugiaTarget ) + # Return a list containing both the processed features and their adjusted targets. return(list(Features = CPAFeatures, Targets = CPATargets)) } -##### Feature Approach #### + ##### Feature Approach #### -#' Function to run the feature climate-smart approach +#' @title Preprocess Data for Feature Climate-Smart Approach #' -#' This function creates a climate layer by selecting the most climate-smart areas in the entire planning region. +#' @description +#' This internal function creates a "climate layer" by identifying the most +#' climate-smart areas across the entire planning region, based on a percentile +#' cutoff for a given climate metric. This layer is then attached to the +#' original features data. #' -#' @param features feature `sf`object -#' @param metric climate metric `sf` object with 'metric' as the column name of the metric values per planning unit.#' -#' @param direction If direction = 1, metric values are from low (least climate-smart) to high (most climate-smart). If direction = -1, metric values are from high (least climate-smart) to low (most climate-smart). -#' @param percentile cut-off threshold for determining whether an area is a climate priority area or not. Note that the percentile here is the lower limit of the threshold. +#' @details +#' The Feature Approach to climate-smart conservation aims to prioritize a fixed +#' proportion of the most climate-resilient areas (the `climate_layer`) and +#' ensure that conservation features are represented within this layer. #' -#' @return A `list` with two components: 1. is the data frame passed to `prioritizr` when creating a conservation problem containing the binary information per planning unit per feature. 2. are the targets for the features in the conservation problem when the CPA approach is used. +#' This preprocessing step involves: +#' 1. Identifying the `percentile` cutoff for the global climate `metric` data +#' (not per feature, as in CPA). +#' 2. Creating a binary `climate_layer` where planning units meeting the +#' climate-smart criteria are marked as 1, and others as 0. +#' 3. Joining this `climate_layer` back to the original `features` data. #' -#' @noRd +#' The `direction` parameter functions similarly to the CPA approach: +#' - `direction = 1`: Higher values of the `metric` are considered more climate-smart. +#' The `climate_layer` will include areas with metric values >= the `percentile`th quantile. +#' - `direction = -1`: Lower values of the `metric` are considered more climate-smart. +#' The `climate_layer` will include areas with metric values <= the `percentile`th quantile. +#' +#' @param features An `sf` object representing conservation features. +#' @param metric An `sf` object containing climate metric information. It must +#' have a column named 'metric' with the climate metric values per planning unit. +#' @param percentile A numeric value (0-100) representing the cutoff threshold for +#' determining whether an area is a climate priority area or not. This is applied +#' globally to the `metric` data. +#' @param direction An integer specifying the direction of climate-smartness: +#' \itemize{ +#' \item `1`: Higher metric values mean more climate-smart. +#' \item `-1`: Lower metric values mean more climate-smart. +#' } +#' +#' @return An `sf` dataframe identical to the input `features`, but with an +#' additional binary column named `climate_layer` indicating which planning +#' units are considered climate-smart. #' @keywords internal +#' @noRd +#' @importFrom assertthat assert_that +#' @importFrom dplyr mutate select #' @importFrom rlang .data +#' @importFrom sf st_join +#' @importFrom stats quantile #' #' @examples +#' \dontrun{ #' -#' featureTest <- splnr_climate_feature_preprocess( +#' # Example: Create a climate layer where higher metric values are climate-smart. +#' feature_preprocessed_data <- splnr_climate_feature_preprocess( #' features = dat_species_bin, -#' percentile = 5, +#' percentile = 5, # Top 5% most climate-smart areas #' metric = dat_clim, #' direction = 1 #' ) +#' print(feature_preprocessed_data) +#' +#' # Example: Create a climate layer where lower metric values are climate-smart. +#' feature_preprocessed_data_alt <- splnr_climate_feature_preprocess( +#' features = dat_species_bin, +#' percentile = 10, # Bottom 10% most climate-smart areas +#' metric = dat_clim, +#' direction = -1 +#' ) +#' print(feature_preprocessed_data_alt) +#' } splnr_climate_feature_preprocess <- function(features, percentile, metric, direction) { - if (any(apply(metric, 2, is.na)[, "metric"])) { - print("There are some NAs in the metric data. Please check.") + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(features, "sf"), + msg = "'features' must be an 'sf' object." + ) + assertthat::assert_that( + inherits(metric, "sf"), + msg = "'metric' must be an 'sf' object." + ) + assertthat::assert_that( + "metric" %in% names(metric), + msg = "'metric' sf object must contain a column named 'metric'." + ) + assertthat::assert_that( + is.numeric(percentile) && length(percentile) == 1 && percentile >= 0 && percentile <= 100, + msg = "'percentile' must be a single numeric value between 0 and 100." + ) + assertthat::assert_that( + direction %in% c(1, -1), + msg = "'direction' must be either 1 (higher metric = more climate-smart) or -1 (lower metric = more climate-smart)." + ) + assertthat::assert_that( + sf::st_crs(features) == sf::st_crs(metric), + msg = "CRS of 'features' and 'metric' must be the same." + ) + + + # Check for NAs in the 'metric' column and print a warning if found. + if (any(is.na(metric$metric))) { # Accessing 'metric' directly from 'metric' sf object + message("Warning: There are some NAs in the metric data. These will be removed from percentile calculation.") } + + # Convert percentile to proportion for quantile calculation. prct <- percentile / 100 - qntl <- stats::quantile(metric$metric, prct)[[1]] # Get the percentile + # Calculate the quantile cutoff based on the global metric values. + qntl <- stats::quantile(metric$metric, prct, na.rm = TRUE)[[1]] + + # Create the climate layer based on the direction. if (direction == 1) { - print("Higher values mean more climate-smart areas.") + message("Higher values mean more climate-smart areas.") # Inform user about the direction. + # Create the binary climate_layer: 1 if metric >= quantile, 0 otherwise. df <- metric %>% - dplyr::mutate(climate_layer = ifelse(.data$metric >= qntl, yes = 1, no = 0)) # Create the climate layer + dplyr::mutate(climate_layer = ifelse(.data$metric >= qntl, yes = 1, no = 0)) } else if (direction == -1) { - print("Lower values mean more climate-smart areas.") + message("Lower values mean more climate-smart areas.") # Inform user about the direction. + # Create the binary climate_layer: 1 if metric <= quantile, 0 otherwise. df <- metric %>% - dplyr::mutate(climate_layer = ifelse(.data$metric <= qntl, yes = 1, no = 0)) # Create the climate layer + dplyr::mutate(climate_layer = ifelse(.data$metric <= qntl, yes = 1, no = 0)) } else { - if (direction != 1 & direction != -1) { - print("Please enter a valid direction: either 1 or -1.") - return(NULL) - } + # This case should ideally be caught by assertthat, but included as a fallback. + stop("Please enter a valid direction: either 1 or -1.") } - - # Get the most climate-smart areas + # Select only the newly created 'climate_layer' column. climateSmartDF <- df %>% dplyr::select("climate_layer") - # Attach "climate_layer" to the features df and have this as the output + # Attach the "climate_layer" to the original features dataframe. features <- features %>% sf::st_join(climateSmartDF, join = sf::st_equals) return(features) } -#' Function to assign targets for the feature approach +#' @title Assign Targets for Feature Climate-Smart Approach #' -#' @param targets `data.frame`with list of features under "feature" column and their corresponding targets under "target" column -#' @param climateSmartDF `sf` object produced using the function splnr_ClimatePriorityArea_CSapproach() -#' @param refugiaTarget target assigned to climate-smart areas +#' @description +#' This internal function calculates and assigns conservation targets when using +#' the Feature Approach to climate-smart spatial planning. It adjusts targets +#' to ensure a specified `refugiaTarget` is met within the climate-smart layer. #' -#' @return A new sf dataframe that has cutoffs applied. -#' @noRd +#' @details +#' This function is a key component of the `splnr_climate_featureApproach()`. +#' It takes the initial conservation targets for features and modifies them +#' by introducing a new target for the `climate_layer` itself. +#' +#' The target for the `climate_layer` is calculated as `refugiaTarget` divided +#' by the proportion of the total planning units that are designated as +#' "climate-smart" (i.e., `sum(climateSmartDF$climate_layer) / nrow(climateSmartDF)`). +#' This effectively scales up the `refugiaTarget` to ensure that when `prioritizr` +#' tries to select `refugiaTarget` proportion of the total planning units for the +#' `climate_layer`, it will actually aim to select that proportion *within* the +#' climate-smart areas. +#' +#' The new `climate_layer` target is then appended to the original feature targets. +#' +#' @param climateSmartDF An `sf` object (or data frame) containing the +#' `climate_layer` column, typically produced by `splnr_climate_feature_preprocess()`. +#' @param refugiaTarget A numeric value (0-1) representing the target proportion +#' of climate-smart areas that should be selected. +#' @param targets A `data.frame` with two columns: `feature` (character, listing +#' the original feature names) and `target` (numeric, the initial conservation +#' target for each feature as a proportion, e.g., 0.3). +#' +#' @return A `data.frame` with two columns: `feature` (character, including +#' original feature names and "climate_layer") and `target` (the calculated +#' targets for these features). #' @keywords internal +#' @noRd #' -#' @importFrom rlang .data +#' @importFrom assertthat assert_that +#' @importFrom dplyr bind_rows +#' @importFrom tibble tribble #' #' @examples -#' Features <- dat_species_bin +#' \dontrun{ +#' # Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects. #' -#' targets <- Features %>% +#' # Define initial targets for species features. +#' initial_targets <- dat_species_bin %>% #' sf::st_drop_geometry() %>% #' colnames() %>% #' data.frame() %>% #' setNames(c("feature")) %>% #' dplyr::mutate(target = 0.3) #' -#' dat_species_binDF <- dat_species_bin %>% -#' sf::st_drop_geometry() -#' -#' out_sf <- splnr_climate_feature_preprocess( +#' # Preprocess features to get the climate layer. +#' preprocessed_features <- splnr_climate_feature_preprocess( #' features = dat_species_bin, #' percentile = 5, #' metric = dat_clim, #' direction = 1 #' ) #' -#' targets <- splnr_climate_feature_assignTargets( -#' targets = targets, -#' climateSmartDF = out_sf, -#' refugiaTarget = 0.3 +#' # Assign targets for the feature approach. +#' feature_assigned_targets <- splnr_climate_feature_assignTargets( +#' climateSmartDF = preprocessed_features, +#' refugiaTarget = 0.3, # Aim for 30% of climate-smart areas to be selected. +#' targets = initial_targets #' ) +#' print(feature_assigned_targets) +#' } splnr_climate_feature_assignTargets <- function(climateSmartDF, refugiaTarget, targets) { - # Calculate the target depending on the # of PUs deemed as "climate-smart" - trgt <- refugiaTarget / (sum(climateSmartDF$climate_layer) / nrow(climateSmartDF)) + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(climateSmartDF, "data.frame"), + msg = "'climateSmartDF' must be a data.frame (or sf object)." + ) + assertthat::assert_that( + "climate_layer" %in% names(climateSmartDF), + msg = "'climateSmartDF' must contain a 'climate_layer' column (output of splnr_climate_feature_preprocess)." + ) + assertthat::assert_that( + is.numeric(refugiaTarget) && length(refugiaTarget) == 1 && refugiaTarget >= 0 && refugiaTarget <= 1, + msg = "'refugiaTarget' must be a single numeric value between 0 and 1." + ) + assertthat::assert_that( + is.data.frame(targets), + msg = "'targets' must be a data.frame." + ) + assertthat::assert_that( + "feature" %in% names(targets), + msg = "'targets' data.frame must contain a 'feature' column." + ) + assertthat::assert_that( + "target" %in% names(targets), + msg = "'targets' data.frame must contain a 'target' column." + ) + + # Calculate the target for the 'climate_layer'. + # This scales the refugiaTarget by the inverse of the proportion of planning units + # that are climate-smart. This ensures that the desired refugiaTarget is met + # specifically within the climate-smart areas. + total_climate_smart_units <- sum(climateSmartDF$climate_layer, na.rm = TRUE) + total_planning_units <- nrow(climateSmartDF) + + if (total_planning_units == 0) { + stop("Input 'climateSmartDF' has no planning units. Cannot assign targets.") + } + proportion_climate_smart <- total_climate_smart_units / total_planning_units + + if (proportion_climate_smart == 0) { + stop("No climate-smart planning units identified. Cannot assign a target to the climate layer.") + } + + trgt <- refugiaTarget / proportion_climate_smart + + # Create a data frame for the climate layer's target. climate_layerDF <- tibble::tribble( ~feature, ~target, "climate_layer", trgt ) + # Combine the original targets with the new climate layer target. finalDF <- targets %>% - dplyr::bind_rows(climate_layerDF) # %>% - # dplyr::mutate(targets = .data$targets / 100) # Convert target to proportions + dplyr::bind_rows(climate_layerDF) return(finalDF) } -#' Function to run the feature approach +#' @title Run the Feature Climate-Smart Approach +#' +#' @description +#' `splnr_climate_featureApproach()` implements the Feature Approach to +#' climate-smart conservation planning. This involves defining a global +#' "climate-smart" layer and adjusting conservation targets to ensure that +#' a specified proportion of this layer is captured in the solution. +#' +#' @details +#' This function orchestrates the steps for the Feature Approach: +#' 1. **Preprocessing:** It calls `splnr_climate_feature_preprocess()` to +#' identify a region-wide climate-smart layer based on a percentile cutoff +#' of the climate metric. This layer is then added as a new binary feature +#' to your conservation data. +#' 2. **Target Assignment:** It then calls `splnr_climate_feature_assignTargets()` +#' to calculate and assign new targets. Crucially, a specific `refugiaTarget` +#' is set for the newly created `climate_layer` feature, ensuring that a +#' certain proportion of the most climate-resilient areas are included in +#' the final conservation plan. #' -#' @param features feature `sf`object -#' @param metric climate metric `sf` object with 'metric' as the column name of the metric values per planning unit. -#' @param targets `data.frame`with list of features under "feature" column and their corresponding targets under "target" column -#' @param refugiaTarget target assigned to climate-smart areas -#' @param direction If direction = 1, metric values are from low (least climate-smart) to high (most climate-smart). If direction = -1, metric values are from high (least climate-smart) to low (most climate-smart). -#' @param percentile cut-off threshold for determining whether an area is a climate priority area or not (e.g., lower 35th percentile of warming or upper 65th percentile of acidification). Note that the percentile here is the lower limit of the threshold. +#' The output is a list containing the modified features (now including the +#' `climate_layer`) and their corresponding adjusted targets, ready to be used +#' in a `prioritizr` conservation problem. #' -#' @return A `list` with two components: 1. is the data frame passed to `prioritizr` when creating a conservation problem containing the binary information per planning unit per feature. 2. are the targets for the features in the conservation problem when the CPA approach is used. +#' @param features An `sf` object representing conservation features (e.g., species +#' distribution data). +#' @param metric An `sf` object containing climate metric information. It must +#' have a column named 'metric' with the climate metric values per planning unit. +#' @param targets A `data.frame` with two columns: `feature` (character, listing +#' the original feature names) and `target` (numeric, the initial conservation +#' target for each feature as a proportion, e.g., 0.3). +#' @param direction An integer specifying the direction of climate-smartness: +#' \itemize{ +#' \item `1`: Higher metric values mean more climate-smart areas. +#' \item `-1`: Lower metric values mean more climate-smart areas. +#' } +#' @param percentile A numeric value (0-100) representing the cutoff threshold for +#' determining whether an area is a climate priority area or not. This is applied +#' globally to the `metric` data. Defaults to `35`. +#' @param refugiaTarget A numeric value (0-1) representing the target proportion +#' assigned to the overall climate-smart layer. Defaults to `0.3` (30%). +#' +#' @return A `list` with two components: +#' \itemize{ +#' \item `Features`: An `sf` object containing the binary information per +#' planning unit for each original feature, plus the new `climate_layer` +#' feature. This is ready to be passed to `prioritizr`. +#' \item `Targets`: A `data.frame` with the adjusted targets for all features, +#' including the `climate_layer`. This is also ready for `prioritizr`. +#' } #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr filter mutate select #' @importFrom rlang .data +#' @importFrom sf st_crs #' #' @examples -#' Features <- dat_species_bin +#' \dontrun{ +#' # Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects +#' # in your package. #' -#' targets <- Features %>% +#' # Define initial targets for species features. +#' initial_targets <- dat_species_bin %>% #' sf::st_drop_geometry() %>% #' colnames() %>% #' data.frame() %>% #' setNames(c("feature")) %>% #' dplyr::mutate(target = 0.3) #' -#' Feature_Approach <- splnr_climate_featureApproach( +#' # Run the Feature Approach where higher climate metric values mean +#' # more climate-smart areas. +#' Feature_Approach_result <- splnr_climate_featureApproach( #' features = dat_species_bin, #' metric = dat_clim, -#' targets = targets, -#' direction = 1 +#' targets = initial_targets, +#' direction = 1, # Example: higher metric values are more climate-smart +#' percentile = 35, +#' refugiaTarget = 0.3 #' ) -#' out_sf <- Feature_Approach$Features -#' targets <- Feature_Approach$Targets +#' +#' # Access the processed features and targets: +#' out_sf_feature <- Feature_Approach_result$Features +#' targets_feature <- Feature_Approach_result$Targets +#' +#' print(head(out_sf_feature)) +#' print(head(targets_feature)) +#' } splnr_climate_featureApproach <- function(features, metric, targets, @@ -434,20 +956,50 @@ splnr_climate_featureApproach <- function(features, percentile = 35, refugiaTarget = 0.3) { - #TODO Check that geometry is the same in all the asserts - - assertthat::assert_that(inherits(features, "sf"), - inherits(metric, "sf"), - is.data.frame(targets), - "feature" %in% names(targets), - "target" %in% names(targets), - direction %in% c(-1, 1), - is.numeric(percentile), - percentile >= 0 && percentile <= 100, - is.numeric(refugiaTarget), - refugiaTarget >= 0 && refugiaTarget <= 1) + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(features, "sf"), + msg = "'features' must be an 'sf' object." + ) + assertthat::assert_that( + inherits(metric, "sf"), + msg = "'metric' must be an 'sf' object." + ) + assertthat::assert_that( + "metric" %in% names(metric), + msg = "'metric' sf object must contain a column named 'metric'." + ) + assertthat::assert_that( + is.data.frame(targets), + msg = "'targets' must be a data.frame." + ) + assertthat::assert_that( + "feature" %in% names(targets), + msg = "'targets' data.frame must contain a 'feature' column." + ) + assertthat::assert_that( + "target" %in% names(targets), + msg = "'targets' data.frame must contain a 'target' column." + ) + assertthat::assert_that( + direction %in% c(-1, 1), + msg = "'direction' must be either 1 (higher metric = more climate-smart) or -1 (lower metric = more climate-smart)." + ) + assertthat::assert_that( + is.numeric(percentile) && length(percentile) == 1 && percentile >= 0 && percentile <= 100, + msg = "'percentile' must be a single numeric value between 0 and 100." + ) + assertthat::assert_that( + is.numeric(refugiaTarget) && length(refugiaTarget) == 1 && refugiaTarget >= 0 && refugiaTarget <= 1, + msg = "'refugiaTarget' must be a single numeric value between 0 and 1." + ) + assertthat::assert_that( + sf::st_crs(features) == sf::st_crs(metric), + msg = "CRS of 'features' and 'metric' must be the same." + ) + # Preprocess features to create the climate_layer. featureFeatures <- splnr_climate_feature_preprocess( features = features, metric = metric, @@ -455,217 +1007,511 @@ splnr_climate_featureApproach <- function(features, percentile = percentile ) + # Assign targets, including the new climate_layer. featureTargets <- splnr_climate_feature_assignTargets( targets = targets, - featureFeatures, refugiaTarget = refugiaTarget + climateSmartDF = featureFeatures, # Use the preprocessed features for target assignment. + refugiaTarget = refugiaTarget ) + # Return a list containing both the processed features and their adjusted targets. return(list(Features = featureFeatures, Targets = featureTargets)) } -##### Percentile Approach #### -#' Preprocessing for the percentile climate-smart approach -#' This function filters the species' distributions to their climate-smart areas only. -#' @param features feature sf object -#' @param metric climate metric `sf` object with 'metric' as the column name of the metric values per planning unit. -#' @param percentile cut-off threshold for determining whether an area is a climate priority area or not (e.g., lower 35th percentile of warming or upper 65th percentile of acidification). Note that the percentile here is the lower limit of the threshold. -#' @param direction If direction = 1, metric values are from low (least climate-smart) to high (most climate-smart). If direction = -1, metric values are from high (least climate-smart) to low (most climate-smart). + ##### Percentile Approach #### + +#' @title Preprocessing for the Percentile Climate-Smart Approach #' -#' @return A new sf dataframe that has cutoffs applied. -#' @noRd +#' @description +#' This internal function filters the distributions of each conservation feature +#' to include only their occurrences within "climate-smart" areas. These areas +#' are defined by a percentile cutoff of a climate metric applied to each +#' feature's distribution. +#' +#' @details +#' The Percentile Approach to climate-smart conservation ensures that a certain +#' proportion of each feature's occurrence within its most climate-resilient +#' habitats is protected. This preprocessing step identifies these areas. +#' +#' For each feature, the function performs the following: +#' 1. Joins the feature data with the climate metric data. +#' 2. Filters to include only planning units where the feature is present. +#' 3. Calculates the `percentile` cutoff for the climate metric *within that +#' specific feature's distribution*. +#' 4. Creates a new binary column for each feature (`_filtered`) indicating +#' planning units where the feature is present AND the climate metric meets +#' the climate-smart criteria (e.g., top 5% for direction 1, bottom 5% for direction -1). +#' All other planning units for that feature are set to 0 in this new column. +#' +#' The `direction` parameter defines what constitutes "climate-smart": +#' - `direction = 1`: Higher values of the `metric` are more climate-smart. +#' The function selects areas with metric values greater than or equal to the +#' `(100 - percentile)`th quantile of the feature's occupied metric values. +#' - `direction = -1`: Lower values of the `metric` are more climate-smart. +#' The function selects areas with metric values less than or equal to the +#' `percentile`th quantile of the feature's occupied metric values. +#' +#' @param features An `sf` object representing conservation features. Each column +#' (excluding geometry) should typically be a binary representation of a feature's +#' presence (1) or absence (0) in each planning unit. +#' @param metric An `sf` object containing climate metric information. It must +#' have a column named 'metric' with the climate metric values per planning unit. +#' @param percentile A numeric value (0-100) representing the cutoff threshold for +#' determining whether an area is a climate priority area or not. This is applied +#' *per feature* to its distribution. +#' @param direction An integer specifying the direction of climate-smartness: +#' \itemize{ +#' \item `1`: Higher metric values mean more climate-smart. +#' \item `-1`: Lower metric values mean more climate-smart. +#' } +#' +#' @return An `sf` dataframe where each column represents an original feature, +#' but its values are now filtered (`_filtered` suffix implicitly removed in `rename_all`) +#' to 1 only in planning units that are part of its climate-smart percentile. +#' All other values are 0. The dataframe retains the original geometry. #' @keywords internal +#' @noRd #' -#' @importFrom rlang .data +#' @importFrom assertthat assert_that +#' @importFrom dplyr across bind_cols filter if_else mutate select +#' @importFrom rlang .data sym +#' @importFrom sf st_as_sf st_drop_geometry st_join st_set_geometry +#' @importFrom stats quantile +#' @importFrom stringr str_sub +#' @importFrom tidyselect everything #' #' @examples +#' \dontrun{ +#' # Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects +#' # in your package. #' -#' out_sf <- splnr_climate_percentile_preprocess( +#' # Example: Filter species distributions to their top 5% most climate-smart areas, +#' # where higher metric values are considered more climate-smart. +#' percentile_preprocessed_data <- splnr_climate_percentile_preprocess( #' features = dat_species_bin, #' metric = dat_clim, #' percentile = 5, #' direction = 1 #' ) +#' print(percentile_preprocessed_data) +#' +#' # Example: Filter to bottom 10% most climate-smart areas, +#' # where lower metric values are considered more climate-smart. +#' percentile_preprocessed_data_alt <- splnr_climate_percentile_preprocess( +#' features = dat_species_bin, +#' metric = dat_clim, +#' percentile = 10, +#' direction = -1 +#' ) +#' print(percentile_preprocessed_data_alt) +#' } splnr_climate_percentile_preprocess <- function(features, metric, percentile, direction) { - if (any(apply(metric, 2, is.na)[, "metric"])) { - print("There are some NAs in the metric data. Please check.") + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(features, "sf"), + msg = "'features' must be an 'sf' object." + ) + assertthat::assert_that( + inherits(metric, "sf"), + msg = "'metric' must be an 'sf' object." + ) + assertthat::assert_that( + "metric" %in% names(metric), + msg = "'metric' sf object must contain a column named 'metric'." + ) + assertthat::assert_that( + is.numeric(percentile) && length(percentile) == 1 && percentile >= 0 && percentile <= 100, + msg = "'percentile' must be a single numeric value between 0 and 100." + ) + assertthat::assert_that( + direction %in% c(1, -1), + msg = "'direction' must be either 1 (higher metric = more climate-smart) or -1 (lower metric = more climate-smart)." + ) + assertthat::assert_that( + sf::st_crs(features) == sf::st_crs(metric), + msg = "CRS of 'features' and 'metric' must be the same." + ) + + # Check for NAs in the 'metric' column and print a warning if found. + if (any(is.na(metric$metric))) { + message("Warning: There are some NAs in the metric data. Please check.") } - spp <- features %>% # Get the list of features + # Get the list of feature names (excluding geometry). + spp <- features %>% sf::st_drop_geometry() %>% names() - percentileList <- list() + percentileList <- list() # Initialize an empty list to store processed data for each feature. for (i in 1:length(spp)) { + # Select 1 feature at a time from original features data and join with the metric layer. df <- features %>% - dplyr::select(!!rlang::sym(spp[i]),) %>% # Select 1 feature at a time - sf::st_join(metric, join = sf::st_equals) %>% # Join with the metric layer - sf::st_drop_geometry() # Drop here otherwise we get multiple version below + dplyr::select(!!rlang::sym(spp[i]),) %>% + sf::st_join(metric, join = sf::st_equals) + + # Check for NAs in the metric column of the joined data frame for the current feature + # and print a warning if found. + if (any(is.na(df$metric))) { + message(paste0("Warning: NAs found in 'metric' for feature '", spp[i], "'. These will be excluded from percentile calculation.")) + } + # Filter to select only areas where the current feature is present (value = 1). filteredDF <- df %>% - dplyr::filter(!!rlang::sym(spp[i]) == 1) # Select only areas with presences + dplyr::filter(!!rlang::sym(spp[i]) == 1) + + # Handle cases where filteredDF might be empty (feature not present in any unit or only in NAs) + if (nrow(filteredDF) == 0) { + warning(paste0("Feature '", spp[i], "' is not present in any planning unit with valid metric data. Skipping percentile calculation for this feature.")) + # Create an empty df with expected column for binding later + temp_df <- df %>% + sf::st_drop_geometry() %>% # Drop geometry for consistency with other iterations + dplyr::mutate(V1 = 0, V2 = 0) %>% # Add V1 and V2 columns with 0 values + dplyr::mutate(!!rlang::sym(paste0(spp[i], "_filtered")) := 0) %>% + dplyr::select(!!rlang::sym(paste0(spp[i], "_filtered"))) + percentileList[[i]] <- temp_df + next # Skip to the next iteration of the loop + } + + + # Convert percentile to proportion. + prct <- percentile / 100 + # Calculate the quantile cutoff within the current feature's distribution. + qntl <- stats::quantile(filteredDF$metric, prct, na.rm = TRUE)[[1]] - prct <- percentile / 100 # Convert percentiles to proportions - qntl <- stats::quantile(filteredDF$metric, prct)[[1]] # Get the percentile + # Apply filtering based on direction to create temporary V1 and V2 columns. if (direction == 1) { - if (i == 1) { - print("Higher values mean more climate-smart areas.") # Sanity check + if (i == 1) { # Only print for the first iteration. + message("Higher values mean more climate-smart areas.") } df1 <- df %>% dplyr::mutate( - V1 = ifelse(metric >= qntl, yes = 1, no = 0), # Filter areas of the highest xth percentile within feat's distribution - V2 = ifelse(!!rlang::sym(spp[i]) == 1, yes = 1, no = 0) - ) # Filter areas with the feat present in it + V1 = ifelse(.data$metric >= qntl, yes = 1, no = 0), # 1 if metric is in climate-smart percentile, 0 otherwise. + V2 = ifelse(!!rlang::sym(spp[i]) == 1, yes = 1, no = 0) # 1 if feature is present, 0 otherwise. + ) } else if (direction == -1) { - if (i == 1) { - print("Lower values mean more climate-smart areas.") # Sanity check + if (i == 1) { # Only print for the first iteration. + message("Lower values mean more climate-smart areas.") } df1 <- df %>% dplyr::mutate( - V1 = ifelse(metric <= qntl, yes = 1, no = 0), # Filter areas of the highest xth percentile within feat's distribution - V2 = ifelse(!!rlang::sym(spp[i]) == 1, yes = 1, no = 0) - ) # Filter areas with the feat present in it + V1 = ifelse(.data$metric <= qntl, yes = 1, no = 0), # 1 if metric is in climate-smart percentile, 0 otherwise. + V2 = ifelse(!!rlang::sym(spp[i]) == 1, yes = 1, no = 0) # 1 if feature is present, 0 otherwise. + ) } else { + # This case should ideally be caught by assertthat, but included as a fallback. if (i == 1) { - print("Please enter a valid direction: either 1 or -1.") # Sanity check + stop("Please enter a valid direction: either 1 or -1.") } } + # Drop geometry for subsequent bind_cols operations if not the first iteration. + # We will re-add the geometry from the original 'features' object at the end. + if (i > 1 && "geometry" %in% names(df1)){ + df1 <- df1 %>% sf::st_drop_geometry() + } else if (i == 1 && "geometry" %in% names(df1)){ + # For the first iteration, keep geometry if it exists, and make sure it's the right one. + # This block ensures that the geometry is the actual sf geometry and not just a column name. + # The do.call(dplyr::bind_cols, ...) will handle the geometry column from the first element. + df1 <- df1 %>% dplyr::select(-"geometry") # Temporarily remove geometry + } + + # Calculate the final filtered feature layer (1 if present in climate-smart percentile, 0 otherwise). percentileList[[i]] <- df1 %>% - dplyr::mutate(!!rlang::sym(paste0(spp[i], "_filtered")) := .data$V1 * .data$V2) %>% # V1*V2 will be 1 if area is within the xth percentile and if a feat is present in it - dplyr::select(!!rlang::sym(paste0(spp[i], "_filtered"))) + dplyr::mutate(!!rlang::sym(paste0(spp[i], "_filtered")) := .data$V1 * .data$V2) %>% # V1*V2 is 1 if area is within percentile AND feature is present. + dplyr::select(!!rlang::sym(paste0(spp[i], "_filtered"))) # Select only the filtered column. } - resultDF <- do.call(dplyr::bind_cols, percentileList) %>% # Create sf object as output - dplyr::rename_all(~ stringr::str_sub(.x, end = -10)) %>% - dplyr::bind_cols(features %>% dplyr::select("geometry")) %>% - dplyr::select(tidyselect::everything()) %>% - sf::st_as_sf(sf_column_name = "geometry") + # Combine all processed data frames into a single dataframe. + # Rename columns to remove the "_filtered" suffix for easier use. + + resultDF <- do.call(dplyr::bind_cols, percentileList) %>% + dplyr::rename_all(~ stringr::str_remove(.x, "_filtered$")) %>% # Remove "_filtered" suffix. + # Re-add the geometry column from the original features object. + sf::st_set_geometry(features$geometry) %>% + dplyr::select(tidyselect::everything()) %>% # Select all columns, ensuring order. + sf::st_as_sf() # Convert back to sf object. return(resultDF) } -#' Function to assign targets for the percentile approach +#' @title Assign Targets for Percentile Climate-Smart Approach #' -#' @param features feature sf object -#' @param targets `data.frame`with list of features under "feature" column and their corresponding targets under "target" column -#' @param climateSmartDF `sf` object produced using the function `splnr_climate_percentile_preprocess()` +#' @description +#' This internal function calculates and assigns conservation targets when using +#' the Percentile Approach to climate-smart spatial planning. It adjusts targets +#' to account for the filtering of feature distributions to only their +#' climate-smart areas. #' -#' @return A new sf dataframe that has cutoffs applied. -#' @noRd +#' @details +#' This function is a key component of the `splnr_climate_percentileApproach()`. +#' It takes the original conservation targets for features and adjusts them based +#' on how much of each feature's total occurrence was retained after filtering +#' for climate-smart areas in `splnr_climate_percentile_preprocess()`. +#' +#' The target adjustment logic is as follows: +#' 1. Calculates the "original" total number of planning units where each feature is present. +#' 2. Calculates the "filtered" total number of planning units where each feature +#' is present *within its climate-smart percentile* (from `climateSmartDF`). +#' 3. Determines the `proportion` of the filtered presence relative to the +#' original presence for each feature (`filtered / original`). +#' 4. The new target for each feature is then calculated by dividing its original +#' target by this `proportion`. This scales up the target to ensure that the +#' original conservation goal is still met, but specifically within the +#' identified climate-smart areas. +#' 5. Targets are capped at `1` (100%) to prevent values greater than 1. +#' +#' @param features An `sf` object representing original conservation features. +#' This is used to determine the total (unfiltered) presence of each feature. +#' @param targets A `data.frame` with two columns: `feature` (character, listing +#' the original feature names) and `target` (numeric, the initial conservation +#' target for each feature as a proportion, e.g., 0.3). +#' @param climateSmartDF An `sf` object (or data frame) produced by +#' `splnr_climate_percentile_preprocess()`. This dataframe contains the +#' features filtered to their climate-smart areas. +#' +#' @return A `data.frame` with two columns: `feature` (character, with original +#' feature names) and `target` (the newly calculated, adjusted targets). #' @keywords internal +#' @noRd #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr across everything left_join mutate select summarize #' @importFrom rlang .data +#' @importFrom sf st_drop_geometry +#' @importFrom tibble as_tibble +#' @importFrom tidyr replace_na pivot_longer #' #' @examples -#' Features <- dat_species_bin +#' \dontrun{ +#' # Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects. #' -#' targets <- Features %>% +#' # Define initial targets for species features. +#' initial_targets <- dat_species_bin %>% #' sf::st_drop_geometry() %>% #' colnames() %>% #' data.frame() %>% #' setNames(c("feature")) %>% #' dplyr::mutate(target = 0.3) #' -#' dat_species_binDF <- dat_species_bin %>% -#' sf::st_drop_geometry() -#' -#' out_sf <- splnr_climate_percentile_preprocess( +#' # Preprocess features to get climate-smart filtered areas. +#' preprocessed_features_percentile <- splnr_climate_percentile_preprocess( #' features = dat_species_bin, #' metric = dat_clim, #' percentile = 35, #' direction = 1 #' ) #' -#' targets <- splnr_climate_percentile_assignTargets( -#' features = dat_species_bin, -#' targets = targets, -#' climateSmartDF = out_sf +#' # Assign targets for the percentile approach. +#' percentile_assigned_targets <- splnr_climate_percentile_assignTargets( +#' features = dat_species_bin, # Original features for 'original' counts +#' targets = initial_targets, +#' climateSmartDF = preprocessed_features_percentile #' ) +#' print(percentile_assigned_targets) +#' } splnr_climate_percentile_assignTargets <- function(features, climateSmartDF, targets) { - spp <- features %>% # Get the list of features - sf::st_drop_geometry() %>% - names() + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(features, "sf"), + msg = "'features' must be an 'sf' object." + ) + assertthat::assert_that( + is.data.frame(targets), + msg = "'targets' must be a data.frame." + ) + assertthat::assert_that( + "feature" %in% names(targets), + msg = "'targets' data.frame must contain a 'feature' column." + ) + assertthat::assert_that( + "target" %in% names(targets), + msg = "'targets' data.frame must contain a 'target' column." + ) + assertthat::assert_that( + inherits(climateSmartDF, "data.frame"), # can be sf or just df after dropping geom + msg = "'climateSmartDF' must be a data.frame (or sf object)." + ) + # Check that column names in climateSmartDF match expected original feature names + # (after removing any potential _filtered suffix from the internal preprocessing) + original_feature_names <- features %>% sf::st_drop_geometry() %>% names() + filtered_feature_names <- climateSmartDF %>% sf::st_drop_geometry() %>% names() + assertthat::assert_that( + all(original_feature_names %in% filtered_feature_names), + msg = "Feature names in 'climateSmartDF' do not match original feature names in 'features'." + ) + + # Get the total number of planning units where each feature is originally present. + # Suppress messages from dplyr::summarize with `suppressMessages`. suppressMessages({ df <- features %>% - sf::st_drop_geometry() %>% - dplyr::mutate_all(~ ifelse(is.na(.), 0, .)) %>% - tibble::as_tibble() %>% - dplyr::summarize(dplyr::across(dplyr::everything(), sum)) %>% # Get the # of planning units where feature is present - tidyr::pivot_longer(tidyselect::everything(), names_to = "feature", values_to = "original") %>% - dplyr::left_join(targets) # %>% - # dplyr::mutate(feature = paste0(.data$feature, "_filtered")) # Change names - + sf::st_drop_geometry() %>% # Drop geometry for aggregation. + dplyr::mutate(dplyr::across(dplyr::everything(), ~ tidyr::replace_na(.x, 0))) %>% # Replace NAs with 0. + tibble::as_tibble() %>% # Convert to tibble for consistent behavior. + dplyr::summarize(dplyr::across(dplyr::everything(), sum)) %>% # Sum up occurrences for each feature. + tidyr::pivot_longer(tidyselect::everything(), names_to = "feature", values_to = "original") %>% # Pivot to long format. + dplyr::left_join(targets, by = "feature") # Join with original targets. + + # Get the total number of planning units selected using the climate-smart filtering. df1 <- climateSmartDF %>% - sf::st_drop_geometry() %>% - dplyr::mutate_all(~ ifelse(is.na(.), 0, .)) %>% - tibble::as_tibble() %>% - dplyr::summarize(dplyr::across(dplyr::everything(), sum)) %>% # Get the # of planning units selected using the climate-smart approach - tidyr::pivot_longer(tidyselect::everything(), names_to = "feature", values_to = "filtered") + sf::st_drop_geometry() %>% # Drop geometry for aggregation. + dplyr::mutate(dplyr::across(dplyr::everything(), ~ tidyr::replace_na(.x, 0))) %>% # Replace NAs with 0. + tibble::as_tibble() %>% # Convert to tibble. + dplyr::summarize(dplyr::across(dplyr::everything(), sum)) %>% # Sum up occurrences of filtered features. + tidyr::pivot_longer(tidyselect::everything(), names_to = "feature", values_to = "filtered") # Pivot to long format. + # Join the original counts with the filtered counts, calculate proportion, and adjust targets. df <- df %>% - dplyr::left_join(df1) %>% - dplyr::mutate(proportion = .data$filtered / .data$original) %>% # Calculating proportion of climate-smart areas over areas where feat is present - dplyr::mutate(target = .data$target / .data$proportion) %>% # Calculate target based on the set target per feature and the proportion - dplyr::select("feature", "target") %>% - # dplyr::mutate(targets = .data$targets / 100) %>% # Convert target to proportions - dplyr::mutate(target = ifelse(.data$target > 1, 1, .data$target)) # Make sure that 100% is the largest target possible + dplyr::left_join(df1, by = "feature") %>% # Join filtered counts. + dplyr::mutate( + # Calculate the proportion of the filtered presence relative to the original presence. + proportion = dplyr::if_else(.data$original > 0, .data$filtered / .data$original, 0), + # Calculate new target: original target divided by proportion. + # Handle cases where proportion might be zero to avoid division by zero. + target = dplyr::if_else(.data$proportion > 0, .data$target / .data$proportion, .data$target) + ) %>% + dplyr::select("feature", "target") %>% # Select only feature and adjusted target. + dplyr::mutate(target = ifelse(.data$target > 1, 1, .data$target)) # Cap targets at 1 (100%). }) return(df) } -#' Function to run the percentile approach +#' @title Run the Percentile Climate-Smart Approach +#' +#' @description +#' `splnr_climate_percentileApproach()` implements the Percentile Approach to +#' climate-smart conservation planning. This involves filtering features to +#' their most climate-resilient areas and adjusting their conservation targets +#' to account for this reduced feature distribution. #' -#' @param features feature `sf`object -#' @param metric climate metric `sf` object with 'metric' as the column name of the metric values per planning unit. -#' @param targets `data.frame`with list of features under "feature" column and their corresponding targets under "target" column -#' @param direction If direction = 1, metric values are from low (least climate-smart) to high (most climate-smart). If direction = -1, metric values are from high (least climate-smart) to low (most climate-smart). -#' @param percentile cut-off threshold for determining whether an area is a climate priority area or not (e.g., lower 35th percentile of warming or upper 65th percentile of acidification). Note that the percentile here is the lower limit of the threshold. +#' @details +#' This function orchestrates the steps for the Percentile Approach: +#' 1. **Preprocessing:** It calls `splnr_climate_percentile_preprocess()` to +#' identify, for each feature, its occurrences within the most climate-resilient +#' `percentile` of its distribution based on a climate metric. This effectively +#' "filters" the feature data to only include its climate-smart components. +#' 2. **Target Assignment:** It then calls `splnr_climate_percentile_assignTargets()` +#' to calculate and assign new targets for these filtered features. The targets +#' are scaled up to ensure that the original conservation goals are still met, +#' but specifically by selecting areas from the climate-smart portions of the +#' features' distributions. #' -#' @return A `list` with two components: 1. is the data frame passed to `prioritizr` when creating a conservation problem containing the binary information per planning unit per feature. 2. are the targets for the features in the conservation problem when the CPA approach is used. +#' The output is a list containing the modified features (filtered to their +#' climate-smart occurrences) and their corresponding adjusted targets, ready +#' to be used in a `prioritizr` conservation problem. +#' +#' @param features An `sf` object representing conservation features (e.g., species +#' distribution data). +#' @param metric An `sf` object containing climate metric information. It must +#' have a column named 'metric' with the climate metric values per planning unit. +#' @param targets A `data.frame` with two columns: `feature` (character, listing +#' the original feature names) and `target` (numeric, the initial conservation +#' target for each feature as a proportion, e.g., 0.3). +#' @param direction An integer specifying the direction of climate-smartness: +#' \itemize{ +#' \item `1`: Higher metric values mean more climate-smart areas. +#' \item `-1`: Lower metric values mean more climate-smart areas. +#' } +#' @param percentile A numeric value (0-100) representing the cutoff threshold for +#' determining whether an area is a climate priority area or not. This is applied +#' *per feature* to its distribution. Defaults to `35`. +#' +#' @return A `list` with two components: +#' \itemize{ +#' \item `Features`: An `sf` object containing the binary information per +#' planning unit for each feature, now filtered to include only its +#' climate-smart occurrences. This is ready to be passed to `prioritizr`. +#' \item `Targets`: A `data.frame` with the adjusted targets for the +#' filtered features. This is also ready for `prioritizr`. +#' } #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr filter mutate select #' @importFrom rlang .data +#' @importFrom sf st_crs #' #' @examples +#' \dontrun{ +#' # Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects +#' # in your package. #' -#' targets <- dat_species_bin %>% +#' # Define initial targets for species features. +#' initial_targets <- dat_species_bin %>% #' sf::st_drop_geometry() %>% #' colnames() %>% #' data.frame() %>% #' setNames(c("feature")) %>% #' dplyr::mutate(target = 0.3) #' -#' Percentile_Approach <- splnr_climate_percentileApproach( +#' # Run the Percentile Approach where higher climate metric values mean +#' # more climate-smart areas. +#' Percentile_Approach_result <- splnr_climate_percentileApproach( #' features = dat_species_bin, #' metric = dat_clim, -#' targets = targets, -#' direction = 1 +#' targets = initial_targets, +#' direction = 1, # Example: higher metric values are more climate-smart +#' percentile = 35 #' ) -#' out_sf <- Percentile_Approach$Features -#' targets <- Percentile_Approach$Targets +#' +#' # Access the processed features and targets: +#' out_sf_percentile <- Percentile_Approach_result$Features +#' targets_percentile <- Percentile_Approach_result$Targets +#' +#' print(head(out_sf_percentile)) +#' print(head(targets_percentile)) +#' } splnr_climate_percentileApproach <- function(features, metric, targets, direction, percentile = 35) { - assertthat::assert_that(inherits(features, "sf"), - inherits(metric, "sf"), - is.data.frame(targets), - "feature" %in% names(targets), - "target" %in% names(targets), - direction %in% c(-1, 1), - is.numeric(percentile), - percentile >= 0 && percentile <= 100) - + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(features, "sf"), + msg = "'features' must be an 'sf' object." + ) + assertthat::assert_that( + inherits(metric, "sf"), + msg = "'metric' must be an 'sf' object." + ) + assertthat::assert_that( + "metric" %in% names(metric), + msg = "'metric' sf object must contain a column named 'metric'." + ) + assertthat::assert_that( + is.data.frame(targets), + msg = "'targets' must be a data.frame." + ) + assertthat::assert_that( + "feature" %in% names(targets), + msg = "'targets' data.frame must contain a 'feature' column." + ) + assertthat::assert_that( + "target" %in% names(targets), + msg = "'targets' data.frame must contain a 'target' column." + ) + assertthat::assert_that( + direction %in% c(-1, 1), + msg = "'direction' must be either 1 (higher metric = more climate-smart) or -1 (lower metric = more climate-smart)." + ) + assertthat::assert_that( + is.numeric(percentile) && length(percentile) == 1 && percentile >= 0 && percentile <= 100, + msg = "'percentile' must be a single numeric value between 0 and 100." + ) + assertthat::assert_that( + sf::st_crs(features) == sf::st_crs(metric), + msg = "CRS of 'features' and 'metric' must be the same." + ) + # Preprocess features to filter them to their climate-smart areas. percentileFeatures <- splnr_climate_percentile_preprocess( features = features, metric = metric, @@ -673,13 +1519,12 @@ splnr_climate_percentileApproach <- function(features, percentile = percentile ) + # Assign adjusted targets for the filtered features. percentileTargets <- splnr_climate_percentile_assignTargets( - features = features, + features = features, # Original features are needed to get original counts. targets = targets, - percentileFeatures + climateSmartDF = percentileFeatures # Use the preprocessed features for target assignment. ) + # Return a list containing both the processed features and their adjusted targets. return(list(Features = percentileFeatures, Targets = percentileTargets)) } - - -##### Penalty Approach ##### diff --git a/R/utils.R b/R/utils.R index 58b4a0da..8d1cbebb 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,242 +1,572 @@ -#' Function for creating polygon +##### Utility Functions #### + +#' @title Create Spatial Polygon from Coordinates +#' +#' @description +#' `splnr_create_polygon()` constructs an `sf` polygon object from a series +#' of longitude and latitude coordinates provided in a tibble. #' -#' `splnr_create_polygon()` allows you to create a polygon based on longitude and latitude coordinates in your input data. +#' @details +#' This utility function simplifies the creation of spatial polygons from a +#' tabular format of coordinates. It takes a tibble where columns 'x' and 'y' +#' represent longitude and latitude, respectively. These coordinates are +#' converted into a matrix, then to an `sf` polygon, and finally to an `sf` +#' object with the specified Coordinate Reference System (CRS). #' -#' @param x A named vector of lon/lat coordinates from which to make an `sf` polygon -#' @param cCRS The CRS to use for the polygon +#' The function assumes that the input coordinates (`x`) are initially in +#' WGS 84 (EPSG:4326) and then transforms them to the `cCRS` if a different +#' CRS is specified. #' -#' @return An `sf` object for the polygon +#' @param x A `tibble` (or `tbl_df`) object with at least two columns, +#' typically named `x` (for longitude) and `y` (for latitude), representing +#' the vertices of the polygon in sequence. The first and last coordinate +#' pair should be the same to form a closed polygon. +#' @param cCRS A character string specifying the target CRS for the output polygon +#' in an EPSG code format (e.g., "EPSG:4326"). Defaults to "EPSG:4326" (WGS 84). +#' +#' @return An `sf` object representing the created polygon, with the specified CRS. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr bind_rows tibble +#' @importFrom sf st_polygon st_sfc st_transform st_sf +#' #' @examples -#' splnr_create_polygon(x = dplyr::tibble(x = seq(-50, 50, by = 1), y = 120) %>% -#' dplyr::bind_rows(dplyr::tibble(x = 50, y = seq(120, 180, by = 1))) %>% -#' dplyr::bind_rows(dplyr::tibble(x = seq(50, -50, by = -1), y = 180)) %>% -#' dplyr::bind_rows(dplyr::tibble(x = -50, y = seq(150, 120, by = -1)))) +#' # Example: Create a simple square polygon +#' square_coords <- dplyr::tibble( +#' x = c(-50, 50, 50, -50, -50), +#' y = c(120, 120, 180, 180, 120) +#' ) +#' simple_polygon <- splnr_create_polygon(x = square_coords) +#' print(simple_polygon) +#' +#' # Example: Create a polygon and transform to a different CRS (e.g., a UTM zone) +#' \dontrun{ +#' # Note: EPSG:32611 is UTM Zone 11N. Ensure it's appropriate for your coordinates. +#' transformed_polygon <- splnr_create_polygon(x = square_coords, cCRS = "EPSG:32611") +#' print(transformed_polygon) +#' } splnr_create_polygon <- function(x, cCRS = "EPSG:4326") { + # Assertions to validate input parameters. assertthat::assert_that( - inherits(x, "tbl_df") && !is.null(attributes(x)), - is.character(cCRS) + inherits(x, "data.frame") && !is.null(x$x) && !is.null(x$y), + msg = "'x' must be a data.frame (or tibble) with 'x' and 'y' columns representing coordinates." + ) + assertthat::assert_that( + is.numeric(x$x) && is.numeric(x$y), + msg = "Coordinates 'x' and 'y' in the input data frame must be numeric." + ) + assertthat::assert_that( + is.character(cCRS) && length(cCRS) == 1, + msg = "'cCRS' must be a single character string specifying the CRS (e.g., 'EPSG:4326')." ) - x <- x %>% + # Convert the input tibble to a matrix, then to a list, which is the required + # format for sf::st_polygon. + # st_polygon expects a list of matrices, where each matrix defines a linear ring. + polygon_matrix <- x %>% as.matrix() %>% - list() %>% - sf::st_polygon() %>% - sf::st_sfc(crs = "EPSG:4326") %>% - sf::st_transform(crs = cCRS) %>% + list() + + # Create an sf polygon object from the matrix, then create an sfc (simple feature column) + # with an initial CRS of EPSG:4326 (WGS 84 assumed for input lat/lon). + polygon_sfc <- sf::st_polygon(polygon_matrix) %>% + sf::st_sfc(crs = "EPSG:4326") + + # Transform the polygon to the target CRS specified by cCRS. + # This is crucial for ensuring the output polygon is in the desired projection. + transformed_polygon_sfc <- polygon_sfc %>% + sf::st_transform(crs = cCRS) + + # Convert the sfc object to an sf (simple features) object, which is a data frame + # with a geometry column. + final_sf_polygon <- transformed_polygon_sfc %>% sf::st_sf() -} + return(final_sf_polygon) +} -#' Remove NAs from spatial data using nearest neighbour +#' @title Remove NAs from Spatial Data Using Nearest Neighbour #' -#' `splnr_replace_NAs()` allows you to replace NA values in your data with the value of the nearest neighbour. -#' The nearest neighbour is determined using `st_nearest_feature()` from the `sf` package. +#' @description +#' `splnr_replace_NAs()` replaces missing (NA) values in a specified column +#' of an `sf` dataframe with the value from the nearest spatial neighbor. #' -#' @param df An `sf` dataframe -#' @param vari Variable to remove NAs from +#' @details +#' This function is useful for imputing missing data in spatial contexts. +#' It identifies all planning units with `NA` values in the `vari` column. +#' For each of these, it finds the geographically closest planning unit that +#' *does not* have an `NA` value in `vari`, and then copies that non-missing +#' value. This approach leverages the spatial autocorrelation often present +#' in environmental and species data. #' -#' @return An `sf` object with NAs replaced with the nearest neighbour +#' The `st_nearest_feature()` function from the `sf` package is used for +#' determining the closest neighbor. +#' +#' @param df An `sf` dataframe. This dataframe must contain a geometry column +#' and the `vari` column with potential NA values. +#' @param vari A character string specifying the name of the column in `df` +#' from which NA values are to be removed and replaced. This column must +#' exist in `df`. +#' +#' @return An `sf` object identical to the input `df`, but with NA values +#' in the `vari` column replaced by values from their nearest non-NA neighbors. +#' If no NAs are found, the original `df` is returned unchanged. #' @export #' -#' @importFrom rlang .data -#' @importFrom rlang := +#' @importFrom assertthat assert_that +#' @importFrom dplyr arrange bind_rows mutate pull select +#' @importFrom rlang .data sym := +#' @importFrom sf st_nearest_feature +#' @importFrom tibble rowid_to_column +#' #' @examples -#' df <- dat_species_prob %>% -#' splnr_replace_NAs("Spp2") +#' \dontrun{ +#' # Assuming 'dat_species_prob' is an existing sf object in your package. +#' # For demonstration, let's artificially introduce some NAs in 'Spp2'. +#' df_with_na <- dat_species_prob %>% +#' dplyr::mutate(Spp2 = ifelse(runif(n()) < 0.2, NA, Spp2)) +#' +#' # Replace NAs in 'Spp2' using nearest neighbor imputation. +#' df_no_na <- splnr_replace_NAs(df = df_with_na, vari = "Spp2") +#' print(sum(is.na(df_no_na$Spp2))) # Should be 0 if successful +#' } splnr_replace_NAs <- function(df, vari) { + # Assertions to validate input parameters. assertthat::assert_that( - inherits(df, c("sf", "data.frame")), - is.character(vari), - vari %in% names(df) + inherits(df, "sf"), # Ensure df is an sf object. + msg = "'df' must be an 'sf' object." + ) + assertthat::assert_that( + is.character(vari) && length(vari) == 1, + msg = "'vari' must be a single character string specifying the column name." + ) + assertthat::assert_that( + vari %in% names(df), + msg = paste0("Column '", vari, "' not found in the input dataframe 'df'.") + ) + assertthat::assert_that( + !is.null(sf::st_geometry(df)), + msg = "'df' must have a geometry column." ) - if (sum(is.na(dplyr::pull(df, !!rlang::sym(vari)))) > 0) { # Check if there are NAs + # Check if there are any NA values in the specified variable. + if (sum(is.na(dplyr::pull(df, !!rlang::sym(vari)))) > 0) { + # Add a unique row ID and a logical column 'isna' to identify NA rows. + # This 'cellID' is crucial for reordering the dataframe correctly at the end. gp <- df %>% - tibble::rowid_to_column("cellID") %>% # Add cellID to reorder df later + tibble::rowid_to_column("cellID") %>% dplyr::mutate(isna = is.na(!!rlang::sym(vari))) + # Split the dataframe into two parts: those with NAs and those without. gp <- split(gp, f = as.factor(gp$isna)) + # Find the nearest feature (row) in the 'FALSE' group (no NAs) for each + # feature (row) in the 'TRUE' group (with NAs). + # 'd' will be a vector of indices corresponding to the nearest non-NA features. d <- sf::st_nearest_feature(gp$`TRUE`, gp$`FALSE`) + # Replace the NA values in the 'TRUE' group with the corresponding values + # from their nearest non-NA neighbors found in the 'FALSE' group. gp$`TRUE` <- gp$`TRUE` %>% dplyr::mutate(!!rlang::sym(vari) := dplyr::pull(gp$`FALSE`, !!rlang::sym(vari))[d]) + # Combine the 'FALSE' group (original non-NAs) and the modified 'TRUE' group (NAs replaced). + # Then, remove the temporary 'isna' and 'cellID' columns and reorder by original 'cellID'. df <- rbind(gp$`FALSE`, gp$`TRUE`) %>% dplyr::select(-"isna") %>% dplyr::arrange(.data$cellID) %>% - dplyr::select(-"cellID") # Remove added column + dplyr::select(-"cellID") # Remove the temporary cellID column. } return(df) } - -#' Substitute numbers for all_names in regionalisations +#' @title Substitute Numbers for Names in Regionalizations +#' +#' @description +#' `splnr_match_names()` replaces numeric or integer values in a spatial +#' (sf) dataframe's column with corresponding character names, typically used +#' for regionalization data. +#' +#' @details +#' This function is designed for scenarios where spatial data contains numeric +#' identifiers for regions, and you have a mapping (a named character vector) +#' to convert these IDs into more descriptive names. It assumes that the `sf` +#' dataframe (`dat`) has only one non-geometry column that needs recoding. #' -#' Many regionalisations have numeric values in the shape files that correspond -#' to a vector of names. Here we provide a function to quickly replace the -#' numbers with names. +#' The function directly applies the mapping from the `nam` vector to the +#' specified column. The names of the `nam` vector should correspond to the +#' numeric/integer values in the `dat` column, and the values of `nam` will +#' be the new character names. #' -#' @param dat `sf` data frame with one column of numeric/integer corresponding to `nam` -#' @param nam Named character vector of names corresponding to column of dat to recode +#' @param dat An `sf` data frame with a single non-geometry column containing +#' numeric or integer values that correspond to the names in `nam`. +#' @param nam A named character vector. The *names* of this vector should be +#' the numeric/integer values found in `dat`'s column, and the *values* of +#' this vector should be the desired character names for substitution. #' -#' @return An `sf` dataframe with numeric regionalisations substituted for category names +#' @return An `sf` dataframe where the numeric/integer values in the relevant +#' column have been substituted with the corresponding character names from `nam`. #' @export #' -#' @importFrom rlang := +#' @importFrom assertthat assert_that +#' @importFrom dplyr mutate +#' @importFrom rlang := sym +#' @importFrom stringr str_subset +#' @importFrom sf st_drop_geometry +#' #' @examples -#' dat <- dat_region -#' nam <- c("Region1" = "SE Aust", "Region2" = "Tas", "Region3" = "NE Aust") -#' df <- splnr_match_names(dat, nam) +#' # Define the named character vector for mapping. +#' region_names <- c("Region1" = "SE Aust", "Region2" = "Tas", "Region3" = "NE Aust") +#' +#' # Apply the function to substitute numeric codes with names. +#' df_named_regions <- splnr_match_names(dat = dat_region, nam = region_names) +#' print(df_named_regions) splnr_match_names <- function(dat, nam) { + # Assertions to validate input parameters. assertthat::assert_that( inherits(dat, "sf"), - is.character(nam) && length(nam) > 0 + msg = "'dat' must be an 'sf' object." + ) + assertthat::assert_that( + is.character(nam) && length(nam) > 0, + msg = "'nam' must be a non-empty character vector." + ) + assertthat::assert_that( + !is.null(names(nam)), + msg = "'nam' must be a named character vector (e.g., c('1' = 'Name1'))." + ) + assertthat::assert_that( + length(colnames(dat %>% sf::st_drop_geometry())) == 1, + msg = "'dat' must contain exactly one non-geometry column to be recoded." + ) + # assertthat::assert_that( + # is.numeric(dat %>% sf::st_drop_geometry() %>% dplyr::pull(1)) || is.integer(dat %>% sf::st_drop_geometry() %>% dplyr::pull(1)), + # msg = "The non-geometry column in 'dat' must be numeric or integer." + # ) + assertthat::assert_that( + all(as.character(unique(dat %>% sf::st_drop_geometry() %>% dplyr::pull(1))) %in% names(nam)), + msg = "Not all unique numeric/integer values in 'dat's recoding column are present as names in 'nam'." ) + + # Identify the name of the single non-geometry column that needs recoding. col_name <- stringr::str_subset(colnames(dat), "geometry", negate = TRUE)[[1]] + # Use dplyr::mutate to replace the numeric/integer values in 'col_name' + # with the corresponding names from the 'nam' vector. + # The `!!rlang::sym(col_name)` syntax ensures that 'col_name' is treated as a variable. out <- dat %>% - dplyr::mutate(!!col_name := nam[!!rlang::sym(col_name)]) # Apply categories to data -} + dplyr::mutate(!!col_name := nam[as.character(!!rlang::sym(col_name))]) # Convert col_name content to character to match names(nam) + return(out) +} -#' Scale spatial layers to between 0 and 1 +#' @title Scale Spatial Layers to Between 0 and 1 #' -#' `splnr_scale_01()` allows you to re-scale your data from values that are greater than 1 to values that are between 0 and 1. +#' @description +#' `splnr_scale_01()` re-scales the numeric values in a specified column of an +#' `sf` dataframe to a range between 0 and 1. This is particularly useful for +#' normalizing data like probabilities or costs. #' -#' @param dat `sf` dataframe -#' @param col_name Name of the column to scale +#' @details +#' This function inspects the maximum value (`mx`) in the `col_name` column. +#' It then divides all values in that column by a `divi` factor to bring them +#' into the 0-1 range. The `divi` factor is determined heuristically: +#' - If `mx > 100`, `divi` is `1000`. +#' - If `mx > 10`, `divi` is `100`. +#' - If `mx > 1`, `divi` is `10`. +#' - If `mx <= 1`, no division is performed (`divi` is `1`), as the data is +#' already within the desired range. #' -#' @return `sf` dataframe +#' This approach ensures that the data is scaled appropriately without +#' hardcoding a fixed division factor. +#' +#' @param dat An `sf` dataframe containing the column to be scaled. +#' @param col_name A character string specifying the name of the numeric column +#' in `dat` that needs to be scaled. +#' +#' @return An `sf` dataframe identical to the input `dat`, but with the values +#' in the `col_name` column re-scaled to be between 0 and 1. #' @export #' -#' @importFrom rlang := +#' @importFrom assertthat assert_that +#' @importFrom dplyr mutate pull +#' @importFrom rlang := sym #' #' @examples -#' df <- dat_species_prob %>% -#' dplyr::mutate(Spp1 = Spp1 * 100) %>% -#' splnr_scale_01(col_name = "Spp1") +#' \dontrun{ + +#' # Scale the 'Spp1' column. +#' df_scaled_spp1 <- splnr_scale_01(dat = dat_species_prob, col_name = "Spp1") +#' print(df_scaled_spp1) +#' +#' # Example where max is already <= 1 +#' df_already_scaled <- dat_species_prob %>% dplyr::mutate(Spp1 = Spp1 / 100) +#' df_no_change <- splnr_scale_01(dat = df_already_scaled, col_name = "Spp1") +#' print(df_no_change) # Spp1 values should remain unchanged +#' } splnr_scale_01 <- function(dat, col_name) { + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(dat, "sf"), # Ensure dat is an sf object. + msg = "'dat' must be an 'sf' object." + ) assertthat::assert_that( - inherits(dat, c("sf", "data.frame")), - is.character(col_name), - col_name %in% names(dat) + is.character(col_name) && length(col_name) == 1, + msg = "'col_name' must be a single character string." + ) + assertthat::assert_that( + col_name %in% names(dat), + msg = paste0("Column '", col_name, "' not found in the input dataframe 'dat'.") + ) + assertthat::assert_that( + is.numeric(dplyr::pull(dat, !!rlang::sym(col_name))), + msg = paste0("Column '", col_name, "' must be numeric to be scaled.") ) - mx <- max(dplyr::pull(dat, !!rlang::sym(col_name)), na.rm = TRUE) # Get max probability + # Get the maximum value in the specified column, ignoring NA values. + mx <- max(dplyr::pull(dat, !!rlang::sym(col_name)), na.rm = TRUE) + # Determine the division factor based on the maximum value. + # This logic tries to scale the data into the 0-1 range. + divi <- 1 # Default: no division if max is already 1 or less. if (mx > 100) { divi <- 1000 } else if (mx > 10) { divi <- 100 } else if (mx > 1) { divi <- 10 - } else if (mx < 1) { - divi <- 1 # Do nothing } + # Apply the scaling to the specified column. dat <- dat %>% dplyr::mutate(!!col_name := !!rlang::sym(col_name) / divi) -} - + return(dat) +} -#' Returns the feature names +#' @title Extract Feature Names from Spatial Data +#' +#' @description +#' `splnr_featureNames()` extracts the names of conservation features +#' from an `sf` dataframe, excluding geometry and any specified columns. +#' +#' @details +#' This function is a utility for preparing data for `prioritizr` or other +#' conservation planning packages that require a vector of feature names. +#' It typically removes the geometry column and any columns related to cost +#' (prefixed with "Cost_") by default, allowing you to specify additional +#' columns to exclude. #' -#' `splnr_featureNames()` allows you to extract the names of features you want to pass to a `prioritizr` prioritization. -#' It requires an `sf` object input and returns the column names of the object excluding any columns you specify in the `exclude` argument. +#' The output is a simple character vector of column names, which can be +#' directly used as feature identifiers in conservation problems. #' -#' @param dat sf dataframe of features -#' @param exclude Character vector of any columns to exclude +#' @param dat An `sf` dataframe representing conservation features. Each +#' non-geometry column is assumed to be a feature. +#' @param exclude A character vector of column names (or prefixes) to exclude +#' from the output. By default, it excludes columns starting with "Cost_". +#' If you provide a value, it will be *appended* to the default exclusion. +#' Set to `NULL` or `character(0)` if you want no exclusions beyond the default. #' -#' @return A character vector of names +#' @return A character vector containing the names of the conservation features. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr select +#' @importFrom sf st_drop_geometry +#' @importFrom tidyselect starts_with +#' #' @examples -#' df <- dat_species_prob %>% -#' splnr_featureNames() +#' \dontrun{ +#' # Assuming 'dat_species_prob' is an existing sf object in your package. +#' # It likely has columns like 'Spp1', 'Spp2', 'Cost_SomeMeasure', etc. +#' +#' # Example 1: Get all feature names, excluding default 'Cost_' columns. +#' feature_names_default <- splnr_featureNames(dat = dat_species_prob) +#' print(feature_names_default) +#' +#' # Example 2: Get feature names, excluding 'Cost_' columns and 'Spp5'. +#' feature_names_custom_exclude <- splnr_featureNames( +#' dat = dat_species_prob, +#' exclude = "Spp5" +#' ) +#' print(feature_names_custom_exclude) +#' +#' # Example 3: If you only want to exclude a specific column and not 'Cost_' +#' # (you'd need to manually specify exclude = "geometry" and then your column) +#' # This case is more complex and usually handled by direct dplyr::select. +#' # This function's primary use is to remove cost columns and potentially others. +#' } splnr_featureNames <- function(dat, exclude = NA) { + # Assertions to validate input parameters. assertthat::assert_that( inherits(dat, "sf"), - is.character(exclude) || is.na(exclude) + msg = "'dat' must be an 'sf' object." + ) + assertthat::assert_that( + is.character(exclude) || is.na(exclude), + msg = "'exclude' must be a character vector or NA." + ) + assertthat::assert_that( + !is.null(sf::st_geometry(dat)), + msg = "'dat' must have a geometry column." ) - if (is.na(exclude)) { - exclude <- c("Cost_") + # Define columns to exclude. Always start with "Cost_" as a default. + if (all(is.na(exclude))) { # Check if `exclude` is literally `NA` (the default) + exclude_cols <- c("Cost_") } else { - exclude <- c("Cost_", exclude) + # If `exclude` is provided and not NA, append it to "Cost_". + # Ensure it's a character vector and handle potential NULL/empty cases. + exclude_cols <- c("Cost_", exclude[is.na(exclude) == FALSE]) } - dat <- dat %>% + # Drop geometry, then select columns that do NOT start with any of the + # prefixes in `exclude_cols`, and finally get the column names. + feature_names <- dat %>% sf::st_drop_geometry() %>% - dplyr::select(-tidyselect::starts_with(exclude)) %>% + dplyr::select(-tidyselect::starts_with(exclude_cols)) %>% colnames() - return(dat) + return(feature_names) } - -#' Ensure all features are in the same order. +#' @title Arrange Features by Spatial Coordinates +#' +#' @description +#' `splnr_arrangeFeatures()` sorts the rows of an `sf` object based on the +#' longitude (X) and then latitude (Y) of its centroids. This ensures a +#' consistent ordering of planning units, which can be important for +#' reproducibility in some spatial analyses or data processing steps. #' -#' `splnr_arrangeFeatures()` sorts your data based on longitude and latitude values. +#' @details +#' This function computes the centroid for each polygon (or point/multipoint) +#' in the input `sf` object. It then extracts the X and Y coordinates of these +#' centroids and uses them to sort the entire `sf` object. The primary sort key +#' is the longitude (X-coordinate), and the secondary sort key is the latitude +#' (Y-coordinate). #' -#' @param df An sf object to sort by Lon and Lat +#' Sorting can be beneficial for tasks like debugging, comparing data from +#' different runs, or ensuring deterministic behavior in algorithms that +#' process spatial units sequentially. #' -#' @return A sorted sf object +#' @param df An `sf` object whose rows are to be sorted. +#' +#' @return A sorted `sf` object, with rows ordered primarily by longitude (X) +#' and secondarily by latitude (Y) of their centroids. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom sf st_centroid st_coordinates +#' #' @examples -#' df <- dat_species_prob %>% -#' splnr_arrangeFeatures() +#' \dontrun{ + +#' print("Original order:") +#' print(dat_species_prob) +#' +#' # Sort the features. +#' df_arranged <- splnr_arrangeFeatures(df = dat_species_prob) +#' print("Sorted order:") +#' print(df_arranged) +#' } splnr_arrangeFeatures <- function(df) { - assertthat::assert_that(inherits(df, "sf"), - msg = "Input must be an sf object.") - # Sort rows to ensure all features are in the same order. - suppressWarnings( - xy <- sf::st_coordinates(sf::st_centroid(df)) + # Assertions to validate input parameters. + assertthat::assert_that( + inherits(df, "sf"), + msg = "'df' must be an 'sf' object." + ) + assertthat::assert_that( + !is.null(sf::st_geometry(df)), + msg = "'df' must have a geometry column." + ) + assertthat::assert_that( + nrow(df) > 0, + msg = "'df' must not be empty." ) - df <- df[order(xy[, "X"], xy[, "Y"]), ] -} + # Calculate the centroids of the geometries. + # suppressWarnings is used here because st_centroid can sometimes issue warnings + # for complex geometries (e.g., empty geometries or geometries spanning the antimeridian) + # which might not be relevant for simple sorting. + suppressWarnings({ + centroids <- sf::st_centroid(df) + # Extract the X and Y coordinates from the centroids. + xy <- sf::st_coordinates(centroids) + }) + # Order the input dataframe based on the X (longitude) and then Y (latitude) + # coordinates of its centroids. This provides a deterministic sort order. + df_sorted <- df[order(xy[, "X"], xy[, "Y"]), ] + return(df_sorted) +} -#' Prepare data to plot Cohen's Kappa correlation matrix -#' -#' Conservation planning often requires the comparison of the outputs of the solutions of different conservation problems. -#' One way to compare solutions is by correlating the solutions using Cohen's Kappa. -#' `splnr_get_kappaCorrData()` takes a list of `prioritizr` solutions to perform the Cohen's Kappa correlation between the solution. -#' The resulting correlation matrix is symmetrical along the main diagonal and contains Cohen's Kappa of pairwise correlation between the solutions. -#' The main diagonal should always be 1. The correlation matrix obtained from this function can be passed onto [splnr_plot_corrMat()]. -#' -#' @param sol List of `prioritizr` solutions (`sf` objects) with solutions having a column name `solution_1` -#' @param name_sol Name tags to the different solutions -#' -#' @return `matrixOut` matrix +#' @title Prepare Data to Plot Cohen's Kappa Correlation Matrix +#' +#' @description +#' `splnr_get_kappaCorrData()` calculates Cohen's Kappa correlation coefficients +#' between a list of `prioritizr` conservation solutions. The output is a +#' symmetrical matrix suitable for visualizing pairwise agreement using a heatmap. +#' +#' @details +#' This function is essential for assessing the similarity or divergence among +#' different conservation plans. It takes a list of `prioritizr` solution objects, +#' each expected to contain a binary column named `solution_1` (indicating +#' selected or unselected planning units). +#' +#' For every unique pair of solutions in the input list, it computes Cohen's Kappa +#' using the `irr::kappa2()` function. Cohen's Kappa measures the agreement +#' between two raters (in this case, two conservation solutions) for categorical +#' items, correcting for chance agreement. A Kappa value of 1 indicates perfect +#' agreement, 0 indicates agreement equivalent to chance, and negative values +#' indicate agreement worse than chance. +#' +#' The resulting matrix is symmetrical, with diagonal elements always equal to 1 +#' (a solution perfectly agrees with itself). This matrix can then be passed to +#' visualization functions like `splnr_plot_corrMat()` to create a correlation heatmap. +#' +#' @param sol A `list` of `prioritizr` solution objects. Each element in the list +#' must be an `sf` object containing a binary column named `solution_1`. +#' @param name_sol A character vector providing descriptive names for each +#' solution in the `sol` list. The length of this vector must match the +#' length of `sol`. These names will be used as row and column names in the +#' output correlation matrix. +#' +#' @return A numeric `matrix` (`matrixOut`) representing the Cohen's Kappa +#' correlation matrix between all pairs of solutions. Rows and columns are +#' named according to `name_sol`. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr bind_cols select #' @importFrom rlang .data +#' @importFrom stats setNames +#' @importFrom tibble as_tibble +#' @importFrom tidyr pivot_wider #' #' @examples -#' # 30 % target for problem/solution 1 -#' dat_problem <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +#' \dontrun{ +#' # Assuming 'dat_species_bin' is an existing sf object in your package. +#' +#' # Create a dummy prioritizr problem and solve it for solution 1 (30% target). +#' dat_problem1 <- prioritizr::problem( +#' dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), #' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" #' ) %>% @@ -245,10 +575,10 @@ splnr_arrangeFeatures <- function(df) { #' prioritizr::add_binary_decisions() %>% #' prioritizr::add_default_solver(verbose = FALSE) #' -#' dat_soln <- dat_problem %>% +#' dat_soln1 <- dat_problem1 %>% #' prioritizr::solve.ConservationProblem() #' -#' # 50 % target for problem/solution 2 +#' # Create another dummy prioritizr problem and solve it for solution 2 (50% target). #' dat_problem2 <- prioritizr::problem( #' dat_species_bin %>% #' dplyr::mutate(Cost = runif(n = dim(.)[[1]])), @@ -263,76 +593,168 @@ splnr_arrangeFeatures <- function(df) { #' dat_soln2 <- dat_problem2 %>% #' prioritizr::solve.ConservationProblem() #' -#' corrMat <- splnr_get_kappaCorrData(list(dat_soln, dat_soln2), name_sol = c("soln1", "soln2")) +#' # Calculate the Cohen's Kappa correlation matrix between the two solutions. +#' corrMat <- splnr_get_kappaCorrData( +#' sol = list(dat_soln1, dat_soln2), +#' name_sol = c("Solution_A_30pct", "Solution_B_50pct") +#' ) +#' print(corrMat) +#' +#' # This output can then be directly passed to splnr_plot_corrMat(). +#' # splnr_plot_corrMat(corrMat, AxisLabels = c("Sol A (30%)", "Sol B (50%)")) +#' } splnr_get_kappaCorrData <- function(sol, name_sol) { + # Assertions to validate input parameters. assertthat::assert_that( is.list(sol), + msg = "'sol' must be a list of prioritizr solution objects." + ) + assertthat::assert_that( length(sol) > 1, - is.character(name_sol), - length(name_sol) == length(sol) + msg = "'sol' list must contain at least two solutions for correlation." ) + assertthat::assert_that( + is.character(name_sol) && length(name_sol) > 0, + msg = "'name_sol' must be a non-empty character vector." + ) + assertthat::assert_that( + length(name_sol) == length(sol), + msg = "The length of 'name_sol' must match the number of solutions in 'sol'." + ) + # Check each solution in the list for 'solution_1' column and sf class + for (i in seq_along(sol)) { + assertthat::assert_that( + inherits(sol[[i]], "sf"), + msg = paste0("Element ", i, " in 'sol' is not an 'sf' object.") + ) + assertthat::assert_that( + "solution_1" %in% names(sol[[i]]), + msg = paste0("Solution ", i, " in 'sol' is missing the 'solution_1' column.") + ) + } + # Check if 'irr' package is installed. If not, stop with an informative error. if (requireNamespace("irr", quietly = TRUE) == FALSE){ - stop("To run splnr_get_kappaCorrData you will need to install the package irr.") + stop("To run splnr_get_kappaCorrData you will need to install the 'irr' package: install.packages('irr').") } + # Prepare a list of solutions, selecting only the 'solution_1' column and renaming it + # with the provided 'name_sol'. Each element will be a tibble with one column. s_list <- lapply(seq_along(sol), function(x) { sol[[x]] %>% - tibble::as_tibble(.name_repair = "unique") %>% - dplyr::select("solution_1") %>% - stats::setNames(name_sol[[x]]) + tibble::as_tibble(.name_repair = "unique") %>% # Convert to tibble, handling duplicate names. + dplyr::select("solution_1") %>% # Select the binary solution column. + stats::setNames(name_sol[[x]]) # Rename the column to the provided solution name. }) + # Initialize a list to store pairwise kappa results. + # 'y' is a counter for storing results in s_matrix. y <- 1 s_matrix <- list() + # Loop through all unique pairs of solutions (including self-correlation). for (i in 1:length(s_list)) { for (j in 1:length(s_list)) { - kappa_temp <- irr::kappa2(dplyr::bind_cols(s_list[[i]], s_list[[j]])) - kappa_corrvalue <- kappa_temp$value - kappa_pvalue <- kappa_temp$p.value + # Combine the two solutions (as single-column tibbles) side-by-side. + combined_solutions <- dplyr::bind_cols(s_list[[i]], s_list[[j]]) + # Calculate Cohen's Kappa between the two solutions. + kappa_temp <- irr::kappa2(combined_solutions) + kappa_corrvalue <- kappa_temp$value # Extract the Kappa value. + kappa_pvalue <- kappa_temp$p.value # Extract the p-value (though not used in final output matrix). + + # Store the pair's names, kappa value, and p-value. s_matrix[[y]] <- cbind(colnames(s_list[[i]]), colnames(s_list[[j]]), kappa_corrvalue, kappa_pvalue) - y <- y + 1 + y <- y + 1 # Increment counter. } } + # Combine all pairwise results into a single tibble. s_matrix_all <- do.call(rbind, s_matrix) %>% tibble::as_tibble(.name_repair = "unique") + # Rename the first two columns to be more descriptive. colnames(s_matrix_all)[1:2] <- c("plan1", "plan2") + # Transform the long-format results into a wide-format correlation matrix. matrix_final <- s_matrix_all %>% tibble::as_tibble(.name_repair = "unique") %>% - dplyr::select(-kappa_pvalue) %>% - tidyr::pivot_wider(names_from = "plan2", values_from = kappa_corrvalue) %>% - as.matrix() + dplyr::select(-.data$kappa_pvalue) %>% # Remove p-value column as it's not needed for the correlation matrix plot. + tidyr::pivot_wider(names_from = "plan2", values_from = "kappa_corrvalue") %>% # Pivot to make 'plan2' names as new columns. + as.matrix() # Convert to matrix format. - matrix_x <- s_matrix_all %>% - tibble::as_tibble(.name_repair = "unique") + # Note: matrix_x was part of original code but not used for the return value. + # matrix_x <- s_matrix_all %>% + # tibble::as_tibble(.name_repair = "unique") - # creating corrplot + # Set row names of the final matrix for clarity. rownames(matrix_final) <- matrix_final[, 1] - n <- length(s_list) + 1 # 4 is the number of inputted scenarios - matrixOut <- matrix_final[, 2:n] - class(matrixOut) <- "numeric" + # Determine the number of columns to select (number of solutions + 1 for the first column). + # The original code's 'n <- length(s_list) + 1' implies the first column is the row names, + # so it selects from the second column onwards up to 'n'. + n_cols_to_select <- length(s_list) + 1 + matrixOut <- matrix_final[, 2:n_cols_to_select] # Select only the numeric correlation values. + class(matrixOut) <- "numeric" # Ensure the matrix is of numeric class. return(matrixOut) } -#' Prepare data to plot Selection Frequency of planning units -#' -#' When multiple spatial plans are generated, we are often interested in how many times a planning unit is selected across an array of solutions. This array can either be a `list` of the solutions of different conservation problems or generated through a [portfolio approach](https://prioritizr.net/reference/portfolios.html) with `prioritizr`. -#' `splnr_get_selFreq()` allows you to calculate the selection frequency of each planning unit of either a `list` or a `portfolio` of solutions. The resulting `sf` object can be passed for visualization to the `spatialplanr` function [splnr_plot_selectionFreq()]. -#' -#' @param solnMany List or portfolio of `prioritizr` solutions -#' @param type Either "portfolio" (`sf` object) with a portfolio produced using `prioritizr` or "list" with a list of solutions -#' -#' @return `selFreq` `sf` object containing a column with the selection frequency (sum over all solutions). +#' @title Prepare Data to Plot Selection Frequency of Planning Units +#' +#' @description +#' `splnr_get_selFreq()` calculates how many times each planning unit is +#' selected across an array of `prioritizr` solutions. This "selection +#' frequency" can be derived from either a list of individual solutions or +#' a `prioritizr` portfolio object. +#' +#' @details +#' Understanding selection frequency is crucial for identifying robust +#' conservation areas—those that are consistently chosen across multiple +#' planning scenarios or alternative optimal solutions. +#' +#' The function supports two types of input: +#' \itemize{ +#' \item `"portfolio"`: If `solnMany` is a single `sf` object representing a +#' portfolio of solutions (e.g., generated by `prioritizr::add_cuts_portfolio()`). +#' In this case, the function assumes columns starting with "solution_" +#' represent individual solutions within the portfolio. +#' \item `"list"`: If `solnMany` is a `list` where each element is an `sf` +#' object representing a single `prioritizr` solution (each with a +#' "solution_1" column). +#' } +#' For both types, the function sums the binary `solution` values (0 or 1) +#' across all solutions for each planning unit. The result is converted to a +#' factor to represent discrete frequency levels. +#' +#' The output `sf` object can then be passed to `splnr_plot_selectionFreq()` +#' for visualization as a heatmap. +#' +#' @param solnMany A `list` of `prioritizr` solutions (if `type = "list"`) +#' or a single `sf` object representing a `prioritizr` portfolio of solutions +#' (if `type = "portfolio"`). Each individual solution must contain a +#' column named `solution_1`. +#' @param type A character string indicating the input type: `"portfolio"` +#' (for a single `sf` object with multiple solution columns) or `"list"` +#' (for a list of single-solution `sf` objects). Defaults to `"portfolio"`. +#' +#' @return An `sf` object (`selFreq`) containing a column named `selFreq`. +#' This column is a factor representing the selection frequency (sum of +#' selected occurrences across all solutions) for each planning unit. #' @export #' +#' @importFrom assertthat assert_that +#' @importFrom dplyr mutate select starts_with #' @importFrom rlang .data +#' @importFrom sf st_as_sf st_drop_geometry +#' @importFrom stringr str_c str_pad +#' @importFrom stats setNames +#' @importFrom tibble as_tibble #' #' @examples -#' dat_problem <- prioritizr::problem(dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +#' \dontrun{ +#' # Assuming 'dat_species_bin' is an existing sf object in your package. +#' +#' # Create a base prioritizr problem. +#' dat_problem <- prioritizr::problem( +#' dat_species_bin %>% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), #' features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), #' cost_column = "Cost" #' ) %>% @@ -341,59 +763,117 @@ splnr_get_kappaCorrData <- function(sol, name_sol) { #' prioritizr::add_binary_decisions() %>% #' prioritizr::add_default_solver(verbose = FALSE) #' -#' dat_soln <- dat_problem %>% -#' prioritizr::solve.ConservationProblem() -#' -#' # create conservation problem that contains a portfolio of solutions +#' # --- Example 1: Using a portfolio of solutions --- +#' # Create a conservation problem that contains a portfolio of solutions (e.g., 5 solutions). #' dat_soln_portfolio <- dat_problem %>% #' prioritizr::add_cuts_portfolio(number_solutions = 5) %>% #' prioritizr::solve.ConservationProblem() #' -#' selFreq <- splnr_get_selFreq(solnMany = dat_soln_portfolio, type = "portfolio") -#' (splnr_plot_selectionFreq(selFreq)) -#' +#' # Calculate selection frequency from the portfolio. +#' selFreq_portfolio <- splnr_get_selFreq(solnMany = dat_soln_portfolio, type = "portfolio") +#' print(head(selFreq_portfolio)) +#' # You can then plot this: splnr_plot_selectionFreq(selFreq_portfolio) +#' +#' # --- Example 2: Using a list of individual solutions --- +#' # Solve the problem multiple times to get different solutions (e.g., by randomizing costs) +#' dat_soln_list <- list( +#' dat_problem %>% prioritizr::solve.ConservationProblem(), +#' dat_problem %>% +#' dplyr::mutate(Cost = runif(n = dim(.)[[1]])) %>% # Vary cost for a different solution +#' prioritizr::solve.ConservationProblem(), +#' dat_problem %>% +#' dplyr::mutate(Cost = runif(n = dim(.)[[1]])) %>% # Another different solution +#' prioritizr::solve.ConservationProblem() +#' ) +#' +#' # Calculate selection frequency from the list of solutions. +#' selFreq_list <- splnr_get_selFreq(solnMany = dat_soln_list, type = "list") +#' print(head(selFreq_list)) +#' # You can then plot this: splnr_plot_selectionFreq(selFreq_list) +#' } splnr_get_selFreq <- function(solnMany, type = "portfolio") { + # Assertions to validate input parameters. + assertthat::assert_that( + is.character(type) && length(type) == 1, + msg = "'type' must be a single character string: 'portfolio' or 'list'." + ) assertthat::assert_that( type %in% c("portfolio", "list"), - (type == "portfolio" && inherits(solnMany, "sf")) || (type == "list" && is.list(solnMany)), - (!is.null(solnMany) && length(solnMany) > 0) + msg = "'type' must be either 'portfolio' or 'list'." ) - if (type == "portfolio") { # check if provided input is a protfolio - - if (class(solnMany)[[1]] != "sf") { - print("You did not provide a portfolio of solutions. Please check your input.") - } else { - selFreq <- solnMany %>% - dplyr::mutate(selFreq = as.factor(rowSums(dplyr::select(tibble::as_tibble(solnMany), dplyr::starts_with("solution_"))))) %>% - sf::st_as_sf(geometry = solnMany$geometry) %>% - dplyr::select("selFreq") - return(selFreq) - } - } else if (type == "list") { # if not portfolio check if input is list of solutions - if (class(solnMany)[[1]] != "list") { - print("You did not provide a list of solutions. Please check your input.") - } else { - name_sol <- stringr::str_c("soln", stringr::str_pad(1:length(solnMany), width = 1, pad = 0)) - - s_list <- lapply(seq_along(solnMany), function(x) { - solnMany[[x]] %>% - tibble::as_tibble() %>% - dplyr::select("solution_1") %>% - stats::setNames(name_sol[[x]]) - }) - - soln <- data.frame(matrix(unlist(s_list), ncol = length(s_list))) - colnames(soln) <- name_sol - - selFreq <- soln %>% - dplyr::mutate(selFreq = as.factor(rowSums(dplyr::select(soln, dplyr::starts_with("soln"))))) %>% - sf::st_as_sf(geometry = solnMany[[1]]$geometry) %>% - dplyr::select("selFreq") - return(selFreq) + if (type == "portfolio") { + # If type is "portfolio", expected input is a single sf object (the portfolio). + assertthat::assert_that( + inherits(solnMany, "sf"), + msg = "For 'type = \"portfolio\"', 'solnMany' must be an 'sf' object." + ) + assertthat::assert_that( + any(grepl("solution_", names(solnMany))), + msg = "For 'type = \"portfolio\"', 'solnMany' must contain columns starting with 'solution_'." + ) + + # Calculate selection frequency for a portfolio (sf object with multiple solution columns). + selFreq <- solnMany %>% + # Convert to tibble for dplyr operations on columns, ensuring unique names. + dplyr::mutate(selFreq = as.factor(rowSums(dplyr::select(tibble::as_tibble(.), + dplyr::starts_with("solution_")), na.rm = TRUE))) %>% + # Convert back to sf, explicitly retaining the original geometry. + sf::st_as_sf(geometry = sf::st_geometry(solnMany)) %>% + # Select only the calculated selection frequency column. + dplyr::select("selFreq") + return(selFreq) + + } else if (type == "list") { + # If type is "list", expected input is a list of sf objects (individual solutions). + assertthat::assert_that( + is.list(solnMany), + msg = "For 'type = \"list\"', 'solnMany' must be a list of sf objects." + ) + assertthat::assert_that( + length(solnMany) > 0, + msg = "For 'type = \"list\"', 'solnMany' must not be an empty list." + ) + # Check each element in the list. + for (i in seq_along(solnMany)) { + assertthat::assert_that( + inherits(solnMany[[i]], "sf"), + msg = paste0("Element ", i, " in 'solnMany' is not an 'sf' object.") + ) + assertthat::assert_that( + "solution_1" %in% names(solnMany[[i]]), + msg = paste0("Solution ", i, " in 'solnMany' is missing the 'solution_1' column.") + ) } + + # Generate default names for solutions in the list for column naming. + name_sol <- stringr::str_c("soln", stringr::str_pad(1:length(solnMany), width = 1, pad = "0")) + + # Process each solution in the list: select 'solution_1' and rename. + s_list <- lapply(seq_along(solnMany), function(x) { + solnMany[[x]] %>% + tibble::as_tibble() %>% # Convert to tibble. + dplyr::select("solution_1") %>% # Select the solution column. + stats::setNames(name_sol[[x]]) # Rename it to the generated name. + }) + + # Combine all single-column solution tibbles into one wide data frame. + soln <- data.frame(matrix(unlist(s_list), ncol = length(s_list))) + colnames(soln) <- name_sol + + # Calculate selection frequency by summing binary solution columns. + selFreq <- soln %>% + # Sum across all columns starting with "soln" (which are our individual solutions). + dplyr::mutate(selFreq = as.factor(rowSums(dplyr::select(., dplyr::starts_with("soln")), na.rm = TRUE))) %>% + # Convert back to sf, using the geometry from the first solution in the list. + sf::st_as_sf(geometry = sf::st_geometry(solnMany[[1]])) %>% + # Select only the calculated selection frequency column. + dplyr::select("selFreq") + return(selFreq) + } else { - print("This function requires either a prioritizr portfolio or a list of solutions. Please check your input.") + # This block should technically not be reached due to initial assertthat. + stop("This function requires either a prioritizr portfolio or a list of solutions. Please check your input.") } } diff --git a/README.Rmd b/README.Rmd index c447afa1..910adacd 100644 --- a/README.Rmd +++ b/README.Rmd @@ -13,8 +13,7 @@ knitr::opts_chunk$set( ) ``` -# spatialplanr spatialplanr website - +# spatialplanr spatialplanr website [![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental) [![Ubuntu](https://github.com/SpatialPlanning/spatialplanr/actions/workflows/Ubuntu.yaml/badge.svg)](https://github.com/SpatialPlanning/spatialplanr/actions/workflows/Ubuntu.yaml) @@ -24,8 +23,9 @@ knitr::opts_chunk$set( [![Issues](https://img.shields.io/github/issues/SpatialPlanning/spatialplanr)](https://github.com/SpatialPlanning/spatialplanr/issues) -## Overview -This package is designed to assist students and staff in the [Mathematical Marine Ecology Lab](https://mathmarecol.github.io) at the University of Queensland. It may be useful for others as well. This code has been written to simplify the process for running a _prioritizr_ analysis on a given region use the workflows and data of the MME Lab. It is still a work in progress so feel free to submit pull requests with new features and code improvements. + +# Introduction to spatialplanr +Welcome to _spatialplanr_, an R package designed to streamline and enhance spatial conservation prioritization efforts by explicitly integrating climate change considerations. Building upon the powerful _prioritizr_ package, _spatialplanr_ provides a suite of tools for conservation planners to develop more robust and climate-resilient protected area networks. ## Installation @@ -35,3 +35,336 @@ Be aware that this package is in the very early stages of development. Functions # install.packages("devtools") devtools::install_github("https://github.com/SpatialPlanning/spatialplanr") ``` + +# Purpose and Goals + +The escalating impacts of climate change necessitate a paradigm shift in how we approach conservation. Traditional conservation planning often focuses on static biodiversity patterns, which may not adequately account for the dynamic nature of species distributions and ecosystem processes under a changing climate. _spatialplanr_ aims to address this gap by: + +**Facilitating Climate-Smart Planning**: Providing functions that incorporate climate data directly into the planning process, allowing for the identification of areas critical for both biodiversity and resilience to future climate conditions. +Offering Diverse Methodological Approaches: Implementing multiple established climate-smart conservation planning frameworks (e.g., Climate Priority Areas, Climate Features, Climate Percentiles) to offer flexibility based on specific planning goals and data availability. + +**Streamlining Workflow**: Offering end-to-end functionality, from data preprocessing and integration to advanced visualization of results, simplifying complex analytical tasks for users. + +**Enhancing Decision-Making**: Producing outputs that directly feed into spatial prioritization software like prioritizr, enabling the generation of optimal conservation solutions that balance biodiversity representation with climate resilience. +By using spatialplanr, practitioners can move beyond reactive conservation and proactively design protected area systems better equipped to safeguard biodiversity in a rapidly changing world. + +# Core Climate-Smart Planning Approaches + +_spatialplanr_ implements several key approaches for integrating climate change into spatial prioritization, largely drawing inspiration from frameworks like that presented in Buenafe et al. (2023) "A metric‐based framework for climate‐smart conservation planning" (DOI: 10.1002/eap.2852). + +These approaches are designed to transform biodiversity features and conservation targets based on climate metrics, allowing for a more nuanced understanding of how climate change may impact conservation priorities. The main approaches included in _spatialplanr_ are: + * **Climate Priority Area (CPA) Approach**: Identifies climate-smart areas within the distribution of each conservation feature, creating new components for climate-smart and non-climate-smart areas. + * **Climate Feature Approach**: Treats climate-smart areas as a distinct conservation feature, allowing for explicit conservation targets on climate resilience. + * **Climate Percentile Approach**: Sets conservation targets based on percentile ranges of climate metrics, allowing for targeted protection of areas within specific climate resilience thresholds. + +# Data Acquisition and Preprocessing Utilities +_spatialplanr_ also provides convenience functions for acquiring and preparing data, which can be crucial for climate-smart planning. + +```{r} +# Load spatialplanr +library(spatialplanr) +library(tidyverse) +``` + +1. Get IUCN Red List Data +Function: `splnr_get_IUCNRedList()` + +This function interfaces with the IUCN Red List API to retrieve conservation status information for a list of species. This data can be valuable for assigning species-specific targets (e.g., higher targets for more threatened species) or filtering species based on their conservation status. + +Note: Requires an IUCN Red List API token. + +```{r} +# # Example: Fetch IUCN data for a few marine species +# # Ensure your IUCN Red List API token is set: +# # Sys.setenv(IUCN_REDLIST_KEY = "YOUR_API_KEY") # Replace with your actual key +# +# # Example species list +# my_species <- c("Orcinus orca", "Chelonia mydas", "Thunnus thynnus") +# +# # Create a dataframe matching the expected input format +# species_df <- data.frame( +# scientific_name = my_species +# ) +# +# # Get IUCN data +# iucn_data <- splnr_get_IUCNRedList(df = species_df, species_col = "scientific_name") +# print(iucn_data) + +``` + +2. Get Global Fishing Watch (GFW) Data +Function: `splnr_get_gfw()` + +This function facilitates the retrieval of fishing activity data (e.g., apparent fishing hours) from Global Fishing Watch (GFW). GFW data can be used to inform cost layers (e.g., higher fishing effort areas might have higher opportunity costs for conservation) or as a proxy for human impact in planning units. + +Note: Requires a GFW API token. + +```{r} +# Example: Get yearly fishing hours for Australia EEZ + +gfw_data_aus <- splnr_get_gfw( + region = 'Australia', + start_date = "2021-01-01", + end_date = "2021-12-31", + temp_res = "YEARLY", + spat_res = "LOW", + region_source = "EEZ", + cCRS = "EPSG:4326", + compress = TRUE # Returns polygons aggregated by fishing hours +) +print(head(gfw_data_aus)) +``` + +## Visualization Tools +_spatialplanr_ offers a rich set of plotting functions to visualize input data, climate metrics, and most importantly, the outputs of your spatial prioritization analyses. These functions are built on ggplot2 and sf for high-quality spatial visualizations. + +1. Plot Climate Data +Function: `splnr_plot_climData()` + +Visualizes the spatial distribution of your climate metric, allowing you to quickly inspect patterns in climate velocity, temperature anomaly, or other relevant climate variables. + +```{r} +# Assuming 'dat_clim' from previous examples is available +# Plot the 'metric' column from dat_clim +splnr_plot_climData( + df = dat_clim, + colInterest = "metric", + plotTitle = "Example Climate Metric Distribution", + legendTitle = "Metric Value" +) +``` + +2. Plot Climate Kernel Density +Functions: `splnr_plot_climKernelDensity_Basic()`, `splnr_plot_climKernelDensity_Fancy()`, `splnr_plot_climKernelDensity()` + +These functions help visualize the distribution of climate metric values within selected planning units (e.g., a proposed protected area network) compared to the overall distribution. This helps assess if climate-smart areas are being adequately captured. + +`_Basic()`: Simple kernel density plot. +`_Fancy()`: More customizable kernel density plot, allowing multiple solutions and specific zones. +`_climKernelDensity()`: A wrapper function that selects between basic and fancy plots based on input type. + +```{r} +solution_df <- dat_clim %>% + dplyr::mutate( + solution_1 = sample(c(0, 1), size = dplyr::n(), replace = TRUE, prob = c(0.7, 0.3)), + metric_category = cut(metric, breaks = 3, labels = c("Low", "Medium", "High")) + ) + +# Basic kernel density plot of the metric for selected areas vs. all areas +splnr_plot_climKernelDensity( + soln = solution_df, + type = "Basic", + names = "solution_1" # Column indicating selected PUs (1=selected) +) + +# Fancy kernel density plot, perhaps with zones (if your solution has them) +# For this example, let's pretend 'solution_df' has a 'zone' column +# (this would come from a prioritizr zoned solution) +zoned_solution_df <- solution_df %>% + dplyr::mutate( + zone = sample(c("Zone A", "Zone B"), size = dplyr::n(), replace = TRUE) + ) + +# Example for Fancy (requires a list of solutions or specific structure) +# If you have multiple prioritizr solutions, you would put them in a list. +# For simplicity, we'll create a mock 'soln' list: +soln_list <- list( + Solution1 = zoned_solution_df, + Solution2 = zoned_solution_df %>% mutate(solution_1 = abs(solution_1 - 1)) # Invert selection for demo +) + +# plot_climKernelDensity handles both basic and fancy automatically +splnr_plot_climKernelDensity( + soln = soln_list, # Pass the list of solutions + names = c("metric", "metric"), + type = "Normal" # Explicitly request fancy + # zone_column = "zone" # If your solutions have zones +) +``` + +3. Plot Prioritization Solutions +Function: `splnr_plot_solution()` + +Visualizes the spatial output of a prioritizr problem, showing which planning units were selected for conservation. It supports both single-zone and multi-zone solutions. + +```{r} + +# Plot a single-zone solution +splnr_plot_solution( + soln = solution_df, + colorVals = c("grey", "darkgreen"), + legendLabels = c("Not Selected", "Selected"), + plotTitle = "Prioritization Solution (Single Zone)" +) + +# Plot a zoned solution (assuming 'zone' column exists) +# In a real scenario, this 'zone' column would be part of your prioritizr output. +# splnr_plot_solution( +# soln = zoned_solution_df, +# colorVals = c("red", "blue", "grey"), # Colors for each zone + not selected +# legendLabels = c("Zone A", "Zone B", "Not Selected"), +# plotTitle = "Prioritization Solution (Zoned)", +# zones = TRUE +# ) +``` + + +4. Plot Cost Overlay +Function: `splnr_plot_costOverlay()` + +Overlays cost data on top of a prioritization solution, helping to visualize the spatial distribution of costs relative to selected areas. + +```{r} +# Assuming 'solution_df' and adding a 'cost' column +solution_with_cost <- solution_df %>% + dplyr::mutate(cost = runif(dplyr::n(), 100, 1000)) + +splnr_plot_costOverlay( + soln = solution_with_cost, + costName = "cost", # Name of the cost column + # costName = "Acquisition Cost", + # colorVals = c("grey", "darkgreen"), + # legendLabels = c("Not Selected", "Selected"), + plotTitle = "Prioritization Solution with Cost Overlay" +) + +``` + +5. Plot Comparison +Function: `splnr_plot_comparison()` + +Compares two different prioritization solutions, highlighting areas that are uniquely selected by each solution, or selected by both. + +```{r} +# Assuming two solutions for comparison +soln1_df <- solution_df %>% + dplyr::mutate(solution_1 = sample(c(0, 1), dplyr::n(), replace = TRUE, prob = c(0.6, 0.4))) +soln2_df <- solution_df %>% + dplyr::mutate(solution_1 = sample(c(0, 1), dplyr::n(), replace = TRUE, prob = c(0.5, 0.5))) + +splnr_plot_comparison( + soln1 = soln1_df, + soln2 = soln2_df, +) + +``` + +6. Plot Selection Frequency +Function: `splnr_plot_selectionFreq()` + +Visualizes the frequency with which each planning unit is selected across multiple runs of a prioritization problem (e.g., from a sensitivity analysis or robust solution generation). + +```{r} +# # Create selection frequency data +# selection_freq_df <- solution_df %>% +# dplyr::mutate( +# selection_frequency = runif(dplyr::n(), 0, 1) # Frequency between 0 and 1 +# ) +# +# splnr_plot_selectionFreq( +# selFreq = selection_freq_df, +# plotTitle = "Selection Frequency of Planning Units", +# legendTitle = "Selection Frequency" +# ) +``` + +7. Plot Importance Score +Function: `splnr_plot_importanceScore()` + +Calculates and visualizes an "importance score" for each planning unit, which can represent its contribution to achieving targets or its irreplaceability. Useful for identifying key areas. + +```{r} +# +# splnr_plot_importanceScore( +# soln = solution_df, +# pDat = dat_species_bin, # Original biodiversity features +# method = "basic", # Or "complex" +# decimals = 2, +# plotTitle = "Planning Unit Importance Score" +# ) +``` + +8. Plot Correlation Matrix +Function: `splnr_plot_corrMat()` + +Generates a correlation matrix plot, useful for understanding relationships between different features or variables in your planning data. + +```{r} +# # Create a data matrix for correlation +# +# corr_data <- data.frame( +# Var1 = rnorm(100), +# Var2 = rnorm(100, mean = 0.5, sd = 1), +# Var3 = rnorm(100, mean = -0.2, sd = 0.5) +# ) +# # Add some correlation +# corr_data$Var2 <- corr_data$Var2 + 0.5 * corr_data$Var1 +# corr_data$Var3 <- corr_data$Var3 - 0.3 * corr_data$Var1 +# +# # Calculate correlation matrix +# corr_matrix <- cor(corr_data) +# +# splnr_plot_corrMat( +# matrix = corr_matrix, +# plotTitle = "Correlation Matrix of Variables" +# ) + +``` + +9. Generic Plotting Utility +Function: `splnr_plot()` + +A versatile plotting function that can be used to visualize any continuous or categorical data column within an sf dataframe, with options for color palettes and legend customization. Many other plotting functions in _spatialplanr_ internally use this function. + +```{r} +# Plotting the 'metric' column from 'dat_clim' using the generic plotter +splnr_plot( + df = dat_clim, + colNames = "metric", + plotTitle = "Generic Plot of Climate Metric", + legendTitle = "Metric Value", + paletteName = "viridis" # Use a viridis color palette +) + +``` + +# Example Workflow +The following example illustrates a typical workflow using _spatialplanr_ for climate-smart conservation planning. It assumes you have already prepared your planning units, biodiversity features, and cost layers. + +A typical workflow using _spatialplanr_ for climate-smart conservation planning might look like this: + +## Data Preparation: + +* Load your planning units (PUs). +* Load your biodiversity features (features). +* Load your cost layer (costs). +* Load your climate metric data (climate_data). +* (Optional) Use splnr_get_IUCNRedList() to refine species targets or splnr_get_gfw() to generate a cost layer. + +Choose Climate-Smart Approach: + +* Decide which climate-smart approach best suits your planning goals: + * `splnr_climate_priorityAreaApproach()` for prioritizing refugia for each feature. + * `splnr_climate_featureApproach()` for treating climate resilience as a standalone feature. + * `splnr_climate_percentileApproach()` for targeting specific climate metric ranges. +* Run the chosen function to obtain climate_features and climate_targets. +* Define and Solve Prioritization Problem (using _prioritizr_): + +Create a prioritizr problem using your PUs, climate_features, and climate_targets. +* Add objectives (e.g., `add_min_set_objective()`, `add_max_targets_objective()`). +* Add constraints (e.g., `add_budget_constraint()`, `add_contiguity_constraint()`, `add_locked_in_constraint()` for existing MPAs). +* Add solvers (e.g., `add_gurobi_solver()`, `add_cbc_solver()`). +* Solve the problem to get your solution. + +Visualize and Analyze Results (using _spatialplanr_ plotting functions): +* `splnr_plot_solution()` to visualize the selected planning units. +* `splnr_plot_costOverlay()` to see costs in selected areas. +* `splnr_plot_climKernelDensity()` to assess the climate characteristics of the solution. +* `splnr_plot_comparison()` to compare different scenarios or solutions. +* `splnr_plot_selectionFreq()` for robust solutions. +* `splnr_plot_importanceScore()` to identify key planning units. +* `splnr_plot_corrMat()` to understand feature relationships. + + +# Conclusion +_spatialplanr_ provides a powerful and flexible toolkit for integrating climate change considerations into spatial conservation prioritization. By offering multiple methodological approaches, streamlining data handling, and providing comprehensive visualization capabilities, it aims to empower conservation planners to create more resilient and effective protected area networks for the future. diff --git a/README.md b/README.md index 0076f51c..dab24873 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# spatialplanr spatialplanr website +# spatialplanr \“spatialplanr @@ -15,15 +15,14 @@ coverage](https://codecov.io/gh/SpatialPlanning/spatialplanr/branch/main/graph/b [![Issues](https://img.shields.io/github/issues/SpatialPlanning/spatialplanr)](https://github.com/SpatialPlanning/spatialplanr/issues) -## Overview +# Introduction to spatialplanr -This package is designed to assist students and staff in the -[Mathematical Marine Ecology Lab](https://mathmarecol.github.io) at the -University of Queensland. It may be useful for others as well. This code -has been written to simplify the process for running a *prioritizr* -analysis on a given region use the workflows and data of the MME Lab. It -is still a work in progress so feel free to submit pull requests with -new features and code improvements. +Welcome to *spatialplanr*, an R package designed to streamline and +enhance spatial conservation prioritization efforts by explicitly +integrating climate change considerations. Building upon the powerful +*prioritizr* package, *spatialplanr* provides a suite of tools for +conservation planners to develop more robust and climate-resilient +protected area networks. ## Installation @@ -36,3 +35,453 @@ development version from [GitHub](https://github.com/) with: # install.packages("devtools") devtools::install_github("https://github.com/SpatialPlanning/spatialplanr") ``` + +# Purpose and Goals + +The escalating impacts of climate change necessitate a paradigm shift in +how we approach conservation. Traditional conservation planning often +focuses on static biodiversity patterns, which may not adequately +account for the dynamic nature of species distributions and ecosystem +processes under a changing climate. *spatialplanr* aims to address this +gap by: + +**Facilitating Climate-Smart Planning**: Providing functions that +incorporate climate data directly into the planning process, allowing +for the identification of areas critical for both biodiversity and +resilience to future climate conditions. Offering Diverse Methodological +Approaches: Implementing multiple established climate-smart conservation +planning frameworks (e.g., Climate Priority Areas, Climate Features, +Climate Percentiles) to offer flexibility based on specific planning +goals and data availability. + +**Streamlining Workflow**: Offering end-to-end functionality, from data +preprocessing and integration to advanced visualization of results, +simplifying complex analytical tasks for users. + +**Enhancing Decision-Making**: Producing outputs that directly feed into +spatial prioritization software like prioritizr, enabling the generation +of optimal conservation solutions that balance biodiversity +representation with climate resilience. By using spatialplanr, +practitioners can move beyond reactive conservation and proactively +design protected area systems better equipped to safeguard biodiversity +in a rapidly changing world. + +# Core Climate-Smart Planning Approaches + +*spatialplanr* implements several key approaches for integrating climate +change into spatial prioritization, largely drawing inspiration from +frameworks like that presented in Buenafe et al. (2023) “A metric‐based +framework for climate‐smart conservation planning” (DOI: +10.1002/eap.2852). + +These approaches are designed to transform biodiversity features and +conservation targets based on climate metrics, allowing for a more +nuanced understanding of how climate change may impact conservation +priorities. The main approaches included in *spatialplanr* are: \* +**Climate Priority Area (CPA) Approach**: Identifies climate-smart areas +within the distribution of each conservation feature, creating new +components for climate-smart and non-climate-smart areas. \* **Climate +Feature Approach**: Treats climate-smart areas as a distinct +conservation feature, allowing for explicit conservation targets on +climate resilience. \* **Climate Percentile Approach**: Sets +conservation targets based on percentile ranges of climate metrics, +allowing for targeted protection of areas within specific climate +resilience thresholds. + +# Data Acquisition and Preprocessing Utilities + +*spatialplanr* also provides convenience functions for acquiring and +preparing data, which can be crucial for climate-smart planning. + +``` r +# Load spatialplanr +library(spatialplanr) +library(tidyverse) +#> ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ── +#> ✔ dplyr 1.1.4 ✔ readr 2.1.5 +#> ✔ forcats 1.0.0 ✔ stringr 1.5.1 +#> ✔ ggplot2 3.5.2 ✔ tibble 3.3.0 +#> ✔ lubridate 1.9.4 ✔ tidyr 1.3.1 +#> ✔ purrr 1.0.4 +#> ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ── +#> ✖ dplyr::filter() masks stats::filter() +#> ✖ dplyr::lag() masks stats::lag() +#> ℹ Use the conflicted package () to force all conflicts to become errors +``` + +1. Get IUCN Red List Data Function: `splnr_get_IUCNRedList()` + +This function interfaces with the IUCN Red List API to retrieve +conservation status information for a list of species. This data can be +valuable for assigning species-specific targets (e.g., higher targets +for more threatened species) or filtering species based on their +conservation status. + +Note: Requires an IUCN Red List API token. + +``` r +# # Example: Fetch IUCN data for a few marine species +# # Ensure your IUCN Red List API token is set: +# # Sys.setenv(IUCN_REDLIST_KEY = "YOUR_API_KEY") # Replace with your actual key +# +# # Example species list +# my_species <- c("Orcinus orca", "Chelonia mydas", "Thunnus thynnus") +# +# # Create a dataframe matching the expected input format +# species_df <- data.frame( +# scientific_name = my_species +# ) +# +# # Get IUCN data +# iucn_data <- splnr_get_IUCNRedList(df = species_df, species_col = "scientific_name") +# print(iucn_data) +``` + +2. Get Global Fishing Watch (GFW) Data Function: `splnr_get_gfw()` + +This function facilitates the retrieval of fishing activity data (e.g., +apparent fishing hours) from Global Fishing Watch (GFW). GFW data can be +used to inform cost layers (e.g., higher fishing effort areas might have +higher opportunity costs for conservation) or as a proxy for human +impact in planning units. + +Note: Requires a GFW API token. + +``` r +# Example: Get yearly fishing hours for Australia EEZ + +gfw_data_aus <- splnr_get_gfw( + region = 'Australia', + start_date = "2021-01-01", + end_date = "2021-12-31", + temp_res = "YEARLY", + spat_res = "LOW", + region_source = "EEZ", + cCRS = "EPSG:4326", + compress = TRUE # Returns polygons aggregated by fishing hours +) +print(head(gfw_data_aus)) +#> Simple feature collection with 6 features and 2 fields +#> Geometry type: POLYGON +#> Dimension: XY +#> Bounding box: xmin: 104.05 ymin: -8.85 xmax: 104.75 ymax: -8.65 +#> Geodetic CRS: WGS 84 +#> # A tibble: 6 × 3 +#> geometry ApparentFishingHrs GFWregionID +#> +#> 1 ((104.45 -8.75, 104.45 -8.65, 104.55 -8.65, 10… 1.04 8309 +#> 2 ((104.55 -8.75, 104.55 -8.65, 104.65 -8.65, 10… 6.45 8309 +#> 3 ((104.05 -8.85, 104.05 -8.75, 104.15 -8.75, 10… 2.89 8309 +#> 4 ((104.25 -8.85, 104.25 -8.75, 104.35 -8.75, 10… 7.34 8309 +#> 5 ((104.45 -8.85, 104.45 -8.75, 104.55 -8.75, 10… 2.02 8309 +#> 6 ((104.65 -8.85, 104.65 -8.75, 104.75 -8.75, 10… 6.32 8309 +``` + +## Visualization Tools + +*spatialplanr* offers a rich set of plotting functions to visualize +input data, climate metrics, and most importantly, the outputs of your +spatial prioritization analyses. These functions are built on ggplot2 +and sf for high-quality spatial visualizations. + +1. Plot Climate Data Function: `splnr_plot_climData()` + +Visualizes the spatial distribution of your climate metric, allowing you +to quickly inspect patterns in climate velocity, temperature anomaly, or +other relevant climate variables. + +``` r +# Assuming 'dat_clim' from previous examples is available +# Plot the 'metric' column from dat_clim +splnr_plot_climData( + df = dat_clim, + colInterest = "metric", + plotTitle = "Example Climate Metric Distribution", + legendTitle = "Metric Value" +) +``` + + + +2. Plot Climate Kernel Density Functions: + `splnr_plot_climKernelDensity_Basic()`, + `splnr_plot_climKernelDensity_Fancy()`, + `splnr_plot_climKernelDensity()` + +These functions help visualize the distribution of climate metric values +within selected planning units (e.g., a proposed protected area network) +compared to the overall distribution. This helps assess if climate-smart +areas are being adequately captured. + +`_Basic()`: Simple kernel density plot. `_Fancy()`: More customizable +kernel density plot, allowing multiple solutions and specific zones. +`_climKernelDensity()`: A wrapper function that selects between basic +and fancy plots based on input type. + +``` r +solution_df <- dat_clim %>% + dplyr::mutate( + solution_1 = sample(c(0, 1), size = dplyr::n(), replace = TRUE, prob = c(0.7, 0.3)), + metric_category = cut(metric, breaks = 3, labels = c("Low", "Medium", "High")) + ) + +# Basic kernel density plot of the metric for selected areas vs. all areas +splnr_plot_climKernelDensity( + soln = solution_df, + type = "Basic", + names = "solution_1" # Column indicating selected PUs (1=selected) +) +#> Picking joint bandwidth of 0.0885 +#> Picking joint bandwidth of 0.077 +``` + + + +``` r + +# Fancy kernel density plot, perhaps with zones (if your solution has them) +# For this example, let's pretend 'solution_df' has a 'zone' column +# (this would come from a prioritizr zoned solution) +zoned_solution_df <- solution_df %>% + dplyr::mutate( + zone = sample(c("Zone A", "Zone B"), size = dplyr::n(), replace = TRUE) + ) + +# Example for Fancy (requires a list of solutions or specific structure) +# If you have multiple prioritizr solutions, you would put them in a list. +# For simplicity, we'll create a mock 'soln' list: +soln_list <- list( + Solution1 = zoned_solution_df, + Solution2 = zoned_solution_df %>% mutate(solution_1 = abs(solution_1 - 1)) # Invert selection for demo +) + +# plot_climKernelDensity handles both basic and fancy automatically +splnr_plot_climKernelDensity( + soln = soln_list, # Pass the list of solutions + names = c("metric", "metric"), + type = "Normal" # Explicitly request fancy + # zone_column = "zone" # If your solutions have zones +) +#> Picking joint bandwidth of 0.071 +#> Picking joint bandwidth of 0.071 +``` + + + +3. Plot Prioritization Solutions Function: `splnr_plot_solution()` + +Visualizes the spatial output of a prioritizr problem, showing which +planning units were selected for conservation. It supports both +single-zone and multi-zone solutions. + +``` r + +# Plot a single-zone solution +splnr_plot_solution( + soln = solution_df, + colorVals = c("grey", "darkgreen"), + legendLabels = c("Not Selected", "Selected"), + plotTitle = "Prioritization Solution (Single Zone)" +) +``` + + + +``` r + +# Plot a zoned solution (assuming 'zone' column exists) +# In a real scenario, this 'zone' column would be part of your prioritizr output. +# splnr_plot_solution( +# soln = zoned_solution_df, +# colorVals = c("red", "blue", "grey"), # Colors for each zone + not selected +# legendLabels = c("Zone A", "Zone B", "Not Selected"), +# plotTitle = "Prioritization Solution (Zoned)", +# zones = TRUE +# ) +``` + +4. Plot Cost Overlay Function: `splnr_plot_costOverlay()` + +Overlays cost data on top of a prioritization solution, helping to +visualize the spatial distribution of costs relative to selected areas. + +``` r +# Assuming 'solution_df' and adding a 'cost' column +solution_with_cost <- solution_df %>% + dplyr::mutate(cost = runif(dplyr::n(), 100, 1000)) + +splnr_plot_costOverlay( + soln = solution_with_cost, + costName = "cost", # Name of the cost column + # costName = "Acquisition Cost", + # colorVals = c("grey", "darkgreen"), + # legendLabels = c("Not Selected", "Selected"), + plotTitle = "Prioritization Solution with Cost Overlay" +) +``` + + + +5. Plot Comparison Function: `splnr_plot_comparison()` + +Compares two different prioritization solutions, highlighting areas that +are uniquely selected by each solution, or selected by both. + +``` r +# Assuming two solutions for comparison +soln1_df <- solution_df %>% + dplyr::mutate(solution_1 = sample(c(0, 1), dplyr::n(), replace = TRUE, prob = c(0.6, 0.4))) +soln2_df <- solution_df %>% + dplyr::mutate(solution_1 = sample(c(0, 1), dplyr::n(), replace = TRUE, prob = c(0.5, 0.5))) + +splnr_plot_comparison( + soln1 = soln1_df, + soln2 = soln2_df, +) +``` + + + +6. Plot Selection Frequency Function: `splnr_plot_selectionFreq()` + +Visualizes the frequency with which each planning unit is selected +across multiple runs of a prioritization problem (e.g., from a +sensitivity analysis or robust solution generation). + +``` r +# # Create selection frequency data +# selection_freq_df <- solution_df %>% +# dplyr::mutate( +# selection_frequency = runif(dplyr::n(), 0, 1) # Frequency between 0 and 1 +# ) +# +# splnr_plot_selectionFreq( +# selFreq = selection_freq_df, +# plotTitle = "Selection Frequency of Planning Units", +# legendTitle = "Selection Frequency" +# ) +``` + +7. Plot Importance Score Function: `splnr_plot_importanceScore()` + +Calculates and visualizes an “importance score” for each planning unit, +which can represent its contribution to achieving targets or its +irreplaceability. Useful for identifying key areas. + +``` r +# +# splnr_plot_importanceScore( +# soln = solution_df, +# pDat = dat_species_bin, # Original biodiversity features +# method = "basic", # Or "complex" +# decimals = 2, +# plotTitle = "Planning Unit Importance Score" +# ) +``` + +8. Plot Correlation Matrix Function: `splnr_plot_corrMat()` + +Generates a correlation matrix plot, useful for understanding +relationships between different features or variables in your planning +data. + +``` r +# # Create a data matrix for correlation +# +# corr_data <- data.frame( +# Var1 = rnorm(100), +# Var2 = rnorm(100, mean = 0.5, sd = 1), +# Var3 = rnorm(100, mean = -0.2, sd = 0.5) +# ) +# # Add some correlation +# corr_data$Var2 <- corr_data$Var2 + 0.5 * corr_data$Var1 +# corr_data$Var3 <- corr_data$Var3 - 0.3 * corr_data$Var1 +# +# # Calculate correlation matrix +# corr_matrix <- cor(corr_data) +# +# splnr_plot_corrMat( +# matrix = corr_matrix, +# plotTitle = "Correlation Matrix of Variables" +# ) +``` + +9. Generic Plotting Utility Function: `splnr_plot()` + +A versatile plotting function that can be used to visualize any +continuous or categorical data column within an sf dataframe, with +options for color palettes and legend customization. Many other plotting +functions in *spatialplanr* internally use this function. + +``` r +# Plotting the 'metric' column from 'dat_clim' using the generic plotter +splnr_plot( + df = dat_clim, + colNames = "metric", + plotTitle = "Generic Plot of Climate Metric", + legendTitle = "Metric Value", + paletteName = "viridis" # Use a viridis color palette +) +#> Coordinate system already present. Adding new coordinate system, which will +#> replace the existing one. +``` + + + +# Example Workflow + +The following example illustrates a typical workflow using +*spatialplanr* for climate-smart conservation planning. It assumes you +have already prepared your planning units, biodiversity features, and +cost layers. + +A typical workflow using *spatialplanr* for climate-smart conservation +planning might look like this: + +## Data Preparation: + +- Load your planning units (PUs). +- Load your biodiversity features (features). +- Load your cost layer (costs). +- Load your climate metric data (climate_data). +- (Optional) Use splnr_get_IUCNRedList() to refine species targets or + splnr_get_gfw() to generate a cost layer. + +Choose Climate-Smart Approach: + +- Decide which climate-smart approach best suits your planning goals: + - `splnr_climate_priorityAreaApproach()` for prioritizing refugia for + each feature. + - `splnr_climate_featureApproach()` for treating climate resilience as + a standalone feature. + - `splnr_climate_percentileApproach()` for targeting specific climate + metric ranges. +- Run the chosen function to obtain climate_features and + climate_targets. +- Define and Solve Prioritization Problem (using *prioritizr*): + +Create a prioritizr problem using your PUs, climate_features, and +climate_targets. \* Add objectives (e.g., `add_min_set_objective()`, +`add_max_targets_objective()`). \* Add constraints (e.g., +`add_budget_constraint()`, `add_contiguity_constraint()`, +`add_locked_in_constraint()` for existing MPAs). \* Add solvers (e.g., +`add_gurobi_solver()`, `add_cbc_solver()`). \* Solve the problem to get +your solution. + +Visualize and Analyze Results (using *spatialplanr* plotting functions): +\* `splnr_plot_solution()` to visualize the selected planning units. \* +`splnr_plot_costOverlay()` to see costs in selected areas. \* +`splnr_plot_climKernelDensity()` to assess the climate characteristics +of the solution. \* `splnr_plot_comparison()` to compare different +scenarios or solutions. \* `splnr_plot_selectionFreq()` for robust +solutions. \* `splnr_plot_importanceScore()` to identify key planning +units. \* `splnr_plot_corrMat()` to understand feature relationships. + +# Conclusion + +*spatialplanr* provides a powerful and flexible toolkit for integrating +climate change considerations into spatial conservation prioritization. +By offering multiple methodological approaches, streamlining data +handling, and providing comprehensive visualization capabilities, it +aims to empower conservation planners to create more resilient and +effective protected area networks for the future. diff --git a/data-raw/CreateHex.R b/data-raw/CreateHex.R index 928a20a9..09587ef1 100644 --- a/data-raw/CreateHex.R +++ b/data-raw/CreateHex.R @@ -1,6 +1,6 @@ # Some code to create a hex sticker for the spatialplanr package # -# Last updated: Saturday 8th July 2023 +# Last updated: Friday 13th June 2025 # # Jason D. Everett (UQ/CSIRO/UNSW) # @@ -95,12 +95,12 @@ hexSticker::sticker(gg, s_height = 2.2, # h_fill = "#9FE2BF", h_color = "black", # "grey40", - url = "mathmarecol.github.io/spatialplanr", + url = "spatialplanning.github.io/spatialplanr", u_color = "grey90", # u_family = "sans", - u_size = 15.5, - u_x = 0.99, - u_y = 0.06, + u_size = 15, + u_x = 0.98, + u_y = 0.055, dpi = 1000, asp = 1, filename = file.path("data-raw", "spatialplanr.png")) diff --git a/data-raw/spatialplanr.png b/data-raw/spatialplanr.png index e6b11af1768393895284ab3e4528fb48b0b51a66..a25c00962fbbe82d6ccb7eedc4da733d66a4f4b1 100644 GIT binary patch delta 159166 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�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 delta 157555 zcmdp;i9b})|L`qYvyQz6nX#5FlnGIyp{axx`<773k}PApwqnp|C_{;CN!hYQjGc_^ zDoS=E%06UYo-_J>f6wdnyq@PDcwVnwU32fbpR;|=IiK_Syw4qOKbBp0EF^+Hf+2!2 z;y?sb1akySDeKb!sH)kZIBP9vFP3!8`)^t0l(w_KzYnp^nks+8D!M95E?-hxSVh*d z*Wz{cqaC}MdS$z$U==&YM`8-BMLUR4ZZ*5QCv1kL;*KH+&IC1*m51T%j@9dc0_WGx zn7fs|@k3l%;YD^;pJ47K~M zNP325P5!lPg^INN$>1ukdkEcznJ&~mJKa9%dl%^-?$)R^@QAk+Hh2`bb%wWCZ;R*h z+$oL%CtT#BkT~7N<%zWbk5zU1mCmgG@P|Ja-_9_#!j$Se@AM`&3^Dn+Hj`m}I5Nz5 zN%%Pz>01lyFUWn;*ACfG>FjaG$bOwrHp|JlOJ!Vd0|`5aO_PTBeowwKd01OX?EiVe`LVC%b|1L1h~ZR~?J`ae%RPB}QMX2Ie;I*;P|Q`LvL*s^#DqwvI;L7)BW}ZT@ogNhMWr*2=kg9y`g&61oO`vXs3>G>ZK2WgE?wPLc?GvfDx9csj5q3+8x*ZFQ?F$^Aj89+&AKF^?Yh#o>%(lAhK0NQ8(SL(^ zD$2K(_}OpG;b5B$-`=OfU3U4lhK0Rd@w)KGyU?GTix&h8&BtA5u5JIBavS5`9o;)$ z{!_ndi2f!=wGH=9O~pxKV&dZ3?r`~Hj?&Ef?u+p6X^eDxKh$eO@^g%qsuy-d=tiqX zcKFl|{mtD|H)^mopcjP;$(Vmg-zEhW z-(yK>#vuh>GO8|bd90>!;WB0YV@Q5LgfBq|xX$h~&JeOoQOs9%6Z)aC6CW_O)=8`!TX&u03s<0}|9Cly8Y0X1+eOj6t-^8n=M87k9 zWwA#=xnw>$>2^U>X1Ah*ny7MiRK`p4g!bUhrJ@1^KI!4BQq~eLWi`aK6nKje`l^_r z?^L35`}G{0_ya3Ud12=g>e>e) z!$YKXvOEH~m~WobJ+Dq6O5$~$LaSoJ<V%kfQAhUJoiA>7khjCJG5lb%ZyDO_gveV&2IG2IL&gwp%(HcX2Haa8t;3ml8LB%sWnS+68L`894u*qu8T3tBq%?3zkU8!Y?bSPJ`& zo(&15Qg`fHQKyHst~$Xvb+*y12H&Bz=x2JlSxFM8i&B3Moz5Dd073Ful)aY7MmdoECOC-gf z$GHnf5evp;VbIh&h= z+THA`_3b+%dn;+X^Ub|)XgZ9ni*F{>`f=}mW?@a1a#EhtdCZw%<1Jc0E=m#bfi?FG zem>*zjPP}{Ae_us5}|%G`n1$>y3TyMDEA;1J-gNGUi?@HH%{hf934Mhr(EZsQ?!

anHkkrp0Q)`HRru0$zR`d9fRgC-Xak6Dl ztlj0on;i+Kzjt&!S`fk-v5#w~R9{N6&aUW!F8Z|*6KbaPkJJBk0PEPjy5cu=Pc)}gK(=Uc{y1%ltX9Z9lfvI{BW8vUBaz32OD za41b0zdgw!WZp1cJ~pevxct>HW+R5A=XupUyu1?MeKdR5_t$ATSwnd4n%T^>XkH^U zm+ss}(jR`-H51;dlIJB^9Px;zJBD2|!A4pEpPXI?mNdOtGg}%lk9122GlPm?7urvs z+$6cZoNsjF^1VK(Ks_I1qh6^1W(!Vzn_^UaYCj`a`7VE+!k+J+BcL;lAB-zRehWOf z<;QZzg_yyp8P>JQ&zE=3i>D) z&~It|&jRwiSAwq)yDw56uai18T0CaDO8K$K(}i0>6=fX~XPLj~Lgo)BK^wa&!8;gV zrQOzpDD9!spS}$7eKktZ^tvYRG`g@iFttQ&_S$Yu3tSubhS~8tK?-%}`Ou%&Bs*na zoP*}r{N$<nPW4PS3Bvo4Ei#H6L8I5FnsW%)o zZlEttP=Agx=`n;T*|^NCZ-h3Cfh!z>$ob2`i_c<49_r6d6{5t!dGVm-L1uZ&vP?PBNW9ezCG~MVwZ) z_&+d^{$I%#?s)Peud2bY38%&XKvLA+CPMip%I9LgA?5K=e1`DO$&`UaF@)0J4Q2ag z!Ok(YRPGOTxF-qZ7nF@|jX-sB(MF8c%meQ0NNG$~-uL^@$nWy<>K&LbSBf!cCnGkG z*;YI*3@!?THk9@R?v%CVooA45$UE>|5>%T%D6*fQn>pOos>k=vMM=CPL>0g~tmb)Z zrJ|za%gL%;%rCCsCGd{mc0v^LnU(&q-nfCZIVGDvD92!2I39t|peRtKdC@8x(Imqr z!i5@y5;j)@@+>_r2`rc)+W#&7IUcJm{AhM;G%1T=_u9CDziR=)UBy$9P(ps82hRoi z)~kshZzfzwg=qJ)wqsNDhb6~lFAO8%%HqcQ%0I!-DyL#dPZ@&aQ6{aHlplYm!jDT{ zs6@pNCj;}u>aAN7EhlvX%7ko6xio>5v?Zt~qvA)B3jdo!Z17>XdtO?eSx<7vFFq|B z3?r0oa~SfWVL&b@_{C0yJIpf+dQwiVnx{Plza(pq+Y*RRr9PSefvzJKW)8cqPd>gD zxYEJU`Nbnte6Y`uqn>A6ol=-%>6>8v_p;qsm;)m|rE3F>oR ziQf3puc^+`)YlStNK!?yrei#%!-699vIGo}XZsnZ)hC(3<#d!>3B+Qh`Zu6w#1IRW zKobH8&M#*h?$jg?oO*FRBJCk9&uB#SqNVb9w7V(~_Dd=`v6}oM4D^cy#XO%m&)>@0 zq4;!0322I`S>bU5#DwA5k|c6s8M*2MNCa6>tZm_~!b6EqlFe~iwJgr=2c4k%o|3#C z6=gZ+CaCiIHYU3-XHz-6hgYCx?sp z>Pt)vB!s>0_I&!uyXy9Nds>eiq&=nO3oeog^7^l(s7}=kVL$FP6jUdrlV5;}G%#-s zw3|?*1Z8FT(Z+VZl0(n7_8ooJ_ z_^VEew43~SU%=YgulmwXs|{yr9z`<$d>P5AhaTh5x9Lr7`m!MkdPn3eUDc|ZIb6YJ z!B;JSpl-%CY2Xb9&vFrkSC86zdkctbS+uas%$Pl|9aMb#ZFw=L@VOsU8KAY|6+Cf_ zyXgJNxVgD|a8VottxWSKCJK7?{T{2`a^E|w1?}D)pGc7geKa|FD{%P*G+_~cCvjXh zrpp0L*)|Op4W>ZTowE(z;`GI)JpOU=02Lo!h)+4dQ|*uQB}HoSZ2XH3=UYFd)aT}zUEXQAu$^P@UxQ#p`+URTQTsbC4~VBW5Ux;AfNb>6Zmr?5LE1992HFu@f>EH5(3< z7vYPi>Nf8%+0-rldi7ZIpkj@mGw-)(WaXy@o{ley+PkfB?|1&3 zs#$)y7ngWO3(ZJftrg!PjCPL{RRv)^@covJj(;^=g$%Lf8!)@-Ir-`lQNC(8u_s6^nKwxLnI|`!(Ctaf8hY z*9VkIDZFERanrYc2OD707z`#Ep1px1!NE*A6Gb95?Oz6)2>x)~N9`Spc2l@M?=d!# zuq9&>>?7(c2b$s(A9jv9GoiB|Lxo7v|Yd zE(oYg<41T9&zIMyGcSEd+rtStF{pUqbCll*{MGY9w6~Kz^=xcJ(YIrf)Ca)q%Z$;o z2JM0p#rj7fMfy%ZG(CKYmYTvXB#K3P-@JpsJAUHBY5?Q0X?|CjCNH{ybaJ*j=~DL1 zPv@;c_ju|Jdq;mOkt{>HpMWZh!?l5V@s@0wS_0(5KuztpdC^BRqiK0XV~e?` z>?(M~)>5PrtB1tiVjPbF1z5d{JA4?VGX8Yv@Ci_`37nQFNDQ2VmwB*%yb={b4}C){ z2r7Ouz63ITua~L_hTH=}P8=BQonDDQ?nKX>9fz8F{xJK=rO6+EOa7t{&y77wjeXKs zAQP3D&9a!7BZL10+644y*vHU`r2E$6hmHCciQiAnC7gKxAQm2vZ3dxay- z_0Vce?yma9XhDYA!y~&2ba0a zuX9QIUo`_h?C>Av_Uopao|2vq$p<-^W!!i^8^c?(Vo0xw*{gOhC;`*=DD}D+aP(@H zTA2@n_PB=VnohYbgO@}_n*NOVp{<(&k;6?NU4u^aGG4Ozj{X^5rzKC_epprXLg@q_ zTIDuE$t;M&r#R;&DjMuF&W$!|9}-0O|2Sq>nH8gDV-Ydr_pG(%KtlXcYNB|ZcHlc; zf*T58zqQ!SG0rs+ngkHsu^>Cg_!7M$kAuOJf+?S3T$PTiU`*D2TAN3Dub+hW@R|Gt zFl?T$VAVpm_bPjm^bMSr+cSH0+uu@n{$9P*T0fS{%YQvQA4IpcSrOF;Q~BDV*y6*> zYsW_wPLqKlofV~3Sg9zT&>WSy?|cor`+8h*_wyW7{6}5NwZ2g`8!jBum`Fy$ zb0wp-eCdO|Mf-ZH(rdYs*xY|hY-a~H5gy3ih|*da7y#~2UCO=syWE8XlS(>tw0qB1r{%Tks0I5`!sP> z%~mQp)BKwh2jlu=i|cy!-=kqi&XoKJnZlY`STJ)iPMWZNP?%4bk;ws5$cdWmNu{x& zspDO3+cEsd8Eqjql1&7i z1@U0dS-B_tHg^y^XqnHoa&!}nY6k>QImctD_Y};dR==JbS zl|&HL+F@*>=Z{wM2V9NUOO3wVoGNRGaeX^2Ni&GF1YR}~bbCL`9Mu4QV0bL;4eh>g zu+i)ZfBnR6;A&}#(GmddeIcG~IyNaqKzo6O+pz7yJ6bwO5=W9y1M|Hu#aw2gFwg(a z3n|!jZR6Im30WoyYAV+yWieeO=sIIcE=bQG51x%Zd;4bL&JALe5cX(^AewJtZFJt9 z(@4YExTz=4{HW&ofWH9d*5QI?kFQHSi#+Xg!PI%yV_sY}HSeRNUB`xOL`SwdeLe2S z?^?-0e_%5viAU%K&kER074=CBp0~0S94GfHztRUfTp5iN;mTQM_+`%cM=m2DWnuus zZbl=Mvy$D<)U>t5UW_Jxxdw0LNMzR%QLLG)Cbho-4f43zn7>c_0i`*Lq(vl(B=Zw; z-hmwFO%dw`&WhF)q#dH zwqRc(O^tpc1x9lL*s-@+jLl{#>rGklFuu$h}oD%zVeS_#qf2xc1EMd&UR~urOiLMjZ z@R}alI#u0F2=gW#>+55tYdo{C8~I!)z|m}hW4_Z!$?dAm-}m25-^qH2PtJ+chaVOw zyxLQ{qiO+?RJe$WN4)I5-(9NITcUS+D^iGQ#jb#T;qv?92oT)V)a-&OZbEBNjhXp)9(|5a zvec$;t(KWKNm#j%(|Joq`3U>;Zf}s^x0Z*kFb*p%Q~xP*2l|~VTg9u1Mcg)x8Uyrn z5$$?=^*7j`Nws%MqzoA;)qn=ye&u2l>qTA+kgeY8X^y|W?@iSyEJMY!jn(W4=lLRP z?*HnpvMiN<&r$^~QO9S7cM4q;f!(seKfje`6F7IRe@scIeJScwsMCU&v|7T+Fz_!+jk8du+0 z5>a*J59~QEQ!Ve;Og%N5E(tfkQ^?=uSsFJs9~8Lc4b4Hztbz$85tkV*E`JV}a3XTE zCSQBQ#~70I11@s0fr^NRsn8!kr|Ex=eQ<+8AdfC26zyg(s3>qDm_DTT0hY7Q?%`20 zdOF{!>?_x^o^a6F2{NqRmuB?+b?|Bt1D$k-BKM{8D@@1eSOqE7)lDc1c!jFWW6jX2 zD@jk-=_#Y8xmjsEj%AjNF)S zN_$GT-E5G0GIsnHu2;*>3a@ETUvj`#v1<6EshmyX8$B>(ljM)rN<-E~UQs{2dMg?+ zF`zZz7yn#6crZyS%q7vTxeay}%VbX(J}fAYiGUIhisdpfbq0n~gy@7>kG>PK^?Vm) zK0ZGw#C&Yf>$I;B&-oAHW7!U;O&_(x%APG34qc!nRbF(-c|OSxn!!P-XSzb9qFE!d z;#%S#*r0+<;^<^sD<)m_hU^9t*&LzPK7I=SQ7S~gSPx6D-wM-ztIc!Z?0^0d|J1Ou z(?27IzF-w#aN{Qyf~)XhCN|};Bdq_&zwz_L`V^3=!ubD-)X@K{mg%*06FcO+sWZaA zeC7Gl;a=or&8LQAyUlwi{GLpNUVOwWJH^B9!?j^UImopbCaO~rI4m@Oh}p~o%Xvh8 z_{5Qy=N`htpN^bT8h{vyyNAu_yCjemT9MIy;%8R0dF~7AS8<>D=nDyWz#lu|bn%&? z8hF83cb<>j!mKgLQal|nkbsUkZkvWW79+W&-9e&Nwz(-XU+7O;vu%AGT<|#`lQ&g+r%zMd-?^&JE!0K z^@rSVXVMB5^gh7U4rShdR6}o`ai;%0+o(7NOE2dXd*=ktA!%J-G3D58F1G__Yr^xLXuI7>x|=?Dy93${ zy$p6P^F})$Bx_`!dP2#@Ay~+1?STDlvGm(hejb^1_UhW!Rt`bf=%v zO$Tu$=XgK$(IGS>e{*Y~t9!{bS4h7yAUn6qf4(+o2{w}&hPC$arMGj!v#2v@g_M-D zZ9P~UmqISueTd_!^kP*|ZwWul#I?1k07Aj!2^UU@65h&Z+g$hb+B@k7U&h(#i3xYC zO2j^i@iJKU{0c2r$<75c^qsEpd;IsO@|J?<_UmU8J&ze8O#`^LM(3K3F>?ciVRY3> zqBtU`n9+HPPY!OG&s=xWBZtmB!}n+beXZ}(b23bS2n5YNRz^an7YUTe;<6XF=qHYeyP)UUMb+AE$s3EsL=zW-&&)DrhQ_JK$b+gDN zar$M$qCe|Ff)r|SK)U_rDU8|NIgcEZ5P5pD$e$i-I?rrMEKh`(kIn~PMxW5g^G1O}bW_Di<=^Sjg9%r~@Im zhXNh2!SEm2dei*riu7QI}X`y5IHMjRJdVuv-i=q4dOJ*cpWYcHjw)L|Za{Hu0np|RovJ0Un5VuhWP06yGG;7&^T^a~ znHXQOaoQg4_lX%t7N6ykuOgjiv)LhU#=+hNN&BIjs4{0|1aL$?_%)jEc0?9Za`tmX zj<1dNeW~Gu3Xg?lxF+HZnvG`7zEskoh~iDzs2vsI5z0IV{`pMI+_cG3+Oj z?iHIywIAr+x^98@dtEcH{)`y&hK;}mr2M{d9(X3;B9w%s%lW`m5|p$p=G0*6&kFsf zuT#?u_V^z8vk32F;{5l(a``B9O&nRea%}YZOUCbIQ@t0B1m+d%EPwKZqE$I+4+6*N z`NC)Gsof7oul4iF4|Xn+&p&L;t>$SaWQBfJ9#uLWQoenqEmCpIk;Q5G(w}y%ebT2} z#iMvwE@cP60J#yJ@XdEdb!`|Cu^&+>&bVPiYW4ThZrk7pJL4|-F-Xm}QEM1&k+dkZ z&`?<5nkzQ&}=>Ky7V*Ub_?#I*|*rJ!i=QSJ8%C9U?IJr#oXjOS5bff$g`tD{XcmG2|8q zen!@M$W$>NhD5lkR$;%)6*m5;ajaw3#uT7ew-P~c*Iqm@@wrskg=>`CRVibH$ILUS z^||+KUP`?^JnD6*PpX337c#xrbV2x$u2a1&Adr45>JH5_PI==Jth1bP0gE@ZyYGh; zU*c; z<#I#;{iJ*5ewo8vU->e;Ic20u^XNcfy$l>tk#uYwdVn{gfj2KBf1DD&uxCN5PZP%h zFIT(#@O0gOEC?7g_px|G(p#VA`wo||}MgHSpP z7hw+j{JbJg?vxQ=R%r1ut{9|^%_Ckv<<01?U;e!UDTZ3!N)pW$&fiCA+Vzyn8GL-` z7#qFWfD%ayyC9G^@@P!X`(HiBJK=T%b}#wJ6A-PahVX~& z3`$DjWzWyG^)oHI>N>bcfJW}YCc21!`g-Xvj3$yu40%=Ijq6qn|Cv2jnG4V)z@44U z<_e}mtP$TSTXu}er$=dlXujZrR+IW}^`4d1^wH+jC&}SF9^4Wfw1D=Gvt8<@@x-JMG&3EXy92 zIs_sD4+evfLUbBbPZEwp^lSUp^m$UT&wrBT`#`eRXbR5D% zf++*Po{%U00~cWhMgS1wm*gMuB>7C;SYKLLSscZ^{|u0p`SICVR$0c;qUY}R;tOX0 zas}`YFb8`bqtkm)WeTOIkq?sU*HQ9#(qtq+Ru~`AH_p`k82PHK?1h3ly6nUj&MK^~ zA1r4vZ{S^v+4Oopc!r--FBN+|@{6Ac60ettviejbP$W*F>?C^VH>01Bc?Ng+humy3h9CXx#Bo)>B0W3}h`DR4Ng&GN zQ=-Yq;b8frQB+XhWeUzv*0Ql#?28zsU6YQZXgE2E?T~3;+YO3TOlC}jd`ZX|`DRJ6 zX`lvut@CzL{I>#AEO{p~k-#8X7wqdP@S!PL&T&2qj01SWY*%+jyski}--zM~LL8<^ ze=f+jN0d`p0f$y7|3K0nlL4C@N75ENOJge6ayVK4}fJt>(Hcw5t8;r!7=mcdq+P z2;}jd@SRekf<5W1MGER|o$b#vS74{UX#5oay0`+vwl6deZ>d4A747Q_3mR=n8W_s4 zedx(gXqbw8KPa{~HtSwLD{HRHNSi1q&jljC4LRK5SKBHhf)<(kmWn1=1>G`h0WS5S!dA_uPU{_JL{tDf zvZn(DM;`co3iGafv48h-VK#{JlzfY@4xmTI9@PIKIC5S9ZM=^#UXU=K zz>n=nXc<))LKnrS(-;@IX(aW$5Zd?w42x3@;P;dqqxqsjo0)#a>JPsG#s-MXvL?27I1z0m&m2=H~(^4->Luptd`6tiiRv3`JVCv3^wk+kWL=o`>R9U^7e-C zRxsOv2B0xBpfuD=hxV^w|EQmb8`h`*qsTunY?Rh7Z@uznfpG&}83M7l8ZLl7y1Jxk z#^Qc+e&k0C;B$=mO9D6o_C#WjNMjs9gb_5V@S5HuQHy3d2*jx00t5(6Ve@oM?V}K{ zd1l$AvJ-@eQh?jY#34lhDg^4GizGOEh_A8&$JHgut?JTWQR4={%_}|8f+Lm5Bm-tu zMw2MWQX?gYxy$9f1{@R%yT8*iK5qF;2T+gr(tjY4V%>w63vB~mO5+{%3{J%PMjBBc z{)EPvPd6r{{Iztj6FCQ%n4?saX2SIOsylpoCzJHk;>a&9!u0|A^1e?ZDx$g5~9r!LRtDT1{3`N#%pUp$Xlg%koa~MF1j^;PVAfIXNlRNbqL*YY# zFXMok4p!&f1g^tC{b5Jo!{a>wWn?M?TndMZZ!Jf4*|9TNr z!MW^m_>(X#_5JT<+j=wH)wo+)CN>kjVc*&<85gxbawE?~ z2Uv@`?~h#*k6Xb!cJL7QX@CAS-M+zAWKLH+MlK3D$>JnWMddZFEde*JEdFZVb;j#+ zx10dp#5Hy@mGRD*!_YYz19X$1&gm(+Lu%I_zBWER_I*qeAUd4D-|YGiqxxWXARz|H z_K%CvK@!xNKtLm(TvY?GC@?f}NE?eY&|fd)J}ES;1}2DheVex^f7z_oBy)r@MPcw! zxysJ?Prwjd=tH<40-b60I^dWpK^+3QG_#(X-CRDa?ztk~q%t(zTdHsK995|~Z6oGB z_>V2MCbgb_CdZGhwpMmc~1QA0~iwLz%JN%JbATr$8NdOrDsnt{wtPV@UDz zy+TYXCaY>jdfYkgjXMr1k~LZ6Bt>JCBvpj4Y~!o|(GD12F5p2QHAJ{y2N;Y5J|iod zByy46q1yC&Kvx}uciKu181hJ-0Exq*lf!Nni`QQ((Ii|go+D!h@Xj1S%ge|ZKJ-qR z48+>f4l|F@`sK?!;gf>$kF^UPlqckqG4Es!wk+AT`xj5ot8@F>9g(CLyoJSr%~|~O}}$9J(~F5 zWB_;3XrhngstfSP${5sRc|E`o89$ZR6LXDmFiJr^&-#v34ImIJ(*H()F!U>#&ef={5CF#t`!#95er`5bLzN)J^#}F^a3ugQ z>T3l@MAn_T+`T9K^*8@XkM=HQ+*&M2#*xec-%%ojg#bSR3l`7bEF!;fLZ`m5U-WTqxEJTNK-}F0)bU%$5^;J(~PNO<5)yX__}DDsN*1050a4mbcC2GdQjHExeHC zJ8q$X*GKSQyDq@6#I4@P;z`Z`GjWojn)!Caw2?G;C!SmaUpjMK=d9hY8Z()OJ%vB}2vqeZK!^>>X-DII{6lf-G+nCsVSnA0%$O9P%yH_hj6zDK9Rk_wSDa7PkI zRjed(A3q4l6o6_0Km`KV769!p-(Lx0la|U|_YoziyVAxa!}qeBCGKy0F{BmF{K8|P zfW_Ry4O$nH_|*W<1uzu*{P44@FH^~wdDQdE?`1$hrt5VTdN>y7!;dHu5LW=0Es$fo zDnaVg52BrkQx8ovFb>A%bwme<^BTZzgEEsGx}JhizPw&4589B=qEHS{0SQ4Umcq!c zepeclgiJOEOYE9`OA7G|3=I?7n!60DdmY}|ejY^2!eceB5|aSwmjrYlc=xqknGs64 zHYXK4CF{XVUJ^Q+mPqFFW?PmFW_srugM0{-&>ZMu2>?U{(J+V&v7jM}z5TcNb`(;e zY6;f&+vZ|oQeg6YG6+Y3v`zlWro1QdRi(;|N;=2=`*n{G9qyJuyu_g)z@@mr~FtH!ToKrk+{K0tDjwe}E7e zTpS>9`&7>cus*jAA(TKrg23&0rTdORB4AP~Xt(&Ka;t3lPl+{%gZ)WL?rYmw0thER z9vDiaO$c~$+jY2Mnlc0kpKK6`tF!+Wub*10<&a1=fy-s#w4k{qgSH2N@5zcwivLF+ z8B&txkf^`T$$+Z39i`Q{Q2%43{XAUGEN3g+@a%Df`&=t|?Fu2cm*mN9#01r^AXEUxhBNBz&VC>Z!p5B@}M6=<{ zqmU18N0IV?Ispg@U|Mxztks(X6T> zC<2s`pO-&!?H*j8GAWIJgukgmXwd*`$VL?MH%gixo7@SzeA9u3V4r^(tI8=Yfc-KI z21NXUKIoe2$m{q2At~;BRv8+MOeiI_(+1JXt;#RJvw`|knAer}T{RG%09Y_EQnJ7T zdf37!{3@VgFZym$zjHesrRAwhkU3ys_1?LgP5qcBe*pYAVj+6Rr(>0O793eR1*W@% zXe|l+hdTepHIKqd{E-rQUL`7YUQPp$OjkjX`dWwWbl(*RuIDuaYAI){=mprfzf<7^ zD@|*l=iiW+NBwAp1ARZqA-S93Dyo&8C58(@*_&r|xab zS1>i>`GMR={g0|@1uVIf%D@68NiBHJ|MWWTNBpRRN-XqE%$C+>w1n7b&{`TT;hW?n zMAt(7B{Hl8hF)qRC{lazjRm#B6-?PRRerwATZ1;b04Bf4^qsE6i?wPMu`78atO{^7 z2z^R!{b{Ui*fM8+2_Scnv_lV$(FZj^a3AFSD4do^`Xeg}p0tnbu+86w#>uuX=H$m5 zd-YR=6c_+E1VX|#7d?#l(aWykk>PiN3E)YCc4R-J>a7ohaac+If`;phplP^~j=B66zejjvo_`q zfOCQXn52TIy`j%L)$Em&{|=nO7A%7xgZnhBZy%zf$$rt?$JGy#0S3xM7)|5Wdcj5N-kfrNbvINH zcEBt`9_#^eFPg9S@wAVG4Fx76@QDQUnHYrL@bY&Sxxz}W85cB-9J%+K8T|O=T?&rr z0V?Og(QyeHI1w*RUGEJt>*#+DAdRbp@=C7dENyuAeL=Kwf&UX-vb|`H5f56`%Erkt zf?RTWm|I6paqz5}P1v_UDEk@8zo`vu)WqZZOVHaQ3qXOw#8`8^_O-&&>hQ=)BhK zFV|`SkAOTXS*AuGJArNS^oP-}C+h>f4O`>=q%|MsVkq)>Nku)I_V{=VH$5^UNSG)E z@>hZTcm-S`ULpRferQ*4v>-GESZM|VSUGct@zeD=?bk4_#q&7O5+GxiwnyHJ((0aS z?7Ea{5x3FYt79D_51}uCr*_#TO&`&;fJyiXEGcsMO&rSPJ=pKGJh(xgmI8DOjz+f_ zKb0ip0M;hnaDa5l?PHldb5eII0f-&b8g}=IFIhID7sZLMoR<~P8T3L0RGWGPU^ICukiV^RV;``Hh!G;yHT}ut#j>_ z&F7PtCjj~=qtlGU-uoV4c~14JH_-K7hLVE)Onw70@E=(6UknAf%)!JIQ@fWH_6LgmB$e&o0OK3nt{EPnfpO)h9hnxNj^=QIGv zai5|AqwfJ=W?B(OH}C5_axmy9DZKKXY6Gat z)x3!{hXp-4J86IJnv9RAc>8M8iUpm9jk)fszgXbMG=Azu9@QS46SpDzLAxhOmT6x! zUbT9>SO0dVA>y*gP?h){P#iGnptgvRdB)a%DiO>wzZ$0~X14uDgA{g)&3Oy0thLmA z`00)ATGKpv`+nO74FPk8#K$yv<0z(R_4r`5k%u;Zbs?Co-s;3i_#u|s$l~WxZ{x}o zSKj~-grN@*cE0r0Rm}hdS>nq3<+}8+z6tdf05XsMf@tHGoMJ&JRMv$wlXpvG{pFqx z%`5{-Vt!cKZ0kzkEn-jAjZ*oZh>}_?pm^$UWL4jN&@x?a?7x?A5J$<^3ah2^=znC^ zOI%-S_MtnA6#)zIH%qu2IEP=9;f>o8zoUfDDC*=L95V6*rJN6BBbnsM8~d+i#^8d0 zFBBZ!2f0C=RcUo_M_l(y^ulo0Z`vt~1ncjQZ_tHw+f56|V}Kue@MW6SMT6gkL0qA~ z5;CM1@YE`Cx^P@j{q~{F@|r7e$84&hXtkx7h38){>b(ckHt{ zO10^3DkfU8mhQbXS{Pd~*{Q{@ieebG3%@BAcn|6lcx%TLRW_icoUaSW7Gv4iRMm9L z)&)E1Bc)cqA4wLBjaxB>NO-^Xd}sA0Od#ZJ`RgNUX6Y26BkT|DY3DFVhmURG4@n72eXfLFQ zS%f}H<<^;&YH_wP#W}I%n1C$k4iJ7!rq2l~Vh$WESKNij?X-d|aR{EDuePuM)bqr= zcfrbv5%lWW2MlS~n&jUf4YDrvRD19%%Tq>PVCE2y`8d^AOk+~FRq0G?=Id(!K%pa% zVHYADU8CuUylxm0%Tu`t`3~8-H)-D%C znIlX_CSRKZ87U(y8C{Oe$p)&f(GR3y#IYJyzW+~{mH#`15_P!gbD+pxYwd>jc7N^0 zjB+wzZHyB3Y>obZlRN)|@O&BT4|Zc5**$D~?nfCt-Cmy(B(gWPrro;nrZ`fg?*GJi z!j8DnK~w!TVS6j?!4r^fFuiU_2XP1{`U|5ltO5Sxa7X~xr@8n=Dz&) zrtPLK7y7A^U`Y2W5@4n*&+xXSw=HY?8_BXif&hI(*$^d181&Q8g?mNh88FHb zyS841OuP}_ILyDeK4vXeOK(G#Kdy!s{0*a1+D3gwm_rOHnJ(rGse$6MR*7`t+eTNK zoK=uf+6e*+>%7(6i{rQ0ey`In1>O|QRjd!4{w~7r4uAaXRA$K3lLz9gF-cMskbH%= zp>-+b6JV>D;OK1ULt?L7%n_RxZy(|BddAcVYtF;)Yhr|LN>AR1b**z`4qiGaKH9vc z!4+pj2hrJXe2z>?OB45B@O&4(_m>+A5!d?JxvA{ca$u30szv7;%*(B_eO@tbPR+Jq z7?Q4bO8Z6!zAMlu6YXZ^yagD_L}vXy4LU%8D7ff!mjoZ2?`*N#xlSolEeghL?_ScJ ztU3__B8KYrqH|UxM-TDYJT}y=2p>5bE(3AR*d3nVHT`{UIgd+Nx}jI=f%vrf3|;n6 zT-J-cAKC{FY60e^n?!eS-MT_kym1z8OZr6OYVR~WTR;zvIdk|d|82&cCj-uh$AXK7 zw{%I&xUkF*%fvr;-+72Gq^Oim*k4>{1|H-2b-|{l?==0g#%Q+wPGRUPZr=q{C@Fm8 z)DgW$G(x0ZqV$37i|38ENnxhMk_fEDIhPRp?zjI&+6P#NE?jOoq4DdsD5#-HeOeip zT|}sGq*@njy3BZBhcyrK0hmyEoxg&ocz3lQ861qxDT+PDN@feIXPJip9E z)6JjAd+t*}!uBhNT;$7^a8t{=B^Bq7Yp}Jtt z92{}KTu~V&YPX2;*hM*-;*-u#*{kIeL37ZH_x0*N1zLa<{#Va_PeDSN)ur299 zs#L`_T^FL4R)z6s5qJ66JQO`9Z%q60igrX*=2t0=7Uk_4Vf2YESo=c5j}2ibK+Bvc zJXiu=U}le(Iz%*QuxFjgd(?eDh9HIa9h*IBp7D*2hwD!jttVbayVlKEft~;)#0_Y# z@&JR91P1P6O7J^m_9_{U> z?eGrIiaYuQYNiE?zf73bR^nvr(Y(kdKa7oX58MJC?~5Sh$q_4e^7MnL9@`)U^PvvA z9l?|xh1+%_4aH;md5yLe3EQcpQAj&wKs9Nuv8g;_A8M(kUTF-CZ`AN(*;;?8_0wG9 z%~jy!cNIYaophVP{*mA4PCf@d$D>_NLqnqaA6C`MwVFPAV!n7oOv0@4-AKE7CvfnG z>qqZ;9*FTB%h&3qrnhMfga)lkmsv&<6T58#!n%{&08SI`jUW38rDBGBkEUM>1D^)~ z$2R5|N=9g39-2v&tZlIaA0$DT1-}}T_vflw63P2A^pzjhURZBA)D2{62ZUKiwBUx9nvkJv?$$3DU#CNT|+w5P|^&HAR#4!BHi6RNQp{HGk}!BAc9ig z#`nGV`@VaBf6dI9bM{_)?O1E?^*rlL-_&v=Dkr}wUv(MSd4!&7S;0s982>J*fF`{ zJInuz?g1H3mgXrn>iS{Ztm;KmoH+{VAFBm=LYjlLp4KTj37rBSv7p=+FGcLXP%Jwd zXJhtEOUh$&4JD)Dn!}T;&6&dn!C=;o%iJHqcwJ|0S43CeSS}vw@nmeBIeIo7l3q2* z$s@$oQ7XnJ~5@Ww(UB;#JSbtjv!FuUF$SsXieX1^}Yy9s!3@ zT8z;pg1x$s3Q6?16#UJ7TZ}`iUI4%;GEavx85IXb8vlGX8hq61bs~G~{ul=)NLq97 zTZHyve84*vrn1r_S++Zcpoxcb6d&roGN6P6^G z!rM;nC5D;?%4C`)a))q%Tr}A=>1T~*RV`IyQps>RucG|1^_}t(`Ap~ zbg{B9q^k67#=VAUQI7Yx-c^smc4LV({#mJFyr%8TNEafaUXF=d#Mc9B zEw0wwHSq%ntT&o}OgPS|jI%XieHT!pi-R&{atB3z57m%Fw+lQD%I}t3Lc|jnICH#T zh*(vw#Xhmhn-bXt`D6fERn!86C7(+PHRIW8C*Cq%Q)~Nvc?9QZSQ*?(Cx6u_4YvT4 zpTFHRTK7&GJ|D?P-hqp2tXKy79@<6f_~R)+CemyXveqgI!SF_ZDAg)q)J=tz=<- z4AkW;9uh8+v~$VW~H{yWpdX>0TpKW#a%?T_HX#~Ld_M+ zzF#T~Ar=#dDQ-3m=muM(vi79ao$e>dM){qRe7`IP5w;y|^N3?jYgq0y*{k$t?kYQHseeuTioab(4%zDoIgIZ#~J9_ z@aS->)y5Z`y$a@vRo_F8p3!{&&TaKU>GkV&A|tpj%h^ngkqh2t4QPQ<~u!Vdi$pmNue<&iSCaw2vA$1JK$}yVr_4h zqs6!O*Q(#WPK^cp0OBc50N=8j=!vbY{p^|Git+Ic$AqZH`KDMG;S9o6Z+CZh){}W{ z7xvqgrV28CD0fMEMJd@g1^%sv1X zVOfHq@mgejjfbSFNo5&2ant4w{{b+>EE|^emTih9xEcxbbAeH(I`e^iWw2Y$)7?WRmJdZIW z>D&RL>BvTfVK<-HfwJt!NDId`{wu#{4{5A8>Xcv?mvA!d&2a^9N5MI|yl-Ca{CRz6 zz*?lqnyD+}BnJEXV6*AfGGAbw4@eLY?3C{H&7fag5=r3@bRcUFTZDcePjDR=6I4%g zF%@E0=fhO|o9*Xj6DIAOJM~Qjh530BwcG{kNTL4IX0+N~2!IKw1aFcpUXXfcD|_be zbti6%ulew@CzG`P8Y^U)#q+e154Bukg4(1XY=VZuG3V1D0E)rW8r>Z^BIou}eC#txc|EJvQT( za>k_98w{z69{0fxPXY`0-%{Ru{(fk$@~vT@&UEk0dk?uD{IMe#-x(`PQcAXDMB)Sv zPX6}__fK1u{A{&7X&XWjGUa~w#h23W1a#Jpghu;sJ3}{kvq4wKop2TQ4OF_bPgzTZKe;s5CWN9B2H3cJVFT#QB@#?3}E>b z9}05`2@+xX_z#HvgRJHSQJ-9psf?M_;XO$C)&G_Z;F>tVK{I)#9K)Zs!^hMYPn4Iw z{iPKH9HE89t9@(LWP7FS2&hh}Cvlu~=B@UZ03j8-22)dJKml8fK zq%Tbk(rfHjvuQXBASEjRJhjAZp_dWrw>s(lF^WP!lB}6{>zBrg7M`F0;0v5wC4ijR zsq*L-I4K9vQxl78_)-qoN{|JmD0Oj@f|)uXY)$}T9_=(zlp^LRnQ^Zyk4Xs3j`;_N zIpc6iGYb=)X0NvME@UuIUM=~qiPWQ@#?i$^M zI8PpC7uR$#u) zpmaL~MtagO@;dw)FSsd>Kj09jAal1-03ueC_kdC$z2jva_CLTv0zU$OlfJ8orJ$Hc z-UcU^%khh;>w{Ty@6Gos>rE=K60}KJ<*^Y8xVD7}`^y8JotF~f?vmKtsyNe41(7@n9m zfNRC$TQXbJL*uxLD1y|Gm3M!--}BH$_t116WH`CI`<;(obS)(t=7pB81ixTN!T7xT z5`*_KW7f($)%x1d1e9s(@OqY~!07CuA?hv}yQt;Q-@iWoGDb$rg#pS&iM9VUU<%dK8l(f zK02Gw{&Jp3f|P|mfkJij-Z|BEK^&Uwf>ZS*@x{YUYyAk!d}WJ!YslCRB(Jg`OlJ*= z&61DtBLm5+%eZa*Hp;-y9%jK?etUNxiVNHFq90c;d4M#I$yMxC zYLKEKV-&Pw$)l56b^P=$I{v!8U@GW99LHzc#u=TvTsWY0GAj=3IB|bPZ@1}3ki(Rj zvoj|`)QEUW)j>AU@BxsZ?S5!{JCM|wNKQHLjnl+a$kQ0g^l-hI z(u<3uI8IPWAf!mO(q)?K`NpU^(9i5?(X`G7U($tUKdH-~$)U@Kb<4rNr0{&EpUNl% z#%GmnQV}(EQ`piMbJ&qNB_qVQ2aV{#N4HI_s zX#j!HO^_A?+A>yfs%LU*S7M(y*8Kslov3#(DO(%`&ZK&J#B#`R(m(}bIc~&bv3E4DdHILgi2@^SuIEh2wGnolHJX_>NY#FtDs=npz4qL5Ja#qf}xrS6K zQD&Bt!43_+yM|N)ffxkai z!Q}Tn>2Ou{8M03hL+s>r$mn-*O|4>z-wboYcT5Q3 z=8yT&Q6;hmsTZ)hvk_B9y1Na?I!e`eqqhSBtG#H}U#Su8Qav_a(DZtZ1?5;+*RksSgG2(LO5 zjO^o&-_nt$cL>A;bXx$dbm%M$YQZ=sO(k-R`88e4i3O@f0RH3|Kf1mPf@kD2QU}rq z_MPUzz$hC)VBUSJ@#zt5s^<~=M3PajJ0wly(uwqx?uSxdp*RoMoNezTREzH7kNQC! zFo|PN*e60DcHNb&%gTTIC707J8C*+>=iuH`%5&Y_=OI)qG`DipSbnKarW*K|4ZUzn z71z5G(e(4Wa66UQUy%$yj-H_AG+~OyK*_e;=mk^H83o3v$`1fnepSi$9JyW`BMc=- z*x497)*g6!k<@Vu>Slv$QzXMHxN5-HGm&VQXDmYjjgR{1rNX#<*Mu=E`p^v3A_!0H z3lc;(XWet(e^cJBr137WC6J&HT$=SYbA7mqXBs&51x6Btb_0; z!N=dFSiPoa`X2_tSGI334Xz6+WP4Z#;#bLp$_=Wh`gFBmp9*yE?CwI=lf)iYxz7@Pf-6F6>I#7ZX*Ae|l=HA4=hDsZp`y9!Yse@X_tusyoeGnAN{C%Q0B*foGii9Px`qq`f5_ZYeV40{ zxrZYr@y*3mLu&v5wPXfKDFzVM|9)aJAe!n$7nkBW?gQCEOV!rldQ3QI#aoqQ3_goF;KMh*8h1m5Pp!f?~mrehzd40Y^Vk1dhc;z|r z$cQn^f0GrR?mVTSoKxjt$SART2OVGjeQT48?b#jB!qf~k1zK5mM245@Uo~t9!WX)4 zBDkNBhBw7>=6J&fS=zq~x1UsG7{LST9Wk!{%vy}NgWB&-UHob9zq~jT5>>$>>VAXq z86K_N>LG%PHhBN!d$#wZ0Yuz@1!@k{XNkS4A1t_1>{azZAL{H?X=}(tp?Ts^t{2B` zsk_4Wm(eYg8M=&FUdpJKdW>||6m?`AOjew>=n5eO%+Lg4w-62<22aH{Rwh|-qFscC z*Q7%OIH^^+7RaH@piwIZ-FyB)S?!QV*CqTd$cS+pqKcYJ;NYKIuLR0?f#iKFF1#L% zv4v`%m#O=v!*lzy*rytAk9< z9M|T6C#s>VFs3Gomwm#35n}SZb!1JAG$Yn!cn##z`UI?~M_juu=*qQc$;ul6*6b4? zUB%cgtG-BI-PwBv_Nt;aB!2d*sm{psJ80<&aqnJEgyCa|of4+pB&l^Ni?MzQPHg*& zc#fk^bMk-d|DaCA0XOSWKsirc@TaqDp(M;2T8J|$O`j8&y&|I!FQW8$wtg$oTKa0;$s}V~-6;Rzo9^|ziG}d!S9`F+@;j&NKcu7Qls>Gb(tE^8s~}htN2@w2 z6tJGCnm^?5XkAt5bLA0q5sP)nPL&>tn6`j{=I~J+aG0++3?(sm$4du6Py>9{+@~d> z2dN=*aU-QF{7_Gy7iV|jKdXJ7n#dUr|Lo3vh?>KrTLN=WS2(q~{_aSHvGqmu>K!=R z^y55#|D=akjgH;evj8fnY&-`g@Q4=cmqe``9J$%x#@J4I2^<^)@zQbwh;SSP%+W;e z)kZz4!yP?Vu=d_Vr05T4W5*Z+&iS({F7zm-&zN@+!^}MHsJi9Hd8T-3XlOh~AB2iQ zh?hdKZ@&|GY7i=3w3*SzdCtAS$t?<~n;TKV;hs+w)f&=^(MKmr#ob|2Dpq=ChVxFk zjdEV{8uCdE`-CwgG;{BsPB{{0yPi5Kevk5|M<%8kJhu*U#04-Y; zr_jMijDz)805SB~2Tbe`a@FW{FA8W9$+datpVaiK8*Ep)3j=G7^BnZdlcczr8W_&h*x#4`?v^?sB5+Jq?;Ji&M`-UDW?r$$H?5(UYu8wDY#N~#z zj-U9$#v1)jI|3|iTlObIh7SA7igWPp=%V=hDLy+4VeSPTizFr!ZA$;rU1`H8GoOri zUB0@DU+Cx-aVrEpwhqjA)T045xNn3;wx;(@gkzI{LJ4q<6qWL3b}6V5gr-Qx6;XHf zHPl2ZO^GsZfHfB-h^9J7y}{`!m@1}AQ2;||R;Odu>7Z)rQt^}gZq#lso7h0?xGWJg zv|#1aMA_qww)E?)-ZW_o2m30qikLU*ojA&jbODvDRL*!(j#N;dJ_Q${cxh3(Nb!a3 zrHJXu6ad!ZMQ_ecj{*~JT_<10({402mbsLwVT^;)3bW+(FVMGeb(Jq@u62F8Mr45~n`>VS6t zJob3_N$sK|#Euv#xme*UM^n6eq(HKE$2@yGN*7Q#V$_w`5>bYWRSg}- zmW4$`3>LMV>knEMFa$iO)`D%$!|qRyNtL?`)ROIBvc;P52=f-l8|Z_EZHpN&0?W zPf56@+F_V@d8hZd{*0si_ADszF@H_BU5eGS*3vAbDc?+ZMXf!+YuALS zi5jZA=yE{W5l*QZnCZ*7Rt@m{VwE^z_wzX6=b4;ts$jx})mS=x5d_2M5o-8l(tKpA za@eM0t!i>AGL_!6M~lP`&xz9sj6Vq_W>|I(Ne-B}w}DrI9r{Mh=z5RF5G@osu8Vpk z!poMJPnsz%yk>-$nZ*qa>~CE|ssc45?DtQ%_;}DeCOvoV9yC_$oImmvL0!8iG-neEDaI)pIb)DdVfwcezgz*w z5zKMjsrLgJTtPo)8@3Gw9v3l~ustEh)nueYvZ0$%L`Ea=99Lk)IE!!B4nIDnRLz3Zo=avC!^_o_fc_|Pb? zTz?XrM_`k@Zer03<3oSZ28*u2KD65fU6~9F`Smm_$7IMS0(t>csbqy!DUuUDdN7GO zvZeC2l-ygNGV1Wi7)qdDu2c%Wk%rMvp~GA$wr&nM3f8V)fXF zdbrXLG=SZvxEAqX-P0(R!yWDM+Lk~Tmgw6@?*;aV08cHBOsY_usr)6=mGHy@O#OSc zc9Z%VL7Q44T=>N+uwwXuf4fz6v4`nA^IQjqh*ysMPJ zvVE5+yt>Go zM`L-cVDtWqeL_AA=vNBi$fX8Uk&C=f3CKo62B<9jG;v|zdlIF!cRabAjg!9r)&q;G=Iot@~dR{-LK%p84CO{Ub zPbRSxCQsWy2Ia!y{QKt(Ofahd{qu%D`-IYU*+3XpH83n`7{bNV`O%4g3smpCu0Ytz z5L68Q1Sbsl$w0+GYyV%x)s#>!Q1K|Jn4{i%=ij6IOpk04`^VA#W*8XP>PZVmzUv=_k=e09%HP)+IK6Of4w-Ki+OYBw2Vdi zIr2;5K=B^(7BrpDSKsv>AC5BClNjT$vA%Z>^;SI(qy&+`gDO-bQUbsXwe4eWmZF3S`1*54^zfY21$M45&SAegxkG)8|L_0mScRm^JZ9ji)f zcc#PE%V6^e8^jB;7^$AOz(?>JK+shz+F@^2&A$eInLm5g7hrvEre-SN`Q$;Vj{Ovz zw%F12_VNXCh=KSvzvG!r&(5u9Pcw$;=fR0W`DqcYhlI=@!FusPPdV zUUhTqg4KW3bJH8F9~H=()j;RG=*%azj_xZjWE}b@@2~KgxZ)ZB140R%=UZjfRJ_;A zA;3+FWd3rp~!{*)N3D>i~KG!`%DdIMBV`}C&dN==lz zR5=E4tl~xQ#x?;F_StikLQ)W71PY z>Oq)HKo^bmy|d2XB1eqnKsV1-sirby#T z(mixq!QO<8mAo`%H5C0Fq>a;kheELfugA{eCep7g#l^f^ z9htj#k4>euXUvJ8f=V_~Z{$}uXt|qo{Ktdg=lQ8+O?VdF3@I<(f0JrI_?YM66#3<2 zw08?G2J07?-D-hh$@_=i1JhRAK~L~O6GjA_hNJCv;bGiCi9*B1QFyn$Qr|XogN5tr zJJcvG7d#(mc{~47P0UmNx7iKC{sMomtawEcz32TO)UV~}8G}D$-2ND9MSI(HgfCrf zpuv@uQoSf!4A(+-XE>g-^cBLS^X|uC=KI%YUNz(xCcXSMJGI^1LDz0GJ~6+*Wv)pF zlXunt#cF5Y&D7eWXwjk(fpnNSuISq_Nr54wh(XN zeg>A|mlXKNOctZ+58T7dnkejjSoEo)&W>x8D0N4~GW7Y_;KyMjYP7JIq--^Ts>TBp zX6%FzuX}?jyPs-S^+*+O>(_4N$lS%f9c$CuKBsdR`f|n_|*1r46A{s$A~G z%x?)XoZh{EzwX&DFK&{2ra@onIDL(VX7?=zuzwlzFITmYj4rm2%Js<)*qe_gwe0Hi z{wgPP&aT;o;D2}&t}zZ{eele!=l0ul%N*wbCyf+rqm>_N-p|KVYR!xRh|jd{Axm1x zn=99s)Da)h(cKoecyvTDu`t3!_`Z~)ZNM!UDWx=3n9=qlJk~fErP|KVnx`UAXo(oA zYHi=}4j#Sq$;kBRf&n(}w3p{t7;kGy{`ja6cfU%;>4|ymoe&P|U^ghp0bti7bJ43S zMP*~oat!&(PXiQ;mIeg8@={y+=12q0VO;qH&evzTW%dEY)!M{0O7F`l3@}&?`9n$H zTYV5rC*#F@H)>0;_`{5x=fkxiF7_8|S9OYiODlOVcFvbE7owNId279?Hj%S8p(cta z3Ut2q&l8wVG;f=cB7r``cd3nA>S4CTyVN80Cr<|HzdzidQ~&lNhv=#QR!VP7!Ojsy zfpA-L?Ys6UBV+%XC>!9;ner73R}T27-1@*T$VPueVgE}S1H;=1f_}jhb%VPreM*15 z!gPk-qRoA4v-~7i8cJdLJEm&&a7JoU?$&^>boe-|6TkD~RCeKPbXQw{*W~SqxzAmC zSMRIEJc(KBuR8~o*;N=Lw*r2Q#B(Zc_>jDuS$y%o5_9!By6`BTE`D8(2>KpM8hQn9 zTK%)nfPtaWpl?*S(CqtRwJ+xSHA&ny_opLVe#9{^T|BwMJR(kGJBO~mp?Z+VTS1|!SgOHuZvXAp-F&g}Xzrt*v z-a9{tk&Cb~v0WVfzAiHh+sWBzG&h~L@foSj8S;DIMp_)C%GVUKGQa zMA-jo4ZD_s$n=}WPqVj-SH#aRnLPV;xYp?*T?+x&+rE-j5SC}FWN+$x(!a_=MyRdO zPB+e15@HJO%K_C+Et#1%Eam?|%@N zN_pUhAY<)<0UgDyOPKJjAv58wohqn>yIk`9NLwJM?;=T*a*ua*-q5dndFiYVfw{KE z!E2kmgpzsQu;~9JDQ5i%d__ATe?7>7a`??)=*shl+I4NTZz_2bPdblZv;@$-It%Y_?i|&rv{8HEOV`W z5^3Q6wqDY08XOqG=bOCUwJkH0yaE3a3W{{{#nobQYg)9hG$#n(il;wAbPT1a**9sS zjBc?^6ebmv-+6X0z>)qnea6uC=}7Gxcv(&cTMj-IOb1)5!=HX~E^0#*ZeMM`U;1V+ zX?%Qjct+FI<7-O|&e!S6QHjCfqle=D{zAKc`uaUWdYCHz3+)Q&A-{!FZoCx6#9&~n z{?)tOtz5al;tt})!NF2t!ZlA@)Ws`!K z12LI8IFwloTe{CeF#daN{P&l)uivppHF=oFlnHqBy_*`TjhaD?GFnK_CpnV%vvLkY zlYXPOeVYBY9Lg={G8^_^sSEa2?YfXBY0?CjzbIcRZcAQCUV?>8H>Ph&F0`++OT&u3 zLK0z!VcI;IFVAyn8dkO=nVxO;8%L70r4$hU?>u_~PNlqxrw7MU2gehgqydZGIHFB< zBZ3%C?<>3Us@jMwFMqau{A89fGh0e{j`|&`J+0961qD^l1C9*v2fu+ud?2Trtgkt`OL2`hZZtpd+M8B-uWa%PyO&3EQU*;7++UG-;yuT8QErbmY?(I|uLk|Y}wA0+$45)7% zhPyUxowt|YN%#J)81wJwhW)pK!57Yr4;t>LG0RXf*^|!QgRFq>SQ9N(ysuo!4t^&u z$1jJTO}!_39wBE53gc#JCHK=`ZC|7pb4E8Yj0_BuzE;hz?S%S!xb+yyUTC^` z7&jI{cFK6XPNbG!%>;2fZXSGbE#_}BhYV=CwK~~O4js;3QpR#WHLmjEOVC8k2CiK6c)(4qV%Z*HiZZ5E~zzdl+f#J4KJTyOA19>mMjWcM|)mpId z3X4Rlo-hq%z*8lPNushNe^bcM zhXD~aCeQdt9l)l3;4(G+tANR3V)UyIZwCER<2vtW=2lx&jgkVvwv`xTSk43)F9%>S zTYv8_Kl<4Ir-;2Ad4c;X5o`CwLpYH9`26VBo@AVH&2PN$&4`J*u5CD7Vq3b)oe(upitrld|Z% z%KzB11yOsnOZmUn+F0~JiN?y;#)_do`Wni~7ne=u@lBSHnvKR8si4CdAY>5yMBadE zoPE)`(1Go-{XQpL7SHS$QcWRFM)O#th|KG!8)m~h!VQs zE5oXlGPw{Ej?_yv?z=CQPA)C2uSmP#NV?sf2XX|77&kEVbq)qsJDzPX1$~6A>Ax>M zex&w4S12W@%?wwHb=Y$2Z^DtCir{a13G(_$XxL*Ny>ry_ho|2u&&adYHyPI#K8okb zI(4{x-Zymbscqe9hi`<_kk~Wb#Q35Y?X}hL^@zSNK6NYRUpKo+b$;eL>;6BL4?cb$fY>V!1mrIyZ;=FS$fzi*$v^(!F^P{MJ+x*k zwlVXr#?$v&xxgA;uY7LhV`rJ8zQl6LZSk7;0${u}|Z;+~IPr-7_oBhU0 za*noO6hDw$gIxVFgi-vz3&8dFRc5@lKOdbxa~<@FnZZ+1f;#wl^CZ5+vB(6F9oo?^ z{~54g+}j!1^|3|_omI9_U7er(7|QjmtNPgL{gk1x(ikz5nfzT2-eM=Y>j$?#h|Bih z6j9MuyS?dkdZ5t$2YEuyH2foAM=bo7)e#YlgkO7+barM#Niy8A)%#(!+=3wBvKr1HvX7~*w?0rt069-aH zH`HUm8qsJiB4FCZQ?-6Xsr_(&3LNHFVw9+fN_q5xx@C&(f$$72(2*!_oojG?HFh#Yz9q769LSbZ8 zazB5>lAQbr5&xe(p+GfUcn0V2nB>x45f9!|`7w{}VcG^f)t_zEWAAbc-n<8=i7}L0 z(R@v?mDUk$Itrifss?(}XygQcQ-xdkK!udp7VIM@yQpOB4N@5CP+mKW&*#)o7R|}D zT#RgP$)C6uuxv{wcZc~OeKo2E7$FU>+&Z3Fc6w7-l(2N@=MXCU>7+=J0Z*{cz_9wc6+$0pqq z#A`LHpEK@ri>lN@pVs`$(ob|2?`QeTWXyM)A~!E7DINv+#T8f0sHC? zRt>@{)o1c99=OH%LD*I2r`ef%O_ig(+~OFPXxJHRx}uve*#)-+<_%mw-udoo1xO%a zRGdW=JJUzYl=IO$w7A+2MKCD8d{QA6kcA(tJnGBf%ZQE8m{1^?!Q$ImpWKLkNkN9E z6_%jI-#)1J$m{UYdmBzYSz0k_Qz{&rBFf%biNyq-QzLAip@+o!XZ}vV*_F=7>1FNl z-I`%p_k>D`IQ58y6k04QRw;C%a5ZTu^1<7i+`Ml+evi8nZyH;tC*)1Iiuk-@laLT6 z{Fr`Wk5;b$tCZ~5;WzX{+TC#4?dVI{4+AO~(UJ6(xMT-sPHxz%1*y^UsR>$Ph|k)6 zKzeY|1-GDw(kk_SLe<;#mCZNW52v(S7GQNb!O8}#@SJENk?PY|Z^E+U-L%{X&W2Lp|?1_%SW7Y@06mG$gMg|Vf zo+0iJchbK_2ss2ht=e#43_T>!XPceD=++=+f8a|=^r|%6o=TZ8f$Z)m7^Ct%=yy?&PXsOtU^pRc4iI%bJj;x8k3>Kel2t+B9 zanI;i9978Z9}H2XT5a4;tBvJ!U?a)H1_6=I^gM7+4LuLbfsrDDjD8zKuBCYzr|`py zBfIu*G&qfllZ{fD4=*=T9LssAAPWl(%gvR4_ALs+-eblkNKP1PfwhgT*vH+IWkXPD zW<#J4&;>Y?jOtG^K=eZukDOl88L5772oWmH86LxtO1GlC?y`s}g4_Ip_X^A*w$Ns>cuFaa5`_QTW^8pVF1An$rL_(5-O`I~cZ=kpvruJw*OIZG7 z@`!`7`Olij`x0cQSfzOfs>?`gTI{A9e;X+x`zb;~LYgoC?Dk}iXP3-LFz$RG zN}QtQR7BYSWL}K1)w(2uJ&oK7ks@ib*7pCbxmWVuwSPdYopeO76+1K(^XQNOzi<(L z|FNEIl<((2q<#{I@JTWsAyJz873Y zY~X>2_BdPLlSdppBML4?H(NY7zl4R5${Vn%%=e5bulkZaYT#uPsSN*syI-IVLfv?w zF5NY2Is`N9i|v@Oc%xuBNR<^hafSOcIG$%~L&>)Xk5kIB$@+~H8MiS~a~eXDKUAkg zFsdi!8mA=rtLcxhic}EWq2mD_Md)|5?LZ-Y>8J07n2DUTEqD4S1%zJs@PYcC>(w!a zx8bHeI0Z*`twmjQ)I_LO{S^9Xd1CD~g@+(Aa?9)i7OeOO=G$6@1l1dv?KZaLQG*kb zLllZQx*EF$dZK9uNOYve7*N@R+tOoBHU0Ez4P_A-!B20;A_N|Ol4HR2-oK7Q;|iyf zasBC0J?rl&Lb4RL$S@n!-vOY-X6=ZWjQ}iTorf9NKZDVBLPj?E}Tc($fE09n0 zjm)Nl`2=T}EhhS||B?S-6&gs^d-|IZO2D6vZ(|Xmp#*v*60x5;%)=}1Lg>JUdH4B8 zCvKydc5GT)5bRPrb`MVk$Gb->wh!T1juPNNTPF%qql0fNV{+U^9IuU8;w*#07^F}e zB!|~aZE|*_)x_#?c+#8Q`drS3@jUAne!;qLkP4^?5##EPd8;M4-h2i2AJl_#p_}mX z>F2d?{%#vv`pnbwDWN1+r&&@T^|CKIU~3Cxorgz@t%g+K1a+ktw~l8>?tGPWHQm$$ z7vp_tyo{>kVOVo=L)~quXUrdVmZ?EZj z#oYl=ruXf%nOUB}z8D3oPmR%A9{dx!3$J;?RTqs->s z=RTyPmB5j`MWCn5TvpVOC6fvZiN;W{hawwz8w`T8TqAX;y$<8L^-%=2jzIZzCY_jJ zW_1){tzPaz7_&-5!ERJM-15Z8hd+V`$g_pG7Sg=<)3jegri}tg7JhoY=0VSX;Zuy{ z?jB-~#^ZlU`moZ1L{uc<_qQwrr`P?$o>FA0eJsa58P_<&08XD`sVNLc=H34DB>Mi=TRPHFS(biec6cPzSny1go| zkE+qdD(FdFDaIpSQ`}GjP3bOLyQ!;{z&Y46t^q6_j;*4q14X=$OCqP9P>QQTxX#<> zuHfx*oDup6*pLRXgAIXguSTU?*oPS68Qg5R>kLK&rFylG&OUu6lNi30etDSgT-tBu z%&z2jJp=6FrAXVC5Bdu}lfC;xL@mfO;=H9TS>xqCIz$m1j1_N0onoZ;Tzu(ybyPq!8JWnDg~BVQ(kDO)Hea7H{u z3^|l$v}8g0c1yJ}TS|x1GSmb&ITc01V>wyhlF>^Lv+)Y{D3luG7`y@pqs^z-WSQ+z zTyVw0T&quij3UDIIv76=P=uvt;F~Bj(=aGMgMFi#jnY|ihQ_(r+6PNw%8D|U$G6)t zt`@A%UzoFK9kHW!_KXxq)Un^QYa!T30_1bVGpN;(4TJ62dN>OUdSJ+@a1}PcZ=oN_ zu6?`qhnS(}WCen39VT~k5q)ZnbUG=J{$7~hzR%-kHs$tALq{)oEAHa@40NoxzA+XC zHp88qe@u~AFL#ee{SAU)l7Y93Cis(7qV+7Tjk08^~g3R&zWPDxN^ zH5o0^>-AF;@eJcJNZ-pm2D3g&t++r?9OI7STT$Ky-7>PtQenxSOy)s7*+k#ZCd&?; zHIM0gy;KdnUe`(&MT;a*v&Tni7ma+3Cy;05K}Xfp(G@sJ#}v&2Q!p>Q1#83#eZ$hL z2b(@SuSC{?xtIUd|Nh;Jzu!NVYRvHGd^LIQsA^zixX}-|185571`^|F+U?QD5A1Tk z#$!SFg1FvZQ9}t&4`mM~_u@HP0<-*C#%@!cKGBbc;-)N9Lx1Oe-7}-Ixeaavzsl3X z#1}BRhFZpWobfqeOvd-`Hk`RL0NZq_huR47aCFc$S@OK7_*WP=J}k(d+w_yi5@vWM z&<;;(C@8C7vhoS+O1XC2Jv%Fnhefd!k_-O$RfC-o$7!&U$XOI^pyn4kK;gorDQd`g zFU7_1+qnB#R+{dVu-e$}c>*(Ywu?f}}(if15d3Ih+ zQT^<9l=w+T0~ANpP+9#G-WQ@zL;XJ-)B;mXyw!+x?}hnli9V`gddNkg@}QS7-^sh?rd zUteBLT@Xeg=?)|&+;P@Up%P9MPgm4w%o^5v(ROYC@qU%{UUw?QR(?yuW9~>fLzy`M5anMVX5$}-tV`7m4FeZ zC@D*6xAM#aypd@p>~LkXPlH%7^I2cD0A>n5fK%~HJq`nTd0x$Y^>u z|Ip_aB+HmF3qJ)}=c>Pzi6lxv+P;AB$EB(>(t(R3Fn}>%U85vpS0IB*gl71=KfZAr zfa?+N>`(Ps;kZgDiCB(e(YK&5ux@iGP+Wi9z@&fzOz>hmv-fj9K5|;b)*bksZQM$1 zJLB5>Ny#C~+kdajr}21mrQ?SoN1ig$5u_lWQpFP(!(*r&Ip69D>$>#`boUi8}CjEV9xskm5GMs;vbm%c&sW%u}7CUm-nVQ? zl+fpiI(*k;lt%WdHzXxop2`-GHROZneD(5vVSQw?Y>y6YTTKq#MO<6>825h=nVEMafn@TT^EeK>JG&2UbN-) zg|sbN@QCi?vc~E(uipa{mwy>3P@-$RweykWqqpSHS5Z=inc_TlL{-Wb*NFQnb}b!{ zzfe8JD?Vpf{ge&u{ir#3y6MR9nu&vED5PSa@b~t@q<}wiMLXZMrAqFIqD-&oTfQ3D z(tetC@dOrnzQ@}6`&(X)t#o-&P1uQ{%A1I&^b1l#WH9=Ehe z1aGTb_N0w&nQLs_M&G8fjf=Zv_WgdzX;T;pI+3er`2jd$v}b5sU1L~E_z-Qc9I|wC zn?vcWC+UP*Pq~o_003*IOyAyu`mep8Rnh=t4j5o_Jb9#?hxcj705_2RnpXn(dq<_A z=Sx6P>3Ny`skong;>Pw<7sOWMPr%3UdB{k2r{?-2YxNy2Tl$l0HcKMFs48;ZqK;r# zQ_~v$OA-kKh9jpjH0mYNr>%7v&^>x9<3||~8L+a}cF2>JiWsvg{3e)f9LO+!1Be8O zG&km3^@Hp6sIS>Hly5yMwxa>iOVepazVcV3Ko8fuhSLy&Yx0RBBE!QA!2W>jQJPMJCNl`_&B8f$Yz!TGmn%HNGFzIcGkb4}@K+o@3OM;u0ugV)^d zw?~0u)GB#|o0Kg!gSa;>jt%}LyeugG(R;wUSRPlH?Qa&P)pg-AG66f9lo1d0*Fk~2 z&Xm za1?3rWosnIvTGZg7DI?H2G$@|H56^$6i&Lq(jR9llOBf&fE1t9b5~tI_YS)-)!0Bx z{{>b4sr57yh?71$Zd-Un^h^LPolazeu8?u<@jg+?I|CT6nQQnkzs$WAz?q>@{eBx) zng(j29!(J|?OFD`od#N&z;SfSoFMH8ssGs@_77JC#<+AzpSokhDpJoU@q4pT`~&^6 zD`KlvT)3C>4Vj8G6_jKRne_MW8xT8b-B?@4{dGSYrM%rWq;#jd6jHKik?gu;j&TBg zF{Qi)ac_=$uZe$jAbrdk=~Qc|p&kRf9(s%t@E>>3W=@~oIpAOy*apczGDFR&&3 zB|Z_mX87m(P(TGV2)*6T3<1q7nT2Vz-1EBz-)g70@Edd6#ku|Jh0^Z1 z{HPYBk0oQ)P*dmNLfQ8KbMQ4eNs;l#VR^$lpo-W+qz{|Li6SH5*L1QAvOx5tmjEe> zZY1bJAlmxit=1x3WTb9AVRaZrd%3w(%*s2MAd-PR>w=-bzONF#gsT+ZzlMb(mgVF% zZH?PmU7Ku*cK4q>`!RVwcz@MFIWI?ZZ6TZna=GGh=iTy9c5K^n8kQS# zO)Y(PWr&!8r8hNgOm^}NKi4P6sP*eAG3_Vrz9zlzu-bZ)gwmI}a{pG16Zul%a3loyiS!lNcI zapzbGMcp!}0|68j>07E?dnT>|$|!=*kt^Ce!Is!YG|=o)Me;{B}_60vNeqOleMN z0YJXLKgC*R008Q76tlvc&(2YRm+}JO?OX1mz2gd}dwrNlfHckD$gs;qeJa7y0UlE} zKv9E~m5DUee~Cyz>8yAoj^0dV{I+okU(?rt_cP^<%Cb)$0TR z`5^Svye`!GOXfLhw0{3=3Hv8TGfIQMd$YuNDS}^YF)lj&IC^I83ttpMGXbZf!&&)F zOmgx=S{Yjy8>5RbrVsP57z3m}?U(THH8`>^pL6fIxbXLRroZ%zK}`TuPg2_e6wntk z7JzODXRmU;kruxv_=*pBDl`>pz5qq(CH;x`cfvI_bfOcNhk;F`;>cG6GYHW{p}Ric z9${L19M^8~w3`}Xs0*=+(ipenLDzzW>@a7hwD!)(J?7xY)$hXC6&Sa%#b}-%%9_lg za0EmNt;>sVgXyFWtXK#;Dd6>Ki2Ftw0}@M(_@{L^lD7hgX%a5(Ad}EZb}ejLgC|%7 zh5*A5Fjh8A5ov${22uYzKHR3cy@9iJ&5hv2L`LoB6L`^#lACK=Y~h zG*q&127_8OcsclNyBS5E-;uKF{E)35|XS`|=as?36{CB=YOLE}_bz*F=}G_Z}f;Zhv%Q2-6( z2ADi71Bfg@+Qp-4V-fEIO(CkH)CFJF7KG3 ze&2yV!2^3!((|+iWFMMX?SA`j0|HAxuKKsMN%jdFdP!qUw-l zBGe{oGcE69)m4jzlj~PZ4|ZEK795;soUTLSB=5*kYojHtnSYKmjT%2WI1|sju$JSn znJA}Ai^`E5iKw30x-;p!t8wLJQD%TLSQx4;(7}ygL3jz#A&{QqX5FYC0vrmCQGocj>-<(~jZi5Z z?IBoF!7qF%{zmoYUQr_&nzGA)H04z^L}d5k7bkIH%*{eHargcbUhvBmSt!e^4jH z$%+iEf;Br(H;?o2qSWA!TwtD5-aA{(h~K5Qtksx$E~BT z^Si*xyUsEo&CSIHtgdqwNI(#5^ZrtsRL6!}?%_-^W+BTypl5J3m=5 zAg#`ayV6I5ODn}9mnKne?iC7&YR<%q_vHMmaem@bHI)in`V5ZWFz{@$%+Jqnu6mY~ zZMV=41dsKp3&)Vyv~+|>q?;Mf(U|t^1&BO==J7y=(twM~Xk{Q`0MuIjXcY!UXx9an zWAxguZoL^N;ojhV^y@kREfkyKyvP zb9dqJXg5E)v7`83kxWg0VO~X?tUHk)v;a%QW27&u>HIBD*nXKBR2m;and=bL7O2)o z!hzMPkKu@kd>x1_)#q6J7gVpXG_E;0C7MAj3S$< z*{35I8)iHJB?89d!`Ip^?l(Am%Hw2QYN+A>-t7tqA-%HYoT11f(>;5#rH6Zgw{Z!R z_TW!tk7^cO$NudTC1MZ`hJmXFv?9 z3(FyWygrj~YGvG&W*9ij5+l)r72`TTImbJrbY=Iah8;2L;Jx}iyau-aQabfe_VA{H zk$=SNyKpIjrXYt^(6N?UvO50KHU7+keD8YklQN&nU#AWVr z8^r*@aiZrgf(USM6abh2$V=p9Fv+{b5@SS46>r4J;6IIXx_ICMQ-T{n2C!iO%<`^- z48T?XLSc}n#5IpDM{T>s0L@e%E{#i6s%QeiKtYOnHDwVsyP%O$1!6;hkJ{;VB68ui zV%;GIh?WcZ#C^b&y|IUqsoT}_m;hfJLe1|5PjP7xh7r=Zytp5WDOc*K*4Wk8JC+Pp zTs8^{J~a0$m40LikULu#xOXFwiYF6fmySXQm&mvs2tEEA*eIp74s{0fPoob}KccQ3 zeX8EP^;3LV;`>x6qnzgzz4HDUW^*BtJHb&?O>K%6D~l%0VYoH)&9Y|^OFR&+KLL#5 zaJ0$NYS5+YVa?A8Pu2$@oG>Q+ui6&dE|%@Fgi^88rhj2Sct&vA&l-(*27f_60RY0h zu4o?94#hJ3@Gt}bmkX@9_8S@dzu$r{|Drhn)JLHCFM5cmNL=`fM)X~p>U<2*)3VN2 z|3FT_e82qgzupMq4Q(o7?+n|>aDd0=sggN>%HV`zO^(~hMp!POHUPIoRQ4Brbcy$3 zoY2hx=1X4nNwkMO5%Bqf4Db{{&5-*11F-SnPPhP-0Kbz8@_~y>2bp8m&WK~LQR!~B zKH6dQj(R8g1<0xn_1-903FpsN{pNj}*ZXx?Sd7XC<}G-Q^sP@(nRG2p(scv{Zzu@1 z#5^15=?ugi8e~DPUeoU{dLaIOom@oy;$6O5bv?~kROb46#O&8I&cR{Et}}ZQm4Uwb zUY>z>e~x%0AT1~Ps7puU{+he^g-yk<*&djzQ~8+&kwD02tI=nM<-6XWP45P3bH5C4 zR3N&GIcAHq(D&KFO)h^^g{vRM@nh}u%QP5xS-6Nuy=USm9CK<+>CXh7B+j* zo6>b#bXvvJ3`YcJxMhLPGi#Q@B)qx`bl(LfYwE23;?mXZ2P-74@B8-l^e25LYLJ! z0{9J{lq$Y^Bg1hNwtHjAhR|HG>;oDkWJm-JHY0myl;0Ezyd*1jJ=cyAY$sd!tqP@_eej9jx#@srSOHym>aSO;`Y{Wt=f@)&o(NT3Ip|~y|5ni%q2A8v6zG(ccd+7r6qiXbVF^$P3=%VlcDkI$N2B=TN3IO$7-mlQ%I0=KSl5W%evQ=${-nz> zhcfNKZc@}mUbobS=UD-V?{=}L;dC~{_yf8W-Q*(d6NGCrTGSj`G7|uh^}N-bLuBC4 zHk*NMhMBgc0?bdTgRA}M9pd-z2ooUFFDJH zxS!rD+ zPy*9#eVAMJ%N^4Ay51xVS2~f7qAhUkx)I_DgZO_ z_n5)y;qU$JwkvBKUWIFE#3fH-y5w_ruIJZH*mvh^f=$oK1unoXw~?QeDSOssyCWt7 zr_?wSxj0ctAg!g@?sD=iDC93bMosBVo;OQ)ks84ToWq{Q{hefX9@mi*p44x`*uM)$ zvd2631;X@DrKi?m1^7(6qT0o!!QG#UhVw6gFT4+!(M-+Vn-|UU2?{ieXMyfnQX=9< zCEkC&)V%F~n-LLj#C!QJX+d)zk)Z5@+|po<=H?wc_9h6%m&mhb7`T|Vll79&XfZiS zTV9mtlKP?o_z`yZW0A!X#Fxm$c#H@3dBpXD?1eFovju(6j@Ii-z`=ok>@#anoaX~1 z%1k_n0ac)bqy(OPS)+HltN&mN9$~^ilfK_bZ87=U;&h%mx$yD5x)(@^tn;tj(pxQ7 z>r$xe5Oj3D_PMCPPI#x^v3lXCmU-{~`j7eyx|^Lnc>{A3h!KZp^$UC^+uyp%lOq?K zIP`rsubgjiHhua1gwiBU@wTYwJ$pR$(&3-9H#=+R2;YCx{G{1ncluh>ZT$tjoSe0h zUcq1D@@zEDx~KOWy$4>f=1Q0>&a5LWu>4BmKpT|Tf!y2n`C4I5&fmClmjB#%<&gQJ z*fmZz2k)$(l<}Y;rTp!TwjPI0BnR2<$>;yb&#duJPC?iMq?6&)gHX`bUbu|A7@hV@O$RoebUDFIPG!)CT*Z^$Lq0!xKnJQxys0(~gH9F^iJ7jc?omE14>7;vjX^h*`& z=qhYEp<~82^3Y=;fzc0_9uklZabtnX)j=Mx>DXkIJKoL03R(yE1ZMQwx8eM2Nd`&; z|D7#-<4bOiK%l~uU*eAq^nvaJ0}6v{)#%2Xf0o}=|IHF-s()T@E#mRaD5A3G^%^UK zoYbql%mJsq(w|Q+%^V#+S9JI!+WI@;b&dVnM7oXi@dU)(^9-cHw*zEBw|B#b+Upj- zze^$4`ZZAWc@`>Nm+KB>!_E%>Sj1V3zkf&hTWfV$opz1*U=U~EdDaPh|NbI+nYmS6$8pj|DBlK_Oe3( zs*g6-zwK-I{o8#5zsg~TZxOcs9@AEtcubRADal2rMG zD0(h|5yD+)nEEGcdyX{^KX2>IPv)q9gWuOlODscnajK>KKQedGDB9Qk07~*J@yGMY z#;;{lmi&?@EaHO+W=2$GUQbQRt>>13{1Hbg5ivC72ta{TDTzV$7l5>Gjs8L*)v`bW zi;59);?~(Ir}6NTv*^S5P1!U4$%+LQ=b|cp#vb9L-e2`hSHBnuxPb&BbH7;&u0BO&Oq8oGjHymIA2H- zBc$_?>DiD)>VITiw_F3rgWI|G%Vp*cM)&~dVy9yxTXAybTbV1n?##~zIySfy#^$B9 z?-#4m1O}!GwlFC#;1w}$wE(vC`q!F1<*7uqYFn=JsexQaK&BsEDaL;$l>9aa&MC8h z4~}$od_Xv*C5#F8NC1`wgHA=+%6uOk&cHU(3knUM(&^l%3FUX@i=pUaOTu z$?2uk>Iqh*vqJmpvL5(h52_X{Y4Abin#bFOtfjSVjR%87ulgYlm&WP_&&w9*&CxNx zqI^wn{&&_jyH^fo4n_CSzj-MhcRgR0Uyy)F!A?p2k=6L_3jTdVc(V<#X}o5mYfW7$ z{TEghmL-nWOfw(aqSr@+GN@uF+81tza{Pehom_P=ey76=rTpA zuYc$ZtJd3c*Jgs8-RFpI{6!u>|G~}RlnVgUw-*dfKdSg0f6&)g&3$+ygL;TqK~96@%Ug_E4Uw4}vXOm!J=zaR z<=yTClq=Za{qdP%lb~x&IcsWZ{ul(ymr4(#@o&Q2;)6jMpO_cz@scxcSK!WE2DMx$ zq7U>EiQVB}&V4rT4HOQ@Cq7!a{l7p7)+^HJ<^077QviWbcA7NW^148LwYMfF*ul0o zs-Nc1pn;E_yg4k(trm;}oGdnX)C6hZZ~#cHB!sDn6Q5uORQ?vXnwN%hoJtYDzWAJIy}R7 zxbDrQsL80+S$9WZr?lAZs3fh-^2sX4o|{F6i5B(pJRG?Ti6zwK_9=hzU+ty0^c?;n zuQT_)3h8$1RqI8eiD&s>8~B2z;q-~Cypq>v^-H~5sLh|{3k3Y8k&hX`d)LPAAaLZ;>}9J2oSXkx=$WZHs`>qE*s4!=#)h-ABzZJL~SP^Q$|-Jz59E{oWSiZG-L;2TnF? zeiqAnjn8PHkmsH%nhT_s*S1Q=#%R0y18z$NMB^Gs*Nwt8&e;q;*jU%kD zj=%i7*?+YTE`oFnUhZOb3>GH*JiW^e2EC1)i3KaC2bF$=qr=~Mu_1JK`n)p@(yQ6# zc5pfC>>Em+3OU!kq;ERDqik`83(eh~m+0-cI=D27%ZRV}10M0|($lzV|H1&dmU!#H zE99+b>wfdp>o3+Fj_`ffuPa}4`oCMh_#`23G9y^R_(Y>-V=C!wXW+MNqfJ*&1f8-L zXYs?P!-i_z2QgkMt%|&bA7|qd_K`h5PC_IWn;9%G-VOQe$a?%a=ZqwA`#~Qy^b_y= zat*Op>ylxvb07?NFu=mbBkbhXjS4ZigOGDU*ssGsVy{gynBZIB?!N=@KWK6B@0=bR zP!xn$PyTX24&+{QomdW1^-f$|UfvBbDMmOl;+czOdXG|K$|$NgYOACBA?{-JtdL8$ zo3@F6Z2qBY=p?xy;|lJdmlBJ^131ckYgh`LJ6+;iO0&MRhj%*Xxrh~(_ol_hyk|xq z{b-_BptcFW`o9=*DS%1B=A23Esa(AC)Q3Vk!y#>%HNUFE=&gw_3xuO))kv9ZMBTbC z8U+Vhp_v&!@_oW8sp;{7s2olQdOZ$7;-IKjr}F(qCuf&Yd$&HF=bePoctv=!1d(HK zgnT+jGlv9@?~NK#aZ6X;C>D6~?9amJ(uIIc!7-2C4d?$u%-tAfHKJWZGmAc@9!Db` z6Q##i(?y5d-P0U(_{tD@@d+emmin1`L|wXSA4dK~d(uTU?g*oi#Bnw`!7l2%NM2o5 zl*{t`tsKSDpNy#h(wSP`HDb>U?5EJi&N*sE=G#K{p5mGdTwBj)J>Io18R}+_(Ki!6 z#o_+~m)a@3`{C19@mJgD{2nsDn|MuYquhC@^pclLrP%%o5cEIDO=pfM?5SNn{a{*^ z8_*rsQnTMFd4gK)YlT1hrS1r&KHnN#lJPw#rkfub7T{X=?anh+26?>Y>tL1X*=X2~ z1Mp+f2jxh2-1^iXxruxQTyw>aqpmBfA;BklqHh_c&+!{t7s|tJ8n?BM#8208-Nc|@ zm7>=}g^7J>kA#*6L!&xZE)n+%u|k(lsg9^;OE9l%%H;=2gZ3&J>=(Nq78zGg{C_w+ zTV!jbftTkK`c?S0OkW&(1nSUib3QvELhpHXSygybgDd%u=yYt7z&cxc$Dl8PmK$Tvy9@(S4$^&t)0z2x?~b zl}A*>g{MD1K7&h4i4-mjaHi%W*A0pI`1&4M=eHWVsVnaa+->SB?F~02Q&ni5u|Cgg z3L0pse7VeBhp4yNx}co%9rkiaB*W61g1T&{qY*;D=IL7HA@MYwU#OEis=os^Q<22 zB%Py1b{ylNU1|ZW-lp1S`ILeU8ZCxYJzI(}U|;VNCBGP^pFbzN_kLW@ob74yp1yM| zI`QL6|IGO-zYEq5~qipr3{mr6w%9NW{aa`<@K`{)Gjea;-X z!0Hjo`fsI~{?N4An|XOSUR!^5am3vn16l9k{X=tLc@$;k!_$+_nN~Z;qE=G1xHe^{ zy1mH5%{V(Sx5>_zqSm-?g=a21-Z6FmqFZcM&->|F=9ouJX_#e;m#nYCsjvCURy}8i zQfB+-7(RMG--TF%qj6WKc@jJ5*2lp%@lcE3^iHx{W+76Vwr5AzI|)w7ogthpg67X+ z=_0I2A$Qdkuegf05%`zDpsTN{2d=zT_8b~=@wZEw>HUTfW9E5Yub}p-NOQ)ST_zHx zvDiP#6`E~KKvQ>|8L#l%=o+aXkRBTgY1eycFSON+HG7*L-P1kO`;+Lpbu-4g z7)RAW2n+W{Ka%{ZGvFdhEa46j{#1GLXf@9ijekYU0{7=l8hlj(d{3sbo1ah99S?Q7 z2K$;$*d)BJtIp+b-tB8R$%kh&Myu7PB4}#gB2)?_&o*g`1NQe9O$|-DryEYV1Oyyb zzOfgX8>$aH^51@^CjL6hVTq3Ww`{>j?4;<8GILys6a>xCO#QLu8$=rxBCAb~zHf#b zR~&B2^5dsaZEz}pAE@Ze1jI)i>WHqsRX6C{RPY$59^{SPclPDa!VZf1i$a)o&$6F& z!S9!+MJ+!eXzXRNshOtP6@mhDJCqT(YQ2=`eWE>kA2)&J20A`ptFhc}dH(}0JKT4` z%K7;5W-IlT(svaxbYevi7AP@t*`&+dMbz5{!6*6LM% zok^MU6E=n<3A)^>hds4bzBaca9Vt95RjKmrVf?l%aS}o6n`piBk*=*hP_MzMRB`3z z8XoZ;+Pbsp_AMJ3@CFv8hNrcstr#o0y6U!V!X}EXxnI(+c*O5C@WPu#gNRUDr4)27d+S6QvnKh7+qavUu?)IA zrFU5(1_64K6RFX3s#+H=JQ9)R<;s%ed`RE=!-;-Fk#_T*unTLF^XvWDU(&(0>O_J` z5RC*@Y(b03>dvR)4mrsdFi2dyyzh&P6Dfz=i%J9>%=~COy*t0MD52HG65@jvyrf8G zuSRJJKzg_}zP0fP_&wSuY3BA|Cat<;E#KvzV~~DbT}{fp`orV+w?}m8FX%v4Qg>I(o^LpY;CrepdZ1eJ0}FnwNJP@{qBbSHHviZror)e^c}=R{HJQ zwl;0HBrX?U{<*7>fMS1mct1Ob^Kqz<^vfuy1cC9UaXKV5Wu4ONVKWoi)u|?!((^Ch z%$ePAY9AVk+<#j{;KmxKC3PaZdUK7rWKCP~rc$EDFgw{YnWp@8rB$+k>;~zazA1&5%sN7$ z`|T?I{Ct9YJXMDrPtx#%G8BZUNYV^nr;Gf~E}t%r3@j{ZyjmhAOF)0~aQ8S*}@#ZZ^i<3eA*v zQyS*P2}FP9<)P$)etn96FgnM_TO~wOKDNN{Tv=^UR9`oU%SHxcET}7voPI3H9fi%O zZdYY9Yh9#suE3;GD7!o;wIw6OHL#?xo2+fGRz<##JdFGKm^YNe`L)M_VQk)t7X->v zGe|yGjpK~15bQQA2~wJ_5D$O$>1r;8vj(xGF;*j-)qrVRuoMjW=p&LE3T3JpjtH6V zM+WnbcdxyRbeGb{s&?3x=80OZsi+ztUmr3PboM2g6M);=W8rEsHFT2ve?I3ZO}`g+ zImTCcke#H^_$nUxXq)d=(&q|sD4I#xg^)7>t%{_WTC*nW5_J9dr&l&tak0($Idph{ z20Qcs3xDoND5rKuT?{dAts*ibtuWEx>&Qq)^IbWyX)o3gwz)VvkTAu~$Ddor7EL$G zYpe5E_VrYk@)Nn79<`xuH^whAZj$c&q&qpw5+X^-fIn`VP~{bSej)6mSTXJ>({n4b zY2_fBsOJ>76A+PZDKc6%F)gvCEgx9~)Zpwr>_7vR>%{1}hP@Imi{ugxvzpx@k^0M` zB!TU8K70PT$@}-p7&?aRt{%0yhur}D{M+%k??)L7Z)$_zTyP-{moOs%-`=d{3yYI3 z9OAa=S|bBbYRBe1_VT`oB;hDQ)a0&`X;PphyPF?NbFYyp?6T}kc!!QvykOVu^(*?2 z6K#S1Ob$7F$ei06&1Y^ly!?%~ZMWuZxcF6>ad9q`(W;_a3&VBU!yBKR8q~#^mX5=-$d6oSodOPMtNK*a4=-mjM#1E8 zE;T3k@0OXRU5UK@6}hDm*eIk%&DXKm|D5dh@B&76J$6uyDsUaxmo9@2YQzNWP;VE= z+OY@+fA9?cU`ZV;JGpX*6iMZKe1k{Ut67UGu}SLiF8&sFcZ|2!lUk9B`59+TcKg#K zoRA(z)yZ_OowzX8DU(QZLsC?L*Z?1AIQsp(3Nme38zcAdvP(7waVv_Au+oi`CZtj< z8CS_%82O%B|D8`bufmruD`+_kZ99+IqIgFwaQEu(-0+ns3Y2PFEHlp|yGoTO&UFT# z6#hO!Wsp`IOqGBT*S?_8o?pkF``^?Gry!1UH%h<&=O|9w@(a=63het@$SzsE#<4&Xzvfhff7D05r+OGPUr9`u3hLym3L|a3A_j?g zV&xk@<|U9{&}v&Fo&TW{Gj|!xI7RT8O*I(tBv!Df;R~E=XOi_7VSB8;VZa=Bh05?p z=>EOyWGFBO8~k^9!UovWIWE|#ps$Tsiy6La%0GAeg8v`eMQ7FG5#or8zI&SkO%9G? zR)^DuQ-g7m5Et^hCjNKeVol}04PyjT)y1y5#A70;lt)bEd5rzDykc9wj{5I{LSJ;Z zXSz;X6Pt1~*pkHcV#Ody(sx`lt>H=!_2lHxD3T_WyBK+SyoKc*VI$Kk2x>9IL=xib z+fx>2i9tRdDGEJt##qtnLziO|f~&iFi8_u=$Hb^*L_uW0QB-g>r??=puKQb!d*Le8 z=fc|8NGQ^F)ScgiX^vJp%*nQnpei8P+!*m=W$007~EQKT(b}I?iJY0@gSJLP2t4AQ|wC} zA!hnIevS%eDT|G=Nf;eOPC_8bkpYuU2alR?d{DBF%j)F&4qQHF~vtX-EJD{C?qFGLCjEyk-Eg$yt zKe#g?{G;msP;?tQ^gh#)=QDq0TuY-+weX=weQ=WXZQFEo<@}SDMMN%{)uuKc^-Z}qACba(>~U%n18bCV0N(*_sH3f_r};5j1{znxK2q0jg6 z9-l=dDR)7wvJ~=KdiWaYJIZ+SVpDsQ?QYSLAgKP&{FXIfX29uj`ZwCorT zhu@r6TqC@B^QPhFci{xnl3jy}E`+)2#MygQZI$2dpp}9P64R9Edt0*W^SFy060*Dq z4S1D!T=e;^YNTUN9@(A~nRWgcja;XL+FY)80lwkRl}V<#h9%FdV$Yv1ku9NS8J@I? zPKHnnvEJn=65h{0`YgUs}uaVzcViF)sy|o6` zOs8|o2X2Rsu0dDYl0HENJ#)p@o|x#|x7plO@1(44;>j`N!sT3W4LeogpDX1|((dRp zW!ZSkTN1B5>_R+XYi14C+WdOiJq(Od&$B`Vh8Yy%3$|G$3m+{)s5kPg-kJs^G^_aX z>rDF_mtitYS-R?3;?!%PB8E>z*A?P$=ntE@<74@OQ5o?pl~qfb_K^bZ%BwY*VoE;2 znJyM&m(7{i@96gBPpJ0TI>q_9J>l2D-kY4US!JKjRxxWqH}%XB?wS&{W6AhQo($`L zZ@IPJ%`QFlTBUR|oIe@`WfmZQdU?|!HQM&RC9;42=H2qay*v^6!cg5}(e%godgiKq z&$-QIc~=@)te-u{$~qLXXDdzi?ctQLz3ar=uV~mRu=TNLuaZ?Ju>0;U zy;fbmaq?B~hgbcITZ{YG2ZZndmPQJ?n<-bDnq`HUgQek(Gqamib?TqoNP-V~CeKeyfmOmwb5zJu64wjXo zOWLHb`d$}*>{p#3-%H-W3 zYrB|?NxPUv=MQk;0ZZ-}IcHQ6CV*60hA%PE1{T68r~9)H(r+nRU;w=S^=d7ygp%)- z^lfssC~l?cxcsE@-i4k0g%!CBrh5^j$|IFgq^QRcIW$1l?RzF`f@|A&rM=47cHHPa zokY47)k$w@!rNz=VjaSB-XKT)%?G(yBa&d-h zIq3yjYekBOe-UEQ8rt52zursNV2>(dBS(cuWjcfTe#*N<_Bfn%O>OxV+O0j7l766> zu$cQWCXxg`#4AIOo-?S)wV@+W5+82d&8e>EG4-f zq}5Z~_xKwvHM$X&mft(6Uu+XIi@v}d8E(|r%T!xb-kGb@HnejZQjH%JUmN|@{wqV) z>2O`HIXYu9Q84K!;z!A1+3+=FPpegez@I~spSirO?qR_7aQitbaQnO%HFF3VHNTi0 zYIgJ>h|}n2$H8a91xIO<>e~R%cFvRWc zDy1Ew*>^EbZ;C`Xd4MSb`M^K0iQh8^%1fZf=myFaY_OhEp}N|2cC4c*=?}H(x}AOJ zWawA~K8mXut%r?wwlQr?d&N2^dSmT$v3(EWMxXVtA8sh;-u;*>n{b@|!R8;G*o0z9$;P zjSj5xFljmB;p3`oNk2Ky8;Yqai)4dX1QNu| z(y&f};%~nJ$n1R zKk7Xh<<5==mM2*SNY7(0VrQutHUtA+77om3&2qSM1on5b9cY(RVQKGajxKE(HRC|I zSELA36ODYg-HU4G>A9wB+3xM?t%q?uZdng!>s_G`u>a!wigk@ZF9Pk1k|b3A-5V+% z&VC_a{8~J7DrqQEWqn)d{ZS%&tQg}w*G(gmw9&hXiqq&zGdOZCf2| z-^Wg!TV=dEOA2r!xn#3g&d?6lb|^#ShB6iS_BOrNrj99LNCBd0%!a+5MXOWB?dGVq z!~C4xQVhb@1e*etu+4MzSw|v&pw^&DX&UtVq6;6}zY14KV9C0*l@I>*i)S2EK46W??yABd_@WXA z8u^7p)jbmx&Bgu2vcyw;=s62noXmkRN{EN#)pI+tILWrfzT}NSyS05?$DlDhe7y?? zh5XpQucOSJ6&%lUGPqX-X)LbV*h!bTrsk z{`+RA-;48;uY47U?a|h-k3NZh%ThBRJ}i#W9%A$q?rEaWuI70(MHTm1J?bu}qdbz` z+Pph2umYborL=rg1Z%{bv;u2p>st#7f4z9Pm8|jg50emno6h99 z2=|UKQ`G!HraHDy2q&^#=3A7om-lp=4)1OTtiv+A%D$&<&Y5GL>+3l=m=}vX5)^N& zwH2`YqRj1KRkaa0kII;LmdxNrDjYj3Cz%RD+*G56BpCshTYKKa3;6wn`F55pfZkfk zf<#4_qIhjhu`66b&$wDum)Mhm0w0HRm8MT4auiPn(lKv_{UzFTC(B=KfVDAK$sADF zizCc`@&5K%hF{o%#fPR9FX%~Rk8Y5Yzqobl)|R(SWK`7Lu2EB3+Vi^D#hxUbtu!$$ z?O9}LP1&m*U$Gu)3Rcz6XI_l;TF|xBZG!vGoXI4f;Pq;`K3F?>xDh50vr7zb75&!Z z8^+3$LXFzxzu<;ZY?5w8pDMi1`p+)&1&4}G1}ZQ^NRq0Y$clk9@$jjC(LHwNV2FK* zYj4v?JbVq13U0N&9)pZcdV1yTxPZ>q7;9IDXwTjh5af70>w@ z6tmB)E$vqyY;B!2y;5ao`yThQyqHeqq67j6tl4$tecC?ueL7Y5*0H!DB)i4y-oet> zH>cPX`p5K}7XfGxIMa0eVb(V^amw)TT!Lq(zZcCSH800KUqJHsp6P9VK#R*39~^i< zjR%!ZmWsud;|CZK;-KQ3`p4tHdGF2q>}3=`^rAYFdiQnX?)s7`wdI>hVqfZ-!Hv7= z_qPL$`|Ib<;zvtV>NIlOV-twku-xrBd~;|`%z8{(Qr7A>4qTZXVZJEq zqwql3}Ed#?G28v~^sLB9geCPAy zW!FAY0~|p?hIeI{-=4nC%c}StK`GSALhn;qor(cPz}Wa#GujHk*X-PvbJ0XuoL3ZD zgbW2bDb(Ba&o^bE<8UQ&z#8|wI@C3FVq>bzSWM4na4$}55)x_KE-DmUUqZ{h0i9&j zUpx}tQG~e761t>?we!R#6Tbr8&7oPcz$#7ab=EB@!TZ{L!_e1wR%;GB5c&K(smAs+ z_!cJCwzvbC5;UoP z{@OUsJQ^Katao9z#BK~dZg-CQ8Z5CoRSx_R6v42x`#9&sM_0A2fYo9%w;EySH|5hM z5cYe>)(EHoU0)H-c(G*~#4;Xt+B~NF6wOq7iM7V3j13GhL=wyS*gh~(9sZa-B`wFX zQPKQPd+bXT8ETwD8QICO(dL?KgL0_r)G4qT2*vc2iHF<2P&7|$*Xb=?R>0algts$A z@6XeNRuH>*-1R_*AKyS30nd+39)55UF zv7`a|vbA+1$;^Y6h+2Plr>8{s!2?Wp0*_J6;L}slxkJ4e#!N(2RYvkEA^_T78Uwnaj5msxjTH5!ePqx0tAhc& zok8jYrqD2MWIyR4k|M~lh-9F7TLc^(432r!UsA%-N=`Sfhp`gvvhBpjYEA}mma{|^ z{j3R{V69cmo<3U%la^Y(o=F{>WQU~aJAH*-56>C9=-{=-V9#4BJ9*amEJezc_Ln@Z z3d>GGBKs$z5&guS*ff5tUva6yYbM6VM+b+HdX4pl!inEHJzeeN)`FTvkWT>hnkaiM zeQM2boa2t=>=Cv&YLU}5F`+w5A)gBJ1(k=bokTbYry~jq3dY=8Ir>fNqq4JEI!^Ct z9uSw6Z&QS7dazGxU2QyyH8IpNp{(}(PCeUWaYpqeHlxBDi`S|AX!FkU@Q@A8hryIpRjoFNZb1loxl%TR=6%uz)I>1h}Qf0VGrdTE>~_Tx(;ZJs1BzW5pE zBSjH8;qoMmjZX>r$4}EjMBj>CfBVjTpz7nir;?I{ySsb*L;bIGx`UJgbV(0%f4*(x z=sac47;DUI{>TdIf3XsEd1GrQ^C`Q0{u0YZgSP+8sBb|)zyC!o)CK>vaZy_QoPzB_Glp(JH4#_=`8nRXA$o-|9DpMY5Q ze9=Y0MveMNhX>ff3)u0I8SSTGlvXGy0l8A5JisoKA9}Ad&8w7g!AQ_^yUlZnr8x(9 z32&*j4kaJ`n_7k6EG5lrb5V{X$c2yuy<La)`dd9cQ*sdN{f`!v#BHOZOOa#ULl@l*g44&*`Qc!)iRsBKl}2fUMo_kQmGqxu}PT& z6GS7r7IIT~2ArxRAGon`3*VTx7N{Zt4*0MK&D~Zs>F4KVB#W?!THjCCl^z1K3 z{CePxSP4gepLuu({P%GQQ%-S%SQ@vp{LTZjiJt{Vio1|erdAj@nszdMV2~gAAa&FJ z9+DyT`Jl+E1IznZwfp%mi3ST3b#+Y@A2-smQoO51inUSom4gK@`5N6f8e@@m&jfIA zE%UQju^{o(&|~7|kf?gGF5h|~aNM;gWr1m|43a`&0#p+KdoJ!BGAtSL;)et?ASJq3 zb`&J56d|4W>cY(s@TTVef}LU!2Jzd>4(!8YsxYpR;$I-oco+$(<&j$X?pLoJK) zVs{TG(?^i_V2TV4WHJ{$7IA_rK_DJFD(g=7;pNC-U1Kb=@%L;`T+<=$ z(=lhA$%$B`+@GTehbzG?+)X_03`_Sl+cMG1YQ;wNyw7WM=}ve31_niLCpsr@^!H!C z&M46m>?FNWe#snH7I(c|>INt4Wy2?Ivv+2HG^?fAAmNmhl%_T3*5QdxpCP_`5$!{e z^kamjp!4evYM-Z+V7(_p8NcA(h`k;PtiL5^w?0Cp3}gKW;cqJd5o>jekdC9+K`L2>(sfb zd;L@G71e7JU<)3nc6}v79@_ow91qNbr{aB@@hqmQa_z2P625tUq#Ys&=ZxY7o&4Zl1Nr(zktngW2GG%xYJc5S72j@}w$fkRsC!M>z&Mmga2;@hy%Hl5qunv@vo;RaK^6AU ziqoqgymOr#NJcpNoA+c+*ecnp4UkF)*{__-nq#- z0NnJUqOUI!;RrO{loFF!ASd)0P3U#{cTG@8ZBM_3CJsb$nlYB7cMtC2fL|L(edIW6 z0V6T$-6>n0FxjS>u<#ARD*SGnXG2mTgkz~+=d|e%cPVDzDTC<(4jAXvBvYmW zZilfxI2-WIQKPg}o7h(j5LL+$L}S^X>>UVq$^wkBN%hJO5zs=ROz z`yP~M-iu@Nm1Wd=IMm)cN3N=1H z-gWxW07cgWukbU2qSq$H1-Jg3Z~hVDOR$$XTuX8JLFrh#R`*FV;L=OccWU`c~-%&q!FC^q~AY{t${hQM4 zL8_~Id)4_K6{&Fzeq{w!SqxL}P1XB6=D-si)gwnHru=4Z=SH!yX3dkAyK%NKw!J{% z@82LL%ojrJ*fCqoVE5`3KGUGNn!vQMxh`eCLOgoxtl{Lt0?G$B3Tj~u`Q1nXW6SGA zg$ca!fR>}s1>!c)gel-vyf)&=mC^L*42ux*Ob9n5jyjg?Y8iA}(|!%b9{i+Vna})6-0ntB z2v(lwjw@jjB(B+V5uO`XD<7N1n98SivtyeLPtnqGk@{cn)=bpa2G8*+@)atKC}6&L z(Uws0Gnu-|rYg7+QiwfSVR2(8VZV`ypqZAJCmM*xl4+u&yB{eH=i@!(3Q(+tf~DdR zMQ+deW1W`Bia!f9evl(GeoR02a#=!qIz@enEY50)tn??|;*zL#MRRQJWq!QM_Z_|L zmw>0&Q#NaLIEprm^}4D&Pmv;D!F|H0_5pgndTpLW(qi+3%HtA;hz-8`fHd8pFxRm8 zn=KLj$^!!Ju>%1r`~irt-V;a2PB>{$EjQJo0_My(F{BZ5QeOiO!rm&p#~IG;cd*N%qjr`zX4 z@Do3ownshtk!#yKICukpP)M-*FmqbfW`L$s>ZJC?*;VxOHP5UXTeYh@V^eX{rk3o$ zukG5}j_k?wIpO;Cc<($Ft9S?lxfSWs(fhPKJ;Icfi|f-31bj^(Q_5Z_>CvzM$JTep zWBu;`ClRuR?Ci>n$W}&@RkHU?_8zzOMly4ABV<-&@4ff9MHJ<>=WS)*ve)nOIp=)O zIiK_U!-IOf-`D$^ul>B9jI&>N69pa!x4lU@*xpW%e0SUrNvNP6sBTSsJyQ~M2MctB^lF=SE!YF;cTc{H-h5y~6 zeVyPaTd#j*+DvATTC{qULZuSv8YQon{FFSfi;jT{ZuaBG*B?r@{hJ$z`JAKA4Wl1` zpQeb&d3OM*vD@10$jAs$i&T!9cYzx_$jGd#n}1CmU0Zu7qD8M8Mh^S>dhqA`^E2Ga z&o)+6KHSQY5}rSWKvMZhEvUx;c2!*0!$e1m{OwHYc#3?(WgXxmWg%rf)QBj|kPbnS ze9na;<)rMG{*zqA(pNls)mR8lZ; zl=MSS$Jla=JQ`$5vBPKQmD0FC#353`GRxJ*I@enWWPd?t%=jZ6_wFqCy{rq?GEm`H za0ypLaMIAav~n}jZb}60CH^&pFo~j40fEqB#a#b4V{as=UBbhVFQ3%s&{70LTnWiI zvYbGzXS?8EAT`t&d0JARPl@#awMm8uo&WH=%LGZ#7NP`Zk^3pRw;Z}oA;&fR`{%0c zfWbfmGj+7COZbqU%netr#28tBbm?6dcgOo}$C3OlA9=}mF!8zda;2u3u3ZQmd`T7z zH>x#AGnZ1yhf>*)df4;YIOf|b8yS1l5lwxDo6OKO)F?G82!1~G&A^O8g~=-{Q6VL$q%=g zRR<5#zBTW@Qo?k7GrBL*LP@faFk~QkwvGFaqP=`Rndmv3# zpx)CvSI2Ni%polG!}s0HVywhI7-%q{7;P%|#V$m=XMkB3*YbGGvN?BoL{x6tjrZ}u zGP(MIWTg9;JpMS;36ZX=d`SwZdkWZ|0tH{C_4QO5K(?i?scw@TJ?YIKFjov<&U4t zSNiD1Jy@LD82zMYeW1;NC7ah&o43r(6sO$oY+}l1fxXZ=cS(r}#tC_^X@Z);45k_* zKeB{+xuBDkHRyWu@CdcEZzWrsg5z{j0^h&^M{{)oZ(-6=$BRNk^^TL`2&SuKty>3~ ziu=FbcApMQKJ%0HTZf%4g9`S+ZK5xX9*6W< zZ3-3c1iWnF;mi^MX^;_TrOQ46!M1;c9{#Go7w9cd_Ci$Veh!8jmtO(gg7P7a3QF|* zc(_DIJYT)Tc56XH9OD6~y#IDeBS{-kDjsxpyMyE!r>vRLM8*~sUA)!YBGxIXaqfi6PMh20#o*%AfBx+Fwib zWItQ~U612C4;dy_I(xiCTedA0i|hW*!~?`*O={xVaFg|;hQ%h75y{?Sl|f?YF>jkM}Q z0_Ux@wN%)GYqV@@PN4P%G1^WJuk^@@%Sm+UR+=$({s!nUz*3E#jb4ZM0Vx7KhcP{JA752j4z%vE)Sr6Kblph!_BX~}{ ztko!B(5Dz4!JZ?9>(>4YG~UT^ku9!CShGs4YJq4&Y#giLBy4WM*R6a3nyobfr9l5( z;?V3)e$~A8U$Fl9y!C&t+(iw-Zy=7O)!p=XxPQ;z+c)`HxM|OEM;D_ z0zndqvyr*1wa6QdkU@QZAlIOAth#^I9?|am>qhfmBvn?gOGUq)Bkie{9;`O@e~B#d zdN2#|FCQJ>m+`l}$=oW?cW0ZVRc}@ic(XS{ik)3hRMpc5?qb9no&24?{(s-ECg+M) z=Osc!zwDIxA(S0{u!jG^cysU?ui-DK^(c}$`}B0!k?~Vrk*8`8@mo#*gJb{m4HTbK zzLk^eiHIO!J?%m1UgFHhy`sb)LUSHwUSvAaqUcWy#@|IlNlnH+;Q)JqcQy=2;D~>~ zEO;Cx4L>MTyCWUav$L)wv#$m`y3?QO zxV~IK(vyaVkv7d4eJKKfy_ti;8?f(8vgK znU{zh&yp=GHUVkWh%9HV!xW}=!?D4IN1r6^sYo=+?)3((Nzacs1HU#x*9f9*-%g^-vi-5Rs31+mmV4%^n53*Z{nmPpxe41Ri$2`?d>5OowaVr_ z0zHwsEOCYV0U6lF*SziEi>XiW_)l(KIVU*8-!`1(@ab?SuBTl(OyL`H_TnrkX^2V| zqQ>fNz`60adA|CXg(HYrYBy7wpNvpH;lh8-U%1%e_6%feAF$=lHQ8j1E$!#gL&J39 zS+cP(q`BucH6q{(N`y%aT$xFl>#e%|g4^$1LXx)SP&7S)(zpIFiYpJVsm(DdO7t&? z4ruj@HorP|!J$$3BT=65rd2#ZJV5L6cm$T25=)%Wc}QVopZJV#{0+f*sejP7%P==g zI;jD(5DDkxdH!x8lJZN+cyg+fh`K1NzF#lm zJ=@{RH@c&**nFuwq;L4vZOn#`-vb%heI~`!JV)MqcEV%j5x`Ble>ND}n?*5$p z@GaaU0YkbC>z_8hdYvWYksF6$D`#L|pdgdoJ~x2&06A@4J#%3U5Q%N;5}f~|GB|*r zB;_*9?z^kzxXh4PsCuu3<1Ro3mpHT}h?f{j7c8txPPcuE3tvVZf6tDDdUsP{tfz+G z>>pI`aTs`RMJ3M0ei4-F_7!x>|FF?=E*z!LNR8o2pK5h)RUpOm{lLRovYW;&#*!j% z8wK(u>DH#z7DbE6fw{D$@5hP%k3x`e9{Y`ZzWcJqxsToUxj_Y&X$y#6HG-cC;D5=c z9DH8&p2UC<)wE9+PQ|#k0Hd$FXZsvBbpo|(-xu4Z#ap{=Zc}>~+eG_7o(`{INxdC& zwk!ZkIrIpRf7$#B$yHkbS;GQnkqSE}d2DCRak%!#xgG0%Xa3&=NKAp(6ajR)$#q$p z^re#DaR550TS(q3)UUp?u_1o_$!O!2PP_Zow3n2orlu?0GPb(e)JWV(Vy^yuWKdt4_sQHg?)gvQ>`)kH26v%gKulgm1V4!Dp4v0(_3OW2lkc# z>78SLA^h%IkUx&rd*rG)|NBv zhjTRjvxDQwE-(RT4tloKoO^w@-*{#>WoTR?#VFdge-1KhE&z$R9I9rYl6W?V)A4;( zq%y9kI#(A{#8s+YkKzV zH+6hhQNzJBiRLT4SdiFlGAiAMF^8P4ok;9=C7QhYJL7@{Ct90320! z&6r@J^O`|igU*m#@8EYX+|%^ z^xRJ6{v63$nA=)l@Y)EEekXvS55t#{tBm`Vm7LS4ddU6sXan_sK_b`GjvcosVB8o$-0JyP>E9oWCnGiofzz4zP2m`%5 zeq5WxZM=R+T-rVDlq$=A%VcYMsxn=yD_Ni5PJy9~=hMF#g>9mPVADB57ydUO=s+c& zda(ik7B2j}Q!I;1G~#cfcQ*S57DD#8;v8IoP;^?c&>lbW_3ASk;VY4M?mA!^t9^B! zx~MSIakQr$!(!laDh#liW(&V@J%nn$xHl>bj1LbKf8!Gr`EKQTM>UJ`kb9f$wzq2P zTRbce4-Eabz;p>jPkQqY*hYedoSm};R~>`pUbvy zu+2)%-Uw(4QIDYvCKWwd#XhI6y*6s*cxOQ7We5Gl`PB*kJr(cdgN2_7q%Qn6gch<2 zLo)j~g4fv$aSSugb-xuIK2{)B<9rfJ)tR^aOaT4;kJni2r=a4oTi@0Zn$ig^FnF3Q zBv21yP(DvJNAU;H@2g$t-$1yc9`W1sdl_Q$^emNWzIm!Vqu{zjUv5xivpJ=JFE1G> zL`f)lR81@ghtKfe?&&^BbfbKiYo!gBy#7c*J?93AI`Oo^m)SqTm{$&o`gOrKlm7u_ z29URAhs?nogU9f5;-CC=9z@8%705tl5X3AjrY|y~f%~5aPg468GSjJ?8ZxMw+O@FLzERo*n57}8`j->eJnDca82s*6>darRR`vb=?x zPX(nd`b>fJ&~at-mo?m(lMcGdJ>u*tKc5+XW7w=bBh0=;1=II&>(I0snz`Ts(n${( za~@X`u`^_lC9b%MQ&@QAPe`1kok(|O_$nUKFMq_v{!>YBQo3=A{l@QYDvqt@R24SE zt_i>sri8^U&IixRZIq8+Zzrf^*L9ZHbvPo7dEZir)F$) zi{E*^aro#H`N+jXocO>=JiWLhf!YAoN$N7{Xw*?&A#T=3!3q$yETNeM8Kx~TRT$=e zyaZjQ61GrS%?aMu6*nU;8nLfld`Mn5M`qP#+$)oQJ=^;X72K{+)E@Jy4VvC%U+CjI z4}f;IL$nsR-T`P!))Ksq#dXF}m)G=;Jy-^TWqFpdv~oK{CbdnsHYHMhi2*b?r!QIQ zX@E~5T@1^?i{)+-u}zRf_DPN@T_P{1eYBe(B9$29_h!lOLH>7+P~X~9R#Ak~(@*%A zdg3{Z${;rH>OBbbDx?n(QS|hpS}g!@C9Idd+Z%z5GLWHh=oxmuc2_KMn}ju#eg#mVpKuhH@gk&BZ*9wFUl2DNT4CWRrT z{Jt^I#y4cfv`wvU40&sJ8fLuS4-KjRUR$GZ7?BkD+M&OXS=08o|6ob2RwbK;X=Q14 zm*hwNE@eBGkC_wyMiPVEIn_$3DAnTxXUxlIF`^iL&V!Sy&tJQ86U%<~pIR(zJeKq# zh_H)z+%p9cpk60_8KsDv8(`I_qi^~MNko=?37ub4Se10x7k(D9&SC%nD(Y*s!Ma*! zwGGiMq3Y~}}} z>Y4KFk8irWnOUDhT4h6{m%h97M&n5XnD;MsG}g6~xr>o6l&I!wZErt-=QKEn7!i`BmF8SenVf zjcp*?umn-eR<#z(02Q=ExuD&-Ke+f)${{qrMGG0Ekh&O_0 z^0)5+!cI&*7V3c@Ml<)%*F}rW^)~Sp90r*e#*3g_9 zGF=tTj|tC}Z1EC#JPddPvllkRBP8z2H$PD{7(SwVQqbU|lP(q}{%1*vL zH!3$~0s+l~QpKYyhp*7mGlUZa1L~=JZsZmzkl3tkYtK4yr}dq52`vNI4I;W?c@N7i zOMwp}L%R_d(B+j@u>}%8Aue~d0r3iPak{F95}$bQUGG!hU{kpa z`7ugUX-@sJ%4x`NKAzt73w6_^`2ACNVqGo3&E1v5WT0i)xi04A{YvH<5rJQL-W~UT zu0GZlc%aNOs7mSm6=uxd)I^c(3 zsmij|6I>23#0!3gJ_=)fsipX^=*b6~C(tv|f#{fU2}ftPPY(;_hA8grQtbONQ^0=r z-~PR#h}vQ^oC>DNlTX|9%wS?BhxyMVpBFrR==M={e`4I^F=)L+B$o0|h-&=kHFXcA zXYCxA)2-roW*hK-nOJk(nbn0v?G&WbthMC4hRLE$td zIxG@@4Tc;HM%@>eU24N?SQJ4GSA6V0f5&j*>a$M41iU!pE&xVr$<`MWx#!RL`3Eba zR~0|YhHh;5VBMr_au&k$hZPCXwR2(`yAZ)YYRO-!d8abX{ng`K2R4R0*%ZcY5$S(^ zSo0IgQ)l_nxIg57IU(V!y3A9f;SZ$e#H8EVF@%+6Qa@KKHj^sAI4CSVI(O2Y!X>1g zE#%e|Q4c<;r0szbuwZ<<5c#@0xmHFj5@pvy0);0d#iZdI^nmu+#f(@~*xE-ahNYyL z<11b9bh}WBR>dp%3a)q>I=Y3UW#idi&J44!VP;T1?eG4Nec?PDn47vw(bKLs5{oyS zHrD7qpi@Y;(0{grZD%y;#E(WBYG91J1tjYx+Jn|84^d%xw=C2z-jR1dKccF2VfYH- zD>8CMdHh6g1Wz&+Rw^!3?xpL;8+|;*JG|y}ZzT{fhu(C6Ec$xD=W zQy!cUm#~4ds2Vlb*l-k@9j-U>2~~vjZGLQVc<1Z-o#IEi%(ZBJRp+0Tv`yAR*%p%h z_g-SZUf`7F#8mbQ-l6a-cBZK+V$&b78aL3j#h1rz5VQ?U;{>E6T<}U-b$hz|`GO=B zAr9ZViBgcm6mp^71{J|7y7G>?kwz^7g1iNg%#e*N1ur5ITqVzAOAYQ_eHD*f`SCrx z(O~|L_RWP8;LL*}a_RAPMnWY-yb0SB3MvIZQtGM9@a?^?xSv|AT<-IHYk5cgXoTXsz8xBt zj;Uhz7b@TCjc@>=6ad6$b<=9QXTPccL_zcWNjS`)B&cw6kQuK24X)F^>&*^`964!b zxxMYtVZX9bA8y*|SVpqPkG+5@f0+NPdkaT8EJD%3qZDEYPR>_9LcAqFY2__PEVhd^ z&F^tRE@7D(=G5K`HZesl1!7~N!pLUNw@Q7|{ zE}MmC2{}Iibvub7&xA{At}$NWKp-;j2zJ0(uNh2bKriWwIDY-Ca&pKYeghU(=5k>x zaw&2QFh6tcna9eRx%lqC5gv_9^)M>A$BD^jq22P{Se$hE^@`>9JgQNLrMF3(c)Ksr z=XMboxpTOL1y0kLKDudVyy&#s9t99%Cr_C!_IK0RUY@@P*9{ibICbHAa&?xiic0Nm zkwA!_f`hHzu`5nB4HOZdW9{^m>e~>BNvnK1==Tw2!wM@fjMS^1P5~{(Mnd14UL0U6 zw+E7%1i2zxPXZgR92m}B&9Oi0vYXl`w$YyyR7sFwo=5IWNy3GHMx~Z&ZzY!};3rMw z{aj50`$TV$(`WtGhX7G8L}HDI3n?uE%Ha$n-2ced)cHf~&oS{JTYPE~v%n|?0V1(P zq@0WekuyN}DGJ8v6I(>*$CwVphf6qX(}r((&t7v(m_+aQAE)GHDuydW%W;y`Q=b4$ zWhCp#1b7Tx=WH92)x(Xnb4JUhtjK;KG(s!(!dPURkav3|f3d^YgXPgY91vVR$}qj< zEq{0;5GQHdVVC=U>^GBA?ywd&SuL_ppMDInP(g!OhO^(}!C)vAgk?aD_9`=rIcFTU}^Am8-_n~H-F7t04KA!8#=gY(&qv&PRoVDs)rJ&+JI*!i;8s&{dxiCwdJu804 z{vpu}+^f#U%Cp~Okq`!6frUG%$O;}e1>%{%5H(}+B3Un*HI`m_B z&(XcNayt|RG=J%Gv%pg?AEi+60FS!ZMIfK5wap_v-rWWaN%Kh6QWiBj(Fiedjimql zC?yx%?jIlU2m<_TUE!>pk0T`9{R!>SuiNJDq=1*p{@sWo=sGBNCE{aLI743 zyqx9s^*8R#iW&tEPnlkMOZjPbTk*ru1|u~&uJa^L+@7QMXeKKu)3aAp6tIcnmY|u& zj_JyK_P2a7`Xu)S7Q;Gxy=IC~EBP1k0%y!;r zLH|@zGtYWE;T+Tc+it(+(WZPV4mBu*#y=gsa*DlO@R)?n?zN_no%e?RO8xwkES6U; zI`g@xU!F~*&K5n7(nL}e17Pek!sxx(goo^83Lf!C_>~AFHq;yaqW1y3WynbA9lg9W zyARt?6qh0;;&nOWWIZD8JsGewau4NR5+hKf)>UcuOflaa4TFL@5pNiO+WdKo*3aYr-mUscl}Cksj3keOVf~4!#uM~=8Tv6@WpvSQ>W((Ie{VWy zU^huHQ?3VIf5D--$EMHM4!xt25+6ROpz8c_tJwAl7MS;bbfXY+yDa*Po>GQy1y!X~ z6)1)5;4j>}kQhM@(=`-c)4{ibmh=*D8#|-3KC=K=AX1eVp$+U6fI}Ta1A-{qqQm^) z%H) zyn0i7dN9%dSYtXvo8s5u2}#SFW1E95CsZ-@(SFSqZmUMY)9T`$+`Y}<*hm)*^oQ); z)=$);XrU1@ObTuRj>qkRAw)|J;SZb_dG5(3hp;&pgukR3Ng^1>hg( zRyAJn)MLWHKUl>VsbTEY3dHeaWCb|tALNWgI}sa)y`lxlnFcH+g!9NJIKas2LaZJ7 zvy@cx2uAu__tp$Wg7>H{cWm>Qr~-%DaBIUQ^eBDYt|EE;oNGLN4{AX!#QQ5J=Id?v zdb~dR{bPF3Z9r|C7&7DjG!XrXn2G1pU+bg$>r91Pa+;?|q}+66L@)!DoDL{) zLrf*(-an@om1?#6tg)JZ0$`u1hmnm#8V6iEcPmXZelN0gy%26@DUthiwg~p%)9gTD z10zIE6r(~KW0uA|(%n}Yq5WC$@mJ++?=hOKggXh(mpH@Td3izvdN%GC8E40IwO&yN z?wFMw3VNDbR`>4y(9!-@l~TX*dcaR@)PGiF=D2IO+TMs|YwLW|^?~qs&lz&lVG}mL z7}O2*X{H>0dpJE?w{^q#l)Q;TEH4(#{tVo1GX}+Oa&DP>=Q`pqz`BNreCZG6zhjdH zGcmVbJNkH)30DfbQHd*&@cl>GDnWJQIfKT->ci&jMzF%EsTJfT1Lzc5_Fv`Ax#$$i zkMGs!$L_pAa@B~Gzr;modpKJtghyo(G2Q)ymT(a!ukppHdjzq6M z37Yk#tvf$=L0AD3uMeoVctCM|X-V!WsqT-G=y@X`Z3kzI96}bpEu11HSy4HoIxvxo zq_D63q~ouTIuU0dzfi*#bAfv3l?Pm!Sr6UIoY&YVopp0IcmVw9`f-kk1b>%ZJ7fyu zd&Y<1cFs~xmj^sK?Boh#;A2Oc^dEkRt%=pkfv@~w;S1CGoW;VIBl5eFJod{w_OG`g z%+J5fElItVnixCX=)Cu(&&miXVT)7>9-zIiV4*LYiOf_!Ial|PcxpNB#;JtL)=#T4 z!}s+4^|YL)h3fc7ofu)YXj6|+hYQ1$E<2kC6apYV>-2H-w3qf;A(e)m;;8m37{J2m z_>6i^92?-rv=@WNzp)|l(O<6PRg(H>zeO(NCxDP~Yq>#fXYYCj&#bYD(}aAH@3x`i z{^W`JmUXks1^g;JkxmKCfI%v88zHDO(&mwZBm&9BHK}V0i3F8KmABRO_~j-U&w*6pFa`d)$>vmw5QZ?WdJtP%Jok;B>rK z-M3&}b!L$Q9)V$~QA;hdf^pJY(3a(93-4p+R0-RZw+VVVN8lQ)*p?68r?lZWbOJ)<_V^+7k-4wrmoDn+^g+pPD&mvek zf%`U&92%J@`d4qoR4lTtTl%**8^$UMxg#9(qIBD}pfO=84EfveMxFxg?P@wccEr%p zZ|uR3@V%Wm&*|={hvTTZ`Yq~c*O~O@)Vjc>W7>1HWX;gnZ@2 z$?i8t^Suxrxey<0U{MJ4)~sTA?&->k=Owr&l`E7of{XT^ry>QP_ndG$qm>O34e7@K zndRb51@_l`aSxw}ahXUBnz8T!b1+8)0a1hE+|17IA0hDiILFAa#@pch*U1?bM}WT& zX)N+aF<`R_PeluO1B2Z)xNcQHZ0Wc)d1 zTKQuEC!+DI7X9L9aK~W36-Us`+wfvzRC@uROHG{QPw6i6sW)9`*b$%&z`w;QAKv)( z_u}nN1Ov<=XeHNEywKpXd+||)Jw@&;6mT6gG6Z#&NVz#FjZ}#GN8}Aa=L~2=ae&PW zI6T2e_er=_|FaMAA6``ckdaRh6dMT@cBeuGk38!kheb3V|GvXid**Fa<-XBwyLmQt zCUFcQS$)rUGcxm5PX$Mzt;rseYNr0R-L-LZ4fa97jkfMpv+l^@aMMX|JxYyKP(_^)w48kt}`VRo>X%n~z*`mCis_ zA#8MeW_K99)BOVu`z>^P%9LSO4{w$7tpq}N37o*5jF7)N9l_o%eEm`vOis2_Y8xoJ zx^mp54iG7K<~^eFthRmrJp~o(VDKL1MG!4gzQBh8?%JP`sv9h7ALy!H60=D`rYK|U4fL_}ScOBZvevOm?B{Yxio`C?SyD!S#ZwvX2$B3Q*?k&uL>;x8wX z*osBfE5LRFF%+FnL|T{J^wCK2qEX^U9hZp4YN8wAI->WLENXkw*7ItCo~}XOK!}th zYLJ58IaD*1|6JzcV{_Lc= znG{0>VH1daM+HoUL3wk|2l+g0s z@K4Hs#f|c&f`?0ZV}Gr{ebv{%8upb>zbL=@9_R`xYS;&z_V3|@2O+@dMe3tzau=+= za}1J#(;wG@j9cy&L~&Ueeddiz)EQ4s?(?W*!;C7=9{=;KbOB>T^+ZLZ4 zU0U+O%Zqc;Jh$`vGFG;%-~!!;>XgpLEkhw~Ip=50A)Ho{)A%3?KskBzyKibsDd#8= zI?}F>POsEP)8KCOKAvvgcw%%=k77BJkd`WM2xXGm69_T&-sBTyq=dbE8Mi*ul2La5 z#ZPpbA~YKv=;JIDM2&}0z~gUI4>zfjJLS5aB<>ZaTk(oV-+0eEen1JE;QKmqN7-z0 zk6%B^sNt%8y|f!J#&{8^pKk@k$;E(sR8jm*xg`{7tMF{?Lqa&1U}8W@nVBzDk?WHL zW~x&{vtufqg>R~q!14k48u`C!2_T!>|7@w2KuC(>vZWfNY^-2VxB26>1b3`(R&gK= z>g&7e;UUWOmT?tTuZHja{4ht_Pd*?I+>`I&@ky?ctcp(@jVMw@TxPj2Hp%y^?#1Ul zP81nh6A0qCSr*)a6#T9IQF%WU_?$>)%%5!4_`3US+V2(F0HqzngF3ls0=5pkTusAs z;1xWnWOTP_Wrq({@o2RR-Ud>j1o<*^g^24#&UJ&b>QBFP4gv!@5q|u@R*|JvwV#lR@|d82s#*m@~6*Ah{SsD~hAg%$RrMR9xxAA4I-#>gyi7R+vg)5P-3?$0sE_3s1xQvw1k6mBj#Av8T6+B<+o+_&* zFXQ<3mYr{o731JDk=D3u@95UV${77p)BPNFo-=W<(>idP-%?(;m#^Zx67|q)bK;-Y zWBQ36olV_Zhob^wYS~yUZ7G~H9Stoe8o#<{JydQ(^w4f|K0C!hX1FnfiQ;bBmQ;PD z6-gTR;mmUa^iPSURY|ukzwnniK{T?+57<(nnr<(So8yCSz(2B*v~h)c%vQ99lC^Nr zMNpY86im0)+tx4_v~fCO{meU8ejABckT)e)@IW8lM0{d>x*B{DDZ>G`TTz5Qvq~c2 zIPqyZ6~PaKW$DL&W$q!v4yV5($U5?Q=oOsC_7m7kzH;etZ>zlc zhZ;5(tOR~jz=SUw%bFh%oh7AIZD)h8-;xW7e)a0d3B^5UbSt=1fr1zK!)oX;9a05D z(yLgG9cpM%yf`4zAyOLgIo&xkpZ8kkMbR%9uKx3RVX*KSNLO+WXAASk=%_`1-LOs& zzWGezJ~TzlmEr{Ur9b6g-!0#LW!GqTaH z9R!AvWfoW5!tME)8cu=St%fQyVcAM-yAp?K^>!C}Tc0{PWYM znhMLRlSA+E+2|H$rs3V`<^{hRqdo?dJo-SXjp z!jHK24KGla8TSYRW`3g!p7u3%FLo!QZOhrEkJrhC^Xc?PF~>E-Wk&=u&cA7J$5)^q z%B`vLNx(OgMo=65HAy&AMjXajZV^bQ8YOg^Eng-o^f~<)|Mw?q$AwCy>X!p6i**bv zan|5&ri9Ibh!|lS@;TqLen};fO5iXe6r1ZNrbD!WPdy?6{6hXnRyrvbzJB0TL?drh zh`4-IImm?9nTKx!4FGAmUywydG=jhBntz>v);s`{@@vqa3n5H97reYz6G07dtYE?3 z0{ig3U|dk+NELno&_EMGBCdTJ#5lip@{h~8h$-D)zGZPQfgGCTd+fRS?- z{g|aD$eV3Bu=KQd)#?baRw+GbJGi%mw zu6r=fep)7p6LwL?<)h`36~%^y^Z|M;BKgE8=^4=$F#dT-(GY#(H>l zj_V8$Pm;_$*OQOJ3jT8DhkPZ+Y*s3p>CfueVq4$~>WtDG`w6WcQ>I5ELWwf-86l84 z`Q1M&Q~JS1S0R6c<#{^;+ne`jREiid#gX-t60|}pY+8nM4KZ%HF_c4l3?L>L?@F>! z{>mt zJeWS^YGFd*ju0wXYVH*?qS#)(#8x3i3L<9HGPY!&OpxU!D^hSYvX7FcP=Zzf3vF!| zj)hrxw`zRnWV=O>n>$6`FKv@xgK4Z~^YGVaFvLABwh@EGyxSxf?hg!ygN$Yn)>E$$ z2C&}paQ1gkdAwh8{$5{^IZ~J0MsVc# zG!}4AgT;8oVX51RGICV82I*0i$+3cfa9RWjVQL&7cL9F zTcFiLperA)qBrsL4j7h6h$+n*c@XQ*^vC)A^T_pf-SJmT3Z*1XE$&aMmW%8_8|al8 zV93e-bgQB}C0y=xZ*TLjJ+#kmD*AOG+2VVIS0)GlJxH%S&<)T{-Z)&zzYR`4Cx6|4 z!znS7lS4$D#)#I`N0IGW+pqNW^$cM6qSrN=*Dd<+ptk%KZrH zhXPMVwx-FA`_>*>^cEAA(_-@Pl6>AD+v(e&FFjw$E3~6Rw@EC*1>D8eJF1Q_{lU zmbYN>FFT+*{Z;H+A-&TJXQ$r|nC3FJ{F2+kKgiF#v{B!=HKjJ)Q!#VGlF8Y?b$-Om z8CW%d(wg;oL~02Ox)HqSu5gq4p&8&A(F{J5+@=eJbI2uSE6y}8-&z^#$kv`|OD-^a zQ%U%$2milIF%wi>{fH<87xVDcA<7SHHHC9Ri4Li16j$BIgYg}WgFttY64#<02{D%L^}xWA3x#nn-Lee-(l5!aHDvpF(jp= zHcTbWUPFP$njx}F1ctdO*`(l=FZ~T|z`whrGCbRVzARe5VESTb@taxzB#qP9cXlm^ zob_7LNAf>dTi4GiZT(8u-Y}?oeWw_)i)r>7EOVbot1M~}Sz-R$IKFn)!>Oi^lKbj> z&+hqe^-1%tCTnPtMNO29^`{iKB-Pt^vX2w#qj>MNUfG-~%ShqXU533w8Po@!WQgnh zsokq=gLc}Sd5so~GK-7Kcyq2`7fk#vo|f|1+h<%@} zSagLbjn;3d+9YdVll%wm&i}0k^f){>BKLH>+O~G_tI7=qCRE|;dGvQLMfgR1-$TsW zMDc#S*7AyttsG)ee({&@Wx8#Dw{2p|b##K(wr(}neSKTEgp27(&ay;}wgQ2YW=ggq z_XimPxBRO*Gi&r^dCuM${sEsdPq67^!)UP2q1lv2V&J6mJ_4S#1}%hLz&@`QsD{OK zJwgA?cKLmmdH&2CZynEX-|QN9qH=%acg_3_7lp@@{CQiO$%}$ZpVn>yRbr=Ge#N%1 zXuf9JmqOc4r)tI4QZc(J4<5L)DsOy(ZqA(a{>4$R^`LIQX{}1Tv|#yxVv|V5ebKck z+V6PKb2Ca=vG=owH=V=#gO1-3(bGOVGOK^VgrTZLE@-G9ugv0Ji8)zpN~{R|{|V9!#sM zXzWfxv*;@%l2BN>V8=~;9rwdOqmgy+uEz#_r<#cjVC*H4^As$ zj2*HArLPu0Lh?OEl3sTA#M9pFxtZAYEDNj@wV)4O;K zASBU_6xj}K)ojhgie}dU&+jZVS)NRJ-v53kFyi;$Aks&quT%-WA4=%WywIWR{GHpq zfwJ?kmll#}lfGD|S)w>9+R?-#S(jMRPurubF^ptW1njb)FvQ2985*jZ;#W=|^>I@) z=a%G3n=|V^E*MPyQtiwP`Yp{gp(3H{eS|}*_WKky z4EabL6m7kpTk4}Wu4xwgytCtJpII#Sd;Fkt8W6Ay^1xERn7zu%poUJ}_oWUE&4$gs zP+iXnxWJmc+DO0t{8~^K8QA$A%Cr8n0<#pY%B3Cn)NyB=uyg5_{y+u)r)CafD|3IV zqxap`yKZObV|vw21#0l@>lDn4laIP<>_IO!r{A@|i855I>hZQ%))^aW&1gCxveWtX zd;B37jatnX&zMM}3^-VGJ^t+jTTu9ppc!xT8`vygpi;nvOyw7HZVE6@+|=Z)(pU5Y zAO!;p`#(&RUHgtRUEzjmCRuwQ|4jyU*(-p*a++mt9jSbni9D(zz4n~4%k?CCp!##q zdy;JY8EDdnsIYtd-e%*f3(7+i0ox^_-u*z*H1_fj``!a%KNAJrabc<;>nzc|Awj!~ z{h8sKEm7r{Squ!mOrr$8RAD$0RDmCFPwtgpeOya(&Hu(BE%1ee+K4$NvR>lD?I0*j z@Wiv+eM0se-} zuSG1IVxdi*m8BB4J&}8*@Xy;y=~voqG}28^-@e4z}S$8{cT# zW8i_^D9yA|kf`yj7RI2Md6Dc|q)5<^1H~6m@d9uHG z<2ak{Y?Drd*8{Rw_!WO3SOH& z##w7$QKhRwjxq)L_}+g*D^PQr54-kvlmFCIu)oxJbE{`ZMWXJn+#<}+G7Zo_Fr`4> zku=WLf9|e!S$rn7UnY%~-tr4GX3W^}o9gVBAZc<+@@(2CKsEc02#O2yccYjl+g5%W zynq%A?s>Cxmn}oRtBDzH4}w9i{n|O%p~UP3AT3KEGb7?};|he$mXvw_IKMsmDfq_l zgVl+KHybnO;;LI?aO=xi*X#}I$^@6!{L9w( z&4=IO7kUYFNvc7O{lE}?Kzd}EjBB+oJ$QLg@}|`Aj~17VX4Plo@Q&EMaG0+p&A#un z1_;-+z(j0DrQD}o=9fAq{UjQ)Sl4j;-tpf^ncCYs@OuscR?o1@n9F^6bU=He?8xQHNWoc;eU}K z@~4j}?%g-7(_PsCtXYrQsYm{nVOQG(WGWxsY$S)_)?yuI=&(0zT-v_+c%szi0D(V?4f2SzSU*Ih_z;DFJGOjFZq%94)Y_*93b%a=vb zUNb&F%+sbeuR0lJ>`WHDzPT?sP@F#e$Ee~1kKwd+&1SP{x};l>p`>4DTwYMO&ONhX zia%1jw`H4ru#Zk-1c^`Cw;cl*f!q!%|7-T1(H>F(0HpC1CY;lpV&D_eiz8RU9Y!ES zA3-|DMqu^)w~RC(O}*u&9S~SWtiyb@pI^CoZ(G&FJ!8Jwwz@R0B5FJz*?vBz6NJbU z#qG{sVamvMw1{m+C~~}7!YUYA!|ZV#frRWMTiK$u!y3b;yTGzN9PBZkzs&EmDY|Tk zi;MLNoH}Q-f<6&`leG$Yty*pwT z!gqBG&qHLc?ZHs0?~dXzNfYvmeod*zH@(3CKoR(#{eMo|oxPkC#hzOLAFnRidVTlV ztqt+}t<4nJ0h)^0c>>`Y$$waE4M1@KbWVXix!2Ki)PH^JWBpgDboi3@@BB<~)|z`n zfC3#piLTiA8fkFiP-jCCy(RkWVpOB;BKwO|_SS>zOn$+gc9znfAGYso-=BRBLQZ)1 z-s)g0JAHDxR!iX}=p-^*794>-<@Pc156{W)kKNfR`yctg9no#ePzr>Tl9a=}v{zCH zJq>?LK>?vY!G=ctYaZ1PxR1{>9A*@_=Nz1Kkpf!{d&!MGWf~luoL);Ga=cc%mfxPb zxZdRAJLU*JB{whuGgkZk&~f(OEJ@($+E>0S;7J&Ga_k_Ii8O-@qWv#36$*0shx+-1 zY|FAyOJ~@gOpkt=k{<1PF@T+Z!fV_TQNX9ylvT#_#O(i3b=Cn@HC@{WLAo31l2S@K zr9oPxC8Qf9L~_&3p}Ry7q@|ITkV8mFcM8%a((n!U{XFmce*X~X?0wGcnKf%oT)#Dr z8A!3WX+=3+2}f^7M~A;*X{e7}4iqJVLZ@rAr})8Tf^lmh|9>#XW# zzge*U1plWOS5(sf&x^IZ6yoEBR%Q!XF-rAGD;wERPwV({<~CRRS{Cnq?^B~NTZ*2w zo~79J)BnXX-0ZICow?m>7WB6E=!&U9rzpkvNjyA(D6|c%Kd|ySU1f4M?8HR}6y&yh{7OtE%giz3 z-w@Xc#50+)-!>fxt*hAMq+)%7TYL6i;!5p(!^@VF!U3Dl#cZ}dGr(OQuR?0KF=A&+ zD)ukR%nm-_zUOp)M*CtFIS}i`2ofHel#IY3wh7LAK0I{L@#(~$^`+ko6Xs?Y*i7gX zJ$>{i4q@c+RX7fHz1T9_5o=O6mRtc2(bJAmuoss}JKH{-(>Ou+*)>1Sme{fYBQB6) znI7(y0PjE?-zr0x;?*b&dk!UVeRQV{@whg@BNvL~cj>OzN~eKP8)W`U#xB9iE;9p0mc(F3clV03zC$#qeyuwAaZt@v&W>xsx%*VGa(!h%34I$MfjTdtE@3En3(SmFh+#H#Ljve8?ldURzM zTWSkOtYK{0uHqTXTVU0GbEG!|=Rd*w2f1GA8>4I@SSMPI zpx_7r0R;Sre6U1#kg}@#6F8dDsieW-SwPVl4f~X{;p=hA6{!7+$w7Ay{~@_$=&+0BohqYVUS2*X>xUk_@bc~W z79Ar)2!45(|M#u1GUkXs2lAQQ^2eY5CSXxnI1&ko6aHME^L)F`CvDIv6QL5Szn)Df zKh&S?3aST)W*LRD`WjqU71F6rv$EN?6vxvcI!3W{A=FOyW(iK1Dg*gG`D{YGTsnn( zdTw`ksKz?EwHb2+mIs6PkTbu=>R29$XFtf4xISIG>BmZ3<0qY#f`y~E`i(&T3hbS= z4hOhlxW5yurROxDR1EcQRq5k>f=_N5U!Cc*0KEM_ndB+n2pS*SBm4Ct=A}kPz|5H~go0{<_WHPEtUzQlSzWyY> z=1Sd4{xG`eUL&j>?_op<_J%DVfyQRyw^589i4X-QPZa;nacSFENSw+x-b0m=^@w%2 zMpLy%N{sb)mf*`GRG*4`a5n^Q=ST^UrjiFIwlGOOIUb5&5ULY3Ll=6-kwVshz8rGX zl$;9ZWBpuH7x2_@uin9ZLWA0Gh0F45Dc&jaoVL!9_d#=_^|)`$^@X&==E#ZKCev|s zdc=L~cNs0=pK5d8`>`wZE~WVEHT$(PgUZsP)y!4Lf^wEv+c^aXBWkF zV?g8^fcvat*gq_Q-M_*ljF39oEu(6z73=SAUQ<=b>;^wua-1MD>{XZ`k43WEfN<%A zv^Ie(=r%)GZ~ECRYwJzd{xBO*TJ$g_1TQvXJbUS&#F&Gb*2M^L6OE=O^!zp|A)%VM zXq^0eoCI`uXtA1v6|^~goU?!eQuYlkl-6u0K6tDzid)GLAmKGrsgCRr&)E9StFCI#2NH*E8#BVbztO zG2dA8Riu2_1QG^QbO5W2^X5&}8EifWt;`>v`V>}8m{X{2VJM$?f_e6PS5fi}zUK@v zBtHW-7+8Nlwfk1vaEzUM|Abz?sB-Q|FHId+Dt#PZssn+zsDNWneiiH7JFsH}HjG?M z->qB{$;EFn!<6}?N<5z?HWzeSqugO!A>tlPllDa^)IDLX1IKk@cTj=yRVI!iZ5wA}48Dm?5jol#!tzaF8 zx(4c3=IMrFMd>-5#_XfzTHJnDdzHWb8W_iZY^;nz#id>aQ$&*(3EcS2b=^C%xr&zX zaLc<^#RM5EJES?>^@dCMbg|K2QD=dhuyc6tz9YxV5EVuHYD41A1p{HCw?Qr>3WT8|-pUSoE!Qwd;#{i(+$)5kVZ6nFUjg`L&B zpACqW3MhopR-vCynJq_9yyM6I$^;c_CE6OQH5Cdyj9>Ef3|NDGE~!iS|aQCCNmCcg-bF`sY~y z=&_vk$pKJH^$y+9lZfPf0^>oHnYA>}wMR0W75Lmx5}@~Sr)0CsZ`RER>la=z6zEST zR)`3YcRZ&Mi4pdll;N1p^OWtq8gH(^hl;U(<0cp9go=!XHr(ATQF^x zC>}$yrmhO!X)a+wnLW1|@AJzNU}5}ssD2t@^braPAR+U})po%e2R+xry>>zrLp*d(36t1KpQEq_EF;_Tg(8IY8R{;)GEiU`D{%8E4Gq_7YjJrPhHA zf0qdI-cQN_WK81gpLHMUIl~0|nHVC)Jo*DF1zi}utMzv0iwoc<#PSm{+CS$vy~s%7 zb;_dAqTuZMazvis)@yL<7Xa<>&>H~xjX_gNI(Q`;ykcr0101Kj*siOXfe?5JkUc&Y z!G!EM67?f=rYpY5B>!+a(EXQ5ngc3~dR{2K@-0*GMyFW>5S@W7w3an+L`KhLvO?6n zmFbb7+JRW-4d)-8T<3;AKjeX4m*JqWVm2rD{q8TLdl7-sZ9|!@&GJNQh1FQUWqsM! zVcFmQjgXwN>!nMKso z`S!=!$vYtN!7cjvljVh8uzvEM9y#r~y5LS#$+uhijx{tYeJ$)vqZ7-fibk8houFjK z3kRUC_EO)Vv@s=;tNT_b;>4l zIIK}N2ftVra+*`uj^DiM*aouY5FmBp{j*W`8(jTK(GL{_(o)kSLLiPS&v}9hI2jSi z$QILo1)6kI)gM_Dk41FjH#4t?=>Fw!h~;PCURVwv=IYwynPiMu6PCaYFPYjWBE)O^ z#1HKBc7&COyWLs8BrI*OBZNfe+e4tLd34SOT-Rhk+#6~aOjSuLQ?87G5soY1&?hx6M+u`o~WUj zDuqB2P>@Cj{p$ucKp!8MOza7;7gaXa<9-c34aImJHo#k1hR7O$BgeA)LG}NOt5|%_ z_*@HT4*^2`Y1>It))1geEXCf2B0&mq7e)hLStBiJOA_C$1gBpL^&2Ff6hJBQ@~7@c zWFWEGS^OErV@w{eLjcrK#_M|Yc}et@ufQ7?empfe_7}27dL@tlAdluztHrCswr}sh zG8vcpeCa8;Gv5GNK@Gt;kndBev2{UaWDeu9Hpe zu)0gEI*e8aF(BeOzG*W6qP4ZA@@~t=7d^2DtXr{gvy$Pgp z+n^Vg`_H^=LX4A*W~eg<{(>obII5*N=3!-h%zsXREF#R7=U+z}XWbi7$lnrijiqE~}dd%);terJOPe}}Tv zK;utU-ZlO3i+w7|bP9J$WBQ54CdR$`{-^(p-|HW?x=U*SneM+IMFAd0d=*WWY2tOp zWH$I`7LGp-9-0~a`H58i9k^?~`^l_&tP*9qzSd*yK4VHx4Y*gRY&?HBj8ZNqxAS%o zDvGn+m2!HG?c%pq8EM_JQ09U)xO6DcE#6?M}Aig(7XRb|L7!{%~uIU zskT^iXgw|1Xvt{2Y`e$1G_{baOK4q>{bJ(<9x3ZF8y(C(R|gO@qp}IuP!QZ%p#Pfj z6Tv-lqFUS6Hn=np@58QrKOPSfdswNY{v-vyBl|+6f?Nsj{+fHNrTCe&wb{P8S}|~P zO6z?9Cf3jgc4VY^xKz5k3YRRFHQL9h;rR3Y=MY9J;WL0gi6%JpM7GFwYn%ux*9Gro zlMs7mhv<+bL3%(ydF4&ad0ZBmzgP`W$WJ7mn?0js_3etlwDwN=Y3~V{biSp223R$# zyqyXF>$OUE_H{o3>`oFuIS&D%^`#2Eb|s&Q7+8SD_)H%77z!`?vDsn6JgqXg=Do|! zMu=5pDXx!UauPALjR(-rdiSL_m4`9(ERxuhiAerJJx3RaD@&Gc1X$@)8sDpkw4Y4s zjJNdo;FO5jL+o1wX>P{|ATdo4jFE0J$PCu& z9t6;;fgLTh7X#YMGyx6w2pxWTxz)+e;`b7z3IkmQ{t;PE>;*6DXtf!dmlnydP9FUU z)rt}~*U|qMi|l$uq6W1A9;&B4wU6{3y#L$)SE@G(CNDR^F{Ap9W(nSn-SfH3qy13a$ zE-U*26ql;FAD(KgYiR?7O+;MDeAr|}dVi9MP;fZFNlS1lrZ_TfEUtu{oN0jriKY>*r-Q18& z7d8W~ND`Fj;E|cdf68+b#njIPiY|3e_Xq*S?uGVQsx~F@i;BpvKs;Zw3jL;(t6gj& z(IF;LdL_@>cHF)gvszPez7V^+TI`$hT0auLqd(eRB;kyjvD&6eCGL~v?RQOhId)pG zv)~zVubo12YJ`2CwH-FgEbKFs@XE>&-*oC4`pQJxb}o=xP(OKleRV#RdcOE9j5Ia` z8_A)O6hNJuj6`4}t+E4gS~|#6v|5FwK4}#dpKquuY)*{rGZ{AW%JqypS6)eWAVr8p zqCvVIKz;Z?QsW;t5Y}KC@umDeQ1iYkTS+iDC{T$+1)^i!zJ@M^iUN7QOR3`@Du7$L z4d{vZKNyQ-)xTItRz?GxQ&!Dy(qi}tL?~~eH^xRP8z~A>Km@H0p#Z{{Zm-b|?~biT5R?Ph1rfOBo=A{t1WY(eFnS5@3kQMG9B>TJd*XvW${2Nkn69+` zbFEEX+#h-B(CuVsf(UkaT`H0Q3<6Fva3{37vezOz3CW%!0cv*!92 zw1Atau$6OFbCKw=G-yH5Y(EF1kr}(5OOy#+*r9#}h_m>$^mHd1dE#)*^?Q{$YDWA0 zQdM#q)2`YrJtr?P@iuz3$YFe{{l7%=Asp6*FV@F>9$(Ze$lmj4K5%17zE>PGW@g*~ zj!4GWU%~%}E$N>pi;riZ!vhld3-p~!$HpnRQk_HhXQ(=XqMCZR)(F!GV8lC$^wMGR zS$zVs17&Zln3fpFo>K?~^6VI`!EIY7>k9aiBAKCh(noLCX;Z=dj@{8f_FNba`{TbK z|JwnZD+QiDI85MqpUy$RWxmQ%0Rd1Ni1eIKfUBsO%-Acao^@jfu_Ir6^|L#YocR$O zbm_9(zF1+n{_DCt*#!HOX`jLUV_N`b1v6IA<)iA~JkRn5gE?EpXytoSHa~_E9gHF6 zBJ`?|sliE7^>5#R#00=D;!YVedb<%);RXe(EEBbVbWLT=sGu_gr<1Y=BH~=%N&T*o zs|sp-a}>?jt&Mi}j20@6MsZuAUiaOi+_|0wHEOs4CExg~qb=NdNxPsk_p_>0?~B;p zcbr~X#;q4G7X8*N>K*#b6C^J4CBAWCP1SrP$d#gSQM2X)i#`VYCgZPc2_mUBy_zFr z0=vR+UAD)IpMNKGu?!e~aEF}K#H&V&XAZW4pR4<6BS4tf{Oajj=L5))tj4s@(XTS! zQ-crU9=Ln`Cgu;oA-n-TT`vlz?E#p9WE`(EhE*NOBS4_wo$eD4qA5zNY>vj1DSBZX zh;u?9!%icCr{#DZhvdjVWV9EC`>gc(L>L}e2)h3HL5uAI!ggrY0|2VJsQJz@?}Hu+Ghay?@-~_dgH|Bx3|J8qLIyfXSWEeEoD!kP0AySfO?Dntks!Ailv>>sIr(6L^O(DL8ZAa0n^-U+#J^J!c!U!UE z@}2mEc_-pPcCSUi-4|7uJ>*O}BKC}wYkEW6KZwwNW^k8STG7;BFF~Sq+Z2&_iTlgvI+|3c^f*$DK4jW_QuWk2%`}*t{JE?k)m2u!7i!)a%JR$Zy{Y; z9jO5h_YVJ+0B_B&4FFL5deP~umvAaLt1jST%F$bT&v=}Ni=y7cD&xh7uW;j2Rq*yK zj(Y%fVoU_+6NYSh;rTTZ&!KfY!tO|~W;5GO>fORo{WZgwg zKP(BnelcjInWUOkmXF0g8`4gNtyM69B)>g?-9#(@YOAzl=zSdS6)q~Pao!7E(`QKQ zihTuuqNkgVhFR;)?9-OJ`W?};J;C>ZPU0=kHm~k|e&@mb)~w&z8Pts_k~4H+1cdrt zCmAi12%M0_V}@SbF|blKs0QP>J;sdP^pAbeb2EYrqHXY#7bIv#M+zOy0h|vOvCBD4 zGIX54%y>!hCUWRQ*aLqaiGYo|3YCy4CKeLFuUG`Rk1fnR28lwpmuO7i^E9+v z^~*1+7}ojjEy){iub|?JZLl6km&heJP>4+lUhM8^VKMpaBsC#^?-7u&!^dd4p*{n5`36aR4tvCvhCKe(L4QybU%-3*GY< zTT;d&qeMwHaVfy93ym18$+~z5a#~0cL+sL=2MBSDKi%0CrfNS7VLdRRkJt4GVme6a za<6T|2gAJC@tF{Z2v`)zxn@MY>8~BLSo^4lM5&B%rV4V`>mf)$b}3v)ATNI01`_rC z1}z>vs~vrbW7nFGbyQ&o7Ct#*U1@E52)4(UJA*S`&B+#|s64@!blR0s9HjkJ#y_%^ zp-qsT${DLGl~ArLRoWNHRQromiMK*3d)HXdEHPWhT)&YsXvezXyVqlo@H3q0rHY+G z`80CgXXt%jOtCdk7BJVCMtCKZR${caAc3@3`4vBG^Rs4BbiI8o>D4_e^J|XGzdc3I zCew;3$kevlM|w;lVANeVWwhqC05r9KVw6d4gskL>rr-UNt=Ow(H7UEe|omk zl>5k{d3yzb9L5%qDs<@=MkK4v*nu-v=-Cv4jt8YFeb(haZV#wXf?UU~9ZHC?vb2pR z=uj;KUJFkIVlGlW!V*~GpzB&6yv@GXSpFjv-=f@WXA6vuzj3ax4wjfP>y6HWzVI+H z{dtz1O=e3x1D!b6zGFe2(a!sF{T)|M`{R;s%Gz)SG3&qp{TplP(OVktGb-j@$Z!d| z=6hyPkz1iqqLWll?ET}k-EY7>Z`9QnM z>!7L7@8{`a{g0vR+vzczE8>N{!56ukYu}KT2KRU6y_;Q^F4{J)Zsg|mGW~Mt_*Pd% zZ?;i8hw`mqwZD0Bt(v;Fb%^F-p^V79k`GxIi)=RM10^-2*Hwzqd!Qj`_a3E6lI^u`BGuw%?{?sj_=^(F<*x6%AzZ z79xB)Yo@rMa(?4((8-Hca%OLS6L}?6)-vYQ6sJsPf<9oWwLO{oi|O3bw4%Cw`&P1>;HG|LBzCNEeHs@mOYXd1UB3dD>F-%Vd6!5R!{Eb@NmGxk+8=6f?8&PMGECpvX>BsKG!48^73*Yrl3m ze7Xcz!$7WR6)nLPo>akZyZ|*R_ANe)zSXiEc<;JpLN;IFRF{r=DbN?Wpzz! z-OV>Ao%PM}{clO6qLcc}FdENhnFe#nwrN=U2P`Kl*x1zgpubo1LqkK2b5^QkzLV}$ zB{m-`>JqCSR%sRtWpQPE|J%LePgNd8g^0psVNb{RWAE+RCw(=8XUQ}zFS=H4v{Oyx zV>%iF+7YzXEEt2)7#KQ&zu+Rh$4XPNhMBb2{hC%9t8(ENzojL%GnPB^EaQ;>pW0zf zN=^O-Z8|n49r$j1Z#&$ny-MNS%H-fm&&Zfh$HP3YGCX@)ME-b8UBDm%=$y@SXy~&2TKn&9H=+Rd0 zT0S3gFEe;6!F=YJAXFIgZ`(+PyJi)#%|q{xDEIGH<#p?wz2-mIxhT@<7;=>_nbp_Jaq54_KLHb+F$+Qa8#tF{BVr7Sm;X(cI^D{ zs6(m!7rExW7M#}zK2+8+4^L4(cJ~yF6@xN<29E@Yx*W3sq?6B_(e!m`S4tsTLecZx8 zBL+6J7uN!;piUP&E+)sp9b3M;~FfmvkDm)9$Ky+ z*f_gt+_R8hb@Z@(MANz&C^F`c05&7zW%KYBTNkax?CsNfQ)G8=L+oknb?|I86@HA_|Ma7RqP5efEv;g_ zWAhbVMdy>oMw>;$m4$UR%o|l1B`ybbN(t1%yedXBwG#W_42SdUnADHO(mOoaFJIz$ zcuy36r=xOOPaoIW-)b#BcL;2P%tbUN@iLOPXb_uk2}1A`|0#+v+B`@n|4I)ym-8m! z>9ff(d*6+z+Nta>O_cvrl&nvrlY1*+YOMp6x0i_64u*^t6U@(=zgS=G+Y;D$>{6o>5f!-#+dVJvu4V;(>=-x z=QE6bLuKXJlp!Tl)7n;-i2Ij{dW2gp10T!9r&oWnvN1RDs-AX1o|_ug5=r7g3&|8c z_*h`EZ}&f=-r_W(=~@9RA;3B>o;^gNp!W8^l)j3S%lVIIL5shIP1b!`d48>-Omj8z zz=dZ)G52nMc7eCny=S3_1tYg@-}H8WV*ozn4E6XbOFEK39w!#p3r|z?OI~!heRy-2 z+ED)iH3sooNltrgl;VbHw2-z*q$N z4!^ef4-FgX{_xmu4wx@He=|dTQdIr^J2Jph6fYvYyjuJ)PO8(z-ta0}s>(!Rw5fXA zPN=dGDvzeIEj-13RpuK~X!a{*@{ML)hk!pb;*RDEy6*5e1m$qoM08Pk>zFThs6K@7 z+FE)Fn_}_q4Q9Wg;D@OY_gZA8v!$hhVZ#5^9#1+4Gd0w)%@Zo?-4LcDK(k&^${9W5 z@uQQxY|%Bma4jNtX=JiTntke!#=}@Xl-*Cqrf{w=`J~9@*LCsDq*=yewerQjl7)yO z9ZDO-$}k3l#g*=T?6gqO*?fXi2rjtspz~b3)hs$qh!*3m;|}6&>Img`wfp`C0MgS% zm4Cv;yYepHKexOQjRezgfO&nq5>2Y~Opl4Zi{4lx{y$*?OC)vd8*`=JATCHBmO7jn zs5y2%ejHWCVK|8l^!bUCoI zE5U!hi5mu`B!NlCXV z0S_SFWbkOZ>iCVET4wKVsS`t~N$ms^`hUHW)l&(Ppu0wIp|!|khWg^UPSS+LJ(v6? zKGb}=Ms{-G%rE@9R<=#Ursj>AyknH#W?RWr>E!yO!^2+!u@AZckvsv}L@EoyGI^Ny zW@+g`8%E=ka=6^1SjvJe-G_;!#(lM)rq-OTbpO}JxXlfzB?`%*B}i<5q-N6@J7D>1 z)sv1fyLU$txnI$>wCL+eNlD)>xDR+t2a`ThmMRha*Oi4bT9b*^c`@JlP1SK7wHUte6Eu^E(L-^i#JmhMk_1J;;Ph!BrkN%r;|ML(6w^#|FEn?>qnGu2}c6 z>@%~!3-8yk?H60pLnSFIt6HOglm^>4psRyd1+wjbr(SpK?qfI^EnM@p0exZD(9)ew z3T;ObjH3jR=Mi7yUOz~)auE8va_07Sd114dgT;L1`htj<`2X}-Zfn%osj8hrRuVND znwo>jPba$VcWC8?IexKg&Vr4WD{hW$Zq#OSJ?(mbjy*LSoh}IKQ*upyg+i^obw%&Q zN|JZZs@;antDn&`H}}Ee%YWx2`nwMH6m7)1itFlL^qWjXgkQsCME zBk?wka*pR{Zzv8PkUqEz#KMgo8J+C}NBc~-`LgF!sFn`k|FzVSzH0zo zr^0Cb;AC?+xA*QEI`g>L#ZG;U)vh}BDtTa2Wd$|2Im8092>0to-tWJco;GW3jaMlg zhW$xzw;DDYrpCI4vPI69gZK#idO%ZxfnEy?bl-3;(71G+**OfJmIrsa6p8-0iJC>K zRU4JDF7LvcJ|FA%hrbOh$bbCs!9=}s>z(lV zJa+2w)((f1#wB#^tk-&l2ZrC=bHuVMixlEXO;SS%c{`K~m*S5 z^2Ez>k$!401c%chrs2`&SV}Q`BSAbc0IrSf8*P|C`#`9?pOnJ|$NG1A&}pH6YG`XU zSp{{q;>RbJ!{Qwd7{$wl8hdVm1-CW5)_o8!j|6Di*2`erWRhLWTNBNz`1mo_dnAMr?9kLxuT^~~138k{EfLD`ZtjQgjHSs_QyC0AL zJ1kVJ7r!z9!$PS1e`f^0Q>SQ_drpt0Ix>Xo<3NOtnXWhAKz3|0SM6L&FH|&WK&@=Q z^WVt8v~u40IsR0n?N0Y;Gj48V^TB>8XZJ6+g0hrvzwJvbt}r2!;nLXEE$gZ#%4Q+N zd88*utISzaX!zfAti0%gv(q{TIt=a)oOuBCF<*(t)=p5GooKe3UtcSw9pxD~TW#ta zzQmds8$DZ!%*!VeF3b=wf+nV9yA?#*N#|!$CZ1V`!U(Yb+g_ZQl{?MRyVDrGVX?&19DPz|?L40IZ0wFD?Q;`pSNxkdvO)RV;#^&p7C7%|8HSqz zQGSG<&zCl#DkmllA-Si#Qk%AdqZJq%bj}f9xOPOXsOE3jXVuGa{g@@lkl6LWQ|PUi zndY_Knob!JGs&@0VnM_$&@hnV#!l);hwzn3_7$7IUTQf_^XZM?%Hh4*nI+gcqj_`j zFi-Cu|nefd!@DHJ4Mq05i|E>k$^$3os ze7bBJ@tWmY&`ZN<2$?ul+q3EMwWTR(Z+6Ng_>=F>ZzB9Ujl(f2cuulg>k`P`txVa1KkvcbGf?gTi+39Jj z-l*{<4VWH37C$5Gx*14yIsclz7A;vT5%aI%bNN9eZzc9ZT`lUszvdU&{-sOO7nu6Q z7;Jm5dl3Gu*3&?0$F|cDs*zx8Ib8j%nphva|IOD{LVqe9=GDXN>^2#M9y+(^fDZoV zd$nvYOyEhqXS$|GE+e{nezpPx!rkJFA7_S_m2C6iR$c4)NRKF``LgxMe$ zFSZ6OfYGkO4-F-|s^TKFAIg8&^6GX%@Ju^)7k=VPO>2yvJZr2J6Q!X$i`-8QhRZFIZ&>j zK9qms;T5XsMgzmSLh&pLVz9C@v`&&D>KS?KCNLua$HasYG5j^v{)Y81o*(B}6;l14(JdB#XN9!RE<@;s{{$d{wA$|zpP#;C!~zN6L_P~oz?o{8S4K>S z)$|-maa7hij+$2P!cJY>##bs9Vz+lzr>oXp`(0Q-jSE(bR$W~0H?uuv8V(R7Jzy4_ zqhKPj>-P)acHo^UGSgf{HB}?#ITPO9sy-Us<(o>9Ks@^FalA*^+K5jc{nq%_2~zRg+0>$)5gsH;Ku z_#w_~44KbO!r`(seB9&sv)+g^r0b`((}gEbHJr_DIUdMrKA+O)63%xZU1!38y?W?7 zE~9KEC&L^`6(nk9z_;HNlvnKAiR>E5?ehJ@rSPSnz&osCf`?#AlKFha{1xP3Y*h;` z1=U%xKto8GUJ~?tg{UL^cXYjRTq>>LOQJu}^~>n!mPH#qZ-F^3xa(sySYUcS+D5GO zse5R){2u9g@uKQHpSM{c!&tiF2WyNM9i(slstw~(Sp;A5J;;9?upxt;i!=I8(&*!| z0$rMc6jw9akEy<`A!`v7Pf!P4*-=J<_&=7YGQ6<7Q9Mibzq#8=z=q(8hL7!$2xPg6zGtC88 zBBD&Mc=G3SeK1u}i_Ew9V&M@?<}>lfEl=OH(+*GQhCJJNO!QC;qLh?sbhWOi!hZxMx!v`-fm|AUU5O;#2#9lf)e6a(Lks zielw4yU-Omj+0lIe^K)tbC&UT0JL?p6yZnB9*n1`x5R@dm4#UyaQFKr_f!lO;{V9P zMo3~b6wU6~ogU9;TABZjf5lcf*i>%ulY{v>0ZYbY!%#?MKzUNVvB#3{5n#Xy2?kkL|KvWgnp3Qu+)itbh}osT4$&;zYT?0pjs2_DP9_KyymiO#iK5dz@Ul3v|qWtKq=)r3u62H)zx<}>Z!lsc-XbT-0)?+H;yR`5XIkG5J7*BJk zW5$J2-dkmSt^{w8DyZFrM^K7tEwUX|$Jasz4Z+GW1#Kf*)evNz-GBT#ChW2^Zwz#( z5s#XNr+H~8L*Gl(706XJyygf9%WRZ>Q)kuv!bfDt!hzAx5x^!B1);eTGdT<78qCqC zLj7tvBgmmPygs-H+ry0bcYOBuLU#6X$Np%lAMqHl$?e56zU}!0LzxfOFLVt$W1I6t zO?_nrZv>nOy!LhNW(jh%Ut??GO~^en)H{zVdJ|m7lob=^>^9MhrTp{c#VBUEos!_r z0KMb5|Cm6Y@?)||xiLt1=Pe&q%xmNL>2}Xz65D*)N=#zlc)4s%+a1uy((y0b48~JN zgty=F)5Nqs9(WYe?!2AOuRqc;p*}g6g4X_S1Z`dI`LLRU!RlXjj%64-N%w*k8H()z zZ)liZ#`!nR1A@y;Alek*+!oDvmhpTgDV*#N9}mCk z&A%VDCz4&+nh*(4r}&{|9I$N@^}ejw8W~giV8?fW({eceQ9sUZ*Mu9{$4aV~BPk=k zM)xbLYt55p-^nd}b54+O5hbMLe9-AaBfy+Ie1(_%9Njr~B4j$|8AIY$>QZ-iNGk5m zrAc2PL+g7CuXhmlk?JY%N?JOw)!048pP0<~n+4XF-z7nC+a+2Tnk#u*`+aM-k9EKG zJWAqYCx>Lt>{z6o|2K{GlU@9E?8kzUCYiKO%ilD3b=LA0Rq27J2|$q_-6dGZ78Q&% z2k+s1(`fVyYPo*P`Y3|?aG7Pp^GEO7+9^}_xFUBxXvJQbk^(OK@ZVb=3t|+VdxHT_ zcXWcHdz?VpGK*=0&9eRHNL^;0T82}}MgO4uw9Od?IEAt^5r;;cm0%4Tk(!d8fz&AI zr~{}(l(Jtm;si#PSuzX*TM$v@M~7<^SWt<=j~3_EKnhDSGkqBS8#Ct)$EW|S#dsvOeW5wUU_VJ{MLbT z_VBTvn$De?;9U#ywZ!t5i4Zipp{E4?5IUV)r&jQWwUNC$-Md6h-jtcCdDYQ^^cxAm zbUILxlnW|?k5;28T{l-bb3)TUj5!K2;=&#?@9v^oS%3<{myggTU&j^_j5GyNiB|B@ zb1OAL_MnzL6nXpv6iQDwm+kW~gvG>Y)IOXPm&{(wh3`CR7~MbQ`p!7 zB?h;t9PHO$6n_Q~opE51=tS6MPv2PFhsH;POCP!=b6(Iwl-~m5F^^H6t+J5I&nae= zPa=Cp1m&*_~MTs#Q}fj%%A(*u5x8HisYmLx(X?Xy}eC5a4x79vTO$aazY*UsLs#zeO$x)?=rWi zu+mj(k6)LqV8P~j`-BnKrzFn#+N8j&!SKCoLqnfC2zstF1*N;j$H!AN<=N6s)v%Jq zPkC*l{VFy7SW~r826Kf8BV1D)=KRxGD)$Qva*-%L)aP_u-&ghRt^WME7;L-bua+am zz5JTD{M$UMc^rkBQWnF#&1SET+hcI+D-$xoqOSyR7e1w|5@@a0pxba0qIw2&vLd^# z#;#LjKr865&SEk_5M#Xb={=&=<5HgpVh~|JbylzdH6r|WBG=cM=d`Od{T`eQS?6W&8npC5=p zPcHEuguO!b>>{9)Rs6T;-Q1dF>)1NZM09;;wlcE>t=}|Sc9>h8f5r`Y7GoVtO{s-x z3_jazsf2Dym2<_#R$Ondjv9oFmJ*!XC-q`WFBCd6o7+ylilpi56P>gq#yI$#L8AhR zlOmrA;_fd0#GpeV2kq^Vq{gqw-!ZH&H`Ag3FY?#>*Ov7s+XcIEt$lJgvCROI<>n3= z#Mazi47%>P`&BYBn+vcOS&1-NiQ&KyS;FnvH=%6cMTMhtN7|iHL~PY{2>QY)VJp%d>1J!!W9}oL(C`fc6tT~T9A`T(Rz#wum~S4%2UwsVicT-EX;#i z;(-~(xW#S$cI+G_bDEu#j23)hnHJR2IsXK!tDszj*P?Cp;M;;aenYFc<1LfV=7B^+ z!t%KU1ii(+f=&Lt%7_STVbU?~C6(}$pWnQmJGjkodn5yP(E64ZNjx6O`ah@bfJ6^P zW(`BEmQsF~^`q^Gpb3nhfoJZi195L&s65VZ4{FA08SmN zYZ$)JSnZPT`Rhk?ribEuR7^ZB?4!}}6cka@_P~8wDir)r4-Vy!=Pd{8x?;`-# z-n*tIsIBfi4-A(}gA2uoq{5TH{tjBatpFk}qH7sPwsB-DPrn_5OxhT@zp`?-`CEeZ9`G6=W zDN3h+AdS?ayBnmtySw2Vy!ZWn|8Y1^%$eD<_nx)anxUJBc}22<&3*FP#ev9<|3j_h z@LZNra-GS`xkd>nbw$Mo*Uf>*7JOkc>=X`cn|1MX?aPm%4-LhZ`ATXPp_+c$3Zs|y zOcr@Xxk6w4{FO41U7a&EO`Vab;;y`I!_BCDHUnFPfHX)9TeItH^Rf2srz5^@hT9tR z!Q2k}#2Nw(<2bGfzTh0)U8Xkl)_OP@Q=j*4CD$fHw6z$sAK!iopq;W84T$;%aWdNUwsP{)xHbMiGwKtLc-V&3oow8#`S~bO>QQQCd!v)_#6y|U8$aTy zJ0RSn-Qco!KLm!IowiObqRmK`xz;U>xA3V1Ozf{zVs z45IHW1zjI?Q72E*{D6=xZX6Rek zoGj6bCKaXB2xsd#=aBQ)95gVd+x&7QE1BROfkoHbD`_p&0)cP z_J=h&z=}z%VmFofPWVeVy2&Nl!cRviCwS9&eHTsIcM>5D}W1AfN?Cf_XE)_9Mg zkMMRF@#|BFTfum(SF<;cgHU0Z`5_ip)0q2c?ob^h5Y`#Io#zg9#Rz|b?aZC*13Y<` z^zbKC5A>GsDBz?}$X6zxgP|Iv9Z+mi{^<|Fc0sJ9u=r~J3-q1^x9%gWAE^VdFc3ll z(2r~g!9imHx3kIHJ1?~bSIoQ!5Eep)WbjeQ9-b4-`jr7rG$$gN`N=I2(T~>TDO>pVs#y1qQ$5a*=fvJnaacX4 zR#3ZGT({5sNqbhKH$T-?p;7yieM^`Vj}fIpmpw+vF1TR7pghsTZaWRCAAsc*W3V)x z1XRrW3W3t{N}uhjjj+4(8@fOJ>KEqI>{vK7qLQYj$kqAB#C=HWaPuhAyve}#_&zXw zeg}MNWb>QQZt8c6kJs$2+98+Luf$@m8Vs{(K3xAFm*A(TmLs3)%cPuqEDfCSJS(m7Y) zdw!}|uSG3v*p-0Gp1=MYs}h=iZ9@vOE0UFX95;JVd8BW#fB5o{`| z@g9GK6Vhoye=PYK!5hmRFU|^-uDPskRM&KzP(6&>wRJJz`e9a-1<#CG`&%Z#Z+jRF z9@Vz|*M$9cO^`A_K*#chK5r?#Z!#@iV0fEO%eJMAKF0eyK=P$tr9bOiyHDT`{u(f3 z1Yx{ko>2w=CQP4YCK*6SF?3>@^NVN1Vkd$XBLT9<;toJ_<;Yf~(AUDzkq=za!qfl3 zIBK3`;m3%5xYnw0kYPP(;?#;c)<8EA4GI>gg=%fV+&T=Xebuxhev+O81NR6BZaHw% zgj8A5CV>%s1(FlAgn$?RKGOt;S!1D|L`^rvNEkL#F|Y7eh)GG0_3uxqD8nZb=BG8g zzUR4OZ4lSHuJbU*X_1%CE@K{m2p}z^wB%~?jaWeOAXE%H(8!-wz706K3AIEo;gs6v~QTi&GXUyL={qLh|RbqMLJ$DYjY=6$d+XU z`V(w(lDlt{8yQbqbxGTCu-sU$vJbPX#h!lVRzvk1QbouxpWv)TWT&$GkkOuI(LZQ` z&*e$<;<v7XN%CaPoVthYxV}B;pk6m zmLXIM(LyLtmkxN2wlAtY(FcJxvZ@Sauc@VQ{-cQGfD{dKw=e-AcFtpVjP{HR;bJ-r z9#a3IVRRy;mNLjz`w1d|^j^F?c9GmuB?6Et9+{BPo?r;b450jse z+WYC^bZv%@Ewbwf0TQ*f8%kBT)BEHNCnkV}DNsls2MVFq8Hih)ygyM;0LC&DH3yT- z;z2%Z8PVCeTxRES+W@Btq_fBAlM6;T5{iO%4wS z0IcNE@UJ#uz(<6iW>WgIxd{nmEn~CjI4xq0WY4D#r$r_&8l5ky1QcF9Fa*Vf&bV%y zL!h>G?3zN=2V8iOMr4}A_KROdP&cmL@4fP6ixj^lMFWxm zwiS<)k4g2pHm zw(e;Zt03REDOx;{swr|7ZJHrS)Z362q*@WEPPh^jJ5?q;h)6MXo0E$jjo1)r5+Ky zPe#T^9}bTpLH373uq{|yJ~Ux}Q=9NdhC2%KEPcrAPhkkEG5( zK13FONrt>Uq@{G~V|<%=jJ_785OHi_|CMwu2Ec4+$ZVE_G5l03hGZ5#wqKIwU>`*S zGAyKB@jdNc+k0`h3SAmqqsS=ByWw~?wZ6Hnvqis;bGDIlJ}IXc=X=>(yt*+-_G_8| z$8G*3HH$6)qwXujL@H0$LM(t?m&*`EwDNm%q1YF9cJnau`=*(vrDJdXYh#QFpPzwe zd#!Xi848pl!9t>Cv}V`ES0r=U7ESnLF$ZA{?A(MwZS(NMXm9Jx>AduOK8~r#Fc-9C zrNG;v>Y)%Q6+QWgM^XY=O9IM7F1#ovGcxSm18>=vCK{rtZEx@Jm0gYucqdZxqBV*$ z*r@0E`)_YYJ29CO!}(>~2m5st=JNTa~fr0{iRx+S5ncI&k4Ez+<=%ZV8F^!kcT z4{Gdd?HI^)-jLSY6-iC51}1rukG|Po3&0<0)N~jH&_Gr=w@ox zk;bbj>Me-^&BVwRo9%>>M$(W`aJs|%5q&`JVPT%}I6dOKiv3p`Tr_8OqG7l!YB%3a}nPZ*OblMtZ+2+pa>_0oItg#R*GK0Ct{D39K&KxUm&?v<9w-#j-pHq~%*S?qC0pWnjz+Z3}f4TfJ@=K3M#C`w@ry3=EIZq7_9O&{4X0D5D&k2ke z4WwV#O|u!5*7~K%-VevSG!QCeayH0^t}El z2h@?C;f9q)p@GHy%`(6@d5&m@Ad2xo-UZam_y-i+8HVx>!5iJ81V-ewY4yNQX)r&} zi&(IFn}P=dDVLe5;>@yYip@e=G|fA~)3l1xusVC;t}$~+ zLgw~$&(`l8-UWSsO#g}p7WU(QDB*7dNs;c*dXcCRjO=ZNB6ujL1_EVhept0oZ1`#l zD*VUtCFtthfMgpZPfl`^k(TAn_gw`mx3@5Zyk{z4(ZeHiRHeGgM0?uxCNDZHZ1$IS zcUK+HS(3Tp|LPxnSH;^&R-OvCwcj__>Cb^$$_5tH8UR{g(=Q7HNmnp#h58`=zx#ia7sRtb) zz3KOUXLkEP^yjy657sMS2M39X%i&KbJf6A`*GwLCD)HBDQeo)=Dqo(TRAX%9qzh;d z+22+ryk8($Q2+7gVN#6GHr-XE8g36aq}QEQ{+|XUlUr>Su;DHi`R=0gis~_9d)jm> z^dhntV@6N5))31eH!mX?6Nb0dr4)k%v#pmY&*~^PFugh(eAb|`eU4h+m+lw*I&|sM{!erO@!wZclFwI~3#3+Vi6<$_%%6Q*5(mBu zX6oW`3$ORCf^VQxI}xrPWK_w6v$r~~#X!s`^Q$-sVaLTl|-WhXlg7Kf-wR*G_p&ni>vpx2?CMNwFYdY&`0OSU* z$v9`rZSePgH`=l1QcS^|r9!=>3VZbXkY;f}C zJbVLOjHY(D4-zm|z*@?=)sAyHwThh*TMeP%y<5wBTJ|C6~>2wf6N5RGc4sm<%^%+E&^Jvgfo{L*+d-`0Lrqo{5 z^=Soba!2>+q0E<4^VPsQ=47FGc|g{#0q$|nH00ven&MideR0Z+HyYGIJyZ^^5Gncf zI?lSk?+Codh#1ICWKtlHh*B;-Bles!d6dV`i>MEea-K#a{+at3fFG8;ODHNy!1mC1 zWD~Lt&^o-543n3hSLg>&ZFK6}T?wZ)cln=3=ST-+j(6oX!Q0F79`2_fEc54d+YSTA zd?PY)7&Y|R!?a`jO@Vx=_YOTnrr2iDIefh0_tI_wqTpIu!c*Q@s`Zkp;@AQ{UCtnv z>+r#exzT;cbeFRWcaIiPQIFkkaXt{3hHJOFYO2XrJLmiZg_CVwHH-kV|6uq|s5>{W zDkZp_ZP;5U20kJKH0jbJ=K`ByEZ|ZmI9<@@htCVu3y@$;!B3m70>iPP8Pf@oPddRV*$l<#j#^spL zcn5a*lE+@a>;+=+Ft;F2m{$x7`5?!VhrI^93kwyPloj6S-EdElH#ZL7m%%3g955}M zzNufM=M}l*0$lD(KN`4F|7Vd0a%hez-vBP^SbyY@#c}bmt$ZTbG65{u;vY==q92$2 z!^{7%d?5e|4J{uZA5G^i?*KCQr+?HwVlD%L^FItN>AG1d4*2@w|K%U z9~(fIDzaw@so780B#h^B?Df;<(-~y<@I39Wyv~XudcTT19Oyiw%7GoQB|@Ruu+)(> zQBFO~ozL23mx8*6SG}pRXG1KWH2y%$OxlMO5mMm`;b0Hc_Xi!DwZ7r-GVUMe{F$xy z|MA|9B=e_B0umA~ww?ZUOC+Ur{9=hkzTS^C?aY(R>4Bm_zxp&79@*U9mMNnuLujua zq)BLMR8!>rUJ+v@d`$@^Zh9V%9~Cy;*St;3yuy1(%1rar2@blUkF3gPaN}@ph#kxY zl4y@@9vs(4v`Hi#6mOjD(uaU)XKS*qf8W|4dnfN^eecwS`LDm16y(4PSWkr>@71T* z+5md7UGG^#-6m%VmyU$5LafAc2%mnqgxnm@`gnkFjjP*?5219#QcH+Ac2ywm8O@g( z5x`WBfb>M6&JHT{lruBehAXsb{Rv8v|D3XY+bFv{b zCCV03yISr&pbBv)gLw>gP@-4Q%Zvu{O&n|>a#K#(y9l^uAc~=yAwWnbw+N3vetrTb zxp?aqQay4n^4$X(V?>V9;pW>|O?>VI7IyL0y8k*>$NqO!M^Mp*Kg$MG;B1Qf~io0wSeZ{1ip>G!Poiv5`Ww1QAEMHR~!o869T3| zV7;ZBt(F~wvcgYM9N-UJe)RqAYS`bdZViW{K^4X7EHED7^>)(_QvK zRi$zF#daF@XP6EX??03MGfiR5J2_p}9C-I*Snnrzws7J49PJD&Fa zp;|oSgZV4WcyZ*9ueElSuYU7a+pUr3H|vmZfE=410luAOZgaEc^2Jp0_`&XVq51pQ zhBNEq<*r8o&*n3aqFlB`z3Ql4_h$NI)*&UYx^lWfn{28J#@~K}8*E_iATIo_h6AyU zQ1C!#0n%LXYK(>N`x9*QGi!~=#ihJAjwk5LGD(_1P(4}Mf1QmLo!*#_ZcI=ZKT4B2 zFmOz>vj%1tNvS>1OS*Y8yzeWFrZ`(XMMZJm(cs-R?g~AWC!?w{8?PH@U2Ht$Lu-#; zJK!!7YoyViZv|*E4o^Q?;mwV===~<7^ge>^g^wI+Ztk16Un%e>+Dhw65*ljjkR$93 z?!zCXdyGuoIr+@b7*wdFxxmKA`v_y1-^I})vrLdcuVX1<9uONmJ_vtsvW8@;F*GK( zbYf{R8&tE}OOgM1Fr;XrmBS)89Vx{uFR*%ZKVXpAUQ)VqY^#Ny``j0xV#9Ea3i5v# z9!+>nFYi%k$8`YK`>9uGw@Mh$Uzq>tFsVv@SUiB9{&Ua+0KJWx>5E;aZ5E6M`Tt~# z3`|0_iyHamjRXrcUqJ|X94PtV$;c7{8WkFC8y`QUuKF56;N+@=f`PlhvuZ%t2RYbZ z{yl$$JQK^4p4}y5Wx8^d7VgEa^NJ4LQYIZ0uW>&aC|TVlH?q&PV|lLz)b~33w!|vE zAPsspd*K?>TsKv<v9E!y&kPwx(cZrOluG<@JXe2kUd{HLr-ewv>{UjLHvzU9e!n znfsmVn~V7K9O3Az$&*lnuggMW1`m4nDtoTY(K-1q9sZh)xc(=dG@kZJQ#e6J{qXC3Y+8RMOkP@Vr7wjh>;;eOhjq2@Mo2 z$(RW(=}Rchjgy`TZa&Dtj%$TVqw`^aKCsx^?2NPfL0FAj33E^7noeAXo~&_56E`<- zv%l$R;58>a+aniL2dHdR(#F+!Bn=5M?vcljiAy~?L=6ez!Yql8ZZ9lSc)9IS0jyfK zf|;e=H>n&@v-Uz#<`?<~v4sA<7KT zwX(DQJg?OG;*J&EDE<}obllc{yILttLFr4qhYoqu#a{`l{R}s_3t~>m=idt6|j@_k4iWln4+5-ZgO(+NO_rxYe_s1j~#7zO;0#1F!WK4A)P45^h}&~V{CQ1 z86pjDKMf^mFvxsky;y?CZ2nj**a zl>R_|=>%jv@FEaGwrj2!5v4$4xL>6A6oZJl{D#m1f6WkDi^8efa(>ZgKrxTl>_<IG-9`3)U%!+oIP&jlK^?Labp- z931KWQgFXgkzoYL?2@&QIE<}V`?Y#VNcEi!%zoD3J9e?)2$ za}nzd2tX|=4t6C3r{%@cA7gwAqyOMxj7}uqERXlmw35<$DOZYFpPMVa>SS7D3`AGK zJ*RK+T3W4;&sN}P$Tnoq*nW92Wb$EB>fKPxhMnaP zqg^I$Dkh~%>tFs_3yF<{FOJxN%J=i*QVk}Z2l^qZpBMxOZ}8k;UE5Ekdw8h1%O~;h z+?m5_=O1o!D?t(-;5rg~EJSQS>OUvnvpHF^WPn#%c|~B48s3j0-}hw`R*$GVRA(}> z*D<6{I5cUHtBCMPg@c%w2agwncA;rVGsuWMP3SXALrA?_tMam8l)(g%eej1AF&v-^ z7@h9goQJ{)uz)l9J^EP~*i2ypB8Q48N+|{!iM-^oOY-I$KJ2m-bxM)5M-RKcmEjiT zJvZ`XYKebsa8fo{ro5=qbXg6gGRBN`bVvC(N6unE62L#LC>g5$0{c@~79HY4OJ1B$ z+DNAO=Ut)|1~QI(K2UrdryCMbp`G)vJ`8zx3drw4vz`lpFeJR2^oyydMq$#BoNGW=sKaCS(J)r{BWvHJW z5dR!b%8V*^IG!l&+F>Wlh(xN4Jt};oEk0W3V~dVF=uO36vt`Tmgw4BESyEfvDV(W{KiA5spW9cGZf4fBX;xJ`kIX#imdOXmo_+{h`sRKIC*@JFr@J1KkT#_yi zuFl{|E>OwYCmE4jq>K%2_y$2D(m>+C3M3AW&N481d2K=-*nVkkgO_3J53vs>euN>gjRA5scT3Ox6rnhzNV1OP|7~Sv%#( zC{0NgXg~qA-y$^B`{d>@8=lQ-LJ-Rp?dThdjImi7sXT^@?^*<^)V6L!hxAK5u_k4M zUS@d>UQne2cTmp3I%x-tUB0?Kh4|m5f1m?G8BqAWfzI}XM8mi1&+p95U~I1N%#83~ zks4WpbJdH3>E&W-n0pkxsjk;vFD0&I&GUB=#&*yvzBgtHr(75OLU>)>#ZqEAS)#_G zU8ha(Tpcf;7R_(toq=0%&2Wks2~vgekZbJ9{;lVsl#!Y18eA(5PQP0}wEwPNkQqXw z8w`$#%c-Uj(=I)V`$Mmv@M&;{Cd5|IcJK)i6!- z(U>99v@&62F6L1%5K_fJ1!U#B@Ak+;t9glb{{5$?1fQo$E}J2ec9SmGcx-kSZIQdf z&kE3@5u-6~Bjkj^rD08s9&H~oBzt&!U%2Y0SAVEAYEtIRV@u1nIz{$~;TVtI z=-HC9*ho|SrjS@XfnF8QEm^CXT+2^EmRHZ9v_MMW7d|*?Bf(|<9zxp55}wgm2UPYg!8h`B z&pPE!=|fc^eT(S5445s)?{#F?yPZV&6B<@QxieuGHU|m^+#FhY5W^Ys3I$F;PQF)z zb3sb$#c^rK8BFFMTAUOiIU+<Uj zfl);uUp#Y5USGshLZj)Mq?R+*_{L(=kzS0D-yAd%O@8w{0DRBt*b66ww+$C5v z#JcjCIljBLQ(DlNF-n3)LEj^J5jDN1HLA&5aZI~oF%bAQ4q?>dA>pQWY+jZMnBy0Y zWe3kW#Xv26Fce=)gFVzi9(y54I8ueNY$lVZypy4@m`-56C+pegxj|j_5jFFcN*S*v zsFPBg!Oc>E=aF3WW;dgnxi#xaAZu>|0{xfJfA%6%k{Yr4UY6KVnf;c}o#lyI~lnJ&DN8jIBrrCaP?!ym{oK8 z-(L<<)D#Oh-4w}5I)qV54lO^L?$OnPO5fxNYC9Qy9P5kb>m9}!ZszfZW1)V!ocL-K z4Afx2t|?=I<`30bZ+#o~Ww4`f`DmiPxtRRQb^_bjJ@6(*?Dkez389%X6 zz!R-RmNmAfEQ>s1fqd^J2iG+LZ1}rXP*J$|yhJX(QXOlJyb-vYgi-C6RSxvFtBD8m zgucCNvttaFHeSG@t=}v#7epuAYIIG|fAG5O&^Ic7%WgB12U=&*I0~eqII8zGVD5cZ zf4PvZb&X5oiE1r=xgW9_7!-85s6=D5{#lQGWOT_ei4IjcbmX?8t}ZzOy2%iDN!+O7 z6@CyVqo<{+JxqKh_>Xfy#68r3`-RGvm|jW0*lfbZM6h`}a*AkGhZ&TE1^H7%#5 z6?_~~M;fjSIVMz(@M**wfrEFM6rjYhPVrELNxxBDsPKp2a_yBvFs!%g{aEZPiS>Pk zOZrQJ?BLh{^Sl#&WHP6BH#bmkIx=CmR5rj~4m+GvjlEOb${|V$3JG7P6iE^=4tS5` zA%`3O=lK!hsJ=jWIG)vvfn zEutDp%T}(pv=oqmCH;O+@68>peNK}yOcvQAXJLcZYRvNsCW?$EBk2kY4}Z667wrH? zveq)1wPTZVAO?zu6(sz@dgVoX=(~6P;Oi#Z0ZxZxL3X}8!9MXO<(O{dzirBqrX0^f z6etzz!C$eAd4Fw~0_Q2=W?2ePigx6^n|L|1KO5K)?IA`+iF>@7D$>(c?9jD) zTAh3|oqD4+WFIm)sksMj;QLnX|ATICd5&v-@lW^{LIY^pdjWBOy?VQ_N1(mLM)Yl>hh11GTOm$C;G_2YzxeQh^_VtUGniq1~G~Wbnj0iJ{PhpzQSz0 z;3&&IQg-M&x|Q~Lnji_^?{~5})!%yBv%7T!@=?krd*8p)5)LJKg#62kRbD%-iAjYm zO;tAsbBGB9ebJo8g+zn0*!7x~?GcOQdn|8q?U-VU>Q}ZWS!two zDc-qS`4kMBCo%}bxH z=FBbGx|Cgq=(;kqT-90YoJT9J^>1CQV+Ui=()turE+>7f%gmgKrWc!BJ>C`9e>D9$ zhxmQc=L;9Ok!>|c^+#FOCnw?ZcI7kAFUOD%y1j1Kcxlp{s-;3=)eDbPIcuv(j+p?j z^$!DOu%FSnOsAf(twyxMCfDm8buE=q)-1~5a4c=)Fu@uDlxFP<&vMniV5${jDQCY*PtEvN6QKaHbmr#+Hs<2O@Wq!f!e z{-<)YKn@$J@`x>8Hz7LSQ8knxVu@Pdt59C=ViRy!CoKEVuf(~+nU(xZS^`aj{t32R zBHz?3f8@c$vz-0=3D*%q-^OW=cX0hiXh!&mO@S$nL(y4iEiri1$8VvFP^7 zzD^b6?>R2rF#^lkcx^C;aOwo6?Sy)Xrfh4OBHg)A;n7#U(Ye}lp&3S$-=D2_yrPeVM{|5TBG)R zr}rkitzE^mdf05`d2sXn#qE7pqw_bJb4v54F%0hmo98@6UFW=RAt_Ai^Jvu6^~>9i zSZD0f&&OjdVK-O16>GEinb#?6qY}?zo$Ubb5j5|?)OT7{S`%@8dfd=(OdIIs;qxV$ zp}=yQ_m`($COA0am1I^3wO7iOz=5Fw^fyNQEhc3@t$@=mo5-*M#t$+H#J_8L`65a)~}NH zh|(0enNyQqivUw34=1kh5#a!lkmqbFxua-D>O%b8Wk)adiWfR9cA8J}ZQ>iEagMt2 zDKkMDI?&AX9?69`AR~0RQ2eWgMOX$gCOEXNq8WOrx46(5GB+roapt;O9~4{=S@Dy$ z2n&P51!adDAo_H(?HF`_3$TE-A zA9p&*pDrf}$3J^#Es0y8Khit-slfZ|uRg`2XBD~w^rX9S^JdeobEnl$=}NtKtk1s> z#;QY+;IPWOyNWq+YYDs8N5zNecMU~1aVtjG!_oxnIk!3`<%wb!0r&Bx^JUDUKI1J| z%<2D_9B#KcrU-s5onys$)^*kY!RO0C4&jNgBh6x3J+Wnnz#85GX(Qsw%q-Z$Pc`@f z&{fu@Y@`AEen*vb4tr#}^w8VX-zB>vZ3uA!ggqjdOUcJMGv}~fa|E6iZWA0o^ZVrzHBnzKTZnCBRBGu z$aDRy1%~gRoR*NLMhv8@RNu*e)tFmgNF+~=(_XgP1id-H&-jFR<&@PrtQLBYDziy6 z-7N4&=$y#sDjYmx6(_ueS*)|vLGh#y+vu0Qe%%7YtZZ*5lbb_S)2k(F(XWIlY)}7w zw4HpZR~3-KJaxie_{F%&rwiO34h~9FS;YwFERY0!pLInL7w>~Uy-GJZ5mp`yyzure zt4OC16=hBr1K1cFy3c~aVkDn54ba@ud!aOYpPbJ{B&<`4c^T52iIWRy;%{Z_O#RZ@-pR<^$FTkZ|6;n*zK^G*)+`dm=FMoICPtyhA(eI^-n7J{GsaggH1>c&K zvyeYPwS!l+@RIZa8A&i^`p!HDhbTMCm*DgqO5${*MY89@bOYJjjq2~Ar)u0F31jZ$ zA{Qz?Lc)v23Fn+DiJ~oP1~Y{o#UmOkyo3eZZ{ZNt#=#|g{^m^zZBen%{=m-@FnZoJ z?CdG8`H(;LvUi>!Kb+}d8>=utA*`nGFQ>|X?*3I_!; z&4AJj9`b{j0dI6y{H-azeIamFVdLAYA23;eW@Kb=HYt;=kGwAHx=T9Jj%n~W+2~a{ z86~33Wa8<}1GX*!48rOkM{Jr->~Kc*iSGqve^;#I1==SFYfPDMXiYqM`)GWnmLl5@xN6)nL0ZH zSuaR%@9?B0#=XC4u=5`c^vy6CJ4Au&9-f4S{GnEr#t@>C{^3&37Rg8z>y<>U6`|Qw zFPQ_BUjrQ9POXqLTotUavt>`|%>o_6Y5F$k7=oMC_-0yd_uZMwec8Msa1Yyx=EJO) zEEM&d)#kg)Acgi82_8K@x0^ko!zw2lM)#_UROot>OU};TnxS+4{%m^a=%Y4U?E!+@ z>?swk8zh~Q@OeSl1#h&MdEHh>#Rq3tV<3jRUFZ)O-M+@4rbrFNL>H|sMFn5-U z@K_8L*Jf@pf5%rV>MC`wxW?nvI5_K5YEd&r^lDdDOq691`C=oO30$P ztCy5vOQ)-&8_e>)=L9S9bApsZL&Dqi>b(52u^1aTnR9uYQ6pYzA&RQ{4pEtJzM5Zd zHw_-6$mdLc!;Fn!4KjL}vU;)>BU11I7-J;uzzN?EsrL8dcE_WUSgWZndg#9bYO!Z2 zE>89DdBzH~6N~SA^zW3;b|$&*AxBS#sD06^tRCLurbN~OuL7aHJ9?4ZNkfB8-{r8_ z!?m7@6`Km%MChhtV0hfk$TxAbK%yyy=`zkWKix18tdMQhhGIWsQD&YW(s1xHeor{s zK)u7bcwEvC_=8ErjPo@_Ap9`$9jyP9Wmaur&?i>5n7SoN$ zgDo)VHqo-_mLtn(CaFAgluzk=v?8xz+oW7A{!*{n3JeVy`b-O|G9lNeh`$|p2d;KO zmYJj+mf&x{evcwBtft`*^;$vNA-Nm-=#QE_>N-ZWU>gl3t@M413w<8Xs^LbWv z94^EV^Zn-)K{Dv8LGuhs-#dK8Jzw80eJH|dg84vTAr&s3;Mqq!^GK^}1yH<}G<aV6<-^?YkuNmTwKr~34tM7}=kO11fOyj(=Ci4UuV3O=}|AK5X?etZIO8?(Od zDE3r}*`)-TzggLZ{9dTI(pQrn^-u$AVieNn098_+_c!`S`MZZ1C68Uc#U$8$A^|f4 zh7Hi9ens;@_TXUU`IjXgn6R3_T*w=jfzj;8qaGUZ5QQ|8f*#{5idQhZmJ>czQ#dS) zm6s&m+QYxj2az6EFpx&PK09G=tbJMCOeR>YC>s}I3cbN1o)QG8K|6r&ze zxXi7aFu)p;B20yQe2(1!@$OnL<=6lPPeJmI-&cf)l>Jm!=x_ z8IcnZfym?Z+J{u=hN=y}iAGGBR0Ob3{LrN)nWqH+5Y5|Ay<|B_!6pP84Pzmz1@uF% zhNHkG0tlIFkh{W+ZO%b4V?c&HXbKCjfEYN? z76#Vcxe!pEw&;BQm5nnp`J7hmE$@)y>r;UG^n*k$hwFT(wYo>eS~~^%e5i_c0G~Q# zU+$ko-u_P!qxaN62V(h!p5!Akg=^)Eti;e2TiJ zooLg5Ha!2%W#9kGFG8$t7n{HAQ$t0~SivgTn#kv$ljc(4;V^lr4IA_!a*VZ|>EBtA z&-8>s4OwmL3hE=Dv(8Q^7R)Dl?ZKYGS{b#-BtyYSv{s+blxzKYelXazru0el| z-@Sk8W7Z=z{LUk_zI%E48$S$PPU(*h0K%mE>BEmB&>*3Z@SoKZB$AttD>XDRiCsY$ zk%ub8c3}w|gZ9bTh$)(!&8!N`He@@mV~2dzM3_+ehBdP%HuaB74I8<%JuUM}4@CU9 zZoM{`y>a>b%jTs8gqk~SHutAXf8WA9v&y0il0NOanbe`?+6;O>b{+HS5bg2B@e5AA z^MOd_WC~9F?@A9u6R1@ul9GMCgq}mT(K9l{$liNg=dr~OQ5v}Cu_szZ(_LOg4HnAd z*LTZBMp{*mH5%8~X2PFCqkl5~1|gb1Bw4qP7o=H}HgD-4!Qdd&R;KBsEl%Gh2yXzo#ykCip<;zSlbuffumkNQJH(| z0i$(~EtP+%d&<<>W4y=l^PWuFfJY3=3D?$d@bR6u;BT&g4mk(*#rkC$T*UzR!WL0G z(=vGQs^0@_>x0Or3(K~?-}&V8F{5e#%PO}Sl@#(Qw7EZRRdgQiolJQ}j&xgZn(S3& zGi_wBA0m9*H{f^^{p@$ajBCpJ9wH2pMyi_%?0O*}^^o!KSDe7#V^_jYs4c=&iAAWF z8;!-*F896t4+(=9XaC!$ykCgawQ!LQ+Lf*?BheCS` zD9klyoaPZd1}XqP#8i>bba_>Zp6r!6sr%bj!$$AwsC#)>nc73ZDR8pL^ZIh7f_mlR z#cFqn64-P8)BY{yHTCV|u6I9;cC+7J`|~00qu^*%0!__hb^pIqB0EnEcdCQyMhlRc zsXbZ#<-RI&-&L6E8!$2QE)z=pmk8hLkyce0C{}wq75Xg*jy0&ACD#7=)s&A&9Z34v z_Uq4Q9ne{2Hn$T*>dqNDf}S1iT`%+%(JeTw&!XmNn(sFpz7cYm7R?XQ1qn4GB7^OzwIpNxJ!p4*@0lAXNjR(fTx29ZHFSe+SAUt6(+Sq)PKp z2hWV-Ih&JS>L62e&P0-6WysvGy=T05cZMg zFmAYhmzVVAP=DFL@`8N%p6Pjo7x2wV>uQ^4CjPqzc&ny_8Zl@@iZ<)CxVhZtPbtrZ z1O(gMXuLk9+(k<1uKS}>uLS26K7F^`GqLwx(0v{|_JHPGOyj7^_h5yUb#^ekCtir# zbu-Yl{vxOX#OgGtst_e8Mu^U4d&*1?die~@-TLeSLmqkD^Wo!GA9-x`dKR?}w1e12 zCHR_VTd<+Ave{b%Wx$>g!$l;G^t@7_#+K(2nHi9CyJzyEzA6;vdH$F6D2e_69F)>{ zK5Mu?8y_C6cDO)Za1nB}$Sj(6(GsR!f7am5yI&9G!3xb)yi~f@6XL!&4h+{|?zveo z+G01=E|NC-6Sma4{w%S!rcdYExxSpOJ*c~Mznls`8^)}c3b6YOLtj`*bW0)Sy@JCglnQ{?ii*|Jx zaz591DpXDCGy6+_vgb==SM9Z^!>}nmvcs=iqxF|(sbqR1r?y~|;Zs^*ru@Z{roI}# z?(WM6c%Umav6*iGKrOF3a24c_C+|V_<+Y>O(ifA zq{bVaBhF_*8l>9x-hBRRXR>^+|MuYL;6pDR?-d`up&`}SQhQK_qboW&n2LOvW$fr} zM;dEmu?(|zT}h_T0vv45Z8d=M;TmXVl4kNxh&2P>S!HxQmE^Nuw`b(*@;lYNq-+w> z1g;jkX)><8Zs0-Ssy8!GdL7P^o6Pi_(>FLkX{O`iiv)3%Z?q8l4bOpo z=l2lMZGZkotR-%WN>X>c3(SROzlL;{+$Y}=JKXPT^nczqGfe_m-Qki%V-5Up@H0O< zHSO14b|)S5lrislT=7tQTtc+2Q)NZ(p8P+izA`Mz?)w@A2`Qzd5lN-HL68t>>F(}s zZV?e_0qF(-L22pkZlt?IV(8{Q8>EX{D)=Z^ZO+nhl3xn9{Gpa{5E7GaP-;B;zD8IkMJ2Hf zf{?QQ^T4nEdEhTLj!P6D>>s8-x=RnK%q^J0`0E?ByfC@dcttRw>qNGLLvTRw&#A50 zfRTBrI%!p`DcMWmN3@0&}HeO=&qUJHK1k-C-5{F;35=mY|CT_a+(6 z+UlWIK}Vj$ry0egm~ao!V1fza?~_1`hfR-kFzYqo@t2Ay?>s*pHm93zezN8Fz4!A! z>NfA>%g6Pr1#>0aBdHA%ZN+2JpL-_By(kZA4N?m!>+Lq7tXUU;QzfPZuiH$j#GW_7 z$|TZ@M`dRvl~vvLW;)Vur_*77if{5h>DRbDv`1Ko1jEizDG8p#!_}9-dQ_b^RaI+31WTspOrxy=txm(D*he8~F`NHa%!=?_n*@CXiVm%5sz{F@%m;oBHHQ;w+iBNjF)^E}ktN_&Ws7z5x8&6-E$;z+rZL zK}bhv1oPcI>`jxEg=}V5+6VK9_zxeG6nip|2^2{xnPye|d#W0>xiiEIK)s~XXvq}v zkglth^e;vJTkWI5`A7NFN|(LF1njJFB5kbCoTE7_F&BMrRE017d9vvfuV+ZCJy$!D zFVEG&_LaC+S(339(P5av$3+i6%>|v5k;LSy9DzsxkN!=mKl zjNPb3Xp6}S;tA9e<`iydk83H-bWEFt!mO*@*ZpbU2f)%x zmcHpmkbLv}oodD{CS&$ac4_ObyA2uGt-kN@rAg1rF6B1Y<|Q`gtgn6_GVOOU&dj{{ zn?OM=U#zLCV{cNg-Q5qmbn4lB>_uu(@J?5kX;L2|D=#mXm6cs`;orQkp0}G3m~rGM zO-cB2)H+fc-C8`Y@y!?8FJ2kNo%u{zkV5uBI&!0I!AT}K|58Rcz5kO2Gwy}L5=wL4 z2N6-f#(omv`k;~Q>#1r-++=RsA{XcXvV+)Tey$>I3KPi7E6IR0q5NKGQny`3$hRG5 zeEXuLiaeLeqjwm~sqtOOJ0sO}yKWuf#jdYTKi5mwPRa6? zLk!6>i02jh39)x_1W9QwE=m2&&$AvN=C+&rU^+{Ui90WQJ1>A^sD4k4I}&IfpP1XT z+!n;^@&kINJaO4;7Il?+q};3l3<7SBFA%>0AEVYwozIT1|KN_uLk4aTjD1;E=g;Zn zPfE9~k|$*BUiau_y#7+2lJ%i0|LF;DzM}xDSBgbJh@Ixro>-&=t6YGlJ`-AG(09Yk zWP)1D>|}xooXK0b0S$81T5{maj4mz?L1%lj&Sxm~c6N1UU@O3csVnJ^&;f4hYo+34jUF>`U)hf?h)#WUc_g`g2PkX=l^CZ%w| z%y+|YyBUn;mX?6foLTT8+;TQl>wvMtY->u?OV1}|dV0!8-$&Sk^upP|9rP&S_CNQZ z{l~f?c#s^rEunvq^-jW#?3zAqzfIYi9+)7p&vqNQ0y)5!db~$-SeV7iZQF{DR=P<#bB>Qjr0 zj=2l%po@-vYjX@Z3PNj3kM#|%j6RQbsn=By z5vG(yL1E9d`>F&p#azKgzp@y(2a@h!6rwQiPrbZq%L*bU*Xu!GMkUN+IQ*3)M0&mvJSqz z%lNfL;VF)Tz+oNPg)Xt5yVZPXV7pN{;E>V=QJqMcB_swv371R+KZC_tF%a{{g4>px zw_W<7+r4+!Rpm>I%<-XD#3FkG!h&|^iPp53^75U$tekT9CMvD)Si4C*R>sH4-lk6O znKPmSLS(`gLpH+q`o$PpSH_v^hTTNT&O92HLtVO z_6PPwwWAadk8W)+aWUN{7re3=^NuL8fCTjU#)tIpHhlqFr+!k8uKDcf_>9b!mn+tR zw_n$Nz9TzQxOOYieAAyk|1|ra=*xe#?V#g-#x5uQzPz~+@kZ#d?!)+9GKa?!{%7pH z+}+;f?fM&Jm7wxbIh;*@t>PF=xd+^wlfyWN8T5}o8?xdCx zN=&+9w6(LkxXd@RzK2|NyIw6@Zke!4v)3Hf5_a&W%3E1kS=iZSRa6AJ?oO1}$Bf_JFDE5EqM0sj>x#L0_2C8uYTp9uDJ5?@)N(bJd4k2Hr?Gx z4414~z4r-L*Y_pTWjP?WH4m=)5cy#JIu{>YWW9ebT%0cqp$XfE=;FoUKNp_xd2o4? z+|1xW#>THrz;gO`KtV4m6FQeL$9-l}%A-C6==ATlm_^jcCBzWtpVd{GTBGn>oxznm ztToa98Q0Se7q4fo5nkz`m~vb;Hdw=WZ+-WvsIu!v>(c%GA9Qwh{=C{Y(Va|8NilJ9 ziVi^WR#J@xr&G4~(N?D_KfG@;$m6t~+8a4{SX~gce8enolsM*fsf*3&U$kEp-H8=z z5Wda030~iNu|X(-l$>M>_oj#%j?y90j{>%6 z8y^)MB@Lr%roN3u=nNzMqB%ML^x3|Gr%vE?NTu!A?5qqY@p{1^azvy=i2nH7tR3@* zOk6}At(|&->4?_5zV)ZA+=7GS=bH*{so$X&S|?oLTy{l^Q|-f1w?0>W`erUJ(C;nS zX8tpO5kvw#dU;SKXo#Bk*oVXK66NDVYp|to_tjinf%0OhKfD;v$S)j~6HO*==bMga zGk9nK*qXy${mrer{HoFXB%MMt=#m?MsXzy!2(zImy8ul68FftC5e?rg+B3Wo+rrd+ z6d)+!|8;R7cLRYW$qMxnnxCp1I6Oq{iXdCPfC*=ftOW3xhi+_`G1sgafnHUpodzi{ zzS()tOIqW;WLM-22}y@=vPXUWQ+7YG!mcV3Dy-E^4{dYkg9(eG(!xaB#=;C3BrSAZ zQ9R@Py}v)>;!Z5@I~h0PbW`>GYQCJp8%*UB{Z}isvMro^r~Q{Dl#v9{C}-mW0!p@q zW;r1qes&{bc4b3tfS^!>_jeSoDDNhY8#%)8)TyMO4>1{H1D)3#%r2a~BI}SFGD-Sy zf4r`Hx0yiR&gUn1E|kH?CbrA=kSW$uBY50{aPlq7JJ9yFC6TBN!qqqT z+hb!G)f)x9aKv<(bhnL-BcWXE+ul($hO6PF)0>uckFiR%%0fQeuh4N#c7OZv(3+Eg zO3{wh_l2}&2L0Pt#d|XqS+;yq7!N5PG@^97z&Decsy6^ZF-Tc>Cq1Q^yl#}5)!~(l z1nAE>a)G25o%vt|8DC8-6ErKW4hzxyly&>+0B>eg)gBxru}BC3dFGVY5?g`0nNUBZ5=6Lcw>%}YLpAW3Z(@N_eflA8XUc&-pGzeFy8 zl&f@7U4VJ?|GoBO<$1B9!?!}MfO^2&to*+hd&$;rK^%1Ih@0E&GK=A-xNSP;AQNav zdA|%u2~Gimk$q6l-sJvLt_=6`a7a@SNW46*D&G7R;{ISavz04Botd3{NwO6Z?yQs@ zgI;ByT~YBUeMo^CXZdist^Q&~MppK_nOiQ3C$K9YW)#PH6HXlcQT|MMIa3+yCpO8; ziAdQTH8Lt(24soEp$A$#`urv%p(&71|SHX4_9z53N zVZCo6^eq|1%;(0c3c^%x3UrOv33&fGFBJWeRAqtTcrl`K7aP}yXs&3$h|e{nQuR43 zRCM@mfTUeAFPgF{rA$LQrmrd?n#LcKi0H zO2~jcA2(R?i{y*`esMwyioD_jB-q7eMP>Euo>^ZUlTDogiGLDD=0{6S@fH54Ptw$e z4knzfrKPB9S6d0DOXNadh*Nuc^9p|?oRUrb;H6bq>krYfkkq@x!-~LwaMk1x2VvPY z97F~5-3)*e=XO1^JGq*`pSVd5KA)aHw6t~dye287hr~`@;cL7IFTc=RJ3gUm+KA2m zkY9lMujpWMxif-j?I1@gF~V^W`Uh_fKgDtFBr9lQ^-D@`jg+b?eEG^dS#zJ{^nDq6 zHJq+-g9UFDS0v9su!4kY_~Rbt5}*>|+Ql<;TLZ8w2)h9>o~la!Vr`$w=NQ^#S^g5X zL@E$By9h%X+2wbTOM5MCvhlPJ^XQ=-kGhR!SEVbHOT}jk)U=vse}(zG&&i?K<(|YB z=DcmiN%eal2^KCsTf;7oM5yw1k+FqNoeA;O>!!ZVt(N+nY?Y%DF>kVu7lnQTz}TDWZU~IDhMEcRRW7zm4(n8;TIii`WC~ zJHUYdQUP1ViB`6SNGcsuQN0&&#GFG(jwS*+TbV^+qMBU%qE#GF>+FIT`m#d;l~jb& zTDMZ`ve$6&vjGyJ6%O-NVnjxKg*m;hHAbX-CNf9kR3nom9 zLR5Xa2CC9M+lnyRE<%A(WmaBxvE7mi4&PuOY!VgzZU$mfE*ImPp%a>vm|Nalj=BvSf{a3S~#o()=wScQ_>Nv7>31jlx*5^r_gjhrD(Roal@Qf1-vm)6P zxl67i&$VCc4>M6!`fw-Ng>dDdSYcWd{QrPR(FOtfQpKWRM;mWKmTQJ zF4Sr>UrS>QwU%65aRjl2{E9@*fB#wT0k+%&o&oTa%WlVq8E?J+x|oRc4_fsXe;aKw z3i0-O>9T*czA#8@;lcK5y9yJHgH&U`EE8>uzNF;sRb&!fc*qg)81vy>C;qPEH2?YB zG1beOn2z1k(V3Z#iwEXTP9e+7h8R@NtjbDwGqbbR8%fqb(8dp2Ls`n9gS0T?qeoKP zDpV1>D%kJX1xj8zTMkHor&j>jdf?4-H!}Gal3tt!x+{RXlX#A8EHh5}zRFPfokPav0e4fCu z+0ANbL~hb<+Z%S^!i5rs<`Wjb7=NCV2tDG%*@2_pXuPSnv3%}jv>Lm{(cNOx$qxWJIAC%$xG^8 zbiDkw8>Geb!%OaCI45Pf6K`aO-*iK?4#{c3tZc%aQ&YTSV`KgO{j5SlZEI`P-sk&< z78VX8wu0DU5AGp~L$2rNq3{K@DqrDcvNElXZBO=ar7$G#ku+ z?$lP6_=P&*kKCZ3kT9xdxr37#sVOL*A%`~FGwAPhUnooC@2$$zUAv}RZen8M4UtO5 z(2)@~T3T8_Ha9XdiWYwn(YFqwk(|xU?_d-59`~keU)eDopxDUjpmm5K73)#gDlaAJ zYtULRdHl=qJ3V0wSANSi&bvG{_J1-H&yqmvzpPqm2m?QCyMEZ~S3I|818i)^PbiQ> zSUNrQRsA`ym}>^hi{=8If2mCb!C+c&t^sl~h*t4<2CD4cG6TH5m?Z>&=2+c{y@`3$ zZ@_T%3fc4Bi_Y09uHku4Gr5Acpvc1u4i-G@2n0FRsVUM7zNHp<@!&{IRtKjK+uPfh zC<2TMOjlOOo^i2W*zL6J+<8|J&K{vFnWC8f%1LdM-k+?7hVY08EMQu&Yh~Z(ZLHF? zG1RBjJ>odJ3ej(=6H`-ZNU?CSf`Y|gh-a5xqHy~NQ-Is>yRve0VnXuG8~W9xOvNu? zp?v)wctc8p&;iIsiy)f=t@A~&ibW3n_@xf#l`iL_Ig5hc_I9L(1}KP-knlOF@G%7H zQoE|;xHtmv<`!0VS(JE5*hyu4sq$`rryMtCa(jw&>%I(hCc@wRz2SRa!GZB{yu!l5 zIlpV$-&IvC7p~0IIKhWK3Vy_WWvGEW+dDfet>{%8+}xeN>@q!Xc*%(6bNjS>d!}l{Z#kAeG%??Vs9MTP$vB26Sph{#QrBBLK!|UTNI)xt zbRuaSBLbhqN88ImrT-m@XM7>L<6h?t$Elu>U^B#^AQYzz@bURphV zmpJ6lb(AzrqUNScvU&160vJkJCVJhsC3+b?K)_)Ou&y?rZc*yw>myoYdO}JBE-4=5 z!`4f@RtQv*g()0IYOi?TsSiFc24V%8I95jMuki$=`33LP)#<VD7|tp|AvJMeN=+RgWFFeRh?nLO@p zr1T2PL+g~XRLKI90c(pm*w~~6$@PKepoP;h{3K)Gvu5~c5?tIC64gD`n6gB#{Hoje zv-1Hi1I}8ZB;a2I6=JCsoTGk2sO6CWnAxNGl7jeH8{dBGfQ=+vAG7;$3+=w<(Pr}o zVM7}%iB)3O`h`|s%{86N1{dJAU&9vBltnh1e!tojm(fxe9Az=MPo7Q*oYHeH$n&n1*H)cP9#0sVFWXj){E!J$TO_{OO;{rGJbSWZXC( z_%VIm!rFQjH~qq+v$C|5t?{(5ZfjRS)ZCm74)Dk8`)RhYqQB1}rSM#XHtSDDi#I5a zEPL zR5}32>xS%!*3#6meBVasw9l=;A+mE5=Q?Txd(kuORnmP4wsJG~Y9H!1x*ClVSdH6` zfX`SJ+F{1<#!Kj}?2xCNoZOt-Y+=2N#n;I+ zUmu`)k!8@+DhHYtWFT*K$}sq9KJNB9&3~y?O$6fYZA^1MLIR@J8&SO<9OiCaVrn2) zYg_;%=YLVmwzJgXKpDa$bytG9qbJ}7~5XXS!3xs_R89)J4T zj#0ruc)W};`R>lo%L|L0le4?lb+=|amn2b+*ynaS`D77@9`2wU5 zY6I_+Czurv;GLqz#x%trX|=VrmruGXZOzPH$jZwP-b>TE`Uta-N1_x@hUQvQ8C6(FX z71jc%$e}^uzN<=J@^WK57d{!6GpuBsc_*j`qZ zqZJIax6}F)faaa~96JcN!B0ps!xUO}#(Ny0b2mO|5J(}`Q{N5f*(i*M&MI6hK-{Y6 z+}b}r*^FU!Mgt;IWnupMM=ntxOH*^XJ|pvcJQh;2j>?wIR~E<6cvxfrIUU)l@C45V zn#cR|>bKOr89!JtuDV!el6(61!Ls0f#+pB~7 z+W;Ns0U)&@2CGnydh$HBGJ~Em5?w|`-f-I&Xz<-@A9DoEaHd4sNNeiUEAz z)`3V*bMtcmEl4PB+=JFC2)9$eJ#qb$h;3%g=mljKJ-*%b5Vnm4PNr37mHYp!BdOU; zqhRC0*V|UO|F!JGzrDY2bR5U@o0G>-lfc)P&f{_&Qdh(aJUin~N=icI;(m%czBK-h z;so&hqY`{!<5mU(YIPF!pO+VD;SjXD#(Xjay)#0~a|sE5vc1!4vRBKRWNp7K zemIs_E=XAynzuxM3O0#u@fW?ix&kL8{UVCq>*n%roVMNa*{pqE-NB$hQ*#uRRNqWm zXQ!m_9V~JKbG;1I`ag^J0f_;siG;ym(S!HiP3I!jC!;bPm1F{LDMQd*dffOzOUnb$ zpR9XfT>;h@Al;Epss2-(JdvUK#~3J2d{~cr@vx+{)i$3Wv>*g-RcN6jbgKnhW4pFDS~* z{p{X&ya%3bn)m)A@XR-Q!73HkR1F&-QHxR%&abHn2IT=iKfi^QmADd~Sq$=ROnG~> z*DKC9EoDq*F$CP)lQtGc_jibbpm<-upHb0JR;GHUQxaZOWJih>4%?=0xITBh7^Zya zj}Wit)dStctVCISgO##@B#ymTZMrhtc2*;0#E%Qi9%Y?c- z_82?!*8quE{F{8yG-EH+#S;V)9+y(rT>?-fzT<~x9l3mPe7mE%~AG}UZ3f|rsET3UxTS(e1l`7K@UP^jpiD>aL+&dp`H-lYsyqg} zbbYrGIce^QdA^2uBA_RFGC+%E{IQdxdiDy}rqtX%)-*kTayrYhh6 z$;@ZG(eh-In1STl=>fBtuO>1$-MNgE{wDrkk)ofxd!As%x`YhHsWSFN|5})};7k%e zZ-g+onu8Pv36APA)U?qadW?W-$CBUVlMaS^1bz7~Py1Q2CZn79)G`ETh(89>95` z5`+eV`IGP8M?(NzR8gOFxNul~DKc+cq17`u_=15U^zUCrc6N4YY0o?ynK4%{sfNGy zB)PsGH|;lQ2nFtVea(ib5>*r9;btmBXg&T&Z%O4?C0?+kti2|q5SK1#9|@L4lp~z? zRjN8^?V0|eXTCxcA#dPtYDgRs+g+Y*u}tV(wUWx4WC0b3r`c6zdVI!ZcI0fq3$Ax? zqD3BhVu6cmk~Hu%pOCw2lk!`z5#13Z0XkTmX_5y%;M=_FYSfsXcHoRpPft(I&v7w6 zM^ums^0V~Wa2uCuyp@)w<>O2I_RWM*jiGn;{+X+;xr4*k{e5yTZ*Mdt6PIBnOG~$- z@3T2te72Hqwb7U__9Z#eeQht4R+W1gT&U>heeH7uha^) z@VRh*fq@?28nOv5uHo;Ou5D}_h1=ht_o5x3K}Rv^PFsrezb6i_Z$VK7Cda*!p0FSX z6GpKS4x}SMo0f7A6?TvL7WDZN1U#E{n}eXJbVpo5S%SC}h%a=q0o^qu&rtyzb4(FM zQe9moutQ)2>QsuD?>!3<9E~x?wmN^*_8TjFj7?CU^%w3aXRT!YCr;Z@@da3fy{bFs z$VN#b>`~jrN5iAB=qZ(?-~xJ5Ud5hd`$n$S$&7+mYCrMi#>{+hw{4>0;w1I-n28`F zA`?^7=%^@BR>G{jyr8r+y`YY_$ z$R(k2@Yk`1|CUmXCOxoNL5=Y|Vu|HVWQ=mJ7ncEdLG#4{Z*Uwh|A+~`XBV~B$`(=# z%~3?WMsRj8t;`x3%l@A}Wi;z4WNb(|+Sq)$EC&xCpG@Y}e?c|B*xtaw!OM2L{p5Sj z^mM%^2MLc|Mn=Z-4L0(~pn`%|Zu>rgm6d0f#kbQ#exE}^@ReqDnV&7*Y*cNm`HH=N zkMm5|g;FMtak=r@kFQWXHH+ToB%8wQ_Ug2&()W7SeFXT`)m`YXF@-5~dlkHgje>%5 zxxv%qI;z1bmz}eYiivr8eAT#warWepD}!UfAI{!%ehKr7fv=&EpGRIIUuyM0iMEIy zW!LnBovwW=e6eqj*h(Dd&#w~cys|OIy82_vaCLr@V43K=#C(X{3t$v@k5pAbdps-* zUjsv6TiAxS(a@ z^TRphn`eqH(Z4E1%**XA$>KgSY^=|@M)6ZYvK%*%So(< zb=p~3W6OD^6cpIZx;>JRh=RlhZjA+%XN5|M>3&6xpA8Bj+V?z)@-*m@E+y1#q7T5o zbYql6q>`rt!&N!CxK_^5N)C?IDNONrp4Y{FU0>)v^pUi0W3HS%LbK%0ERolk-1u$< zp7vj9+RWuNgx z8tEE+P_&%ZOll+c(o(1PMZ6-txU~#=5H`=q>@3Ma$)MF{T3y_%eG_J#uiKvzV4V8* zS3Kk6e^r77*zt`H@ zv)?xL-KKNqe2%>%eSNkR$wYtyHpgqLb=^D~iS%2W8fwlaCP}Wo-uI^UJ?z+XQ&v`% z(@(!4iOhTk^8e?oH-u&|2S_o*H(9kzRyW{s{Zm}XXo7Ss;;7D{`(s_;FTPIcz+XO z3aGx#+zP;;>o&3^G z=Y9}E(_-Wzg@MnUoW1?x@1IOzl88h^L;%b9nwl!7=f=Gb@g*viD@Hv2%=OVQe0W5J z>vm71WgU}!2Xp1*!qF=r?DFF$F0yi^9M*Zss5VI@FPsPyj?aYmxs>d)n^P6)Yh<(g zFew}-`JoXJMBau6f_G0A42)EYQs43rDlTBjsb~G9!$~z`b!4HCs^%2GPlSU;w>G{HqhwI$;fUhXV!)s(2W6behjMcHrvWb=@$ z!+m%CA&`#CTaqOYbmj@4N|SqS!4X)F^-=|)Q_f`W)Sv-wm~U!}!O}*u{mQ0Dle^?( zr3RzVWuJb#Rk+^|QB_sD+HE1QjM819Mp9FA`cotXdLy~Mz7k4PjlLuR9nu{i;;)(= zu=hJoPB_Q|X9!#|Dc>mLK~>hHFZ~x+1hZRzhCvQgdzAAsL7Th5oXb6Zu3 z;TV`$uwI7Z!Sg->v<-_Fze-DC-zFaiww|104=>&i;@%V#L`O$|oKJiAJ{mK7Gw->oOWAL?Ob*BeP>NQe)5M^Kj#> z!(KmsO^^2i?=jiW_sV#WLOVYGv7+JPiv7(g00Q&Wo*O}4PHCCJO1Ql4Bn-LD1Cg>` z6jR}OG~V&Wn+q{}h!mA#mK-!E}i-=57*)t+WapI`e3gF*)_Q0#kNUR1h>=X!oY!JK2)wL@K3etv%9 z32$UqTa1Emhi%n7afSUr5|@gKilVwY&)($H`85EY4FKhZ?L0o7C8yr!Wq7z;OwqD~ z?2Tqjdb)zVJl5^)t+Ji~1H=$|-f(cBQEKEl-UwD4H=N%Aus8~B)>SvJurM4T*p}-= zv+4dU52aSfzQEy}+P4qkTxGEltQ)dJjwL&T+wmY4QqlDIt9XjM>>W%s9Vf)Z(D)94 z?=kNxh+hu8qhaU}GXuiq$4N!m+mHGArD+kjxj7J83{WQ%&>^|8VXo9+kFQj^*?{8* zkgq%&(Q4>EnN)bLn{V@%nW-lqh;=X|u_*DRkq-ruX_8n-?BGxswFxfgE&~kj+K8*`}9sn#hXO1Cc6D4A6*o!tY^>be*jpL_W3ZE=;Y?uiL5jRKTOEri+TF!(vS-Q0Iju__AaN_3ver&Sq z@UVMUzbcC5)7xlPPY;HG0}o3ylNr%H`cKyas{e&Ouo1UKJg z9{nfBf&nefT_Sf%eka-97PhvjCo{#3wV{RDELk9dvsxVBS!{>54_lYFA^WS@MJO$q z^8vEMh{Q9wLLuqRd9;8V=qQ?(3jtL-NDX`Xms8^@8a}t z>}<9*^VYp+)v-HUy5%sKUSdMf-HvqRz`N2CKP6-k06>x!Ioa2Jh}vTCL{(K$mFs;2 z4#w#0tdzYy%bPcC&PU(tdQ7suo3LG8dLji-0{_H3NeHfT*XOb10W*Mtf-`t6X@-2> zG!e%0#LU_gYm-30W66K9e=9fU33^~bfkt6m6|Qj-WxgTP_eN~D~RpLvxskfy`s6kveej?o3IBlzbcNc0Xjbp=SBfR4wmcP+IIJ_h9 zPuU6y7SFX3Wi0fD9t>mVc4L%qgjJaGgpglCdn|&_2BHPmVJ|1TZ5mFh%>VL5GnvfD zPQ~E*DKE={{j`yc|IXO8xewR6dzv}{Bk`sTbZ;mZY45G8t6CMnI;{6F~ z@*Wc}flEv&sDTf5p!PHN+c%ZJXDYxWKoP3hiA-w02*5!9N2i}O&09(&HO5$p#$Rq` z)N~1fFf%$j3YcOjfC5urFIZH!PYmj>(mYd#JK+cRF-RIWsR;;Ug+0{C;k-5*#=)Z} zRrhvPNvz~NBJ6lrt4=kv)U}e5l7u8NFhTPy1?cKPv%>1nC)?Vh<7UJr!+YrNc1$a~ zq~z<6?|%9B@9jn8&~{F|=gCM{uFh&q`VErxWEyV8{N^$2;Qnq;njr_&gqg$bI?`H6 zsnG2t#21&~R5vdOYmccvo7tt4YqpzlfoFJ`3D*Gs_wgYO?Eq!KDIz8&W>C%j9ZH0+ z?x!|GEDF1f{Cr0({5}X>mhj?b6!&49V+33z_l3a{E?+XDbbg>ud!(|4{b6^NM1Ezs zg0=8kKlggrua~9%^G8(@rEgO_AI#q=HCwS8R3(8s|8|JYKtD;&$%*}?n?U6^6-LRn zPsssExoj&gW%i4d0C~stD+-t;tKoB=^$Z0WvyQQG{nZXs#4AP9J}ou&`{ir``MO&q z2QM$@wx5I&D={xFGb5Rn=Ll_0(JpNP$=#%=l}vi zr25jjLhG_yYJV-w`_5c!rQ4|VaN&GG+|G_!b6I|M+a)VQ#O60O`38MJ=tb$Oglk^a?Y_wV0~%1VOtA%Q|df`rWv z&_k>afhQoxdhzt_BOuU1g+%ETwKeGSeykbOzyCJzfPwZ9mMtT7~Z}fl(t#KokFR9Yzkyp z8a`>;)$naJ&dj`t864r?>4Zq^4Q4ADjQ0V}U_$}&N&zD5K_Pdh*-Bk$FE4(CI=6;S zd+7S@IA1}*;10M25|6;pD-rRA`{a0J~MX&%Q>4G9rZW^HXq)YF$%A(_E% zS9UF5wB5rakv}yYk^F+2_(9>p;=|EZQkm8sZ9nF|O1&U1S7;?qQYnK`AQl~NB zez+IW2+7{as+rw}*;9s8Luuj>^G?6;b8{`Lb&SDMB36F>kg-eovR#YQbd7|@lN^@! zT3YOe+F-2#w0JqFTdt*`gx7c&IHatmM&Nu8Mh!uL&LX^h2|N{aU1k3@&MX~P0YvtY zg@r`|%rmCusF$G{)=46tgapc-f&!~Fubpk<@L5ot=ruB+RjP;n6dY5 zt{`13jpj=YS!A(H)_?%S@!zL_Me=2ATafB!bjP-m;#Z0aTL*_TX9QQ>&E+79W&Jy7 zJ>9rctp4Vx5AL04g%*LQt6RKHQ}8=lea5BabGuQKm`^h0U1gz!LvYwuNIXN`-fDP!;5Hplg zropJe824k3b}WD1ZF_Ie^kAVu$D!qs()GkI&F~%*YQhvjKFH;8NmLKI#RLW?xMxic z(84#^LV`a%@|+G0@Ksg+;5~a5m6{sfVqjv^FJW%}%-Gl%Hv*8Gz}UXepmW0)xyo3A zenEPu_Fw*mlltEm&R0cLN8mvaL5OPyWf_|=e`~<`-KW$c!IsgSzPErf<^C4zFj9O4 zF<={2Xib+`(SRaUV8`n#n_@5>M@OsoVAPeRgfLC8j12#rWL4-$`oor%eY zQZ77zLx1L9yq2Cd^Og{?!fQ-6e*SkdeNO>uOhkkgCh6HIiAou<^Y^d#r0WDDgQ4J) zT&SOCb5gNE9^>xq=_k9&r}BefU~WI1#3U;}6-U1!=BH6~h27I3mVp;^P)9#-?B)QN z9-)z`F<{bf42$$TX#>sBKX`a}vK|Vn4!lz}$Fb5wm_h&kR*9qN{rmSGu#R~7{J`|C z)y&_&Kc%Fk{P5K)js#7_mqU}TslB}c9)jfW-o0Z@l*K*6#>PIbY7*)KH8teo;xfoT zsQeTa37!^}9U(yEkt)8a&FFKF>al->IWztPQ6%;ifhyt2*d}5l_6_m{vxB)#wlwSB zo-N3!N_{RL$1%Q4K9RNnVikIuN@{opceLI&;+iU2C9*&nOc-a9GrX|iKf4#_DZ>)W0>I)RGCv5)B> zydWeb=f@9=Q6xeDV|lAQ!~g;dX5MuqjW=z}3A1EaU11YwL2cuI{-nQWbk1pNN>55E z_;IQK@Js*s6={?w^xtQu`R_BAS7A?yeJAUI5b~E&P?!&;@pKOk8iMlrd+y9C z8Q33^LcpCIzNcR(&PsWDmct0AN8NPD`z8OBSzv{Djd-?6Hk7@ z>27{4!qRZ^A}0qZYkVG=m50fLZHx2l92`CU-An7Ag{^8+yLt25Ga>pC!O6jiBhr54 zz|WuCRMf~#d~`N2nZ(`aVD2{4Wu~LIpvLsvuh}&FMk?e{5^~Vey<@(%eb1J>^4HcS8-h2=`yZ6b*-Nr{{J)~t|%F*9&72z+ZA zDjQFyzdgb^;yr{mhqLH_6I8Sd{(-EyISPZCisJkC#9YtyK(mIx&i#9=dL~uymEN`bs*j(65)7(-m8EpVs!K$h#p4&Ok@>0^_o{2rr`CDV7aIf>D+e z0;HlQ6O+JqD*r7hwVt#VJRKj4zR_xSa&oF({!C)D?|u45*XREFp6}<{q|%U36&17r zY|rEV`ru0eR&wy%+}saaGP2Ziy#p6QVq&As!T9`NJ~GkzBUle+KahM~10w}d*;uII z6QsrZBU77^mvEa6QjDePLB^s7`91^W=D12_u`lKFhK3JnYHEIC)LQPicL}6C8pwFX zI3T^gff@R?g3x0lu}MjP@yS66B%U(wv5E-_`~e3&U)N`mf=6}Ab}y%Cy1lq2__ z6TlsX4~hAdAYuq6wkd&)&ycv^894wO-++FBsi}-+r465CwvQFiADcJc-96~+68f$c z_Q}-}@~9~uoFxwU3LELT7f>?`*r__%2?sVUiNnK#EbZ;h z*Lzh#Oz!gm`;Cd1o}eC1XxoFHyo5=P1`**gK)uSNvtEm8;mDLJYevV03H1mXLiD7$ z6*;kOLD*yS^SF8R5?Rx~EtUJvi4=q{AJHGJT&nDF{-0mVkNs4BhFltxlaZ*;%OFEgr4#RNdWz{18{hIzoe8h|hc z^g7UD37-UKW*JG0bIXnKx@--n=#iXl)UB@X!{1yS5Ffg76Yf*IP; z%2ZV!&!i1iitmvS5-weC>L-jPnD=eFyw}z3I4r^A>Tp21czB4E(ZvU!Pixc?_0MrQ z{y(O^J08e?4ciEb5LsCvqwKvYGg(RY9+AjS_Cu5vGRlmM5X#CZvk-z3VVM`MGT-srMK{0TjG~}n)R}ivf<>n^9Ultt~ zcX9OvpttYk4|PlKYdW|4sz;^0GH2K~45r$|)o``4VNeJtxX8ircZm~N*;e~22+3K1 z+PCcNXpD`Gb0kZZIcafla5P5%5CGld>c<7tN}=B-M%wX#jD>J==2o(*BB!Kvvc6~jhC*kI|26M|jQodW4-kepYE|U}~zv_qOKt{A* zp24_!^(v>q-S%I#d_-=9)8~V_-RRVQ!fNVEQTt&MS8|7&L#}fde)zRtCvU?`WxKg#M`?2D2yY3*{TiZ)Yk%B*e+~&cbAEd{qCAxX64ZjFe z=jpL)9Kcw+Iyom#Y7yTklyruaDEM7rVJ4{hwexkfZr`RtU(b`!9AQbih+pi zYHn0s=LKb-*H}s=Pq}oBI;Wb#L6dcxo$y?4*w^~W%T?DVez!zZ*xItIhqhWJb#HwF z-li>(Sh^ig+Nn8?_+M65){B@J{uu+%@9(ed_kFYp?g$E=FivPkQ!cQF1Gt^j~^V;QX`Qns+j~7jeq9e@7=-%}#!~ zcIgrkX#XiziyHOsmz;S3lsinYcG|zjYrLI5DSq1MBsQ-Yu|didA3YMPJ6v9+g1SFF zpKSv$AN~_;>_g{Ieoq#$Y6&HuwC|!7i8SmV*~yJunPxN?CdzC z(};tau`@MOr!UAhD)CZf)zk!j{w&VVPkZsVmCGB;-yfUJo!l)K-YJ}~bG0? zSJ%kdvv(g)TN{=UsoRY`lanM>k5?H%?vatf6ld%A(B0krFUU4FU>*?QDgCa_N^Kf0ahD*1ew`wFeKFXZ3W_i!cF$esB*YC2`1|)Qr)g~p zaDg$g59dEe{uI0A?Jd#QC-iSyqmW5?;1Ng-*sop<9j-8M5C<#Coao+tIG4fnUI{j7 zhcuKXl~2p;x)?=7M6OZKx``w2-b*!(*X&RAuiPGZbc(5C8{O=Y%Xc>WC|0kd&x!Ao z7D5Y`7zUASEMra5n`u>JD+@v;C@`scHac4E5zG`M8VFqjJ{*15&Ic~8F8(+38&*~v zo&_tN#SPp!^aGy!jahL*YkRv@_ml!C1c0~*4B(rnZbsfcxba--5!C^i;h8^q(Jw47 zys@Npkn3hEcOe*|4dPenR#n!tyLJxHjZ1fr{hjw@;gLdIF}(L39dk-cW3#T%=<6r` z{%sZeI#%w_$VM1!Q8hI%GH-mzy+(EZ8f#$KuS&d&l1G;_Ye}TH*{QDz_w+2?Pg1-$ zbK@EZai`rrBIY~`YZfD~1r~I?%(kb_T@(kihvY{41gtNl7CwuN{iFX-IrTSpS$&TE zc&~8cGA&Wst-(?lTU%RN>Me>%2yvA%5#WJ@$sg!hLAd_ITar(x!+-Q; zwsM?zMaXcs>l;}vK7ApT22b_#rG=n0%Zidmw!%0I!nncDa>ezYHcvMptJ`E}cc9e- z$;Pssu@|QK^hpdI(vp&7*)OtE5t5#J%6gEKhr6_OamigmSy>n*lWA$;^M(u&v4uSg z^WjQo=8Dn308sl19q$4*sN>esA62}VFt zap-<9YmMQDb-FJ%&r3RWqU{>3WwSLx%Ri2?eR2sM)~c*z)}_=P_rJv6sZWTxSh_r6 zB=CIG@{;6}42|lEOXb-YzF$)iXjVslT=-|ckgs%JHD$=M=!#~E7dE*{SgVT4*Xhj? z$JL|CGJUcsc7O{|>+wK|oVIxhn1uy|?L3RsQ&fCr zYiHMF#Shvn>1E6fh!n!psn*OXu_xr1FI=l4lvG7K|t-^(Z^xaw8^mDf?Z&k|eSqry7&%Zc? zif~xmRLS?&S-o7-*x2r8tBo?EIx$o_lFno56;$AaV=W!?55~$W`HaYXrA++ z4?w?(3pROqB@g;;p;1cDz8>{661hi`5Nd2#7gBufL8$r!_{~c{vx7c@Q@Qopv6p%T0a{T-;-Ao&tnQ>mscvrUWXkX9UUr0ri~=D4QFq} zav%4kK?%XUJpTEuX#!i=$ps10IhtL{G`jfG>6S2~AqDF(d#ers`Vr5}zOW`Fqn*DT zggKVdxRl1%%X|K@*+RY?{toLBevZ|Jmi){1ZHRvbhoS48_oE+cL&Cqi7Ezu5NF3E{ z@Nb^ry2>rf&9JvtEXhN~(>Th0p+V03%M~u2V%=Tqgy+w%Lxg=8U^jdN0|Ve^t<22) z!MkYUz5EDd@$Yg&#HPK{H0&gYCM?P=rY!~3sJ>ROH7s_rbWK=dH@stNN+kY{%=Nk;_|pg{ z#T*bO;f=DX&5~!0u)AD=Z|gRx853jNt5+`YC>6>$9UdSLrh;XvlgGzvmAjUgm*19@ z#B44OSQg7iDHxX*qyQppPJt_{$G_xh=ik)Oh#I!xPt>b&=K>52Ymdw=B?iaeK!yJb zWbly@9%-C=0sA?{Oh(4MdH_o>F%H!s44Ij1h%v!)+);v2`K-Q5LRnPB*hzXaAtSH{ zy^A4(Ro;wlb;=C%Ke>=AC^YdisD|LEYF-2>0;j>p1QwNBtzBIb3)?}rMcaQ&k^}|@ zK7TF>)xg}xC*|Ki!SaVyF~HuSE5K;WWzQhm@E_;d-btR{E7}ryvol5}yogJd{=6yZ zj%&h_Zh4d=S7zC##6Y}!k1oX9q0wHrdsOCI_<7%*CuC&iAkU!W?yy!!r7Ik0UPX@a zzW%bkTZ_-vCA~kSp{2>^Og{kIe^?(&9ULu07+qs$pX4yzz0-cH=x~4A_4u$Z($fS~ zW~PUK;`x#-*$RZzrr+hHTF-UrTCjGjvND7D1}==@fZiSQNzo3m;{c()%uheAjki@* z;YmrCs!cSErf=Tn!A`@@o1#UX{fx5#qq``Z->H7i>3p=jo+mIKqC~-gLU#RAPNGwE zVI)kL0BT_E_xVG*t$0$l+D=ur?emC;blYwP%&S*hQI9U~P#0`SK-DpiKefi!37J z9&)|z#si-gKdg3-jnQpXZ*)yG2220@aupfa+Vug&UeDNA#KdazgR(n!N)rD5bt%wU z%$ftstJ7-Dc2il$PJm1y>q+$(0gl%g_${Uv9Qje#|~D%&~Gs86WomotN&h$ zlHSuBy~cIuC-dl0FnAjy+BV5XMc0fcgZ&9_oP13#F=+ZDW2Xb=Bwl@B{bTm}nRp zCbu7u;^$;pIro;Qrl#7mMSO2-`?T3_$j-?b@=1o4XyZ?QmB*iVIXOmii8iT_cJ`s} z=(85$5G4ugVq#K0~RY*!9v@$bN?v|Qq21gI}O8+ zXcXH%!Vw~!Xo(oSZ+Z3Q30=I{SQ`!GAe%u+R-BNX&QD3+Z`}uX*lS+AkYd;{BYQS& zKzpgWGn6e~@kykG?3NFbFr&78H$3!FIBk|e1W*O&GMDbrFPBd+k4D%n3KjFRu&|&S zpaT8UBvg0rP~qKUDIidqQQnkP_9&yEfOC8!l|~O%JXy^^v#$?YA|Pb9F>sdIUz(U- zSeQ9nMHpIJTYrkrc|b!(pTblqTh8XCS)c-WkiNdY=TRC*Vy5+5B#9ekZ2y7ve=#R? zPjL|~1~;w)<`IG3MU*CPo;IJTl>)_lv2};o;Ib{sVnx@3nspX-_33tv4X$NuqgJ}w zSYmCr1t`o{@|D)37%H?F?YkJ~^`1NMcI@r7QZS2r;P{&H2S$uiH{`L#s$w0<#=YIY zGd}Zj440*(dR8`o)0;ioN2DO6HJ{}HD2tN+c>o3lP*Mq-O1?ykiSP5P43luLC>i|x z0tED;08Er3X@Bi47FvQxIycX&#}&9@AiHM3g9h#gr*8u(1hBj7?Y;YRVuCV$k*$(` zlB2!>x&Dtt2|ixgl+7$0ST39`b{g{Mfx9cSMck|dfCp&`SJ5lZzzS#C!+lL+Va~zc z0v_;X!pcKQlObhZ$xUBvmB-|Hj)Wn1LvRFcsW0rY27c$Fp)jwY^4MF*0c0Tlb~8v+ zd+v2bG_l_rHWeY6AwB{Ow6eFice`sXa+}%aI_2!+r9*9JLm6! z%@B28^ti|yq$qA+AD{POcoB1wtB4tU4i$}B{Q8SAfkl7WC2$h)McGN%2HM#X{5SI} zD=&OZJwplWio4oypR-G6-J}o5=Tb!nANBmE^#4%3VHe-|4&fOpzs3;U(O%jm&C$wp z;V~RjzF1R?kqXCYupLluNXEC3zr;|vbt@w`_eEr6r={J5*J4LpTwJ4(+`yx8`0bAV z##T&S%#gRDtPss?18 z@((9I+L8eU4xI!W)%o(bKCcGO7$jT8maQebaqJuaAe|uh!-sD(mrj;M=RlHo=X8-F zKXtluVT|-TKX}IH><<0qq11{`W0s(@UqoQoEcV*G1UpSwaFa|4g6;-X*CiHB=fc9y zIq%C!YWFEDzDV|PqiriT9I6xrR>|wnB8@tNVR1w2;!|>tR|3+~=q?xI=~JAzIL=6M zVIalh>m25Jy!m1@YAPsT!OhubNY2?X@>#Vb6#7&h(8LVT%12VHnlp-xGj6XV( z{{H<{iT#j^Dyvqt9I0$OUuHM>kMLFEUqz>-1%ENCUnT&HMhNzD!)BRg$cY=DTm==fkCp2muQH8_V!YhhB*WfV9GG|bb4Po zT`Dl$K(%gg@{23|3rRhbw(0_CrchbcBjj~|4mJzBAb;7q?At=tqWJ6AbfB|K=3S;FYcG|j@5zgLd>P(K&`tZ(j@x)Q z$)6^G!@nv(`*hFX2gJ^g9+w~?yH4;@aG<=kb?bdWm%hFcWsS!_24xfucECRU1sdxBM~2RH^1@k4B5N9#pR$ zAdS0kYn!M)*$if$DBmUK0)w(J7>}K{$F@P|WK%Qlb0P)WyUfgdr}tumIa6q1-M14V zm23*Ng+?A~0}D!kI}HflFbpDujVl@-F?J9AfUARA(D2LYrlCAzCvRS!%Px6*bbNA~ zmi8F!Jk^(F;*JF&!WGQk+gV|9rP=8$Z#z69?tO9(6R=;Js7o_*a+oHwxF#hf1zS_G z2m3KB_Xh2in`10%YHB361{rKVx`ToRz);|rL)52ZbV*rU>^zIysOzxeUw^0J`$RjR zscSVWI~zrSa5~k*lQ~Vm_OGq2eOH$uF0b%DH`Du1GSBb&qT6)~+|v;(WTD63SALjj z*#Er$$>Mi#kP1R+=087chz`j6o}(BdZ^KJfxm2Q}SM9;aBlNGkS4LQ7KA!4KJ7P!Vq5zRhc1_2rFvE}{40du+g`ogRn9#l;DwjTorh zfW~ntReMAuxZ#V9^agQUe7weBYGR@?(9XciezWVuQzQ5}IM`C_>+LN5dYy=^dtQG0 zaV?$){n=)blZ#nWZ2$Z5k;K1PT^PujSC}f<(muby>zkf_171b30oUNNK;d6#jP#&_ z%KtE|uBpi=LAbc4_9x%S89n#Bmv%aoMGl&{E5&>!KEGHJk6ETN0IvgO^L416 zH{gF-0<(kzimw6KFHs(Mec0FckkhdId3*cwTwfg||7B0lopG;4E>J|zN%y~(h_5@| z*NBddB`fQiaaj+RkxU}d))^ZcTN)}&PEB12%D<_CQHUXexs5q}Dw!m)VL#m{Sd`=X z2m4p}t6l&1Iv?lS#dF|u1F3}!;7z^vJ$!dUgMA|MBc=5DLUwzsy?`r zb?$9(ap-FaQ^o`nRd&k@7Es!`K6_peI*E1V-q^8nCNdQ{fZNL&1kPnv`Q`F}Q zrVHM`fBWW*S4z){o|3ZPN7Q3JAg6P)88TrAoS$lzkm3kq(&{45G?g- zZ||9Hp}vt(qi)?E`9+pJ_pe8X`=DGjO}o>sn293nL)Z+j$MxIZ7j0*bI*2?v+G*bh z=_rc(2L@pBkbjM3lEYu9v-rwI1x;8X-D?Uv*KX|! zYNx4!x9sNzj30Bg+7i)^j@`PCt4)Ptt87#)8Qg9Ku-O<88`Sl00zzzQ%vtP3S0rAl zeCNMeVgMSF4A9AdKm~*_Z~M{{L{Opp<1y4Kq`J6cTxEhxgB#@VBS##oop!G6rHR9p zW1H35hH1&R>Q%(1x9ui#YfSiOx^0K%G4-=qn8`1KE*j(p6umGuGmn2fVH00MT-8<8 zRq~>QGYb=+MDNZ`_GGNk*vfaGT3&Gu#k{AE@QPQww^xlkpH@hW7ILwgU|!f3i=@S? zE!?kNNqaJlWVm)N9>~D_pmEjl3h*tn{f08UzuJpKKYskU1~CMwAgX(u^2-8>kNWGp zIk>a)ntkvF#su~ej?<+S1$lY-Sq$=e_~WEYxIWu{d-JU@v@kF;*)~}lD(IEp;_P@U z%62l@uTE$bR=nEvCe)_?#`O z=1o2X0JhPz)4x`)#cv?LV@6=KfZ7zCGs?F)x3xOarKNFrEzi5KW=jff=Yj%*>E>4``Jz zg+IPyzW6p{;j6J>bVA1qDoQ0q7cBVkt+KAXh>p3b=pqUKCX20!Y`eTu4M@s&S~;R# z{}RM+{Ei8aikj<`aJ1Q88T(l>0nzmkwARd8(`7Hb0Vx5{6o1u4Ja%*Y`+D`jwO8p{ z=UoIEA+(4e{rwNz;`Dm)4w%=@ni)O1gPtqFlXKO0GqGLFt%(FD(+3B&0>F-jN-xEbA`jOOaDg>HHxB ze-o%e!KF=o$z{srQ|~%Uyn+|vCB8krum6fupVV23iV$839XUCEkapy9$m?HATEoA!TJ{1kiKR*RM>ftcTrdR@X{O3VhZA zE1Y|~yN;fHP+rvt5h#72$-4OWy`B~sH9hqghf)DS!Nwn-o(!z56{Rb^53Ozjt`K$+ z{2=C9SN=O@5!(+x4l_BRWuhZF z@N_rh=I;Iiq7!c2%Il7nw?0!k)c$C|RK>`GpC|QxvfGyK2bM%b;fqB+H*m3Qq~cy` zJFQJJ0!s{N4mK#jaakWC(GL6q@Gdtt3y+N(r{YJJXQ8wUX~-NB%E`%*t(aGcz?a9) z%}r#;!OcC}63t9V93}7JQax*p2i5B9L3!qNGE!0)Ie#^VCb8FM45Az8d-rfaII4L; z(ug@d^L-tr>X9uryn*O8c^vdrgtFM2?FgI4bjN5#zI_X&gS#JQttEg)fz}`W;td(I z0=L!A>`C<)lwch!OB+L52uBASdx}w=F=6{U$dzV$SGB6-5*SU?{ zz7Feh^&Ejb$>Nq77w0K?q2?%ErAM5Gf3|Sh`-Kp#dGro4UG*dC_9lvj=A?$vvL_80A5q zbwcJz32n^NoFuMy^e4amuGrZERmSAx;00%*ngs}0d5%P0Ati&a8pw;KPY;MQYcC)B zW<*@SXlxX4Ij&uWSxPJbm%QHU86ZhCvl#LdjJPQw!2EXaM)}_j%5^Zu2T80{N?EKg za)D|Z3@J#D!%fI(gTU71VIgxnF)=Y{Za=%bFKCzRfh=2HL4g`5CGjo6QOrrCzfn7E2?~nZX~Vi=X}30v?!gytrqdGWcs_7wB&AtR}a&tH#7WvdC&zb9QzH?hq=3Vkeo`K#Z&KSshktgAknD`ZD^&1II9guyz&=mP=6CjN`m z)XvwB$2*mz|C&>9CNT6JS|XN~5SF0k<*1@UKqFkxY*8HazDE0I_@+hAj~}o@*X{Y? zbg6K_&MignC)Ox|5BYro(Qr5pH}BrXAcLozm_ZL6fKiZvbNy>Y7ae@ngUiB3ANT<7 zg+@h*h{v?tL*FW>Ul*@(aixzf{EGN#Ts`!o$?0MfPb@wKqOUcilO*S-a}B|eEi(C$-LVpGZEKtUM&o#ykB`y5 zgW>ECk*V~yg>1)0HK>F!DR*PYra)=}$jW85T_2btzdB^X{~!MVm%+ynVDd`MzW9)m zk}j;S<`fr4@9k;*bTKkBGNMI0RDS_}S_jULfq||zo;q3mAx7BjqL8#=+)HK97u=D^ zZv1gne}BL7gqY*FWbJwc5;7QJWMcA#OhZy^ljk?-{L0EyW9T$^Ml&-TGnnh+1AGm^xMG^-_-sIQd0Y+TmBR>_~ca!KNgnox-{_F(~NF)bzBnsw#N1AzSET z0V)F9Xh{@_iu-M40!NyTfu?AaOc!h-6=I7^m1(lxv!8)S%!1|Gc1xL*4o7PE{v<`OzUCjiRGOkVN zRj9o^Jxw4Qv-mn)C~qwg+bRz(N$z+RCEBobgo4|srCG*L1d4~|*fEgo8=%%X%J3UE z@!ixOeKhded;r`|yWLUr=`}S{Q?8KxIkS;gCo(nsKXl{!7!r3Tje-xYvm z_7X~@3eZ#?9q#a~L6?<8%<3BXxu)^HN<8-rba^{avS;|shH-qj%*7QkJRGa#r3*Ga zpb+Q2&U%(rRBVi``oX+Wi=Vcngc6$2Us503;OTueM?q7FcG z+JrzR!Gc`^H~77wDF6M-59)=xXNb2YCLvP-vsmDb8v0l-okEw=4vaOyHSwYgKS&B( z0Rezv5t5gqQymz&xH{%hL!b$+pQg^Ra_+BE7V|4&*L7!L6 zZtm@DLsTW~&|{@n5vPwu-rL;m)*F?JFnjO#NJCFy8v_{w#MO_e$jJqo3v7WH_+2i0 zv$b7MN}bcA`sTBbeASFDki#=f{BnA7hrSa@p8JR;;eXe1x{(NSI2*d#p?>Pvy^2)0 zc;QncD#TJ+$_?uWrZV?~bmY&4=YNjCXvB!V@LD~Y*6-8w+ zF&03CI)7qyq~OmRd0=lJ_vepgZ+~k2vO9GQA@?#?38eu zkrRIqD}iUHk(OU_N%HvJPC>y^k;YzlNQ*=T$a~SnW6@&3b$^%w5SPh%Ofcu7P9=&~ z*-}~+G0<;kDZB-^uzs{%$FsBt@#Lzyy1Koel9TM0hRXz&FT6=I_UOgo6D%uAK*cdF|a>5RaI<%MokLiv$C$d;y!=O<=UO004qtjSde7XFWvxF zOfxh0pbXsa)U6!wH}p@#$V6~$&E z-=^(FD7tR2MINeT80hU?gK*UDpJXP_^WMGtl^%SAT_N#z{RyZg_CX|4H@P1ZtHor( zbM0CfzjF&r2%cTu<8;ms?d_lIz2iGiNLb`Jk$hKM8=}7vYv@z16qV$a6r$#*pJkgm z9SQ{aDTOeiFb?b8FAoih7B|eebdTEGSXl)X6cmIQp9P>$a=%*^lAbO(RIe+7FI~!h zygCs;lz`yx#s#;SgoGBZicz1VBe<}jcDrUD+9cVE7+kRkrc=0xkMO@vggixCk&m>P zSg4e@d$4g=N5{`6`9X1piv~cE}Ag^|9zc+*)v@ICI*y8)EDe38q_T@kL4B?xY4GaxA zNQ4*dvW<)}Oapm02NlI^yqXqL=ETH?IQ2_{;HN2d`XvjW-e8&C-0qx-_d}ktGB&oc zI>>(;9rXkTC-^-%1%=DO4nEL@OwtmNh)^}*tERVp4ODwUK^}h=*&O^$YJJ3DF@OV> zOR{y*(QH;4P#cf{Cm-u~KK|Ba5@fPHQSll_8}vL8P9?(qtLf83rdU4T6wy<`_v!?a z@ef2`)!~_7=wPut%MN9PvkS_60|Q#%7tD&SsOXgC8=Y4DwuPX%*yt6ReF@r5P-Ugy zGH3xiM@aa7TAlmx(Khm?LgcfhH4RNyk=;ONk-8BC=sm$9K-eMdZ^ww2>Iw{dV74*0 zgZUD4pDvKO?EKmc$hJ}6?dHmb?Cn_4#yC&>{d*3UewuPs??Kqd&Lbla+V6nt^+mLN zd4!eccQnifCpqEpF!9|;b3u#zE(7Z%$RPqO0!tggrs!E!B<%AOSkQtH{g5cBu-0|7byREg~5Y#YF$) zA6K3M~&!#6e9(6|#2( z^Va|HDWo^R2UHvK`ZjDUK$BYv+Q5)~RyMX`I561T0)!%TMUeFfj>?!J$77sDSPkh>C`OkSa7s zYM1)#x)k)!M}FA!@`c?njpW|^bc*;RuUld{DvuwFkdxmN6cGV8%XxTudH9cfd?`a} zU*1OhbL8p6vvT38pRU(8!+Z0fOAJ^h5G3N_?g5MdridColiwL|p1~KVF1;Qa6$=$= zs1#AdfHlSP^eh7rF)^seh+XD?0D;T~>G@y2+<*>~4S79qqn+YXWJhajc1A`Ftf8*X zl#DEcEiJVu(d7TNqMeihV2v_pLAz*f&WMj6t+BZbcECPe)9F?=1SNvjJS4Tgi_pOV zfM;{|(IYnJDx`tH%hiZ@?cO9$0PE?b+fH@*=;hgN&c_Z!rR=W@|Fe0w0spI_p`^x3w7v@?U}ko4A%(C+d_%*J_b)tp^oXpJg5V4m%rw6uM8SZ_an2HGqkf z#n(m_eLoK*>+|cit}_;ap{y88u*6kkiolU3CMF@otV{xdO%}fxj@OZhQSx+`^Tu8=|6CkTL$_m@N9O<vU1|OtxHRN_uXS+n;#D+ zsj{9s_gBng?FUZU_WmKbl>r#os;3rY)*f91MTAx-pD|bwxVVS_*v$X=bA{?I@^J3q z(e?YC16uxVr(r=<40C_ocdmTZ%|Y0GJREOp|q{0=n`9i91F{ z?X|x9IX?ePm6RkT92tOuGk=i|i8Nw}D(nzlAeU|_V(%MNo)*$o9p921Fc zOSESu;{I2-()cD>CaKM?7B#||1DiOcIE6QKtKPZ854u&DE10aTtelz=x{8hBDBqyB zDutrD?6!iOQ61Kn`&$p8x2k${0caO{yYjZbU)X(R^um^%iGjf-Fw>OUbg5spggIqn zZtf}Fz}eeIMxewb2ZB{=c;n6kJ3A-?&$qVRJ9f`)i>H4bn7+Prkap5}R89v8{=?4! zrX+vPjhsWQ(6S1!A9l{@iDYKpcrsx{5k2&?i1n<;@9tYI*B=378cucMRoIijbgc z?A!c2I~=kT>RDNyn;9f&y0w4r!RbCOp`rwuToJc9l3KSOYz#I{VKY`XN=Hkwrlu2d zQPlPiN{Vf|R*Fm)VZgtsqA~+~h1RfR1~PqVWMsq>q+-tE!SH(BPIgr(Z$9sVrTD=E zuVl^1k@{x;>C>*1xOp<}T=?|yp#H{Wvp)#G=a=eSpFP7Z9!i1{!s?zrU!ov`suees zS}6K1P2|7Wnr7#CAQn9J=;$bXSVBM`_Fmg7ket<5du~wCAT-G?!P-z8tK65vJnrWA zJ%E^uft-(NBg@~c_`!AZx2WvN6D(Mrfa@ixCl%Phha>r>%8>y2a@;0Y`9 z%~pX(3Rn)^y&DJmI-8r%sI~yy)}65o7wt;+Sd05=T!yTp?($Ymgd zKYkR2NQ@?nVie19V?(-P=WB_tpX)IoqZq20S?_ICz4-r$3A|aZG{OONSgGC590lC~ zXpdL`P+OtrW#zLS7@MiVYymY}v1|g|aj>hrNI~)JJ$%AFgC4AZYQ`-pMut8=B7kXg z`a?1TND&x-bh&$4!w}T-0}RrJh7uZ*>sO!?JnI;QT#Gkwn4yzm1^6>kTj=4y8kA&G z@C3B9q-30)m6<-GgNwP?<(P>mK!pjYzh4KCbFqN{;1yxKbgRzA2&6{Tp+d5u9 z*2Kw&F(BCa;E_Xd}+ykYU-boPV`V74By~H1vPv_ zKhW2rPLmkYroVqq0VT29ZX?|RZIPrnoD+s*3kn_+RqeiC%Hd{E79e;40N2<4lG0M! z2M;n}8qC|SeVdsX2nP;=q{tWz@j*J7c7g6LJfY8@V*%SHAki15XCs=}Mb?mjD*s#c zpaVdw*eTiFc->_3{G_rOW>G)XuzO}^7|=JNcqS(Hhm?BATg{?r4s)G!=Eo6iY;5Mj z$+?9x}Pq7|85i*ifoz+&vhg#K{OP|L}SP8;LVrJ+=4{0ul?r;2mmopB5_f4 zZlVTY(Rn;LkQ@^u3v7ORx;az{b)ZDxuLHVRN@`58IaHzRLej=2XF72u+5kcVPQOIH zagub$S2gDf@F>tWd4dnc;roZktcZ^v-7=X&TLi&h4b>^?zv@Jqmq#Q3!^6s+n#dsz zBH?adH~$zuQLuwN&t@ILStY;?gh)>3nU}iH-s^KxoZuer>gEx+3JX~KFmR{ecolaM zqKe>BGWa6n<-n&yPCg?j0(W*D!VfCM=1+`$eC{932{R$zdHO7`xC>%OVY1c-59SatpPid}&dbZ<5>(tyj*p#muRmhazte0Zbvzs|T=3McE=`sfc1AM9?3d2ew_Nu_%l zicI*B0rxb$0uQA6?{@|?&JBzpGN2Hi=@8l0gtoz=LJ^xvf8>cgsjL(Q&~%l9BTX=^ zq5JE~SQT$_$MgrbD_35C#zIYP`C{$x?exyMjp7G=c|~O~H9Ifq!N$h*mbbbHWHP?f z+N6~>YW?x!MY_Jl3u2G6JC}AoL~I>g8Zk2!3R-xxKBW zuipe=Gf-I?wg8X=C;577E0Vw(eKxQ=ARiz9?#_q9QB{)&i}DDLPQa(B$PrE?gN*ds znrtmtzr1a_0cRShJFQe_VLYT-6~JFtz@S7vx^tE9JS9-Cly73zVG&^^2doKH&a&4{ zXh5|AGZq9Yg-i%iMkg|poaGf2ZGpt0ul+z8z)lO8K2!ygTDP*j4~d1ra6?3rlPL@X zY909H_Mc+F-&C|26GIAn1EtGOzgSa&3#f8OmI)=E^jY!qA%65TGvu+pq0?sqZ$SA& zOEdT|Vu=A@1>zZx2f{kvL~C!Xe5yt<1R)N z<~vyEwNv_75W&6ztTa!)U;xlCFZGiD-P6|E`U?c{o=V25L`no;(;$)<76fvrDV#Dk zF78Z_crHXiHdh+0E7X%j;s>tenbQ_dW^N+p7yzR0o>}dl6ahW z6eq(lyeMyPC()!+4$)^eD#S?KuD@Uwc#RBD!DWPt10K#7ip|K#C@QN6GsSrL@ZrIF z6q3|4Zqp@P?7jV=2vP6e+3|oA1oN-y+AeG|ZESQK)k{FH1B`)9XG-E7)=VIoHBC$u zy}grXeV&de<*seAo2eS6qGh<+a!;=S{%mR2#x}wmm7Ncf7XwD)c|&miV8!Zr7=I%o znfYx%D{sl4SP8TWYmEpGkK@-eAndne>6?&&fdP>jAD9f_HWIO^VG#F$hA+`AN-IZQ z)7V#XY8blRbw$N*ajwSdz(&)G7Nv!SxhN_rMMRR>B|*>156CS3=~X-P zN;1!XimAG~x(-UgrBhI2^0YbFd~|_1eECvatMh)v2pT}AtfE5mc+83)V%@sF1O{ge zTcTK3={-1%V^dS5%>&wRp2)h%K)!0}c2`Z!5%zJ8lg#x`M=;PcX!Y$jrYeH|gZmmb z9+0tO^@>oOUcuZCK4{k1L|{6LhGd!kb^>eQ40I3~CFP!-H6U>~L(Qwi5$d;YhRlKE zVmj4Z+P78N99^9wqZy{g_5OUWHRIfX$9mmf!QN#a zXpcH7?SL~vSI;0xeFc)jkgj{y)+N9=T^N9^4OFT~QJ!`y{_gQ{KHG|ZdD=({wDr0_ zH-~i>1~3Y>lN&(mz$P3}sK|Um&);NDB%GGKB*tLy7}Q|#>v zNxLlQ_g@-!irz~{@Fy?GHj6*R7Cf_<0{>3{9Rc{kdSj!xJhY|h)83za@LN$m=Hlj# zTv}QR*~Y`dL?unrQOCcZC?o-isB2utHr4$WmMn6?tZ73CdF%hTa+#U}bd(3uo0>^_ zP*H<22^Y!-1k9)U?NO)tZizL7nF4m)+Y^tZmug=t`U$eFc5I*c+XK2{B!a?`Xhkr3 zuxD6{R)nQF91}c0B2FwFnk3e5goOVrD@Ne^1CQSW>4X-A&%3k9MS4hvgu%bwcUqDM zYnkZb9ayZHtN~gR)q%sXivsPYL;;)mg-?}3Iw+V~9#*!nn5tZKb_Pu`X1~7Tq)3llhv5@v8_g>yE9)zwHiQi(3~2BiSYI0o z-YCG-k6eI|cplDLP|Duvhxa6ClQ*y&AAWAZ>sz z6%cEvE$U^R`A$w*%?5B=WMVY9YpyEyu_!GUT+EpYeHiV6DBwUe>2AX-flE4IxS}Y3 z6&;QKN+BXa?R)H>vmi2>r1dHL!IL33^Hqcmrl;w@1%gI}N=rBn> zS?7PpEb%`rOJQLYyk`K=K&GIl>I``C?DQ(vzUJhyvanoWV9+o&9#g2x$;=e6$kB)I z5PpiEIU1(DwXgyKF0Tjy3jYKzZ>`EWbw90I=6XA?+S!g>FD$B4 z(ML!lhHsoU3Lh}ku|+UfasHeKO&suFN>TK`Iz&u!3JVA3MVa{CWo7+7IHsqfdXt?k zJmouJw88!N?_cgcDM%p(4n%NjxNM*{7{1T&ab$nUCM{g=x43f#Zd#Xj_r5x$v-@o= zdj~=Xb^3I7#4}l-9?yRfzvF-u9n3IKR|rhgLZspp#li4;tf1%;0jcF$`Z_w=99|C0 ztGwbdH&t6&S|+oTkFY=?$Wd7R6-q$DpFh(}gT=3bTyow9vJ#g3$h(4q>iO-V|yKBaT zTsKNdWJ}$lh5->cP6%+#%(N^ptPoxrudX(NJ_z&#<>m)C+OTn`oC<^S7Uc_oivy;z zD!1mLu!Mqw0-B!+v_H?n(o%J<@Ay0DL6(--K#9TSOf;}7#tBHns2~;p`uI=a1p4}{ z)S>mF|G))B@~eXqa#Q z+JBa;|)Phn#GOnPL~tq@Iby9>K_mgAHF%=KJ>%uw;WhFSDP3iB-0; zn%X^B=7P={;zeOTqVzp50U&)!PJ*flh%q&_^6=q-)$M6FqEhpQy`nO>C>-`T5Jf;) zR-uVH3VbSK;OtLtUXpO-#4W=}!#l#gkNkJC+eyT~E22*%n~8eo+*+N#Ai6MvexUQg zh+KI4=9T_?Ha4Yj_ZrY2@_v4PgI-EXY#@=nghxc1;$qVaJ{Vh+8FBXo@CQksBZS1J zM$A#IR#SGS`_~{A*4z#-9%PlISvQVyMm5X%`i|{pYTrX>Dc1_?>oA%B!*JA!rx=c( zT-r=#P3tn{S;xAB2JrU5?g4&pz4!VFs(aOmjpZpRv<_9vI_QOd#THFr_)#0G8X7im zd2j8AJE@1@{Hdag1tC za>Kn|Z%z-A74GTSC_f&m189a?cH;{t%9@%K2KV<=VMH3ukl z9$o&Q=H-$gMD9N)o8 zXUjnYh!KM!3$oaZ?oxov1O$;_TsF4@w+|>oAOvJGV=I*#zQ4Ual-}COs2a28<5}~a zB$^~ipHM;%xcoTZ;j$t6582^(9?1C}oOI?3xr%A5XDFbl!mApdmZ!x zkH3E43C?^9cLyiJJzqE`9=|F8u6%>^Wk95gKG~pN12qsKk>cZ9#z0_l=y0-0NJ!W} zT%Q8%4|)xcOc~D-Ef9);zaiYn>nLepaT@$S$lQE)CS}>28w6E}(slsP(B0Rkz?(bV zIdTyBBc;$3vzz!8+5|6z{>R|*kKy{8Vmo3a`|qN!7hsq|a(~Hn(BA!YwFn{OaEBtWbxp`iT?Zlwiytt?07gg0n9d$> zA_48$aIPM}I*{1v!;oA6L9QPE|r$T&oKDE)YNx51s3#zIMcGZhxLG?q9;}qS3$T z^~jAjs!7PIy#g0bJ}hI*VzYz@4o!%IfyLQ=vCjOZ0M?pdnT#+$tk)_~gWZqxa|>$% z-&;`;BszwIGQeeEi1T-lsS=VpMI|L+`xT0c-JDwC#z4QxU&jLb%?UV4Krm6TZ$MgF z8i&ip6Med)--0q;ym*nLVR0X4O0+Ctuo3u(gGv&xMGiWLEmuJmKYAyo#^Va>NxaHsFq$uK}4SvX5@bE%2F z{Q|7)`b^o*W?MVEXQ(M%`F7;q+b>@_D^@s}0ATUBaf7%at-W*w2pek#%R}1_mnGoY zfz=8*_yRyg`vSCAT~zn1O~fgb)xC1Zjsz=NA>FgQR9Wu(+yPCKyU1z$m-}R-A|S!k zV6OCjTtb9xm9T`n0P1q!xFa??sGq!f#o6k0uCDO$GB(WF(Em{2cc^vtWx|UF+T5kW zLIo#=4N8cHuf|Krj-LzRa3yGOZfXj5`r9bD#K-R2hYd5ZN8G=_`DxD(N%2Tj+5PNc zr~u#~D`G|x%oI8FqCyYQiz>j`+`_g0-4Akvf3a^Pm24ThgyG_Rz9%F&1aF-};{N@Y zZ{M1^y7D7`+GrAIi#eQFQ)Bew#}PJ&b@*`f=MuE6(`SaH{RCldosZA=urV+ow%Xdx z8MzzkSC)a^8+-5Wdh`bHIEoL7s6|{YEc`DlEG$2ur>6%XCqzh7Ii3DDglEp&x?{(~ z6wN4g>&S>j7Gcq=CkP^h>9>|#U$N$!WtB-zo9GnYT$Bq@joT*x)CSR1khBg^iN*EiF`M+@1OtwHlJzRDfPq45vC9PSYun|%M zL`oEzdjqi6l({eJ$Coc({-JWb@=3zZJ(8=k2iAjYZipljtHP?o0AL^zIiNr1f00Mb zM-zjSIz1D4&lk-S^zPd%pOEnJjDP0ioTY-&{w%pmi8|zks{c2gAgNYzPKBcMF`8FM z0^8dr|$+5CjxebmPtXMMT5&ra)V(Wq$JbAOLhGsRPKX>k2A37~0hp`t? zB;v(;M?QuNHCB3fc`+CUL^yCAkXxiXBs3e?lpR%Y3m4y9-y>zsA2^FeaQ~_0oD;mX zrH!QantG~>{#x?c-)fOkJxXM#%65c3o|aO9Y!7qt5{|^08eRt#ZDf2|#iI%;t;6XW zP_0)aRk0$*OdNbm9Lgb`gI(C*JV^bmQ*#Nil9yVn!m*C*<{CxC#hPw zO+?cK2#;ia9y(*GH8#@6tPYg|>34UJe);;f%aif_4hxw6G*#{$d?aS0aGjH*$=zMX zhrVxPhBrx~99r^VSkPd@fYte^R7uSybMq5}0ba?>WEzT2Xe#4^eP>d7&N%=AkHJ3g zKIZ|jmE4jEVG)s-vMK1FS57_v++1%cYWaLL>$@2^Z%1~2KZv4<5LvTxeE>^^I&bg z4*AHEa#eM8A{NG^RuJ@^7uRA1TFaJg$GpjSVxNEPA@{R{om1!PdZz_6x)z{> zdbp>j_IHtnx_T^dLr@#ijwJ3?!|xvsj9C7B+b8)&{X*^m)}Cif?T0=NTR0GfRQJVOMPvIMecIL~_RDjg2b$t2m( zz_&mWwLGE!nxXG6g2H0&oe~F?Z&km!K|oJt>Lxu0&Bqnd%svlna!9n4Zh0uZ85urm zZDqC5*H<%`Et9xDpEWD1F^`+G%M<4|Z{iFoWttSN*HAoPdTS9w3IVElL@26#x85ir z@ra667<pk|U|LB*X2$%!X&roTeszl3()qfKA?>$Jh&G{U);wg5tm%kJtACC{=t2 zhms<@meYqS7&-{NvW;AcfC;r1UDRI4(hGsw3r`>)OE1eYlnqR~@^T_3=j(!EpAC

{?t^!h>8^6U!c`Ja`Nf3XEWC%TDqPQ38cFMNg`e}sX9EkfTJ)qO&Szxaw(iT zHR02W`~$E}f6he_UJ9hJ_uO9A<`*HU`ZDSY4%Ov%&jk@D5hRu)b>mULlm>#g@7y9> z_jv>aC+D+CbQ=3Vc|9f{o5suI)SV%Yl+(0Lcv^{YodEDOZQ6PG4!Y~N3CAG=Ark0%p9zcjCJ^7A5Zza#bZfbUM6kc2aedXg&tgtoU3Q)usxOi-QiN8R+#le_UN zF!|#haJNL*yxH!c;E1~P#r{qVJ zWqkhZj`j;UI!@HQ^+J+RpO#eJU2USm(g#KH_We#V8-=w&r6EY2wkVFHWCxbpjIxVR z9ROIiu(<1cWDhL86A~a=%K#NvQhMo|bc#NAU|REwv+QAN+I)x+CU>@T^-_711!yG~ zMAG6xf&iFJ#5{X8osDM8$HS@q=L6ZX;bErN@6o}PD_5TBXn*sjaSW9+c;kwW*;NIv zeV(LR26}B=oSdKF+&ObB7HL5}L4|$N2GLeZh~f5(gGr&!wQ6JKcYJ9dR1icS6&E^^jhHE;0#Uh;CzZI=DBU{*=;?BTu0 z4JQQ-wP7J39u%KYqcMWDWnbuSepHo6MQ7k=>&(6I0<6z8kR{kX4beg2+@bbjm@2s= zp+|`ahQ2FfaT*NYrZvMm7e%@my69JP86k zp0ko2QFsnOIXnh3cQ^H*%GJGJc6{DYUxQG+A3iJt z^j+eMRN&-@_VLlT4CZ*0E<6kUKtd8jwHzn)`(;d3+L++6=bXjn{&$|ENfs}{s_(z= z`!gQ;Ts#|8R}~SjAUMlhtlWsWKsDNQS@3hdVuYBPzukelW#ocgMVBT{!gA#5q8&?#TWvN+vc6om`4Cbnf*EcOQuKR5o=?-7U5| zx$e9<<@g@1uBLj;)VBx5-gZ@*H+YY{9M@wCPQ~oagD`ku?7@X|BSd48#3G0j`fVAI zdx^{bY8HUUVbxcyI}Rn!iac5m|NIFi<*nTdvf;J7|8RTp5mZg8nN086_gji<-NmOM8B1h70JHyA7s>)W@q7lg)eH**YOEq}QX zOGa&yzbQe%EH06k5K=RXQ&5(W2S>V!$B(D|QSJHY?aLqId11Az zzqQCZt%(Q1Xp)_MYtPH(3yAwBB_G=(E63@EKJN9uN*fz3!^6X&S9r4e!19Ei=B(<# zsUgQpMMYWztxczqtKQ6wd5NBK8Y#kYiyjf~R7YO@8Nz&xa^yIcafYM)73wH++J0JU zzRzXQu);|`4}7KJ?vbCbcJ!(-tmnV=Ne>=3sqF>B>|@G-%BKZQ!D&}aVxTFoba8oX zao^OTY*nMdM75A@hlQ4|u9-#(XsWvHlSRw6T_`f zDbV}*AxS5Af;EE?ru<)b_abO@W+$n(s_W{O&gtwym5J{ih*kBj`0Db(puvw11;)I=3FYb>EhaXC zQAc<*nJtMA9LaU;En!reLlKA0!a&ZqIXX7|9AcdK5PMc}*|I0Q))*LMg3*UOzu?)c zwl-L12Pi@wm)wrNm#S5PpRQkf_qKomr-~1dLZpt2aN+Ppa1xnEOy;3oN0MuYjZY<< zgMIp2jB!ERFO0=JFrzn72}il0vDQa}CW^TI#$i>?i_PK+(=E7FxgGgd@$A^wYeedy zqN1h&E4D4@>th%wL#p){(AMuW{*^-v643%2;N)f*EU?zW;cB z)^#_`-!5Q_0i^BuCeCN5&q8YTQJq}Re$9%L;DrzslD-JmNSRV|v-iu^`$a`Vc-w=c zH=@yv4hq>4m~&-YRy-n&sZfDxPd6Y!va(KhS*Rv#deN2)qMlAiN2|odq(q2Uygp;V z%T!_?o=D3*SMDXaq=#HgB_@Tb)~~Vo>fl}oec&7&1^6~R+~#cb?Dr;w!7ov8D}Ac> z155pY{S*q;80e%Z%^e*L)?3z2mbTBEIddjBb~T|Q-<~Ez1bv+>I`k#p`T>TT&sawS zurrtXjv)WVNV|eMlzFUg%trmtq2go|qzpd&+oaDMok9kBtJpc+9BB5dSLv6aE(E}} zP*Uy-p~rkq%cKN_6qsVvvHRGAo;0waNrY^q`|KSJq9f#RU& z#+H_mH*a=m>&=aL+=iVWcmDX-chKjCL8eyGeG-Kg!2F?D!!GqZwr}@lF=KBvwYeWY z+)Xam1Cbv;ek3)>?jB9>-`}$g<)Cz3-_!_+CQWs9(bbl(hPh<9gLxjz*NMO$F2 za%OjeslxFAdl6SpP1{|&pi7G^Eq!k5A|)ep9XV4t5gr~{f@HrjBiF^-TP;^hq6L1g zSZ?TOXmQn-UxO!*pT$R?bwPN62}Tiq{o|O&4*a83OPnTx7CP-AXUPGa_Gc|r`E_>T@wnj z7CoGr+~WNHwghe}Hsrb(*(Udj(-$^fgWXmZrWx>Vj{O5SrZzZ6@P zXt+sNTU*UbdDrllOFq%t<(86~l9F}hN(MTGgu}kD$bH8rQ=#i99-^d8hT&=Y*~O!J zAYjtMKfkI`ZkybP!>0MRv0}BeD0L!=m*6W=-hi%Xy}MN=}{!^Ojhop*`PqKoHN8 zS3ZY6;hn$Ugi10zCkgb$Sc==-_2VR((_k4Q#k&|;0>|kiusDP#%)MuA@84?-_(hS< zf{bfPdu9eFy=Jj=7>ya%ibs`tdplnZTc4rE#Hv(vvJ7=`OU&}_a>e7G9NsOK!+()C z9NNksZ^s8`z;d9a`NG14O=2;56>jQ<+exf|a57#r2GrLg)A!3RzjooNtNF_j$Rw{& z?W#o(esB4$!^OLMQQm<5M!Wx$pufN_4c%%i(3~5(>j;9#ml92&R0>WAwb%H#Atxo_i;`=!xwnvGW^8zY^_r;d4$) z`hGv2P97fm`mwK55p3&Cu_`0$A|fK-tiL4oV7)s!6G!>qb$hua?x{juv~+Jl=A<5$ zneA=OB<#sLK0P{koDT;LBQ90bs(AH9B6&FnnjL5Hd_^OR>FL~^l$vUsul@aQc+-R6 z$<-djn_K%HhhHn%{{hqf$`yIN;pR|D-@Cgazki&9xOGXZqwa=2lmX> zXJeqgO?aIOAB-9&b)`U6gaDDXwY(s@A=X$58R5~Zx~*&${P%hBW5bHa08T*xrL(a$gl$Vjw zC#_#@k>t_mE>Aj|qJoFxHggx1oFl&b`E@9Ie76W5nVG3eoDkfbDu~rM>DKi6INiN= z?5G_kJy^iUYkNuMc)S^i5%?Ai6%GV`U)o~TckbEK2q6~giIrc=g%+o5hEP8WO;%x8 z6c#OR+{86VnG&HZ`{27;r0%gNWZxS#rc}S?qnp$p2rJ|f8%>@hNTv$up!YgAVuMMl zCU$NZ7=H3pPGol#MW8|+qWm78AX+|^h*8E zK1hj?lv?fdS8TK0FZyQM#9Zd0ON#7m$<3^QbICiE`-dL7QtPPK`~}|}nlCNADAp8# z$vVBtRabQEJZp(Ml9JQi88Fz8++Kb{b7W)$=sFnE0Iy;5!1evOTkU&fbWp{r-Pr!Q zShMLGhX47qiVq~OsLHIbJD;jZS2gV#IYv2Gn?xSD%KIY5C9Y!wDAd`^4J%ikVy-gG zdJ;7NyAnXo6%cc+GDQ+iSN>=t_Q&8TdPbfBq@SC@fR??zJ+g!IkptVdZ?6GMAS!B~ zm%^rN+hEhMZFkVAfz~oP>nFxfe6KeB{54lilzm1OdU9r!&;c&if)_l*qqm|WeZ9PPPKBVgp z>aV^gDT78}_`ZI<^q}Wv-Ud-CiI6dFg5vBykV$U*YdCR+a`{HO*`?FNKleryd`%Gm z+nVG(s;L?3$z(%scJ%5kh{Jumg2wKF!4g@5^6*Sq{YS&Y#8Dd$qx5G+MU~JtG!J^abVvkiv=6UYu}%Tu2P^oQ;fhW=|}LBYo$ndq5Gjo!BW0 zaz?dprA7r;`GVu~=LxY7GcnELdApzg(6zZ`PfR|8NoiJ!D7i z;fX6~1cSN48T_z9NH4-TC%Of#r)}Je8+lWl=}N>C zKucrwWtCzNIuCXd+SaJ)s^33kuX|QR_WXOlQ%{}a5YNFa+``e(@sp0#uuDt3^b~ct z#1T76oZJ)6(C=8G`s+)ZG&F8rDH^xw8cAYA4_IK(xH)30TW+=J2EZy5(RJ?5JXh?_ zXU^0-5-2+#9qnhCu49P~L!AAJ(B&@|V6ABJXFt_&HFo}`_-l1Y9#;{~p4vh#qmw7Y zi;Hba%km0b8|K^GI@cK;izf&ucAJe&B8J|+DtP#cL}(WuCNh{AOK;>=)uSlZtR(u1 zG7&(pHuPXm*to;7e97b#I_@ABq~A6#Uu2o!0%Gav+S*#|{gE*-;xT!oiQ&9nZ@#U5WkIuUYY$pOoGc*Mfe@<{ii6OHM*4Nsn!;^^0!IWZ0K^9oM%{49?1`42Yp zoTX-mXwb7TdY8SIGL0^WfG)7fytl^bh0f|j*f$}s0KoLHriS2cGWfj#Es3*X)jch4 zX~L#h)0JDTeNVya67l&rds-QFkgHQ{DY>z&f5FmPhJWq6)9e#7}*YDYLZePFY zPAbZ$OY>2IrQaofi<7AErw*IeJbx>gLN_<>%@-E+o6kDbvbX@(f7Q62{S56Uj!?%4 zZeqIU%=E=akXxJXcr6ni5fR$=q@lrO^4AECG6dKa^g#m+jYmI+is0t1$_h}Ww1yaP zRSMVtnQea#RP#D_`dCO8-*lb>=l|QKgbqU;P^+sz!Ly;xb}M2#SW^2Sq>Fp%j7g8CO8@9AG7cby>Nq#!-4Ch=S0>jRzD6-!B$WHczAeXhuQy2%M`VKU z1>l<4Y;`$D7EYZzuin=u*KuJOXES=fL5ihHJ8PQc^y@AjG~$D&jTvKcN%wVB8^D6u zd8hnYZr&SgiQ-6Z6hfL}r-r(u*$2l}g3pP)iz=&@QGZXH@cgvUssP^4GROC7+uu)A zy*cy{NA&~mZp!}sSF)}cy@;ReVZ7UpPdy;vpJDMBg6p@C&b-y8 zugDmvqiif6vF5_Tt`{#JV#1;BDsbZWxi#DqqcOipfWVB(USU@kJSI__X`VuuxF|tv z+3`9QTv69`on8kIo*QC#Kn(71Va(q79kq+6a;5?gdy>soXYY$~t_5N&!G7hBmyZeB z>?N>ie{Ej@9^-D5S{t7SK=FZy=KPs69#^;BIB_Dz*ptHYr4xUapqmZnGxluJ?Z4bz zK~A*bVEwTUe}jYs|M>WL&7~gKw<(I9=RI~zA_aQ?c&()510gY#8Jw9KzKVU*&F=S1 zYhi?boguA2xZC8ZkSiFZgYqlr9g}Bm9}xZU;X~a`#aGkigBn{6_!}4D(%oY7*%8&z z+#^)SML{NQ8AWT&n`@)ea&Eq>{`@+(;A98LAQCF+*%cLsF2*UlucgUSwoo)VTa%p; zdx0sqBQn&(DrDRsEb zdFU-YoOq$%a#EP7xYwVY>8=gL{F^sroUz$(LG!c?mtLvw<(_K1w!dd!oO93c)Z-Lj z2q3Ev6i$2;4>w_!?&O7lF(AOk)2D?Go5mTi{VJ-c+5k5K?t8TWz&Me1Ug_*(q~a?>B#-vwXM|KnOdQ?k=0Y{b6`J(HE5{*_tVUr7BGdo&86zT zMtSj!IS1zc`$f+}=JakM>AKrdcJxC9!SVloaneGC>0!9ETS%tv%M}6E!VCWKgIoXo zwqO@epjfg(V0W)+j2rzW?OiMJv-9uWh#ThjqjW6}{8{k64#2w?bNAm1R!|f&5OPom z6fJyTn@elrxvM=D{_kD?-43K{hv+|&*kB$cOp)cD?$w`0Zcpr2i?prC#A3A#tjh;) zL@6*8^1mlm&G`4R4Jm60noyW(RN^xo;d0$vFT;N$^;O|7U+`cfi{f@SdI>#=nXdZx zT~|$QxhG`QHnY~d-Ho)O_tI{*Kj{4TKD&kX)NDaV72_a19?!B0bESW8o7G8?k`H__ zyU1s{j<-N73F6>I;4k-M>KOO!Fx89eV=U=i6kY$L#y}xCmoR%;ZioSY?KDRt<>6%B zDdA-$y}9HO%zj;ca)YbVn6=G4tJas+Sn|O8&(DDq6%&;7MS<(I9D6CuCdL={zi&}+ zvwFe@Y|E1M$oWmMAYuBypR20V z*BYKWy`s{NI@Y7hjttqKm};^j#DI5Wa#fFqFgA{ZA^Ic|!+F*0rtM4~|1pq88|9mj z`t!qW$WmvFavStCM&wn~>?L%{{{8<)twqpJC;t7(eytgLJmrfG_mH1tcTdmMmV9&H zo7FA;r`K*QZF~3AdZ?A^PUrQO`efI9G)b**`rP?AWz>F4c->y+-`15ep9_D?j4h4s JtlxX;{{SZ^FS!5! diff --git a/man/figures/README-unnamed-chunk-13-1.png b/man/figures/README-unnamed-chunk-13-1.png new file mode 100644 index 0000000000000000000000000000000000000000..cae4a419221e7c92e7a2a8ea243e210cd366c208 GIT binary patch literal 43452 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ℑIeQc_N|xBzp9XHTakUdL()~)ZX}C%l9@V|kERlS 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 Sz{PBVA46SJT(OSR?f(JXY_%@{ literal 0 HcmV?d00001 diff --git a/man/figures/README-unnamed-chunk-5-1.png b/man/figures/README-unnamed-chunk-5-1.png new file mode 100644 index 0000000000000000000000000000000000000000..009cad890789557b5afe7c0a3e9498a12463cc79 GIT binary patch literal 41027 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®{c?19HKVc?hjoiBQx(V|WTC#bEv zw)ycGGWeC1i}du81olDA-p(KQ3O^{Wdbqrta#nswzxk=k!HzNJi%8XXjFozR9ghW` z1*6Pcl8FRlGM}KfzUPI6y`;1I;lJQO5X^bqPWh-_=MD3x5<$!WJ?NoXNB zjugg0v7>iw+Bj5jB2X)<{GMO*^#PTR^0)*fltX!0VN$ebGwobK$SPDh%F<6;*=*n5 zs{u}~&p&Y!N6zM}d;ctdnS#~Vw~nqt%pXa;1UPd8O;ZP2-%pH{DzI7FY;L!07s&7q zZN3)X3%%rec9*Kd@5vlZM2+@;NE^>k&;?NTj4O8(Y50}8#2cH09dPKUwd`G8uK=WockB))wW zrZT*J;!;N*5G8|`Hh?NBJ8A5SKko?{beP!qe9>dla*L>o2U(|H+V+e$Cra-KTUWD= z!|surp?W=b%&qFtTZdFOrb|nRF@IBptZ_J?RI7JIKFasbS+| z`noR(iE74cwb}W!#Pm$$M5U@Lvwfe#WI?M;I?tFO_*L5gsVAV-pi6Y!qLw27G$EEuk8?F>faQ}}z7tZACKUdeJnEiX1R zZALQfJ@izyV5=*JjF;WSDHN5BI$7z z@BT`E3N$T5&*z+#iD~IGfu@9E<9^~>LY7500~|njHVH|;&Nn4nktjWlXD-jf6&sng zn8xFnQS7V{x_(qr9H%D#A#r>~Y)ykEddN#mZJ>>`Gb~|i1rw*UY&W9VinoS5Gi>`i z69w)5q~kYIoYzkXzZx!1^lYZO3YeycM67x3HLkGFuN6X0JfcX>Y?Kg5%Y?*5x}<+CdhRXhYsf6U;nw_b9Z zMsy;Lo;-EiJZ)JFK!K$?0cjG&te_Y5+2&1xJ;2yj%4)vc^Pugd;k`K-2^}cpNC8?X z(<&3FIOwi}jVb9cn8;&sDyTW&Z&85X$EkLyI3hEEk#~@;r_o$1qp)_WC_MK ziB?+d^`x9LvvSmPB+`XYl@(@#_=$h+)ZUQL*$pd<76n z*rX9vkRz7=luO*=0v-b5C53U7i!Uo|#H7>EHY{Qb2>+yEKY;~0w>j+ZeWK5mqHG(_ zXw->dxU$zAav%P_LIR0M_K&?11;!oNoCUTU4w9XJ*O20{%YIQR@@qXOrQ>94({ikY zU#A(K6h!?xFTAMtJq#a3u-_5Uq7r`fpr$B@{r$`FUJLvQ>Z`gRr@x;=V*&*sJ1oe;-pU_E5RV$||@*qE1s+)!9gREf$XBA;v z;mVWGICDuweVJ*l53EL<-eHlDf8SG>!d#LdHJ@+XBtp%R!Th49ytw9)wNn#k7-TLp z4jCFPRmc}FG|n$~BRCtiwBjZIjL7!EFj0@1D0r8RENkS@4?pzzivqBS*W=K3+{7U3 zp?N(io=NO(a+r-Lbcv~0ET6?A|FEm!andgn%TPs!NA|<$x;BIshfuz*qRJF%|GZ} zgvj+ugm$ra>z=8FyTyzn3?E8Ez@wtL=f^V&lOyGa+iTv9%56F&7TGAOw zZ0DLDL4kjR8FuJ4EGbKq!qM6c6yHI|vJ8d-AK!Kpg-4;?G@R4sl+9S|G|6&e$^B~K z$Q9nef07(X1@Co;UxE0pv=pVre6S0!R$c*iC;_x4_3{-rZ%CMhZh5f+@@9v!JZ~_k z)3-&SjH&E*JSWDIMLY@2m!J8yjH^&EAH0;;dmsJDPF&rQY0Twg9r4OIX6$Qrv`mO+>gH*?#(tf0EVdpD8_fQ2jL)~v7!GQYA*Swv5^rV z7}Og<;lga6W!k=My*}#a_?B#Z=|nyQR5><3d<^rFXTdvT6M%BFW7{*9zCiy~sBb9c zd**CmrzOQdaRh_3YNE~fFz-t4$-}Gob`Q91?s`-%wJ%?&_-ZRPZ=JP$wMY%eC+RVO z-EPGAxUDreaKc{%JDp4m<|XUQmfdih4b-_*iu!imn>z~Q#+gAt{|YmQfRdp}`ClaT zM~{2o5h~+OyF3>VVyLzD{6(}nsrW&Xx*fdflUBh~NlLw)i z5e~3H#9P1x%d4qjO-9y-(=06|w@0A)21B{A#k^puvFrIJ}hia|qxd;Vc_s!!bMwx2AdLGJbxo=iuHDfQ0Xcs=s0w->iS+gsUqP^sdv;r(=RgCFL-q9R? z>#_-&3B7%%{dQF=DOiCvVt}t;Amp4@oSB!Ch;W5Cfv)wW=j<|82FF$TVix66jV|JR z&o+3j`iGd(w=41~TUPmgMN|k@RY7#*6-kK5;7PdqMD)68IQMX<(xp|<(TUYa%} z7-hWVPt2b47S^aU2%J`vrhN@T881DF$np!StZeFayZe+@!q_H@e4K7W1;RY_*uS<( z8bbCVWgLfVeY<~Pjx1`A0$=rPxVbP^zfBB0^ES!VxxKjbW3GAa#X*zvDQzZFp7|1s zqI$4|BSH24i7Yv__D~twhS-T|$S0Na{Z{R|6rYYs5V41E=N#FOQc%lwq>`lt9+jQQ zOjh-(4mGT_h0t^*zeR#Z6jqh$y`+SycpuW=73l{rg^>-X6^1tW zry>G4hDrulh9zXCL4Vc`_yvLlLYHXh`k(R;{8A$4hh{Mr%OdnU41t^5UkQH0FDdt< z)4wlPr2?^jO9GeVcTofCF990xN0J^|;{5l;C0O8eT=FAgen$WhD6=1eiU_iCK=AL2 z$3P@4=TZ`r_`MzhdZ!Qu&RfaZ?RNnLJ=N?ja5`#)G-Q7l9tRbT(pHrHjD*BSVI*k1FB~7tI0m7 zeG+w65-VS4Ut9dXs^Z~F8gdZCe2~CXW`UFAV60MSpk4J5IU_2z?gNH~?XDFsf2!XY zml|X}KduTijmJERMCnW|1!&-iFZfYy<(@LMy_Hqjd{q_NKyx6;#p`6~;iCp>ryH+_dal({gX}JoFB6`_CL-L67dS=Q*rOY( zY3}a=Cc~6;dZWdCzCCV~*4VaSu^gPAvCV70Q!HP{T`*EE{30nwnXB>EB7Rz}d(x~- z>626sUVa-yYKnYF)<2>dx&yUx2eUwB3R*!7Zfxj5nq$;of!SBXFPq_ zkg2{`fWIg&4zF*q)Znr1NZnM)Fot1&?|aub8>cd~xDwe!NL9ru=#Wore_>MrIItq7 z1%i9a{vdiW0=y5vZTY|LaY)Y;^tMQ!rpP?B-E~ma!je>$*<}XTx7iRs<=%->FB8Fp z(p2~-Tef;}RW2qz$7wY$<84o{-eqiK+wzx`HigZi+qxxh!n z#iI=?aNXptnDTg?-S9@Ri$_vI3Vw*WXkWGBgQLh6^ZJLb{kPj6Hv|jUwJE)Cld5e` zP&^o}y{vz{;KWaAK5ix9cz`j&&6yWZ%u0&!l2uF!Y-1j2E}r7NnzvTyNQ|W(^WOwklliNNegJ!{T|R&pgCeO zSu%3Gj2z!3S4-dj1ie|ka@{bU9B;=H!zPd zoMDGr6#}@Qw*j#Ahek#M!Omltnd=C=8UJA7Mf_3!0OFIk9RK6VAHiGA!z4~@f-Oc7 zpg^~d`�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 a-GBc2q8E3S9lM?}0D-5gpUXO@geCxRS*w)* literal 0 HcmV?d00001 diff --git a/man/figures/README-unnamed-chunk-6-1.png b/man/figures/README-unnamed-chunk-6-1.png new file mode 100644 index 0000000000000000000000000000000000000000..5f48857557e43c5528d60810c3f5cfac0df77ede GIT binary patch literal 51874 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

Global Fishing Watch

- - - -
-

Global Fishing Watch R Package (gfwr)

-

The gfwr package provides convenient functions to pull -GFW data directly into R into usable formats. It contains three main -functions, including : get_vessel_info(), -get_event() and get_raster(). The two first -being devoted to retrieving information and features on one ore several -specific vessels. The last is of particular interest to us because it -allows us to gather information from global fishing watch raster on the -fishing effort (further details in the function appropriate section). -Here we mainly use the splnr_get_gfw function which has -been created to enable data to be retrieved and processed in a variety -of ways, some of which are described here.

-

The time spent fishing is computed using Automatic Identification -System (AIS) data, which is transmitted by most industrial fishing -vessels. The AIS data provides information on the location, speed, and -direction of the vessel, which can be used to identify when the vessel -is actively fishing.

-
-

AIS Caveats and limitations

-

The AIS coverage of vessels has several limitations such as:
-1. The number of vessels that are captured (AIS provides approximately -70’000 of the 2.8 million identified fishing vessels).
-2. The size of the vessels (52-85% for vessels larger than 24 meters -against 1% for vessels under 12 meters).
-Good to know: IMO mandates AIS for most vessels larger than 36 -meters.
-3. AIS interference with each other in areas of high vessel -density.
-4. Some terrestrial satellites only receive messages near shore.

-
-
-

Installation

-
remotes::install_github("GlobalFishingWatch/gfwr")
-
library(gfwr)
-library(spatialplanr)
-
-
-

API

-

To access GFW APIs, you need to :
1. register for a GFW account -here.
-2. Request API key here.

-

Once you have your token, add it to your .Renviron file (by executing -the chunk below), by writing (GFW_TOKEN = “YOUR_TOKEN”) in the file. -
(You could be asked to restart R for changes to take -effect.)

-
usethis::edit_r_environ()
-

We save the key in an object that will be used in gfwr functions.

-
key <- gfwr::gfw_auth()
-
-
-

Fishing effort visualization

-

A region_id is necessary to use the get_raster -function.

-
region_id <- gfwr::get_region_id(region_name = "Australia", 
-                                 region_source = "EEZ",
-                                 key = gfwr::gfw_auth())$id
-

The get_raster function gets a raster of fishing effort -from the API and converts the response to a data frame which contains -occurrences for each vessel and for each grid cell (data is binned into -grid cells of different resolution), the Vessel IDs, -Flag, Geartype and -Apparent fishing Hours which are basically the amount of -fishing hours of each vessel per grid cell (geometry).

-

Data can be provided through :
- DAILY, -MONTHLY and YEARLY temporal resolutions.
-- LOW (0.1 deg) and HIGH (0.01 deg) spatial -resolutions.
- VESSEL_ID, FLAG, -GEARTYPE, FLAGANDGEARTYPE.

-
gfwr::get_raster(
-  spatial_resolution = "LOW",
-  temporal_resolution = "MONTHLY",
-  group_by = "FLAGANDGEARTYPE",
-  start_date = "2022-01-01",
-  end_date = "2023-01-01",
-  region = region_id,
-  region_source = "EEZ",
-  key = gfwr::gfw_auth()
-)
-

(You can remove the option message = FALSE -to see the columns types.)

-
-

get_raster caveats and limitations.

-

Date range is limited to 1-year. Nevertheless, with some -modifications, we can get round these problems through -splnr_get_gfw.

-
data_sf_combined <- splnr_get_gfw(region = "Australia", 
-                                  start_date = "2019-01-01",
-                                  end_date =  "2023-12-31",
-                                  temp_res = "YEARLY",
-                                  spat_res = "LOW",
-                                  compress = FALSE)
-
-
-
-

Visualization

-

To display the data, we load :
- The coastline from -rnaturalearth package and modify it to get an sf object, -and we constrain it to the boundaries of the given data.
- EEZ -Polygons from oceandatr package

-
# Check and modify if necessary the spatial reference of data_sf_combined
-data_sf_combined <- sf::st_set_crs(data_sf_combined, 
-                                   sf::st_crs(rnaturalearth::ne_coastline(scale = "large")))
-
-coast_clipped <- rnaturalearth::ne_coastline(scale = "large") %>%
-  sf::st_as_sf() %>%
-  sf::st_intersection(sf::st_as_sfc(sf::st_bbox(data_sf_combined)))
-
-# Load EEZ polygons
-eezs <- spatialgridr::get_boundary(name = "Australia", type = "eez", country_type = "country") %>%
-  sf::st_transform(crs = sf::st_crs(data_sf_combined)) %>%
-  sf::st_make_valid() %>%
-  sf::st_intersection(sf::st_as_sfc(sf::st_bbox(data_sf_combined)))
-
-
-

Here we display the Fishing Effort in Australia from 2019 to -2023.

-
-

Raw Fishing Effort

-

-
-
-

By years

-

-
-
-

Year-on-year comparison

-

We may need to compare different timeframes, such as seasons, to see -if there are any patterns.
Note : As more vessels -have adopted AIS (mainly in economically developed countries) since the -deployment of these technologies, the rise in activities must be seen in -the context of this increase and not necessarily of more intense fishing -activity.

-
# We need to change the temporal range according to our need group by it to display the total fishing hours. <br>
-data_sf_combined <- splnr_get_gfw(region = "Australia", 
-                                  start_date = "2019-01-01", 
-                                  end_date = "2023-12-31", 
-                                  temp_res = "MONTHLY", 
-                                  key = gfwr::gfw_auth()) %>%
-  dplyr::group_by(Year, Month) %>%
-  dplyr::summarize(Total_Fishing_Hours = sum(ApparentFishingHrs))
-

-
-
-

Fishing gear type

-

Here we display the Vessel activity in ‘Micronesia’ in 2020 according -to the fishing gear type.

-
data_sf_combined <- splnr_get_gfw(region = "Micronesia", 
-                                  start_date = "2019-12-31", 
-                                  end_date = "2021-01-01", 
-                                  temp_res = "MONTHLY")
-

-
-
-

Flags

-

Here we display the Vessel activity in Papua New Guinea according to -Vessels flags.

-

-
-
-

Supplementary materials.

-

The fishing detection model was trained on AIS data from 503 vessels -and identified fishing activity with over 90% accuracy, which means that -it can identify a fishing and non-fishing activity with high accuracy. -More details on AIS operation and limitations here.

-
-
-

Hierarchy of vessels gear types :

-

Fishing Classification Hierarchy -

-

Source : https://globalfishingwatch.org/datasets-and-code-vessel-identity/ -

-
-
-
- - - - - - - - - - - diff --git a/vignettes/MultipleUse.R b/vignettes/MultipleUse.R deleted file mode 100644 index ce774d84..00000000 --- a/vignettes/MultipleUse.R +++ /dev/null @@ -1,301 +0,0 @@ -## ----include = FALSE---------------------------------------------------------- -knitr::opts_chunk$set( -collapse = TRUE, -comment = "#>", -warning = FALSE, -cache = FALSE, -message = FALSE, -eval = TRUE -) - -## ----setup-------------------------------------------------------------------- -library(spatialplanr) -set.seed(100) - -## ----------------------------------------------------------------------------- -Region <- "Coral Sea" # "Australia" -Type <- "Oceans" # "EEZ" - -## ----------------------------------------------------------------------------- -PU_size <- 107460 # m - -## ----------------------------------------------------------------------------- -cCRS <- "ESRI:54009" - -## ----------------------------------------------------------------------------- -Bndry <- splnr_get_boundary(Limits = Region, Type = Type, cCRS = cCRS) - -landmass <- rnaturalearth::ne_countries( - scale = "medium", - returnclass = "sf" -) %>% - sf::st_transform(cCRS) - -## ----------------------------------------------------------------------------- -PUs <- spatialgridr::get_grid(boundary = Bndry, - crs = cCRS, - output = "sf_hex", - resolution = PU_size) - - -## ----------------------------------------------------------------------------- -splnr_theme <- list( - ggplot2::theme_bw(), - ggplot2::theme( - legend.position = "right", - legend.direction = "vertical", - text = ggplot2::element_text(size = 9, colour = "black"), - axis.text = ggplot2::element_text(size = 9, colour = "black"), - plot.title = ggplot2::element_text(size = 9), - axis.title = ggplot2::element_blank() - ) -) - -## ----------------------------------------------------------------------------- -Dict <- tibble::tribble( - ~nameCommon, ~nameVariable, ~category, - "Green sea turtle", "Chelonia_mydas", "Reptiles", - "Loggerhead sea turtle", "Caretta_caretta", "Reptiles", - "Hawksbill sea turtle", "Eretmochelys_imbricata", "Reptiles", - "Olive ridley sea turtle", "Lepidochelys_olivacea", "Reptiles", - "Saltwater crocodile", "Crocodylus_porosus", "Reptiles", - "Humpback whale", "Megaptera_novaeangliae", "Mammals", - "Common Minke whale", "Balaenoptera_acutorostrata", - "Mammals", - "Dugong", "Dugong_dugon", "Mammals", - "Grey nurse shark", "Carcharias_taurus", "Sharks and rays", - "Tiger shark", "Galeocerdo_cuvier", "Sharks and rays", - "Great hammerhead shark", "Sphyrna_mokarran", - "Sharks and rays", - "Giant oceanic manta ray", "Mobula_birostris", "Sharks and rays", - "Reef manta ray", "Mobula_alfredi", "Sharks and rays", - "Whitetip reef shark", "Triaenodon_obesus", "Sharks and rays", - "Red-footed booby", "Sula_sula", "Birds" -) - -## ----------------------------------------------------------------------------- -datEx_species_bin <- spDataFiltered %>% - splnr_apply_cutoffs(Cutoffs = 0.5) - -col_name <- spDataFiltered %>% - sf::st_drop_geometry() %>% - colnames() - -## ----------------------------------------------------------------------------- -target <- rep(0.3, nrow(Dict)) - -p1 <- prioritizr::problem( - datEx_species_bin %>% dplyr::mutate(Cost1 = rep(1, 397)), - col_name, - "Cost1" -) %>% - prioritizr::add_min_set_objective() %>% - prioritizr::add_relative_targets(target) %>% - prioritizr::add_binary_decisions() %>% - prioritizr::add_default_solver(verbose = FALSE) - -## ----fig.width=9-------------------------------------------------------------- -s1 <- p1 %>% - prioritizr::solve.ConservationProblem() - -(ggSoln <- splnr_plot_solution(s1) + - splnr_gg_add(PUs = PUs, Bndry = Bndry, overlay = landmass, cropOverlay = PUs, ggtheme = splnr_theme)) - - -## ----------------------------------------------------------------------------- -s1T <- s1 %>% - dplyr::select(tidyselect::starts_with(c("solution"))) %>% - sf::st_drop_geometry() %>% - tibble::as_tibble() - -r1 <- prioritizr::eval_feature_representation_summary(p1, s1T) -print(r1) - -## ----------------------------------------------------------------------------- -target2 <- matrix(NA, ncol = 2, nrow = nrow(Dict)) -target2[, 1] <- 0.2 -target2[, 2] <- 0.05 - -## ----------------------------------------------------------------------------- -z2 <- prioritizr::zones("zone 1" = col_name, "zone 2" = col_name) - -## ----------------------------------------------------------------------------- -p2 <- prioritizr::problem( - datEx_species_bin %>% dplyr::mutate( - Cost1 = rep(1, 397), # when giving sf input, we need as many cost columns as we have zones - Cost2 = runif(n = dim(.)[[1]]) - ), - z2, - cost_column = c("Cost1", "Cost2") -) %>% - prioritizr::add_min_set_objective() %>% - prioritizr::add_relative_targets(target2) %>% - prioritizr::add_binary_decisions() %>% - prioritizr::add_default_solver(verbose = FALSE) - -s2 <- p2 %>% - prioritizr::solve.ConservationProblem() - -## ----fig.width = 9------------------------------------------------------------ -(gg_s2 <- splnr_plot_solution( - s2, - zones = TRUE, - colorVals = c("#c6dbef", "#3182bd", "black"), - legendLabels = c("Not selected", "Zone 1", "Zone 2") -) + - splnr_gg_add( - PUs = PUs, Bndry = Bndry, overlay = landmass, - cropOverlay = PUs, ggtheme = splnr_theme - )) - -## ----------------------------------------------------------------------------- -targets2b <- Dict %>% - dplyr::mutate( - targetZ1 = dplyr::if_else(category == "Reptiles", 30 / 100, 0), - targetZ2 = dplyr::if_else(category != "Reptiles", 10 / 100, 0) - ) %>% - dplyr::select("targetZ1", "targetZ2") %>% - as.matrix() - -## ----------------------------------------------------------------------------- -# NOTE: when using sf input, we need as many cost columns as we have zones -p2b <- prioritizr::problem( - datEx_species_bin %>% dplyr::mutate( - Cost1 = rep(1, 397), - Cost2 = runif(n = dim(.)[[1]]) - ), - z2, - cost_column = c("Cost1", "Cost2") -) %>% - prioritizr::add_min_set_objective() %>% - prioritizr::add_relative_targets(targets2b) %>% - prioritizr::add_binary_decisions() %>% - prioritizr::add_default_solver(verbose = FALSE) - -s2b <- p2b %>% - prioritizr::solve.ConservationProblem() - -## ----------------------------------------------------------------------------- -r2b <- s2b %>% - dplyr::select(tidyselect::starts_with(c("solution"))) %>% - sf::st_drop_geometry() %>% - tibble::as_tibble() %>% - prioritizr::eval_feature_representation_summary(p2b, .) -print(r2b, n = 45) - -## ----------------------------------------------------------------------------- -Dict[[1]][6] -Dict[[1]][7] - -## ----fig.width = 9------------------------------------------------------------ -(gg_s2b <- splnr_plot_solution( - s2b, - zones = TRUE, - colorVals = c("#c6dbef", "#3182bd", "black"), - legendLabels = c("Not selected", "Zone 1", "Zone 2") -) + - splnr_gg_add( - PUs = PUs, Bndry = Bndry, overlay = landmass, - cropOverlay = PUs, ggtheme = splnr_theme - )) - -## ----------------------------------------------------------------------------- -zm1 <- diag(2) -print(zm1) - -## ----------------------------------------------------------------------------- -p3 <- prioritizr::problem( - datEx_species_bin %>% dplyr::mutate( - Cost1 = rep(1, 397), # when giving sf input, we need as many cost columns as we have zones - Cost2 = runif(n = dim(.)[[1]]) - ), - z2, - cost_column = c("Cost1", "Cost2") -) %>% - prioritizr::add_min_set_objective() %>% - prioritizr::add_boundary_penalties(0.5, zone = zm1) %>% - prioritizr::add_relative_targets(target2) %>% - prioritizr::add_binary_decisions() %>% - prioritizr::add_default_solver(time_limit = 10, verbose = FALSE) - -s3 <- p3 %>% - prioritizr::solve.ConservationProblem() - -## ----fig.width=9-------------------------------------------------------------- -(gg_s3 <- splnr_plot_solution( - s3, - zones = TRUE, - colorVals = c("#c6dbef", "#3182bd", "black"), - legendLabels = c("Not selected", "Zone 1", "Zone 2") -) + - splnr_gg_add( - PUs = PUs, Bndry = Bndry, overlay = landmass, - cropOverlay = PUs, ggtheme = splnr_theme - )) - -## ----fig.width=9-------------------------------------------------------------- -zm2 <- zm1 -zm2[2, 2] <- 0 - -# NOTE: When using sf input, we need as many cost columns as we have zones -p4 <- prioritizr::problem( - datEx_species_bin %>% dplyr::mutate( - Cost1 = rep(1, 397), - Cost2 = runif(n = dim(.)[[1]]) - ), - z2, - cost_column = c("Cost1", "Cost2") -) %>% - prioritizr::add_min_set_objective() %>% - prioritizr::add_boundary_penalties(0.5, zone = zm2) %>% - prioritizr::add_relative_targets(target2) %>% - prioritizr::add_binary_decisions() %>% - prioritizr::add_default_solver(time_limit = 10, verbose = FALSE) - -s4 <- p4 %>% - prioritizr::solve.ConservationProblem() - -(gg_s4 <- splnr_plot_solution( - s4, - zones = TRUE, - colorVals = c("#c6dbef", "#3182bd", "black"), - legendLabels = c("Not selected", "Zone 1", "Zone 2") -) + - splnr_gg_add( - PUs = PUs, Bndry = Bndry, overlay = landmass, - cropOverlay = PUs, ggtheme = splnr_theme - )) - -## ----------------------------------------------------------------------------- -zm3 <- matrix(1, ncol = 2, nrow = 2) -print(zm3) - -## ----fig.width=9-------------------------------------------------------------- -p5 <- prioritizr::problem( - datEx_species_bin %>% dplyr::mutate( - Cost1 = rep(1, 397), # when giving sf input, we need as many cost columns as we have zones - Cost2 = runif(n = dim(.)[[1]]) - ), - z2, - cost_column = c("Cost1", "Cost2") -) %>% - prioritizr::add_min_set_objective() %>% - prioritizr::add_boundary_penalties(0.5, zone = zm3) %>% - prioritizr::add_relative_targets(target2) %>% - prioritizr::add_binary_decisions() %>% - prioritizr::add_default_solver(time_limit = 10, verbose = FALSE) - -s5 <- p5 %>% - prioritizr::solve.ConservationProblem() - -(gg_s5 <- splnr_plot_solution( - s5, - zones = TRUE, - colorVals = c("#c6dbef", "#3182bd", "black"), - legendLabels = c("Not selected", "Zone 1", "Zone 2") -) + - splnr_gg_add( - PUs = PUs, Bndry = Bndry, overlay = landmass, - cropOverlay = PUs, ggtheme = splnr_theme - )) - diff --git a/vignettes/spatialplanr.R b/vignettes/spatialplanr.R deleted file mode 100644 index 10467e0c..00000000 --- a/vignettes/spatialplanr.R +++ /dev/null @@ -1,99 +0,0 @@ -## ----include = FALSE---------------------------------------------------------- -knitr::opts_chunk$set( -collapse = TRUE, -comment = "#>", -warning = FALSE, -cache = FALSE, -message = FALSE, -eval = TRUE, -fig.width = 9 -) - -## ----setup-------------------------------------------------------------------- -# library(spatialplanr) -devtools::load_all() - -## ----------------------------------------------------------------------------- -Region <- "Coral Sea" # "Australia" -Type <- "Oceans" # "EEZ" - -## ----eval=FALSE--------------------------------------------------------------- -# Region <- c(xmin = 150, xmax = 160, ymin = -40, ymax = -30) - -## ----------------------------------------------------------------------------- -cCRS <- "ESRI:54009" - -## ----------------------------------------------------------------------------- -PU_size <- 107460 # m - -## ----------------------------------------------------------------------------- -Bndry <- splnr_get_boundary(Limits = Region, Type = Type, cCRS = cCRS) - -## ----------------------------------------------------------------------------- -landmass <- rnaturalearth::ne_countries( - scale = "medium", - returnclass = "sf" -) %>% - sf::st_transform(cCRS) - -## ----------------------------------------------------------------------------- -PUs <- spatialgridr::get_grid(boundary = Bndry, - crs = cCRS, - output = "sf_hex", - resolution = PU_size) - - -## ----------------------------------------------------------------------------- -(ggPU <- splnr_plot(df = PUs) + - ggplot2::theme_bw()) # Plot Planning Units - -## ----------------------------------------------------------------------------- -(ggPU <- splnr_plot(df = PUs) + - splnr_gg_add( - Bndry = Bndry, overlay = landmass, - cropOverlay = PUs, ggtheme = "Default" - )) - -## ----------------------------------------------------------------------------- -splnr_theme <- list( - ggplot2::theme_bw(), - ggplot2::theme( - legend.position = "right", - legend.direction = "vertical", - text = ggplot2::element_text(size = 9, colour = "black"), - axis.text = ggplot2::element_text(size = 9, colour = "black"), - plot.title = ggplot2::element_text(size = 9), - axis.title = ggplot2::element_blank() - ) -) - -(ggPU <- splnr_plot(PUs) + - splnr_gg_add( - Bndry = Bndry, overlay = landmass, - cropOverlay = PUs, ggtheme = splnr_theme - )) - -## ----------------------------------------------------------------------------- -Dict <- tibble::tribble( - ~nameCommon, ~nameVariable, ~category, - "Green sea turtle", "Chelonia_mydas", "Reptiles", - "Loggerhead sea turtle", "Caretta_caretta", "Reptiles", - "Hawksbill sea turtle", "Eretmochelys_imbricata", "Reptiles", - "Olive ridley sea turtle", "Lepidochelys_olivacea", "Reptiles", - "Saltwater crocodile", "Crocodylus_porosus", "Reptiles", - "Humpback whale", "Megaptera_novaeangliae", "Mammals", - "Common Minke whale", "Balaenoptera_acutorostrata", "Mammals", - "Dugong", "Dugong_dugon", "Mammals", - "Grey nurse shark", "Carcharias_taurus", "Sharks and rays", - "Tiger shark", "Galeocerdo_cuvier", "Sharks and rays", - "Great hammerhead shark", "Sphyrna_mokarran", "Sharks and rays", - "Giant oceanic manta ray", "Mobula_birostris", "Sharks and rays", - "Reef manta ray", "Mobula_alfredi", "Sharks and rays", - "Whitetip reef shark", "Triaenodon_obesus", "Sharks and rays", - "Red-footed booby", "Sula_sula", "Birds" -) - -## ----------------------------------------------------------------------------- -datEx_species_bin <- dat_species_prob %>% - splnr_apply_cutoffs(Cutoffs = 0.5) - diff --git a/vignettes/spatialplanr.Rmd b/vignettes/spatialplanr.Rmd index dd190c8a..029fc710 100644 --- a/vignettes/spatialplanr.Rmd +++ b/vignettes/spatialplanr.Rmd @@ -185,9 +185,9 @@ the binary habitat suitability map for Green sea turtles: ```{r} (ggFeature1 <- splnr_plot( df = datEx_species_bin, - col_names = "Chelonia_mydas", - plot_title = "Chelonia mydas", - legend_labels = c("Absence", "Presence") + colNames = "Chelonia_mydas", + plotTitle = "Chelonia mydas", + legendLabels = c("Absence", "Presence") ) + splnr_gg_add( PUs = PUs, Bndry = Bndry, overlay = landmass, @@ -205,7 +205,7 @@ are fairly ubiquitous across the whole Coral Sea. (ggFeature <- splnr_plot( datEx_species_bin, "Megaptera_novaeangliae", - plot_title = "Megaptera novaeangliae" + plotTitle = "Megaptera novaeangliae" ) + splnr_gg_add( PUs = PUs, Bndry = Bndry, overlay = landmass, @@ -224,10 +224,10 @@ planning unit of the study region. ```{r} (ggFeatNo <- splnr_plot(df = datEx_species_bin, - col_names = colnames(datEx_species_bin %>% + colNames = colnames(datEx_species_bin %>% sf::st_drop_geometry()), - plot_title = "", - legend_title = "Number of features") + + plotTitle = "", + legendTitle = "Number of features") + splnr_gg_add( PUs = PUs, Bndry = Bndry, overlay = landmass, cropOverlay = PUs, ggtheme = splnr_theme @@ -260,8 +260,8 @@ units are assigned an equal cost of 1. ```{r} out_sf$Cost_None <- 1 -(ggCost <- splnr_plot(out_sf, col_names = "Cost_None", - legend_title = "Cost", legend_labels = "1") + +(ggCost <- splnr_plot(out_sf, colNames = "Cost_None", + legendTitle = "Cost", legendLabels = "1") + splnr_gg_add( PUs = PUs, Bndry = Bndry, overlay = landmass, cropOverlay = PUs, ggtheme = splnr_theme @@ -289,7 +289,7 @@ out_sf$Apparent.Fishing.Hours[as.numeric(rownames(PUs))] <- gfw_data$Apparent.Fishing.Hours # Put corresponding data in PUs -(ggCost <- splnr_plot(out_sf, col_names = "Apparent.Fishing.Hours") + +(ggCost <- splnr_plot(out_sf, colNames = "Apparent.Fishing.Hours") + splnr_gg_add( PUs = PUs, Bndry = Bndry, overlay = landmass, cropOverlay = PUs, ggtheme = splnr_theme @@ -316,7 +316,7 @@ enviro_regions <- oceandatr::get_enviro_regions(planning_grid = PUs, ```{r, eval=FALSE, echo=FALSE} -splnr_plot(df = bathymetry, col_names = "bathymetry", plot_title = "") + +splnr_plot(df = bathymetry, colNames = "bathymetry", plotTitle = "") + splnr_gg_add( PUs = PUs, Bndry = Bndry, overlay = landmass, cropOverlay = PUs, ggtheme = splnr_theme @@ -370,9 +370,9 @@ importance scores ```{r} (ggSoln <- splnr_plot(datEx_soln, - col_names = "solution_1", - legend_title = "Solution", - legend_labels = c("0","1")) + + colNames = "solution_1", + legendTitle = "Solution", + legendLabels = c("0","1")) + splnr_gg_add( PUs = PUs, Bndry = Bndry, overlay = landmass, cropOverlay = PUs, ggtheme = splnr_theme @@ -389,8 +389,8 @@ overlay of the cost to show how the solution avoids highly costly areas: ```{r} (ggCostOverlay <- splnr_plot_costOverlay( soln = datEx_soln, - Cost = NA, - Cost_name = "Cost_None" + cost = NA, + costName = "Cost_None" ) + splnr_gg_add( PUs = PUs, Bndry = Bndry, overlay = landmass, From 1ad9d00de83ebfb264b48d5ca84bf8369a4e45c5 Mon Sep 17 00:00:00 2001 From: Jason Everett Date: Fri, 26 Sep 2025 07:12:56 +1000 Subject: [PATCH 2/3] Add more changes --- R/splnr_plotting_climate.R | 9 --------- README.Rmd | 1 + README.md | 2 ++ 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/R/splnr_plotting_climate.R b/R/splnr_plotting_climate.R index 3a372152..5e53c40c 100644 --- a/R/splnr_plotting_climate.R +++ b/R/splnr_plotting_climate.R @@ -263,15 +263,6 @@ splnr_plot_climKernelDensity_Basic <- function(soln) { #' @return A `ggplot` object representing the fancy kernel density plot. #' @keywords internal #' @noRd -#' -#' @importFrom assertthat assert_that -#' @importFrom dplyr filter mutate rename select -#' @importFrom forcats fct_relevel -#' @importFrom ggplot2 aes after_stat element_blank element_line element_text expansion ggplot labs scale_fill_viridis_c scale_x_continuous scale_y_discrete theme theme_bw -#' @importFrom rlang .data sym -#' @importFrom tibble as_tibble -#' @importFrom tidyr pivot_longer -#' splnr_plot_climKernelDensity_Fancy <- function(solution_list, names, colorMap = "C", diff --git a/README.Rmd b/README.Rmd index 910adacd..0cef93cc 100644 --- a/README.Rmd +++ b/README.Rmd @@ -14,6 +14,7 @@ knitr::opts_chunk$set( ``` # spatialplanr spatialplanr website [![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental) [![Ubuntu](https://github.com/SpatialPlanning/spatialplanr/actions/workflows/Ubuntu.yaml/badge.svg)](https://github.com/SpatialPlanning/spatialplanr/actions/workflows/Ubuntu.yaml) diff --git a/README.md b/README.md index dab24873..b6133b1a 100644 --- a/README.md +++ b/README.md @@ -231,8 +231,10 @@ splnr_plot_climKernelDensity( type = "Basic", names = "solution_1" # Column indicating selected PUs (1=selected) ) + #> Picking joint bandwidth of 0.0885 #> Picking joint bandwidth of 0.077 + ``` From 5d9c538c01e310e65d3d44e8c2998a8b94916d36 Mon Sep 17 00:00:00 2001 From: Jason Everett Date: Sun, 5 Oct 2025 15:00:19 +1100 Subject: [PATCH 3/3] Update plotting --- R/splnr_gg_add.R | 151 +++++++++++++++++++++++++++---------- R/splnr_plotting_climate.R | 102 ++++++++++++++----------- 2 files changed, 168 insertions(+), 85 deletions(-) diff --git a/R/splnr_gg_add.R b/R/splnr_gg_add.R index 257409be..e28b4d0b 100644 --- a/R/splnr_gg_add.R +++ b/R/splnr_gg_add.R @@ -155,41 +155,47 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", contours = NULL, colorConts = "black", cropOverlay = NULL, lockIn = NULL, typeLockIn = "Full", nameLockIn = NULL, - alphaLockIn = 0.5, colorLockIn = "black", legendLockIn = "", + alphaLockIn = 1, colorLockIn = "black", legendLockIn = "", labelLockIn = "MPAs", + lockOut = NULL, typeLockOut = "Full", nameLockOut = NULL, + alphaLockOut = 1, colorLockOut = "black", legendLockOut = "", + labelLockOut = "", ggtheme = "Default" ) { - # Assertions to validate input parameters are of the correct 'sf' class if not NULL. - if(!is.null(PUs)){assertthat::assert_that(inherits(PUs, "sf"), msg = "'PUs' must be an 'sf' object or NULL.")} - if(!is.null(Bndry)){assertthat::assert_that(inherits(Bndry, "sf"), msg = "'Bndry' must be an 'sf' object or NULL.")} - if(!is.null(overlay)){assertthat::assert_that(inherits(overlay, "sf"), msg = "'overlay' must be an 'sf' object or NULL.")} - if(!is.null(overlay2)){assertthat::assert_that(inherits(overlay2, "sf"), msg = "'overlay2' must be an 'sf' object or NULL.")} - if(!is.null(overlay3)){assertthat::assert_that(inherits(overlay3, "sf"), msg = "'overlay3' must be an 'sf' object or NULL.")} - if(!is.null(contours)){assertthat::assert_that(inherits(contours, "sf"), msg = "'contours' must be an 'sf' object or NULL.")} - if(!is.null(lockIn)){ - assertthat::assert_that(inherits(lockIn, "sf"), msg = "'lockIn' must be an 'sf' object or NULL.") - assertthat::assert_that(is.character(nameLockIn) && nameLockIn %in% names(lockIn), - msg = "If 'lockIn' is provided, 'nameLockIn' must be a character string specifying an existing column in 'lockIn'.") - assertthat::assert_that(typeLockIn %in% c("Full", "Contours"), - msg = "'typeLockIn' must be either 'Full' or 'Contours'.") - assertthat::assert_that(is.numeric(alphaLockIn) && alphaLockIn >= 0 && alphaLockIn <= 1, - msg = "'alphaLockIn' must be a numeric value between 0 and 1.") - } - if(!is.null(cropOverlay)){assertthat::assert_that(inherits(cropOverlay, "sf"), msg = "'cropOverlay' must be an 'sf' object or NULL.")} - assertthat::assert_that(is.character(colorPUs), msg = "'colorPUs' must be a character string for a color.") - assertthat::assert_that(is.character(colorBndry), msg = "'colorBndry' must be a character string for a color.") - assertthat::assert_that(is.character(colorOverlay), msg = "'colorOverlay' must be a character string for a color.") - assertthat::assert_that(is.character(colorOverlay2), msg = "'colorOverlay2' must be a character string for a color.") - assertthat::assert_that(is.character(colorOverlay3), msg = "'colorOverlay3' must be a character string for a color.") - assertthat::assert_that(is.character(colorConts), msg = "'colorConts' must be a character string for a color.") - assertthat::assert_that(is.character(colorLockIn), msg = "'colorLockIn' must be a character string for a color.") - assertthat::assert_that(is.character(legendLockIn), msg = "'legendLockIn' must be a character string.") - assertthat::assert_that(is.character(labelLockIn), msg = "'labelLockIn' must be a character string.") - assertthat::assert_that( - inherits(ggtheme, "character") || inherits(ggtheme, "theme") || inherits(ggtheme, "logical"), - msg = "'ggtheme' must be 'Default', a ggplot2 theme, or NA/FALSE." - ) + # TODO Remove all uneeded arguments, especially the lockIn + + # TODO Update the asserts for new arguments + # # Assertions to validate input parameters are of the correct 'sf' class if not NULL. + # if(!is.null(PUs)){assertthat::assert_that(inherits(PUs, "sf"), msg = "'PUs' must be an 'sf' object or NULL.")} + # if(!is.null(Bndry)){assertthat::assert_that(inherits(Bndry, "sf"), msg = "'Bndry' must be an 'sf' object or NULL.")} + # if(!is.null(overlay)){assertthat::assert_that(inherits(overlay, "sf"), msg = "'overlay' must be an 'sf' object or NULL.")} + # if(!is.null(overlay2)){assertthat::assert_that(inherits(overlay2, "sf"), msg = "'overlay2' must be an 'sf' object or NULL.")} + # if(!is.null(overlay3)){assertthat::assert_that(inherits(overlay3, "sf"), msg = "'overlay3' must be an 'sf' object or NULL.")} + # if(!is.null(contours)){assertthat::assert_that(inherits(contours, "sf"), msg = "'contours' must be an 'sf' object or NULL.")} + # if(!is.null(lockIn)){ + # assertthat::assert_that(inherits(lockIn, "sf"), msg = "'lockIn' must be an 'sf' object or NULL.") + # assertthat::assert_that(is.character(nameLockIn) && all(nameLockIn %in% names(lockIn)), + # msg = "If 'lockIn' is provided, 'nameLockIn' must be a character string specifying an existing column in 'lockIn'.") + # assertthat::assert_that(typeLockIn %in% c("Full", "Contours"), + # msg = "'typeLockIn' must be either 'Full' or 'Contours'.") + # assertthat::assert_that(is.numeric(alphaLockIn) && alphaLockIn >= 0 && alphaLockIn <= 1, + # msg = "'alphaLockIn' must be a numeric value between 0 and 1.") + # } + # if(!is.null(cropOverlay)){assertthat::assert_that(inherits(cropOverlay, "sf"), msg = "'cropOverlay' must be an 'sf' object or NULL.")} + # assertthat::assert_that(is.character(colorPUs), msg = "'colorPUs' must be a character string for a color.") + # assertthat::assert_that(is.character(colorBndry), msg = "'colorBndry' must be a character string for a color.") + # assertthat::assert_that(is.character(colorOverlay), msg = "'colorOverlay' must be a character string for a color.") + # assertthat::assert_that(is.character(colorOverlay2), msg = "'colorOverlay2' must be a character string for a color.") + # assertthat::assert_that(is.character(colorOverlay3), msg = "'colorOverlay3' must be a character string for a color.") + # assertthat::assert_that(is.character(colorConts), msg = "'colorConts' must be a character string for a color.") + # assertthat::assert_that(is.character(colorLockIn), msg = "'colorLockIn' must be a character string for a color.") + # assertthat::assert_that(is.character(legendLockIn), msg = "'legendLockIn' must be a character string.") + # assertthat::assert_that(is.character(labelLockIn), msg = "'labelLockIn' must be a character string.") + # assertthat::assert_that( + # inherits(ggtheme, "character") || inherits(ggtheme, "theme") || inherits(ggtheme, "logical"), + # msg = "'ggtheme' must be 'Default', a ggplot2 theme, or NA/FALSE." + # ) # Initialize an empty list to store ggplot2 layers. ggList <- list() @@ -198,8 +204,10 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", if (inherits(PUs, "sf")) { ggList <- c( ggList, - ggplot2::geom_sf(data = PUs, colour = colorPUs, fill = NA, size = 0.1, show.legend = FALSE), - ggplot2::coord_sf(xlim = sf::st_bbox(PUs)$xlim, ylim = sf::st_bbox(PUs)$ylim) + list( + ggplot2::geom_sf(data = PUs, colour = colorPUs, fill = NA, size = 0.1, show.legend = FALSE), + ggplot2::coord_sf(xlim = sf::st_bbox(PUs)$xlim, ylim = sf::st_bbox(PUs)$ylim) + ) ) } @@ -207,8 +215,10 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", if (inherits(Bndry, "sf")) { ggList <- c( ggList, - ggplot2::geom_sf(data = Bndry, colour = colorBndry, size = 0.4, fill = NA, show.legend = FALSE), - ggplot2::coord_sf(xlim = sf::st_bbox(Bndry)$xlim, ylim = sf::st_bbox(Bndry)$ylim) + list( + ggplot2::geom_sf(data = Bndry, colour = colorBndry, size = 0.4, fill = NA, show.legend = FALSE), + ggplot2::coord_sf(xlim = sf::st_bbox(Bndry)$xlim, ylim = sf::st_bbox(Bndry)$ylim) + ) ) } @@ -265,11 +275,17 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", } } + + #TODO Consider adding locked in to the selected/not selected solution column so it plots as one. # Add locked-in areas layer if 'lockIn' is an sf object. if (inherits(lockIn, "sf")) { + # Mutate the 'lockIn' data to create a 'lockedIn' logical column based on 'nameLockIn', then filter. lockIn <- lockIn %>% - dplyr::mutate(lockedIn = as.logical(.data[[nameLockIn]])) %>% + dplyr::select(tidyselect::all_of(c(nameLockIn, "geometry"))) %>% + tidyr::pivot_longer(cols = tidyselect::all_of(c(nameLockIn)), names_to = "LI_Area", values_to = "LockedIn") %>% + dplyr::mutate(lockedIn = as.logical(LockedIn), + LI_Area = stringr::str_to_title(LI_Area)) %>% dplyr::filter(.data$lockedIn == TRUE) # Filter for TRUE values in the 'lockedIn' column. # Plot locked-in areas as 'Full' polygons. @@ -279,11 +295,12 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", list( ggnewscale::new_scale_fill(), # Start a new fill scale. ggnewscale::new_scale_colour(), # Start a new color scale. - ggplot2::geom_sf(data = lockIn, ggplot2::aes(fill = .data$lockedIn), alpha = alphaLockIn), - ggplot2::scale_fill_manual( + ggplot2::geom_sf(data = lockIn, ggplot2::aes(fill = .data$LI_Area), alpha = alphaLockIn), + ggplot2::scale_fill_brewer( + palette = "Greens", name = legendLockIn, # Set legend title. - values = c("TRUE" = colorLockIn), # Map TRUE to specified color. - labels = labelLockIn, # Set legend label. + # values = c("TRUE" = colorLockIn), # Map TRUE to specified color. + # labels = labelLockIn, # Set legend label. # Apply color and fill aesthetics to this scale. aesthetics = c("colour", "fill"), # Configure legend appearance. @@ -328,6 +345,48 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", } } + + ## Lock Out --------- + if (inherits(lockOut, "sf")) { + + # Mutate the 'lockOut' data to create a 'lockedOut' logical column based on 'nameLockOut', then filter. + lockOut <- lockOut %>% + dplyr::select(tidyselect::all_of(c(nameLockOut, "geometry"))) %>% + tidyr::pivot_longer(cols = tidyselect::all_of(c(nameLockOut)), names_to = "LI_Area", values_to = "LockedOut") %>% + dplyr::mutate(lockedOut = as.logical(LockedOut), + LI_Area = stringr::str_to_title(LI_Area)) %>% + dplyr::filter(.data$lockedOut == TRUE) # Filter for TRUE values in the 'lockedOut' column. + + # Plot locked-in areas as 'Full' polygons. + if (typeLockOut == "Full") { + ggList <- c( + ggList, + list( + ggnewscale::new_scale_fill(), # Start a new fill scale. + ggnewscale::new_scale_colour(), # Start a new color scale. + ggplot2::geom_sf(data = lockOut, ggplot2::aes(fill = .data$LI_Area), alpha = alphaLockOut), + ggplot2::scale_fill_brewer( + palette = "Reds", + name = legendLockOut, # Set legend title. + # Apply color and fill aesthetics to this scale. + aesthetics = c("colour", "fill"), + # Configure legend appearance. + guide = ggplot2::guide_legend( + override.aes = list(linetype = 0), # Remove linetype from legend. + nrow = 2, + order = 1, + direction = "horizontal", + title.position = "top", + title.hjust = 0.5 + ) + ) + ) + ) + } + } + + + # Apply coordinate limits based on 'cropOverlay' if provided. if (inherits(cropOverlay, "sf")) { ggList <- c( @@ -336,13 +395,14 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", ) } + # Apply the specified ggplot2 theme. if (inherits(ggtheme, "character") && ggtheme == "Default") { # Apply the default spatialplanr theme. ggList <- c( ggList, list( - ggplot2::theme_bw(), # Black and white theme. + ggplot2::theme_bw(), # Black and white theme. ggplot2::theme( legend.position = "bottom", # Legend at the bottom. legend.direction = "horizontal", # Horizontal legend. @@ -353,13 +413,22 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", ) ) ) + + + } else if (inherits(ggtheme, "theme")) { + # If a theme object is provided, append it. + ggList <- c(ggList, list(ggtheme)) + } else if (inherits(ggtheme, "list")) { # If a list of theme elements is provided, append them. ggList <- c(ggList, ggtheme) + } else if (inherits(ggtheme, "logical") && !ggtheme) { # If ggtheme is FALSE or NA, do nothing (no default theme applied). ggList <- ggList } + # browser() + return(ggList) } diff --git a/R/splnr_plotting_climate.R b/R/splnr_plotting_climate.R index 5e53c40c..eed0d9ea 100644 --- a/R/splnr_plotting_climate.R +++ b/R/splnr_plotting_climate.R @@ -61,8 +61,11 @@ #' ) #' print(plot_climate_alt_cmap) #' } -splnr_plot_climData <- function(df, colInterest, colorMap = "C", - plotTitle = " ", legendTitle = "Climate metric") { +splnr_plot_climData <- function(df, + colInterest, + colorMap = "C", + plotTitle = " ", + legendTitle = "Climate metric") { # Assertions to validate input parameters. assertthat::assert_that( @@ -248,7 +251,9 @@ splnr_plot_climKernelDensity_Basic <- function(soln) { #' @param solution_list A `list` of `prioritizr` solution objects. Each solution #' (e.g., `s1`, `s2`) in the list must be an `sf` or `data.frame` object #' containing a `metric` column (numeric) and a `solution_1` column (numeric, 0 or 1). -#' @param names A character vector of names corresponding to each solution in +#' @param solution_names A character vector of prioritizr solution names corresponding to each solution in +#' `solution_list`. The length of this vector must match the length of `solution_list`. +#' @param climate_names A character vector of climate column names corresponding to each solution in #' `solution_list`. The length of this vector must match the length of `solution_list`. #' @param colorMap A character string indicating the `viridis` color map to use #' for filling the selected areas (e.g., "A", "B", "C", "D", "E"). See @@ -264,7 +269,8 @@ splnr_plot_climKernelDensity_Basic <- function(soln) { #' @keywords internal #' @noRd splnr_plot_climKernelDensity_Fancy <- function(solution_list, - names, + solution_names = "solution_1", + climate_names = "metric", colorMap = "C", legendTitle = expression(" \u00B0C y"^"-1" * ""), xAxisLab = expression("Climate warming ( \u00B0C y"^"-1" * ")")) { @@ -278,14 +284,15 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list, length(solution_list) > 0, msg = "'solution_list' must contain at least one solution." ) - assertthat::assert_that( - is.character(names), - msg = "'names' must be a character vector of solution names." - ) - assertthat::assert_that( - length(names) == length(solution_list), - msg = "The length of 'names' must match the length of 'solution_list'." - ) + #TODO ADD assert for new _names variables + # assertthat::assert_that( + # is.character(names), + # msg = "'names' must be a character vector of solution names." + # ) + # assertthat::assert_that( + # length(names) == length(solution_list), + # msg = "The length of 'names' must match the length of 'solution_list'." + # ) assertthat::assert_that( is.character(colorMap), msg = "'colorMap' must be a character string for a 'viridis' palette option." @@ -299,25 +306,26 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list, msg = "'xAxisLab' must be a character string or an expression." ) - # Check that each solution in the list has 'metric' and 'solution_1' columns - for (i in seq_along(solution_list)) { - assertthat::assert_that( - "metric" %in% names(solution_list[[i]]), - msg = paste0("Solution ", i, " in 'solution_list' is missing the 'metric' column.") - ) - assertthat::assert_that( - "solution_1" %in% names(solution_list[[i]]), - msg = paste0("Solution ", i, " in 'solution_list' is missing the 'solution_1' column.") - ) - assertthat::assert_that( - is.numeric(solution_list[[i]]$metric), - msg = paste0("The 'metric' column in solution ", i, " must be numeric.") - ) - assertthat::assert_that( - is.numeric(solution_list[[i]]$solution_1) || is.logical(solution_list[[i]]$solution_1), - msg = paste0("The 'solution_1' column in solution ", i, " must be numeric (0/1) or logical.") - ) - } + #TODO Re enable for new _names variable + # # Check that each solution in the list has 'metric' and 'solution_1' columns + # for (i in seq_along(solution_list)) { + # assertthat::assert_that( + # "metric" %in% names(solution_list[[i]]), + # msg = paste0("Solution ", i, " in 'solution_list' is missing the 'metric' column.") + # ) + # assertthat::assert_that( + # "solution_1" %in% names(solution_list[[i]]), + # msg = paste0("Solution ", i, " in 'solution_list' is missing the 'solution_1' column.") + # ) + # assertthat::assert_that( + # is.numeric(solution_list[[i]]$metric), + # msg = paste0("The 'metric' column in solution ", i, " must be numeric.") + # ) + # assertthat::assert_that( + # is.numeric(solution_list[[i]]$solution_1) || is.logical(solution_list[[i]]$solution_1), + # msg = paste0("The 'solution_1' column in solution ", i, " must be numeric (0/1) or logical.") + # ) + # } #TODO Write check for ggridges @@ -327,13 +335,13 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list, group_name <- "approach" # Define a column name for grouping different solutions. # Loop through each solution in the list to prepare data for plotting. - for (i in 1:length(names)) { + for (i in 1:length(solution_names)) { list_sol[[i]] <- solution_list[[i]] %>% tibble::as_tibble() %>% # Convert to tibble to ensure consistent data frame behavior. - dplyr::select("solution_1", "metric") %>% # Select only solution status and metric. - dplyr::rename(!!rlang::sym(names[i]) := "metric") %>% # Rename 'metric' column to the solution's name. + dplyr::select(tidyselect::all_of(c(solution_names[i], climate_names[i]))) %>% # Select only solution status and metric. + # dplyr::rename(!!rlang::sym(names[i]) := "metric") %>% # Rename 'metric' column to the solution's name. # Pivot data longer to enable plotting multiple solutions on one plot. - tidyr::pivot_longer(!!rlang::sym(names[i]), names_to = group_name, values_to = "metric") + tidyr::pivot_longer(cols = tidyselect::all_of(climate_names), names_to = group_name, values_to = "metric") } # Combine all processed data frames into a single data frame. @@ -341,6 +349,7 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list, # Relevel the 'approach' factor to control the order of ridges in the plot. dplyr::mutate(approach = forcats::fct_relevel(.data$approach, rev)) + # Initialize ggplot object. ggRidge <- ggplot2::ggplot() + # Add density ridges with gradient fill for selected planning units. @@ -503,7 +512,8 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list, #' print(plot_normal_kde_multi) #' } splnr_plot_climKernelDensity <- function(soln, - names = NA, + solution_names = "solution_1", + climate_names = "metric", type = "Normal", colorMap = "C", legendTitle = expression(" \u00B0C y"^"-1" * ""), @@ -519,8 +529,12 @@ splnr_plot_climKernelDensity <- function(soln, msg = "'type' must be either 'Normal' or 'Basic'." ) assertthat::assert_that( - is.character(names) || is.na(names), - msg = "'names' must be a character vector or NA." + is.character(solution_names), + msg = "'solution_names' must be a character vector." + ) + assertthat::assert_that( + is.character(climate_names), + msg = "'climate_names' must be a character vector." ) assertthat::assert_that( is.character(colorMap), @@ -542,15 +556,15 @@ splnr_plot_climKernelDensity <- function(soln, stop("For 'type = \"Normal\"', 'soln' must be a list of prioritizr solutions.") } else if (inherits(soln, "list")) { # Ensure 'names' matches the number of solutions if 'type' is "Normal" and 'names' is provided. - if (!is.na(names[1]) && length(names) != length(soln)) { - stop("When 'type = \"Normal\"' and 'names' are provided, the length of 'names' must match the number of solutions in 'soln'.") - } else if (is.na(names[1])) { - # If names are not provided, create default names. - names <- paste0("Solution ", seq_along(soln)) + if (!is.na(solution_names[1]) && length(solution_names) != length(soln)) { + stop("When 'type = \"Normal\"' the length of 'solution_names' must match the number of solutions in 'soln'.") } # Call the fancy kernel density plotting function. ggclimDens <- splnr_plot_climKernelDensity_Fancy( - solution_list = soln, names = names, colorMap = colorMap, + solution_list = soln, + solution_names = solution_names, + climate_names = climate_names, + colorMap = colorMap, legendTitle = legendTitle, xAxisLab = xAxisLab ) }

S*cb|n+E5$54o zz1yP*uSprb6{*Fzw%Qcbfkjq{NS2e_c^E+q2`S*sl2;m!svBH}!#&M?Niu zLyD33>#u_+dksIcrRzHsNR5VFq{B`754(o<81dkqE>|gRbOerQR){y5rP3~2D6}?r z8}m<+1OWOi4MbUlB=?Q@o6X0Qcbfq(rQmu$a-!=ylvZ#E-43UyL}>mlKqT2ti>KY* zoG5x6ePqtp<=EG{!x^9rqxNN zjYC|8eMlcv-9V;kYRQX3Aep)z&5~D|(q+lXzb+|Y1PfaYBvQ`Kj#h$M4a27HPu~9x zGcLTSZYJV%$RZ@1uvXUryG+;PZ07mkBg0k8)rbs?xS9UrGK7%E6k#V^;0PYtE9U2j zRiplbvH2pcj9D4YDM?BkyeIwAiF0qID4;w>M{*O@P~vZ`X5r6-A1~gT)_a?(-%HnF zlTn4f4JAJh?utVXoeam6w&pZ6rD}2fb%h9Cz3+C*^Exv7$W3I`2o3ST=ig70RNV`~ zRGXS`Ecf%?b}eeeU)QPTq=Ov)1uKI6C~H4&TxAd62L!{{vu^#^*68O^u{X%hZGYfP zCWWEu*XC1k1m?~wVUkxgZ?nrxb@B8*glF1YaX8?xq;gH=-e+{&%KD;xf1T!b`)M-F zfnDUGeCMyEe-ymg{fPWuJz3tRgfVyto#CkP*hw!2Fd+J3BR@f@EA0vc;?|;t67bj- zW0_4iW3yzU=mcE`tU|y&x-b@ZB-J&;(a9fBr zWQ;wPU42wvHkluD>=dc#vOxmsJX>fIR*>}~MEB(VJBI>kk?ZE;nJOt#{^$;Wkf==6 z?Z{60rCY{+l@>nLjP`I}yWx{Z{Etq;5@sWj^8t@W>VfG)?7PT46*rmpQ9|o!pHdin z4$rfhEBZ7)f6SYH<<)Ubc3L(RI@?yzZ+|nxLnKr8yw-QjfwDgY)A|a=>E(JlA%Bw= zK9^_}K*vyjq%41`qwUhefaE9350o4)+9WnC)>$fD37T?J!%|30VcGuEa@H*3^sgiM zWjl)jH+u;j1dhwCKLUr@N>JF;?F~yfvOmX8Bzg=ZuxT^+$(V`jE|Rs;I^IMR>Fpcc8o zq-q$M-`sZhc$(tyBkl?*4VC?6lu7)|5|nKv@SoiuJbmr#V)qBX0tstAn1`o0Ql1F` z*hyNK>I)S67514-1P#cL5NH|f8M-ow0YJ@|U|`}!Yi?ha$4}AYNx+9vjDH|~Y+8eD z{mnex4`d>1H|zgQoW*fTx^Gy#qNgft$@Rc1S#a&7vU@~UPG5+-u?5)nZicp#O*48TsO^^sR z5GgSk(I8ij5c>Z49R`lO6iQ(?|M_cD5Je_%od5s%AG{1ST(}#X@|$gb0DdXTs>xJ5 HHx2neN$L!) literal 0 HcmV?d00001 diff --git a/man/figures/README-unnamed-chunk-6-2.png b/man/figures/README-unnamed-chunk-6-2.png new file mode 100644 index 0000000000000000000000000000000000000000..ee5a463ba69b4f80cc3f8fc0b850a2972669c505 GIT binary patch literal 37410 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 R42}#y;OXk;vd$@?2>|5FKbQaj literal 0 HcmV?d00001 diff --git a/man/figures/README-unnamed-chunk-7-1.png b/man/figures/README-unnamed-chunk-7-1.png new file mode 100644 index 0000000000000000000000000000000000000000..972ac6bf9c02e96502e29f7d674c025bfda2576a GIT binary patch literal 37104 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 literal 0 HcmV?d00001 diff --git a/man/figures/README-unnamed-chunk-9-1.png b/man/figures/README-unnamed-chunk-9-1.png new file mode 100644 index 0000000000000000000000000000000000000000..b008fb9817efdd1a5c5d364847bdf2cfa56a670b GIT binary patch literal 38994 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 delta 36299 zcmV*TKwQ6?l?1nv1dx3S=m`Y@2p>ouOvbT?7<_+6OLk@Hec5vXU!UF|U zg#u7O`SwO_D3aZ3a!6`MGb1x(OB$IqW{pOp8A@6rspiO$5;>yOB%94{vQf6nc2%Ja zfGXGo5)neft1Ob~tzL9M`X}pcL%ew~t$Iy^Tg= z1acfac!0n3mwt=?{6GIMv!jI3d7i?uY)+kegY)OlbKt-Mu3Wjo_3JBaZ*Lnr92OTB zx#Nx#9653{V~HI;e3-xTSN{tC<3IibF0_ApIQ<^6?Q!V#yIJc7Tz~x>jk3cXM-OF% z+x#%%jf>X_0+G4VC{(G+sp~Dm<^h!7&(z(jm@Z3o8yu zyc$t;7UB?V*rt8`B5#~IPqlm}mshvAy0Oh>tIM#ngB|NW|wKci}pGLLJtp}Glv^0lp;_TQqzwlEZ6<+&#Ro1gjsmrlRIcE`s~B9c;_sJ6gr955V2#JOY6X0yp(`Hf%a z!4pRSIhk19ZnLu0res?z&ox+_n<C+iMwNxr`#~pts_^sdiE$+JO&g^%0-+ebvKKUU&^{G!6&X7}i*?zyz zfA`=0_nF#dD!Y>nTFYW)W`>{pxu50NfBo08`o*{2ejCfT-OctZFVL&ZpxrWGeeo^6 z_VQ_xM04-4{rso@#-F2NCUC3U=kNTpFR;4R7MU5Ph^zCaVxA3^CNF+>MuM=vnD+CTMzByp@$#lv(KJ11Ir?=FJhUJrP?a;X_Io(h>DxSU#7+7 zCW&1}`CXPW7q|cbfB=6sFUwnoyzH))>c8^$VY)diUtn*8c z-_Ngp@%*_}I@ivTRAw^dS(6xGFV_qKM%x}yeG$9AgNla4jeTeo zjj}@!C;Yd6^fmU`KAUG=qSNkBs@7>Q-bp6}TSv?#9X|H4kMVz(fBwVN%nRs_TaWU- zd+y**zWE%<+(D9*-)(zD)#gYe3z)4}dEbd6D5bc*y2j@}_c>m;-skL=&%V0Hoy#?z zeDE$l_<{H1nioO2M@@ucX&hPxr-(_`mt?)GSeV>R11yz+a7`D0|vozI?@u1-X;_J*3I`fB1ig|AOPkkMr1L9~9?%9=9Dn z$TQ!54yqE!I7uXREzv|{+cm8rjAFt#Ccy$N8c!qSS(7M>*m8-mM@7QY-z(cx!Ltil zxEcjciR;^45`QE6%(mnx$nqo=u{-ej%(q|WmgPBq{iE;Cd~^TpNBF|?ual(6x*4D; zGpsmSEK`3)&>I_G+Ek8kCbrMRAmkrB{Z+p3)n|yz8L~orw7%2ffBn>#sHuow{;3aV zzq#$;68E1t$}_81pm43}eCW|&ROToy$Djt$gFVui%wDdj5az$4bhu(JroR@;krx$E=)rlgj)) z;y7ldJz%>x5l*U|Qz*-j&7_*%C8tm6C_&I!puOl@du#ODP6X!e&2YYjcaO zt!;mHc6JIC)zdZ@4ETdT_ybl}R| zGn6`AUQc7+q^cdSyz)xnv%|}CW;r=JA5PCTrw2K6)kI+44yU!?^fWkXdgaIbb>c+x z!dn*!a!bDh3o{w$^!>Np_qN}8?JQsZ-YI`XhI+C>Wf(?$`kODZzBAg}x{l35Cytm0 z^xJhz5eNwvo2{@AAI$B$|`2IQOC9{Y|Apfg{~jdFU{jk*@I6`;M~~L8aB3D1;FUo{zZQA ziT6?VT;ebQL(MDl=rvIgu%l`?si#IevY<4}r7>x8X#k02aP;A**) zE$K3glbDi~h@8%Ni$i0(D%zp-L=t%v$9(UX!nM_PUcY~Et?=99 z2NtP1D$8pfEh+Z`8%^Q2c;wquat4G#N*oc#34<8a!Yx>~O~2b=bLA?*<<|+WzDX30 z-n7lK!;&@N&St`G^@PJSB}%SM#d9Y7bLQ$g&z(Att$-+`H}tdpJxXCIi%TmT42B~O z^pfjRDSMfH9tmaFHe;zchI)SkpU*w}DuW>4LPvAH9m&{Bq70$eXkxdDSE(`HCYR8O zSpp^r&alO)*G{sw{TTb^X90PV{%b$|ICmY{$Jd|vHm{wzz-AV(UM{@dT$NC-RR}s;LUlBvW!9jD zJ*X5Xv68_r`y9i;?rjNw)gD!^*UFYk@If&{Dy(l zj_zOJ&|HmKJH#$k2%Uc_eLtX5@^EtXV{H#fg!5<5@{tEe*u{KZ1RwgFf^a8g zBj7d$tYtpdNv4ts;B+^LQ_;UDz#6tlk{CB0uvA^(@R1`N+c$s5p@xGBecG*Udc8i) zX0s6EB#GHsxlDD?$C}$unD~^ni@(#KSRuZ4?h2jOHjdvxD~qVJEh(U`j0@ZE(%*;~ z`aZRaydiB%ain2$J?Wt>O%R0W)*98?EakBk?bVf4E}cII+F`vP3k}wn!gqFelce0B zSuIi8x`^MO%&>o(!i64+1gB2WPMHhsgx~whclp%4y98tuV=*Z@Fr91+?Tywc`m?OD^(NhYL?u2Jof|E93LXl3(M*NoZQG($@|d5W=jhR+eDaf@;Ep@)q}gl~_Q8MoNndz=*&f5n5^>za@>`j7 zN@TgBte95~Nn*oC_6+}5XXq_PD=Hn_Nf?ZTz0+%XHR8s8h-ENZgEpXr(_CLhSr!i* zn&oF7e~|m{KEZsmhI14507{bQ+fw8@RS4;q%lNvu=+a)5sId<$(S??xY6_G^Se+%Q z&XIpZ`a^%8!O$nEEs{8H_K>m$EkINnlj2%wckTw5RsI;I~*TyA379#(&gxN%^V zSZ_I|Xjx&N$)I;jXlDt#vqDmyA@Qnsj?I6se)tjo+{fN;_ET@;9xSnoc1J`P%FPjB zV*INCR7FxFO z;isUc+5L>|A{g`2ZaRvI&aW0k@nxFUF(|alO*ApSI_WAU->o{ zFJ7YO)Usnsh2nwR5A&b=wO^rJatmFj@L9TgnwpoaH9?%vO*AY zKG-bbjV--X7G1WY+}(jweVXPVq-S(WPxsc8bKoS)>m)6ZWtyd9>?EMq?eP2?7x>$OZ~E{cm3xh%h;q4%)|#cI z#R=Z)#>Pf29Z-LmUE`F@Z++|A{Jp>T_h~kpwA-yrG(JV5$15mCQH0mN&MgbaINudf z19SpTb;5q7lZF+6 zyL1H?1=)YROV7KN;j@b`rmq4gL99RuL8&Cf>8{H@*mkgnT~yd7Db=JhjiW962%qMC9%Jb%G$kvJ}1_Ff)H+QLopDq6pvj3*2mwbLW1)hw`?t zdy(uBbxdivP1Qa$G4!3`4tBqXuFN24bsLq0lGNQ@7fitukuobBO9wN;>XzS?9Bj8t zMMa!AFjx56GcTNEy&vQ0ZFF1}^fn5m1WFQ1;(l%ts3ewze%r;0L?u%8!Op~6Muh`; zco2VQh0nBGF^Y**Cf*Q9gx%jnMH=OJD8DC?t8UeBn?-W9;(6S4bbsNeS64Ua4~9n3 zLz4KlWltvb8ynQ1kKGH!c4eW49qNwe)+3`hXs!ABcTdt@xrAd0d&}vpi-@0FMFj(# z!S>|oLCVKAW7-Lz_8nN$V58JfN3U9c1oy)c&E-1`v$*b;d zL3LJ^{lhjo^hcE(P1{%ZSX4b)iKK8^M)}ezRaq`;wl_8iZ4UyeVtK;}oOo3MK#~L% z_Obh0q7dO#vqD&@RE*tO1r(86B7Y4~>8V-jnFE7#Qbg?WcdRD27p3G8GbURD_mKw%2^I2%VUtE@pqGpeBJr+R8 zDS_6Mt%!wEQV6i^xY#rM&^s55FTkoa(WQAJEl*r)*v1}QBf=__?gWvaaaz})R3Wa- zqb(P!;!&@UxZiP-ur|=dwRsdGl_;(^InxWPBIX=!C?pV$bcTRv&#oiek3bRs?@(FE_;Y z$VmS5cZifj;vFfjCZYhRy#k3E6?aQwuo81#pPLWm261fxH|XLHT9RjNj{E>xexGW; zQ~aG$QlQRW!|ATcJ*85*<3MIKq#17G)@KOZ8etUUhJEHdiy%x0%Cl&@MC=X=G|ycp za8?V)$cmyYtYJ6f$%@>pMO=TG#WrOsW3NHEq5Fcv)R zlms-YF65HajpNuNgXZ>21NyraPfh>`k)dVEg=nbHh zqSRcF#C5k+ERbfqB(;T)wKKUf|+%k84yUp_# z*1_?F3!SSXG5%mHxlVt^j!GxD3Wrj;PZw28ZQG(UzmLS*7Ur5kZ{ym6sK-?2N4nbS zed|OXfYn*Ezcc~^rP@Sdh0;d-q_%)EI@8)2i4!DV1sXG1nb-U{k~4KBM3c&_@nbPo z?VTOgu3koQ8LuoaAkTI2oC>yAr(CYn52v3Xz%(Y-7#CV88*G1Do|H)SDjToTk>%YaWOe45g^TN^_W{bV3ep~+Twpqoqh8&L~$aO95u3pRxk)c zHd@`$0JbbXc<*hLJ%>0+G6tE(_(@L_GE`>8GAbli82rzhLPSA>e~~APLhNN?>x@O-gi5%Tv+46$_Cq= zK7kR7t5<(!Id*72KlhQxdGzk%h2K5vY$y?x_TM8vm(N_{$p=nkc75=k+xXx9(ueufGcU2;>Y@XO z#Bs1Z7uT^kurQOQ15O`!g184^%(aaj9=Y>q_VI@vIKi1G9^~YO6|`3+3?*eQP0t)} z)v|xb{kI+FO_ea*i3knS+^AN#^TAtX zX1hle%c{ilJZg<92Nq@~IL;<0nSXB7^u&L6bg`eY<~bHk&%%#J0Aa~d)STj67)ff6 zj<_saF@Nv~gW4>1C)krmF=YuoGS60uC*OAmKlkLr{PYtEy@5}=H=u9cLXAp^`DT5B zIRCxZ-r}3jeGk>!$!Z?$rgQtm6OZ%20}s${w-^qGXbqK$Xlhlf)xzY8qKMCa_H%!H z{_~$N+;l4Vy}rKAr$7B!?!W&54jd2wrCP1>i@*4bJoeaQY;0`e`#$AzsUUDSaptVS z(GiYq5$N=dr0H*O@Z9s?<<8@Wvuht(n&bccn?EaD*f_%TJT9C+&wu?7e-BGT5=b2& zYwWBL4B{IOAPPv_Qg-(D&6nTg;}3tH;GWxLqPdREFMa4iK6L*HR=3&=`dzfLDV01L zl``|q8kN!{OD7$8X#q0r_xbK?Z}C$fxF=gJ&DE>?TfgzI&>0M|EQ?pqUg2;4?q><3 z7!?g5aSH={wqE7m|Batzr_-a?>k(>&W7{-q73Lb%38vV^l}-NpfAJ@*Y_)%}lMpND z%Rbt6(I)Zb>iRaP&R^lN`|rqp_v8a7c<7EJ41)-z6aLOW`UAdwdIjaUeC?$-`RGG; zar-Sor7gJ*zxI*$^O1+{Vr{!ke<WQde6x;M04udYc7q(KlvgmBY-v3w<#=*t zoB1R$Kwu6;1m>e{8e6AnRvLe7CBmhcbwcRvaHHmVC88)~UJclBT|$5N?dSCBgmDN_ z$ebH#2YoOHTZu$%4&yDOL-7$ z*d|dHpMB{9cielH58iuQW`pNAc=eGh=jP_9IN-H+2z}YRsbC<*ukzP1j3j5cg9-%L zv0|U?t1JBdKl}p!&cF66+Mf;MoDn_Z8#NV2LOF~rEG_7=wp^&r@bZf<@YNIh z`I(P=D0^_ZuEV@5{T_c>nxpC{I;~A~6p~a9Pmm8vt|L-Ed&vDnal*@|PV*0+{t9od zv~Yu7Rs>wdLB^rh$|BfY;}8G%Pq_7#{VdNlvv}4kW$I?Q?O&Y7e(5Auxz5UZ#NYpC zpW@&CjbGyMfn_s}6ic%WmS*=JM}OTYaOLVI z2^Ol{lm~r0sqQl699T<1D=h5U!>qIhEOh!bs^!A6D1T8ujJUkA&YwK<9lrR|8MXt5 zTW_7-RRlg2Z?DyAy#D&@{LR1lpY!uS z|MR@>eGf1*Gc%P3o&GKe0=nHUo12@w`szustK4Lu9qjHJC|h)z-7=fQgunIAzQ`{> zxxvRDJi*djGfRQgTFdcN7~vA(xgG;|2`r1mtuds;Fcp6nS1?E{bh$xH9n0_Hw69Aw zzuE#PueSJq{r{fkm!Eow$L_g}#hLmH6+Zd}KU1|;PfBc*Eu;KLzSe_NC)s*#@u1fsPd z@m95&N%ngE>%9DChyV0{{xrY*;Yawu-N#wjg(sf*CyMCyeKy)%zIXaEzFj4*+t_{w zXXhG;S0!rhqZ>%oMvcbzLz4CeSdNkUwWJbcAUc29GEQa*D|7VxkT48Ml7xO=w5ZdS zq2JzQxYJ^LXN8>y@62!*(Q+GMGU*uVZLKkLphmQOkZz|#&{`E5+q9HY#&+&UANeTv zeBenE+a>YplwF&B^D`XTH_yR^S?0=$Qmuhf76U(EeW%0u>l>WEbcOc%b>hY{u5GjI zUuS>k^6BF7n^OGtZ~u)<)DGZlU;7%bzIu}V`}dnnA-SoYogG@O7O%c~lJ)g_*JjC2PuY94Up_ZWBZaJyqgT zRKt%9RT7w~*SMwW;yD(+U14Rj#a6qU1;$A;dz=yqO_B&7eBWH1+vdw0JbaY-W}R}$ zMWG0ym|myN*7gq9dl73}ZMHi-dc%N3BjsV;iU`J=hcil{lLV)?&fLLc+_Ha(*?NB! zODTq7$lBUEm(HKVuP%_p2@jq)!hiN}{93k6+H7_C-7kEbx>>q=u7F3~?M<$?ea^3L zb9rr(?!Y&waE#sCB5KH+GLtDrN#%z)6d4~az-6W6acFs-gH;)45jLIvkaO48+3xgE zT4Q(Di5p8KT4CFY{qr*%Kd{6t3k`qfYaXSVyd8ruqB9t>+3K-={R*qC0b9d_zVFMi zrrBPI*7*X;aXGX&%WOloZvLRpwTl<%IL#bdEqi!-C~3AyWtOUEarfb64%$6dE?=bI zA8_^R)d`Z2)|!Qd1(uhWab1Tnj96P+V{2<`LL1$2Z1x{ILNc?T)vY$|Nb!H&Pya5h zYv&7n?jkEY0vU!u$c5|coV&J;LgVx{qsIWrG8$8mpXF778eUbMI)Eua9ouj+8&RbEGA+jmZrL|^m zZVt7496w2ImA&mww@+)mC1;wIS)s=ksCGpbvAlsa*Ee=py|6+2)+)-Nv00@29)v@Z z+I)@{2o%7g>#t2@0MLawml0B4Ugdq0f$=BsDe*y&)|R(5{{tGz~4nE}U> zxG5Pf}EpXjIF1ON*rEs=hx2RDp~Ea@13+)d<6IqDn%$ z-C}NT9>;MEn@S3H=j$sq8uhGbSt|aXBnd$f5CpPZU0zA1WG2(?~Q4L#kw$?IM*|b1a7WUJ{$nvKD)}WLqEuaC*%E`BmKPDJ~ zDJE&$wk)u$f=GL&I$~KymM5pwIUyd9l4(a1JNvysoCWZ@p-2n1ZH*?cxp&JlWnX7qm)Q8}B8I;K)sN-!78wn=QOAex^_6{Yl5Wx7(9g_T$%^%R}sIUE0J zWsw+Oaq&ep`lDrjpZY?n;-dyLE-Xv2pxY!@uTeXEoVBfW+O5{qty=!=Iz35;U4Eko z!;qcz6>N7)0Kl;}9mEQHSe7F?N@>w#t)*gkIKc9|SwVj*4WmL>!2lKXp;DvY>(k!e zCXN$4&%@h8;-yxr2@@!Z%|0?V)dXFt)hhGzbL{N2D3?o=%VoB=cNh+bSeC+ZT(-8h zvT`cp4%1o}%18!5z?Cakvd(Q!rawmrD^}W{FvnEb z$MSolBIf4pX89dq`MH$>*}@73SmD5EdAVc05Gj9J<#(af82KWJjGu;RujmUE4aFCB zVD!Jn$Mn$nqFMCCP{y%@sCnJ>Y+q=ZVp4Hq8QbrWgaeXt#pv29qNaa@kh>G$DEpA^|!DGKDd=k(>ZSJlWK*T?O+YN0?IY^ z$vuXB;|n>GN$)WgMbK`=*eH|%D4O)M!rLnHDK+Y7vjt1b+5RXdaDLoQYm>6FZiU3F zpmiDTRk8Zp*n<{veQESmb4q5QZGdGH*A_;Fu$&Sq=+o`*&{#Ua&dQZt3y9_aE(}9c zO%VG10j<_b_W$WpFQw3>%jB-9MZABP4QUr0u(dzi|B=;tc4zNTByq{%b@P8 zl2m2|g-vBg-3ofpLRle><7T#vd5>~^hQ8a7!f(!^RQBtbqGk2v?Cqr83f7>F-B}eb zar$<0%P6lZMEE2Uu5S8va!OKQuDfm~+NeO9cFTsJzCv7`lZUWU;EL*o-QR!0+9i%o zcSC5JhSQwJQ4c%v;L0URXk{C*fGYz2)E7r@C%269LQ}v^%V$P`QoCh2s_CwY63Mvj z!;bOALdM6&Eu&nqUB!XeKJJU&hH!;bPBWk#k;Bd6SS`lU8f;^CQ(shaz6iv2Bh*kB z(_vrkx7@&<-ABz|V`ue>*(rbg=qB!s+U~NlT4#iLloHLO+?TXd7KH@M5#FuYV+r@R zMnCA`))%SNc5W&ccv@M~^zYN0-}KMjZkPG_xh$h-ulmCI--5`xR2L7@vnsUv35k~i zF$Q7uYUrRRdRQvA|FUe7Qk`KOp`N=pogaT;*GE&=}lDWPm51tgGPztNuz>a;&wI+4l zp}%&?4ZZv}iV) zgkeal)w)5Ea3jy7HMRLA+RY>Mw$@Uu^4vYicMJb5^r^8)j8K35WOKa|QK?BB=WNLY z+9vzUGic{Z3foew_s40c_PCtKBS`#LkVR=sK4ZTf8j=h>v3g7qH+}vb&d5IvX?79!B)oMghENX*F z5ex>)mvm8-jPtZAKfvH7{QI@cLkwvu!J9Mo%7MBj=_unAVn&EJm)d@}ku91&# z{w9^bN3yM;Cn&es3Z(nvJc4X%Exs@)yvWhE za(-`S`(rB{jD!aK&S;6PH7e+e07V?ivfe3;#nGRLqsY;k&oW=gHpR}Ul6hHIF$X0Q7V+g{t8woXS%Vet0P=n8*O_AaxaY# zJHJc4TA|XpPHSs}<>h7e@8559n|-caxysJY4j_^^jYb2{^D_3;UQWx-T`Lu8wHmJL z&}y|afGM5W?RL9RzqIApMY<35Ll4|!sAMJR88i&51s7_fXTsVY^VO?RwZtaqOrYV2bXXrT% z;#v*c?_dwMi5mN}w~Q`1B3089b%{I*OH~N|PTQc>DS`|{^+hbdhuzyGZY*aAvb^2O zSp99RVMqLK-nenODd=ryRg@~~%UORC#{qU{ow&Y`Rm;NxVLDqKai%m&(Z!BlNh$}NFuPXg{ zHRAfn7jb=2^sc+>#PwxKrcZt0NF1$U$HdVf(&c6rN2$D-AJg-cbihooNoRA7*7g=D zndIHlCYR8bI9J>52)#=Ozf%&CF*Atr=xyRwAPz*3I{i(GWV>Y&I}(3J*A(hl+O!@W zC*A0HD1D7f9zJ!?oh@> z-WSS}x3(Ql@r5gWWy|kz+bd{y+!tvabq-BWtKfyAzx8yqxX|TZ{oN3eew+4AhD{69T=LVZj zioE18+cOkiS*WoxrCMuB^(KA0IvR6YgN}_3)p&pU2EHAkqeVyL6~~MHsj2tZppoAiYmw>{r^UYd2PFLr;6WAR!jMM?Vv{U6>5$&b6) z!2cuv7xRnDEFHK-BrFwRloM1GNTI1X61`!|&Xy{I6t+fH*$IccK$&wr1Gx z?fRq>fw~6WZnwbRO5dXCKaEC%TCK|V_D+GMF>!OYjpw-x2LnpwGPSuysG}MAegunnl3~=k#lt%hf1}IH-CT~t1faV;Xo*vNi4t1 z`@-)C_cjrg2^_PeizDp84ptP1Zw(@>l@i=xup_^T!vf*L3c7+;7i_n(noU+XH2sao zaa-aT?H0#qY8+E~sY09nECJI7J6Lg;>(3zV;lO{`9zzo3`qRR>_PZlr*q*UH^@VS2 zS5oysN$C;0zioUQjQOI6<+n%L%UOS8aa3A9QwpL0FY4n)1H!<6N56rSB;m@H%cBfB z(XoKvf;^fLylhbZh$l-=Znm!-nauaMf(+SqLhe|?GKPWe`Eya?* zO6z~h*{RDKtu?h;jk&p5TCEnHjtG~flQoKBhC|^$HyZVcZn53gb;HncPXKDYVRRV7SrwIL-)XdML>sneBh6 z;-)zj#h3%z)l)wqfuB_y^3UQGtBTOzK_oAXzN zc1uz`tG`WBn->9fWzzUO5jl?rT{_i$_~kh|lo-SokyFMF2SSWbIk~AX+zR$!TclJg zGt!>{pHMdTutnV1hxRJwZR3!5HB%iS5(L?Hjo;-=*c!CaUR4PCneAn??P7lqc8KeX za!R0-yb--BO2?>hVB+ZI;#e~e8Ii!v`pe?DO;Q`h5oL+3C~UtYwwtqKZ8_P|jY133 zp4y%!ZVX!_r8-GvHmen+-7;8?*xpzcdZw{md=Uy4y0H)KxWzFz>R+aTxilGA`cyxiimWI`Z?Z+ERd)C zS#~jP3($!s^lEtJ3WF(iPSa-FHjZO6H#bMAno+m^RBkLGC6a8A6?4>XSX<(a&gQJ1j{xtp7e!w+)UScgh(6P zof0V*{O$WM7Gtf7G#3O%2&AQzH%d+WqJ4DgjU)BUcNEF2^EX)%G0ddtOj;HZur`vfm zO{wBN7xyAJLhf(c<3*cq)(v{vck`(3Siig4u@@IQ_i+x@oiuZr?QfSCzZWvDcj@ou zu5n>|z*6}3Sb*=Owx_Ht00x*!-&}cKD{+*2=Zs2JDm27lhMa$D0Hqkj(3m+uxxG!C zB-pl{)%+EJO8(pL4+@C#UTs?TQj#Q@2DEM4*fYmu*`B*EW$1UQ?YRy`{ZA)=T^t5U zEXA;P^F?|tYTTGo2!&CU2w9?Fd~8aci1$YJNx?9ZXw+YxPn?A4DaEs-pjm3WHDSAe zap~SV*I%5bMvi~QvEYlblN&wei^7;G{wD7)mHL7yzDUQ6vUAr{BXD$@FXG6Q<(!OT z*58ykDr0+;Kv0^&E0q`y-hFT3i9PV_{=+ODy9<>V1Ucvd3M(3nP`@}7Br}OJbTmaJ zt#BavL*~zDLH!gOHS7=tLz)ZA%vD^f)w1D5gX_A?%*=n_`~FQ4IV46BmU6jFwOS=I z8dWK?OD75SxdjGzgjxz!sVKndZ=1m$W@szQ5|+7uoRmztBl<6;t1jRPrSK)Ak-bTK$U87<@Lt6z+?_&>I zU|CqfAVYs|vy*_JFL4aV;+UekNoe9I$hZ{@um{uQXd47M^HYjs8#GZkK+4aD&vq;^du~nK9J~LtNKmYilc$s%`E+%%E|I zc3)8Q%ozqv#~f#<&^X1iiBr@x4vp>R$?ud#oZN6A{TcE?T7eL>QO%g*i!|9F4va6{ zjAVarg+A7>mG!4xQ-KhbB^#vCN=gmkOsA4Bky*i5jzN4qQ{1aPdV}v8M~v+zj>FU! zN~Ca8g-lbVEsLW;q_yRUJnXPN@`YDJmka~W?`AIm@kK*eYPn>CkuRDuX(Qj*o)}+L z1VBRxui5YBe36f1+f4K{jx*wmI205 zuyp8%AbXWrG9^BfSz`Mg;`)L?QB{UmqHIAq4WBp_1khg9ypx7|{7Zs_UnC8+!db7uAhe`k!w~Xy~1sOG{DTaT3 z2MQGjM2&rt7?8I;9D-94#5eB?Pvm6c+Pol}d0$u#D(sJZfkrD^658XCRPg~rNz}Gu zQ2mZnL@d{H{dp!aqAQ5BQ!>l*l$NPQKBuuHV3_GICHyB|RS@5Fd7s8{*v`~6M!t}` zx+?Mw`aR|g^G1!U3-Ub-ui5w_sm_0m(C-W=bg_b-@SV+SL2R#@vZk0*3_ItGnrKv& z8kwNP$QPnK5;shxzr5{c>k&1UNBtSwt#E*L%9C+)t60M}QFVbTK7OzLj-0?Zk3xf> znU+JI9x0fOWsXR!(cfWU1WT5v8Sdi)P#f~QIm z#hPJtkxG5$`?J6#^>@2n9LHv3W0PL5hwV62_8(;@k-EMU4~1P#ALHOoMJ3-JQkj>4 z-4iLj>2B5Df4!&eH|2!lXL)MquD0t;Y4XOG8uvy1T4TQWLEnNm?F)agBT6*XW+%Dx zKZKTN5sv;DRpb0Y+LUu(0Uwms;8lyrV-jVxleASt_Ea2VMS)1eX0=ic@)-HqpEJ}} zK|6$fbISyS9^v;PQKFQh-|y4!3*h9s4$Zkmwy6@vqYM^6P~ylJblfS8*&djCPDZtA zRnB&uKq>$1#sF5v7q)*hy}xl^fay<<`9fv=5tpaf7s_Xep*Q9~ivsy)!gd29Sr$-? zBT2YN9H-cx_eCm1N8a{yTm-T#E!daZ9%rkZ?7bcN85&&lMUpYIaLZF|CywMi_om~R zW~$Yuj%ghRbZbp&vrDu$R``C~2HW#N^|xQ>Iegsh|75!Rgz#2wy~nXBzPN;!FDt5YF@1Yvox}TE~>vn zQmRu`5&oe21MNLL&!e&L7PjqK{GsRyr>LYoYzvLgD`WY60W=Jy&+c!VN$6q?yBT_G zMMG0o#Z;aT`a*x(Q?2!-D(j^Pk{kj61Cj%hzPro#bI6j3jG1nte60#c_jP$hqfkuY5aL=7>i8ktO8WmHsuv=u4o?jb}(x?||>?vN0WE(ef?tCTd--6h>6 zFd!1rokI>GAl=QI|6A|F`vPmR;4~u7 z)D8!XpYv;TAE|*My?;0z0WI~_`zXfwqVbV+epKHX>}qVBT6iz!T+Gp}F?ceD8p$v8 zFI#Xd#Z}0#pt3DD|mN~`V^yKx*_w&iQ9{%E&ieMd8?bn@n4@m72$)KwK zlGygDYybB}pqbNJ7I0knWp6r8EYsw;<%#WEareHU&m^6sTg7owl%p47zZK;VI)`%Y zR*BhJGeJlZC;03dflK{+j=P@Y$X74(R6f`JW^h6rO`bM>ygH4l@lGVJHj;^+9ja#o zM=q~we)7=_H1|%{D=JT|0Zg&%x@*zDhAQ*+jH5)D28 zSym6kdzR>53+NMa?;hgcaDUZ$?yc`;wZMa+tdI^t>L?X{Bq@)0)zm_6{iVeEwIkCP z7cnk;<}tGJla&WggI*5}%nIEuFq8}=8#y(wDJvb7;c9D}N;VnD0!BSFvwg`SuJ664 z^E-903Z8tncfqSD_RY0n>>Dd3P|bcaG&ZVhITMutZUe;=jb)yt`Z~W%hS|`U z+_I@^5u@Ow#4jVBfC4dBLU?Zl1%J%U6(Qua8L>|JIYpnA|LY&k+t>YYJ0gRf+RyY6 zq(0^g97@hevqmH^H4uNeORIInl)Q8PZqyle^B`XAFmKxv2)-m*-k|SI{$qx$`HeDF z({1!odLMyiev&48UFarxtL( zzfz0MZf$LY3$mC1|FN+ol4Tq>@-a-((q|C8VTOjQ;1F(apl4_Y(8h#vWRHGs%bC-) z-LYGB%hWRKOve!I4^4S%j(a-%T}(~cW!zKNA%xFzQPnxDC`Z^uLLp9VV5WSyk{O>ER9SAjRN6^D9H`H4dWS&u7WTH4fKi=$-(;|G5`FA zy`1aNvEKa>u+{ie$*umI0j_Ch134JhW0}@qVhfQ%QxvDBn@1X&?Sb*$hYZ=^sx0Yk z4|COqfO)XZwaDAp&@(}~l1z?hl22@XfyRvjHDqbPkEJYESc+QlYWEon)BGO>IV8Hh z>VWnk{SWzEDj$;RH%WI*;b~FHa~ZSU){s4cq2EY>T?zsA5?62n-%bt)NUiVkYF#=m zp{!wTJA8}q;$faY(SYg8L+JP7SI$Wc47}*+5-!v4+d|w-mix0n{izu@%|6=K?-$G> z{*+As^Q6BG3yEUX5twYw$XpP+L*!vO*uNwIDCeB1ek8H~+V}A*)oqY{*Gh4hm~*Zt zmfs`ebNbTe9g$-FE!606i-@$Bj79KU>0)(c00{@*;i}7rdv8_Gb5{rRCnRe##|SiY znD?x3z67}*k{0Rg4(RBBN9J&XeH5QHT_6_VQ80tZ&a6t#4qS8(Y}PA)wrhxllfWM9 zT*2y@W6M=cRYr^jZCsrQn-CK_ofxiNt59S@Wc(rn9VLdo5o`>pzd4@zAjOxT!7o@1 zqK6q`Dn5PSD^%{KyDlRANrA(`h#yl|*>bzuRJ zze`hmwI@5Z)bqN0hWvG&GDeFC=oS1Z1*^G~KUxKa)!d+~Xi7{L;ck9!VgCKRNJ}<&6QA`!g~FgT$xrh8Vm9dw<*hX4 z_e08o+PFv^j0F?W8;O5$jmt^`98+Kbt&rZijI#$ycUa@zmNeWgYN;f~dxcsB@7`^On$WqkPhFBU7g>J2^Ok(eknGWyW}Iil{Pf06?>OVj}h zfv;^SgFrHM68*%Bh;ZC6nMyEua-h;C`9-LoX$I*4QbfHxL>FHk1FADnEwv8d2?@XN z@!I*ybCslrc<|2_?rAp1;+`Ujqlb!wO_@pg<=j3q%o-`cid9KopE}3~>PIQlf50&| z!Zc)TbBHuG3jEf~ezLHd%%pvaGvn_jvlswEj;N;YHp`yb;V{1tXf-&CIE#)xgA4f76|0RIw$p>Q z_KQ4@ToNj(weA!*nf}g-^ ziR`Sgd{cvP&^nvKoD;O2rP*LK2a1mwLr(cLF$kfc<0JqQNIWbaG z5R|T^tu&Pc7r~$dOw?Gd2?e#xzK*eU+Qj-!sZvfj?F`#@A-iqPz5h0coU|@P4>C82 zU<*0tp+Z55%jK#=S%=cywB*Jg)h|RZL+2P~+b|~Ghe2=Eh{ReRa`JjnC(rX=9lwiz zD53LR{e5)&>W^Xe@G3UqU*L!k4h*S|A&~2U%_!s7vG6Fs9-=M*!SswaFB^2Z_2iQGI2gxK^HEF|H|LE@^^Mm~@VIfdjX+>vjxLCdT(m+jhir zm=xPr)+T$@TP3+D3OWB%DCMfRHQep4{1LUD?OPEKYnM_Se`AVsrcQ!jav9$H-SLWH zLP#Vhe5g`1nYG~!g^rb5x(y~&ahau@0bq7PMKLluD~Ws1l9ry!trLrgKD2^P zMEFeeM>c0B$9S^3g}iJ7?>Oa>4p_h#@S_K~$p?QS>T8OfP-$YIG00Ep7nvZD0xRWE z$oPE${y=&VSPGt$CmPJNZ4w3jQD|u%i#9Oe;Um8qwj-5tEvKC=b$QvFrrzO@qAbJ@ z#BNMP?=eH7-&ox@f`|6i(42evCBL54`Z-It3oMBr@PCc!?qR|Rq{J1%@Z6f{6V*=p z=l3#Vc>QPHlgHdN`Oj7ZVDrTYxQ`PRzhnXW9*_%`hmxcFmAvrQAy~@7d*?lWu(I|_ zG6OAKts%hI|AQ-xzr9b3o920h%u1XEXjLN#fbcf|GYyD;DRn?N(CJ?{yf9iLQ@Q|c z=PZe#xH>s>2^@#%%1%#nS9z@377B!7iJ^8&*J$odk9dT?8J4W2&*f%Jt=*W| zEH!z`bY9oGBECE8Onk8N%OU*v9!Rfrvhkzw(OtYQHO{~Oxn|#7(fMp%8bJ-T`+M?2 zMy|z1$qon=5MOs>lJBQnswQ%8k7xqB7QyO|L%mH`Cvpz=GvFgJg?h6!eb75|VIm?! zxxf;-AMiimz{VQFi4w<~60`&jtPE6SqzF2!%1HmDwL}1(H<3%XT=Lz3Fz$}`-U^{) z%2?{YWcIanbJ62tzzOXq22go#t63u49%Ie|s~S)AZTuMS^EAH?`U5PK8Be~_)59?XTjygJ%L>49+Qi{?gjC;v4LLW z;7D5Z#k>(Xc{qIcBgijZxk&l!F&*xbf4U(H5;?n$pRr?E$XOBuHlkeg-5ni3!8v8O zN#}Bu10Pzr#j=i~EL>FoP5xHyd#TCXMLyu6T0wW&=K?uUi?gCrt+j{fO4a=MmYq3e zMK@Qte7RvRKaihSXvQz|w#j-pkbaj+NbAk)o|pBpQ>5vy9}6ClnuXkJtlQo_A9t;r zpA1-JESlcS-Da!i0DNKzN_uG1aI>W<%Fb;=%!odOQf&CC*Nwp*<~CWJ0Tv_ZO<>3f zj5A}Omdx>u``w(kM|Ayzm)P@8?5^L_?b?vL!z%mrS>iR5L(<;X>N!nk0cUuj7<^%P z#VRX*&n=F6F_+|MQt{v}TkHs8ca`^%snT3I~;DD}FC&1Ge5Q-^QDh3L6osoK}94G%=^l*2@rVnqI+|EN$kJ zrqP+HX?bl2WFk?$IG1&?z=1K=LA58W>-{qGh&JX*Y@>FVKYGoFiral5YfF)mL>FPK z6ZhK5l3nO@MjCWbVJJz#ePwCyHDA1toUa<|bZmLujAA7mV zGb{gI)Tb{iD_pzR2jMuyL{hrn*xSs1Z&Ke{sw7PR1EMH0IH2T_hc0rOHzQ<}+g>57 zhS@TIBcrW9K7VTU137(IbB5(@Fg|P`U=k(?dkbGO;f@UyeCKSEOEYk%9aa(tZBe19U9SlID{?q?+AU&Z%iwnnl&v)RoF3+&2D~o4U9Emg<^Dw zB=gAZQKB)kl6flhys4%LC~m}0S^Sse;8vpV5dB>`L^vgBKWx}B@0ysoS?t`%N%2P7 zX)f(ts)b%NkcMBcq{}W%ZT01uNp+z#Y(d;t9eAs5q=+W($>%C!MooQzrC?#%4q6{J za(wG|XW{)v`c4zgM^zqrQf_GWRzy0zcI8z%f?P8_H)0ApV%VESk-IDp<4U*=4brBj z#>M>auirGYILGIj5og;w4lR*A{nav6xoA zAN}O|5BbcCWD79zY8O09wbi#PY-op6=iB`OPFDdT-6 z;Yntbn9lYB2|xRtK!XKJvD&Gh_}yms@j??L98qHW!0H!uWK-gkYkXaC666=Ffw`7z zMQf!in@QvSP6k$ioc-KhE7G9FCJClkd(6j`-ZYx1&98kFN3GVkVUg4b;UIc!o%exy zaL=7lewl6*lWDA>ltv`*x$pIYr@pkzTkhsHfj`+Z%d;h0a)=Q+3{Io-1rxj7dZC90 zwSEe2X0OGiw4U;_Y02|XYwd4+`9-!1+cW1Xu&ZBWhG)#77NbtasrNT_sSgc7@B6Qq zxZG+=Ug@urSpY>)`(|QhGJ#}nJtel`;ULbUUD8O^NPQ>TKTlwQ-6Lhu<;+7v%_(sR=ab3!N@Q;t(gAn)6C2>`gI+-+^zj9A^!*9l0t7)pe_o$2XrVdletvoz9O#|Q{>PAkrUa_fkOnX%iE40<4P@lJlY%>y2il@T z8MPU6yGl5~H9*v?_O)%xxgR13ZL#$ypgg)~ifupZ9FBpf+0=mVEGsMsV{cZs5qbo< zC5px}K+x9b`p<+f?M20yghQrS}6&9KWK%fA#tW3q9sR1V>|u28Z%~$5XmXC zDjhsBi+SUUd8+lDgmL5H|!1#0Rd{xa-+>wUU#m6H{o? zfiOTn4X1neFvTJtj0r;mULzwmfSoLG+8JZ5pu5#r((lbd!|P{iAluU3I@UklR)9H@ zR0`Nd8q_%ozET6FM!iEa0^Kvls!v{xm48u|=gI?@7>uS>Bj8!^s+QFn2V^E)`cH2f zhv29T*tUHw87y!W5&kvB7o?DCbJJZFmFI*@y)a;#BhnWk6Sa^sY74#OQTIyLgo!@i zuG#**>+3t?Sn}^amZL@ZUN0c)DH~jgi5xl|2~;(>QtVu`xyV$GHQ63^-P4R`#ZP zf1LyTM!?^qoQrf5yn_YHBpfJ@ZYqN;_j$HB-LV}KDA<-Cw#V%aU2q?!Lw2I$>?wi= z`C!x<%I&cOT8@OJPOW=1DcWp&<*l)O`P)7&60IYpU8kl`TgeUnH&5?3+b8`l(Ww9&teQ`D_k3m~SfW~ls+d!B$CsX}ozDJ0Sx&nazbo;;iqm}i zjhM`3I?X_f{e1|v&;8{pRMYP+U@MAY5+uQ;(N_m}pI_qaZxhlY_H7SxU8ksT9!|a1 z)}g-x+aQ-7xOn-2ZdMb{-WTG_6=Lw>(JmtQvgc5lL+Q z@EHkcn?2=FygzC#+@yz_e^N-ecdwJ+Z<0v<=L(|cpU<#tAG*st!fL8G#L#)iDqQ&D zNfI*Rl~YQr{$D%FX686!-lJ#^czEp@=ojP7D=8+&FX3-H(+dM?h{DxX4F6!e8@(TfWOdGkcH*e3W`{i9Q~qXc&%~S`Fyr#>@#A}u4yEC4a~(y6TN6RZpq9`rk5;iZNHhJ zSY%C@b&l-WivMmq4ha55ewQWALi~xMHPqDD*@9N#*e^*&A=YA?4U38qptKR4y0|4z z%`8~nz}hf{v6?!dYu6vSXS+vLMk41j*gfXZ|%!0o>>ro;b_w(}h!k!&zG?(h%mQEus zhj8R5oEDvC7)8Bo2cH7?Ehc@(UZ_5md`QXEO-0QrTD6qDT49E<{*(Cf`b>jFa^`$W zLX9k-9e)c1+Ot%+t3U-)g9t`gwRfXL4)X?WWrW0+K|rs3MIx=lhRK@IswT~<@D-S+ zQuIHt^+HC-mMSpwh!xWJBlYb;nLSlBQHA;`OcKVP`bBCmZD3h-!s9nYfa!rL_OkLw z=XI=KtbM!++DICLpO!vw2=11wR0uHpE`ck__{b#oa z6=>n`A++;R;oQ41$3|b|tlEK3j>%EBt6TeJWUubBS4v9Ipg+D0d|5*a#Q33lU!on^ z_TFWC_gI5Xane_7LS|@5_r1q<+PAqf9Xf#REhK1udU4LBh){kkk^mT0H z^zgO?7qa_*&ILGRKToK#HTSDF{9<0hGdrvNsANZxQGpp^u7@?v$Y>HLjapd6t~R?! z^`Ll^f7aL%iUSMOt}uuL;tmi<%`Khutf;y*lMj$cRjky3@5By%H6sW?)DNEpx4>lr z6bd48cJATFIGYP(N8KMmLP#fNzN#8Ay3jD?L>5809-gEDrI6_q zoo^4!fV@D7-+P7z^qWPz)$xC12H=+Z!FvtR&Qq}3YDaxPve()##7`9yLPT7Qb`}LW zrW&PRg49i6HsrD)fw{?o=I}Et^V0UtF&bx_n{V9+EMyJoiRI+Hy9-M+lC7$tq{-&r znUQgY!GaeYDOUV~IHp)8OeKpnZzvx##hC?|-o{k3XwGjIDYr@cD$3Y2#H@r7n}p?f z#lLi+z@ouZ)x{iI+qn5viD0-onLb6GS>$N{mO#n!3;8esL!D;U$bt1pQ@xF`p*#MH|poDoIHbz9f#`r&XcN`ybYnx zIbfQ6{mNsHo0G>DH~WChbl*_p!Hq=&jfN?eo4xC`L5Zg!EWQfsolJh{`N6rY8IE(C zlbLT6!UHV(kkxil3HO+(S^R`z9dJb+N2*J_U(ZE0M}Oiu0Z?41pFe|cO#BXg1UR96 z?AH?g@vx&JzJ@Q-6x>d$W;#Sb+QZ4=mC&T8OsWEVWDHG{wp{J5^MaYE=J@LaijW%D z>NR`8%GDgs#*{MMhk&Q&fxDI2STQG#FJmm%nGoL6#lQw=+Sy~LI<@CLFly$kVIJ*d z;P+tS7-MCm%ktJt*ek{__ULcG0Nz>E{FpnO2oLi2aG)DParYWoVyj_1SDHB#=VGn~ zvaxkunG+ZaKJjY9COt9w2z{A2py=2Qp!!qZw0vEAu`}Rz-p)Q2c#l=tb^B6* z=80?AOFUYK#a1y(8Y@a3ct>et6-_v#gwBj2>#z$q_d7h>KL4f-MP^ zUuktuTgLf5jumkKX=6;=J(SvkyC`1vBLBCjkkcRF_g7D9&T%qI9xVgTsZUda2EWLZ z_*f>yT>JwK38{&v8jpQV{6(XXxp^P~d*Nh|lI3<(lsysOxU#x5?`M$!zL4emea8 z_ZaTH*#oJ8dS^FK+wxDGY#ns6_VPI@JvX#jzH!D(+s~F5;>&Dc}ADXFa@mqG*7`F5E*q;a}k_?%W?O)qFFV+k0yQ6Tl(+q!&OdxhTFGo^ZS1nn z%|;?hEZ0+0{S!eT#V=;#Vk+)A?!=k37?4b^( zSNr&8s(uKd;QvMON;`Zr%3_(JSEkklKv;fV}QX$2qgw$hk67PzfMCMDFe8uLN!;v4BJ&h~nIlyZ;Lo zvTcQ#ZLJX){Luk6sJNfrtQ{#@peaQ*d>jv@E>2N@n<$&?R-E=zReo}c_ zb|7;wE!N*+)fmP0_-56zGIkpy(9py}+wnR6`4)J5*KxX! zL$$^^9;Ys-dShZvQ4dS!Ll5rH-pc@rw^~1fdAvyw8=DL-G?l3@917asm)j~3GynOn zoD)u{=yPGjB2Dvu+O5Jb<)2=ZSeliH+O>yyuW>8W%?2I*C*HzxaL9QuPJe>`C*DFX zAokbF87vAdk{D-@_dtyo0A{9=H*!EbO z^_IY=-yXu$IfxtvycI9OY>Ph|#YUpz$wZW00~PZylSK-AS?+mG^Q|b2XYqGkkJdk_ zSlc()D7^`8x?ViHuCuR)eTjB2e6YbbKgqCoq^ zrP8t*b=YbY|AQFV`O{k8tizTgA4zW<6j&08QdAp>f|@Nu=I+PkEMntY5%oynhN6Qo zu*P>c-Nj>78=giL(Jpx9fO+Sy5$$oSZ zTEUs5l-y9VR6R}HjbUC?hZr_lQ=x{f`ukC)a4=js#vk}fc;T&Kj^G{~Qy~^YI}O~h z>xn`llwS^u9xH?7_2Z;=;a-1&d+0T?(-4VvinB~M-kIi-$#asdAch< z6W>Rl>W(vKw5q*rDYbU&hk$i}=lq}q221az(+Dy60ubEL zVdK`RKpg$*=Vh+BTV%99lcT7dt1FK`eS#{H1AYEa?XDjdNmGs+e4p6J%x-b3l2zoE zZ0efgr*oev!GmfYkO9~zTYhO1IT+a=vo#zf#2(Ww^$w%6N^fqgOK$yM*MZXQBX>>mfm~_@SX)}N&ajJ;$XqVg4-H#Gb4xDwRn5i!14VS2&H?-zcR2Jr=$=9 z6qoM~xFu5z+F&ZozM&1jMm!UFg>C#Y9DXFU(pf6}B0C~BM@i@GA8s}-YqW=Uo2-(h zBwH^<-%Dry?2t206Wu+fcTVR-sUfGX`+@D9cz(_eQ={=n;Pgo8pFF1AnKcB(XqtFF znb(>|*1khrY?&z*Q|C9!ytzaBVE0Qvh?J!bS8berujNy@TD7Z}PzT>I;+CCPCI0>4 zC!itrNhI5%x5cchn=V{a^8QY4^tFnZM@}LX#n67Dnw0$7H@}W(m{gv`^`xV> z_Noi=)0249LC%aMiMW6=y^EalyG_Ki-~&7gS8o%}#x9XIqUbQW#! zs=Z#6eO5j)MTvp0TNQ{Y;AX+JnSfO~Io^GmSW=BtFHz=csa2HFzxW1yy@R!6d?KgL z!WbY~Jfj^iL0AC5Q+WBrh|B~P>o{f=B2#qWY1)K341V)q+?ZIm9V`)<`Ud6b;vK~m zUgfuds#wubbl%<)F^rd~#gmnRL}!;HqKrX?(zD0)0shYW6zCByt*$&J6Fmp z#eZNQLEm`t-KIL=*9j&S;_R`6!GmCZHSTs_#zyhTLd24k99jmZrrlonHyWR`99lwo z?zk2A=yq3${ymj>a0g#-jmdu=NGc7VS*+tEe6~T5uF-SbYIo~)bfwvUs*hp`eB1IF`SM=gM6VjV{@Q1#^qOyy? z)%L<@h&cy3x7gkVx#yA9Gos+qZ!{%w<^(QE8OKA1`^NVR{{(NxXK3bg!x%DiW8SfabLzU_ z9)DK;)Bx!i)cHo$tMza45@D{<3`|=iJ}%jqiABZqUt}*Di)LSuwSa#-r5sgfth7IK z*Pic&v)Y=!9xmKG;v&LbQYuQ#x{sR{3$x|B%hu#}e#KQja-~kRH?gk||CzQU1&<}6 zD@+{M2i~$B#^`l81iQJD4wK?mLu($DwyO}k@XN`V)5>RMp8R~Si&u&sK(!_k}z%ak*Cv#zZ_5HTz*aEdAaH5q{ z`^2FKA-*|eh8$#q)$e+gApnM}G6=yf$0l0>llc60@rE2*nvce9A*naAousq<*a~=T zXH$z6Sw9>57aghC1j={+{6&l#?lAV@Ea=a{{X53_wHun!oLkWfTk|)#UTVS%FP>;e`-B4SzOmAFysKiL8;ADiHOMpx0V;BD!%SznNOphn zyzmH`UK`u8nr87@sAdwxZnmCkwML2>d0M(^caycy<=1f$_+DnnkWAs8Mc=WZ8-qfJ z5QK?<2^n~ImH2&HEE5J%Ddde7ey1d*F$@J#HD)c zQ!~EcvfEYOAfi_YS|C&qi7LeW#z%Gq`Rf)_6@$~bebRjhe7n6tZaF=n{&q^VVEBGx z6&8Eazpa-b_3hn}c#xY3^n8jLO@zt=T^u&gaW-1|jFD>oG-oz=DYK<`=}IR#8+TEa z=_;X0e0SLR*lmvVgx5W}0@bY+6mpvn26^xPPNF<7(i^FI5>OtX-^(bdO%K_NC1$S} zi`50`Wcum3YqhSC2t%^ucVsKhQ6ic^i#{X)Pj4tf=t z&HCLY6fv|3G?$h~$y?gc{T+f>3;5mJ7W}n2DHS!_a}BrN@`Mi^ypmG4_PK}k@K%pm zD;-k!iX6NucVwB4;(WP@B~jR7!xFpEeIrd_PL2<-u&T~U`;pYWL5K)gE4!o%ziSf6%*-BZK0WsAbxu7HuD5ru zA>{xzsUg9%*7uOkuLJMNUONB;M(S&5NdsNPsN$LPoOJ=)qRs!bvyCK^N2L5c^_7u2 z^&sIKQ4^jl*JYzq@B74+oGlno%ej)o&>I=c5cQ`)CCoz$Aylk~4dGAJcbt~HqhieI zlAHEvA@S>lC1#&>V}-l2pwOc8OSVURi z-8S|KX`UD$ZWJDPwOZVDaSaH<)`$abp1k}P#4Rf|{<&gK+{Z6@( zqY6nXRs6Ben{5IJOOCk=2Bli;G0(ewVXx)-5z}u74(dTKaAVRB{23AoRx*Sgo!OLr zgW)Nfq&7|0d^!zvoiJ;!CwqjT--xXr(-%b_M@e1&c90mv$ZCFZ0}vK~PyT*CufM0D z3Qz*od0sKV494A0uKd7m&xN|tVTofNrKNP^nzB5zjpLq<(-R+fm;2+_m>*+eRT?Qi z6~4jSv(xo;FHma`i(B1?z!c)Xb|OBsuUDr&?wdJZxMEo2h0VrSp1zj;N+t8HNmtZ1 z!g9Ym`t9V3_!z8FfF;-eMqT`T1Zx?QC9t@S+;K8z-TX74SvUZCHf0}p80>ZOZOuP9 z`-G6UiRZu3&*^&WqwV>f^;p*vJr$Wo;z7<18Qq72HR&WrPcex*NOSHCp|A0Iyhr&s zonHizB8OZ4TP;P$LrN-xvHZl4{R8^gcfIKG-2CAV<@3qFVTJIUiFb0rIyA1vhODKb zsC&@z^1d|3PX{O%K`&}M)_ zV=i&{=RzAKJbKqnbL9PLXi<{oPB(X~_yh6%)!{%Lzy{Y=o8b}ww3vLu>Qz%j0{rRsF@U73R}zWufu}K`gq36 zL^WV9y?;nHe>8eZ9S5QuQ#nuP1Gf|XFPl^li=`%1(9ipX%~QL9-z+NIe2>&Px*pi? zMEqX%&wqKId~m;gC&pYd_BFQ=Nzl%EJ@L=e4WQ&{bOww4eKtu1y6t{vPXlHd-UIg@ zITu>ywl*h0GJX*={;S3^cK!mQGthO`(OdupRVIL0gGlF7B14-BBr!iTBOI7C7l=C# ztEpx@JbS~YBIwG0rzkNZcGJqhNiSWLJ~Cws!D1d9;QA<%Dq0H{l`UOw8%O=)>ljGW zfu&F2*Qpisw59D|o2lXZJxrWSSvs&zoP6;Nhln@kjSO{AXj1-O`r!&rH}TVu^}C4Z zqq`q=MmBztACJSI-4>NtVrzXf6UY;kdmVlxfpm8_aa(Rj&2Lb0f!miYEA?@{#l3%X z0%F!47J^0Z58O@cDFU#h6IfkCx#qdq5b=-PJnZ-YfJWt6~~C4C4Otr-Lr8!R{Ku7cfK~V z)>Nuu^aU&3Vv3Yq3>qZtV2LC0<3-8HWvMe6E3SLUbK{px#7=HKraxxP)W=~RHsJlL zq5PTpcS}K;)N{EO`DSz@y}_Wvo#@70EOzLGlKzR)lxJ{s+xYeq-{@||pKGx##qmg-`vh%qwSagR6a5NU`*h#bS%;osNG z{qyERzc;Tzo2ypntRKo!o5p7)Ipw*^5=ydd1_VBd*pnN)j8~BxzfZZ4XVHzN$S?G|hgXH-nQALV@C6FF4gHlsbfS?@v~JI4h!V_UrL5NG^!Hwj8r zAdZre=%1O!KI%CRXkT8FQn8Ri*&P1Sm$hWk1%yzF5z)q_D8}2Mwj6-s4BS+cjjBtA zby*KGdyK#CjgJBdxV~TaZ5>k3H4p6-6Lal*(rZREgR2i9~rl)yh= zPl{m}@5El8gn|&sYC$-IOKd$9{YJ=`GpZHj)_Si#Fa%(|VaOyXUE~QJ(WoF}UBrTxguiVD9D*q80An zJ2&a@#!yfYJztWmKDv0VwD9wW)HU$Yo}=r^G$_!k1(IYl`iQd*?3iB6jkb7gqNu+Q z2NeOBh6*!0fBUP7s(|)3m#v4|FpNTpBs-(4p^752H(lg*^~ zZ!L++zApX|_s<8c)LrOB`*+AQ*LJ*WvNA;oD*BtXRK2k0^{hi^Du=7PPlL+DYEesI z%=CCbXv275{L|c$%g1PPZ_*pQug?iy8}9|zR!51z&SJ7(p5o%Y7BNcLDmJ@q?}vn% zs{vDKJ=?MoPAi{THfGV}EVT}nB7U#s$SfF3Jqp04a#81GfWPFXBgv%mQcseNfFbUm z%A!^Th(hlzgt|zq^jy?aTQSwJ=TL&QYB|IrZjn7@nl47AC&mijr9#I zn@1nOLM%u$hkF)D9O_xW{EYL{Bz;s@2#~uH=%$Hus(6KFSh&fNNX(PqLBfsf+z#%< z(ZVYmp|I9eXlzlcMTapo$qAX&S7IL|7GV*fBI5E;?8e5pMFfY(q0b!6!pP9a9le~^ zzxrd9PLR(P!{{y&y+fhA9c_CJQ&C#YQ4+iE8(UsJ=jr2h0f#+i7X$9yYbZ}vz`9SM z^u++J&HXgj*Xb1f#2Z{~H8_(_h0=v#*Cz*EwE`i|V!p;#eh4yah-yp`L}BcF6^5`n z)6`LSVZ^JbRQ<~=<3Ii6L7zBO5pAkcpW{)+Xvc3~MWZQL|E;aFEJUG z;BH#;1cl#Yxeda`teTNv_YAHvgqeEXG7)F5y!uK9>TK4j9OeDw`0hBHY=VJ zl3UDvF0!EK!ry)OI4N{EX2kzzWBkgWWDx&WFXYu3{$`#7r~&dsEHcmW30SZGCggkk zn{WTKe0i_x#zBwEE4L%8wkS=M(UO;<2fx~=W$Z3r&1BSCgWl%Y{8f8B)xLa;bEhNh zx<)Kf1n?yWHk;*(yb8y8QL5?x@QcW)(J!kLI*8zdIsK1Ok2()u#jUw#N%-7i|AVok zt>7N6ewo1Ab;;g-xQ32ho&&B2m;C|n^>9~X4mDtiHyK@uvQd&tcWq1S*@7r&}D~; zYp5R<=mv$y7%ya5q;qx*B)gil-e(1I*gnRHQ$cur(7KUU}#8Hkt@w za6DB@RQW{e>i>7xMC2YVzpFwyM&7OsKu0RS5|!{3Y>`k?*|o00c#s1SpCOmDqJ-+Ix%V2%@-A2!6e`CZx?eK;Xkaj&EhCu8;xFKmZ?&$+5hc!QvO{&Bdg(yo z^-5&q%N{Oxoe19M{+Dxuc}O_(t+RUIu}H^BF)+Aa?C$rL+C-kk=?R_j>Nvb8m{!lP zREHTzt3vU|2J)=~LrxtCON?TNr%v0!f%C{CG@^`jaYAN<*_Kpr#qKig7)qq(wGuMs zt8xAX^GTDnJuAJ8-Ai|;O0(2R;^}H@BaoPHh<5SN9G%67)QGxQXaUk}Y}Wak-)mg1XxuS9t2;Nb|Uw2yllDiB@L*qWJ99^iaYsB`EDSlj+>Aj%kQMu()4@acRJbJ{FN zTuWKVu7OV?%FW~6O81{LKDPQ1(%9*Ym+TBvvqgOj0@aiM)V}fHGw2>@*3@p zr~9MLcmNCs#}3FoKO$h@xu6qJK2lt@$}o`6Pwz4 z<0$YFpt+Gix<1%Jt})r}?xbBmLDtaBe&4H&`ED0}=Ull%Sgm{#4)LP`SF7YXCmHl$ z{d6*E578EYfQaNa(lCqos`yi^waRo~{r&=0*HqqUr7;UYql$?|_Gm+ruU05W!qp5! zKb#F$Q6n5q>BVFVN8UZg*CVSnO|@|14hKROEbx|o|e(h$33h~31O zBUpR7^14aSy|ov=UmPbG;HG_8FZ{3Tewfh+2qH80Pex1_Hz(}=+pOl>(EB567nc-?n_%GAZ#;?K)6D^&yFHD%+FHr>mHz91 z9O1e z$;ol)a#UoAatj?D%&i^KWfh8w7E{M9hPi|>d@CV32)X5!3L$nP8!jTd+f8%=ly!W-=BTHpU3M-^bHz)YvETvAL8NZ3H2H(piBae6ltWN z>x3CMmpv}p`C*5N^}XbMtNuRQuWA0JqYWy|AtJWuYGoX{_zCOKCaHw*qI(LmpQB*u`jpuH0@G_&7qj9En)2{Sb#?_rQl17` z+f3BShlKcul~!Bs2sKH&;m)lgJa1lLM4o7UVzLQp_R{_xS3nC(t)Zl#R**V5dhe10}lvQz^;=pl2d z>A?{K<>#@7msk9dpK0^>_`!@04MBjdn{U12OkQIMeghm7gl!XJI?;$e35Eq8<+IEC5>KVg(Fn)( zNCU@t46QP7VfgCcyg4P!XR~N~s$^7bXh2JIa@D$*df?iD`KdCb7#W?Mp1yl)^l^yl zooHA3NaYox8#$ciaspQSAjy<+^kQem5v|I$^S$o>1a4wv?#zI_D^^3kxTFOvv*aW; z!9*+VU??oKYWl_7AW6x%lUh#0ahmy`=R@jlvGhTn-n;QZATS}2d0Nxmc@&@QUhZWX z;U+dYn7ZR~45R3fIE%^9-;%Hh zSW#-bHlg98xa@FGU67}7=z`M4U4Ym{=}1!tKXAucO_MwsY(qc-WJJeB+ju%$aYZpl z5vTNHyE&fs{$7lJ%|FcPBE5e6F0;S3drfuN2b1{ ztn%a%>zGr02$cAJx~I>(X0J>ffQV%P-MhQGy6Wk_KdENKM@*_aGDk=H=|kcW)MYu7 zCDQFHLuPqg{f$CdtzG90Wf!=tq%_3TeC0lQVe~m8hB5a+{-GCxZBXs1Ng1c(*<BIE&xm~ZIY4|A(%!bd zxZnQgEU%pqU7s&5LxSw$@eDDTzzBN+&EL7BXywNF$y?af5PmJ|UBxA>>^#?2R%Nk3*zBU%bA<1YN79JOMBj{33N!^0yhJA156!DW23Ir=35>n~gj6GS3w zU9Mgoo9u7^3Li%!C7qu?W`Ik*nx6!(=raXe9$i8>M#?EaTxgJIlLKN79MUVGE22W( za=y2w{6zmNS2MwkB*04a6T3in6fG49m4Pd4J-hM2bUr>`QWXs^@`x=mGMW2{{QszRuW z2sw+Hp-1wek%;k~uxUI4pJK#_NCVi`WGdAFU?wS%{1FO3cj1<)4tr%HQ`HI?Y|xp! z(9pUXC@)}3+i>R+ceQDgo@&|;GEem;s4B3?p;K}+?12}{0mU!wNLaib9Mm#39m1hm zag7KY^&v2+WP}h7;C#$wn(d7t!x|Knn5J%Prxi9F%7_Hf+BehC^?Xb1M3U*ss3gqYv!spH=Lrv-+;(G6;L?nI zcdjv|219d1qd^vIoZrab4yo@_#O98788P~`>x8zK{|k#73S~XMeM(evB~1=B1#MMS zoExy?d+^#>ljb;%7)Tzy(2-!tjW@Cm1T=H89X74Vz{Og|$)u?Lu18+d2aWI<12(#< zxxT2DlY{StiN0Jm#u*X8ve*(woD8HGp25NCKd~-P?Mjop7m}onnT4C5xWX{wItc^ zHx%4KlK31f_#^dBkhJ`O_Us#sHG$^t&NOKqyWaEqBrW&{(?xhl*ZIvmg+|Vy@hpWeDr_-yhc63=Do%Ab_a$x+OO%)(NGrn?u?o!F}0dzyY-i4>N$x|N+P?D2(+`a1;%`N4K8gNYgvF_sLN46xnHkg{b#>u4$kvHU={9&v^fQvuw3+GhG{X`=nf;SB3j8fawsx~kM&F$TZRf6PqXwy{MZ5TI9w5%&Md zrQ2tp~%9WGqp8}?oVWOb?F?T`~|{dQ(~#q?$i{O z=im|w$!!DGo{r8V$Hoq9Y{TTZ9e628HV4EfDzwIR*vcS2oZP)QK?(pZSuR#( zx~E`*%RFZU$~^mEyre0Dr5H&d(}b@L6(QWNmG(2m$@#owyR$uAU950&W$3ERGwCvs zEY}|gK1IhMimzBCWI^J{-)cWw?H83iFq2Sbnje`Y^U$mDH76x}!XM=1)XM9#pmfb| z1pXj?p3IxT{!%MmdZwv)A&sx&R;3q(Pzd|?%Lb>!Y&SvMmiAf?8$7Q(_DPB^uFJr% uYeFM1V$iR~r-kODC0VJ_YiK;5Btlemr$r5%Q;`<~FXTxZtI8AC@BR-4RJ_^% diff --git a/man/spatialplanr-package.Rd b/man/spatialplanr-package.Rd index dd2e6411..88adcb5a 100644 --- a/man/spatialplanr-package.Rd +++ b/man/spatialplanr-package.Rd @@ -13,8 +13,8 @@ This package provides a range of tools for setting up, running and plotting a sp \seealso{ Useful links: \itemize{ - \item \url{https://github.com/MathMarEcol/spatialplanr} - \item Report bugs at \url{https://github.com/MathMarEcol/spatialplanr/issues} + \item \url{https://github.com/SpatialPlanning/spatialplanr} + \item Report bugs at \url{https://github.com/SpatialPlanning/spatialplanr/issues} } } diff --git a/man/splnr_apply_cutoffs.Rd b/man/splnr_apply_cutoffs.Rd index 78f23d51..36f7f64a 100644 --- a/man/splnr_apply_cutoffs.Rd +++ b/man/splnr_apply_cutoffs.Rd @@ -2,23 +2,93 @@ % Please edit documentation in R/splnr_apply_cutoffs.R \name{splnr_apply_cutoffs} \alias{splnr_apply_cutoffs} -\title{Function to apply cutoffs to feature data} +\title{Apply Cutoffs to Feature Data} \usage{ splnr_apply_cutoffs(features, Cutoffs, inverse = FALSE) } \arguments{ -\item{features}{A sf dataframe with all the feature information} +\item{features}{An \code{sf} dataframe. It must contain a \code{geometry} column and +at least one numeric column to which cutoffs will be applied.} -\item{Cutoffs}{A single value or a named vector of cutoffs.} +\item{Cutoffs}{A numeric value or a named numeric vector of cutoffs. +\itemize{ +\item If a single unnamed numeric value, it's applied to all numeric columns. +\item If a named numeric vector, names must correspond to numeric column names in \code{features}. +} +All cutoff values must be between \code{0} and \code{1}.} -\item{inverse}{If TRUE, values below the \code{Cutoffs} are used. If FALSE (default), values above are kept.} +\item{inverse}{A logical value (\code{TRUE} or \code{FALSE}). If \code{TRUE}, values below +the \code{Cutoffs} are converted to \code{1} (and others to \code{0}). If \code{FALSE} (default), +values at or above the \code{Cutoffs} are converted to \code{1}.} } \value{ -A new sf dataframe that has cutoffs applied. +A modified \code{sf} dataframe with the same structure and geometry as +\code{features}, but with all targeted numeric columns transformed into binary +(0 or 1) values based on the specified cutoffs and \code{inverse} setting. } \description{ -Function to apply cutoffs to feature data +\code{splnr_apply_cutoffs()} transforms numeric feature data in an \code{sf} dataframe +into binary (0 or 1) presence/absence values based on specified cutoffs. +It provides flexibility to either keep values above a cutoff as 1 (default) +or invert this logic to keep values below a cutoff as 1. +} +\details{ +This function is crucial for standardizing feature data, such as species +probability distributions or habitat suitability scores, into a binary format +often required for conservation planning and spatial analysis (e.g., in +\code{prioritizr}). + +The function operates in two primary modes based on the \code{Cutoffs} parameter: +\itemize{ +\item \strong{Single Cutoff:} If \code{Cutoffs} is a single numeric value (e.g., \code{0.5}), +this value is applied uniformly to \strong{all numeric columns} in the +\code{features} dataframe, excluding the \code{geometry} column. +For each numeric cell: +- If \code{value >= Cutoffs}, it becomes \code{1}. +- If \code{value < Cutoffs}, it becomes \code{0}. +- \code{NA} values are always converted to \code{0}. +\item \strong{Named Vector of Cutoffs:} If \code{Cutoffs} is a named numeric vector +(e.g., \code{c("feature1" = 0.5, "feature2" = 0.3)}), each specified cutoff +is applied individually to its corresponding named column in \code{features}. +This allows for different thresholds for different features. The same +transformation rules as above apply to each specified column. +} + +The \code{inverse} parameter provides additional control over the binarization: +\itemize{ +\item \code{inverse = FALSE} (default): Values \strong{at or above} the cutoff become \code{1}. +\item \code{inverse = TRUE}: Values \strong{below} the cutoff become \code{1}. After initial +binarization (where values >= cutoff are 1), the binary results are +flipped (0s become 1s, and 1s become 0s) to achieve the inverse effect. +} +All \code{NA} values in the numeric columns are consistently converted to \code{0} during +the binarization process, regardless of the \code{inverse} setting. } \examples{ -df <- splnr_apply_cutoffs(dat_species_prob, Cutoffs = 0.5) + +# Example 1: Single cutoff (0.5) applied to all numeric feature columns +# (Spp1_Prob, Spp2_Prob, and Cost will be binarized based on 0.5) +df_single_cutoff <- splnr_apply_cutoffs(dat_species_prob, Cutoffs = 0.5) +print(df_single_cutoff) + +# Example 2: Named cutoffs for specific columns +# Spp1_Prob >= 0.6 becomes 1, Spp2_Prob >= 0.4 becomes 1 +df_named_cutoffs <- splnr_apply_cutoffs( + dat_species_prob, + Cutoffs = c("Spp1" = 0.6, "Spp2" = 0.4) +) +print(df_named_cutoffs) + +# Example 3: Single cutoff (0.5) with inverse logic +# Values BELOW 0.5 become 1. +df_inverse_cutoff <- splnr_apply_cutoffs(dat_species_prob, Cutoffs = 0.5, inverse = TRUE) +print(df_inverse_cutoff) + +# Example 4: Named cutoffs with inverse logic +df_named_inverse <- splnr_apply_cutoffs( + dat_species_prob, + Cutoffs = c("Spp1" = 0.7, "Spp2" = 0.3), + inverse = TRUE +) +print(df_named_inverse) } diff --git a/man/splnr_arrangeFeatures.Rd b/man/splnr_arrangeFeatures.Rd index eee875d7..0feb8701 100644 --- a/man/splnr_arrangeFeatures.Rd +++ b/man/splnr_arrangeFeatures.Rd @@ -2,20 +2,42 @@ % Please edit documentation in R/utils.R \name{splnr_arrangeFeatures} \alias{splnr_arrangeFeatures} -\title{Ensure all features are in the same order.} +\title{Arrange Features by Spatial Coordinates} \usage{ splnr_arrangeFeatures(df) } \arguments{ -\item{df}{An sf object to sort by Lon and Lat} +\item{df}{An \code{sf} object whose rows are to be sorted.} } \value{ -A sorted sf object +A sorted \code{sf} object, with rows ordered primarily by longitude (X) +and secondarily by latitude (Y) of their centroids. } \description{ -\code{splnr_arrangeFeatures()} sorts your data based on longitude and latitude values. +\code{splnr_arrangeFeatures()} sorts the rows of an \code{sf} object based on the +longitude (X) and then latitude (Y) of its centroids. This ensures a +consistent ordering of planning units, which can be important for +reproducibility in some spatial analyses or data processing steps. +} +\details{ +This function computes the centroid for each polygon (or point/multipoint) +in the input \code{sf} object. It then extracts the X and Y coordinates of these +centroids and uses them to sort the entire \code{sf} object. The primary sort key +is the longitude (X-coordinate), and the secondary sort key is the latitude +(Y-coordinate). + +Sorting can be beneficial for tasks like debugging, comparing data from +different runs, or ensuring deterministic behavior in algorithms that +process spatial units sequentially. } \examples{ -df <- dat_species_prob \%>\% - splnr_arrangeFeatures() +\dontrun{ +print("Original order:") +print(dat_species_prob) + +# Sort the features. +df_arranged <- splnr_arrangeFeatures(df = dat_species_prob) +print("Sorted order:") +print(df_arranged) +} } diff --git a/man/splnr_climate_featureApproach.Rd b/man/splnr_climate_featureApproach.Rd index de729f0b..24d3be1f 100644 --- a/man/splnr_climate_featureApproach.Rd +++ b/man/splnr_climate_featureApproach.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/utils-climate.R \name{splnr_climate_featureApproach} \alias{splnr_climate_featureApproach} -\title{Function to run the feature approach} +\title{Run the Feature Climate-Smart Approach} \usage{ splnr_climate_featureApproach( features, @@ -14,40 +14,92 @@ splnr_climate_featureApproach( ) } \arguments{ -\item{features}{feature \code{sf}object} +\item{features}{An \code{sf} object representing conservation features (e.g., species +distribution data).} -\item{metric}{climate metric \code{sf} object with 'metric' as the column name of the metric values per planning unit.} +\item{metric}{An \code{sf} object containing climate metric information. It must +have a column named 'metric' with the climate metric values per planning unit.} -\item{targets}{\code{data.frame}with list of features under "feature" column and their corresponding targets under "target" column} +\item{targets}{A \code{data.frame} with two columns: \code{feature} (character, listing +the original feature names) and \code{target} (numeric, the initial conservation +target for each feature as a proportion, e.g., 0.3).} -\item{direction}{If direction = 1, metric values are from low (least climate-smart) to high (most climate-smart). If direction = -1, metric values are from high (least climate-smart) to low (most climate-smart).} +\item{direction}{An integer specifying the direction of climate-smartness: +\itemize{ +\item \code{1}: Higher metric values mean more climate-smart areas. +\item \code{-1}: Lower metric values mean more climate-smart areas. +}} -\item{percentile}{cut-off threshold for determining whether an area is a climate priority area or not (e.g., lower 35th percentile of warming or upper 65th percentile of acidification). Note that the percentile here is the lower limit of the threshold.} +\item{percentile}{A numeric value (0-100) representing the cutoff threshold for +determining whether an area is a climate priority area or not. This is applied +globally to the \code{metric} data. Defaults to \code{35}.} -\item{refugiaTarget}{target assigned to climate-smart areas} +\item{refugiaTarget}{A numeric value (0-1) representing the target proportion +assigned to the overall climate-smart layer. Defaults to \code{0.3} (30\%).} } \value{ -A \code{list} with two components: 1. is the data frame passed to \code{prioritizr} when creating a conservation problem containing the binary information per planning unit per feature. 2. are the targets for the features in the conservation problem when the CPA approach is used. +A \code{list} with two components: +\itemize{ +\item \code{Features}: An \code{sf} object containing the binary information per +planning unit for each original feature, plus the new \code{climate_layer} +feature. This is ready to be passed to \code{prioritizr}. +\item \code{Targets}: A \code{data.frame} with the adjusted targets for all features, +including the \code{climate_layer}. This is also ready for \code{prioritizr}. +} } \description{ -Function to run the feature approach +\code{splnr_climate_featureApproach()} implements the Feature Approach to +climate-smart conservation planning. This involves defining a global +"climate-smart" layer and adjusting conservation targets to ensure that +a specified proportion of this layer is captured in the solution. +} +\details{ +This function orchestrates the steps for the Feature Approach: +\enumerate{ +\item \strong{Preprocessing:} It calls \code{splnr_climate_feature_preprocess()} to +identify a region-wide climate-smart layer based on a percentile cutoff +of the climate metric. This layer is then added as a new binary feature +to your conservation data. +\item \strong{Target Assignment:} It then calls \code{splnr_climate_feature_assignTargets()} +to calculate and assign new targets. Crucially, a specific \code{refugiaTarget} +is set for the newly created \code{climate_layer} feature, ensuring that a +certain proportion of the most climate-resilient areas are included in +the final conservation plan. +} + +The output is a list containing the modified features (now including the +\code{climate_layer}) and their corresponding adjusted targets, ready to be used +in a \code{prioritizr} conservation problem. } \examples{ -Features <- dat_species_bin +\dontrun{ +# Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects +# in your package. -targets <- Features \%>\% +# Define initial targets for species features. +initial_targets <- dat_species_bin \%>\% sf::st_drop_geometry() \%>\% colnames() \%>\% data.frame() \%>\% setNames(c("feature")) \%>\% dplyr::mutate(target = 0.3) -Feature_Approach <- splnr_climate_featureApproach( +# Run the Feature Approach where higher climate metric values mean +# more climate-smart areas. +Feature_Approach_result <- splnr_climate_featureApproach( features = dat_species_bin, metric = dat_clim, - targets = targets, - direction = 1 + targets = initial_targets, + direction = 1, # Example: higher metric values are more climate-smart + percentile = 35, + refugiaTarget = 0.3 ) -out_sf <- Feature_Approach$Features -targets <- Feature_Approach$Targets + +# Access the processed features and targets: +out_sf_feature <- Feature_Approach_result$Features +targets_feature <- Feature_Approach_result$Targets + +print(head(out_sf_feature)) +print(head(targets_feature)) +} } diff --git a/man/splnr_climate_percentileApproach.Rd b/man/splnr_climate_percentileApproach.Rd index 3a891c58..d3f93d58 100644 --- a/man/splnr_climate_percentileApproach.Rd +++ b/man/splnr_climate_percentileApproach.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/utils-climate.R \name{splnr_climate_percentileApproach} \alias{splnr_climate_percentileApproach} -\title{Function to run the percentile approach} +\title{Run the Percentile Climate-Smart Approach} \usage{ splnr_climate_percentileApproach( features, @@ -13,37 +13,88 @@ splnr_climate_percentileApproach( ) } \arguments{ -\item{features}{feature \code{sf}object} +\item{features}{An \code{sf} object representing conservation features (e.g., species +distribution data).} -\item{metric}{climate metric \code{sf} object with 'metric' as the column name of the metric values per planning unit.} +\item{metric}{An \code{sf} object containing climate metric information. It must +have a column named 'metric' with the climate metric values per planning unit.} -\item{targets}{\code{data.frame}with list of features under "feature" column and their corresponding targets under "target" column} +\item{targets}{A \code{data.frame} with two columns: \code{feature} (character, listing +the original feature names) and \code{target} (numeric, the initial conservation +target for each feature as a proportion, e.g., 0.3).} -\item{direction}{If direction = 1, metric values are from low (least climate-smart) to high (most climate-smart). If direction = -1, metric values are from high (least climate-smart) to low (most climate-smart).} +\item{direction}{An integer specifying the direction of climate-smartness: +\itemize{ +\item \code{1}: Higher metric values mean more climate-smart areas. +\item \code{-1}: Lower metric values mean more climate-smart areas. +}} -\item{percentile}{cut-off threshold for determining whether an area is a climate priority area or not (e.g., lower 35th percentile of warming or upper 65th percentile of acidification). Note that the percentile here is the lower limit of the threshold.} +\item{percentile}{A numeric value (0-100) representing the cutoff threshold for +determining whether an area is a climate priority area or not. This is applied +\emph{per feature} to its distribution. Defaults to \code{35}.} } \value{ -A \code{list} with two components: 1. is the data frame passed to \code{prioritizr} when creating a conservation problem containing the binary information per planning unit per feature. 2. are the targets for the features in the conservation problem when the CPA approach is used. +A \code{list} with two components: +\itemize{ +\item \code{Features}: An \code{sf} object containing the binary information per +planning unit for each feature, now filtered to include only its +climate-smart occurrences. This is ready to be passed to \code{prioritizr}. +\item \code{Targets}: A \code{data.frame} with the adjusted targets for the +filtered features. This is also ready for \code{prioritizr}. +} } \description{ -Function to run the percentile approach +\code{splnr_climate_percentileApproach()} implements the Percentile Approach to +climate-smart conservation planning. This involves filtering features to +their most climate-resilient areas and adjusting their conservation targets +to account for this reduced feature distribution. +} +\details{ +This function orchestrates the steps for the Percentile Approach: +\enumerate{ +\item \strong{Preprocessing:} It calls \code{splnr_climate_percentile_preprocess()} to +identify, for each feature, its occurrences within the most climate-resilient +\code{percentile} of its distribution based on a climate metric. This effectively +"filters" the feature data to only include its climate-smart components. +\item \strong{Target Assignment:} It then calls \code{splnr_climate_percentile_assignTargets()} +to calculate and assign new targets for these filtered features. The targets +are scaled up to ensure that the original conservation goals are still met, +but specifically by selecting areas from the climate-smart portions of the +features' distributions. +} + +The output is a list containing the modified features (filtered to their +climate-smart occurrences) and their corresponding adjusted targets, ready +to be used in a \code{prioritizr} conservation problem. } \examples{ +\dontrun{ +# Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects +# in your package. -targets <- dat_species_bin \%>\% +# Define initial targets for species features. +initial_targets <- dat_species_bin \%>\% sf::st_drop_geometry() \%>\% colnames() \%>\% data.frame() \%>\% setNames(c("feature")) \%>\% dplyr::mutate(target = 0.3) -Percentile_Approach <- splnr_climate_percentileApproach( +# Run the Percentile Approach where higher climate metric values mean +# more climate-smart areas. +Percentile_Approach_result <- splnr_climate_percentileApproach( features = dat_species_bin, metric = dat_clim, - targets = targets, - direction = 1 + targets = initial_targets, + direction = 1, # Example: higher metric values are more climate-smart + percentile = 35 ) -out_sf <- Percentile_Approach$Features -targets <- Percentile_Approach$Targets + +# Access the processed features and targets: +out_sf_percentile <- Percentile_Approach_result$Features +targets_percentile <- Percentile_Approach_result$Targets + +print(head(out_sf_percentile)) +print(head(targets_percentile)) +} } diff --git a/man/splnr_climate_priorityAreaApproach.Rd b/man/splnr_climate_priorityAreaApproach.Rd index d76d4fbf..fc272ec6 100644 --- a/man/splnr_climate_priorityAreaApproach.Rd +++ b/man/splnr_climate_priorityAreaApproach.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/utils-climate.R \name{splnr_climate_priorityAreaApproach} \alias{splnr_climate_priorityAreaApproach} -\title{Function to run the climate-priority-area approach} +\title{Run the Climate Priority Area (CPA) Approach} \usage{ splnr_climate_priorityAreaApproach( features, @@ -14,39 +14,94 @@ splnr_climate_priorityAreaApproach( ) } \arguments{ -\item{features}{feature \code{sf}object} +\item{features}{An \code{sf} object representing conservation features (e.g., species +distribution data). Each column (excluding geometry) should typically be a +binary representation of a feature's presence (1) or absence (0) in each +planning unit.} -\item{metric}{climate metric \code{sf} object with 'metric' as the column name of the metric values per planning unit.} +\item{metric}{An \code{sf} object containing climate metric information. It must +have a column named 'metric' with the climate metric values per planning unit.} -\item{targets}{\code{data.frame}with list of features under "feature" column and their corresponding targets under "target" column} +\item{targets}{A \code{data.frame} with two columns: \code{feature} (character, listing +the original feature names) and \code{target} (numeric, the initial conservation +target for each feature as a proportion, e.g., 0.3).} -\item{direction}{If direction = 1, metric values are from low (least climate-smart) to high (most climate-smart). If direction = -1, metric values are from high (least climate-smart) to low (most climate-smart).} +\item{direction}{An integer specifying the direction of climate-smartness: +\itemize{ +\item \code{1}: Higher metric values mean more climate-smart areas. +\item \code{-1}: Lower metric values mean more climate-smart areas. +}} -\item{percentile}{cut-off threshold for determining whether an area is a climate priority area or not (e.g., lower 35th percentile of warming or upper 65th percentile of acidification). Note that the percentile here is the lower limit of the threshold.} +\item{percentile}{A numeric value (0-100) representing the cutoff threshold for +determining climate-smart areas. For example, \code{percentile = 5} means the +most climate-smart 5\% of areas (based on \code{direction}) are considered. +This value represents the lower limit of the threshold. Defaults to \code{5}.} -\item{refugiaTarget}{target assigned to climate-smart areas} +\item{refugiaTarget}{A numeric value (0-1) representing the target proportion +assigned specifically to climate-smart areas (refugia). Defaults to \code{1} (100\%).} } \value{ -A \code{list} with two components: 1. is the data frame passed to \code{prioritizr} when creating a conservation problem containing the binary information per planning unit per feature. 2. are the targets for the features in the conservation problem when the CPA approach is used. +A \code{list} with two components: +\itemize{ +\item \code{Features}: An \code{sf} object containing the binary information per +planning unit for each feature, now split into \verb{_CS} (climate-smart) +and \verb{_NCS} (non-climate-smart) components. This is ready to be +passed to \code{prioritizr} when creating a conservation problem. +\item \code{Targets}: A \code{data.frame} with the adjusted targets for the +climate-split features. This is also ready for \code{prioritizr}. +} } \description{ -Function to run the climate-priority-area approach +\code{splnr_climate_priorityAreaApproach()} implements the Climate Priority Area +approach by splitting conservation features into climate-smart (CS) and +non-climate-smart (NCS) components and adjusting their targets accordingly. +This allows conservation planning to prioritize areas with higher climate resilience. +} +\details{ +This function orchestrates the steps required for the CPA approach: +\enumerate{ +\item \strong{Preprocessing:} It calls \code{splnr_climate_priorityArea_preprocess()} to +categorize each feature's occurrences into CS and NCS areas based on a +climate metric and a specified \code{percentile} cutoff. +\item \strong{Target Assignment:} It then calls \code{splnr_climate_priorityArea_assignTargets()} +to calculate and assign new targets for these CS and NCS feature components. +This ensures that conservation goals reflect the desired emphasis on climate-smart +areas (e.g., aiming for 100\% representation of features in highly resilient areas). +} + +The output of this function is a list containing the modified features (now +split into CS/NCS components) and their corresponding adjusted targets, ready +to be used in a \code{prioritizr} conservation problem. } \examples{ +\dontrun{ +# Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects +# in your package. -targets <- dat_species_bin \%>\% +# Define initial targets for species features. +initial_targets <- dat_species_bin \%>\% sf::st_drop_geometry() \%>\% colnames() \%>\% data.frame() \%>\% setNames(c("feature")) \%>\% dplyr::mutate(target = 0.3) -CPA_Approach <- splnr_climate_priorityAreaApproach( +# Run the Climate Priority Area Approach where lower climate metric +# values mean more climate-smart areas. +CPA_Approach_result <- splnr_climate_priorityAreaApproach( features = dat_species_bin, metric = dat_clim, - targets = targets, - direction = -1 + targets = initial_targets, + direction = -1, # Example: lower metric values are more climate-smart + percentile = 5, + refugiaTarget = 1 ) -out_sf <- CPA_Approach$Features -targets <- CPA_Approach$Targets + +# Access the processed features and targets: +out_sf_cpa <- CPA_Approach_result$Features +targets_cpa <- CPA_Approach_result$Targets + +print(head(out_sf_cpa)) +print(head(targets_cpa)) +} } diff --git a/man/splnr_create_polygon.Rd b/man/splnr_create_polygon.Rd index 172f4b27..dc43c68e 100644 --- a/man/splnr_create_polygon.Rd +++ b/man/splnr_create_polygon.Rd @@ -2,24 +2,50 @@ % Please edit documentation in R/utils.R \name{splnr_create_polygon} \alias{splnr_create_polygon} -\title{Function for creating polygon} +\title{Create Spatial Polygon from Coordinates} \usage{ splnr_create_polygon(x, cCRS = "EPSG:4326") } \arguments{ -\item{x}{A named vector of lon/lat coordinates from which to make an \code{sf} polygon} +\item{x}{A \code{tibble} (or \code{tbl_df}) object with at least two columns, +typically named \code{x} (for longitude) and \code{y} (for latitude), representing +the vertices of the polygon in sequence. The first and last coordinate +pair should be the same to form a closed polygon.} -\item{cCRS}{The CRS to use for the polygon} +\item{cCRS}{A character string specifying the target CRS for the output polygon +in an EPSG code format (e.g., "EPSG:4326"). Defaults to "EPSG:4326" (WGS 84).} } \value{ -An \code{sf} object for the polygon +An \code{sf} object representing the created polygon, with the specified CRS. } \description{ -\code{splnr_create_polygon()} allows you to create a polygon based on longitude and latitude coordinates in your input data. +\code{splnr_create_polygon()} constructs an \code{sf} polygon object from a series +of longitude and latitude coordinates provided in a tibble. +} +\details{ +This utility function simplifies the creation of spatial polygons from a +tabular format of coordinates. It takes a tibble where columns 'x' and 'y' +represent longitude and latitude, respectively. These coordinates are +converted into a matrix, then to an \code{sf} polygon, and finally to an \code{sf} +object with the specified Coordinate Reference System (CRS). + +The function assumes that the input coordinates (\code{x}) are initially in +WGS 84 (EPSG:4326) and then transforms them to the \code{cCRS} if a different +CRS is specified. } \examples{ -splnr_create_polygon(x = dplyr::tibble(x = seq(-50, 50, by = 1), y = 120) \%>\% - dplyr::bind_rows(dplyr::tibble(x = 50, y = seq(120, 180, by = 1))) \%>\% - dplyr::bind_rows(dplyr::tibble(x = seq(50, -50, by = -1), y = 180)) \%>\% - dplyr::bind_rows(dplyr::tibble(x = -50, y = seq(150, 120, by = -1)))) +# Example: Create a simple square polygon +square_coords <- dplyr::tibble( + x = c(-50, 50, 50, -50, -50), + y = c(120, 120, 180, 180, 120) +) +simple_polygon <- splnr_create_polygon(x = square_coords) +print(simple_polygon) + +# Example: Create a polygon and transform to a different CRS (e.g., a UTM zone) +\dontrun{ +# Note: EPSG:32611 is UTM Zone 11N. Ensure it's appropriate for your coordinates. +transformed_polygon <- splnr_create_polygon(x = square_coords, cCRS = "EPSG:32611") +print(transformed_polygon) +} } diff --git a/man/splnr_featureNames.Rd b/man/splnr_featureNames.Rd index 93f57313..f5d4d8ef 100644 --- a/man/splnr_featureNames.Rd +++ b/man/splnr_featureNames.Rd @@ -2,23 +2,55 @@ % Please edit documentation in R/utils.R \name{splnr_featureNames} \alias{splnr_featureNames} -\title{Returns the feature names} +\title{Extract Feature Names from Spatial Data} \usage{ splnr_featureNames(dat, exclude = NA) } \arguments{ -\item{dat}{sf dataframe of features} +\item{dat}{An \code{sf} dataframe representing conservation features. Each +non-geometry column is assumed to be a feature.} -\item{exclude}{Character vector of any columns to exclude} +\item{exclude}{A character vector of column names (or prefixes) to exclude +from the output. By default, it excludes columns starting with "Cost_". +If you provide a value, it will be \emph{appended} to the default exclusion. +Set to \code{NULL} or \code{character(0)} if you want no exclusions beyond the default.} } \value{ -A character vector of names +A character vector containing the names of the conservation features. } \description{ -\code{splnr_featureNames()} allows you to extract the names of features you want to pass to a \code{prioritizr} prioritization. -It requires an \code{sf} object input and returns the column names of the object excluding any columns you specify in the \code{exclude} argument. +\code{splnr_featureNames()} extracts the names of conservation features +from an \code{sf} dataframe, excluding geometry and any specified columns. +} +\details{ +This function is a utility for preparing data for \code{prioritizr} or other +conservation planning packages that require a vector of feature names. +It typically removes the geometry column and any columns related to cost +(prefixed with "Cost_") by default, allowing you to specify additional +columns to exclude. + +The output is a simple character vector of column names, which can be +directly used as feature identifiers in conservation problems. } \examples{ -df <- dat_species_prob \%>\% - splnr_featureNames() +\dontrun{ +# Assuming 'dat_species_prob' is an existing sf object in your package. +# It likely has columns like 'Spp1', 'Spp2', 'Cost_SomeMeasure', etc. + +# Example 1: Get all feature names, excluding default 'Cost_' columns. +feature_names_default <- splnr_featureNames(dat = dat_species_prob) +print(feature_names_default) + +# Example 2: Get feature names, excluding 'Cost_' columns and 'Spp5'. +feature_names_custom_exclude <- splnr_featureNames( + dat = dat_species_prob, + exclude = "Spp5" +) +print(feature_names_custom_exclude) + +# Example 3: If you only want to exclude a specific column and not 'Cost_' +# (you'd need to manually specify exclude = "geometry" and then your column) +# This case is more complex and usually handled by direct dplyr::select. +# This function's primary use is to remove cost columns and potentially others. +} } diff --git a/man/splnr_get_IUCNRedList.Rd b/man/splnr_get_IUCNRedList.Rd index a20c7fff..744f0bdc 100644 --- a/man/splnr_get_IUCNRedList.Rd +++ b/man/splnr_get_IUCNRedList.Rd @@ -2,44 +2,71 @@ % Please edit documentation in R/splnr_get_IUCNRedList.R \name{splnr_get_IUCNRedList} \alias{splnr_get_IUCNRedList} -\title{Match Species to IUCN RedList} +\title{Match Species to IUCN RedList Categories} \usage{ splnr_get_IUCNRedList(df, species_col = "Species") } \arguments{ -\item{df}{The dataframe containing the species to be matched with the IUCN redlist} +\item{df}{The input dataframe containing the species names to be matched.} -\item{species_col}{A string name for the column containting the species name} +\item{species_col}{A character string specifying the name of the column in \code{df} +that contains the species scientific names (e.g., "Species" or "scientific_name"). +Defaults to "Species".} } \value{ -A dataframe with an additional column \code{IUCN_Category} +A dataframe identical to the input \code{df}, but with an additional column +named \code{IUCN_Category}. If a species is not found on the IUCN Red List, its +\code{IUCN_Category} will be \code{NA}. } \description{ -First of all you will need your own API key, an alphanumeric string provided by IUCN that you need to send in every request; -the following function takes you to their website, where you will need to fill up a form (it might take 1-2 days to receive your key) -rl_use_iucn() -Once you receive an email with your API key, set it up as an environmental variable (it MUST be named IUCN_REDLIST_KEY) -you will need to re-do this step everytime you restart R -Sys.setenv(IUCN_REDLIST_KEY = "") OR add IUCN_REDLIST_KEY = "" to your .Renviron file to permanently set it -Sys.getenv("IUCN_REDLIST_KEY") #' check -Not Evaluated -DD: Data Deficient -LC: Least Concern -NT: Near Threatened -VU: Vulnerable -EN: Endangered -CR: Critically Endangered -EW: Extinct in the Wild -EX: Extinct -LRlc: Low risk – least concern -LRnt: Low risk – near threatened -LRcd: Low risk - conservation dependent -Categories we care about -cate <- c("EX","EW","CR","EN","VU") +The \code{splnr_get_IUCNRedList} function retrieves IUCN Red List category information +for a given set of species and appends it to your input dataframe. +} +\details{ +To use this function, you must first obtain an API key from IUCN. This is an +alphanumeric string required for every request. You can visit the IUCN website +to request a key using \code{rl_use_iucn()}. Please note that receiving your key +might take 1-2 days after submitting the form. + +Once you receive your API key, it is crucial to set it as an environment variable +named \code{IUCN_REDLIST_KEY}. You can do this temporarily for the current R session +using \code{Sys.setenv(IUCN_REDLIST_KEY = "YOUR_API_KEY_HERE")}. To set it permanently, +you should add \code{IUCN_REDLIST_KEY = "YOUR_API_KEY_HERE"} to your \code{.Renviron} file. +You can check if the key is set correctly using \code{Sys.getenv("IUCN_REDLIST_KEY")}. + +The IUCN Red List uses various categories to assess extinction risk. This function +queries the Red List for the following categories: +\itemize{ +\item \strong{DD}: Data Deficient +\item \strong{LC}: Least Concern +\item \strong{NT}: Near Threatened +\item \strong{VU}: Vulnerable +\item \strong{EN}: Endangered +\item \strong{CR}: Critically Endangered +\item \strong{EW}: Extinct in the Wild +\item \strong{EX}: Extinct +\item \strong{LRlc}: Lower Risk / least concern (old category) +\item \strong{LRnt}: Lower Risk / near threatened (old category) +\item \strong{LRcd}: Lower Risk / conservation dependent (old category) +} +The function will attempt to match your species against any of these categories +present in the IUCN Red List database. } \examples{ \dontrun{ -df <- data.frame(Species = c("Diomedea exulans", "Hippocampus kuda", "Squatina squatina")) \%>\% +# Ensure your IUCN_REDLIST_KEY is set as an environment variable before running. +# For example: Sys.setenv(IUCN_REDLIST_KEY = "YOUR_API_KEY_HERE") + +# Example: Create a dataframe with species names and retrieve their IUCN Red List categories. +df_species_redlist <- data.frame(Species = c("Diomedea exulans", + "Hippocampus kuda", + "Squatina squatina")) \%>\% splnr_get_IUCNRedList() +print(df_species_redlist) + +# Example with a different column name for species +df_alt_col <- data.frame(ScientificName = c("Panthera leo", "Orcinus orca")) \%>\% + splnr_get_IUCNRedList(species_col = "ScientificName") +print(df_alt_col) } } diff --git a/man/splnr_get_MPAs.Rd b/man/splnr_get_MPAs.Rd index f221eedb..e1847172 100644 --- a/man/splnr_get_MPAs.Rd +++ b/man/splnr_get_MPAs.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/splnr_get_MPAs.R \name{splnr_get_MPAs} \alias{splnr_get_MPAs} -\title{Get marine parks from the WDPA.} +\title{Get Marine Protected Areas (MPAs) from WDPA} \usage{ splnr_get_MPAs( PlanUnits, @@ -14,31 +14,82 @@ splnr_get_MPAs( ) } \arguments{ -\item{PlanUnits}{Planning Units as an \code{sf} object} +\item{PlanUnits}{An \code{sf} object representing the planning units to be used for intersection. +This object should have a valid CRS defined.} -\item{Countries}{A character vector of the countries for which to extract MPAs. To get all MPAs, use \code{"global"} here.} +\item{Countries}{A character vector specifying the countries for which to extract MPAs. +To retrieve all global MPAs, use the value \code{"global"}. Country names should match +those recognized by the WDPA database.} -\item{Status}{The status field in the WDPA provides information on whether a protected area has been established, designated, or proposed at the time the data was submitted.} +\item{Status}{A character vector specifying the desired status of protected areas +to include. Defaults to \code{c("Designated", "Established", "Inscribed")}.} -\item{Desig}{The designation type is the category or type of protected area as legally/officially designated or proposed.} +\item{Desig}{A character vector specifying the desired designation types of +protected areas. Defaults to \code{c("National", "Regional", "International", "Not Applicable")}.} -\item{Category}{Stores the IUCN Protected Area Management Categories (recorded in field IUCN_CAT) for each of the protected areas where these categories are reported} +\item{Category}{A character vector specifying the desired IUCN Protected Area +Management Categories. Defaults to \code{c("Ia", "Ib", "II", "III", "IV")}.} -\item{...}{Other arguments passed to \code{wdpa_fetch()}} +\item{...}{Other arguments that are passed directly to the \code{wdpa_fetch()} function +from the \code{wdpar} package (e.g., \code{verbose = TRUE}).} } \value{ -A \code{sf} object with the MPAs intersected with the planning units +An \code{sf} object. This object contains the planning units, with an +additional \code{wdpa} column (set to 1) for areas that intersect with the +selected MPAs. } \description{ -This code is a wrapper for the wonderful \code{wdpar} package written by Jeffrey O. Hanson. This data is then interfaced with the planning units. -An \code{sf} object is returned with the PU area covered by the selected marine protected areas. +This function serves as a wrapper for the \code{wdpar} package, facilitating the +retrieval of Marine Protected Areas (MPAs) from the World Database on Protected +Areas (WDPA) and intersecting them with provided planning units. +The result is an \code{sf} object indicating the area of planning units covered by +the selected marine protected areas. +} +\details{ +This function leverages the robust capabilities of the \code{wdpar} package by +Jeffrey O. Hanson to access and process WDPA data. It allows filtering of MPAs +based on country, status, designation type, and IUCN category, and then +spatially intersects these MPAs with your defined planning units. + +For a comprehensive understanding of the WDPA data fields: +\itemize{ +\item \strong{Status}: Refers to the establishment, designation, or proposal +status of a protected area at the time of data submission. Valid options +include "Designated", "Established", "Inscribed", "Proposed", and "Adopted". +\item \strong{Desig} (Designation Type): Categorizes the legal or official +designation of the protected area. Valid options include "National", +"Regional", "International", and "Not Applicable". +\item \strong{Category} (IUCN Protected Area Management Categories): Represents +the IUCN management categories for protected areas. Valid options include +"Ia", "Ib", "II", "III", "IV", "V", "VI", "Not Reported", "Not Applicable", +and "Not Assigned". +} } \examples{ -dat <- splnr_get_MPAs(PlanUnits = dat_PUs, Countries = "Australia") +\dontrun{ +# Assuming 'dat_PUs' is an existing sf object of planning units in your package. + +# Example: Get MPAs for Australia and intersect with planning units. +dat_mpas <- splnr_get_MPAs(PlanUnits = dat_PUs, Countries = "Australia") +# Example: Get MPAs for multiple countries with specific status and categories. +dat_mpas_specific <- splnr_get_MPAs( + PlanUnits = dat_PUs, + Countries = c("Australia", "New Zealand"), + Status = c("Designated", "Proposed"), + Category = c("II", "IV") +) + +# Example: Visualize the result using ggplot2. +# Assuming 'aust' is an sf object representing Australia's coastline, +# perhaps loaded from rnaturalearth::ne_countries. aust <- rnaturalearth::ne_countries(country = "Australia", returnclass = "sf") gg <- ggplot2::ggplot() + - ggplot2::geom_sf(data = dat, ggplot2::aes(fill = wdpa)) + - ggplot2::geom_sf(data = aust, fill = "grey50") + ggplot2::geom_sf(data = dat_mpas, ggplot2::aes(fill = wdpa)) + + ggplot2::geom_sf(data = aust, fill = "grey50") + + ggplot2::labs(title = "Marine Protected Areas in Australia") + + ggplot2::theme_minimal() +print(gg) +} } diff --git a/man/splnr_get_boundary.Rd b/man/splnr_get_boundary.Rd index a7b1c7ce..a6aa7e2c 100644 --- a/man/splnr_get_boundary.Rd +++ b/man/splnr_get_boundary.Rd @@ -2,27 +2,64 @@ % Please edit documentation in R/splnr_get_boundary.R \name{splnr_get_boundary} \alias{splnr_get_boundary} -\title{Get the boundary of the planning region.} +\title{Create a Planning Region Boundary} \usage{ splnr_get_boundary(Limits, Type = NULL, res = 1, cCRS = "ESRI:54009") } \arguments{ -\item{Limits}{The limits of the boundary. This can either be a 4 element numeric named vector (c(xmin = 150, xmax = 160, ymin = -40, ymax = -30)), a vector of ocean/sea names, or a vector of EEZs.,} +\item{Limits}{A required input that defines the spatial extent. This can be: +\itemize{ +\item A named numeric vector of four elements: \code{c("xmin" = ..., "xmax" = ..., "ymin" = ..., "ymax" = ...)}. +\item The string \code{"Global"} to create a worldwide boundary. +\item A character vector of ocean/sea names (e.g., \code{"North Atlantic Ocean"}) to be used with \code{Type = "Ocean"}. +}} -\item{Type}{The type of Limits being provided. Options are "Ocean" or "EEZ". (not required if numeric or "Global" limits are provided)} +\item{Type}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} The type of Limits being provided. This is only required if \code{Limits} is a character vector of ocean names, in which case it should be \code{"Ocean"}. It is no longer required and will be removed in a future version.} -\item{res}{The resolution (in degrees) from which to create the boundary polygon if numeric limits are provided.} +\item{res}{\verb{[numeric(1)]}\cr The resolution (in decimal degrees) used to +construct the polygon vertices when \code{Limits} is numeric or \code{"Global"}. +Defaults to \code{1}. Must be a positive number.} -\item{cCRS}{The CRS the boundary is to be returned in} +\item{cCRS}{\verb{[character(1)]}\cr The coordinate reference system (CRS) for the +output \code{sf} object. Can be a PROJ4 string or an EPSG code. Defaults to +\code{"ESRI:54009"} (Mollweide).} } \value{ -The boundary of the planning region +An \code{sf} object containing a single polygon feature representing the +planning boundary. } \description{ -\code{splnr_get_boundary()} allows to create an \code{sf} object of your planning region either based on specific coordinate information, or \code{rnaturalearth} inputs such as ocean data. Creating a boundary is often the first step in conservation planning and a requirement for downstream function sin \code{spatialplanr}. +This function generates a spatial boundary for the planning region as an \code{sf} +polygon object. The boundary can be defined in several ways: +\enumerate{ +\item A simple rectangular bounding box using numeric coordinates. +\item A global boundary spanning the entire world. +\item A complex shape based on marine ecoregions from \code{rnaturalearth}. +} +} +\details{ +A planning region boundary is the foundational first step for most spatial +conservation planning exercises. All subsequent analyses and data preparation +steps within the \code{spatialplanr} package rely on a defined boundary. The +coordinate reference system (CRS) of the returned object is projected by +default (Mollweide), which is suitable for equal-area calculations. } \examples{ -Bndry <- splnr_get_boundary(Limits = "North Atlantic Ocean", Type = "Ocean") -Bndry <- splnr_get_boundary(Limits = "Global") -Bndry <- splnr_get_boundary(Limits = c("xmin" = 150, "xmax" = 170, "ymin" = -40, "ymax" = -20)) +\dontrun{ +# Example 1: Create a boundary from an ocean name. +# This fetches polygon data for the specified ocean. +bndry_ocean <- splnr_get_boundary(Limits = "North Atlantic Ocean", Type = "Ocean") +plot(bndry_ocean) + +# Example 2: Create a global boundary. +bndry_global <- splnr_get_boundary(Limits = "Global") +plot(bndry_global) + +# Example 3: Create a boundary from a numeric bounding box. +bndry_coords <- splnr_get_boundary( + Limits = c("xmin" = 150, "xmax" = 170, "ymin" = -40, "ymax" = -20) +) +plot(bndry_coords) +} } +\concept{planning_region} diff --git a/man/splnr_get_distCoast.Rd b/man/splnr_get_distCoast.Rd index 3bcc6d4c..f4fce317 100644 --- a/man/splnr_get_distCoast.Rd +++ b/man/splnr_get_distCoast.Rd @@ -2,47 +2,68 @@ % Please edit documentation in R/splnr_get_distCoast.R \name{splnr_get_distCoast} \alias{splnr_get_distCoast} -\title{Function to compute distances to nearest coastline for each centroid of each planning unit in the 'sf' object provided.} +\title{Calculate Distance to Coastline} \usage{ -splnr_get_distCoast(dat_sf, custom_coast = NULL, res = NULL) +splnr_get_distCoast(dat_sf, custom_coast = NULL, res = "medium") } \arguments{ -\item{dat_sf}{An sf object.} +\item{dat_sf}{\verb{[sf]} \cr An \code{sf} object containing polygon or point features +representing the planning units. Must have a valid CRS.} -\item{custom_coast}{An sf coastline object (optional)} +\item{custom_coast}{\verb{[sf]} \cr An optional \code{sf} object representing a +custom coastline. If \code{NULL} (the default), the coastline is downloaded +from \code{rnaturalearth}.} -\item{res}{Allow user to choose resolution (\code{small}, \code{medium}, \code{large}) of \code{rnaturalearth} data used for coastline.} +\item{res}{\verb{[character(1)]} \cr The resolution of the \code{rnaturalearth} +coastline to use. Options are \code{"small"}, \code{"medium"} (default), or +\code{"large"}. This parameter is ignored if \code{custom_coast} is provided.} } \value{ -An \code{sf} object with distances to the nearest coast +An \code{sf} object identical to \code{dat_sf} but with an added column +\code{coastDistance_km} representing the distance to the nearest coastline in +kilometers. } \description{ -The code takes a sf object and return it updated with a new coastDistance column. -The output inherits the crs from this sf object so ensure it is in the correct projection for your needs +This function calculates the shortest distance from the centroid of each +planning unit in an \code{sf} object to the nearest coastline. It can use either +a default coastline from the \code{rnaturalearth} package or a custom-provided +coastline \code{sf} object. } \details{ -Written by Kristine Buenafe -Written: March/April 2023 -Modified by Kilian Barreiro -Updated: December 2023 +The function adds a new column named \code{coastDistance_km} to the input \code{sf} +object, containing the calculated distances in kilometers. The CRS of the +input data is preserved. It is crucial to ensure the input \code{sf} object has +a suitable projected CRS for accurate distance calculations. } \examples{ +\dontrun{ +# Example 1: Calculate distance to coast for a simple grid bbox <- sf::st_bbox(c(xmin = 0, ymin = 0, xmax = 3, ymax = 3)) -grid <- sf::st_make_grid(bbox, n = c(3, 3), what = "polygons") -grid <- sf::st_sf(geometry = grid) \%>\% - sf::st_set_crs("EPSG:4326") -splnr_get_distCoast(grid) +grid <- sf::st_as_sf(sf::st_make_grid(bbox, n = c(3, 3))) +grid_with_dist <- splnr_get_distCoast(grid) +plot(grid_with_dist["coastDistance_km"]) -cCRS <- "ESRI:54009" - -Bndry <- splnr_get_boundary(Limits = "Coral Sea", - Type = "Oceans", - cCRS = cCRS) +# Example 2: Using a specific resolution for the coastline +# Note: Requires the 'dat_sf' object to be created first, e.g., using +# splnr_get_planning_units() +if (exists("dat_sf")) { + dat_sf_dist <- splnr_get_distCoast(dat_sf, res = "large") + summary(dat_sf_dist$coastDistance_km) +} +# Example 3: Using a custom coastline +# First, create a custom coastline (e.g., from a country polygon) landmass <- rnaturalearth::ne_countries( scale = "medium", returnclass = "sf" -) \%>\% - sf::st_transform(cCRS) +) +if (exists("dat_sf") && exists("landmass")) { + # Transform landmass to the same CRS as the planning units + landmass_proj <- sf::st_transform(landmass, sf::st_crs(dat_sf)) + dat_sf_custom_coast <- splnr_get_distCoast(dat_sf, custom_coast = landmass_proj) + summary(dat_sf_custom_coast$coastDistance_km) +} +} } +\concept{cost_features} diff --git a/man/splnr_get_featureRep.Rd b/man/splnr_get_featureRep.Rd index 90dd70eb..19b80d23 100644 --- a/man/splnr_get_featureRep.Rd +++ b/man/splnr_get_featureRep.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/splnr_featureRep.R \name{splnr_get_featureRep} \alias{splnr_get_featureRep} -\title{Prepare data to plot how well targets are met} +\title{Prepare Data to Plot How Well Targets Are Met} \usage{ splnr_get_featureRep( soln, @@ -14,27 +14,97 @@ splnr_get_featureRep( ) } \arguments{ -\item{soln}{The \code{prioritizr} solution} +\item{soln}{An \code{sf} object representing the \code{prioritizr} solution, containing +a column indicating selected planning units (default: \code{solution_1}).} -\item{pDat}{The \code{prioritizr} problem} +\item{pDat}{A \code{prioritizr} problem object, as defined by \code{prioritizr::problem()}. +This object provides the original feature data and targets.} -\item{targets}{\code{data.frame}with list of features under "feature" column and their corresponding targets under "target" column} +\item{targets}{A \code{data.frame} (optional). If provided, it should contain a +\code{feature} column (character) and a \code{target} column (numeric). This is used +to override or supplement targets from \code{pDat}, especially for climate-smart +approaches where targets might be pre-adjusted. Defaults to \code{NA}.} -\item{climsmart}{logical denoting whether spatial planning was done climate-smart (and targets have to be calculated differently)} +\item{climsmart}{A logical value (\code{TRUE} or \code{FALSE}). If \code{TRUE}, special +handling for climate-smart approaches is enabled. Defaults to \code{FALSE}.} -\item{climsmartApproach}{either 0,1,2 or 3 depending on the climate-smart approach used (0 = None; 1 = Climate Priority Area; 2 = Feature; 3 = Percentile).} +\item{climsmartApproach}{An integer (0, 1, 2, or 3) indicating the type of +climate-smart approach used: +\itemize{ +\item \code{0}: No climate-smart approach. +\item \code{1}: Climate Priority Area approach (features split into CS/NCS). +\item \code{2}: Feature approach (not explicitly handled in this function's +\code{climsmart} logic, targets taken from \code{pDat} by default). +\item \code{3}: Percentile approach (features are filtered). +} +Defaults to \code{0}.} -\item{solnCol}{Name of the column with the solution} +\item{solnCol}{A character string specifying the name of the column in \code{soln} +that contains the binary solution (1 for selected, 0 for not selected). +Defaults to \code{"solution_1"}.} } \value{ -\code{tbl_df} dataframe +A \code{tibble} dataframe containing the \code{feature} names, their +\code{total_amount} (total units available), \code{absolute_held} (total units +selected), \code{relative_held} (proportion held), \code{target} (conservation target), +and \code{incidental} (TRUE if target was 0 or NA, but feature still present). } \description{ -Prepare data to plot how well targets are met +\code{splnr_get_featureRep()} calculates the representation of conservation +features within a \code{prioritizr} solution. This function determines how much +of each feature's total abundance (or area) is captured in the selected +planning units, and compares it against specified conservation targets. +It can also account for different climate-smart planning approaches. +} +\details{ +This function processes the output of a \code{prioritizr} conservation problem +(\code{soln}) and its corresponding problem definition (\code{pDat}) to provide a +summary of feature representation. It is designed to work whether or not +explicit targets are provided, and can adjust calculations based on the +climate-smart approach used. + +The function calculates: +\itemize{ +\item \code{total_amount}: The total available amount/area of each feature across all planning units. +\item \code{absolute_held}: The total amount/area of each feature captured in the +\emph{selected} planning units (where \code{solution_1} is 1). +\item \code{relative_held}: The proportion of \code{absolute_held} relative to \code{total_amount}, +indicating the percentage representation of the feature in the solution. +\item \code{target}: The conservation target for each feature (either from the +\code{pDat} problem definition or the \code{targets} dataframe). +\item \code{incidental}: A logical flag indicating if a feature's representation +was 'incidental' (i.e., its target was 0 or NA, but it was still +partially or fully captured in the solution). +} + +\strong{Climate-Smart Considerations (\code{climsmart = TRUE}):} +If \code{climsmart} is \code{TRUE}, the function adjusts its calculations based on the +\code{climsmartApproach} parameter: +\itemize{ +\item \code{climsmartApproach = 1} (Climate Priority Area): The function sums the +\code{absolute_held} and \code{total_amount} for features that were split into +\verb{_CS} (Climate-Smart) and \verb{_NCS} (Non-Climate-Smart) components. This +provides a single, aggregated representation for the original feature, +allowing comparison with its original target. +\item \code{climsmartApproach = 3} (Percentile Approach): The function directly +uses the targets provided in the \code{targets} dataframe, which are +expected to be adjusted for the percentile approach. +\item For other \code{climsmartApproach} values or if \code{climsmart} is \code{FALSE}, +targets are taken directly from the \code{prioritizr} problem's target data. +} + +The output dataframe is designed to be directly plottable by functions +like \code{splnr_plot_featureRep()}. } \examples{ -pDat <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), - features = c("Spp1", "Spp2", "Spp3"), +\dontrun{ +# Assuming 'dat_species_bin' is an existing sf object with binary species data +# and 'Cost' column. + +# Create a dummy prioritizr problem for basic demonstration +pDat_basic <- prioritizr::problem( + dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), + features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" ) \%>\% prioritizr::add_min_set_objective() \%>\% @@ -42,11 +112,62 @@ pDat <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = prioritizr::add_binary_decisions() \%>\% prioritizr::add_default_solver(verbose = FALSE) -soln <- pDat \%>\% +# Solve the problem +soln_basic <- pDat_basic \%>\% prioritizr::solve.ConservationProblem() -df <- splnr_get_featureRep( - soln = soln, - pDat = pDat +# Get feature representation for a basic (non-climate-smart) solution +df_basic_rep <- splnr_get_featureRep( + soln = soln_basic, + pDat = pDat_basic +) +print(df_basic_rep) + +# Example with Climate Priority Area (CPA) approach +# Assuming 'dat_clim' is an sf object with a 'metric' column. +# These would typically come from splnr_climate_priorityAreaApproach() +# For example purposes, we'll create some dummy data and targets. + +# Simulate CPA processed features and targets +cpa_features_sim <- dat_species_bin \%>\% + dplyr::mutate( + Spp1_CS = ifelse(Spp1 == 1 & runif(n()) < 0.5, 1, 0), + Spp1_NCS = ifelse(Spp1 == 1 & Spp1_CS == 0, 1, 0), + Spp2_CS = ifelse(Spp2 == 1 & runif(n()) < 0.6, 1, 0), + Spp2_NCS = ifelse(Spp2 == 1 & Spp2_CS == 0, 1, 0), + Spp3_CS = ifelse(Spp3 == 1 & runif(n()) < 0.7, 1, 0), + Spp3_NCS = ifelse(Spp3 == 1 & Spp3_CS == 0, 1, 0) + ) \%>\% + dplyr::select(Spp1_CS, Spp1_NCS, Spp2_CS, Spp2_NCS, Spp3_CS, Spp3_NCS, geometry) + +cpa_targets_sim <- data.frame( + feature = c("Spp1_CS", "Spp1_NCS", "Spp2_CS", "Spp2_NCS", "Spp3_CS", "Spp3_NCS"), + target = c(0.8, 0.2, 0.9, 0.1, 0.7, 0.3) # Example targets for CS/NCS parts ) + +# Create a problem with the simulated CPA features +pDat_cpa_sim <- prioritizr::problem( + cpa_features_sim \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), + features = c("Spp1_CS", "Spp1_NCS", "Spp2_CS", "Spp2_NCS", "Spp3_CS", "Spp3_NCS"), + cost_column = "Cost" +) \%>\% + prioritizr::add_min_set_objective() \%>\% + prioritizr::add_relative_targets(cpa_targets_sim$target, cpa_targets_sim$feature) \%>\% + prioritizr::add_binary_decisions() \%>\% + prioritizr::add_default_solver(verbose = FALSE) + +# Solve the CPA problem +soln_cpa_sim <- pDat_cpa_sim \%>\% + prioritizr::solve.ConservationProblem() + +# Get feature representation for CPA approach +df_cpa_rep <- splnr_get_featureRep( + soln = soln_cpa_sim, + pDat = pDat_cpa_sim, + targets = cpa_targets_sim, # Pass the original CPA targets + climsmart = TRUE, + climsmartApproach = 1 # Indicate CPA approach +) +print(df_cpa_rep) +} } diff --git a/man/splnr_get_gfw.Rd b/man/splnr_get_gfw.Rd index 85dc2cd4..c99b60d6 100644 --- a/man/splnr_get_gfw.Rd +++ b/man/splnr_get_gfw.Rd @@ -2,8 +2,7 @@ % Please edit documentation in R/splnr_get_gfw.R \name{splnr_get_gfw} \alias{splnr_get_gfw} -\title{The \code{get_gfwData} function recover the data of Global Fishing Watch and -returns it as a sf object.} +\title{Retrieve Global Fishing Watch Data} \usage{ splnr_get_gfw( region, @@ -18,54 +17,88 @@ splnr_get_gfw( ) } \arguments{ -\item{region}{Region studied (character) or a geojson shape to filter raster} +\item{region}{A character string specifying the name of the region (e.g., an EEZ name) +or a numeric ID for the region, or an \code{sf} object if \code{region_source} is set +to "USER_SHAPEFILE".} -\item{start_date}{Start date (waited format : "\%Y-\%m-\%d").} +\item{start_date}{The start date for data retrieval, expected in "\%Y-\%m-\%d" format (e.g., "2021-01-01").} -\item{end_date}{End date (waited format : "\%Y-\%m-\%d").} +\item{end_date}{The end date for data retrieval, expected in "\%Y-\%m-\%d" format (e.g., "2022-12-31").} -\item{temp_res}{Temporal resolution ("daily","monthly","yearly").} +\item{temp_res}{The desired temporal resolution for the data. Must be one of: +"DAILY", "MONTHLY", or "YEARLY".} -\item{spat_res}{Spatial resolution ("low" for 0.1 degree, "high" for 0.01 degree).} +\item{spat_res}{The desired spatial resolution for the data. Must be one of: +"LOW" (0.1 degree) or "HIGH" (0.01 degree). Defaults to "LOW".} -\item{region_source}{source of the region ('eez','mpa', 'rfmo' or 'user_json')} +\item{region_source}{The source of the region definition. Must be one of: +'EEZ', 'MPA', 'RFMO', or 'USER_SHAPEFILE'. Defaults to "EEZ".} -\item{key}{Token for GFW API (see details GlobalFishingWatch vignette).} +\item{key}{Your API token for the GFW API. If not provided, it attempts to +authenticate using \code{gfwr::gfw_auth()}. See the GlobalFishingWatch vignette +for details on obtaining a key.} -\item{cCRS}{The crs to which the sf will be returned (default = "EPSG:4326").} +\item{cCRS}{The Coordinate Reference System (CRS) to which the output \code{sf} object +will be transformed. Defaults to "EPSG:4326".} -\item{compress}{Binary operator to compress (aggregate) the data per coordinates (default = FALSE).} +\item{compress}{A logical value. If \code{TRUE}, the data will be compressed (aggregated) +by coordinates, summing fishing hours for each unique location. If \code{FALSE}, +the raw data points are returned. Defaults to \code{FALSE}.} } \value{ -An \code{sf} object with gfw data. +An \code{sf} object containing the requested GFW data. The structure of +the \code{sf} object will vary depending on the \code{compress} and \code{temp_res} +parameters. } \description{ -The possibilities offered by this function are explained in \code{vignette("GlobalFishingWatch")} +The \code{splnr_get_gfw} function retrieves Global Fishing Watch (GFW) data and +returns it as an \code{sf} (simple features) object. This function allows for +flexible data queries based on geographical region, time range, and desired +spatial and temporal resolutions. } \details{ -We have the same parameters than the \code{get_raster} function, plus \code{cCRS} -which is the crs for the sf_modification \if{html}{\out{
}} -Different possible values can be combined and are : \if{html}{\out{
}} +The possibilities offered by this function are extensively explained in +\code{vignette("GlobalFishingWatch")}. + +This function shares many parameters with the \code{get_raster} function from the +\code{gfwr} package, with the addition of \code{cCRS} for specifying the Coordinate +Reference System of the output \code{sf} object. + +Fishing activity data can be aggregated (\code{group_by}) by "FLAGANDGEARTYPE" +by default, combining flags and gear types. + +\strong{Notes:} \itemize{ -\item \verb{Time Range}, \code{Flag}, \code{Geartype}. \if{html}{\out{
}} -\strong{(A combination can be : c('Time Range','Geartype'), if you want to get} -\strong{the sum of fishing hours per date and geartype, for example you want to} -\strong{display the drifting longline fishing in a specific year)} \if{html}{\out{
}} \if{html}{\out{
}} -\strong{Notes :} \if{html}{\out{
}} +\item Currently, the function is primarily designed for data within +Exclusive Economic Zones (EEZs), but it can potentially be +extended to specific Marine Protected Areas (MPAs) or RFMOs. +\item Days specified in the \code{start_date} and \code{end_date} variables are +inclusive in the data recovery. } -\enumerate{ -\item For the moment we are limited to the EEZs of each region, but we can -potentially restrict the working area to specific MPAs. \if{html}{\out{
}} -\item Days indicated in the__ \code{start_date} \strong{and} \code{end_date} __variables are -included in the data recovery. -} - -The code takes several parameters described below and return an sf object -with gfw data aggregated or not (param compress) } \examples{ \dontrun{ -gfw_data <- splnr_get_gfw('Australia', "2021-01-01", "2022-12-31", "YEARLY", - cCRS = "ESRI:54009", compress = TRUE) +# Example: Retrieve yearly GFW data for Australia, transformed to a +# Mollweide projection (ESRI:54009) and compressed (aggregated) by location. +gfw_data <- splnr_get_gfw( + region = 'Australia', + start_date = "2021-01-01", + end_date = "2022-12-31", + temp_res = "YEARLY", + cCRS = "ESRI:54009", + compress = TRUE +) + +# Example: Retrieve monthly GFW data for a specific EEZ ID, +# keeping individual time ranges and locations. +# Note: Replace 1000 with an actual EEZ ID if needed for testing. +gfw_data_monthly <- splnr_get_gfw( + region = 1000, # Example numeric EEZ ID + start_date = "2022-01-01", + end_date = "2022-03-31", + temp_res = "MONTHLY", + region_source = "EEZ", + compress = FALSE +) } } diff --git a/man/splnr_get_kappaCorrData.Rd b/man/splnr_get_kappaCorrData.Rd index a99c9fc8..342a3714 100644 --- a/man/splnr_get_kappaCorrData.Rd +++ b/man/splnr_get_kappaCorrData.Rd @@ -2,28 +2,53 @@ % Please edit documentation in R/utils.R \name{splnr_get_kappaCorrData} \alias{splnr_get_kappaCorrData} -\title{Prepare data to plot Cohen's Kappa correlation matrix} +\title{Prepare Data to Plot Cohen's Kappa Correlation Matrix} \usage{ splnr_get_kappaCorrData(sol, name_sol) } \arguments{ -\item{sol}{List of \code{prioritizr} solutions (\code{sf} objects) with solutions having a column name \code{solution_1}} +\item{sol}{A \code{list} of \code{prioritizr} solution objects. Each element in the list +must be an \code{sf} object containing a binary column named \code{solution_1}.} -\item{name_sol}{Name tags to the different solutions} +\item{name_sol}{A character vector providing descriptive names for each +solution in the \code{sol} list. The length of this vector must match the +length of \code{sol}. These names will be used as row and column names in the +output correlation matrix.} } \value{ -\code{matrixOut} matrix +A numeric \code{matrix} (\code{matrixOut}) representing the Cohen's Kappa +correlation matrix between all pairs of solutions. Rows and columns are +named according to \code{name_sol}. } \description{ -Conservation planning often requires the comparison of the outputs of the solutions of different conservation problems. -One way to compare solutions is by correlating the solutions using Cohen's Kappa. -\code{splnr_get_kappaCorrData()} takes a list of \code{prioritizr} solutions to perform the Cohen's Kappa correlation between the solution. -The resulting correlation matrix is symmetrical along the main diagonal and contains Cohen's Kappa of pairwise correlation between the solutions. -The main diagonal should always be 1. The correlation matrix obtained from this function can be passed onto \code{\link[=splnr_plot_corrMat]{splnr_plot_corrMat()}}. +\code{splnr_get_kappaCorrData()} calculates Cohen's Kappa correlation coefficients +between a list of \code{prioritizr} conservation solutions. The output is a +symmetrical matrix suitable for visualizing pairwise agreement using a heatmap. +} +\details{ +This function is essential for assessing the similarity or divergence among +different conservation plans. It takes a list of \code{prioritizr} solution objects, +each expected to contain a binary column named \code{solution_1} (indicating +selected or unselected planning units). + +For every unique pair of solutions in the input list, it computes Cohen's Kappa +using the \code{irr::kappa2()} function. Cohen's Kappa measures the agreement +between two raters (in this case, two conservation solutions) for categorical +items, correcting for chance agreement. A Kappa value of 1 indicates perfect +agreement, 0 indicates agreement equivalent to chance, and negative values +indicate agreement worse than chance. + +The resulting matrix is symmetrical, with diagonal elements always equal to 1 +(a solution perfectly agrees with itself). This matrix can then be passed to +visualization functions like \code{splnr_plot_corrMat()} to create a correlation heatmap. } \examples{ -# 30 \% target for problem/solution 1 -dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +\dontrun{ +# Assuming 'dat_species_bin' is an existing sf object in your package. + +# Create a dummy prioritizr problem and solve it for solution 1 (30\% target). +dat_problem1 <- prioritizr::problem( + dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" ) \%>\% @@ -32,10 +57,10 @@ dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = ru prioritizr::add_binary_decisions() \%>\% prioritizr::add_default_solver(verbose = FALSE) -dat_soln <- dat_problem \%>\% +dat_soln1 <- dat_problem1 \%>\% prioritizr::solve.ConservationProblem() -# 50 \% target for problem/solution 2 +# Create another dummy prioritizr problem and solve it for solution 2 (50\% target). dat_problem2 <- prioritizr::problem( dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), @@ -50,5 +75,14 @@ dat_problem2 <- prioritizr::problem( dat_soln2 <- dat_problem2 \%>\% prioritizr::solve.ConservationProblem() -corrMat <- splnr_get_kappaCorrData(list(dat_soln, dat_soln2), name_sol = c("soln1", "soln2")) +# Calculate the Cohen's Kappa correlation matrix between the two solutions. +corrMat <- splnr_get_kappaCorrData( + sol = list(dat_soln1, dat_soln2), + name_sol = c("Solution_A_30pct", "Solution_B_50pct") +) +print(corrMat) + +# This output can then be directly passed to splnr_plot_corrMat(). +# splnr_plot_corrMat(corrMat, AxisLabels = c("Sol A (30\%)", "Sol B (50\%)")) +} } diff --git a/man/splnr_get_selFreq.Rd b/man/splnr_get_selFreq.Rd index 04a520ef..4a6e567c 100644 --- a/man/splnr_get_selFreq.Rd +++ b/man/splnr_get_selFreq.Rd @@ -2,24 +2,60 @@ % Please edit documentation in R/utils.R \name{splnr_get_selFreq} \alias{splnr_get_selFreq} -\title{Prepare data to plot Selection Frequency of planning units} +\title{Prepare Data to Plot Selection Frequency of Planning Units} \usage{ splnr_get_selFreq(solnMany, type = "portfolio") } \arguments{ -\item{solnMany}{List or portfolio of \code{prioritizr} solutions} +\item{solnMany}{A \code{list} of \code{prioritizr} solutions (if \code{type = "list"}) +or a single \code{sf} object representing a \code{prioritizr} portfolio of solutions +(if \code{type = "portfolio"}). Each individual solution must contain a +column named \code{solution_1}.} -\item{type}{Either "portfolio" (\code{sf} object) with a portfolio produced using \code{prioritizr} or "list" with a list of solutions} +\item{type}{A character string indicating the input type: \code{"portfolio"} +(for a single \code{sf} object with multiple solution columns) or \code{"list"} +(for a list of single-solution \code{sf} objects). Defaults to \code{"portfolio"}.} } \value{ -\code{selFreq} \code{sf} object containing a column with the selection frequency (sum over all solutions). +An \code{sf} object (\code{selFreq}) containing a column named \code{selFreq}. +This column is a factor representing the selection frequency (sum of +selected occurrences across all solutions) for each planning unit. } \description{ -When multiple spatial plans are generated, we are often interested in how many times a planning unit is selected across an array of solutions. This array can either be a \code{list} of the solutions of different conservation problems or generated through a \href{https://prioritizr.net/reference/portfolios.html}{portfolio approach} with \code{prioritizr}. -\code{splnr_get_selFreq()} allows you to calculate the selection frequency of each planning unit of either a \code{list} or a \code{portfolio} of solutions. The resulting \code{sf} object can be passed for visualization to the \code{spatialplanr} function \code{\link[=splnr_plot_selectionFreq]{splnr_plot_selectionFreq()}}. +\code{splnr_get_selFreq()} calculates how many times each planning unit is +selected across an array of \code{prioritizr} solutions. This "selection +frequency" can be derived from either a list of individual solutions or +a \code{prioritizr} portfolio object. +} +\details{ +Understanding selection frequency is crucial for identifying robust +conservation areas—those that are consistently chosen across multiple +planning scenarios or alternative optimal solutions. + +The function supports two types of input: +\itemize{ +\item \code{"portfolio"}: If \code{solnMany} is a single \code{sf} object representing a +portfolio of solutions (e.g., generated by \code{prioritizr::add_cuts_portfolio()}). +In this case, the function assumes columns starting with "solution_" +represent individual solutions within the portfolio. +\item \code{"list"}: If \code{solnMany} is a \code{list} where each element is an \code{sf} +object representing a single \code{prioritizr} solution (each with a +"solution_1" column). +} +For both types, the function sums the binary \code{solution} values (0 or 1) +across all solutions for each planning unit. The result is converted to a +factor to represent discrete frequency levels. + +The output \code{sf} object can then be passed to \code{splnr_plot_selectionFreq()} +for visualization as a heatmap. } \examples{ -dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +\dontrun{ +# Assuming 'dat_species_bin' is an existing sf object in your package. + +# Create a base prioritizr problem. +dat_problem <- prioritizr::problem( + dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" ) \%>\% @@ -28,15 +64,32 @@ dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = ru prioritizr::add_binary_decisions() \%>\% prioritizr::add_default_solver(verbose = FALSE) -dat_soln <- dat_problem \%>\% - prioritizr::solve.ConservationProblem() - -# create conservation problem that contains a portfolio of solutions +# --- Example 1: Using a portfolio of solutions --- +# Create a conservation problem that contains a portfolio of solutions (e.g., 5 solutions). dat_soln_portfolio <- dat_problem \%>\% prioritizr::add_cuts_portfolio(number_solutions = 5) \%>\% prioritizr::solve.ConservationProblem() -selFreq <- splnr_get_selFreq(solnMany = dat_soln_portfolio, type = "portfolio") -(splnr_plot_selectionFreq(selFreq)) +# Calculate selection frequency from the portfolio. +selFreq_portfolio <- splnr_get_selFreq(solnMany = dat_soln_portfolio, type = "portfolio") +print(head(selFreq_portfolio)) +# You can then plot this: splnr_plot_selectionFreq(selFreq_portfolio) +# --- Example 2: Using a list of individual solutions --- +# Solve the problem multiple times to get different solutions (e.g., by randomizing costs) +dat_soln_list <- list( + dat_problem \%>\% prioritizr::solve.ConservationProblem(), + dat_problem \%>\% + dplyr::mutate(Cost = runif(n = dim(.)[[1]])) \%>\% # Vary cost for a different solution + prioritizr::solve.ConservationProblem(), + dat_problem \%>\% + dplyr::mutate(Cost = runif(n = dim(.)[[1]])) \%>\% # Another different solution + prioritizr::solve.ConservationProblem() +) + +# Calculate selection frequency from the list of solutions. +selFreq_list <- splnr_get_selFreq(solnMany = dat_soln_list, type = "list") +print(head(selFreq_list)) +# You can then plot this: splnr_plot_selectionFreq(selFreq_list) +} } diff --git a/man/splnr_gg_add.Rd b/man/splnr_gg_add.Rd index c0fb2ca7..e60a2f8d 100644 --- a/man/splnr_gg_add.Rd +++ b/man/splnr_gg_add.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/splnr_gg_add.R \name{splnr_gg_add} \alias{splnr_gg_add} -\title{Add-ons for plotting} +\title{Add-ons for Plotting \code{spatialplanr} Maps} \usage{ splnr_gg_add( PUs = NULL, @@ -29,70 +29,112 @@ splnr_gg_add( ) } \arguments{ -\item{PUs}{Planning Units as an \code{sf} object} +\item{PUs}{An \code{sf} object representing planning units. If provided, their +outlines will be drawn. Defaults to \code{NULL}.} -\item{colorPUs}{A color value for the outline of planning units.} +\item{colorPUs}{A character string specifying the color for the outlines of the +planning units. Defaults to \code{"grey80"}.} -\item{Bndry}{The planning region boundaries as an \code{sf} object} +\item{Bndry}{An \code{sf} object representing the main planning region boundaries. +If provided, its outline will be drawn. Defaults to \code{NULL}.} -\item{colorBndry}{A color value for the outline of the boundary.} +\item{colorBndry}{A character string specifying the color for the outline of the +\code{Bndry} object. Defaults to \code{"black"}.} -\item{overlay}{An \code{sf} object of overlay polygon.} +\item{overlay}{An \code{sf} object to be plotted as a general overlay. Defaults to \code{NULL}.} -\item{colorOverlay}{A color value for overlay.} +\item{colorOverlay}{A character string specifying the color for \code{overlay}. +Defaults to \code{"grey20"}.} -\item{overlay2}{An \code{sf} object of overlay polygon.} +\item{overlay2}{An \code{sf} object for a second general overlay. Defaults to \code{NULL}.} -\item{colorOverlay2}{A color value for overlay.} +\item{colorOverlay2}{A character string specifying the color for \code{overlay2}. +Defaults to \code{"grey30"}.} -\item{overlay3}{An \code{sf} object of overlay polygon.} +\item{overlay3}{An \code{sf} object for a third general overlay. Defaults to \code{NULL}.} -\item{colorOverlay3}{A color value for overlay.} +\item{colorOverlay3}{A character string specifying the color for \code{overlay3}. +Defaults to \code{"grey40"}.} -\item{contours}{An \code{sf} object of contours that are important to visualise -(e.g. outline of sea mounts, ridges; can be produced with -terra::as.contour()); up to 6 different contours possible.} +\item{contours}{An \code{sf} object containing contour lines (e.g., bathymetry or +seamount outlines). It is expected to have a \code{Category} column for differentiating +lines. Up to 6 categories are supported. Defaults to \code{NULL}.} -\item{colorConts}{A color value for contours.} +\item{colorConts}{A character string specifying the color for the contour lines. +Defaults to \code{"black"}.} -\item{cropOverlay}{An \code{sf} object with the boundary box used for cropping the -overlay object.} +\item{cropOverlay}{An \code{sf} object. Its bounding box will be used to set the +\code{xlim} and \code{ylim} of the \code{ggplot2::coord_sf} layer, effectively cropping the view. +Defaults to \code{NULL}.} -\item{lockIn}{An \code{sf} object with binary data of locked in areas in -the prioritisation (e.g. MPAs).} +\item{lockIn}{An \code{sf} object representing 'locked-in' areas (e.g., existing +Marine Protected Areas) that are fixed in a conservation prioritization. +Defaults to \code{NULL}.} -\item{typeLockIn}{Either "Full" or "Contours"; "Full" maps the locked in areas on -top of the planning units; "Contours" draws the outline of the locked in -areas.} +\item{typeLockIn}{A character string specifying how \code{lockIn} areas should be +plotted. Can be \code{"Full"} (fills the areas with \code{colorLockIn}) or \code{"Contours"} +(draws only the outlines of the areas). Defaults to \code{"Full"}.} -\item{nameLockIn}{column of data frame that contains binary information of -the locked in areas to plot} +\item{nameLockIn}{A character string specifying the column name in the \code{lockIn} +data frame that contains binary (0/1 or TRUE/FALSE) information indicating +locked-in status. Required if \code{lockIn} is not \code{NULL}.} -\item{alphaLockIn}{A value (0-1) for the opacity of the locked in areas when -plotted on top of other plots.} +\item{alphaLockIn}{A numeric value (0 to 1) for the opacity of the \code{lockIn} +areas when \code{typeLockIn} is \code{"Full"}. Defaults to \code{0.5}.} -\item{colorLockIn}{A color value for the locked in areas.} +\item{colorLockIn}{A character string specifying the color for the \code{lockIn} areas. +Defaults to \code{"black"}.} -\item{legendLockIn}{A character value for the title of the legend of the locked in -areas. Can be empty ("").} +\item{legendLockIn}{A character string for the title of the \code{lockIn} legend. +Can be an empty string \code{""} to suppress the title. Defaults to \code{""}.} -\item{labelLockIn}{The legend label of the locked in area (e.g. MPAs)} +\item{labelLockIn}{A character string for the legend label of the \code{lockIn} areas +(e.g., "MPAs"). Defaults to \code{"MPAs"}.} -\item{ggtheme}{The theme applied to the plot. Can either be NA (default -ggplot), "Default" (default spatialplanr: theme_bw() and some basic theme -settings) or a user-defined list of theme properties.} +\item{ggtheme}{The \code{ggplot2} theme to apply. Can be: +\itemize{ +\item \code{NA} or \code{FALSE}: No theme is applied, using \code{ggplot2} defaults. +\item \code{"Default"}: Applies a \code{spatialplanr} default theme (\code{theme_bw()} +with custom text/axis settings). +\item A \code{list} of \code{ggplot2::theme()} properties for custom styling. +} +Defaults to \code{"Default"}.} } \value{ -A ggplot object of the plot +A \code{list} of \code{ggplot2} layers and theme elements that can be added to +an existing \code{ggplot} object using \code{+}. } \description{ -This function allows to customise plots in a simple and reproducible way, by -giving the option for several inputs that can be included in maps produced -with the other functions of this package.It can be combined with the -\code{spatialplanr} spatial plotting functions. +This function allows users to customize existing \code{ggplot2} maps, particularly +those produced by other \code{spatialplanr} spatial plotting functions. It provides +options to add various spatial layers and apply consistent theming in a +simple and reproducible manner. +} +\details{ +The \code{splnr_gg_add} function enhances \code{ggplot2} objects by layering additional +spatial data such as planning unit outlines, study area boundaries, general +overlays, geographical contours, and 'locked-in' areas (e.g., existing protected +areas in a conservation prioritization). It offers fine-grained control over +colors, opacities, and legend appearance for each added layer. + +When using \code{contours}, the input \code{sf} object is expected to have a column +named \code{Category} that defines the different contour lines to be plotted. +The function currently supports up to 6 distinct contour categories for plotting. + +The \code{ggtheme} parameter offers flexibility in plot styling. \code{"Default"} applies +a standard \code{spatialplanr} theme (\code{theme_bw()} with custom text and axis settings). +A \code{list} of \code{ggplot2::theme()} elements can be provided for full customization, +or \code{NA} (logical \code{FALSE}) to apply no default theme, allowing the user to manage +all theme elements manually. } \examples{ -dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +\dontrun{ +# Assuming 'dat_species_bin' and 'dat_PUs' are existing sf objects +# in your package, suitable for prioritisation problems and plotting. + +# Create a dummy prioritizr problem and solve it for demonstration. +dat_problem <- prioritizr::problem( + dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" ) \%>\% @@ -104,6 +146,44 @@ dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = ru dat_soln <- dat_problem \%>\% prioritizr::solve.ConservationProblem() -splnr_plot_solution(dat_soln) + +# Basic plot of the solution with default planning unit outlines and theme. +plot_basic <- splnr_plot_solution(dat_soln) + splnr_gg_add(PUs = dat_PUs, ggtheme = "Default") +print(plot_basic) + +# Example with boundary, a custom overlay, and locked-in areas shown as contours. +# For this example, let's create dummy `bndry_sf` and `locked_in_sf` based on `dat_PUs` +# In a real scenario, these would be loaded from your package or data. +bndry_sf <- sf::st_union(dat_PUs) \%>\% sf::st_as_sf() +locked_in_sf <- dat_PUs[1:100, ] \%>\% dplyr::mutate(is_mpa = 1) + +plot_custom <- splnr_plot_solution(dat_soln) + + splnr_gg_add( + PUs = dat_PUs, + Bndry = bndry_sf, + colorBndry = "darkblue", + overlay = bndry_sf, # Using boundary as an example overlay + colorOverlay = "lightblue", + alphaOverlay = 0.3, + lockIn = locked_in_sf, + typeLockIn = "Contours", + nameLockIn = "is_mpa", + colorLockIn = "darkred", + labelLockIn = "Existing MPAs", + ggtheme = "Default" + ) +print(plot_custom) + +# Example with custom ggplot2 theme settings (as a list) +custom_theme_list <- list( + ggplot2::theme_classic(), + ggplot2::theme( + plot.background = ggplot2::element_rect(fill = "lightyellow"), + legend.position = "top" + ) +) +plot_with_custom_theme <- splnr_plot_solution(dat_soln) + + splnr_gg_add(PUs = dat_PUs, ggtheme = custom_theme_list) +print(plot_with_custom_theme) +} } diff --git a/man/splnr_match_names.Rd b/man/splnr_match_names.Rd index dea1a52d..50b107a6 100644 --- a/man/splnr_match_names.Rd +++ b/man/splnr_match_names.Rd @@ -2,25 +2,43 @@ % Please edit documentation in R/utils.R \name{splnr_match_names} \alias{splnr_match_names} -\title{Substitute numbers for all_names in regionalisations} +\title{Substitute Numbers for Names in Regionalizations} \usage{ splnr_match_names(dat, nam) } \arguments{ -\item{dat}{\code{sf} data frame with one column of numeric/integer corresponding to \code{nam}} +\item{dat}{An \code{sf} data frame with a single non-geometry column containing +numeric or integer values that correspond to the names in \code{nam}.} -\item{nam}{Named character vector of names corresponding to column of dat to recode} +\item{nam}{A named character vector. The \emph{names} of this vector should be +the numeric/integer values found in \code{dat}'s column, and the \emph{values} of +this vector should be the desired character names for substitution.} } \value{ -An \code{sf} dataframe with numeric regionalisations substituted for category names +An \code{sf} dataframe where the numeric/integer values in the relevant +column have been substituted with the corresponding character names from \code{nam}. } \description{ -Many regionalisations have numeric values in the shape files that correspond -to a vector of names. Here we provide a function to quickly replace the -numbers with names. +\code{splnr_match_names()} replaces numeric or integer values in a spatial +(sf) dataframe's column with corresponding character names, typically used +for regionalization data. +} +\details{ +This function is designed for scenarios where spatial data contains numeric +identifiers for regions, and you have a mapping (a named character vector) +to convert these IDs into more descriptive names. It assumes that the \code{sf} +dataframe (\code{dat}) has only one non-geometry column that needs recoding. + +The function directly applies the mapping from the \code{nam} vector to the +specified column. The names of the \code{nam} vector should correspond to the +numeric/integer values in the \code{dat} column, and the values of \code{nam} will +be the new character names. } \examples{ -dat <- dat_region -nam <- c("Region1" = "SE Aust", "Region2" = "Tas", "Region3" = "NE Aust") -df <- splnr_match_names(dat, nam) +# Define the named character vector for mapping. +region_names <- c("Region1" = "SE Aust", "Region2" = "Tas", "Region3" = "NE Aust") + +# Apply the function to substitute numeric codes with names. +df_named_regions <- splnr_match_names(dat = dat_region, nam = region_names) +print(df_named_regions) } diff --git a/man/splnr_plot.Rd b/man/splnr_plot.Rd index 0ede1af4..ecb802ac 100644 --- a/man/splnr_plot.Rd +++ b/man/splnr_plot.Rd @@ -1,73 +1,197 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/splnr_plot.R +% Please edit documentation in R/splnr_plot.R, R/splnr_plotting.R \name{splnr_plot} \alias{splnr_plot} -\title{Function to plot data.} +\title{Plot Spatial Data} \usage{ splnr_plot( df, - col_names = NULL, + colNames = NULL, paletteName = "YlGnBu", colourVals = c("#c6dbef", "#3182bd"), - plot_title = "", - legend_title = NULL, - legend_labels = NULL + plotTitle = "", + legendTitle = NULL, + legendLabels = NULL +) + +splnr_plot( + df, + colNames = NULL, + paletteName = "YlGnBu", + colourVals = c("#c6dbef", "#3182bd"), + plotTitle = "", + legendTitle = NULL, + legendLabels = NULL ) } \arguments{ -\item{df}{The dataframe containing the data to be plotted. It must include a geometry column to be used with geom_sf.} +\item{df}{The input dataframe containing the data to be plotted. This must be +an \code{sf} object and include a geometry column.} -\item{col_names}{A list of column names to include in the plot. If specified, only these columns will be used to colour the plot.} +\item{colNames}{A character vector of column names from \code{df} to be used for +coloring the plot. If \code{NULL} (default), only the planning unit outlines are plotted. +If a single column is specified, it checks for binary, logical, or continuous data. +If multiple columns are specified, it sums the values across these columns to create +a "FeatureSum" for plotting.} -\item{paletteName}{The name of the colour palette to use for filling. Default is "YlGnBu".} +\item{paletteName}{A character string specifying the name of the \code{RColorBrewer} +palette to use for filling continuous data. Defaults to \code{"YlGnBu"}.} -\item{colourVals}{The colour values to use if col_names is specified and the data is binary.} +\item{colourVals}{A character vector of two color values to use for binary +(0/1) or logical (FALSE/TRUE) data. The first color is for '0' or 'FALSE' +(absence), and the second is for '1' or 'TRUE' (presence). +Defaults to \code{c("#c6dbef", "#3182bd")}.} -\item{plot_title}{The title of the plot.} +\item{plotTitle}{A character string for the subtitle of the plot. +Defaults to \code{""} (no subtitle).} -\item{legend_title}{The title of the legend.} +\item{legendTitle}{A character string for the title of the legend. If \code{NULL}, +a default title will be used based on the data type.} -\item{legend_labels}{A vector of strings containing the labels to use for legend values.} +\item{legendLabels}{A character vector of strings to use for the legend labels, +particularly useful for binary or logical data (e.g., \code{c("Absent", "Present")}). +If \code{NULL}, default labels are used for binary/logical plots.} } \value{ -A ggplot object. +A \code{ggplot} object representing the spatial plot. + +A \code{ggplot} object representing the spatial plot. } \description{ -(For now can replace splnr_plot_cost(), splnr_plot_binFeature(), splnr_plot_MPAs(), splnr_plot_featureNo()) +This function provides a versatile way to plot spatial data (\code{sf} objects) +within the \code{spatialplanr} package. It can visualize various data types, +including binary presence/absence, logical values, continuous data, or simply +the planning unit outlines. + +This function provides a versatile way to plot spatial data (\code{sf} objects) +within the \code{spatialplanr} package. It can visualize various data types, +including binary presence/absence, logical values, continuous data, or simply +the planning unit outlines. } \details{ -Written by Kilian Barreiro and Jason Everett -Written: February 2024 +The \code{splnr_plot} function automatically detects the type of data specified by +\code{colNames} (binary, logical, or continuous) and adjusts the plotting +aesthetics accordingly. If multiple \code{colNames} are provided, it calculates +the sum of features for each planning unit and plots this sum. If \code{colNames} +is \code{NULL}, it will simply plot the outlines of the planning units. + +This function is designed to be a flexible replacement for several plotting +functions, such as \code{splnr_plot_cost()}, \code{splnr_plot_binFeature()}, +\code{splnr_plot_MPAs()}, and \code{splnr_plot_featureNo()}, streamlining the plotting +workflow within the package. + +Written by Kilian Barreiro and Jason Everett. +Last modified: February 2024. + +The \code{splnr_plot} function automatically detects the type of data specified by +\code{colNames} (binary, logical, or continuous) and adjusts the plotting +aesthetics accordingly. If multiple \code{colNames} are provided, it calculates +the sum of features for each planning unit and plots this sum. If \code{colNames} +is \code{NULL}, it will simply plot the outlines of the planning units. + +This function is designed to be a flexible replacement for several plotting +functions, such as \code{splnr_plot_cost()}, \code{splnr_plot_binFeature()}, +\code{splnr_plot_MPAs()}, and \code{splnr_plot_featureNo()}, streamlining the plotting +workflow within the package. + +Written by Kilian Barreiro and Jason Everett. +Last modified: February 2024. } \examples{ -# Binary plot of species distribution -splnr_plot(df = dat_species_bin, - col_names = "Spp1", - legend_title = "Legend", - legend_labels = c("Absent", "Present")) - -# Logical plot of species distribution -splnr_plot(df = dat_species_bin \%>\% - dplyr::mutate(dplyr::across( - tidyselect::starts_with("Spp"), as.logical)), - col_names = "Spp1", - legend_title = "Legend", - legend_labels = c("Absent", "Present")) - -# Continuous plot of bathymetry# -splnr_plot(df = dat_bathy, - col_names = "bathymetry", - plot_title = "Bathymetry", - legend_title = "Bathymetry (m)") - -# Plot Planning Units -splnr_plot(df = dat_PUs) - -# Multi binary features -splnr_plot(df = dat_species_bin, - col_names = colnames(dat_species_bin \%>\% - sf::st_drop_geometry() \%>\% - dplyr::select( - tidyselect::starts_with("Spp"))), - legend_title = "Number of features") +\dontrun{ +# Assuming 'dat_species_bin', 'dat_bathy', and 'dat_PUs' are existing sf objects +# in your package, suitable for plotting. + +# Binary plot of species distribution for "Spp1" +plot_spp1_binary <- splnr_plot( + df = dat_species_bin, + colNames = "Spp1", + legendTitle = "Species Presence", + legendLabels = c("Absent", "Present") +) +print(plot_spp1_binary) + +# Logical plot of species distribution for "Spp1" (converted from binary) +plot_spp1_logical <- splnr_plot( + df = dat_species_bin \%>\% + dplyr::mutate(dplyr::across( + tidyselect::starts_with("Spp"), as.logical + )), + colNames = "Spp1", + legendTitle = "Species Presence", + legendLabels = c("Absent", "Present") +) +print(plot_spp1_logical) + +# Continuous plot of bathymetry +plot_bathymetry <- splnr_plot( + df = dat_bathy, + colNames = "bathymetry", + plotTitle = "Bathymetry", + legendTitle = "Bathymetry (m)" +) +print(plot_bathymetry) + +# Plot Planning Units outlines only +plot_planning_units <- splnr_plot(df = dat_PUs) +print(plot_planning_units) + +# Multi-binary features: Plotting the sum of multiple "Spp" features +plot_multi_spp_sum <- splnr_plot( + df = dat_species_bin, + colNames = colnames(dat_species_bin \%>\% + sf::st_drop_geometry() \%>\% + dplyr::select(tidyselect::starts_with("Spp"))), + legendTitle = "Number of Features" +) +print(plot_multi_spp_sum) +} +\dontrun{ +# Assuming 'dat_species_bin', 'dat_bathy', and 'dat_PUs' are existing sf objects +# in your package, suitable for plotting. + +# Binary plot of species distribution for "Spp1" +plot_spp1_binary <- splnr_plot( + df = dat_species_bin, + colNames = "Spp1", + legendTitle = "Species Presence", + legendLabels = c("Absent", "Present") +) +print(plot_spp1_binary) + +# Logical plot of species distribution for "Spp1" (converted from binary) +plot_spp1_logical <- splnr_plot( + df = dat_species_bin \%>\% + dplyr::mutate(dplyr::across( + tidyselect::starts_with("Spp"), as.logical + )), + colNames = "Spp1", + legendTitle = "Species Presence", + legendLabels = c("Absent", "Present") +) +print(plot_spp1_logical) + +# Continuous plot of bathymetry +plot_bathymetry <- splnr_plot( + df = dat_bathy, + colNames = "bathymetry", + plotTitle = "Bathymetry", + legendTitle = "Bathymetry (m)" +) +print(plot_bathymetry) + +# Plot Planning Units outlines only +plot_planning_units <- splnr_plot(df = dat_PUs) +print(plot_planning_units) + +# Multi-binary features: Plotting the sum of multiple "Spp" features +plot_multi_spp_sum <- splnr_plot( + df = dat_species_bin, + colNames = colnames(dat_species_bin \%>\% + sf::st_drop_geometry() \%>\% + dplyr::select(tidyselect::starts_with("Spp"))), + legendTitle = "Number of Features" +) +print(plot_multi_spp_sum) +} } diff --git a/man/splnr_plot_circBplot.Rd b/man/splnr_plot_circBplot.Rd index c0a43692..5d2c7b5a 100644 --- a/man/splnr_plot_circBplot.Rd +++ b/man/splnr_plot_circBplot.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/splnr_featureRep.R \name{splnr_plot_circBplot} \alias{splnr_plot_circBplot} -\title{Plot circular barplot} +\title{Plot Circular Barplot for Feature Representation} \usage{ splnr_plot_circBplot( df, @@ -15,29 +15,46 @@ splnr_plot_circBplot( ) } \arguments{ -\item{df}{data frame that should have the following column names: feature, value, group} +\item{df}{A \link[base:data.frame]{data.frame} or \link[tibble:tibble]{tibble} that +\strong{must} contain the following columns: +\itemize{ +\item \code{feature}: \link[base:character]{character} or \link[base:factor]{factor} unique identifier for each individual bar (e.g., species names). +\item \code{value}: \link[base:numeric]{numeric} the value to be plotted on the y-axis (bar height, typically percentage representation). +\item \code{group}: \link[base:character]{character} or \link[base:factor]{factor} for grouping factors (e.g., "important", "representative"). +}} -\item{legend_color}{vector list of colors; should have the group names and their corresponding colors} +\item{legend_color}{A \link[base:vector]{named vector} of colors. Names must correspond +to the unique values in the \code{group} column of \code{df}, and values are the +corresponding colors. For example: \code{c("group_name1" = "red", "group_name2" = "blue")}.} -\item{legend_list}{list of groups/legends of groups} +\item{legend_list}{A \link[base:character]{character vector} of labels for the legend. +This should match the names used in \code{legend_color} or the levels of \code{group}.} -\item{indicateTargets}{logical on whether to show where the targets were set} +\item{indicateTargets}{A \link[base:logical]{logical} value. If \code{TRUE}, horizontal +lines indicating \code{impTarget} and \code{repTarget} will be drawn on the plot.} -\item{impTarget}{target of the important features (in \%)} +\item{impTarget}{A \link[base:numeric]{numeric} value representing the target +percentage for 'important' features. Required if \code{indicateTargets} is \code{TRUE}.} -\item{repTarget}{target of the representative features (in \%)} +\item{repTarget}{A \link[base:numeric]{numeric} value representing the target +percentage for 'representative' features. Required if \code{indicateTargets} is \code{TRUE}.} -\item{colTarget}{string with a colour value for the indicator line} +\item{colTarget}{A \link[base:character]{character} string specifying the color +for the target indicator lines.} } \value{ -A ggplot object of the plot +A \link[ggplot2:ggplot]{ggplot2::ggplot} object of the circular bar plot. } \description{ -Plot circular barplot +\code{splnr_plot_circBplot()} creates a circular bar plot to visualize feature +representation, categorized by groups. It's particularly useful for +displaying how different categories of features meet certain targets in a radial layout. } \examples{ # DISCLAIMER: THIS SOLUTION IS NOT ACTUALLY RUN WITH THESE TARGETS YET +\dontrun{ + dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" @@ -55,6 +72,7 @@ s1 <- dat_soln \%>\% p1 <- dat_problem +# Assuming eval_feature_representation_summary is from prioritizr df_rep_imp <- prioritizr::eval_feature_representation_summary( p1, s1[, "solution_1"] @@ -74,7 +92,7 @@ target <- data.frame(feature = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5")) \%>\% df <- merge(df_rep_imp, target) \%>\% dplyr::select(-target) \%>\% - na.omit() \%>\% + stats::na.omit() \%>\% # Use stats::na.omit dplyr::rename(value = relative_held) \%>\% dplyr::rename(group = class) @@ -90,3 +108,4 @@ legends <- c("Important", "Representative") impTarget = 50, repTarget = 30 )) } +} diff --git a/man/splnr_plot_climData.Rd b/man/splnr_plot_climData.Rd index 689b5610..d750e151 100644 --- a/man/splnr_plot_climData.Rd +++ b/man/splnr_plot_climData.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/splnr_plotting_climate.R \name{splnr_plot_climData} \alias{splnr_plot_climData} -\title{Plot climate data} +\title{Plot Climate Metric Data} \usage{ splnr_plot_climData( df, @@ -13,22 +13,62 @@ splnr_plot_climData( ) } \arguments{ -\item{df}{An \code{sf} object with climate metric information with} +\item{df}{An \code{sf} object containing the climate metric information. It must +have a geometry column.} -\item{colInterest}{column of data frame that contains the metric informatin} +\item{colInterest}{A character string specifying the name of the column in \code{df} +that contains the climate metric data to be plotted.} -\item{colorMap}{A character string indicating the color map to use (see https://ggplot2.tidyverse.org/reference/scale_viridis.html for all options)} +\item{colorMap}{A character string indicating the \code{viridis} color map to use +(e.g., "A", "B", "C", "D", "E"). See +\url{https://ggplot2.tidyverse.org/reference/scale_viridis.html} for all options. +Defaults to \code{"C"}.} -\item{plotTitle}{A character value for the title of the plot. Can be empty ("").} +\item{plotTitle}{A character string for the subtitle of the plot. +Defaults to \code{" "} (a single space, effectively no subtitle).} -\item{legendTitle}{A character value for the title of the legend. Can be empty ("").} +\item{legendTitle}{A character string for the title of the legend. +Defaults to \code{"Climate metric"}.} } \value{ -A ggplot object of the plot +A \code{ggplot} object representing the spatial plot of the climate metric. } \description{ -Plot climate data +The \code{splnr_plot_climData()} function creates a spatial plot of climate metric +information from an \code{sf} object. It provides a customizable visualization +using \code{ggplot2} and \code{viridis} color palettes. +} +\details{ +This function is designed to visualize spatial data that contains a specific +climate metric. It expects an \code{sf} object (\code{df}) with a geometry column and +the climate metric data in a column specified by \code{colInterest}. The plot uses +a continuous color scale (viridis) to represent the metric values across the +planning units. + +This function can be easily integrated into a larger plotting workflow or +used independently to inspect climate data distributions. } \examples{ -splnr_plot_climData(df = dat_clim, colInterest = "metric") +\dontrun{ +# Assuming 'dat_clim' is an existing sf object in your package +# with a column named "metric" or another relevant climate metric. + +# Example: Plot climate data using "metric" column +plot_climate_metric <- splnr_plot_climData( + df = dat_clim, + colInterest = "metric", + plotTitle = "Annual Climate Warming", + legendTitle = "Warming (°C/year)" +) +print(plot_climate_metric) + +# Example with a different color map +plot_climate_alt_cmap <- splnr_plot_climData( + df = dat_clim, + colInterest = "metric", + colorMap = "D", # Using 'D' for a different viridis palette + plotTitle = "Climate Metric (Alternative Colors)" +) +print(plot_climate_alt_cmap) +} } diff --git a/man/splnr_plot_climKernelDensity.Rd b/man/splnr_plot_climKernelDensity.Rd index 621e15c9..b3194920 100644 --- a/man/splnr_plot_climKernelDensity.Rd +++ b/man/splnr_plot_climKernelDensity.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/splnr_plotting_climate.R \name{splnr_plot_climKernelDensity} \alias{splnr_plot_climKernelDensity} -\title{Kernel Density Plots for climate-smart spatial plans} +\title{Kernel Density Plots for Climate-Smart Spatial Plans} \usage{ splnr_plot_climKernelDensity( soln, @@ -14,25 +14,60 @@ splnr_plot_climKernelDensity( ) } \arguments{ -\item{soln}{For type "Publication": A list of \code{prioirtizr} solutions (e.g. solution_list = list(s1, s2)) containing a "metric" column containing the used climate metric information; For type "App": needs to be a prioritizr solution} +\item{soln}{For \code{type = "Normal"}: A \code{list} of \code{prioritizr} solution objects +(e.g., \code{list(s1, s2)}). Each solution must contain a \code{metric} column and +a \code{solution_1} column. +For \code{type = "Basic"}: A single \code{prioritizr} solution \code{sf} object.} -\item{names}{A list of names of the solutions (names = c("Input 1", "Input 2"))} +\item{names}{A character vector of names corresponding to each solution in +\code{soln} when \code{type = "Normal"}. Not used for \code{type = "Basic"}. +Defaults to \code{NA}.} -\item{type}{The plotting style of the kernel density plots. Either "Publication" which gives axis information etc., or "App" which condenses the information in the plot to simplify it for stakeholders.} +\item{type}{A character string specifying the plotting style. Must be either +\code{"Normal"} or \code{"Basic"}. Defaults to \code{"Normal"}.} -\item{colorMap}{A character string indicating the color map to use (see https://ggplot2.tidyverse.org/reference/scale_viridis.html for all options)} +\item{colorMap}{A character string indicating the \code{viridis} color map to use +(e.g., "A", "B", "C", "D", "E"). See +\url{https://ggplot2.tidyverse.org/reference/scale_viridis.html} for all options. +Defaults to \code{"C"}.} -\item{legendTitle}{A character value for the title of the legend. Can be empty ("").} +\item{legendTitle}{A character string or \code{expression} for the title of the legend. +Defaults to \code{expression(" \\u00B0C y"^"-1" * "")}, representing "°C year⁻¹".} -\item{xAxisLab}{A characted value for the x Axis label depending on the climate metric input} +\item{xAxisLab}{A character string or \code{expression} for the x-axis label, +depending on the climate metric input. Defaults to +\code{expression("Climate warming ( \\u00B0C y"^"-1" * ")")}.} } \value{ -A ggplot object of the plot +A \code{ggplot} object representing the kernel density plot. } \description{ -Kernel Density Plots for climate-smart spatial plans +\code{splnr_plot_climKernelDensity()} generates kernel density plots for +climate-smart spatial plans, offering two distinct plotting styles: +"Normal" (for publication-quality comparison of multiple solutions) and +"Basic" (for simplified visualization for stakeholders). +} +\details{ +This wrapper function intelligently dispatches to either +\code{splnr_plot_climKernelDensity_Fancy()} (for \code{type = "Normal"}) or +\code{splnr_plot_climKernelDensity_Basic()} (for \code{type = "Basic"}) based on the +\code{type} parameter. + +The "Normal" (Fancy) style is suitable for detailed comparisons, +accommodating a list of solutions and custom axis labels, while the "Basic" +style is streamlined for clarity and quick interpretation, ideal for +stakeholder engagement. + +Both underlying functions require a \code{prioritizr} solution containing a +\code{metric} column with climate metric information and a \code{solution_1} column +indicating selected planning units. } \examples{ +\dontrun{ +# Assuming 'dat_species_bin' and 'dat_clim' are existing sf objects +# in your package. + +# Prepare data for a climate-priority area approach (CPA) target <- dat_species_bin \%>\% sf::st_drop_geometry() \%>\% colnames() \%>\% @@ -48,15 +83,18 @@ CPA <- splnr_climate_priorityAreaApproach( refugiaTarget = 1 ) +# Join climate metric to features for the problem out_sf <- CPA$Features \%>\% - dplyr::mutate(Cost_None = rep(1, 780)) \%>\% + dplyr::mutate(Cost_None = rep(1, dim(.)[[1]])) \%>\% # Ensure enough costs for PUs sf::st_join(dat_clim, join = sf::st_equals) +# Define features for the prioritizr problem usedFeatures <- out_sf \%>\% sf::st_drop_geometry() \%>\% dplyr::select(-tidyselect::starts_with("Cost_"), -"metric") \%>\% names() +# Create and solve a prioritizr problem p1 <- prioritizr::problem(out_sf, usedFeatures, "Cost_None") \%>\% prioritizr::add_min_set_objective() \%>\% prioritizr::add_relative_targets(CPA$Targets$target) \%>\% @@ -64,6 +102,32 @@ p1 <- prioritizr::problem(out_sf, usedFeatures, "Cost_None") \%>\% prioritizr::add_default_solver(verbose = FALSE) dat_solnClim <- prioritizr::solve.ConservationProblem(p1) -splnr_plot_climKernelDensity(dat_solnClim, type = "Basic") -splnr_plot_climKernelDensity(soln = list(dat_solnClim), names = c("Input 1"), type = "Normal") + +# Example 1: Basic kernel density plot +plot_basic_kde <- splnr_plot_climKernelDensity(soln = dat_solnClim, type = "Basic") +print(plot_basic_kde) + +# Example 2: Normal (Fancy) kernel density plot for a single solution +plot_normal_kde_single <- splnr_plot_climKernelDensity( + soln = list(dat_solnClim), + names = c("Solution 1"), + type = "Normal" +) +print(plot_normal_kde_single) + +# Example 3: Normal (Fancy) plot comparing two solutions (create a dummy second solution) +# For demonstration, let's create another dummy solution +dat_solnClim_2 <- dat_solnClim \%>\% + dplyr::mutate(solution_1 = sample(c(0, 1), n(), replace = TRUE)) # Randomize selection + +plot_normal_kde_multi <- splnr_plot_climKernelDensity( + soln = list(dat_solnClim, dat_solnClim_2), + names = c("Solution A", "Solution B"), + type = "Normal", + colorMap = "plasma", + legendTitle = "Climate Value", + xAxisLab = "Climate Metric (units)" +) +print(plot_normal_kde_multi) +} } diff --git a/man/splnr_plot_comparison.Rd b/man/splnr_plot_comparison.Rd index bd708014..a00a8135 100644 --- a/man/splnr_plot_comparison.Rd +++ b/man/splnr_plot_comparison.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/splnr_plotting.R \name{splnr_plot_comparison} \alias{splnr_plot_comparison} -\title{Plot solution comparison} +\title{Plot Solution Comparison} \usage{ splnr_plot_comparison( soln1, @@ -11,22 +11,43 @@ splnr_plot_comparison( ) } \arguments{ -\item{soln1}{The first \code{prioritizr} solution} +\item{soln1}{The first \code{prioritizr} solution, expected as an \code{sf} object +with a \code{solution_1} column. This serves as the baseline for comparison.} -\item{soln2}{The second \code{prioritizr} solution} +\item{soln2}{The second \code{prioritizr} solution, expected as an \code{sf} object +with a \code{solution_1} column. This is the solution being compared against \code{soln1}.} -\item{legendTitle}{A character value for the title of the legend. Can be empty ("").} +\item{legendTitle}{A character string for the title of the legend. +Defaults to \code{"Scenario 2 compared to Scenario 1:"}.} } \value{ -A ggplot object of the plot +A \code{ggplot} object representing the spatial comparison of the two solutions. } \description{ -Conservation planning often requires the comparison of the outputs of the solutions of different conservation problems. One way to compare solutions is by spatially visualising the different planning units that were selected in two separate solutions to conservation problems. -\code{splnr_plot_comparison()} allows to map the differences of two solutions in customisable way using \code{ggplot2}. This function requires two separate \code{sf} objects each containing a \code{solution_1} column indicating the binary solution (selected vs not selected) of a \code{prioritizr} conservation problem. It outputs a \code{ggobject} and can be combined with the \code{spatialplanr} function \code{\link[=splnr_gg_add]{splnr_gg_add()}}. +The \code{splnr_plot_comparison()} function spatially visualizes the differences +between two \code{prioritizr} conservation solutions. This helps in understanding +which planning units are common, added, or removed between two scenarios. +} +\details{ +Conservation planning often involves comparing outputs from different +conservation problems or scenarios. This function facilitates this comparison +by requiring two \code{sf} objects, \code{soln1} and \code{soln2}, each representing a +\code{prioritizr} solution and containing a \code{solution_1} column (binary, +indicating selected vs. not selected). + +The function categorizes planning units into "Same" (selected in both), +"Added (+)" (selected in \code{soln2} but not \code{soln1}), and "Removed (-)" +(selected in \code{soln1} but not \code{soln2}). It then plots these categories with +distinct colors for clear visualization. The output is a \code{ggplot} object +that can be combined with \code{splnr_gg_add()} for further customization. } \examples{ -# 30 \% target for problem/solution 1 -dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +\dontrun{ +# Assuming 'dat_species_bin' is an existing sf object in your package. + +# Create Problem 1 with 30\% target and solve it. +dat_problem <- prioritizr::problem( + dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" ) \%>\% @@ -38,7 +59,7 @@ dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = ru dat_soln <- dat_problem \%>\% prioritizr::solve.ConservationProblem() -# 50 \% target for problem/solution 2 +# Create Problem 2 with 50\% target and solve it. dat_problem2 <- prioritizr::problem( dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), @@ -53,5 +74,8 @@ dat_problem2 <- prioritizr::problem( dat_soln2 <- dat_problem2 \%>\% prioritizr::solve.ConservationProblem() -(splnr_plot_comparison(dat_soln, dat_soln2)) +# Plot the comparison between the two solutions. +plot_comparison <- splnr_plot_comparison(dat_soln, dat_soln2) +print(plot_comparison) +} } diff --git a/man/splnr_plot_corrMat.Rd b/man/splnr_plot_corrMat.Rd index 9f408afc..110d9b95 100644 --- a/man/splnr_plot_corrMat.Rd +++ b/man/splnr_plot_corrMat.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/splnr_plotting.R \name{splnr_plot_corrMat} \alias{splnr_plot_corrMat} -\title{Plot correlation matrices} +\title{Plot Correlation Matrices of Conservation Solutions} \usage{ splnr_plot_corrMat( x, @@ -13,26 +13,55 @@ splnr_plot_corrMat( ) } \arguments{ -\item{x}{A correlation matrix of \code{prioritizr} solutions} +\item{x}{A numeric correlation matrix of \code{prioritizr} solutions.} -\item{colourGradient}{A list of three colour values for high positive, no and high negative correlation} +\item{colourGradient}{A character vector of three color values: +\itemize{ +\item \code{colourGradient[1]}: Color for high positive correlation. +\item \code{colourGradient[2]}: Color for no correlation (midpoint). +\item \code{colourGradient[3]}: Color for high negative correlation. +} +Defaults to \code{c("#BB4444", "#FFFFFF", "#4477AA")}.} -\item{legendTitle}{A character value for the title of the legend. Can be empty ("").} +\item{legendTitle}{A character string for the title of the legend. +Defaults to \code{"Correlation \\ncoefficient"}.} -\item{AxisLabels}{A list of labels of the solutions to be correlated (Default: NULL). Length needs to match number of correlated solutions.} +\item{AxisLabels}{A character vector of labels for the x and y axes of the +correlation matrix, representing the names of the correlated solutions. +If \code{NULL} (default), the column names of \code{x} will be used. The length of +this vector must match the number of rows/columns in \code{x}.} -\item{plotTitle}{A character value for the title of the plot. Can be empty ("").} +\item{plotTitle}{A character string for the title of the plot. Defaults to \code{""}.} } \value{ -A ggplot object of the plot +A \code{ggplot} object representing the correlation matrix plot. } \description{ -Conservation planning often requires the comparison of the outputs of the solutions of different conservation problems. -One way to compare solutions is by correlating the solutions using Cohen's Kappa. \code{splnr_plot_corrMat()} allows to visualize the correlation matrix of the different solutions (for example produced with the \code{spatialplanr} function \code{\link[=splnr_get_kappaCorrData]{splnr_get_kappaCorrData()}}). +The \code{splnr_plot_corrMat()} function visualizes a correlation matrix of +\code{prioritizr} conservation solutions, typically computed using Cohen's Kappa. +This helps in understanding the agreement or disagreement between different +spatial plans. +} +\details{ +Conservation planning often involves comparing the outputs of various +conservation problems. One effective method for this is correlating solutions +using metrics like Cohen's Kappa. This function takes a correlation matrix +(e.g., produced by the \code{spatialplanr} function \code{splnr_get_kappaCorrData()}) +and generates a heatmap visualization using \code{ggcorrplot}. + +The plot highlights positive, negative, and no correlation using a color +gradient, and labels the correlation coefficients directly on the plot. +The output is a \code{ggplot} object that can be combined with the \code{spatialplanr} +function \code{splnr_gg_add()} for further customization, though its primary use +is for standalone correlation visualization. } \examples{ -# 30 \% target for problem/solution 1 -dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +\dontrun{ +# Assuming 'dat_species_bin' is an existing sf object in your package. + +# Create Problem 1 (30\% target) and solve it. +dat_problem <- prioritizr::problem( + dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" ) \%>\% @@ -44,7 +73,7 @@ dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = ru dat_soln <- dat_problem \%>\% prioritizr::solve.ConservationProblem() -# 50 \% target for problem/solution 2 +# Create Problem 2 (50\% target) and solve it. dat_problem2 <- prioritizr::problem( dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), @@ -59,7 +88,14 @@ dat_problem2 <- prioritizr::problem( dat_soln2 <- dat_problem2 \%>\% prioritizr::solve.ConservationProblem() +# Get the Kappa correlation data for the two solutions. CorrMat <- splnr_get_kappaCorrData(list(dat_soln, dat_soln2), name_sol = c("soln1", "soln2")) -(splnr_plot_corrMat(CorrMat, AxisLabels = c("Solution 1", "Solution 2"))) +# Plot the correlation matrix with custom axis labels. +plot_correlation_matrix <- splnr_plot_corrMat( + CorrMat, + AxisLabels = c("Solution 1", "Solution 2") +) +print(plot_correlation_matrix) +} } diff --git a/man/splnr_plot_cost.Rd b/man/splnr_plot_cost.Rd index a229fc6d..d7b4c0c9 100644 --- a/man/splnr_plot_cost.Rd +++ b/man/splnr_plot_cost.Rd @@ -5,17 +5,17 @@ \title{Plot cost} \usage{ splnr_plot_cost( - Cost, - Cost_name = "Cost", + cost, + costName = "Cost", legendTitle = "Cost", paletteName = "YlGnBu", plotTitle = "" ) } \arguments{ -\item{Cost}{An \code{sf} object of cost for \code{prioritizr}} +\item{cost}{An \code{sf} object of cost for \code{prioritizr}} -\item{Cost_name}{Name of the cost column} +\item{costName}{Name of the cost column} \item{legendTitle}{A character value for the title of the legend. Can be empty ("").} @@ -34,7 +34,7 @@ A ggplot object of the plot } \examples{ \dontrun{ -dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(cost = runif(n = dim(.)[[1]])), features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" ) \%>\% diff --git a/man/splnr_plot_costOverlay.Rd b/man/splnr_plot_costOverlay.Rd index b0806639..79f16997 100644 --- a/man/splnr_plot_costOverlay.Rd +++ b/man/splnr_plot_costOverlay.Rd @@ -2,35 +2,60 @@ % Please edit documentation in R/splnr_plotting.R \name{splnr_plot_costOverlay} \alias{splnr_plot_costOverlay} -\title{Plot cost overlay} +\title{Plot Cost Overlay on Solution} \usage{ splnr_plot_costOverlay( soln, - Cost = NA, - Cost_name = "Cost", + cost = NA, + costName = "Cost", legendTitle = "Cost", plotTitle = "Solution overlaid with cost" ) } \arguments{ -\item{soln}{The \code{prioritizr} solution} +\item{soln}{The \code{prioritizr} solution object, expected as an \code{sf} object, +containing at least a \code{solution_1} column.} -\item{Cost}{An \code{sf} object of cost for \code{prioritizr}.In case \code{prioritizr}solution does not contain cost, alternative cost object has to be provided here that was used to generate solution (default: NA).} +\item{cost}{An \code{sf} object containing the cost data for planning units. +If the \code{prioritizr} solution \code{soln} already contains the cost column +specified by \code{costName}, this parameter can be \code{NA} (default). Otherwise, +provide an \code{sf} object with the cost data.} -\item{Cost_name}{Name of the cost column} +\item{costName}{A character string specifying the name of the cost column +within the \code{soln} object or the \code{Cost} object. Defaults to \code{"Cost"}.} -\item{legendTitle}{A character value for the title of the legend. Can be empty ("").} +\item{legendTitle}{A character string for the title of the cost legend. +Defaults to \code{"Cost"}.} -\item{plotTitle}{A character value for the title of the plot. Can be empty ("").} +\item{plotTitle}{A character string for the subtitle of the plot. +Defaults to \code{"Solution overlaid with cost"}.} } \value{ -A ggplot object of the plot +A \code{ggplot} object representing the solution with cost overlay. } \description{ -\code{splnr_plot_costOverlay()} allows to plot the cost of each planning units of a planning region on top of the solution of a conservation problem created with \code{prioritizr} in a customisable way using \code{ggplot2}. This function requires a solution as an \code{sf} object with a column called \code{solution_1} as well as a cost column and outputs a \code{ggobject}. It can be combined with the \code{spatialplanr} function \code{\link[=splnr_gg_add]{splnr_gg_add()}}. +The \code{splnr_plot_costOverlay()} function visualizes the cost of each planning +unit overlaid on the solution of a \code{prioritizr} conservation problem. This +allows for a customizable \code{ggplot2} visualization, highlighting the costs +within selected planning units. +} +\details{ +This function requires a \code{prioritizr} solution as an \code{sf} object, which +must contain a \code{solution_1} column indicating selected (1) or unselected (0) +planning units. It also requires a cost column, either present within the +\code{soln} object or provided separately via the \code{Cost} parameter. + +The function filters the solution to show only the selected planning units +and then overlays these with a gradient representing the cost. This output +is a \code{ggplot} object that can be further customized using \code{splnr_gg_add()}. } \examples{ -dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +\dontrun{ +# Assuming 'dat_species_bin' is an existing sf object in your package. + +# Create a dummy prioritizr problem and solve it for demonstration. +dat_problem <- prioritizr::problem( + dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" ) \%>\% @@ -42,5 +67,21 @@ dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = ru dat_soln <- dat_problem \%>\% prioritizr::solve.ConservationProblem() -splnr_plot_costOverlay(soln = dat_soln) +# Plot the solution overlaid with cost +plot_cost_overlay <- splnr_plot_costOverlay(soln = dat_soln) +print(plot_cost_overlay) + +# Example: If cost is in a separate sf object (e.g., dat_PUs with a cost column) +# Create a dummy cost column in dat_PUs for this example +# Replace this with your actual cost data if it's external +dat_PUs_with_cost <- dat_PUs \%>\% dplyr::mutate(MyCost = runif(n = dim(.)[[1]])) +plot_cost_overlay_external <- splnr_plot_costOverlay( + soln = dat_soln, + cost = dat_PUs_with_cost, + costName = "MyCost", + legendTitle = "Custom Cost", + plotTitle = "Solution with External Cost" +) +print(plot_cost_overlay_external) +} } diff --git a/man/splnr_plot_featureRep.Rd b/man/splnr_plot_featureRep.Rd index 6b24aa70..6481a211 100644 --- a/man/splnr_plot_featureRep.Rd +++ b/man/splnr_plot_featureRep.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/splnr_featureRep.R \name{splnr_plot_featureRep} \alias{splnr_plot_featureRep} -\title{Plot how well targets are met} +\title{Plot Feature Representation (Target Achievement)} \usage{ splnr_plot_featureRep( df, @@ -13,35 +13,63 @@ splnr_plot_featureRep( nr = 1, showTarget = NA, plotTitle = "", + sort_by = "category", ... ) } \arguments{ -\item{df}{A \code{df} containing the target information (resulting from the splnr_get_featureRep() function)} +\item{df}{A \link[base:data.frame]{data.frame} or \link[tibble:tibble]{tibble} +containing the feature representation information. This typically +results from the \code{splnr_get_featureRep()} function and should include at +least \code{feature} and \code{relative_held} columns, and optionally \code{target} and \code{incidental}.} -\item{category}{A named data frame of feature and category for grouping the plot output} +\item{category}{A named \link[base:data.frame]{data.frame} or \link[tibble:tibble]{tibble} +that provides grouping information for features. It should contain a column +that can be matched with the \code{feature} column in \code{df} (by default, a column +named \code{feature}, or specified by \code{categoryFeatureCol}), and a column named +\code{category} for grouping the plot output. If \code{NA} (default), no categorization is applied.} -\item{categoryFeatureCol}{A character with the column containing the feature infromation to be plotted if the category data frame does not contain a column named 'feature' that can be matched with the 'df' infromation.} +\item{categoryFeatureCol}{A \link[base:character]{character} string specifying the +name of the column in the \code{category} data frame that contains the feature +information to be matched with \code{df$feature}. This is used if the \code{category} +data frame does not have a column explicitly named \code{'feature'}.} -\item{renameFeatures}{A logical on whether variable names should be used or they should be replaced with common names} +\item{renameFeatures}{A \link[base:logical]{logical} value. If \code{TRUE}, feature names +in the plot will be replaced with common names provided in \code{namesToReplace}.} -\item{namesToReplace}{A data frame containing the variable name ('nameVariable') and a common name ('nameCommon').} +\item{namesToReplace}{A \link[base:data.frame]{data.frame} containing two columns: +\code{'nameVariable'} (the original feature name) and \code{'nameCommon'} (the common name +to replace it with). Required if \code{renameFeatures} is \code{TRUE}.} -\item{nr}{Number of rows of the legend} +\item{nr}{An \link[base:integer]{integer} specifying the number of rows for the legend.} -\item{showTarget}{\code{logical} Should the targets be shown on the bar plot} +\item{showTarget}{A \link[base:logical]{logical} value. If \code{TRUE}, a transparent bar +representing the target level for each feature will be shown on the plot.} -\item{plotTitle}{A character value for the title of the plot. Can be empty ("").} +\item{plotTitle}{A \link[base:character]{character} string for the title of the plot. +Can be an empty string \code{""} (default).} -\item{...}{Other arguments passed on to \code{ggplot2::theme()}} +\item{sort_by}{A \link[base:character]{character} string specifying the column +by which to sort the features on the x-axis. Accepted values include: +\code{"category"}, \code{"feature"}, \code{"target"}, \code{"representation"} (\code{relative_held}), +or \code{"difference"} (between representation and target).} + +\item{...}{Other arguments passed on to \code{\link[ggplot2:theme]{ggplot2::theme()}} to customize the plot's theme.} } \value{ -A ggplot object of the plot +A \link[ggplot2:ggplot]{ggplot2::ggplot} object representing the feature representation bar plot. } \description{ -Plot how well targets are met +\code{splnr_plot_featureRep()} creates a bar plot to visualize the representation +of features in a conservation solution, indicating how well targets are met. +It can categorize features, rename them for clarity, and optionally display +the target levels on the plot. } \examples{ +# For a full example, ensure 'dat_species_bin', 'dat_category' are available +# (e.g., from the 'prioritizrdata' package or defined in your package's data) + + pDat <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" @@ -54,13 +82,27 @@ pDat <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = soln <- pDat \%>\% prioritizr::solve.ConservationProblem() - # including incidental species coverage -df <- splnr_get_featureRep( +df <- splnr_get_featureRep( # Assuming splnr_get_featureRep is available soln = soln, pDat = pDat ) -(splnr_plot_featureRep(df, category = dat_category)) +# Basic plot with categories and targets shown +(splnr_plot_featureRep(df, category = dat_category, showTarget = TRUE)) + +# Plot without categories, sorted by feature name +(splnr_plot_featureRep(df, showTarget = TRUE, sort_by = "feature")) +# Example with feature renaming +names_to_replace_df <- tibble::tibble( + nameVariable = c("Spp1", "Spp2"), + nameCommon = c("Species One", "Species Two") +) +(splnr_plot_featureRep(df, + category = dat_category, + renameFeatures = TRUE, + namesToReplace = names_to_replace_df, + showTarget = TRUE +)) } diff --git a/man/splnr_plot_importanceScore.Rd b/man/splnr_plot_importanceScore.Rd index f089941e..4f965be7 100644 --- a/man/splnr_plot_importanceScore.Rd +++ b/man/splnr_plot_importanceScore.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/splnr_plotting.R \name{splnr_plot_importanceScore} \alias{splnr_plot_importanceScore} -\title{Plot importance score} +\title{Plot Importance Score of Planning Units} \usage{ splnr_plot_importanceScore( soln, @@ -15,31 +15,61 @@ splnr_plot_importanceScore( ) } \arguments{ -\item{soln}{The \code{prioritizr} solution} +\item{soln}{The \code{prioritizr} solution object, expected as an \code{sf} object. +It should contain a \code{solution_1} column.} -\item{pDat}{The \code{prioritizr} problem} +\item{pDat}{The \code{prioritizr} problem object that was solved to generate \code{soln}.} -\item{method}{The method for calcualting importance scores. Can be either "Ferrier" for the Ferrier Score, which can only be used with the minimum set objective function, "RWR" for Rarity Weighted Richness Score, or "RC" for Replacement Cost which takes longer than the other approaches due to its iterative process.} +\item{method}{A character string specifying the method for calculating importance +scores. Must be one of \code{"Ferrier"}, \code{"RWR"}, or \code{"RC"}. Defaults to \code{"Ferrier"}.} -\item{plotTitle}{A character value for the title of the plot. Can be empty ("").} +\item{plotTitle}{A character string for the title of the plot. Defaults to \code{""}.} -\item{colorMap}{A character string indicating the color map to use (see https://ggplot2.tidyverse.org/reference/scale_viridis.html for all options)} +\item{colorMap}{A character string indicating the \code{viridis} color map to use +(e.g., "A", "B", "C", "D", "E"). See +\url{https://ggplot2.tidyverse.org/reference/scale_viridis.html} for all options. +Defaults to \code{"A"}.} -\item{decimals}{The number of decimals shown in the plot. Ferrier Score often requires a higher number of decimals (>4) than the other two approaches (2) for this analysis to work.} +\item{decimals}{The number of decimal places to display for the importance scores +in the legend. Ferrier Score often benefits from a higher number of decimals (>4). +Defaults to \code{4}.} -\item{legendTitle}{A character value for the title of the legend. Can be empty ("").} +\item{legendTitle}{A character string for the title of the legend. +Defaults to \code{"Importance Score"}.} } \value{ -A ggplot object of the plot +A \code{ggplot} object representing the plot of importance scores. } \description{ -\href{https://prioritizr.net/reference/importance.html}{Importance scores} are a mean to reflect the irreplaceability of a planning unit in the solution of a \code{prioirtizr} conservation problem. Based on the \code{prioritizr} package, \code{splnr_plot_importanceScore()} allows to visualize three different types of importance scores with \code{ggplot2} that should be used based on the conservation problem at hand. The \code{prioritizr} development team generally recommend using the \href{https://prioritizr.net/reference/eval_replacement_importance.html}{replacement cost score}, however this might be not be feasible for conservation problems with many planning units or features. +The \code{splnr_plot_importanceScore()} function visualizes the importance scores +(irreplaceability) of planning units from a \code{prioritizr} conservation problem +using \code{ggplot2}. It supports different methods for calculating importance scores. } \details{ -The function outputs a \code{ggobject} and can be combined with the \code{spatialplanr} function \code{\link[=splnr_gg_add]{splnr_gg_add()}}. +Importance scores quantify the irreplaceability of a planning unit in a +conservation solution. This function leverages the \code{prioritizr} package to +calculate and plot three different types of importance scores: +\itemize{ +\item \strong{"Ferrier"}: The Ferrier Score, which is applicable only with +the minimum set objective function. It often requires a higher number +of decimals (e.g., >4) for accurate representation. +\item \strong{"RWR"}: Rarity Weighted Richness Score. +\item \strong{"RC"}: Replacement Cost. This method is generally recommended +by the \code{prioritizr} development team for its robustness, but it can be +computationally intensive and take longer, especially for problems with +many planning units or features. +} + +The function outputs a \code{ggplot} object that can be combined with the +\code{spatialplanr} function \code{splnr_gg_add()} for further customization. } \examples{ -dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +\dontrun{ +# Assuming 'dat_species_bin' and 'dat_PUs' are existing sf objects in your package. + +# Create a dummy prioritizr problem and solve it for demonstration. +dat_problem <- prioritizr::problem( + dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" ) \%>\% @@ -51,5 +81,24 @@ dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = ru dat_soln <- dat_problem \%>\% prioritizr::solve.ConservationProblem() -(splnr_plot_importanceScore(soln = dat_soln, pDat = dat_problem, method = "Ferrier", decimals = 4)) +# Plot importance score using the "Ferrier" method. +plot_ferrier_importance <- splnr_plot_importanceScore( + soln = dat_soln, + pDat = dat_problem, + method = "Ferrier", + decimals = 4, + plotTitle = "Ferrier Importance Score" +) +print(plot_ferrier_importance) + +# Plot importance score using the "RWR" (Rarity Weighted Richness) method. +plot_rwr_importance <- splnr_plot_importanceScore( + soln = dat_soln, + pDat = dat_problem, + method = "RWR", + decimals = 2, + plotTitle = "Rarity Weighted Richness" +) +print(plot_rwr_importance) +} } diff --git a/man/splnr_plot_selectionFreq.Rd b/man/splnr_plot_selectionFreq.Rd index e78dc8fd..3030a676 100644 --- a/man/splnr_plot_selectionFreq.Rd +++ b/man/splnr_plot_selectionFreq.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/splnr_plotting.R \name{splnr_plot_selectionFreq} \alias{splnr_plot_selectionFreq} -\title{Plot selection frequency of a planning unit in an array of prioritisations} +\title{Plot Planning Unit Selection Frequency} \usage{ splnr_plot_selectionFreq( selFreq, @@ -12,23 +12,48 @@ splnr_plot_selectionFreq( ) } \arguments{ -\item{selFreq}{An \code{sf} object containing the selection frequency of a planning unit from an array of solutions} +\item{selFreq}{An \code{sf} object containing the selection frequency data for planning units. +This object must include a \code{selFreq} column (e.g., generated by \code{splnr_get_selFreq()}).} -\item{plotTitle}{A character value for the title of the plot. Can be empty ("").} +\item{plotTitle}{A character string for the title of the plot. Defaults to \code{""}.} -\item{paletteName}{A string (or number) for the color palette to use. Available palettes can be found at https://ggplot2.tidyverse.org/reference/scale_brewer.html.} +\item{paletteName}{A character string or numeric value specifying the name of the +\code{RColorBrewer} palette to use for the fill. Available palettes can be found at +\url{https://ggplot2.tidyverse.org/reference/scale_brewer.html}. +Defaults to \code{"Greens"}.} -\item{legendTitle}{A character value for the title of the legend. Can be empty ("").} +\item{legendTitle}{A character string for the title of the legend. +Defaults to \code{"Selection \\nFrequency"}.} } \value{ -A ggplot object of the plot +A \code{ggplot} object representing the plot of planning unit selection frequency. } \description{ -When multiple spatial plans are generated, we are often interested in how many times a planning unit is selected across an array of solutions. This array can either be made up of the solutions to different conservation problems or generated through a \href{https://prioritizr.net/reference/portfolios.html}{portfolio approach} with \code{prioritizr}. -Either way, this function requires an \code{sf} object input that contains a column (\code{selFreq}) with the selection frequency of each planning unit that can be generated with the \code{spatialplanr}function \code{splnr_get_selFreq()}. \code{splnr_plot_selectionFreq()} allows to visualize this selection frequency using \code{ggplot2}. It outputs a \code{ggobject} and can be combined with the \code{spatialplanr} function \code{splnr_gg_add()}. +The \code{splnr_plot_selectionFreq()} function visualizes the selection frequency +of planning units across an array of \code{prioritizr} solutions. This is useful +for understanding which areas are consistently selected as important for +conservation. +} +\details{ +When multiple spatial plans are generated (either from solutions to different +conservation problems or via a \code{prioritizr} portfolio approach), it's +valuable to assess the robustness of planning unit selection. This function +takes an \code{sf} object as input, which must contain a \code{selFreq} column +representing the selection frequency of each planning unit. This \code{selFreq} +column can be generated using the \code{spatialplanr} function \code{splnr_get_selFreq()}. + +The function uses \code{ggplot2} to create a spatial plot of these frequencies, +allowing for customization of the color palette, plot title, and legend title. +The output is a \code{ggplot} object that can be further enhanced by combining it +with the \code{spatialplanr} function \code{splnr_gg_add()}. } \examples{ -dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +\dontrun{ +# Assuming 'dat_species_bin' is an existing sf object in your package. + +# Create a dummy prioritizr problem. +dat_problem <- prioritizr::problem( + dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" ) \%>\% @@ -37,11 +62,16 @@ dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = ru prioritizr::add_binary_decisions() \%>\% prioritizr::add_default_solver(verbose = FALSE) -# create conservation problem that contains a portfolio of solutions +# Create a conservation problem that contains a portfolio of solutions (e.g., 5 solutions). dat_soln_portfolio <- dat_problem \%>\% prioritizr::add_cuts_portfolio(number_solutions = 5) \%>\% prioritizr::solve.ConservationProblem() -selFreq <- splnr_get_selFreq(solnMany = dat_soln_portfolio, type = "portfolio") -(splnr_plot_selectionFreq(selFreq)) +# Calculate selection frequency using splnr_get_selFreq(). +selFreq_data <- splnr_get_selFreq(solnMany = dat_soln_portfolio, type = "portfolio") + +# Plot the selection frequency. +plot_selection_frequency <- splnr_plot_selectionFreq(selFreq_data) +print(plot_selection_frequency) +} } diff --git a/man/splnr_plot_solution.Rd b/man/splnr_plot_solution.Rd index 44aed336..7ff5167c 100644 --- a/man/splnr_plot_solution.Rd +++ b/man/splnr_plot_solution.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/splnr_plotting.R \name{splnr_plot_solution} \alias{splnr_plot_solution} -\title{Plot prioritizr solution} +\title{Plot \code{prioritizr} Solution} \usage{ splnr_plot_solution( soln, @@ -15,28 +15,57 @@ splnr_plot_solution( ) } \arguments{ -\item{soln}{The \code{prioritizr} solution} +\item{soln}{The \code{prioritizr} solution object, expected as an \code{sf} object.} -\item{colorVals}{A \code{list} object of named vectors that will match the color value with the according name. "TRUE" stands for selected planning units.} +\item{colorVals}{A character vector of color values. For single-zone +problems, this should typically be two colors (for "Not selected" and +"Selected"). For multi-zone problems, the length should match the number of +zones plus one (for "Not selected").} -\item{showLegend}{A logical command on whether to show the legend of the solution (Default: TRUE).} +\item{showLegend}{A logical value indicating whether to display the legend +of the solution. Defaults to \code{TRUE}.} -\item{legendLabels}{Character values (number of zones + 1) of what the legend should be labelled.} +\item{legendLabels}{A character vector of strings to label the legend values. +Its length must match the number of levels in the solution (e.g., "Not selected", +"Selected" for single zone; "Not selected", "Zone 1", "Zone 2" for two zones).} -\item{plotTitle}{A character value for the title of the plot. Can be empty ("").} +\item{plotTitle}{A character string for the title of the plot. Can be empty (\code{""}). +Defaults to \code{"Solution"}.} -\item{legendTitle}{A character value for the title of the legend. Can be empty ("").} +\item{legendTitle}{A character string for the title of the legend. Can be empty (\code{""}). +Defaults to \code{"Planning Units"}.} -\item{zones}{A logical value, indicating whether the spatial plan contains zones or not (default = FALSE).} +\item{zones}{A logical value. Set to \code{TRUE} if the \code{prioritizr} solution +contains multiple zones (i.e., it's a multi-zone problem). Defaults to \code{FALSE}.} } \value{ -A ggplot object of the plot +A \code{ggplot} object representing the plot of the conservation solution. } \description{ -\code{splnr_plot_solution()} allows to plot the solution of a \code{prioritizr} conservation problem with our without in a customisable way using \code{ggplot2}. This function requires a solution as an \code{sf} object with a column called \code{solution_1} and outputs a \code{ggobject}. It can be combined with the \code{spatialplanr} function \code{\link[=splnr_gg_add]{splnr_gg_add()}}. +The \code{splnr_plot_solution()} function visualizes the solution of a +\code{prioritizr} conservation problem using \code{ggplot2}. It can handle +single-zone and multi-zone solutions, offering customization for colors +and legend. +} +\details{ +This function requires a \code{prioritizr} solution object, which should be an +\code{sf} object containing at least a \code{solution_1} column (for single-zone +problems) or \code{solution_1_zone1}, \code{solution_1_zone2}, etc. (for multi-zone +problems). It outputs a \code{ggplot} object, which can be further customized +by combining it with the \code{spatialplanr} function \code{splnr_gg_add()}. + +For multi-zone problems (\code{zones = TRUE}), the function sums the selected +zones for each planning unit and plots the resulting combined selection. +The \code{colorVals} and \code{legendLabels} should be provided to match the number of +selection levels (e.g., "Not selected", "Zone 1", "Zone 2", etc.). } \examples{ -dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), +\dontrun{ +# Assuming 'dat_species_bin' is an existing sf object in your package. + +# Example 1: Plotting a single-zone prioritizr solution +dat_problem <- prioritizr::problem( + dat_species_bin \%>\% dplyr::mutate(Cost = runif(n = dim(.)[[1]])), features = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), cost_column = "Cost" ) \%>\% @@ -48,17 +77,22 @@ dat_problem <- prioritizr::problem(dat_species_bin \%>\% dplyr::mutate(Cost = ru dat_soln <- dat_problem \%>\% prioritizr::solve.ConservationProblem() -splnr_plot_solution(dat_soln) -# example 2 -t2 <- matrix(NA, ncol = 2, nrow = 5) # create targets +plot_soln_single_zone <- splnr_plot_solution(dat_soln) +print(plot_soln_single_zone) + +# Example 2: Plotting a multi-zone prioritizr solution +# Create targets for two zones +t2 <- matrix(NA, ncol = 2, nrow = 5) t2[, 1] <- 0.1 t2[, 2] <- 0.05 +# Define zones for species z2 <- prioritizr::zones( "zone 1" = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5"), "zone 2" = c("Spp1", "Spp2", "Spp3", "Spp4", "Spp5") ) -# when giving sf input, we need as many cost columns as we have zones + +# Create a multi-zone problem (requires as many cost columns as zones) p2 <- prioritizr::problem( dat_species_bin \%>\% dplyr::mutate( Cost1 = runif(n = dim(.)[[1]]), @@ -74,8 +108,12 @@ p2 <- prioritizr::problem( s2 <- p2 \%>\% prioritizr::solve.ConservationProblem() -(splnr_plot_solution(s2, - zones = TRUE, colorVals = c("#c6dbef", "#3182bd", "black"), + +plot_soln_multi_zone <- splnr_plot_solution(s2, + zones = TRUE, + colorVals = c("#c6dbef", "#3182bd", "black"), # Colors for Not selected, Zone 1, Zone 2 legendLabels = c("Not selected", "Zone 1", "Zone 2") -)) +) +print(plot_soln_multi_zone) +} } diff --git a/man/splnr_replace_NAs.Rd b/man/splnr_replace_NAs.Rd index 027e2092..7cd9a62c 100644 --- a/man/splnr_replace_NAs.Rd +++ b/man/splnr_replace_NAs.Rd @@ -2,23 +2,47 @@ % Please edit documentation in R/utils.R \name{splnr_replace_NAs} \alias{splnr_replace_NAs} -\title{Remove NAs from spatial data using nearest neighbour} +\title{Remove NAs from Spatial Data Using Nearest Neighbour} \usage{ splnr_replace_NAs(df, vari) } \arguments{ -\item{df}{An \code{sf} dataframe} +\item{df}{An \code{sf} dataframe. This dataframe must contain a geometry column +and the \code{vari} column with potential NA values.} -\item{vari}{Variable to remove NAs from} +\item{vari}{A character string specifying the name of the column in \code{df} +from which NA values are to be removed and replaced. This column must +exist in \code{df}.} } \value{ -An \code{sf} object with NAs replaced with the nearest neighbour +An \code{sf} object identical to the input \code{df}, but with NA values +in the \code{vari} column replaced by values from their nearest non-NA neighbors. +If no NAs are found, the original \code{df} is returned unchanged. } \description{ -\code{splnr_replace_NAs()} allows you to replace NA values in your data with the value of the nearest neighbour. -The nearest neighbour is determined using \code{st_nearest_feature()} from the \code{sf} package. +\code{splnr_replace_NAs()} replaces missing (NA) values in a specified column +of an \code{sf} dataframe with the value from the nearest spatial neighbor. +} +\details{ +This function is useful for imputing missing data in spatial contexts. +It identifies all planning units with \code{NA} values in the \code{vari} column. +For each of these, it finds the geographically closest planning unit that +\emph{does not} have an \code{NA} value in \code{vari}, and then copies that non-missing +value. This approach leverages the spatial autocorrelation often present +in environmental and species data. + +The \code{st_nearest_feature()} function from the \code{sf} package is used for +determining the closest neighbor. } \examples{ -df <- dat_species_prob \%>\% - splnr_replace_NAs("Spp2") +\dontrun{ +# Assuming 'dat_species_prob' is an existing sf object in your package. +# For demonstration, let's artificially introduce some NAs in 'Spp2'. +df_with_na <- dat_species_prob \%>\% + dplyr::mutate(Spp2 = ifelse(runif(n()) < 0.2, NA, Spp2)) + +# Replace NAs in 'Spp2' using nearest neighbor imputation. +df_no_na <- splnr_replace_NAs(df = df_with_na, vari = "Spp2") +print(sum(is.na(df_no_na$Spp2))) # Should be 0 if successful +} } diff --git a/man/splnr_scale_01.Rd b/man/splnr_scale_01.Rd index 04b50dc5..32065824 100644 --- a/man/splnr_scale_01.Rd +++ b/man/splnr_scale_01.Rd @@ -2,23 +2,49 @@ % Please edit documentation in R/utils.R \name{splnr_scale_01} \alias{splnr_scale_01} -\title{Scale spatial layers to between 0 and 1} +\title{Scale Spatial Layers to Between 0 and 1} \usage{ splnr_scale_01(dat, col_name) } \arguments{ -\item{dat}{\code{sf} dataframe} +\item{dat}{An \code{sf} dataframe containing the column to be scaled.} -\item{col_name}{Name of the column to scale} +\item{col_name}{A character string specifying the name of the numeric column +in \code{dat} that needs to be scaled.} } \value{ -\code{sf} dataframe +An \code{sf} dataframe identical to the input \code{dat}, but with the values +in the \code{col_name} column re-scaled to be between 0 and 1. } \description{ -\code{splnr_scale_01()} allows you to re-scale your data from values that are greater than 1 to values that are between 0 and 1. +\code{splnr_scale_01()} re-scales the numeric values in a specified column of an +\code{sf} dataframe to a range between 0 and 1. This is particularly useful for +normalizing data like probabilities or costs. +} +\details{ +This function inspects the maximum value (\code{mx}) in the \code{col_name} column. +It then divides all values in that column by a \code{divi} factor to bring them +into the 0-1 range. The \code{divi} factor is determined heuristically: +\itemize{ +\item If \code{mx > 100}, \code{divi} is \code{1000}. +\item If \code{mx > 10}, \code{divi} is \code{100}. +\item If \code{mx > 1}, \code{divi} is \code{10}. +\item If \code{mx <= 1}, no division is performed (\code{divi} is \code{1}), as the data is +already within the desired range. +} + +This approach ensures that the data is scaled appropriately without +hardcoding a fixed division factor. } \examples{ -df <- dat_species_prob \%>\% - dplyr::mutate(Spp1 = Spp1 * 100) \%>\% - splnr_scale_01(col_name = "Spp1") +\dontrun{ +# Scale the 'Spp1' column. +df_scaled_spp1 <- splnr_scale_01(dat = dat_species_prob, col_name = "Spp1") +print(df_scaled_spp1) + +# Example where max is already <= 1 +df_already_scaled <- dat_species_prob \%>\% dplyr::mutate(Spp1 = Spp1 / 100) +df_no_change <- splnr_scale_01(dat = df_already_scaled, col_name = "Spp1") +print(df_no_change) # Spp1 values should remain unchanged +} } diff --git a/man/splnr_targets_byCategory.Rd b/man/splnr_targets_byCategory.Rd index 68222dc6..514bd8e3 100644 --- a/man/splnr_targets_byCategory.Rd +++ b/man/splnr_targets_byCategory.Rd @@ -2,27 +2,63 @@ % Please edit documentation in R/splnr_targets.R \name{splnr_targets_byCategory} \alias{splnr_targets_byCategory} -\title{Assign targets to all features by category} +\title{Assign Targets by Category} \usage{ splnr_targets_byCategory(dat, catTarg, catName = "Category") } \arguments{ -\item{dat}{A sf object with the features and categories} +\item{dat}{An \code{sf} object (or data frame) containing the features and their +associated categories. Each row should represent a feature (e.g., a species) +with its attributes, including the category.} -\item{catTarg}{A named character vector with categories and target} +\item{catTarg}{A named numeric vector where names are the categories +(e.g., \code{"Group1"}, \code{"Endangered"}) and values are the corresponding +conservation targets (e.g., \code{0.5}, \code{0.8}).} -\item{catName}{An optional argument for the name of the category column in dat} +\item{catName}{A character string specifying the name of the column in \code{dat} +that contains the category information. Defaults to \code{"Category"}.} } \value{ -An sf object with targets added +An \code{sf} object (or data frame) identical to the input \code{dat}, but with an +additional column named \code{target} containing the assigned conservation target +for each feature. Features whose categories are not found in \code{catTarg} will +have \code{NA} in the \code{target} column unless they already have a 'target' column. } \description{ -\code{splnr_targets_byCategory()} allows to assign targets for conservation planning based on species categories. +The \code{splnr_targets_byCategory()} function assigns conservation targets to +features (e.g., species) based on their assigned categories. This allows for +differentiated conservation goals for different groups of features. +} +\details{ +This function is useful in conservation planning when different types of +features (e.g., endangered species, common species, ecosystem types) require +distinct conservation targets. It performs a left join with a provided +named vector (\code{catTarg}) where names correspond to categories in your data +and values are the desired targets. + +The \code{dat} input should be an \code{sf} object (or data frame) that contains a +column (\code{catName}) identifying the category for each feature. } \examples{ -dat <- splnr_targets_byCategory( - dat = dat_category, +\dontrun{ +# Assuming 'dat_category' is an existing sf object in your package +# with a column named "category" and other feature data. + +# Example: Assign targets based on predefined categories +targets_by_group <- splnr_targets_byCategory( + dat = dat_category, # Assuming dat_category has a 'category' column catTarg = c("Group1" = 0.5, "Group2" = 0.2), catName = "category" ) +print(targets_by_group) + +# Example: Assign targets with a different category column name +dat_alt_cat <- data.frame(Feature = letters[1:5], Type = c("A", "B", "A", "C", "B")) +targets_by_type <- splnr_targets_byCategory( + dat = dat_alt_cat, + catTarg = c("A" = 0.7, "B" = 0.4), + catName = "Type" +) +print(targets_by_type) +} } diff --git a/man/splnr_targets_byIUCN.Rd b/man/splnr_targets_byIUCN.Rd index 3102e9d2..13acb7b5 100644 --- a/man/splnr_targets_byIUCN.Rd +++ b/man/splnr_targets_byIUCN.Rd @@ -2,26 +2,91 @@ % Please edit documentation in R/splnr_targets.R \name{splnr_targets_byIUCN} \alias{splnr_targets_byIUCN} -\title{Assign targets bu IUCN Red List categories} +\title{Assign Targets by IUCN Red List Categories} \usage{ splnr_targets_byIUCN(dat, IUCN_target, IUCN_col = "IUCN_Category") } \arguments{ -\item{dat}{A dataframe or sf object with IUCN categories} +\item{dat}{A dataframe or \code{sf} object containing species information, +including a column with IUCN categories.} -\item{IUCN_target}{Either a numeric or named numeric of targets to apply to IUCN categories} +\item{IUCN_target}{Either: +\itemize{ +\item A single numeric value (e.g., \code{0.3}) to apply this target to all +threatened IUCN categories ("EX", "EW", "CR", "EN", "VU"). +\item A named numeric vector (e.g., \code{c("EX" = 0.8, "CR" = 0.6)}) to +apply specific targets to particular IUCN categories. +}} -\item{IUCN_col}{Optional string to indicate the name of the column with the IUCN categories} +\item{IUCN_col}{A character string specifying the name of the column in \code{dat} +that contains the IUCN category information. Defaults to \code{"IUCN_Category"}.} } \value{ -dataframe or sf object +A dataframe or \code{sf} object identical to the input \code{dat}, but with an +updated or newly added \code{target} column reflecting the assigned conservation goals. } \description{ -\code{splnr_targets_byIUCN()} allows to assign targets for species used in conservation planning based on IUCN categories. Species can be extracted based on IUCN categories with the \code{spatoalplnr}function \code{splnr_get_IUCNRedList()}. -Accessing the IUCN database requires a login token from \code{rl_use_iucn()} that needs to be added to the environment using \code{Sys.setenv(IUCN_REDLIST_KEY = "[Your Token]")}. You can start by running \code{rredlist::rl_use_iucn()}. +The \code{splnr_targets_byIUCN()} function assigns conservation targets for species +based on their IUCN Red List categories. This allows for prioritizing species +at higher risk of extinction with more stringent conservation goals. +} +\details{ +This function is crucial for integrating species' extinction risk into +conservation planning. It allows you to specify targets either as a single +numeric value (applied to all 'threatened' IUCN categories) or as a named +numeric vector for specific categories. + +Species can be extracted based on IUCN categories using the \code{spatialplanr} +function \code{splnr_get_IUCNRedList()}. + +\strong{Important:} To access the IUCN database (e.g., via \code{splnr_get_IUCNRedList()}), +you need an API login token. This token, obtained from \code{rredlist::rl_use_iucn()}, +must be set as an environment variable named \code{IUCN_REDLIST_KEY} +(e.g., \code{Sys.setenv(IUCN_REDLIST_KEY = "[Your Token]")}). + +The function checks if a 'target' column already exists in \code{dat}. If not, +it creates one. If it exists, new targets are coalesced with existing ones, +allowing for sequential application or refinement of targets. + +The "threatened" IUCN categories considered for target assignment (when a +single \code{IUCN_target} is provided) are: "EX" (Extinct), "EW" (Extinct in the Wild), +"CR" (Critically Endangered), "EN" (Endangered), and "VU" (Vulnerable). } \examples{ -dat <- data.frame(IUCN_Category = c("EW", "EX", NA), target = c(0.3, 0.3, 0.3)) -IUCN_target <- c("EX" = 0.8, "EW" = 0.6) -dat <- splnr_targets_byIUCN(dat, IUCN_target) +\dontrun{ +# Example 1: Assigning specific targets to categories +# Create a dummy dataframe resembling output from splnr_get_IUCNRedList +df_species_iucn <- data.frame( + Species = c("Diomedea exulans", "Hippocampus kuda", + "Squatina squatina", "Common Dolphin"), + IUCN_Category = c("VU", "EN", "CR", "LC") +) + +iucn_specific_targets <- c("EX" = 0.9, "EW" = 0.8, "CR" = 0.75, "EN" = 0.6, "VU" = 0.5) + +df_with_iucn_targets <- splnr_targets_byIUCN( + dat = df_species_iucn, + IUCN_target = iucn_specific_targets, + IUCN_col = "IUCN_Category" +) +print(df_with_iucn_targets) + +# Example 2: Assigning a single target to all threatened categories +df_single_target <- splnr_targets_byIUCN( + dat = df_species_iucn, + IUCN_target = 0.4, # Apply 40\% target to all threatened species + IUCN_col = "IUCN_Category" +) +print(df_single_target) + +# Example 3: When 'dat' already has a 'target' column +df_pre_targets <- data.frame( + Species = c("A", "B", "C"), + IUCN_Category = c("CR", "LC", "EN"), + target = c(0.1, 0.2, 0.1) # Existing targets +) +iucn_update_targets <- c("CR" = 0.7) # Only update CR +df_updated_targets <- splnr_targets_byIUCN(df_pre_targets, iucn_update_targets) +print(df_updated_targets) +} } diff --git a/man/splnr_targets_byInverseArea.Rd b/man/splnr_targets_byInverseArea.Rd index b259985d..49203cec 100644 --- a/man/splnr_targets_byInverseArea.Rd +++ b/man/splnr_targets_byInverseArea.Rd @@ -2,24 +2,67 @@ % Please edit documentation in R/splnr_targets.R \name{splnr_targets_byInverseArea} \alias{splnr_targets_byInverseArea} -\title{Assign targets by Inverse Area} +\title{Assign Targets by Inverse Area} \usage{ splnr_targets_byInverseArea(df, target_min, target_max) } \arguments{ -\item{df}{An \code{sf} dataframe with features to calculate} +\item{df}{An \code{sf} dataframe containing the features (e.g., species distribution +data) for which to calculate inverse area targets. Each column (excluding +geometry) should represent a feature, and each row a planning unit.} -\item{target_min}{The minimum target for inverse area} +\item{target_min}{A numeric value between 0 and 1 (inclusive) specifying the +minimum target percentage. This will be the target for the most widespread feature.} -\item{target_max}{The maximum target for inverse area} +\item{target_max}{A numeric value between 0 and 1 (inclusive) specifying the +maximum target percentage. This will be the target for the rarest feature.} } \value{ -An \code{sf} dataframe with Inverse Area Targets added in \code{Target} +A \code{tibble} (data frame) with two columns: \code{Species} (or feature name) +and \code{target} (the calculated inverse area target for each feature). } \description{ -This function takes a min (\code{target_min}) and max (\code{target_max}) target range and calculates an inverse area target for each feature based on areal coverage. +This function calculates inverse area targets for each conservation feature +within an \code{sf} dataframe, based on their areal coverage. The target is set +to be inversely proportional to the feature's area, ranging between a +specified minimum (\code{target_min}) and maximum (\code{target_max}). +} +\details{ +The inverse area target approach aims to assign higher conservation targets +to features that have a smaller overall distribution or areal coverage within +the study region. This can be particularly useful for prioritizing rare or +range-restricted features. + +The calculation proceeds as follows: +\enumerate{ +\item The area of a single planning unit is determined. +\item The total area of the study region is estimated by multiplying the number +of planning units by the individual planning unit area. +\item For each feature (species), its total area across all planning units is +calculated. +\item The target for each feature is then scaled between \code{target_min} and +\code{target_max} such that features with smaller areas receive targets closer +to \code{target_max}, and features with larger areas receive targets closer +to \code{target_min}. +} + +The input \code{df} is expected to be an \code{sf} object where columns (excluding +geometry) represent different features (e.g., species presence/absence) and +rows represent planning units. } \examples{ -targets <- dat_species_prob \%>\% +\dontrun{ +# Assuming 'dat_species_prob' is an existing sf object in your package, +# representing species distribution in planning units. + +# Calculate inverse area targets with a range from 30\% to 80\%. +targets_inverse_area <- dat_species_prob \%>\% splnr_targets_byInverseArea(target_min = 0.3, target_max = 0.8) +print(targets_inverse_area) + +# Example with a different target range (e.g., 20\% to 70\%) +targets_custom_range <- dat_species_prob \%>\% + splnr_targets_byInverseArea(target_min = 0.2, target_max = 0.7) +print(targets_custom_range) +} } diff --git a/pkgdown/favicon/apple-touch-icon.png b/pkgdown/favicon/apple-touch-icon.png index 1f3f6544024cba8e30b9d1258925f6ffe55d4c92..dee267e2ee8e98467805144476d3a752fca57f59 100644 GIT binary patch literal 29912 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 bPjCG{H9M!K)QQlj00000NkvXXu0mjf_&ou9 literal 34928 zcmV*fKv2JlP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 Eg0j|7mjD0& diff --git a/pkgdown/favicon/favicon-96x96.png b/pkgdown/favicon/favicon-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..1dc72d2a10383893d95f0b2f87b3ccb224d8f8fe GIT binary patch literal 10185 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 diff --git a/pkgdown/favicon/favicon.svg b/pkgdown/favicon/favicon.svg new file mode 100644 index 00000000..54b448fc --- /dev/null +++ b/pkgdown/favicon/favicon.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/pkgdown/favicon/site.webmanifest b/pkgdown/favicon/site.webmanifest new file mode 100644 index 00000000..4ebda26b --- /dev/null +++ b/pkgdown/favicon/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file diff --git a/pkgdown/favicon/web-app-manifest-192x192.png b/pkgdown/favicon/web-app-manifest-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..b342a742f90bb23e2dfc13ce963a11efec7ace01 GIT binary patch literal 33537 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 literal 0 HcmV?d00001 diff --git a/pkgdown/favicon/web-app-manifest-512x512.png b/pkgdown/favicon/web-app-manifest-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..282cb1862ed09df8fec47a9fb7b8510d2b8c4638 GIT binary patch literal 193587 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�Z$P(5TwlK^ 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
3UAYM@> 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 literal 0 HcmV?d00001 diff --git a/tests/testthat/test-splnr_plot.R b/tests/testthat/test-splnr_plot.R index 2e3c89b5..428bff07 100644 --- a/tests/testthat/test-splnr_plot.R +++ b/tests/testthat/test-splnr_plot.R @@ -38,9 +38,9 @@ distance <- splnr_get_distCoast(dat_PUs) testthat::test_that("Correct function output", { expect_s3_class( splnr_plot(df = dat_species_bin, - col_names = "Spp1", - legend_title = "Legend", - legend_labels = c("Absent", "Present")) + colNames = "Spp1", + legendTitle = "Legend", + legendLabels = c("Absent", "Present")) , "gg" ) }) @@ -49,9 +49,9 @@ testthat::test_that("Correct function output", { testthat::test_that("Correct function output", { expect_s3_class( splnr_plot(df = dat_species_bin %>% dplyr::mutate(dplyr::across(tidyselect::starts_with("Spp"), as.logical)), - col_names = "Spp1", - legend_title = "Legend", - legend_labels = c("Absent", "Present")) + colNames = "Spp1", + legendTitle = "Legend", + legendLabels = c("Absent", "Present")) , "gg" ) }) @@ -60,9 +60,9 @@ testthat::test_that("Correct function output", { testthat::test_that("Correct function output", { expect_s3_class( splnr_plot(df = distance, - col_names = "coastDistance_km", - plot_title = "Distance to Coast", - legend_title = "Distance (km)") + colNames = "coastDistance_km", + plotTitle = "Distance to Coast", + legendTitle = "Distance (km)") , "gg" ) }) @@ -79,11 +79,11 @@ testthat::test_that("Correct function output", { testthat::test_that("Correct function output", { expect_s3_class( splnr_plot(df = dat_species_bin, - col_names = colnames(dat_species_bin %>% + colNames = colnames(dat_species_bin %>% sf::st_drop_geometry() %>% dplyr::select( tidyselect::starts_with("Spp"))), - legend_title = "Number of features") + legendTitle = "Number of features") , "gg" ) diff --git a/vignettes/ClimateSmart.R b/vignettes/ClimateSmart.R deleted file mode 100644 index 50d922bd..00000000 --- a/vignettes/ClimateSmart.R +++ /dev/null @@ -1,174 +0,0 @@ -## ----include = FALSE---------------------------------------------------------- -knitr::opts_chunk$set( -collapse = TRUE, -comment = "#>", -warning = FALSE, -cache = FALSE, -message = FALSE, -eval = TRUE, -fig.width = 9 -) - -## ----setup-------------------------------------------------------------------- -library(spatialplanr) - -## ----------------------------------------------------------------------------- -Region <- "Coral Sea" # "Australia" -Type <- "Oceans" # "EEZ" -cCRS <- "ESRI:54009" # Mollweide - -## ----------------------------------------------------------------------------- -PU_size <- 107460 # m - -## ----------------------------------------------------------------------------- -splnr_theme <- list( - ggplot2::theme_bw(), - ggplot2::theme( - legend.position = "right", - legend.direction = "vertical", - text = ggplot2::element_text(size = 9, colour = "black"), - axis.text = ggplot2::element_text(size = 9, colour = "black"), - plot.title = ggplot2::element_text(size = 9), - axis.title = ggplot2::element_blank() - ) -) - -## ----------------------------------------------------------------------------- -Bndry <- splnr_get_boundary(Limits = Region, Type = Type, cCRS = cCRS) - -landmass <- rnaturalearth::ne_countries(scale = "medium", returnclass = "sf") %>% - sf::st_transform(cCRS) - -## ----------------------------------------------------------------------------- -PUs <- spatialgridr::get_grid(boundary = Bndry, - crs = cCRS, - output = "sf_hex", - resolution = PU_size) - -## ----------------------------------------------------------------------------- -Dict <- tibble::tribble( - ~nameCommon, ~nameVariable, ~category, - "Green sea turtle", "Chelonia_mydas", "Reptiles", - "Loggerhead sea turtle", "Caretta_caretta", "Reptiles", - "Hawksbill sea turtle", "Eretmochelys_imbricata", "Reptiles", - "Olive ridley sea turtle", "Lepidochelys_olivacea", "Reptiles", - "Saltwater crocodile", "Crocodylus_porosus", "Reptiles", - "Humpback whale", "Megaptera_novaeangliae", "Mammals", - "Common Minke whale", "Balaenoptera_acutorostrata", "Mammals", - "Dugong", "Dugong_dugon", "Mammals", - "Grey nurse shark", "Carcharias_taurus", "Sharks and rays", - "Tiger shark", "Galeocerdo_cuvier", "Sharks and rays", - "Great hammerhead shark", "Sphyrna_mokarran", - "Sharks and rays", - "Giant oceanic manta ray", "Mobula_birostris", "Sharks and rays", - "Reef manta ray", "Mobula_alfredi", "Sharks and rays", - "Whitetip reef shark", "Triaenodon_obesus", "Sharks and rays", - "Red-footed booby", "Sula_sula", "Birds" -) - -## ----------------------------------------------------------------------------- -datEx_species_bin <- spDataFiltered %>% - dplyr::as_tibble() %>% - dplyr::mutate(dplyr::across( - -dplyr::any_of(c("geometry")), # Don't apply to geometry - ~ dplyr::case_when( - . >= 0.5 ~ 1, - . < 0.5 ~ 0, - is.na(.data) ~ 0 - ) - )) %>% - sf::st_as_sf() - -col_name <- spDataFiltered %>% - sf::st_drop_geometry() %>% - colnames() - -## ----------------------------------------------------------------------------- -metric_df <- CoralSeaVelocity %>% - dplyr::rename(metric = voccMag_transformed) - -## ----fig.width = 9------------------------------------------------------------ -(ggclim <- splnr_plot_climData(metric_df, "metric") + - splnr_gg_add( - Bndry = Bndry, overlay = landmass, - cropOverlay = PUs, ggtheme = splnr_theme - )) - -## ----fig.width = 9------------------------------------------------------------ -set.seed(5) - -metric_df <- CoralSeaVelocity %>% - dplyr::rename(metric = voccMag_transformed) %>% - dplyr::mutate( - metricOG = metric, - metric = ifelse(metric > 0.99, runif(., 0.85, 1.0), metric) - ) - -(ggclim <- splnr_plot_climData(metric_df, "metric") + - splnr_gg_add( - Bndry = Bndry, overlay = landmass, - cropOverlay = PUs, ggtheme = splnr_theme - )) - -## ----------------------------------------------------------------------------- -target <- datEx_species_bin %>% - sf::st_drop_geometry() %>% - colnames() %>% - data.frame() %>% - setNames(c("feature")) %>% - dplyr::mutate(target = 0.3) - - -CPA_Approach <- splnr_climate_priorityAreaApproach( - featuresDF = datEx_species_bin, - metricDF = metric_df, - targetsDF = target, - direction = -1, refugiaTarget = 1 -) - -out_sf <- CPA_Approach$Features %>% - sf::st_join( - datEx_species_bin %>% - dplyr::select( - tidyselect::starts_with("Cost_") - ), - join = sf::st_equals) %>% - sf::st_join(metric_df, join = sf::st_equals) - -targets <- CPA_Approach$Targets - -## ----------------------------------------------------------------------------- -out_sf$Cost_None <- rep(1, 397) - -usedFeatures <- out_sf %>% - sf::st_drop_geometry() %>% - dplyr::select( - -tidyselect::starts_with("Cost_"), - -tidyselect::starts_with("metric") - ) %>% - names() - -## ----------------------------------------------------------------------------- -p1 <- prioritizr::problem(out_sf, usedFeatures, "Cost_None") %>% - prioritizr::add_min_set_objective() %>% - prioritizr::add_relative_targets(targets$target) %>% - prioritizr::add_binary_decisions() %>% - prioritizr::add_default_solver(verbose = FALSE) - -dat_solnClim <- prioritizr::solve.ConservationProblem(p1) - -## ----fig.width = 9------------------------------------------------------------ -(ggSoln <- splnr_plot_solution(dat_solnClim) + - splnr_gg_add( - Bndry = Bndry, overlay = landmass, - cropOverlay = PUs, ggtheme = splnr_theme - )) - -## ----fig.width = 9------------------------------------------------------------ -(ggClimDens <- splnr_plot_climKernelDensity( - soln = list(dat_solnClim), - names = c("Input 1"), type = "Normal", - legendTitle = "Climate velocity (add unit)", - xAxisLab = "Climate velocity" -)) - diff --git a/vignettes/GlobalFishingWatch.R b/vignettes/GlobalFishingWatch.R deleted file mode 100644 index ca398e53..00000000 --- a/vignettes/GlobalFishingWatch.R +++ /dev/null @@ -1,204 +0,0 @@ -## ----setup_chunks, include=FALSE---------------------------------------------- -knitr::opts_chunk$set(echo = TRUE, warning = FALSE) - -## ----eval=FALSE--------------------------------------------------------------- -# remotes::install_github("GlobalFishingWatch/gfwr") - -## ----setup-------------------------------------------------------------------- -library(gfwr) -library(spatialplanr) - -## ----eval=FALSE--------------------------------------------------------------- -# usethis::edit_r_environ() - -## ----eval=FALSE--------------------------------------------------------------- -# key <- gfwr::gfw_auth() - -## ----results='hide'----------------------------------------------------------- -region_id <- gfwr::get_region_id(region_name = "Australia", - region_source = "EEZ", - key = gfwr::gfw_auth())$id - -## ----eval=FALSE, message=FALSE------------------------------------------------ -# gfwr::get_raster( -# spatial_resolution = "LOW", -# temporal_resolution = "MONTHLY", -# group_by = "FLAGANDGEARTYPE", -# start_date = "2022-01-01", -# end_date = "2023-01-01", -# region = region_id, -# region_source = "EEZ", -# key = gfwr::gfw_auth() -# ) - -## ----message=FALSE------------------------------------------------------------ -data_sf_combined <- splnr_get_gfw(region = "Australia", - start_date = "2019-01-01", - end_date = "2023-12-31", - temp_res = "YEARLY", - spat_res = "LOW", - compress = FALSE) - -## ----message = FALSE, results='hide'------------------------------------------ -# Check and modify if necessary the spatial reference of data_sf_combined -data_sf_combined <- sf::st_set_crs(data_sf_combined, - sf::st_crs(rnaturalearth::ne_coastline(scale = "large"))) - -coast_clipped <- rnaturalearth::ne_coastline(scale = "large") %>% - sf::st_as_sf() %>% - sf::st_intersection(sf::st_as_sfc(sf::st_bbox(data_sf_combined))) - -# Load EEZ polygons -eezs <- spatialgridr::get_boundary(name = "Australia", type = "eez", country_type = "country") %>% - sf::st_transform(crs = sf::st_crs(data_sf_combined)) %>% - sf::st_make_valid() %>% - sf::st_intersection(sf::st_as_sfc(sf::st_bbox(data_sf_combined))) - -## ----echo=FALSE--------------------------------------------------------------- -main_plot <- ggplot2::ggplot(data_sf_combined) + - ggplot2::geom_sf(ggplot2::aes(color = log10(ApparentFishingHrs))) + - ggplot2::geom_sf(data = coast_clipped, color = "black", fill = NA) + # Add coastline - ggplot2::geom_sf(data = eezs, fill = NA, color = "red") + # Add the EEZ with hatching - ggplot2::scale_color_viridis_c(guide = "legend") + - ggplot2::theme_minimal() + - ggplot2::labs(title = "2022 Vessel Activity Map", - subtitle = "Fishing Hours recorded by GFW in Australia", - color = "Fishing Hours (log10)") + - ggplot2::theme( - legend.position = "bottom", - legend.text = ggplot2::element_text(size = 8), - legend.title = ggplot2::element_text(size = 10) - ) + - ggplot2::guides(color = ggplot2::guide_colorbar( - title.position = "top", - title.vjust = 0.5, - title.hjust = -0.5, - label.theme = ggplot2::element_text(size = 8), - barwidth = 5, - barheight = 0.5 - )) - -# The display and writing in this section is for information purposes only, to understand how the information on the grid is translated. -overlay_plot <- ggplot2::ggplot(data_sf_combined) + - ggplot2::geom_rect(ggplot2::aes(xmin = -Inf,xmax = Inf,ymin = -Inf,ymax = Inf), fill = "white") + - ggplot2::geom_sf(ggplot2::aes(color = log10(ApparentFishingHrs))) + - ggplot2::geom_sf(data = coast_clipped, color = "black", fill = NA) + # Add coastline - ggplot2::geom_sf(data = eezs, fill = NA, color = "red") + - ggplot2::scale_color_viridis_c(guide = "legend") + - ggplot2::labs(title = "Vessel Activity Map in Australia between 2019 and 2023", - subtitle = "Fishing Hours data recorded by GFW", - color = "Fishing Hours \n (log10)") + - ggplot2::theme_minimal() + - ggplot2::theme( - legend.position = "none", - title = ggplot2::element_blank(), - axis.text.x = ggplot2::element_blank(), - axis.text.y = ggplot2::element_blank(), - axis.title.x = ggplot2::element_blank(), - axis.title.y = ggplot2::element_blank(), - panel.border = ggplot2::element_rect(color = "black", fill = NA, linewidth = 1) - ) + - ggplot2::coord_sf(xlim = c(152, 155), ylim = c(-27, -29)) - -main_plot + - ggplot2::annotation_custom( - ggplot2::ggplotGrob(overlay_plot), - xmin = 130, - xmax = 170, - ymin = -20, - ymax = -36 - ) - -## ----echo=FALSE--------------------------------------------------------------- -ggplot2::ggplot(data_sf_combined) + - ggplot2::geom_sf(ggplot2::aes(color = as.factor(Year))) + - ggplot2::geom_sf(data = coast_clipped, color = "black", fill = NA) + # Add coastline - ggplot2::geom_sf(data = eezs, color = "red", fill = NA) + # Add the EEZ - ggplot2::theme_minimal() + - ggplot2::scale_color_viridis_d(guide = "legend") + - ggplot2::labs(title = "Vessel Activity Map in Australia between 2019 and 2024", subtitle = "Fishing Hours data recorded by GFW", color = "Years") + - ggplot2::theme( - legend.position = "bottom", - legend.text = ggplot2::element_text(size = 8), - legend.title = ggplot2::element_text(size = 10) - ) - -## ----message=FALSE------------------------------------------------------------ -# We need to change the temporal range according to our need group by it to display the total fishing hours.
-data_sf_combined <- splnr_get_gfw(region = "Australia", - start_date = "2019-01-01", - end_date = "2023-12-31", - temp_res = "MONTHLY", - key = gfwr::gfw_auth()) %>% - dplyr::group_by(Year, Month) %>% - dplyr::summarize(Total_Fishing_Hours = sum(ApparentFishingHrs)) - -## ----echo=FALSE--------------------------------------------------------------- -ggplot2::ggplot(data_sf_combined, ggplot2::aes(x = Month, y = Total_Fishing_Hours, color = Year, group = Year)) + - ggplot2::geom_line() + - ggplot2::geom_point() + - ggplot2::labs( - title = "Total Fishing Hours per month (2014-2023)", - x = "Month", y = "Total Fishing Hours" - ) + - ggplot2::theme_minimal() - -## ----message=FALSE------------------------------------------------------------ -data_sf_combined <- splnr_get_gfw(region = "Micronesia", - start_date = "2019-12-31", - end_date = "2021-01-01", - temp_res = "MONTHLY") - -## ----echo=FALSE, message=FALSE, results='hide'-------------------------------- -# Check and modify if necessary the spatial reference of data_sf_combined -data_sf_combined <- sf::st_set_crs(data_sf_combined, sf::st_crs(rnaturalearth::ne_coastline(scale = "large"))) - -coast_clipped <- rnaturalearth::ne_coastline(scale = "large") %>% - sf::st_as_sf() %>% - sf::st_intersection(sf::st_as_sfc(sf::st_bbox(data_sf_combined))) - -# Load EEZ polygons -eezs <- spatialgridr::get_boundary(name = "Micronesia", type = "eez", country_type = "country") %>% - sf::st_transform(crs = sf::st_crs(data_sf_combined)) %>% - sf::st_make_valid() %>% - sf::st_intersection(sf::st_as_sfc(sf::st_bbox(data_sf_combined))) - -## ----echo=FALSE--------------------------------------------------------------- -# Create the map -ggplot2::ggplot(data_sf_combined) + - ggplot2::geom_sf(ggplot2::aes(color = `Geartype`)) + - ggplot2::geom_sf(data = coast_clipped, color = "black", fill = NA) + # Add coastline - ggplot2::geom_sf(data = eezs, color = "red", fill = NA) + # Ajouter la EEZ avec hachures - ggplot2::theme_minimal() + - ggplot2::labs(title = "2020 Vessel Activity Map", subtitle = "recorded by GFW in Micronesia", color = "Gear types") + - ggplot2::theme(legend.position = "right") - -## ----echo=FALSE, message=FALSE, results='hide'-------------------------------- -data_sf_combined <- splnr_get_gfw(region = "Papua New Guinea", - start_date = "2019-12-31", - end_date = "2021-01-01", - temp_res = "YEARLY", - spat_res = "LOW") %>% - sf::st_set_crs(sf::st_crs(rnaturalearth::ne_coastline(scale = "large"))) - -coast_clipped <- rnaturalearth::ne_coastline(scale = "large") %>% - sf::st_as_sf() %>% - sf::st_intersection(sf::st_as_sfc(sf::st_bbox(data_sf_combined))) - -# Load EEZ polygons -eezs <- spatialgridr::get_boundary(name = "Papua New Guinea", type = "eez", country_type = "country") %>% - sf::st_transform(crs = sf::st_crs(data_sf_combined)) %>% - sf::st_make_valid() %>% - sf::st_intersection(sf::st_as_sfc(sf::st_bbox(data_sf_combined))) - -## ----echo=FALSE--------------------------------------------------------------- -# Create the map -ggplot2::ggplot(data_sf_combined) + - ggplot2::geom_sf(ggplot2::aes(color = `Flag`)) + - ggplot2::geom_sf(data = coast_clipped, color = "black", fill = NA) + # Add coastline - ggplot2::geom_sf(data = eezs, color = "red", fill = NA) + # Add EEZ - ggplot2::scale_size_continuous(range = c(1, 10), guide = "legend", name = "Flag") + - ggplot2::theme_minimal() + - ggplot2::labs(title = "2021 Vessel Activity Map", subtitle = "recorded by GFW in Papua New Guinea", color = "Flag") + - ggplot2::theme(legend.position = "right") - diff --git a/vignettes/GlobalFishingWatch.html b/vignettes/GlobalFishingWatch.html deleted file mode 100644 index 4b8b52a2..00000000 --- a/vignettes/GlobalFishingWatch.html +++ /dev/null @@ -1,535 +0,0 @@ - - - - - - - - - - - - - - -Global Fishing Watch - - - - - - - - - - - - - - - - - - - - - - - - - - -