Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
^docs$
^pkgdown$
^\.github$
^doc$
^Meta$
figure$
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
.httr-oauth
.DS_Store
inst/doc
/doc/
/Meta/
9 changes: 2 additions & 7 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: patchwise
Title: Create Patches of Feature Groups for Use in Spatial Prioritizations
Version: 0.1.0
Version: 0.2.0
Authors@R: c(
person(given = "Echelle S.", family = "Burns", email = "[email protected]", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-3902-1410")),
person(given = "Jason", family = "Flower", email = "[email protected]", role = c("aut"), comment = c(ORCID = "0000-0002-6731-8182"))
Expand All @@ -20,18 +20,13 @@ Imports:
tidyselect,
rlang
Roxygen: list(markdown = TRUE)
Remotes:
github::emlab-ucsb/spatialgridr,
github::emlab-ucsb/oceandatr
RoxygenNote: 7.3.1
Suggests:
knitr,
rmarkdown,
codetools,
testthat (>= 3.0.0),
oceandatr,
spatialgridr,
prioritizr
Config/testthat/edition: 3
VignetteBuilder: knitr
URL: https://emlab-ucsb.github.io/patchwise/
Config/roxygen2/version: 8.1.0
63 changes: 32 additions & 31 deletions R/constraints_targets.R
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
#' Create a dataframe for manual targets for all layers, including the features and the constraints
#' Create a dataframe for manual targets for all layers, including the features
#' and the constraints
#'
#' @description This function creates a dataframe with the comibination of feature targets, generated by `features_targets()` and the targets for constraints to be used in prioritizr
#' @description This function creates a dataframe with the combination of
#' feature targets, generated by `features_targets()` and the targets for
#' constraints to be used in prioritizr
#'
#' @param feature_targets a dataframe of feature targets generated by `features_targets()`
#' @param patch_df a dataframe generated by `create_patch_df()` that includes constraints for each patch and grid cell combination
#' @param feature_targets a dataframe of feature targets generated by
#' `features_targets()`
#' @param patch_df a dataframe generated by `create_patch_df()` that includes
#' constraints for each patch and grid cell combination
#'
#' @return A dataframe to be used to specify all manual targets for prioritizr
#' @export
#'
#' @examples
#'# Start with a little housekeeping to get the data from oceandatr
#'# Choose area of interest (Bermuda EEZ)
#'area <- oceandatr::get_area(area_name = "Bermuda", mregions_column = "territory1")
#'projection <-'+proj=laea +lon_0=-64.8108333 +lat_0=32.3571917 +datum=WGS84 +units=m +no_defs'
#'# Create a planning grid
#'planning_raster <- spatialgridr::get_grid(area, projection = projection)
#'# Grab all relevant data
#'features_raster <- oceandatr::get_features(spatial_grid = planning_raster)
#'# Separate seamount data - we want to protect entire patches
#'seamounts_raster <- features_raster[["seamounts"]]
#'features_raster <- features_raster[[names(features_raster)[names(features_raster) != "seamounts"]]]
#'# Create a "cost" to protecting a cell - just a uniform cost for this example
#'cost_raster <- stats::setNames(planning_raster, "cost")
#'# Create patches from layer
#'patches_raster <- create_patches(seamounts_raster)
#'# Create patch dataframe
#'patches_raster_df <- create_patch_df(spatial_grid = planning_raster, features = features_raster,
#' patches = patches_raster, costs = cost_raster)
#'# Create boundary matrix for prioritizr
#'boundary_matrix <- create_boundary_matrix(spatial_grid = planning_raster,
#' patches = patches_raster, patch_df = patches_raster_df)
#'# Create target features - using just 20% for every feature
#'features_targets <- features_targets(targets = rep(0.2, (terra::nlyr(features_raster)) + 1),
#' features = features_raster, pre_patches = seamounts_raster)
#'# Create constraint targets
#'constraint_targets <- constraints_targets(feature_targets = features_targets,
#' patch_df = patches_raster_df)
#'# Import some planning data
#'
#'#import planning units/ cost raster
#'pu_raster <- terra::rast(system.file("extdata/pu_raster.tif", package = "patchwise"))

#'#import species distributions - feature data for planning
#'species_distributions <- terra::rast(system.file("extdata/spp_distributions.tif", package = "patchwise"))
#'
#'#import seamounts
#'seamounts <- terra::rast(system.file("extdata/seamounts.tif", package = "patchwise"))
#'
#'# Create seamount patches as multi-layer raster
#'patches_raster <- create_patches(seamounts)
#'
#'patches_df <- create_patch_df(spatial_grid = pu_raster, features = species_distributions,
#'patches = patches_raster, costs = pu_raster)
#'
#'# Create targets for protection - use 20% for each feature (including 20% of whole seamounts) in this example
#'targets_df <- features_targets(targets = rep(0.2, (terra::nlyr(species_distributions) + 1)), features = species_distributions, pre_patches = seamounts)
#'
#'# Add these targets to targets for protection for the "constraints" we introduced to protect entire seamount patches
#'constraints_df <- constraints_targets(feature_targets = targets_df, patch_df = patches_df)


constraints_targets <- function(feature_targets, patch_df) {

Expand Down
97 changes: 51 additions & 46 deletions R/convert_solution.R
Original file line number Diff line number Diff line change
@@ -1,56 +1,61 @@
#' Converts prioritization solution into a more digestible output
#'
#' @description This function converts the prioritization solution that uses patches to a raster or sf object (depending on the format of your spatial_grid) that clearly marks areas suggested for protection (1) and areas not suggested for protection (0)
#' @description This function converts the prioritization solution that uses
#' patches to a raster or sf object (depending on the format of your
#' spatial_grid) that clearly marks areas suggested for protection (1) and
#' areas not suggested for protection (0)
#'
#' @param solution the solution that results from using `prioritizr::solve()` on `prioritizr::problem()`
#' @param patch_df a dataframe generated by `create_patch_df()` that includes constraints for each patch and grid cell combination
#' @param spatial_grid a raster or sf template with the desired resolution and coordinate reference system generated by `spatialgridr::get_grid()`; values in areas of interest are 1, while all other values are NA (only required if feature is a sf object)
#' @param solution the solution that results from using `prioritizr::solve()` on
#' `prioritizr::problem()`
#' @param patch_df a dataframe generated by `create_patch_df()` that includes
#' constraints for each patch and grid cell combination
#' @param spatial_grid a raster or sf template with the desired resolution and
#' coordinate reference system; values in areas of interest are 1, while all
#' other values are NA (only required if feature is a sf object)
#'
#' @return A raster or sf object that denotes areas suggested for protection (value = 1)
#' @return A raster or sf object that denotes areas suggested for protection
#' (value = 1)
#' @export
#'
#' @examples
#' \dontrun{
#'# Start with a little housekeeping to get the data from oceandatr
#'# Choose area of interest (Bermuda EEZ)
#'area <- oceandatr::get_area(area_name = "Bermuda", mregions_column = "territory1")
#'projection <-'+proj=laea +lon_0=-64.8108333 +lat_0=32.3571917 +datum=WGS84 +units=m +no_defs'
#'# Create a planning grid
#'planning_raster <- spatialgridr::get_grid(area, projection = projection)
#'# Grab all relevant data
#'features_raster <- oceandatr::get_features(spatial_grid = planning_raster)
#'# Separate seamount data - we want to protect entire patches
#'seamounts_raster <- features_raster[["seamounts"]]
#'features_raster <- features_raster[[names(features_raster)[names(features_raster) != "seamounts"]]]
#'# Create a "cost" to protecting a cell - just a uniform cost for this example
#'cost_raster <- stats::setNames(planning_raster, "cost")
#'# Create patches from layer
#'patches_raster <- create_patches(seamounts_raster)
#'# Create patch dataframe
#'patches_raster_df <- create_patch_df(spatial_grid = planning_raster, features = features_raster,
#' patches = patches_raster, costs = cost_raster)
#'# Create boundary matrix for prioritizr
#'boundary_matrix <- create_boundary_matrix(spatial_grid = planning_raster, patches = patches_raster,
#' patch_df = patches_raster_df)
#'# Create target features - using just 20% for every feature
#'features_targets <- features_targets(targets = rep(0.2, (terra::nlyr(features_raster)) + 1),
#' features = features_raster, pre_patches = seamounts_raster)
#'# Create constraint targets
#'constraint_targets <- constraints_targets(feature_targets = features_targets,
#' patch_df = patches_raster_df)
#'# Create prioritization problem
#'problem_raster <- prioritizr::problem(x = patches_raster_df,
#' features = constraint_targets$feature, cost_column = "cost") %>%
#' prioritizr::add_min_set_objective() %>%
#' prioritizr::add_manual_targets(constraint_targets) %>%
#' prioritizr::add_binary_decisions() %>%
#' prioritizr::add_boundary_penalties(penalty = 0.000002, data = boundary_matrix) %>%
#' prioritizr::add_default_solver(gap = 0.1, threads = parallel::detectCores()-1)
#'# Solve problem
#'solution <- solve(problem_raster)
#'# Convert to a more digestible format
#'suggested_protection <- convert_solution(solution = solution, patch_df = patches_raster_df,
#' spatial_grid = planning_raster)
#'#import planning units/ cost raster
#'pu_raster <- terra::rast(system.file("extdata/pu_raster.tif", package = "patchwise"))

#'#import species distributions - feature data for planning
#'species_distributions <- terra::rast(system.file("extdata/spp_distributions.tif", package = "patchwise"))
#'
#'#import seamounts
#'seamounts <- terra::rast(system.file("extdata/seamounts.tif", package = "patchwise"))
#'
#'# Create seamount patches as multi-layer raster
#'patches_raster <- create_patches(seamounts)
#'
#'patches_df <- create_patch_df(spatial_grid = pu_raster, features = species_distributions,
#'patches = patches_raster, costs = pu_raster)
#'
#'# Create targets for protection - use 20% for each feature (including 20% of whole seamounts) in this example
#'targets_df <- features_targets(targets = rep(0.2, (terra::nlyr(species_distributions) + 1)), features = species_distributions, pre_patches = seamounts)
#'
#'# Add these targets to targets for protection for the "constraints" we introduced to protect entire seamount patches
#'constraints_df <- constraints_targets(feature_targets = targets_df, patch_df = patches_df)
#'
#'library(prioritizr)
#'
#'# Create the prioritization problem
#'problem_patches <- problem(x = patches_df, features = constraints_df$feature, cost_column = "cost") |>
#' add_min_set_objective() |>
#' add_manual_targets(constraints_df) |>
#' add_binary_decisions() |>
#' add_default_solver()
#'
#'# Solve the problem
#'solution_patches_tbl <- solve(problem_patches)
#'
#'# Convert the solution into a raster using `convert_solution()`
#'sol_rast_patches <- convert_solution(solution = solution_patches_tbl, patch_df = patches_df, spatial_grid = pu_raster)
#'
#'terra::plot(sol_rast_patches)
#' }

convert_solution <- function(solution, patch_df, spatial_grid) {
Expand All @@ -61,7 +66,7 @@ convert_solution <- function(solution, patch_df, spatial_grid) {
if(!check_df(patch_df)) { stop("patch_df must be a dataframe object")}


planning_unit_id <- unique(unlist(patch_df$id[which(solution$solution_1 > 0.5)]))
planning_unit_id <- unique(unlist(patch_df$idx[which(solution$solution_1 > 0.5)]))

if(class(spatial_grid)[1] %in% c("RasterLayer", "SpatRaster")){
solution <- spatial_grid*0
Expand Down
58 changes: 32 additions & 26 deletions R/create_boundary_matrix.R
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
#' Create boundary matrix for prioritizr if you are using patches
#'
#' @description This function creates a boundary matrix to plug into prioritizr
#' @description This function creates a boundary matrix which is required if you
#' want to use a boundary penalty in prioritizr
#'
#' @param spatial_grid a raster or sf template with the desired resolution and coordinate reference system generated by `spatialgridr::get_grid()`; values in areas of interest are 1, while all other values are NA (only required if feature is a sf object)
#' @param patches a raster or sf object generated by `create_patches()`; a single feature split into spatially distinct groups; each layer of the raster or each column of the sf object identifies the location of each patch
#' @param patch_df a dataframe generated by `create_patch_df()` that includes constraints for each patch and grid cell combination
#' @param spatial_grid a raster or sf template with the desired resolution and
#' coordinate reference system; values in areas of interest are 1, while all
#' other values are NA (only required if feature is a sf object)
#' @param patches a raster or sf object generated by `create_patches()`; a
#' single feature split into spatially distinct groups; each layer of the
#' raster or each column of the sf object identifies the location of each
#' patch
#' @param patch_df a dataframe generated by `create_patch_df()` that includes
#' constraints for each patch and grid cell combination
#'
#' @return A boundary matrix to plug into prioritizr
#' @return A sparse matrix
#' @export
#'
#' @examples
#'# Start with a little housekeeping to get the data from oceandatr
#'# Choose area of interest (Bermuda EEZ)
#'area <- oceandatr::get_area(area_name = "Bermuda", mregions_column = "territory1")
#'projection <-'+proj=laea +lon_0=-64.8108333 +lat_0=32.3571917 +datum=WGS84 +units=m +no_defs'
#'# Create a planning grid
#'planning_raster <- spatialgridr::get_grid(area, projection = projection)
#'# Grab all relevant data
#'features_raster <- oceandatr::get_features(spatial_grid = planning_raster)
#'# Separate seamount data - we want to protect entire patches
#'seamounts_raster <- features_raster[["seamounts"]]
#'features_raster <- features_raster[[names(features_raster)[names(features_raster) != "seamounts"]]]
#'# Create a "cost" to protecting a cell - just a uniform cost for this example
#'cost_raster <- stats::setNames(planning_raster, "cost")
#'# Create patches from layer
#'patches_raster <- create_patches(seamounts_raster)
#'# Create patch dataframe
#'patches_raster_df <- create_patch_df(spatial_grid = planning_raster, features = features_raster,
#' patches = patches_raster, costs = cost_raster)
#'# Create boundary matrix for prioritizr
#'boundary_matrix <- create_boundary_matrix(spatial_grid = planning_raster,
#' patches = patches_raster, patch_df = patches_raster_df)
#'# Import some planning data
#'
#'#import planning units/ cost raster
#'pu_raster <- terra::rast(system.file("extdata/pu_raster.tif", package = "patchwise"))

#'#import species distributions - feature data for planning
#'species_distributions <- terra::rast(system.file("extdata/spp_distributions.tif", package = "patchwise"))
#'
#'#import seamounts
#'seamounts <- terra::rast(system.file("extdata/seamounts.tif", package = "patchwise"))
#'
#'# Create seamount patches as multi-layer raster
#'patches_raster <- create_patches(seamounts)
#'
#'patches_df <- create_patch_df(spatial_grid = pu_raster, features = species_distributions,
#'patches = patches_raster, costs = pu_raster)
#'
#'#Create boundary matrix if you want to use a boundary penatly function in prioritizr
#'boundary_matrix <- create_boundary_matrix(spatial_grid = pu_raster, patches = patches_raster, patch_df = patches_df)


create_boundary_matrix <- function(spatial_grid, patches, patch_df){

Expand Down
Loading
Loading