---
title: "Salt Spring Island Tutorial"
output:
  rmarkdown::html_vignette:
    toc: true
    fig_caption: true
    self_contained: yes
fontsize: 11pt
documentclass: article
bibliography: references.bib
csl: reference-style.csl
vignette: >
  %\VignetteIndexEntry{Salt Spring Island Tutorial}
  %\VignetteEngine{knitr::rmarkdown_notangle}
---

```{r, include = FALSE}
h <- 3.5
w <- 3.5
is_check <- ("CheckExEnv" %in% search()) || any(c("_R_CHECK_TIMINGS_",
             "_R_CHECK_LICENSE_") %in% names(Sys.getenv()))
knitr::opts_chunk$set(fig.align = "center", eval = !is_check)
```

## Introduction

This aim of this tutorial is to show how raster data can used to build conservation problems with the _prioritizr R_ package. The data used here is a subset of a much larger data set for the Georgia Basin obtained as part of an online _Marxan_-based planning tool created for the Coastal Douglas-fir Conservation Partnership [CDFCP; @r29]. For simplicity, we focus only on Salt Spring Island, British Columbia. Salt Spring Island is central to the region and supports a diverse and globally unique mix of dry forest and savanna habitats. Today, these habitats are critically threatened due to land conversion, invasive species, and altered disturbance regimes. Known broadly as the Georgia Depression-Puget Lowlands, this region includes threatened Coastal Douglas-fir forest and Oak-Savannah habitats, also referred to as Garry oak ecosystems.

<center>

![_Extent of Coastal Douglas-fir Conservation Partnership Tool area and location of Salt Spring Island_](figures/map.jpg)

</center>

For more information on the data set refer to the [Marxan tool portal](http://arcese.forestry.ubc.ca/marxan-tool/) and the [tool tutorial](http://peter-arcese-lab.sites.olt.ubc.ca/files/2016/09/CDFCP_tutorial_2017_05.pdf).

Please note that this tutorial uses data from the _prioritizrdata R_, so ensure that it is installed before trying out the code yourself.

## Exploring the data

This data set contains two items. First, a single-band raster planning unit layer where each one hectare pixel represents a planning unit and contains its corresponding cost [@r28]. Second, a raster stack containing ecological community feature data. Field and remote sensed data were used to calculate the probability of occurrence of five key ecological communities found on Salt Spring island. Each layer in the stack represents a different community type. In order these are; Old Forest, Savannah, Wetland, Shrub, and a layer representing the inverse probability of occurrence of human commensal species. For a given layer, the cell value indicates the composite probability of encountering the suite of bird species most commonly associated with that community type.

First, load the required packages and the data.

```{r}
# load packages
library(prioritizrdata)
library(prioritizr)

# load planning unit data
data(salt_pu)

# load conservation feature data
data(salt_features)
```

Let's have a look at the planning unit data. Note that we log-transformed the raster to better visualize the variation in planning unit cost.

```{r, fig.width = w, fig.height = h}
# print planning unit data
print(salt_pu)

# plot histogram of the planning unit costs
hist(values(salt_pu), main = "Distribution of costs",
     xlab = "Planning unit costs")
```

```{r, fig.width = w, fig.height = h}
# plot map showing the planning units costs on a log-scale
plot(log(salt_pu), main = "Planning unit costs (log)")
```

Next, let's look at the feature data.

```{r, fig.width = 4.5, fig.height = 4.5}
# print features
print(salt_features)

# plot map showing the distribution of the features
plot(salt_features, main = names(salt_features))
```

## Formulating the Problem

In this tutorial, we will only cover a few of the different ways that conservation planning problems can be formulated. The examples used here are provided to highlight how different parameters can substantially---or only slightly---alter solutions. Here, we use the minimum set objective to fulfill all targets and constraints for the smallest cost. This objective is similar to that used in the _Marxan_ decision support tool. To keep this simple, we will set biodiversity targets at 17 % to reflect the [Aichi Biodiversity Target 11](https://www.cbd.int/sp/targets/). Because properties on Salt Spring Island can either be acquired in their entirety or not at all, we leave the decision framework as the default; binary decision making. This means that planning units are either selected in the solution or not selected in the solution---planning units cannot be partially acquired.

Now we will formulate the conservation planning problem.

```{r}
# create problem
p1 <- problem(salt_pu, salt_features) %>%
      add_min_set_objective() %>%
      add_relative_targets(0.17) %>%
      add_binary_decisions() %>%
      add_default_solver(gap = 0)

# print problem
print(p1)
```

Note that the `%>%` notation is used to attach the objectives, targets, and decisions to the problem. Since binary-type decisions are the default decision-type, we don't have to explicitly specify the decision-type, but we specify it here for clarity.

## Solving the problem

The _prioritizr R_ package supports three different integer linear programming solver packages: _gurobi_, _Rsymphony_, and _lpsymphony_. There are costs and benefits associated with each of these solvers, but the solver itself should have little impact on the actual solution returned (though certain solvers may take longer to return solutions than others).

First, remember that the solvers must be installed. You can check if these packages are installed by running the code below. Note that the _gurobi_ package is distributed with the [_Gurobi_ commercial software suite](http://gurobi.com), and is not available on the Comprehensive R Archive Network (CRAN). Please refer to the [_Gurobi Installation Guide_](gurobi_installation.html) for more information on installing the _gurobi R_ package.

```{r, eval = FALSE}
print(require(gurobi))
print(require(Rsymphony))
print(require(lpsymphony))
```

Now we will try solving the problem using the different solvers. We will also experiment with limiting the maximum amount of time that can be spent looking for each solution when solving the problem (using the `time_limit` parameter), and see how this alters the solutions.

```{r, message = FALSE, results = "hide"}
titles <- c() # create vector to store plot titles
s1 <- stack()  # create empty stack to store solutions

# create new problem object with added solver
if (require("Rsymphony")) {
  titles <- c(titles, "Rsymphony (5s)")
  p2 <- p1 %>% add_rsymphony_solver(gap = 0, time_limit = 5)
  s1 <- addLayer(s1, solve(p2))
}

if (require("Rsymphony")) {
  titles <- c(titles, "Rsymphony (10s)")
  p3 <- p1 %>% add_rsymphony_solver(gap = 0, time_limit = 10)
  s1 <- addLayer(s1, solve(p3))
}

if (require("gurobi")) {
  titles <- c(titles, "Gurobi (5s)")
  p4 <- p1 %>% add_gurobi_solver(gap = 0, time_limit = 5)
  s1 <- addLayer(s1, solve(p4))
}

if (require("lpsymphony")) {
  titles <- c(titles, "lpsymphony (10s)")
  p5 <- p1 %>% add_lpsymphony_solver(gap = 0, time_limit = 10)
  s1 <- addLayer(s1, solve(p5))
}
```

Now let's visualize the solutions.

```{r, fig.height = 5.5, fig.width = 5}
plot(s1, main = titles, breaks = c(0, 0.5, 1),  col = c("grey70", "darkgreen"))
```

We can see that all of the solutions are very similar. Therefore it would appear that for this particular problem, the solution is not highly sensitive to solver choice. For larger and more complex problems, however, we would expect the solution from _Gurobi_ to be far superior when setting time limits. At a glance, it also appears that the time limit settings did not largely impact the solutions (5 seconds vs. 10 seconds), but a more rigorous analysis is needed to investigate this.

## Adding connectivity

Isolated and fragmented populations are often more vulnerable to extinction. As a consequence, landscape connectivity is a key focus of many conservation planning exercises. There are a number of methods that can be used to increase connectivity in prioritizations. These methods typically involve adding constraints to a problem to ensure that solutions exhibit a specific property (e.g. selected planning units that form a contiguous reserve), or adding penalties to a problem to penalize solutions that exhibit specific properties (e.g. high levels of fragmentation). Here we will explore a couple different strategies for increasing connectivity in solutions. For brevity, we will use default solver which is automatically added to a problem if a solver is not manually specified.

```{r}
# basic problem formulation
p6 <- problem(salt_pu, salt_features) %>%
      add_min_set_objective() %>%
      add_relative_targets(0.17) %>%
      add_binary_decisions() %>%
      add_default_solver(gap = 0)

# print problem
print(p6)
```

```{r, results = "hide"}
titles2 <- c() # create vector to store plot titles
s2 <- stack()  # create empty stack to store solutions

# no connectivity requirement
titles2 <- c(titles2, "No connectivity")
s2 <- addLayer(s2, solve(p6))

# require at least two for each selected planning unit
titles2 <- c(titles2, "Neighbor constraints (two)")
p7 <- p6 %>% add_neighbor_constraints(2)
s2 <- addLayer(s2, solve(p7))

# impose small penalty for fragmented solutions
titles2 <- c(titles2, "Boundary penalty (low)")
p8 <- p6 %>% add_boundary_penalties(50, 0.5)
s2 <- addLayer(s2, solve(p8))

# impose high penalty for fragmented solutions
titles2 <- c(titles2, "Boundary penalty (high)")
p9 <- p6 %>% add_boundary_penalties(500, 0.5)
s2 <- addLayer(s2, solve(p9))
```

```{r, fig.height = 5.5, fig.width = 5}
# plot solutions
plot(s2, main = titles2, breaks = c(0, 0.5, 1),  col = c("grey70", "darkgreen"))
```

Here we can see that adding the constraints and penalties to the problem has a small, but noticeable effect on the solutions. We would expect to see larger difference between the solutions for problems that contain more than five conservation features. You may also wish to explore the `add_connectivity_penalties` and `add_feature_contiguity_constraints` functions. These functions use additional data on landscape resistance to provide a more accurate parametrization of connectivity and, in turn, deliver more effective solutions.

## Irreplaceability

Conservation plans can take a long time to implement. Since funding availability and habitat quality can decline over time, it is critical that the most important places in a prioritization are scheduled for protection as early as possible. For instance, some planning units in a solution might contain many rare species which do not occur in any other planning units. Alternatively, some planning units might offer an especially high return on investment that reduces costs considerably. As a consequence, conservation planners often need information on which planning units selected in a prioritization are most important to the overall success of the prioritization. To achieve this, conservation planners can use irreplaceability scores to calculate the "importance" or "priority" of each planning unit selected in a solution.

Let's assume that the low boundary length solution (`s2[[3]]`) in the previous section was the best solution. If we wanted to actually implement this solution, it is important that we understand which of the `formatC(cellStats(s2[[3]], "sum"), big.mark = ",")` planning units are the most important. So, let's calculate irreplacability scores for each of the planning units selected in that solution using the replacement cost method [@r31]. Under this method, planning units with higher scores are more irreplaceable. Planning units with infinite (`Inf`) scores are truly irreplaceable (i.e. they contain biodiversity features which cannot be met by protecting any other set of planning units), and those with zero scores are completely replaceable (i.e. they can be swapped for another set of planning units with no loss of performance).

Unfortunately, this method can take a long time to run for moderate sized problems (i.e. planning units with between 1,000--30,000 planning units). So, instead of using the same problem to generate the replacement costs, we will use a simplified problem that does not contain boundary penalties and uses proportion-type decisions to reduce run times.

```{r}
# create new problem for irreplacability calculations
p10 <- problem(salt_pu, salt_features) %>%
       add_min_set_objective() %>%
       add_relative_targets(0.17) %>%
       add_proportion_decisions() %>%
       add_default_solver(gap = 0, verbose = FALSE)

# print problem
print(p10)

# calculate irreplacability scores (note this will take a few minutes)
rc10 <- replacement_cost(p10, s2[[3]])

# plot irreplacability scores
plot(rc10, main = "replacement cost")
```

We can see that the prioritized planning units located on the far eastern side of the study area have the highest irreplacability scores (i.e. greater than 0.95). This result suggests that protecting these places may be critical to the overall success of the prioritization. Since none of the planning have infinite irreplacability scores, we can be confident that additional planning units could be protected to address shortfalls in the event that any one of the prioritized planning units could not be protected.

## References
