diff --git a/.github/workflows/MacOS.yaml b/.github/workflows/MacOS.yaml
index eeb6db9..f44ef01 100644
--- a/.github/workflows/MacOS.yaml
+++ b/.github/workflows/MacOS.yaml
@@ -46,6 +46,7 @@ jobs:
any::rcmdcheck
any::remotes
any::lpsymphony
+ any::slam
needs: check
- uses: r-lib/actions/check-r-package@v2
diff --git a/.github/workflows/Ubuntu.yaml b/.github/workflows/Ubuntu.yaml
index 03878a2..562a505 100644
--- a/.github/workflows/Ubuntu.yaml
+++ b/.github/workflows/Ubuntu.yaml
@@ -53,6 +53,7 @@ jobs:
any::rcmdcheck
any::remotes
any::lpsymphony
+ any::slam
needs: check
- uses: r-lib/actions/check-r-package@v2
diff --git a/.github/workflows/Windows.yaml b/.github/workflows/Windows.yaml
index e46efd1..76154cf 100644
--- a/.github/workflows/Windows.yaml
+++ b/.github/workflows/Windows.yaml
@@ -50,6 +50,7 @@ jobs:
any::rcmdcheck
any::remotes
any::lpsymphony
+ any::slam
needs: check
- uses: r-lib/actions/check-r-package@v2
diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml
index 870ee9f..b8b6e9f 100644
--- a/.github/workflows/test-coverage.yaml
+++ b/.github/workflows/test-coverage.yaml
@@ -42,6 +42,7 @@ jobs:
any::rcmdcheck
any::remotes
any::lpsymphony
+ any::slam
needs: coverage
- name: Test coverage
diff --git a/NAMESPACE b/NAMESPACE
index 71160bc..21b3247 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -68,11 +68,9 @@ 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)
@@ -80,7 +78,6 @@ 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)
diff --git a/R/data.R b/R/data.R
index 83b1a7d..a5c7650 100644
--- a/R/data.R
+++ b/R/data.R
@@ -1,6 +1,6 @@
#' Planning Units
#'
-#' An sf dataframe of planning units for spatial prioritisation
+#' An sf dataframe of Planning Units for spatial prioritization
#'
#' @format `dat_PUs`
#' A data frame with XXXX rows and XXX columns:
@@ -14,9 +14,9 @@
# -------------------------------------------------------------------------
-#' Boundary of planning units
+#' Boundary of Planning Units
#'
-#' An sf dataframe of planning units for spatial prioritisation
+#' An sf dataframe of Planning Units for spatial prioritization
#'
#' @format `dat_bndry`
#' A data frame with XXXX rows and XXX columns:
@@ -32,7 +32,7 @@
#' Regionalisation
#'
-#' An sf dataframe of planning units for spatial prioritisation
+#' An sf dataframe of Planning Units for spatial prioritization
#'
#' @format `dat_region`
#' A data frame with XXXX rows and XXX columns:
@@ -47,7 +47,7 @@
#' Binary Species Data
#'
-#' An sf dataframe of planning units for spatial prioritisation
+#' An sf dataframe of Planning Units for spatial prioritization
#'
#' @format `dat_species_bin`
#' A data frame with XXXX rows and XXX columns:
@@ -63,7 +63,7 @@
#' Binary Species Data 2
#'
-#' An sf dataframe of planning units for spatial prioritisation
+#' An sf dataframe of Planning Units for spatial prioritization
#'
#' @format `dat_species_bin2`
#' A data frame with XXXX rows and XXX columns:
@@ -79,7 +79,7 @@
#' Probability Species Data
#'
-#' An sf dataframe of planning units for spatial prioritisation
+#' An sf dataframe of Planning Units for spatial prioritization
#'
#' @format `dat_species_prob`
#' A data frame with XXXX rows and XXX columns:
@@ -93,9 +93,9 @@
# -------------------------------------------------------------------------
-#' MPA Data
+#' Marine Protected Areas (MPAs) Data
#'
-#' An sf dataframe of planning units for spatial prioritisation
+#' An sf dataframe of Planning Units for spatial prioritization
#'
#' @format `dat_mpas`
#' A data frame with XXXX rows and XXX columns:
@@ -117,7 +117,7 @@
#' @format `dat_category`
#' A data frame with XXXX rows and XXX columns:
#' \describe{
-#' \item{feature}{all features available for spatial prioritisation}
+#' \item{feature}{all features available for spatial prioritization}
#' \item{category}{the categories of all features}
#' ...
#' }
@@ -135,7 +135,7 @@
#' @format `dat_category2`
#' A data frame with XXXX rows and XXX columns:
#' \describe{
-#' \item{feature}{all features available for spatial prioritisation}
+#' \item{feature}{all features available for spatial prioritization}
#' \item{category}{the categories of all features}
#' ...
#' }
@@ -148,7 +148,7 @@
#' Climate metric data
#'
-#' An sf dataframe of planning units for spatial prioritisation
+#' An sf dataframe of Planning Units for spatial prioritization
#'
#' @format `dat_clim`
#' A data frame with 780 rows and 3 columns:
@@ -179,14 +179,14 @@
# -------------------------------------------------------------------------
-#' Current MPAs of the Coral Sea
+#' Current Marine Protected Areas (MPAs) of the Coral Sea
#'
-#' sf file containing the current marine protected areas of the coral sea
+#' sf file containing the current Marine Protected Areas (MPAs) of the coral sea
#'
#' @format `MPAsCoralSea`
#' A data frame with 397 rows and 17 columns:
#' \describe{
-#' \item{wdpa}{binary vector denoting presence or absence of a current marine protected area}
+#' \item{wdpa}{binary vector denoting presence or absence of a current MPA}
#' ...
#' }
#' @source https://www.protectedplanet.net/en/thematic-areas/wdpa?tab=WDPA
diff --git a/R/splnr_get_distCoast.R b/R/splnr_get_distCoast.R
index 37ac46a..92f6273 100644
--- a/R/splnr_get_distCoast.R
+++ b/R/splnr_get_distCoast.R
@@ -2,7 +2,7 @@
#'
#' @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
+#' 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.
#'
@@ -13,7 +13,7 @@
#' a suitable projected CRS for accurate distance calculations.
#'
#' @param dat_sf `[sf]` \cr An `sf` object containing polygon or point features
-#' representing the planning units. Must have a valid CRS.
+#' 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`.
@@ -99,12 +99,12 @@ splnr_get_distCoast <- function(dat_sf, custom_coast = NULL, res = "medium") {
sf::st_transform(crs = sf::st_crs(dat_sf))
}
- # 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.")
+ # 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))
- # Calculate the distance matrix between each planning unit centroid and the coastline
+ # 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) %>%
# Explicitly set the distance units to kilometers
@@ -112,7 +112,7 @@ splnr_get_distCoast <- function(dat_sf, custom_coast = NULL, res = "medium") {
# Drop the units class to get a numeric matrix for easier computation
units::drop_units()
- # Find the minimum distance for each planning unit (each row in the matrix)
+ # 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))
diff --git a/R/splnr_gg_add.R b/R/splnr_gg_add.R
index da74780..c8fd4ad 100644
--- a/R/splnr_gg_add.R
+++ b/R/splnr_gg_add.R
@@ -1,16 +1,18 @@
-#' @title Add-ons for Plotting `spatialplanr` Maps
+#' @title Add-ons for Plotting `spatialplanr` Solution Maps
#'
#' @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
+#' This function allows users to customize existing `ggplot2` solution maps produced
+#' by `spatialplanr` spatial plotting functions (e.g., `splnr_plot_solution()`). It
+#' provides options to add various spatial layers and apply consistent theming in a
#' simple and reproducible manner.
#'
#' @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
+#' 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, locked-in areas (e.g., existing Marine Protected
+#' Areas (MPAs) that must be included in a conservation prioritization), and
+#' locked-out areas (e.g., areas that must be excluded from selection such as
+#' shipping lanes or oil and gas leases). It offers fine-grained control over
#' colors, opacities, and legend appearance for each added layer.
#'
#' When using `contours`, the input `sf` object is expected to have a column
@@ -23,10 +25,10 @@
#' 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
+#' @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"`.
+#' 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
@@ -41,15 +43,15 @@
#' @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.
+#' `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.
+#' @param lockIn An `sf` object representing locked-in areas (e.g., existing
+#' Marine Protected Areas (MPAs)) 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"`
@@ -58,13 +60,30 @@
#' 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`.
+#' areas when `typeLockIn` is `"Full"`. Defaults to `1`.
#' @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 lockOut An `sf` object representing locked-out areas (e.g., shipping lanes,
+#' oil and gas leases, or other excluded zones) that must not be selected in a
+#' conservation prioritization. Defaults to `NULL`.
+#' @param typeLockOut A character string specifying how `lockOut` areas should be
+#' plotted. Can be `"Full"` (fills the areas with `colorLockOut`) or `"Contours"`
+#' (draws only the outlines of the areas). Defaults to `"Full"`.
+#' @param nameLockOut A character string specifying the column name in the `lockOut`
+#' data frame that contains binary (0/1 or TRUE/FALSE) information indicating
+#' locked-out status. Required if `lockOut` is not `NULL`.
+#' @param alphaLockOut A numeric value (0 to 1) for the opacity of the `lockOut`
+#' areas when `typeLockOut` is `"Full"`. Defaults to `1`.
+#' @param colorLockOut A character string specifying the color for the `lockOut` areas.
+#' Defaults to `"black"`.
+#' @param legendLockOut A character string for the title of the `lockOut` legend.
+#' Can be an empty string `""` to suppress the title. Defaults to `""`.
+#' @param labelLockOut A character string for the legend label of the `lockOut` areas
+#' (e.g., "Shipping Lanes"). Defaults to `""`.
#' @param ggtheme The `ggplot2` theme to apply. Can be:
#' \itemize{
#' \item `NA` or `FALSE`: No theme is applied, using `ggplot2` defaults.
@@ -91,7 +110,7 @@
#' @examples
#' \dontrun{
#' # Assuming 'dat_species_bin' and 'dat_PUs' are existing sf objects
-#' # in your package, suitable for prioritisation problems and plotting.
+#' # in your package, suitable for prioritization problems and plotting.
#'
#' # Create a dummy prioritizr problem and solve it for demonstration.
#' dat_problem <- prioritizr::problem(
@@ -107,13 +126,13 @@
#' dat_soln <- dat_problem %>%
#' prioritizr::solve.ConservationProblem()
#'
-#' # Basic plot of the solution with default planning unit outlines and theme.
+#' # 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`
+#' # 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)
@@ -125,7 +144,6 @@
#' 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",
@@ -164,37 +182,58 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80",
# 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."
- # )
+ # 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(cropOverlay)){assertthat::assert_that(inherits(cropOverlay, "sf"), msg = "'cropOverlay' must be an 'sf' object or NULL.")}
+
+ # Validate lockIn parameters
+ 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) && !is.null(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.")
+ }
+
+ # Validate lockOut parameters
+ if(!is.null(lockOut)){
+ assertthat::assert_that(inherits(lockOut, "sf"), msg = "'lockOut' must be an 'sf' object or NULL.")
+ assertthat::assert_that(is.character(nameLockOut) && !is.null(nameLockOut) && all(nameLockOut %in% names(lockOut)),
+ msg = "If 'lockOut' is provided, 'nameLockOut' must be a character string specifying an existing column in 'lockOut'.")
+ assertthat::assert_that(typeLockOut %in% c("Full", "Contours"),
+ msg = "'typeLockOut' must be either 'Full' or 'Contours'.")
+ assertthat::assert_that(is.numeric(alphaLockOut) && alphaLockOut >= 0 && alphaLockOut <= 1,
+ msg = "'alphaLockOut' must be a numeric value between 0 and 1.")
+ }
+
+ # Validate color parameters
+ 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(colorLockOut), msg = "'colorLockOut' must be a character string for a color.")
+
+ # Validate legend and label parameters
+ 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(is.character(legendLockOut), msg = "'legendLockOut' must be a character string.")
+ assertthat::assert_that(is.character(labelLockOut), msg = "'labelLockOut' must be a character string.")
+
+ # Validate ggtheme parameter
+ assertthat::assert_that(
+ inherits(ggtheme, "character") || inherits(ggtheme, "theme") || inherits(ggtheme, "list") || inherits(ggtheme, "logical"),
+ msg = "'ggtheme' must be 'Default', a ggplot2 theme, a list of theme elements, or NA/FALSE."
+ )
# Initialize an empty list to store ggplot2 layers.
ggList <- list()
diff --git a/R/splnr_plotting.R b/R/splnr_plotting.R
index 76f0fe4..cb013d2 100644
--- a/R/splnr_plotting.R
+++ b/R/splnr_plotting.R
@@ -4,14 +4,14 @@
#' 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.
+#' the Planning Unit outlines.
#'
#' @details
-#' The `splnr_plot` function automatically detects the type of data specified by
+#' 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.
+#' 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()`,
@@ -24,7 +24,7 @@
#' @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.
+#' 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.
@@ -258,9 +258,9 @@ splnr_plot <- function(df,
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).
+ } 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.
+ # Add geom_sf to display Planning Unit outlines without fill.
gg <- gg +
ggplot2::geom_sf(data = df, colour = "grey80", fill = NA, size = 0.1)
}
@@ -284,7 +284,7 @@ splnr_plot <- function(df,
#' 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.
+#' 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.).
#'
@@ -448,7 +448,7 @@ splnr_plot_solution <- function(soln, colorVals = c("#c6dbef", "#3182bd"),
)
}
- # Sum up the zone selections for each planning unit to get a single 'solution' column.
+ # Sum up the zone selections for each Planning Unit to get a single 'solution' column.
soln <- solnNewNames %>%
dplyr::rowwise() %>%
dplyr::mutate(
@@ -504,24 +504,24 @@ splnr_plot_solution <- function(soln, colorVals = c("#c6dbef", "#3182bd"),
#' @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
+#' 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.
+#' 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
+#' Planning Units. It also requires a cost column, either present within the
#' `soln` object or provided separately via the `Cost` parameter.
#'
-#' The function filters the solution to show only the selected planning units
+#' 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 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.
+#' @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.
@@ -622,7 +622,7 @@ splnr_plot_costOverlay <- function(soln, cost = NA, costName = "Cost",
stop(paste0("The provided 'Cost' object does not contain the specified cost column '", costName, "'."))
}
- # Filter the solution to only include selected planning units.
+ # Filter the solution to only include selected Planning Units.
soln <- soln %>%
dplyr::select("solution_1") %>%
dplyr::filter(.data$solution_1 == 1)
@@ -658,7 +658,7 @@ splnr_plot_costOverlay <- function(soln, cost = NA, costName = "Cost",
#' @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.
+#' which Planning Units are common, added, or removed between two scenarios.
#'
#' @details
#' Conservation planning often involves comparing outputs from different
@@ -667,7 +667,7 @@ splnr_plot_costOverlay <- function(soln, cost = NA, costName = "Cost",
#' `prioritizr` solution and containing a `solution_1` column (binary,
#' indicating selected vs. not selected).
#'
-#' The function categorizes planning units into "Same" (selected in both),
+#' 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
@@ -770,7 +770,7 @@ splnr_plot_comparison <- function(soln1, soln2, legendTitle = "Scenario 2 compar
),
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).
+ # 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.
@@ -794,16 +794,16 @@ splnr_plot_comparison <- function(soln1, soln2, legendTitle = "Scenario 2 compar
#'
#' @description
#' The `splnr_plot_selectionFreq()` function visualizes the selection frequency
-#' of planning units across an array of `prioritizr` solutions. This is useful
+#' 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
+#' 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`
+#' representing the selection frequency of each Planning Unit. This `selFreq`
#' column can be generated using the `spatialplanr` function `splnr_get_selFreq()`.
#'
#' The function uses `ggplot2` to create a spatial plot of these frequencies,
@@ -811,7 +811,7 @@ splnr_plot_comparison <- function(soln1, soln2, legendTitle = "Scenario 2 compar
#' 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 data for planning units.
+#' @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
@@ -821,7 +821,7 @@ splnr_plot_comparison <- function(soln1, soln2, legendTitle = "Scenario 2 compar
#' @param legendTitle A character string for the title of the legend.
#' Defaults to `"Selection \nFrequency"`.
#'
-#' @return A `ggplot` object representing the plot of planning unit selection frequency.
+#' @return A `ggplot` object representing the plot of Planning Unit selection frequency.
#' @export
#'
#' @importFrom assertthat assert_that
@@ -928,11 +928,11 @@ splnr_plot_selectionFreq <- function(selFreq,
#'
#' @description
#' The `splnr_plot_importanceScore()` function visualizes the importance scores
-#' (irreplaceability) of planning units from a `prioritizr` conservation problem
+#' (irreplaceability) of Planning Units from a `prioritizr` conservation problem
#' using `ggplot2`. It supports different methods for calculating importance scores.
#'
#' @details
-#' Importance scores quantify the irreplaceability of a planning unit in a
+#' 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{
diff --git a/R/splnr_plotting_climate.R b/R/splnr_plotting_climate.R
index eed0d9e..596638a 100644
--- a/R/splnr_plotting_climate.R
+++ b/R/splnr_plotting_climate.R
@@ -412,16 +412,17 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list,
#' stakeholder engagement.
#'
#' Both underlying functions require a `prioritizr` solution containing a
-#' `metric` column with climate metric information and a `solution_1` column
+#' climate metric column with climate metric information and a prioritizr solution 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
+#' @param solution_names A character vector of names corresponding to each solution in
#' `soln` when `type = "Normal"`. Not used for `type = "Basic"`.
#' Defaults to `NA`.
+#' @param climate_names A character string of the name of the climate
#' @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
@@ -491,7 +492,7 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list,
#' # 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"),
+#' solution_names = c("Solution 1"),
#' type = "Normal"
#' )
#' print(plot_normal_kde_single)
@@ -503,7 +504,8 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list,
#'
#' plot_normal_kde_multi <- splnr_plot_climKernelDensity(
#' soln = list(dat_solnClim, dat_solnClim_2),
-#' names = c("Solution A", "Solution B"),
+#' solution_names = c("Solution A", "Solution B"),
+#' climate_names = "metric",
#' type = "Normal",
#' colorMap = "plasma",
#' legendTitle = "Climate Value",
diff --git a/R/splnr_targets.R b/R/splnr_targets.R
index 76851fa..2d398ed 100644
--- a/R/splnr_targets.R
+++ b/R/splnr_targets.R
@@ -13,10 +13,10 @@
#' range-restricted features.
#'
#' The calculation proceeds as follows:
-#' 1. The area of a single planning unit is determined.
+#' 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
+#' 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
@@ -25,11 +25,11 @@
#'
#' 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.
+#' 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.
+#' 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
@@ -85,7 +85,7 @@ splnr_targets_byInverseArea <- function(df, target_min, target_max) {
msg = "'df' must contain a 'geometry' column."
)
- # Calculate the area of a single planning unit in km².
+ # Calculate the area of a single Planning Unit in km².
PU_area_km2 <- as.numeric(sf::st_area(df[1, ]) / 1e+06)
# Calculate the total approximate area of the study region.
@@ -354,7 +354,7 @@ splnr_targets_byIUCN <- function(dat, IUCN_target, 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)
+ dplyr::select(-"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.
diff --git a/R/utils-climate.R b/R/utils-climate.R
index 4710608..e5de6a9 100644
--- a/R/utils-climate.R
+++ b/R/utils-climate.R
@@ -35,9 +35,9 @@
#'
#' @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.
+#' 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.
+#' 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.
@@ -144,7 +144,7 @@ splnr_climate_priorityArea_preprocess <- function(features,
# 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."))
+ 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
@@ -459,9 +459,9 @@ splnr_climate_priorityArea_assignTargets <- function(targets,
#' @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.
+#' 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.
+#' 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).
@@ -480,7 +480,7 @@ splnr_climate_priorityArea_assignTargets <- function(targets,
#' @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)
+#' 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
@@ -621,7 +621,7 @@ splnr_climate_priorityAreaApproach <- function(features,
#'
#' @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.
+#' 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.
@@ -632,8 +632,8 @@ splnr_climate_priorityAreaApproach <- function(features,
#' }
#'
#' @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.
+#' additional binary column named `climate_layer` indicating which Planning
+#' Units are considered climate-smart.
#' @keywords internal
#' @noRd
#' @importFrom assertthat assert_that
@@ -888,7 +888,7 @@ splnr_climate_feature_assignTargets <- function(climateSmartDF,
#' @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.
+#' 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).
@@ -906,7 +906,7 @@ splnr_climate_feature_assignTargets <- function(climateSmartDF,
#' @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`
+#' 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`.
@@ -1052,9 +1052,9 @@ splnr_climate_featureApproach <- function(features,
#'
#' @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.
+#' 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.
+#' 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.
@@ -1066,7 +1066,7 @@ splnr_climate_featureApproach <- function(features,
#'
#' @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.
+#' 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
@@ -1164,7 +1164,7 @@ splnr_climate_percentile_preprocess <- function(features,
# 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."))
+ 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
@@ -1409,7 +1409,7 @@ splnr_climate_percentile_assignTargets <- function(features,
#' @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.
+#' 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).
@@ -1425,7 +1425,7 @@ splnr_climate_percentile_assignTargets <- function(features,
#' @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
+#' 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`.
diff --git a/R/utils.R b/R/utils.R
index 8d1cbeb..0cc1fd7 100644
--- a/R/utils.R
+++ b/R/utils.R
@@ -97,8 +97,8 @@ splnr_create_polygon <- function(x, cCRS = "EPSG:4326") {
#'
#' @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
+#' 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.
@@ -677,7 +677,7 @@ splnr_get_kappaCorrData <- function(sol, name_sol) {
# Transform the long-format results into a wide-format correlation matrix.
matrix_final <- s_matrix_all %>%
tibble::as_tibble(.name_repair = "unique") %>%
- dplyr::select(-.data$kappa_pvalue) %>% # Remove p-value column as it's not needed for the correlation matrix plot.
+ dplyr::select(-"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.
@@ -700,7 +700,7 @@ splnr_get_kappaCorrData <- function(sol, name_sol) {
#' @title Prepare Data to Plot Selection Frequency of Planning Units
#'
#' @description
-#' `splnr_get_selFreq()` calculates how many times each planning unit is
+#' `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.
@@ -711,7 +711,7 @@ splnr_get_kappaCorrData <- function(sol, name_sol) {
#' planning scenarios or alternative optimal solutions.
#'
#' The function supports two types of input:
-#' \itemize{
+#' \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_"
@@ -721,7 +721,7 @@ splnr_get_kappaCorrData <- function(sol, name_sol) {
#' "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
+#' 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()`
@@ -737,7 +737,7 @@ splnr_get_kappaCorrData <- function(sol, name_sol) {
#'
#' @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.
+#' selected occurrences across all solutions) for each Planning Unit.
#' @export
#'
#' @importFrom assertthat assert_that
@@ -817,7 +817,7 @@ splnr_get_selFreq <- function(solnMany, type = "portfolio") {
# 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::mutate(selFreq = as.factor(rowSums(dplyr::select(tibble::as_tibble(solnMany),
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)) %>%
@@ -863,13 +863,11 @@ splnr_get_selFreq <- function(solnMany, type = "portfolio") {
colnames(soln) <- name_sol
# Calculate selection frequency by summing binary solution columns.
+ # Sum across all columns starting with "soln" (which are our individual solutions).
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")
+ dplyr::mutate(selFreq = as.factor(rowSums(dplyr::select(soln, dplyr::starts_with("soln")), na.rm = TRUE))) %>%
+ sf::st_as_sf(geometry = sf::st_geometry(solnMany[[1]])) %>% # Convert back to sf
+ dplyr::select("selFreq") # Select only the calculated selection frequency column.
return(selFreq)
} else {
diff --git a/README.Rmd b/README.Rmd
index 0cef93c..8fa7be7 100644
--- a/README.Rmd
+++ b/README.Rmd
@@ -13,7 +13,7 @@ knitr::opts_chunk$set(
)
```
-# spatialplanr
[](https://lifecycle.r-lib.org/articles/stages.html#experimental)
@@ -26,7 +26,7 @@ knitr::opts_chunk$set(
# 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.
+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 robust protected area networks.
## Installation
@@ -37,335 +37,335 @@ Be aware that this package is in the very early stages of development. Functions
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 b6133b1..d31f450 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-# spatialplanr \
@@ -21,8 +21,7 @@ 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.
+conservation planners to develop robust protected area networks.
## Installation
@@ -36,454 +35,264 @@ development version from [GitHub](https://github.com/) with:
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/docs/404.html b/docs/404.html
index 4ca3ae9..16f564a 100644
--- a/docs/404.html
+++ b/docs/404.html
@@ -26,7 +26,7 @@
spatialplanr
- 0.6.9
+ 0.7.0
Bndry<-splnr_get_boundary(Limits =Region, Type =Type, cCRS =cCRS)
-#> Reading layer `ne_10m_geography_marine_polys' from data source
-#> `/private/var/folders/p1/b5fzmqs56hg6y8473_y3bzxc0000gn/T/RtmpLjt7It/ne_10m_geography_marine_polys.shp'
-#> using driver `ESRI Shapefile'
-#> Simple feature collection with 306 features and 37 fields
-#> Geometry type: MULTIPOLYGON
-#> Dimension: XY
-#> Bounding box: xmin: -180 ymin: -85.19206 xmax: 179.9999 ymax: 90
-#> Geodetic CRS: WGS 84landmass<-rnaturalearth::ne_countries(scale ="medium", returnclass ="sf")%>%sf::st_transform(cCRS)
Run the climate-smart spatial pl
Bndry =Bndry, overlay =landmass, cropOverlay =PUs, ggtheme =splnr_theme))
-
+
However, we are also interested how climate-smart the selected
planning units in the solution actually are. For this, we can use a
kernel density plot.
We now add other information required to perform the spatial
planning, such as the cost, and extract the names of all used features
-to then run a prioritisation.
We now add other information required to perform the spatial
planning, such as the cost, and extract the names of all used features
-to then run a prioritisation.
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
@@ -149,8 +146,8 @@
With add_boundary_penalties() we set a penalty of 0.5
between the zones we defined in zm1. For the purpose of
-this example, we also set a 10 second time limit for the prioritisation.
+this example, we also set a 10 second time limit for the prioritization.
The results show less fragmentation than in the previous solution
without penalties:
We need to specify which zone the constraint should be applied to,
-give information on the planning unit identifier, rename the column of
-interest to “status” and filter out only the planning units that should
-be locked in.
+give information on the Planning Unit identifier, rename the column of
+interest to “status” and filter out only the Planning Units that should
+be locked-in.
# NOTE: When using sf input, we need as many cost columns as we have zonesp6<-prioritizr::problem(
@@ -619,7 +611,7 @@
NOTE: We can also use multiple linear constraints in
the same plan, however, this might require a normalization of the input
data to have the constraints in comparable units, and a careful tuning
@@ -834,7 +826,7 @@
diff --git a/docs/articles/MultipleUse.md b/docs/articles/MultipleUse.md
new file mode 100644
index 0000000..4992e8a
--- /dev/null
+++ b/docs/articles/MultipleUse.md
@@ -0,0 +1,1176 @@
+# Spatial Planning With Zones
+
+``` r
+
+library(spatialplanr)
+set.seed(100)
+```
+
+## Overview
+
+This code has been written to simplify the process for running a
+*prioritizr* analysis on a given region. It is still a work in progress
+so feel free to submit pull requests with new features and code
+improvements.
+
+The workflow shown here was based on the [`prioritizr` introduction to
+zones](https://prioritizr.net/articles/management_zones_tutorial.html).
+
+### Set user parameters
+
+``` r
+
+Region <- "Coral Sea" # "Australia"
+Type <- "Oceans" # "EEZ"
+```
+
+Set the diameter of the planning units. This will be in the same units
+as the CRS (usually metres or degrees).
+
+``` r
+
+PU_size <- 107460 # m
+```
+
+Choose CRS for analysis. Here we use Mollweide
+
+``` r
+
+cCRS <- "ESRI:54009"
+```
+
+### Analysis Region
+
+Start your analysis by defining your region and setting up the planning
+units.
+
+Get the boundary for your chosen region.
+
+``` r
+
+Bndry <- splnr_get_boundary(Limits = Region, Type = Type, cCRS = cCRS)
+
+landmass <- rnaturalearth::ne_countries(
+ scale = "medium",
+ returnclass = "sf"
+) %>%
+ sf::st_transform(cCRS)
+```
+
+### Create Planning Units
+
+``` r
+
+PUs <- spatialgridr::get_grid(boundary = Bndry,
+ crs = cCRS,
+ output = "sf_hex",
+ resolution = PU_size)
+```
+
+We can also use a customised `ggplot` theme that can be passed as a list
+to
+[`splnr_gg_add()`](https://mathmarecol.github.io/spatialplanr/reference/splnr_gg_add.md)
+and that can then be used for all plots. For example:
+
+``` r
+
+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()
+ )
+)
+```
+
+### Get the features
+
+For our example, we will use a small subset of charismatic megafauna
+species of the Coral Sea to inform the conservation plan. We filtered
+the Aquamaps (Aquamaps.org) species distribution models for our study
+area for the following species:
+
+``` r
+
+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"
+)
+```
+
+These species were not chosen based on their importance for this region
+and only represent an example for visualization purposes.
+
+**Note:** The structure of the `tribble`above is required for some of
+the downstream plotting. *Common* denotes the common name of a species,
+*Scientific* the scientific name in the format used by Aquamaps,
+*Category* is the category that a species belongs to and *Class*
+represents the importance of the species for the conservation plan.
+
+#### Convert the probabilities to binary data and feature names
+
+``` r
+
+datEx_species_bin <- spDataFiltered %>%
+ splnr_apply_cutoffs(Cutoffs = 0.5)
+
+col_name <- spDataFiltered %>%
+ sf::st_drop_geometry() %>%
+ colnames()
+```
+
+#### Spatial planning including zones
+
+So far, all steps were exactly the same as in a spatial plan that does
+not include zones. To have a direct comparison, we will first run a
+spatial plan that does not include zoning. For this, we will define
+targets for our features (here: 30% for all features) and create a
+conservation problem where we include an area-based cost in our
+prioritization.
+
+``` r
+
+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)
+```
+
+We then solve the problem and plot the solution.
+
+``` r
+
+s1 <- p1 %>%
+ prioritizr::solve.ConservationProblem()
+
+(ggSoln <- splnr_plot_solution(s1) +
+ splnr_gg_add(PUs = PUs, Bndry = Bndry, overlay = landmass, cropOverlay = PUs, ggtheme = splnr_theme))
+```
+
+
+
+We can also have a look at how well the set target was met.
+
+``` r
+
+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)
+#> # A tibble: 15 × 5
+#> summary feature total_amount absolute_held relative_held
+#>
+#> 1 overall Chelonia_mydas 22 10 0.455
+#> 2 overall Caretta_caretta 22 10 0.455
+#> 3 overall Eretmochelys_imbricata 24 10 0.417
+#> 4 overall Lepidochelys_olivacea 22 10 0.455
+#> 5 overall Crocodylus_porosus 21 9 0.429
+#> 6 overall Megaptera_novaeangliae 388 120 0.309
+#> 7 overall Balaenoptera_acutorostrata 238 74 0.311
+#> 8 overall Dugong_dugon 13 5 0.385
+#> 9 overall Carcharias_taurus 22 10 0.455
+#> 10 overall Galeocerdo_cuvier 36 14 0.389
+#> 11 overall Sphyrna_mokarran 397 123 0.310
+#> 12 overall Mobula_birostris 20 8 0.4
+#> 13 overall Mobula_alfredi 20 8 0.4
+#> 14 overall Triaenodon_obesus 25 10 0.4
+#> 15 overall Sula_sula 13 5 0.385
+```
+
+We will now look how this spatial plan needs to be extended to include
+multiple management zones by using `zones()`.
+
+#### Different cost layers
+
+We first assume that we have to zones of interest that have the same set
+of features, but separate cost layers. For this, we need to set targets
+for both zones, in our case 20% for all features in the first zone and
+5% of all features in the second zone.
+
+``` r
+
+target2 <- matrix(NA, ncol = 2, nrow = nrow(Dict))
+target2[, 1] <- 0.2
+target2[, 2] <- 0.05
+```
+
+We then create a `zones` object where we specify the number of zones and
+the features in the zone. Here, we define two zones that both have the
+same features.
+
+``` r
+
+z2 <- prioritizr::zones("zone 1" = col_name, "zone 2" = col_name)
+```
+
+Both zones need a specified cost and targets. We use one area-based cost
+and one cost layer that uses random numbers, the pre-defined targets and
+pass the `zones`object to the problem formulation before solving the
+conservation problem.
+
+``` r
+
+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()
+```
+
+The solution can be plotted using the function
+[`splnr_plot_solution()`](https://mathmarecol.github.io/spatialplanr/reference/splnr_plot_solution.md)
+with the argument `zones` set to `TRUE`.
+
+``` r
+
+(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
+ ))
+```
+
+
+
+We can see that we now how planning units that are not selected, and
+planning units that have either been selected for zone 1 or zone 2.
+
+#### Different features
+
+When using `sf` objects with `zones()`, the input feature names to
+`zones()` need to have the same length and contain the same features.
+This means that both zones have the same features, but for some that are
+not of interest in that specific zone, the target is set to 0. For
+example, if we want to separate the example data in a zone for reptiles
+and another zone containing all other taxa that are not reptiles, we can
+specify the following targets:
+
+``` r
+
+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()
+```
+
+This sets the target for reptiles in the first zone to 30% and the rest
+to 0%. In the second zone, the targets for non-reptiles is 10% and for
+reptiles it is 0% because they are not of interest in this zone. Target
+data has to be given in a matrix when working with zones, so we
+transform the data frame to a matrix at the end.
+
+We then define the conservation problem in the same way as above and
+solve it.
+
+``` r
+
+# 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()
+```
+
+We can then also look at how well these targets are met in each zone
+(and combined).
+
+``` r
+
+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)
+#> # A tibble: 45 × 5
+#> summary feature total_amount absolute_held relative_held
+#>
+#> 1 overall 1 44 11 0.25
+#> 2 overall 2 44 11 0.25
+#> 3 overall 3 48 11 0.229
+#> 4 overall 4 44 11 0.25
+#> 5 overall 5 42 11 0.262
+#> 6 overall 6 776 43 0.0554
+#> 7 overall 7 476 26 0.0546
+#> 8 overall 8 26 7 0.269
+#> 9 overall 9 44 11 0.25
+#> 10 overall 10 72 13 0.181
+#> 11 overall 11 794 48 0.0605
+#> 12 overall 12 40 11 0.275
+#> 13 overall 13 40 11 0.275
+#> 14 overall 14 50 12 0.24
+#> 15 overall 15 26 8 0.308
+#> 16 zone 1 1 22 8 0.364
+#> 17 zone 1 2 22 8 0.364
+#> 18 zone 1 3 24 8 0.333
+#> 19 zone 1 4 22 8 0.364
+#> 20 zone 1 5 21 8 0.381
+#> 21 zone 1 6 388 4 0.0103
+#> 22 zone 1 7 238 2 0.00840
+#> 23 zone 1 8 13 5 0.385
+#> 24 zone 1 9 22 8 0.364
+#> 25 zone 1 10 36 8 0.222
+#> 26 zone 1 11 397 8 0.0202
+#> 27 zone 1 12 20 8 0.4
+#> 28 zone 1 13 20 8 0.4
+#> 29 zone 1 14 25 8 0.32
+#> 30 zone 1 15 13 6 0.462
+#> 31 zone 2 1 22 3 0.136
+#> 32 zone 2 2 22 3 0.136
+#> 33 zone 2 3 24 3 0.125
+#> 34 zone 2 4 22 3 0.136
+#> 35 zone 2 5 21 3 0.143
+#> 36 zone 2 6 388 39 0.101
+#> 37 zone 2 7 238 24 0.101
+#> 38 zone 2 8 13 2 0.154
+#> 39 zone 2 9 22 3 0.136
+#> 40 zone 2 10 36 5 0.139
+#> 41 zone 2 11 397 40 0.101
+#> 42 zone 2 12 20 3 0.15
+#> 43 zone 2 13 20 3 0.15
+#> 44 zone 2 14 25 4 0.16
+#> 45 zone 2 15 13 2 0.154
+```
+
+We can see that each of the 15 features is listed (as a number) for an
+overall summary, summary for zone 1 and summary for zone 2. When looking
+at the `relative_held` column in the `tibble`, we observe that in the
+summary of zone 1 (from row 16 onwards), some features have \>30%
+targets met, whereas others (such as feature 6 and 7) have a very low
+percentage of suitable habitat within selected planning units. We can
+extract the common names of those two features:
+
+``` r
+
+Dict[[1]][6]
+#> [1] "Humpback whale"
+Dict[[1]][7]
+#> [1] "Common Minke whale"
+```
+
+They are both marine mammals and thus had a target of 0% in zone 1 that
+was the reptile-specific zone. The percentage of selected suitable
+habitat is not 0% despite the target of 0 because a proportion of
+suitable habitat of mammals was selected incidentally when selecting
+planning units in this zone by meeting the targets for reptiles. The
+same applies for zone 2. We can also plot the final solution again:
+
+``` r
+
+(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
+ ))
+```
+
+
+
+#### Boundary penalty
+
+Similar to “normal” priritisations, zones also allows including a
+boundary penalty. There are several options how this can be done within
+zones or between zones.
+
+##### Within the same zone
+
+``` r
+
+zm1 <- diag(2)
+print(zm1)
+#> [,1] [,2]
+#> [1,] 1 0
+#> [2,] 0 1
+```
+
+The zeros in this matrix denote that there is no penalty between zones,
+whereas ones introduce a boundary penalty when we define the
+conservation problem. Here, we only introduce penalties within zone 1
+AND zone 2 respectively.
+
+``` r
+
+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()
+```
+
+With `add_boundary_penalties()` we set a penalty of 0.5 between the
+zones we defined in `zm1`. For the purpose of this example, we also set
+a 10 second time limit for the prioritization. The results show less
+fragmentation than in the previous solution without penalties:
+
+``` r
+
+(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
+ ))
+```
+
+
+
+A boundary penalty can also be introduced to only one zone:
+
+``` r
+
+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
+ ))
+```
+
+
+
+##### Across zones
+
+Similarly, penalties can be applied between zones if specified in the
+problem.
+
+``` r
+
+zm3 <- matrix(1, ncol = 2, nrow = 2)
+print(zm3)
+#> [,1] [,2]
+#> [1,] 1 1
+#> [2,] 1 1
+```
+
+``` r
+
+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
+ ))
+```
+
+
+
+#### Adding constraints
+
+Another addition often used in conservation planning are constraints. We
+often lock in or lock out areas of interest for various reasons. In this
+example, we will lock in already existing MPAs in one of the zones.
+
+When using zones with constraints, we use the `prioritizr` function
+`add_manual_locked_constraints()` that requires the input to be in a
+specific format, so we first prepare the MPA data.
+
+``` r
+
+mpas <- MPAsCoralSea %>%
+ dplyr::mutate(zone = "zone 1") %>%
+ dplyr::rename(status = wdpa) %>%
+ tibble::rowid_to_column("pu") %>%
+ sf::st_drop_geometry() %>%
+ tibble::tibble() %>%
+ dplyr::filter(status == 1)
+```
+
+We need to specify which zone the constraint should be applied to, give
+information on the Planning Unit identifier, rename the column of
+interest to “status” and filter out only the Planning Units that should
+be locked-in.
+
+``` r
+
+# NOTE: When using sf input, we need as many cost columns as we have zones
+p6 <- 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_manual_locked_constraints(mpas) %>%
+ prioritizr::add_relative_targets(target2) %>%
+ prioritizr::add_binary_decisions() %>%
+ prioritizr::add_default_solver(time_limit = 10, verbose = FALSE)
+
+s6 <- p6 %>%
+ prioritizr::solve.ConservationProblem()
+```
+
+The results can the be visualized again:
+
+``` r
+
+(gg_s6 <- splnr_plot_solution(
+ s6,
+ zones = TRUE,
+ colorVals = c("#c6dbef", "#3182bd", "black"),
+ legendLabels = c("Not selected", "Zone 1", "Zone 2")
+) +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, lockIn = MPAsCoralSea,
+ nameLockIn = "wdpa", typeLockIn = "Full",
+ colorLockIn = "lightgrey", alphaLockIn = 0.2, overlay = landmass,
+ labelLockIn = "Current MPAs", cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+
+
+#### Objective functions
+
+So far we have only used the minimum set objective function to meet all
+conservation targets whilst minimizing the cost. However, this is not
+the only objective function available in `prioritizr`. For example when
+maximising mangrove ecosystem services, we employed a minimum shortfall
+objective function instead [(Dabalà et al
+2022)](https://www.researchgate.net/publication/363818810_Priority_areas_to_protect_mangroves_and_maximise_ecosystem_services).
+For this objective function, we allocate a budget that cannot be
+exceeded (for example area \>30%) whilst still trying to minimise the
+cost and meeting the targets - but not all targets might be met
+(shortfall).
+
+Zones also works with objective functions other than the minimum set
+objective function.
+
+``` r
+
+# NOTE: When using sf input, we need as many cost columns as we have zones
+p7 <- 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_shortfall_objective(c(8, 0.3)) %>%
+ prioritizr::add_relative_targets(target2) %>%
+ prioritizr::add_binary_decisions() %>%
+ prioritizr::add_default_solver(time_limit = 10, verbose = FALSE)
+```
+
+Here we apply `add_min_shortfall_objective()` and provide to separate
+budgets for the two zones (8 and 0.3). We can visualize the output again
+after solving the conservation problem.
+
+``` r
+
+s7 <- p7 %>%
+ prioritizr::solve.ConservationProblem()
+
+(gg_s7 <- splnr_plot_solution(
+ s7,
+ 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
+ ))
+```
+
+
+
+#### Alternative: linear constraints
+
+Sometimes a spatial plan might be needed that requires minimising
+several costs at once, but a binary output (inside the protected
+area/outside the protected area) is sufficient. In this case, using
+linear constraints instead of zones might be a simpler and more
+time-efficient way forward.
+
+Linear constraints make sure that all planning units in the selected
+area meet the criteria given in the constraint. For example, when using
+an area-based cost (lowest number of planning units to meet the target),
+we might also simultaneously want to minimise the cost to fisheries and
+keep it below a certain threshold. Inversely, we might want to minimise
+the cost to fisheries but also not select more than 30% of the area.
+
+In our example, we fill first define our targets and a random cost layer
+with values ranging from 0 to 1.
+
+``` r
+
+target8 <- rep(0.3, nrow(Dict))
+
+set.seed <- 10 # Add seed so the problem below solves each time
+
+costRandom <- datEx_species_bin %>%
+ dplyr::mutate(CostR = runif(n = dim(.)[[1]])) %>%
+ dplyr::select("CostR")
+```
+
+We then define and solve our conservation problem:
+
+``` r
+
+p8 <- prioritizr::problem(
+ datEx_species_bin %>% dplyr::mutate(Cost1 = rep(1, 397)),
+ col_name,
+ "Cost1"
+) %>%
+ prioritizr::add_min_set_objective() %>%
+ prioritizr::add_relative_targets(target8) %>%
+ prioritizr::add_linear_constraints(sum(costRandom$CostR) * 0.1,
+ sense = "<=", costRandom$CostR
+ ) %>%
+ prioritizr::add_binary_decisions() %>%
+ prioritizr::add_default_solver(verbose = FALSE)
+
+s8 <- p8 %>%
+ prioritizr::solve.ConservationProblem()
+```
+
+Based on the problem definition, we want to meet the targets for our
+biodiversity features whilst selecting the lowest number of planning
+units possible. However, the solution also depends on the threshold of
+the linear constraint specified with `add_linear_constraints()`in the
+problem. Specifically, the planning units selected in the solution can
+not exceed 10% of the total cost of all planning units in
+`costRandom$CostR`.
+
+We can visualise the solution again:
+
+``` r
+
+(gg_s8 <- splnr_plot_solution(s8) +
+ splnr_gg_add(PUs = PUs, Bndry = Bndry, overlay = landmass, cropOverlay = PUs, ggtheme = splnr_theme))
+```
+
+
+
+**NOTE:** We can also use multiple linear constraints in the same plan,
+however, this might require a normalization of the input data to have
+the constraints in comparable units, and a careful tuning of the
+thresholds, so `prioritizr` is still able to solve the problem.
+
+#### Common targets across zones
+
+Sometimes it might be required to meet a (common) conservation target
+across multiple zones, so several zones contribute to reaching the
+target. For this, we need to define a target across zones (here: 30% of
+all features across zones):
+
+``` r
+
+targetAcross <- dplyr::tibble(
+ feature = col_name,
+ zone = list(c("zone1", "zone2"))[rep(1, length(col_name))],
+ target = rep(0.3, length(col_name)),
+ type = rep("relative", length(col_name))
+)
+```
+
+We then need to bring our data in a specific format that requires us to
+have an individual column for a feature in a specific zone, so if we
+have `spp1` and two zones (`zone1` an `zone2`), then we have to have two
+separate columns of the input data: `spp1_zone1` and `spp1_zone2`. The
+species names and zone names have to be exactly those specified in the
+`zones()` object and have to separated by a `_`.
+
+``` r
+
+datSpecZone1 <- datEx_species_bin %>%
+ dplyr::rename_at(dplyr::vars(-geometry), ~ paste0(.x, "_zone1"))
+
+featuresZone1 <- datSpecZone1 %>%
+ sf::st_drop_geometry() %>%
+ colnames()
+
+datSpecZone2 <- datEx_species_bin %>%
+ dplyr::rename_at(dplyr::vars(-geometry), ~ paste0(.x, "_zone2"))
+
+featuresZone2 <- datSpecZone2 %>%
+ sf::st_drop_geometry() %>%
+ colnames()
+```
+
+We also extract the new feature names and then create the `zones`
+object, before joining the two newly created data frames to an file that
+will be used in the prioriztisation.
+
+``` r
+
+z10 <- prioritizr::zones(
+ featuresZone1,
+ featuresZone2,
+ zone_names = c("zone1", "zone2"),
+ feature_names = col_name
+)
+
+out_sf <- datSpecZone1 %>%
+ sf::st_join(datSpecZone2, join = sf::st_equals) %>%
+ dplyr::mutate(
+ Cost1 = runif(n = dim(.)[[1]]) * 100,
+ Cost2 = runif(n = dim(.)[[1]]) * 300
+ )
+```
+
+We can see here that we defined to (random) cost layers with the cost
+layer for `zone2` being three times as costly as for `zone1`.
+
+``` r
+
+p10 <- prioritizr::problem(out_sf,
+ z10,
+ cost_column = c("Cost1", "Cost2")
+) %>%
+ prioritizr::add_min_set_objective() %>%
+ prioritizr::add_manual_targets(targetAcross) %>%
+ prioritizr::add_binary_decisions() %>%
+ prioritizr::add_default_solver(verbose = FALSE)
+
+s10 <- p10 %>%
+ prioritizr::solve.ConservationProblem()
+```
+
+After setting up and solving the conservation problem, we can have a
+look at the resulting solution and how well the targets are met.
+
+``` r
+
+s10F <- s10 %>%
+ dplyr::select(tidyselect::starts_with(c("solution"))) %>%
+ sf::st_drop_geometry() %>%
+ tibble::as_tibble()
+
+r10 <- prioritizr::eval_feature_representation_summary(p10, s10F)
+print(r10)
+#> # A tibble: 45 × 5
+#> summary feature total_amount absolute_held relative_held
+#>
+#> 1 overall Chelonia_mydas 44 14 0.318
+#> 2 overall Caretta_caretta 44 14 0.318
+#> 3 overall Eretmochelys_imbricata 48 15 0.312
+#> 4 overall Lepidochelys_olivacea 44 14 0.318
+#> 5 overall Crocodylus_porosus 42 14 0.333
+#> 6 overall Megaptera_novaeangliae 776 234 0.302
+#> 7 overall Balaenoptera_acutorostrata 476 146 0.307
+#> 8 overall Dugong_dugon 26 10 0.385
+#> 9 overall Carcharias_taurus 44 14 0.318
+#> 10 overall Galeocerdo_cuvier 72 25 0.347
+#> # ℹ 35 more rows
+```
+
+The overall summary shows that every feature’s suitable habitat was
+represented by at least 30% which was the combined target we had set.
+However, we can see that features from `zone1` were a lot more
+frequently selected than `zone2` because `zone2` is three times as
+costly.
+
+``` r
+
+(gg_s10 <- splnr_plot_solution(s10,
+ 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
+ ))
+```
+
+
+
+The plot also reflects the observation above that PUs were more
+frequently selected in `zone1`. What if we wanted to constrain this, so
+that `zone1` is less often selected and `zone2` more often?
+
+#### Targets across zones with linear constraints
+
+We can include linear constraints for `zone1` above, so that its area
+does not exceed 30% of the whole area. For this we need to create a
+matrix that contains the data for the constraint that we want to
+include. Although we only want to put the linear constraint on `zone1`,
+`prioritizr` still requires the matrix to have as many columns as there
+are zones. Thus, we set the area cost to `1` for `zone1` where we want
+to have the constraint and to all `0` in `zone2` where we do not want to
+introduce a linear constraint.
+
+``` r
+
+CostArea <- out_sf %>%
+ dplyr::mutate(
+ areaCostZone1 = rep(1, 397),
+ areaCostZone2 = rep(0, 397)
+ ) %>%
+ sf::st_drop_geometry() %>%
+ dplyr::select("areaCostZone1", "areaCostZone2") %>%
+ as.matrix()
+```
+
+We then define the conservation problem and add a linear constraint for
+30% of the area.
+
+``` r
+
+p11 <- prioritizr::problem(out_sf,
+ z10,
+ cost_column = c("Cost1", "Cost2")
+) %>%
+ prioritizr::add_min_set_objective() %>%
+ prioritizr::add_linear_constraints(sum(CostArea[, 1]) * 0.3,
+ sense = "<=", CostArea
+ ) %>%
+ prioritizr::add_manual_targets(targetAcross) %>%
+ prioritizr::add_binary_decisions() %>%
+ prioritizr::add_default_solver(verbose = FALSE)
+
+s11 <- p11 %>%
+ prioritizr::solve.ConservationProblem()
+```
+
+``` r
+
+s11F <- s11 %>%
+ dplyr::select(tidyselect::starts_with(c("solution"))) %>%
+ sf::st_drop_geometry() %>%
+ tibble::as_tibble()
+
+r11 <- prioritizr::eval_feature_representation_summary(p11, s11F)
+print(r11)
+#> # A tibble: 45 × 5
+#> summary feature total_amount absolute_held relative_held
+#>
+#> 1 overall Chelonia_mydas 44 14 0.318
+#> 2 overall Caretta_caretta 44 14 0.318
+#> 3 overall Eretmochelys_imbricata 48 15 0.312
+#> 4 overall Lepidochelys_olivacea 44 14 0.318
+#> 5 overall Crocodylus_porosus 42 14 0.333
+#> 6 overall Megaptera_novaeangliae 776 234 0.302
+#> 7 overall Balaenoptera_acutorostrata 476 144 0.303
+#> 8 overall Dugong_dugon 26 9 0.346
+#> 9 overall Carcharias_taurus 44 14 0.318
+#> 10 overall Galeocerdo_cuvier 72 24 0.333
+#> # ℹ 35 more rows
+```
+
+The selected planning units are now more equally distributed across
+zones, which is also observable in the plot:
+
+``` r
+
+(gg_s11 <- splnr_plot_solution(
+ s11,
+ 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
+ ))
+```
+
+
+
+However, we also expect the cost for the spatial plan to be higher than
+the previous one.
+
+#### Targets across some (but not all) zones
+
+For this example, we want an target of 30% of all suitable reptile
+habitat for zone 1 and zone 2. Additionally, we set a target of 20% in
+zone 2 for marine mammals and a target of 5% for sharks and rays in zone
+3.
+
+``` r
+
+targetAcrossSome <- Dict %>%
+ dplyr::mutate(
+ target = dplyr::case_when(
+ category == "Reptiles" ~ 30 / 100,
+ category == "Mammals" ~ 10 / 100,
+ category == "Sharks and rays" ~ 5 / 100,
+ TRUE ~ 0
+ ),
+ zone = dplyr::case_when(
+ category == "Reptiles" ~ list(c("zone1", "zone2")),
+ category == "Mammals" ~ list("zone2"),
+ category == "Sharks and rays" ~ list("zone3"),
+ TRUE ~ list(c("zone1", "zone2", "zone3"))
+ ),
+ type = rep("relative", length(col_name))
+ ) %>%
+ dplyr::rename(feature = "nameVariable") %>%
+ dplyr::select(-"category", -"nameCommon")
+```
+
+We then create a zones object for three different zones:
+
+``` r
+
+datSpecZone1 <- datEx_species_bin %>%
+ dplyr::rename_at(dplyr::vars(-geometry), ~ paste0(.x, "_zone1"))
+
+featuresZone1 <- datSpecZone1 %>%
+ sf::st_drop_geometry() %>%
+ colnames()
+
+datSpecZone2 <- datEx_species_bin %>%
+ dplyr::rename_at(dplyr::vars(-geometry), ~ paste0(.x, "_zone2"))
+
+featuresZone2 <- datSpecZone2 %>%
+ sf::st_drop_geometry() %>%
+ colnames()
+
+datSpecZone3 <- datEx_species_bin %>%
+ dplyr::rename_at(dplyr::vars(-geometry), ~ paste0(.x, "_zone3"))
+
+featuresZone3 <- datSpecZone3 %>%
+ sf::st_drop_geometry() %>%
+ colnames()
+
+z12 <- prioritizr::zones(
+ featuresZone1,
+ featuresZone2,
+ featuresZone3,
+ zone_names = c("zone1", "zone2", "zone3"),
+ feature_names = col_name
+)
+```
+
+We then create a joint `sf` object of all zones and their respective
+costs.
+
+``` r
+
+# NOTE: When using sf input, we need as many cost columns as we have zones
+out_sf <- datSpecZone1 %>%
+ sf::st_join(datSpecZone2, join = sf::st_equals) %>%
+ sf::st_join(datSpecZone3, join = sf::st_equals) %>%
+ dplyr::mutate(geometry = datEx_species_bin$geometry) %>%
+ sf::st_as_sf() %>%
+ dplyr::mutate(
+ Cost1 = runif(n = dim(.)[[1]]) * 100,
+ Cost2 = runif(n = dim(.)[[1]]) * 300,
+ Cost3 = runif(n = dim(.)[[1]]) * 200
+ )
+```
+
+``` r
+
+p12 <- prioritizr::problem(out_sf,
+ z12,
+ cost_column = c("Cost1", "Cost2", "Cost3")
+) %>%
+ prioritizr::add_min_set_objective() %>%
+ prioritizr::add_manual_targets(targetAcrossSome) %>%
+ prioritizr::add_binary_decisions() %>%
+ prioritizr::add_default_solver(verbose = FALSE)
+
+s12 <- p12 %>%
+ prioritizr::solve.ConservationProblem()
+```
+
+``` r
+
+s12F <- s12 %>%
+ dplyr::select(tidyselect::starts_with(c("solution"))) %>%
+ sf::st_drop_geometry() %>%
+ tibble::as_tibble()
+
+r12 <- prioritizr::eval_feature_representation_summary(p12, s12F)
+print(r12)
+#> # A tibble: 60 × 5
+#> summary feature total_amount absolute_held relative_held
+#>
+#> 1 overall Chelonia_mydas 66 16 0.242
+#> 2 overall Caretta_caretta 66 16 0.242
+#> 3 overall Eretmochelys_imbricata 72 17 0.236
+#> 4 overall Lepidochelys_olivacea 66 16 0.242
+#> 5 overall Crocodylus_porosus 63 16 0.254
+#> 6 overall Megaptera_novaeangliae 1164 64 0.0550
+#> 7 overall Balaenoptera_acutorostrata 714 44 0.0616
+#> 8 overall Dugong_dugon 39 8 0.205
+#> 9 overall Carcharias_taurus 66 16 0.242
+#> 10 overall Galeocerdo_cuvier 108 19 0.176
+#> # ℹ 50 more rows
+```
+
+``` r
+
+(gg_s12 <- splnr_plot_solution(
+ s12,
+ zones = TRUE,
+ colorVals = c("#c6dbef", "#3182bd", "navyblue", "black"),
+ legendLabels = c("Not selected", "Zone 1", "Zone 2", "Zone3")
+) +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+
+
+#### Next steps
+
+##### Short-term
+
+- Test for run time of zones compared to a normal prioritization
+- Communicate zones outcomes effectively (e.g. targets, cost overlay
+ etc.)
+
+##### Longer-term
+
+- How to deal with overlapping zones (at the moment `prioritizr`
+ allocates a PU to a single zone)
+- How to connect climate-smart workflow to zones
+- How to handle inputs that would benefit from using different objective
+ functions (e.g. ecosystem services vs biodiversity features)
+- Look into some commonly used data sets for multiple use approaches and
+ think about zone-specific costs, constraints, targets etc.
+- Define our (and Waitt’s) understanding of what multiple-use is and how
+ we want to implement it (can differ now and in the future)
+- [EU Horizon 2020 MUSES-project](https://muses-project.com/): multiple
+ use/multi-use is “the joint use of resources in close geographic
+ proximity by either a single user or multiple users. It is an umbrella
+ term that covers a multitude of use combinations in the marine realm
+ and represents a radical change from the concept of exclusive resource
+ rights to the inclusive sharing of resources and space by one or more
+ users.”
+- [Bonnevie et al. 2019](https://doi.org/10.1016/j.marpol.2019.103533):
+ “multi-use is a specific co-location/coexistence where resources are
+ being shared.”
+- [Schupp et al. 2019](https://doi.org/10.3389/fmars.2019.00165):
+ distinguishes between for different types of multi-uses (one of which
+ is co-location)
+
+](Schupp2019TypesMultipleUse.png)
+
+Types of multiple use in MSP according to [Schupp et
+al. 2019](https://doi.org/10.3389/fmars.2019.00165)
diff --git a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-11-1.png b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-11-1.png
index 2eb73c5..14669ee 100644
Binary files a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-11-1.png and b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-11-1.png differ
diff --git a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-16-1.png b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-16-1.png
index c934201..30dfe4b 100644
Binary files a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-16-1.png and b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-16-1.png differ
diff --git a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-21-1.png b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-21-1.png
index 6861bf9..32bde15 100644
Binary files a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-21-1.png and b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-21-1.png differ
diff --git a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-24-1.png b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-24-1.png
index f0d444a..9492585 100644
Binary files a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-24-1.png and b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-24-1.png differ
diff --git a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-25-1.png b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-25-1.png
index 6df224b..d144d42 100644
Binary files a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-25-1.png and b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-25-1.png differ
diff --git a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-27-1.png b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-27-1.png
index f78323b..5fbf52b 100644
Binary files a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-27-1.png and b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-27-1.png differ
diff --git a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-30-1.png b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-30-1.png
index 3f0018b..fb37344 100644
Binary files a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-30-1.png and b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-30-1.png differ
diff --git a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-32-1.png b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-32-1.png
index d414735..8e1334a 100644
Binary files a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-32-1.png and b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-32-1.png differ
diff --git a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-35-1.png b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-35-1.png
index 2cc1b12..0c8386a 100644
Binary files a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-35-1.png and b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-35-1.png differ
diff --git a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-41-1.png b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-41-1.png
index ae1d107..a31139d 100644
Binary files a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-41-1.png and b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-41-1.png differ
diff --git a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-45-1.png b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-45-1.png
index 1035e93..b669daf 100644
Binary files a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-45-1.png and b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-45-1.png differ
diff --git a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-51-1.png b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-51-1.png
index 51202bb..d163c9f 100644
Binary files a/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-51-1.png and b/docs/articles/MultipleUse_files/figure-html/unnamed-chunk-51-1.png differ
diff --git a/docs/articles/index.html b/docs/articles/index.html
index 8aa5b5f..abbba32 100644
--- a/docs/articles/index.html
+++ b/docs/articles/index.html
@@ -7,7 +7,7 @@
spatialplanr
- 0.6.9
+ 0.7.0
@@ -57,7 +57,7 @@
The suitable habitat for Green sea turtles as predicted by Aquamaps
is restricted to few cells close to the coast. If we now compare this
with the predicted suitable habitat for Humpback whales, we can see that
@@ -235,35 +227,35 @@
Convert the probabilities to b
(ggFeature<-splnr_plot(datEx_species_bin,"Megaptera_novaeangliae",
- plot_title ="Megaptera novaeangliae"
+ plotTitle ="Megaptera novaeangliae")+splnr_gg_add( PUs =PUs, Bndry =Bndry, overlay =landmass, cropOverlay =PUs, ggtheme =splnr_theme))
-
+
In our example, this was the only reason why we classified species as
either representative if their suitable habitat is wide-ranging within
the study region or important if they are restricted to a few number of
cells.
To get a better idea of the overall distribution of the used
features, we can also plot the number of features with suitable habitat
-within a planning unit of the study region.
This plot shows the optimal solution for the planning region that
meets the selected targets for the chosen features for the smallest area
possible. The categorical map displays, which of the planning units were
@@ -393,14 +385,14 @@
Importance scores can help to assess the relative importance of an
-individual selected planning unit in the spatial plan (for more
+individual selected Planning Unit in the spatial plan (for more
information, see https://prioritizr.net/reference/importance.html)
Here, we use two different importance scores, the Ferrier Score and
Rarity Weighted Richness.
But we locked-in areas that were already existing Marine Protected
+Areas (MPAs). If we want to show the overlap between the selected
+Planning Units and the current MPAs, we can add this to the
+splnr_gg_add() function.
This plot shows how the first solution (without current MPAs) differs
from the second solution (including current MPAs. The categorical map
displays, which of the planning units were selected in solution 2 but
@@ -615,7 +607,7 @@
Sometimes when multiple spatial plans are generated, we are
-interested in how many times a planning unit is selected across the
+interested in how many times a Planning Unit is selected across the
array of solutions. To demonstrate how this can be done using this
package, we first create an array (= portfolio) of solutions. One
example of this is by using the portfolio
diff --git a/docs/articles/spatialplanr.md b/docs/articles/spatialplanr.md
new file mode 100644
index 0000000..d14731e
--- /dev/null
+++ b/docs/articles/spatialplanr.md
@@ -0,0 +1,702 @@
+# A Basic Spatial Planning Workflow
+
+``` r
+
+library(spatialplanr)
+```
+
+## Overview
+
+This code has been written to simplify the process for running a
+*prioritizr* analysis on a given region. It is still a work in progress
+so feel free to submit pull requests with new features and code
+improvements.
+
+### Set user parameters
+
+You can set a region if it is defined in `splnr_get_planningUnits`.
+
+``` r
+
+Region <- "Coral Sea" # "Australia"
+Type <- "Oceans" # "EEZ"
+```
+
+You can also define a region with square boundaries (in degrees) if you
+need.
+
+``` r
+
+Region <- c(xmin = 150, xmax = 160, ymin = -40, ymax = -30)
+```
+
+Choose CRS for analysis. In this case we use Mollweide
+
+``` r
+
+cCRS <- "ESRI:54009"
+```
+
+Set the diameter of the planning units. This will be in the same units
+as the CRS (usually metres or degrees).
+
+``` r
+
+PU_size <- 107460 # m
+```
+
+### Analysis Region
+
+Start your analysis by defining your region and setting up the planning
+units.
+
+Get the boundary for your chosen region.
+
+``` r
+
+Bndry <- splnr_get_boundary(Limits = Region, Type = Type, cCRS = cCRS)
+```
+
+Get the land boundaries to remove overlap. The object “landmass”
+represents the land mass that should be removed (inverse = FALSE)
+
+``` r
+
+landmass <- rnaturalearth::ne_countries(
+ scale = "medium",
+ returnclass = "sf"
+) %>%
+ sf::st_transform(cCRS)
+```
+
+### Create Planning Units
+
+``` r
+
+PUs <- spatialgridr::get_grid(boundary = Bndry,
+ crs = cCRS,
+ output = "sf_hex",
+ resolution = PU_size)
+```
+
+We can check what the PUs look like
+
+``` r
+
+(ggPU <- splnr_plot(df = PUs) +
+ ggplot2::theme_bw()) # Plot Planning Units
+```
+
+
+
+If we want to add additional properties to our map, for example landmass
+or the boundary, we can use
+[`splnr_gg_add()`](https://mathmarecol.github.io/spatialplanr/reference/splnr_gg_add.md).
+
+``` r
+
+(ggPU <- splnr_plot(df = PUs) +
+ splnr_gg_add(
+ Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = "Default"
+ ))
+```
+
+
+
+We can also use a customised `ggplpot` theme that can be passed as a
+list to
+[`splnr_gg_add()`](https://mathmarecol.github.io/spatialplanr/reference/splnr_gg_add.md)
+and that can then be used for all plots. For example:
+
+``` r
+
+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
+ ))
+```
+
+
+
+### Get the features
+
+For our example, we will use a small subset of charismatic megafauna
+species of the Coral Sea to inform the conservation plan. We filtered
+the Aquamaps (Aquamaps.org) species distribution models for our study
+area for the following species:
+
+``` r
+
+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"
+)
+```
+
+These species were not chosen based on their importance for this region
+and only represent an example for visualization purposes.
+
+**Note:** The structure of the `tribble`above is required for some of
+the downstream plotting. *Common* denotes the common name of a species,
+*nameVariable* the scientific name in the format used by Aquamaps,
+*TaxGroup* is the taxonomic grouping that a species belongs to and
+*Category* represents the importance of the species for the conservation
+plan.
+
+#### Convert the probabilities to binary data
+
+``` r
+
+datEx_species_bin <- spDataFiltered %>%
+ splnr_apply_cutoffs(Cutoffs = 0.5)
+```
+
+We can now look at the feature data used for the spatial plan
+individually by calling
+[`splnr_plot_binFeature()`](https://mathmarecol.github.io/spatialplanr/reference/splnr_plot_binFeature.md),
+for example to see the binary habitat suitability map for Green sea
+turtles:
+
+``` r
+
+(ggFeature1 <- splnr_plot(
+ df = datEx_species_bin,
+ colNames = "Chelonia_mydas",
+ plotTitle = "Chelonia mydas",
+ legendLabels = c("Absence", "Presence")
+) +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ )
+)
+```
+
+
+
+The suitable habitat for Green sea turtles as predicted by Aquamaps is
+restricted to few cells close to the coast. If we now compare this with
+the predicted suitable habitat for Humpback whales, we can see that they
+are fairly ubiquitous across the whole Coral Sea.
+
+``` r
+
+(ggFeature <- splnr_plot(
+ datEx_species_bin,
+ "Megaptera_novaeangliae",
+ plotTitle = "Megaptera novaeangliae"
+) +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+
+
+In our example, this was the only reason why we classified species as
+either representative if their suitable habitat is wide-ranging within
+the study region or important if they are restricted to a few number of
+cells.
+
+To get a better idea of the overall distribution of the used features,
+we can also plot the number of features with suitable habitat within a
+Planning Unit of the study region.
+
+``` r
+
+(ggFeatNo <- splnr_plot(df = datEx_species_bin,
+ colNames = colnames(datEx_species_bin %>%
+ sf::st_drop_geometry()),
+ plotTitle = "",
+ legendTitle = "Number of features") +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+
+
+### Prepare Data for prioritization
+
+For the spatial prioritization we also need to extract the names of our
+features to pass into `prioritizr`.
+
+``` r
+
+feature_names <- splnr_featureNames(datEx_species_bin)
+```
+
+We also create an `sf` object that contains all the information needed
+for the prioritization.
+
+``` r
+
+out_sf <- datEx_species_bin
+```
+
+##### Add Cost
+
+In our example, we use a minimum set objective function, which aims to
+minimize the cost whilst meeting all the conservation targets. We add an
+area-based cost to include as little area as possible in the spatial
+plan whilst meeting the conservation targets. For this, all the planning
+units are assigned an equal cost of 1.
+
+``` r
+
+out_sf$Cost_None <- 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
+ ))
+```
+
+
+
+###### Other features
+
+###### Fishing effort
+
+The gfwr package allows us to recover data from fisheries across the
+world, we set here the parameter `compress` as `TRUE` to recover the
+`Apparent fishing hours` per coordinates.
+
+``` r
+
+gfw_data <- splnr_get_gfw(region = 'Australia',
+ start_date = "2022-01-01",
+ end_date = "2022-12-31",
+ temp_res = "yearly",
+ cCRS = cCRS,
+ compress = TRUE) %>%
+ sf::st_interpolate_aw(PUs, extensive = TRUE)
+
+out_sf$Apparent.Fishing.Hours <- 0 # Add column to PUs
+out_sf$Apparent.Fishing.Hours[as.numeric(rownames(PUs))] <-
+ gfw_data$Apparent.Fishing.Hours # Put corresponding data in PUs
+
+
+(ggCost <- splnr_plot(out_sf, colNames = "Apparent.Fishing.Hours") +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+###### Other features
+
+Many features can be taken into account as cost layers before the
+prioritization, we provide here different features from the
+`oceandatr`package.
+
+### Set Targets
+
+As shown previously, we assigned the conservation features a class
+reflecting their importance in the planning region. Conservation targets
+are then assigned a target based on their class, in our case 30% of
+suitable habitat of important and 10% of representative features.
+
+``` r
+
+catTarg <- c("Reptiles" = 0.3, "Mammals" = 0.1, "Sharks and rays" = 0.1, "Birds" = 0.1)
+
+target <- Dict %>%
+ splnr_targets_byCategory(catTarg, catName = "category")
+```
+
+**Note:** The assigned classes and targets were not based on any
+ecological information and only chosen for visualization purposes.
+
+### Set up conservation problem
+
+``` r
+
+datEx_problem <- prioritizr::problem(out_sf, feature_names, "Cost_None") %>%
+ prioritizr::add_min_set_objective() %>%
+ prioritizr::add_relative_targets(target$target) %>%
+ prioritizr::add_binary_decisions() %>%
+ prioritizr::add_default_solver(verbose = FALSE)
+```
+
+### Solve the conservation problem
+
+``` r
+
+datEx_soln <- datEx_problem %>%
+ prioritizr::solve.ConservationProblem()
+```
+
+### Visualize Output
+
+There are different ways to visualize the output of the prioritization
+that can be loosely grouped into three categories: *+* Visualization of
+the solution *+* Visualization of targets *+* Visualization of
+importance scores
+
+#### Visualization of the solution
+
+``` r
+
+(ggSoln <- splnr_plot(datEx_soln,
+ colNames = "solution_1",
+ legendTitle = "Solution",
+ legendLabels = c("0","1")) +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+
+
+This plot shows the optimal solution for the planning region that meets
+the selected targets for the chosen features for the smallest area
+possible. The categorical map displays, which of the planning units were
+selected as important for meeting the conservation targets (dark blue)
+and which were not selected (light blue). This can also be done with an
+overlay of the cost to show how the solution avoids highly costly areas:
+
+``` r
+
+(ggCostOverlay <- splnr_plot_costOverlay(
+ soln = datEx_soln,
+ cost = NA,
+ costName = "Cost_None"
+) +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+
+
+**Note:** In our example, cost is equal for all planning units.
+
+#### Visualization of targets
+
+To visualize how well the targets are met, we first need to extract how
+much suitable habitat of each feature are selected in the spatial plan.
+This also includes potential incidental coverage of feature that were
+not included in the spatial plan but can still be found in the planning
+region.
+
+``` r
+
+dfTarget <- splnr_get_featureRep(datEx_soln, datEx_problem,
+ climsmart = FALSE,
+ solnCol = "solution_1"
+)
+
+
+(ggTarget <- splnr_plot_featureRep(dfTarget,
+ category = Dict,
+ renameFeatures = TRUE,
+ namesToReplace = Dict,
+ categoryFeatureCol = "nameCommon",
+ nr = 1, showTarget = TRUE,
+))
+```
+
+
+
+For a circular bar plot, one additional step of data preparation needs
+to be done.
+
+``` r
+
+dfTargetCirc <- dfTarget %>%
+dplyr::select("feature", "value", "group") %>%
+na.omit()
+
+colors <- c(
+ "important" = "darkgreen",
+ "representative" = "darkred"
+)
+legends <- c("Important", "Representative")
+
+(ggCircTarg <- splnr_plot_circBplot(df = dfTargetCirc, legend_list = legends, legend_color = colors, impTarget = 30, repTarget = 10))
+```
+
+#### Visualization of importance scores
+
+Importance scores can help to assess the relative importance of an
+individual selected Planning Unit in the spatial plan (for more
+information, see )
+
+Here, we use two different importance scores, the Ferrier Score and
+Rarity Weighted Richness.
+
+``` r
+
+ggFerrier <- splnr_plot_importanceScore(
+ soln = datEx_soln,
+ pDat = datEx_problem,
+ method = "Ferrier",
+ decimals = 4,
+ legendTitle = "Importance Score \n(Ferrier Score)"
+) +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ )
+#> Calculating Ferrier Score.
+
+ggRWR <- splnr_plot_importanceScore(
+ soln = datEx_soln,
+ pDat = datEx_problem,
+ method = "RWR",
+ decimals = 2,
+ legendTitle = "Importance Score \n(Rarity Weighted Richness)"
+) +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ )
+#> Calculating Rarity Weighted Richness.
+
+(ggScores <- patchwork::wrap_plots(ggFerrier + ggRWR))
+```
+
+
+
+In our example, both scores label similar -coastal- planning units as
+most important for the spatial plan.
+
+### Comparing Spatial Plans
+
+Sometimes it can be useful to have a direct comparison of two spatial
+plans. To show how to achieve this with this package, we first need a
+second conservation problem and resulting solution.
+
+Here, our second spatial plan will include already existing marine
+protected areas in the area
+() with
+the following characteristics: \* Status = c(“Designated”,
+“Established”, “Inscribed”) \* Designation Type = c(“National”,
+“Regional”, “International”, “Not Applicable”) \* IUCN Category =
+c(“Ia”, “Ib”, “II”, “III”, “IV”)
+
+``` r
+
+# The user can download their own MPAs using this code,
+# but below we use data already within the package.
+LockedIn <- splnr_get_MPAs(PUs, "Australia") %>%
+ splnr_apply_cutoffs(0.5) %>%
+ dplyr::mutate(wdpa = as.logical(wdpa))
+```
+
+``` r
+
+(ggMPA <- splnr_plot(MPAsCoralSea, "wdpa") +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+
+
+We will also include targets based on IUCN categories to prioritise
+species with an IUCN status of:
+
+- Vulnerable
+- Endangered
+- Critically Endangered
+- Extinct in the Wild
+- Extinct
+
+We assign a 30% target to species within these categories. All species
+that do not fall into any of these categories receive an inverse area
+target, so species with a greater area of suitable habitat are assigned
+a lower target.
+
+``` r
+
+
+minTarget <- 0.1
+maxTarget <- 0.2
+
+# Create inverse area target
+IA_Targets <- splnr_targets_byInverseArea(
+ datEx_species_bin,
+ minTarget,
+ maxTarget
+)
+```
+
+We can also adjust the targets based on the IUCN Category. Here we apply
+an increased target of 0.3 for all species with an increased thread
+level on the IUCN Red List(“EX”, “EW”, “CR”, “EN”, “VU”).
+
+``` r
+
+
+IUCN_IA_Targets <- IA_Targets %>%
+ splnr_get_IUCNRedList(species_col = "Species") %>% # Add RL data to the df
+ splnr_targets_byIUCN(IUCN_target = 0.3)
+```
+
+**Note:** 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()`](https://docs.ropensci.org/rredlist/reference/rl_use_iucn.html).
+
+#### Set up second conservation problem
+
+``` r
+
+datEx_problem2 <- prioritizr::problem(out_sf, feature_names, "Cost_None") %>%
+ prioritizr::add_min_set_objective() %>%
+ prioritizr::add_relative_targets(IA_Targets$target) %>%
+ prioritizr::add_locked_in_constraints(as.logical(MPAsCoralSea$wdpa)) %>%
+ prioritizr::add_binary_decisions() %>%
+ prioritizr::add_default_solver(verbose = FALSE)
+
+# Add a solution object
+datEx_soln2 <- datEx_problem2 %>%
+ prioritizr::solve.ConservationProblem()
+
+(ggSoln2 <- splnr_plot_solution(datEx_soln2) +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+
+
+But we locked-in areas that were already existing Marine Protected Areas
+(MPAs). If we want to show the overlap between the selected Planning
+Units and the current MPAs, we can add this to the
+[`splnr_gg_add()`](https://mathmarecol.github.io/spatialplanr/reference/splnr_gg_add.md)
+function.
+
+``` r
+
+(splnr_plot_solution(datEx_soln2) +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, lockIn = MPAsCoralSea,
+ nameLockIn = "wdpa", typeLockIn = "Full",
+ colorLockIn = "lightgrey", alphaLockIn = 0.2, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+
+
+If we instead only want to see the contours of the locked-in areas we
+can set `typeLockIn = "Contours"` in
+[`splnr_gg_add()`](https://mathmarecol.github.io/spatialplanr/reference/splnr_gg_add.md).
+
+``` r
+
+(splnr_plot_solution(datEx_soln2) +
+ splnr_gg_add(
+ lockIn = MPAsCoralSea,
+ nameLockIn = "wdpa", typeLockIn = "Contours",
+ colorLockIn = "lightgrey", alphaLockIn = 0.2, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+
+
+#### Visualize comparison
+
+``` r
+
+(ggComp <- splnr_plot_comparison(datEx_soln, datEx_soln2) +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+
+
+This plot shows how the first solution (without current MPAs) differs
+from the second solution (including current MPAs. The categorical map
+displays, which of the planning units were selected in solution 2 but
+not in solution 1 (red), in solution 1 but not in solution 2 (blue), or
+selected in both solutions (grey).
+
+``` r
+
+CorrMat <- splnr_get_kappaCorrData(list(datEx_soln, datEx_soln2),
+ name_sol = c("soln1", "soln2")
+)
+
+(ggCorr <- splnr_plot_corrMat(CorrMat,
+ AxisLabels = c("Solution 1", "Solution 2")
+))
+```
+
+
+
+The correlation matrix shows the similarity as the Cohen’s Kappa
+correlation between solution 1 and solution 2.
+
+#### Plotting selection frequency
+
+Sometimes when multiple spatial plans are generated, we are interested
+in how many times a Planning Unit is selected across the array of
+solutions. To demonstrate how this can be done using this package, we
+first create an array (= portfolio) of solutions. One example of this is
+by using the portfolio
+
+``` r
+
+datEx_soln_portfolio <- datEx_problem %>%
+ prioritizr::add_cuts_portfolio(5) %>% # create a portfolio of solutions
+ prioritizr::solve.ConservationProblem()
+
+selFreq <- datEx_soln_portfolio %>% # calculate selection frequency
+ sf::st_drop_geometry() %>%
+ dplyr::mutate(selFreq = as.factor(rowSums(
+ dplyr::select(., dplyr::starts_with("solution_"))
+ ))) %>%
+ sf::st_as_sf(geometry = datEx_soln_portfolio$geometry) %>%
+ dplyr::select(selFreq)
+
+(ggselFreq <- splnr_plot_selectionFreq(selFreq) +
+ splnr_gg_add(
+ PUs = PUs, Bndry = Bndry, overlay = landmass,
+ cropOverlay = PUs, ggtheme = splnr_theme
+ ))
+```
+
+
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-10-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-10-1.png
index bfcd744..2c26872 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-10-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-10-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-11-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-11-1.png
index daaade9..c33b477 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-11-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-11-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-14-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-14-1.png
index cb100d1..865ca7b 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-14-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-14-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-15-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-15-1.png
index 1071385..f06963e 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-15-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-15-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-16-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-16-1.png
index b44cb57..08298a8 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-16-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-16-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-19-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-19-1.png
index e05d71e..18f6723 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-19-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-19-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-26-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-26-1.png
index 369d471..502f97a 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-26-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-26-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-27-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-27-1.png
index 9f3dd19..5cada72 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-27-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-27-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-30-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-30-1.png
index d1ecd2f..a99c840 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-30-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-30-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-32-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-32-1.png
index 9af7aea..dce7d56 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-32-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-32-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-35-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-35-1.png
index 2eae88f..7e4f7d9 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-35-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-35-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-36-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-36-1.png
index 5f06041..fc7c81f 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-36-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-36-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-37-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-37-1.png
index 13ec7f4..32bb997 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-37-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-37-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-38-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-38-1.png
index 561f881..fe61114 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-38-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-38-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-39-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-39-1.png
index c548357..0732906 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-39-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-39-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-40-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-40-1.png
index 3635e50..e754631 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-40-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-40-1.png differ
diff --git a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-9-1.png b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-9-1.png
index 3ca4357..797fd5a 100644
Binary files a/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-9-1.png and b/docs/articles/spatialplanr_files/figure-html/unnamed-chunk-9-1.png differ
diff --git a/docs/authors.html b/docs/authors.html
index bff97be..fb86fef 100644
--- a/docs/authors.html
+++ b/docs/authors.html
@@ -7,7 +7,7 @@
spatialplanr
- 0.6.9
+ 0.7.0
@@ -55,13 +55,13 @@
@Manual{,
title = {spatialplanr: Help files for prioritzr Spatial Planning projects},
author = {Jason D. Everett and Sandra Neubert},
year = {2025},
- note = {R package version 0.6.9},
+ note = {R package version 0.7.0},
url = {https://github.com/SpatialPlanning/spatialplanr},
}
This package is designed to assist students and staff in the Mathematical Marine Ecology Lab 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 robust protected area networks.