Title: | Ecological Restoration Planning |
---|---|
Description: | Flexible framework for ecological restoration planning. It aims to identify priority areas for restoration efforts using optimization algorithms (based on Justeau-Allaire et al. 2021 <doi:10.1111/1365-2664.13803>). Priority areas can be identified by maximizing landscape indices, such as the effective mesh size (Jaeger 2000 <doi:10.1023/A:1008129329289>), or the integral index of connectivity (Pascual-Hortal & Saura 2006 <doi:10.1007/s10980-006-0013-z>). Additionally, constraints can be used to ensure that priority areas exhibit particular characteristics (e.g., ensure that particular places are not selected for restoration, ensure that priority areas form a single contiguous network). Furthermore, multiple near-optimal solutions can be generated to explore multiple options in restoration planning. The package leverages the 'Choco-solver' software to perform optimization using constraint programming (CP) techniques (<https://choco-solver.org/>). |
Authors: | Dimitri Justeau-Allaire [aut, cre] , Jeffrey O Hanson [aut] , Ghislain Vieilledent [aut] , Philippe Vismara [aut], Xavier Lorca [aut], Philippe Birnbaum [aut] |
Maintainer: | Dimitri Justeau-Allaire <[email protected]> |
License: | GPL (>= 3) |
Version: | 1.0.6 |
Built: | 2024-11-06 06:42:49 UTC |
Source: | CRAN |
Add constraint to a restoration problem (restopt_problem()
) object
to specify that only certain planning units can be selected for restoration
activities.
add_available_areas_constraint(problem, data, touches = FALSE)
add_available_areas_constraint(problem, data, touches = FALSE)
problem |
|
data |
|
touches |
|
Available areas constraints can be used to incorporate a wide range of
criteria into restoration planning problems.
They can be used to account for existing land-use practices,
feasibility of restoration activities, and stakeholder preferences.
For example, available areas constraints can be used to
ensure that urban areas are not selected for restoration.
Additionally, if restoration activities can only be implemented depending
on certain conditions – such as places where landscape slope is not
too steep – then available areas constraints could be used to ensure
restoration activities are not prioritized for places where they
could not be implemented.
Furthermore, if stakeholders require solutions that do not prioritize
particular places for restoration, then available areas constraints
can also be used to achieve this.
See add_locked_out_constraint()
, which achieve the same as available
areas constraint by defining areas that are NOT available for restoration.
Note: The locked out constraint and the available are the same constraints,
with a different input data. Thus, from a modelling perspective,
add_available_areas_constraint()
is just a pre processing layer in front of
add_locked_out_constraint()
. This is why if you print a restopt problem
with an available areas constraint, you will see a locked out constraint.
An updated restoration problem (restopt_problem()
) object.
Other constraints:
add_compactness_constraint()
,
add_components_constraint()
,
add_connected_constraint()
,
add_locked_out_constraint()
,
add_min_iic_constraint()
,
add_min_mesh_constraint()
,
add_restorable_constraint()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) available <- vect( system.file("extdata", "accessible_areas.gpkg", package = "restoptr") ) # plot data plot(habitat_data) plot(available, add=TRUE) # create problem with available areas constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_iic_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_available_areas_constraint(available) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) available <- vect( system.file("extdata", "accessible_areas.gpkg", package = "restoptr") ) # plot data plot(habitat_data) plot(available, add=TRUE) # create problem with available areas constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_iic_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_available_areas_constraint(available) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
Add constraint to a restoration problem (restopt_problem()
) object
to specify the compactness of a solution.
add_compactness_constraint(problem, max_diameter, unit = "m")
add_compactness_constraint(problem, max_diameter, unit = "m")
problem |
|
max_diameter |
|
unit |
|
The compactness constraint is defined according to the diameter of
the smallest enclosing circle which contains the center of selected planning
units for restoration (see https://w.wiki/4vfg). The unit of the diameter
corresponds either to a unit available in the unit
package, or to planning
unit width ("cells"). Note that, as the computation occurs on aggregated cells,
if max_diameter
is used with a different unit than "cells", it will be rounded
to the closest corresponding number of cells. For example, a diameter of 4 cells
means that no more than 4 cells can be found in line in the solution. In practice,
this constraint is useful to ensure the feasibility of a restoration project,
and to integrate economies of scale. Compact restoration areas are usually
associated with lower costs and easier management, because it ensures that
restoration sites are not too far away from each other (e.g. lower travel costs
between sites, less areas to monitor, etc.).
An updated restoration problem (restopt_problem()
) object.
Other constraints:
add_available_areas_constraint()
,
add_components_constraint()
,
add_connected_constraint()
,
add_locked_out_constraint()
,
add_min_iic_constraint()
,
add_min_mesh_constraint()
,
add_restorable_constraint()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_restorable_constraint( min_restore = 200, max_restore = 300, ) %>% add_compactness_constraint(1800, unit = "m") # plot preprocessed data plot(rast(list(p$data$existing_habitat, p$data$restorable_habitat)), nc = 2) # print problem print(p) # Solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_restorable_constraint( min_restore = 200, max_restore = 300, ) %>% add_compactness_constraint(1800, unit = "m") # plot preprocessed data plot(rast(list(p$data$existing_habitat, p$data$restorable_habitat)), nc = 2) # print problem print(p) # Solve problem s <- solve(p) # plot solution plot(s)
Add constraint to a restoration problem (restopt_problem()
) object
to specify the number of connected components that can be
present within a solution.
add_components_constraint(problem, min_nb_components, max_nb_components)
add_components_constraint(problem, min_nb_components, max_nb_components)
problem |
|
min_nb_components |
|
max_nb_components |
|
A connected component is a spatially continuous set of planning units. This constraints applies on the set of planning units that are selected for restoration, and allows to specify a minimum and maximum number of connected components. In practice, this constraint is useful to ensure the feasibility of a restoration project, and to integrate economies of scale. Continuous restoration areas (i.e. less connected components) are usually associated with lower costs, because it ensures that restoration sites are not too far away from each other (e.g. lower travel costs between sites, less areas to monitor, etc.). On the other hand, it can be useful to enforce several disconnected restoration areas to ensure that hazards (e.g. fire) do not strike all planning units at the same time.
An updated restoration problem (restopt_problem()
) object.
Other constraints:
add_available_areas_constraint()
,
add_compactness_constraint()
,
add_connected_constraint()
,
add_locked_out_constraint()
,
add_min_iic_constraint()
,
add_min_mesh_constraint()
,
add_restorable_constraint()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_restorable_constraint( min_restore = 10, max_restore = 100, ) %>% add_components_constraint(1, 1) # plot preprocessed data plot(rast(list(p$data$existing_habitat, p$data$restorable_habitat)), nc = 2) # print problem print(p) # Solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_restorable_constraint( min_restore = 10, max_restore = 100, ) %>% add_components_constraint(1, 1) # plot preprocessed data plot(rast(list(p$data$existing_habitat, p$data$restorable_habitat)), nc = 2) # print problem print(p) # Solve problem s <- solve(p) # plot solution plot(s)
Add constraint to a restoration problem (restopt_problem()
) object
to specify the selected planning units are connected
add_connected_constraint(problem)
add_connected_constraint(problem)
problem |
|
A connected area is such that there is a path between any to planning units within the area. This constraints applies on the set of planning units that are selected for restoration. In practice, this constraint is useful to ensure the feasibility of a restoration project, and to integrate economies of scale. Connected restoration areas are usually associated with lower costs, because it ensures that restoration sites are not too far away from each other (e.g. lower travel costs between sites, less areas to monitor, etc.). Note This constraint relies on the add_components_constraint(), with parameters set to enforce exactly one connected component. Also see add_components_constraint and add_compactness_constraint.
An updated restoration problem (restopt_problem()
) object.
Other constraints:
add_available_areas_constraint()
,
add_compactness_constraint()
,
add_components_constraint()
,
add_locked_out_constraint()
,
add_min_iic_constraint()
,
add_min_mesh_constraint()
,
add_restorable_constraint()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_restorable_constraint( min_restore = 10, max_restore = 100, ) %>% add_connected_constraint() # plot preprocessed data plot(rast(list(p$data$existing_habitat, p$data$restorable_habitat)), nc = 2) # print problem print(p) # Solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_restorable_constraint( min_restore = 10, max_restore = 100, ) %>% add_connected_constraint() # plot preprocessed data plot(rast(list(p$data$existing_habitat, p$data$restorable_habitat)), nc = 2) # print problem print(p) # Solve problem s <- solve(p) # plot solution plot(s)
Add constraint to a restoration problem (restopt_problem()
) object
to specify that certain planning units cannot be selected
for restoration activities.
add_locked_out_constraint(problem, data, touches = FALSE)
add_locked_out_constraint(problem, data, touches = FALSE)
problem |
|
data |
|
touches |
|
Locked out constraints can be used to incorporate a wide range of
criteria into restoration planning problems.
They can be used to account for existing land-use practices,
feasibility of restoration activities, and stakeholder preferences.
For example, locked out constraints can be used to
ensure that urban areas are not selected for restoration.
Additionally, if restoration activities can only be implemented depending
on certain conditions – such as places where landscape slope is not
too steep – then locked out constraints could be used to ensure
restoration activities are not prioritized for places where they
could not be implemented.
Furthermore, if stakeholders require solutions that do not prioritize
particular places for restoration, then locked out constraints
can also be used to achieve this.
See add_available_areas_constraint()
, which achieve the same as the locked
out constraint by defining areas that ARE available for restoration.
An updated restoration problem (restopt_problem()
) object.
Other constraints:
add_available_areas_constraint()
,
add_compactness_constraint()
,
add_components_constraint()
,
add_connected_constraint()
,
add_min_iic_constraint()
,
add_min_mesh_constraint()
,
add_restorable_constraint()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # plot data plot(rast(list(habitat_data, locked_out_data)), nc = 2) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_iic_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # plot data plot(rast(list(habitat_data, locked_out_data)), nc = 2) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_iic_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
Add constraint to a restoration problem (restopt_problem()
) object
to specify the minimum integral index of connectivity of a solution.
add_min_iic_constraint( problem, min_iic, distance_threshold = -1, unit = "m", precision = 4 )
add_min_iic_constraint( problem, min_iic, distance_threshold = -1, unit = "m", precision = 4 )
problem |
|
min_iic |
|
distance_threshold |
|
unit |
|
precision |
|
The integral index of connectivity (IIC) is a graph-based inter-patch
connectivity index based on a binary connection model (Pascual-Hortal &
Saura, 2006). Its maximization in the context of restoration favours
restoring the structural connectivity between large patches. IIC is unitless
and comprised between 0 (no connectivity) and 1 (all the landscape is
habitat, thus fully connected). The distance_threshold
parameter indicates
to the solver how to construct the habitat graph, i.e. what is the minimum
distance between two patches to consider them as connected. Note that, as
the computation occurs on aggregated cells, if distance_threshold
is used
with a different unit than "cells", it will be rounded to the closest
corresponding number of cells.
The effective mesh size (MESH) is a measure of landscape fragmentation based on the probability that two randomly chosen points are located in the same patch (Jaeger, 2000). Maximizing it in the context of restoration favours fewer and larger patches.
An updated restoration problem (restopt_problem()
) object.
Pascual-Hortal, L., & Saura, S. (2006). Comparison and development of new graph-based landscape connectivity indices: Towards the priorization of habitat patches and corridors for conservation. Landscape Ecology, 21(7), 959‑967. https://doi.org/10.1007/s10980-006-0013-z
Other constraints:
add_available_areas_constraint()
,
add_compactness_constraint()
,
add_components_constraint()
,
add_connected_constraint()
,
add_locked_out_constraint()
,
add_min_mesh_constraint()
,
add_restorable_constraint()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_min_iic_constraint(0.2) %>% add_restorable_constraint( min_restore = 200, max_restore = 300, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_compactness_constraint(2500, unit = "m") %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_min_iic_constraint(0.2) %>% add_restorable_constraint( min_restore = 200, max_restore = 300, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_compactness_constraint(2500, unit = "m") %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
Add constraint to a restoration problem (restopt_problem()
) object
to specify the minimum effective mesh size of a solution.
add_min_mesh_constraint(problem, min_mesh, precision = 4, unit = "ha")
add_min_mesh_constraint(problem, min_mesh, precision = 4, unit = "ha")
problem |
|
min_mesh |
|
precision |
|
unit |
|
The effective mesh size (MESH) is a measure of landscape fragmentation based on the probability that two randomly chosen points are located in the same patch (Jaeger, 2000). Maximizing it in the context of restoration favours fewer and larger patches.
An updated restoration problem (restopt_problem()
) object.
Jaeger, J. A. G. (2000). Landscape division, splitting index, and effective mesh size: New measures of landscape fragmentation. Landscape Ecology, 15(2), 115‑130. https://doi.org/10.1023/A:1008129329289
Other constraints:
add_available_areas_constraint()
,
add_compactness_constraint()
,
add_components_constraint()
,
add_connected_constraint()
,
add_locked_out_constraint()
,
add_min_iic_constraint()
,
add_restorable_constraint()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_restorable_constraint( min_restore = 200, max_restore = 300, ) %>% add_min_mesh_constraint(min_mesh = 2500, unit = "ha") # plot preprocessed data plot(rast(list(p$data$existing_habitat, p$data$restorable_habitat)), nc = 2) # print problem print(p) # Solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_restorable_constraint( min_restore = 200, max_restore = 300, ) %>% add_min_mesh_constraint(min_mesh = 2500, unit = "ha") # plot preprocessed data plot(rast(list(p$data$existing_habitat, p$data$restorable_habitat)), nc = 2) # print problem print(p) # Solve problem s <- solve(p) # plot solution plot(s)
Add constraint to a restoration problem (restopt_problem()
) object
to specify specify the available amount of surface for restoration
add_restorable_constraint( problem, min_restore, max_restore, min_proportion = 1, unit = "ha" )
add_restorable_constraint( problem, min_restore, max_restore, min_proportion = 1, unit = "ha" )
problem |
|
min_restore |
|
max_restore |
|
min_proportion |
|
unit |
|
Given the restorable_habitat
input raster in restopt_problem,
this constraint ensures that the total amount of restorable habitat in
selected planning units is at least min_restore
and at most max_restore
.
The unit of min_restore
and max_restore
can be either in a surface unit handled
by the unit
package, or in number of cells from the original habitat input raster
("cells"). The min_proportion
parameter is a numeric between 0 and 1, and
correspond to the minimum proportion of habitat area that needs to be restored
in the planning unit to consider the planning unit as restored. This proportion
is relative to the area of a planning unit, which is computed automatically
from the input habitat raster. Note that planning unit area is considered
uniform, and the distortion is not corrected. It could be using the cellSize
function of the terra
package, but this function is currently pretty slow
for large rasters. If your problem is at regional scale, the distortion
should be negligible. However, at larger scales, the best is to use an
equal-area projected coordinate system.
Note that when a solution is found, the "maximum restorable habitat" is
displayed, this value does not correspond to the max_restore
parameter,
but to the total area that can be restored in the selected planning units.
The max_restore
parameter is actually an upper bound of the minimum habitat
that needs to be restored to reach the min_proportion
of habitat in every
selected planning units.
An updated restoration problem (restopt_problem()
) object.
Other constraints:
add_available_areas_constraint()
,
add_compactness_constraint()
,
add_components_constraint()
,
add_connected_constraint()
,
add_locked_out_constraint()
,
add_min_iic_constraint()
,
add_min_mesh_constraint()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_restorable_constraint( min_restore = 200, max_restore = 300, min_proportion = 0.7 ) %>% add_compactness_constraint(5, unit = "cells") # print problem print(p) # plot preprocessed data plot(rast(list(get_existing_habitat(p), get_restorable_habitat(p), get_locked_out_areas(p))), nc = 3) # Solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_restorable_constraint( min_restore = 200, max_restore = 300, min_proportion = 0.7 ) %>% add_compactness_constraint(5, unit = "cells") # print problem print(p) # plot preprocessed data plot(rast(list(get_existing_habitat(p), get_restorable_habitat(p), get_locked_out_areas(p))), nc = 3) # Solve problem s <- solve(p) # plot solution plot(s)
Add settings to a restoration problem (restopt_problem()
) object
to customize the optimization procedure.
add_settings( problem, precision = 4, time_limit = 0, nb_solutions = 1, optimality_gap = 0, solution_name_prefix = "Solution " )
add_settings( problem, precision = 4, time_limit = 0, nb_solutions = 1, optimality_gap = 0, solution_name_prefix = "Solution " )
problem |
|
precision |
|
time_limit |
|
nb_solutions |
|
optimality_gap |
|
solution_name_prefix |
|
An updated restoration problem (restopt_problem()
) object.
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_settings(time_limit = 1, precision = 4, nb_solutions = 2) # print problem print(p)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% add_settings(time_limit = 1, precision = 4, nb_solutions = 2) # print problem print(p)
Compute the number of cells corresponding to a given area.
area_to_nb_cells(raster_layer, area, unit = "ha")
area_to_nb_cells(raster_layer, area, unit = "ha")
raster_layer |
|
area |
|
unit |
|
The input raster must have a projected coordinate system. The distortion is
not corrected. It could be using the cellSize
function of the terra
package, but this function is currently pretty slow for large rasters. If
your problem is at regional scale, the distortion should be negligible.
However, at larger scales, the best is to use an equal-area projected
coordinate system.
numeric
The number of raster cell correspond to the given area.
habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) area_to_nb_cells(habitat_data, 20, unit = "ha")
habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) area_to_nb_cells(habitat_data, 20, unit = "ha")
Compute the area of a cell
cell_area(raster_layer, unit = "ha")
cell_area(raster_layer, unit = "ha")
raster_layer |
|
unit |
|
The input raster must have a projected coordinate system. The distortion is
not corrected. It could be using the cellSize
function of the terra
package, but this function is currently pretty slow for large rasters. If
your problem is at regional scale, the distortion should be negligible.
However, at larger scales, the best is to use an equal-area projected
coordinate system.
numeric
The area of a cell in the desired unit.
habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) cell_area(habitat_data, "ha")
habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) cell_area(habitat_data, "ha")
Compute the width of a cell
cell_width(raster_layer, unit = "m")
cell_width(raster_layer, unit = "m")
raster_layer |
|
unit |
|
The input raster must have a projected coordinate system. The distortion is
not corrected. It could be using the cellSize
function of the terra
package, but this function is currently pretty slow for large rasters. If
your problem is at regional scale, the distortion should be negligible.
However, at larger scales, the best is to use an equal-area projected
coordinate system.
numeric
The width of a cell in the desired unit.
habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) cell_width(habitat_data, "m")
habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) cell_width(habitat_data, "m")
Retrieve the aggregation factor of a restopt problem.
get_aggregation_factor(problem)
get_aggregation_factor(problem)
problem |
|
numeric
The aggregation factor of the restopt problem.
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_aggregation_factor(problem)
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_aggregation_factor(problem)
Retrieve the aggregated cell area of a restopt problem.
get_cell_area(problem)
get_cell_area(problem)
problem |
|
terra::rast()
The aggregated cell area of the restopt problem.
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_cell_area(problem)
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_cell_area(problem)
Retrieve the constraints of a restopt problem.
get_constraints(problem)
get_constraints(problem)
problem |
|
list
The constraints of the restopt problem.
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_constraints(problem)
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_constraints(problem)
Retrieve the existing (i.e. aggregated) habitat data.
get_existing_habitat(problem)
get_existing_habitat(problem)
problem |
|
terra::rast()
The existing (aggregated) habitat data.
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) plot(get_existing_habitat(problem))
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) plot(get_existing_habitat(problem))
Retrieve the habitat threshold parameter of a restopt problem.
get_habitat_threshold(problem)
get_habitat_threshold(problem)
problem |
|
numeric
The habitat threshold parameter of the restopt problem.
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_habitat_threshold(problem)
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_habitat_threshold(problem)
Retrieve the locked out areas of a restopt problem.
get_locked_out_areas(problem)
get_locked_out_areas(problem)
problem |
|
terra::rast()
The locked out areas of the restopt problem.
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_locked_out_areas(problem)
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_locked_out_areas(problem)
Return the metadata associated with a restopt solution, which contains the characteristics of the solution. The unit for area characteristics can be chosen among "ha" (hectares), "m" (square meters), "km" (square kilometers), and "cells" (cells from the original input habitat raster). Note that the solving time is expressed in seconds.
get_metadata(restopt_solution, area_unit = "ha", distance_unit = "m")
get_metadata(restopt_solution, area_unit = "ha", distance_unit = "m")
restopt_solution |
|
area_unit |
|
distance_unit |
|
A list
containing the characteristics of the restopt solution.
Retrieve the optimization objective of a restopt problem.
get_objective(problem)
get_objective(problem)
problem |
|
RestoptObjectve
The optimization objective of the restopt problem.
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_objective(problem)
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_objective(problem)
Retrieve the original (i.e. not aggregated) habitat data.
get_original_habitat(problem)
get_original_habitat(problem)
problem |
|
terra::rast()
The original (i.e. not aggregated) habitat data.
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) plot(get_original_habitat(problem))
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) plot(get_original_habitat(problem))
Retrieve the restorable habitat (aggregated) data.
get_restorable_habitat(problem)
get_restorable_habitat(problem)
problem |
|
terra::rast()
The restorable habitat (aggregated) data.
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) plot(get_restorable_habitat(problem))
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) plot(get_restorable_habitat(problem))
Retrieve the settings of a restopt problem.
get_settings(problem)
get_settings(problem)
problem |
|
list
The settings associated with the restopt problem.
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_settings(problem)
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem problem <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) get_settings(problem)
Invert a vector layer according to the extent of a restopt problem.
invert_vector(vector_layer, extent = NULL, filter = NULL)
invert_vector(vector_layer, extent = NULL, filter = NULL)
vector_layer |
|
extent |
|
filter |
Optional: filter to apply to |
Invert a vector layer according to its extent, or a user-specified extent. This function is useful to derive locked out areas from accessible areas, e.g. buffer around tracks.
A terra::vect()
Vector object.
habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) available <- vect( system.file("extdata", "accessible_areas.gpkg", package = "restoptr") ) locked_out <- invert_vector( vector_layer = available, extent = ext(habitat_data), filter = available$ID==2 )
habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) available <- vect( system.file("extdata", "accessible_areas.gpkg", package = "restoptr") ) locked_out <- invert_vector( vector_layer = available, extent = ext(habitat_data), filter = available$ID==2 )
The restoptr package uses Java to perform optimization procedures. As such, it is important that Java is installed correctly when using this package. This function verifies if Java is available on the system.
is_java_available()
is_java_available()
A logical
(TRUE
or FALSE
) value indicating if Java is available
for usage.
Compute the area corresponding to a given number of cells.
nb_cell_to_area(raster_layer, nb_cells, unit = "ha")
nb_cell_to_area(raster_layer, nb_cells, unit = "ha")
raster_layer |
|
nb_cells |
|
unit |
|
The input raster must have a projected coordinate system. The distortion is
not corrected. It could be using the cellSize
function of the terra
package, but this function is currently pretty slow for large rasters. If
your problem is at regional scale, the distortion should be negligible.
However, at larger scales, the best is to use an equal-area projected
coordinate system.
numeric
The area corresponding to nb_cells
in the desired unit.
habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) nb_cell_to_area(habitat_data, 20, unit = "ha")
habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) nb_cell_to_area(habitat_data, 20, unit = "ha")
From a binary, possibly high resolution, habitat raster, this function produces three input rasters for restopt:
preprocess_input(habitat, habitat_threshold = 1, aggregation_factor = 1)
preprocess_input(habitat, habitat_threshold = 1, aggregation_factor = 1)
habitat |
|
habitat_threshold |
|
aggregation_factor |
|
The binary habitat raster (existing_habitat), which can be the same as the input (aggregation factor = 1), but most often is a downsampled version of it, to ensure the tractability of the problem.
The restorable habitat raster (restorable_habitat), which is a raster indicating how much habitat can be restored. If the aggregation factor = 1, the the restorable habitat raster is binary and the inverse of the habitat raster. Else, the surface of habitat is computed according to the spatial resolution, and the number of habitat pixel present in one larger aggregated cell.
The cell area raster (cell_area), which correspond for each aggregated cell to the number of number of cells in the input raster. This is necessary because the cell area can be less than expected if the aggregated cell lies in the boundary of study area.
This preprocessing function produces the necessary inputs of a
restopt problem from a single binary habitat raster (habitat
), which can
be at high resolution. Restopt solves a hard constrained combinatorial problem
(it can be reduced to a constrained 0/1 knapsack problem, which is know to
be NP-Complete), thus the input resolution might need to be reduced to
ensure a tractable problem. Performing this downsampling in a systematic
and reproducible way is the aim of this function, which relies on the
terra::aggregate()
function to do it. The aggregation_factor
parameter
indicates how much the resolution must be reduced. An aggregated pixel
will contain at most aggregation_factor^2
pixels from the input habitat
raster (cell_area
raster in this function outputs). If an aggregated pixel
is close to the spatial boundaries of the problem (i.e. NA cells), it can
contain less than aggregation_factor^2
fine grained pixels. The
habitat_threshold
parameter indicates the minimum proportion of habitat
pixels (relative to cell_area
) whose value is 1 to consider an aggregated
pixel as habitat (downsampled_habitat
output raster). The restorable_area
output raster correspond to the number of pixel with value 0 in aggregated pixels.
A list : list( existing_habitat=downsampled_habitat, restorable_habitat=restorable_habitat, cell_area=cell_area )
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr")) data <- preprocess_input( habitat = habitat_data, habitat_threshold = 0.7, aggregation_factor = 16 )
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr")) data <- preprocess_input( habitat = habitat_data, habitat_threshold = 0.7, aggregation_factor = 16 )
Display information about a restoration optimization problem.
## S3 method for class 'RestoptProblem' print(x, ...)
## S3 method for class 'RestoptProblem' print(x, ...)
x |
|
... |
Arguments not used. |
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) # print problem print(p)
#' # load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) # print problem print(p)
Create a new restoration optimization problem (RestoptProblem
) using data
that describe the spatial distribution of existing habitat (potentially at
high resolution), and parameters to derive a downsampled existing habitat
raster, suitable for a tractable optimization, and a restorable habitat
raster. Constraints can be added to a restopt problem using
add_****_constraint()
functions, and an optimization objective can be set
using set_****_objective()
functions.
restopt_problem( existing_habitat, habitat_threshold = 1, aggregation_factor = 1 )
restopt_problem( existing_habitat, habitat_threshold = 1, aggregation_factor = 1 )
existing_habitat |
|
habitat_threshold |
|
aggregation_factor |
|
This function creates the base restoration optimization problem
object, that can be further extended with constraints and optimization
objectives. One input rasters is necessary to instantiate a restopt problem:
the existing_habitat
raster (potentially with high resolution). This raster
must contains data about where are habitat areas (raster value 1
),
non-habitat areas (raster value 0
), and areas that must not be considered
during the solving procedure (NA
or NO_DATA
). The aggregation_factor
parameter is used to down sample the existing_habitat
to a resolution that
will be tractable for the optimization engine, and the habitat_threshold
parameter indicates the minimum proportion of habitat required in aggregated
habitat pixels to consider them as habitat. Note that An aggregated pixel
will contain at most aggregation_factor^2
pixels from the input habitat
raster (cell_area
raster in this function outputs). If an aggregated pixel
is close to the spatial boundaries of the problem (i.e. NA cells), it can
contain less than aggregation_factor^2
fine grained pixel. You can get
the results of this preprocessing phase using the following methods:
get_original_habitat()
(original habitat), get_existing_habitat()
(aggregated habitat), get_cell_area()
(number of pixels in each aggregated
cells), and get_restorable_area()
(amount of restorable area – in number
of original raster pixels).
A new restoration problem (RestoptProblem
) object.
None.
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) # Plot down sampled data plot(c(p$data$existing_habitat, p$data$restorable_habitat)) # print problem print(p)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 4, habitat_threshold = 0.7 ) # Plot down sampled data plot(c(p$data$existing_habitat, p$data$restorable_habitat)) # print problem print(p)
An object representing a restopt problem solution. It is basically a SpatRaster with a few metadata attributes added.
restopt_solution(restopt_problem, solution_raster, metadata, id_solution = 1)
restopt_solution(restopt_problem, solution_raster, metadata, id_solution = 1)
restopt_problem |
|
solution_raster |
|
metadata |
|
id_solution |
|
A new restoration problem solution (restopt_solution()
).
restoptr
: Ecological Restoration PlanningThe restoptr
package relies on Constraint Programming (CP) to build and
solve ecological restoration planning problems. A restoptr
problem starts
from an existing habitat (raster), where the aim is to identify optimal areas
that are suitable for restoration. Several constraints are available to define
what is expected for a suitable area for (e.g. it must be connected, compact,
must respect a budget, etc). Several optimization objective are also available
to define what is a good restoration area (e.g. it must reduce fragmentation,
increase ecological connectivity, minimize costs, etc.). restoptr
relies on
advanced landscape indices such as the effective mesh size (Jaeger, 2000),
or the integral index of connectivity (Pascual-Hortal & Saura, 2006) to address
complex restoration planning problems.
restoptr
relies on Choco-solver (https://choco-solver.org/), an open-source
Java CP solver (Prud'homme et al., 2017). The computationally intensive solving
part is thus delegated to Java (see restopt
, https://github.com/dimitri-justeau/restopt),
and the communication between R and Java is handled with the rJava
package.
Therefore, a Java Runtime Environment (>= 8) is necessary to use restopt
.
Note that the methodology used in restoptr
was first described in
Justeau-Allaire et al. (2021), but restoptr
provides much more flexibility,
new features (e.g. reliable and consistent data preprocessing), new constraints,
new optimization objectives, and an improved computational efficiency. Also
note that the API was inspired by the prioritizr
package.
This package contains several vignettes to detail its usage and
showcase its features. You can explore these vignettes using
browseVignettes("restoptr")
Hanson JO, Schuster R, Morrell N, Strimas-Mackey M, Edwards BPM, Watts ME, Arcese P, Bennett J, Possingham HP (2022). prioritizr: Systematic Conservation Prioritization in R. R package version 7.1.1. Available at https://CRAN.R-project.org/package=prioritizr.
Jaeger, J. A. G. (2000). Landscape division, splitting index, and effective mesh size: New measures of landscape fragmentation. Landscape Ecology, 15(2), 115‑130.
Justeau-Allaire, D., Vieilledent, G., Rinck, N., Vismara, P., Lorca, X., & Birnbaum, P. (2021). Constrained optimization of landscape indices in conservation planning to support ecological restoration in New Caledonia. Journal of Applied Ecology, 58(4), 744‑754.
Pascual-Hortal, L., & Saura, S. (2006). Comparison and development of new graph-based landscape connectivity indices: Towards the priorization of habitat patches and corridors for conservation. Landscape Ecology, 21(7), 959‑967.
Prud'homme, C., Fages, J.-G., & Lorca, X. (2017). Choco documentation.
Specify that a restoration problem (restopt_problem()
) should
the integral index of connectivity (IIC).
set_max_iic_objective(problem, distance_threshold = -1, unit = "m")
set_max_iic_objective(problem, distance_threshold = -1, unit = "m")
problem |
|
distance_threshold |
|
unit |
|
The integral index of connectivity (IIC) is a graph-based inter-patch
connectivity index based on a binary connection model (Pascual-Hortal &
Saura, 2006). Its maximization in the context of restoration favours
restoring the structural connectivity between large patches. IIC is unitless
and comprised between 0 (no connectivity) and 1 (all the landscape is
habitat, thus fully connected). The distance_threshold
parameter indicates
to the solver how to construct the habitat graph, i.e. what is the minimum
distance between two patches to consider them as connected. Note that, as
the computation occurs on aggregated cells, if distance_threshold
is used
with a different unit than "cells", it will be rounded to the closest
corresponding number of cells.
An updated restoration problem (restopt_problem()
object.
Pascual-Hortal, L., & Saura, S. (2006). Comparison and development of new graph-based landscape connectivity indices: Towards the priorization of habitat patches and corridors for conservation. Landscape Ecology, 21(7), 959‑967. https://doi.org/10.1007/s10980-006-0013-z
Other objectives:
set_max_mesh_objective()
,
set_max_nb_pus_objective()
,
set_max_restore_objective()
,
set_min_nb_pus_objective()
,
set_min_restore_objective()
,
set_no_objective()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_iic_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_iic_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
Specify that a restoration problem (restopt_problem()
) should
maximize effective mesh size.
set_max_mesh_objective(problem)
set_max_mesh_objective(problem)
problem |
|
The effective mesh size (MESH) is a measure of landscape fragmentation based on the probability that two randomly chosen points are located in the same patch (Jaeger, 2000). Maximizing it in the context of restoration favours fewer and larger patches.
An updated restoration problem (restopt_problem()
) object.
Jaeger, J. A. G. (2000). Landscape division, splitting index, and effective mesh size: New measures of landscape fragmentation. Landscape Ecology, 15(2), 115‑130. https://doi.org/10.1023/A:1008129329289
Other objectives:
set_max_iic_objective()
,
set_max_nb_pus_objective()
,
set_max_restore_objective()
,
set_min_nb_pus_objective()
,
set_min_restore_objective()
,
set_no_objective()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # plot data plot(rast(list(habitat_data, locked_out_data)), nc = 2) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_mesh_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # plot data plot(rast(list(habitat_data, locked_out_data)), nc = 2) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_mesh_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
Specify that a restoration problem (restopt_problem()
) should
maximize the number of planning units.
set_max_nb_pus_objective(problem)
set_max_nb_pus_objective(problem)
problem |
|
Planning units correspond to aggregated cells from the original dataset. Maximizing the number of planning units increased the spatial extent of the restoration area. This can be useful when the budget is limited and the aim is to restore the larget possible extent.
An updated restoration problem (restopt_problem()
) object.
Other objectives:
set_max_iic_objective()
,
set_max_mesh_objective()
,
set_max_restore_objective()
,
set_min_nb_pus_objective()
,
set_min_restore_objective()
,
set_no_objective()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # plot data plot(rast(list(habitat_data, locked_out_data)), nc = 2) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_nb_pus_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # plot data plot(rast(list(habitat_data, locked_out_data)), nc = 2) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_nb_pus_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
Specify that a restoration problem (restopt_problem()
) should maximize
the restoration area needed to reach the habitat proportion threshold
specified in the problem description.
set_max_restore_objective(problem)
set_max_restore_objective(problem)
problem |
|
The restoration area corresponds to the minimum amount of area that must be restored in the selected planning units to reach the minimum habitat proportion threshold specified in the problem description,
An updated restoration problem (restopt_problem()
) object.
Other objectives:
set_max_iic_objective()
,
set_max_mesh_objective()
,
set_max_nb_pus_objective()
,
set_min_nb_pus_objective()
,
set_min_restore_objective()
,
set_no_objective()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # plot data plot(rast(list(habitat_data, locked_out_data)), nc = 2) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_restore_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # plot data plot(rast(list(habitat_data, locked_out_data)), nc = 2) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_restore_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
Specify that a restoration problem (restopt_problem()
) should
minimize the number of planning units.
set_min_nb_pus_objective(problem)
set_min_nb_pus_objective(problem)
problem |
|
Planning units correspond to aggregated cells from the original dataset. Minimizing the number of planning units reduces the spatial extent of the restoration area.
An updated restoration problem (restopt_problem()
) object.
Other objectives:
set_max_iic_objective()
,
set_max_mesh_objective()
,
set_max_nb_pus_objective()
,
set_max_restore_objective()
,
set_min_restore_objective()
,
set_no_objective()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # plot data plot(rast(list(habitat_data, locked_out_data)), nc = 2) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_min_nb_pus_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # plot data plot(rast(list(habitat_data, locked_out_data)), nc = 2) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_min_nb_pus_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
Specify that a restoration problem (restopt_problem()
) should minimize
the restoration area needed to reach the habitat proportion threshold
specified in the problem description.
set_min_restore_objective(problem)
set_min_restore_objective(problem)
problem |
|
The restoration area corresponds to the minimum amount of area that must be restored in the selected planning units to reach the minimum habitat proportion threshold specified in the problem description,
An updated restoration problem (restopt_problem()
) object.
Other objectives:
set_max_iic_objective()
,
set_max_mesh_objective()
,
set_max_nb_pus_objective()
,
set_max_restore_objective()
,
set_min_nb_pus_objective()
,
set_no_objective()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # plot data plot(rast(list(habitat_data, locked_out_data)), nc = 2) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_min_restore_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) locked_out_data <- rast( system.file("extdata", "locked_out.tif", package = "restoptr") ) # plot data plot(rast(list(habitat_data, locked_out_data)), nc = 2) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_min_restore_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_locked_out_constraint(data = locked_out_data) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
Specify that a restoration problem (restopt_problem()
) should satisfy
the constraints without optimization objective.
set_no_objective(problem)
set_no_objective(problem)
problem |
|
Using set_no_objective() in a restopt problem, the solver will return the first solution found satisfying the constraint, without any optimization objective. This "no objective" setting is set by default when creating a restopt problem.
An updated restoration problem (restopt_problem()
) object.
Other objectives:
set_max_iic_objective()
,
set_max_mesh_objective()
,
set_max_nb_pus_objective()
,
set_max_restore_objective()
,
set_min_nb_pus_objective()
,
set_min_restore_objective()
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_no_objective() # print problem print(p) # Solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) # create problem p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_no_objective() # print problem print(p) # Solve problem s <- solve(p) # plot solution plot(s)
Solve a restoration optimization problem to generate a solution.
## S3 method for class 'RestoptProblem' solve(a, b, ...)
## S3 method for class 'RestoptProblem' solve(a, b, ...)
a |
|
b |
Argument not used. |
... |
Additional arguments:
|
This function relies on the Choco-solver (https://choco-solver.org/) to solve a restoration optimization problem. If the solver finds a solution, it outputs a raster with 5 possible values: NA : NA (or NO_DATA) areas from the input habitat raster. 0 : non-habitat areas that were locked out. 1 : non-habitat areas that were available for selection. 2 : habitat areas. 3 : selected planning units for restoration. If the solve function return a no-solution error, it is either because the solver could not find a solution within the time limit that was set (see add_settings), or because the solver has detected that this is not possible to satisfy the constraints (the constraints are contradictory). In the first case, you can try to increase the time limit. In the second case, you should modify your targets.
A restopt_solution()
object.
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) available <- vect( system.file("extdata", "accessible_areas.gpkg", package = "restoptr") ) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_mesh_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_available_areas_constraint(available) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)
# load data habitat_data <- rast( system.file("extdata", "habitat_hi_res.tif", package = "restoptr") ) available <- vect( system.file("extdata", "accessible_areas.gpkg", package = "restoptr") ) # create problem with locked out constraints p <- restopt_problem( existing_habitat = habitat_data, aggregation_factor = 16, habitat_threshold = 0.7 ) %>% set_max_mesh_objective() %>% add_restorable_constraint( min_restore = 5, max_restore = 5, ) %>% add_available_areas_constraint(available) %>% add_settings(time_limit = 1) # print problem print(p) # solve problem s <- solve(p) # plot solution plot(s)