Title: | Tropical Forest Canopy Gaps Analysis |
---|---|
Description: | Set of tools for detecting and analyzing Airborne Laser Scanning-derived Tropical Forest Canopy Gaps. Details were published in Silva and others (2019) <doi:10.1111/2041-210X.13211>. |
Authors: | Carlos Alberto Silva [aut, cph, cre], Ekena Rangel Pinagé [aut] (Reviews the documentation), Midhun Mohan [aut] (Reviews the documentation), Danilo Roberti Alves de Almeida [aut] (Reviews the documentation), Eben North Broadbent [aut] (Reviews the documentation), Wan Shafrina Wan Mohd Jaafar [aut] (Reviews the documentation), Daniel de Almeida Papa [aut] (Reviews the documentation), Adrian Cardil [aut] (Reviews the documentation), Ruben Valbuena [cph, aut], Toby Jackson [aut], Jeff Atkins [aut], Caio Hamamura [aut] (Maintenance and review), Carine Klauberg [aut] (Reviews the documentation), Lucy [email protected] Beese [aut] (Reviews the documentation) |
Maintainer: | Carlos Alberto Silva <[email protected]> |
License: | GPL-3 |
Version: | 0.1.8 |
Built: | 2024-11-16 04:50:42 UTC |
Source: | https://github.com/carlos-alberto-silva/ForestGapR |
The Airborne Laser Scanning (ALS)-derived Canopy Height Model - (CHM) provided as an example dataset collected in 2012 at Fazenda Cauaxi in the Paragominas Municipality of Pará State, Brazil, in the eastern Amazon.
data(ALS_CHM_CAU_2012)
data(ALS_CHM_CAU_2012)
The format is:'RasterLayer'
The 1-m ALS-CHM was generated using Lastools software (Isenburg 2016)
ALS data were acquired with support from USAID and the US Department of State with the technical assistance of the Brazilian Corporation for Agricultural Research (EMBRAPA) and the US Forest Service Office of International Programs via the Sustainable Landscapes Brazil Project (Keller, M. 2018).
Keller, M. 2018. Available online: https://www.paisagenslidar.cnptia.embrapa.br/webgis/
Isenburg, M. LAStools—Efficient Tools for Lidar Processing. 2018. Available online: http://www.cs.unc. edu/~isenburg/lastools/ (accessed on 3 October 2018).
library(raster) data(ALS_CHM_CAU_2012) plot(ALS_CHM_CAU_2012)
library(raster) data(ALS_CHM_CAU_2012) plot(ALS_CHM_CAU_2012)
The Airborne Laser Scanning (ALS)-derived Canopy Height Model - (CHM) provided as an example dataset collected in 2014 at Fazenda Cauaxi in the Paragominas Municipality of Pará State, Brazil, in the eastern Amazon.
data(ALS_CHM_CAU_2014)
data(ALS_CHM_CAU_2014)
The format is:'RasterLayer'
The 1-m ALS-CHM was generated using Lastools software (Isenburg 2016)
ALS data were acquired with support from USAID and the US Department of State with the technical assistance of the Brazilian Corporation for Agricultural Research (EMBRAPA) and the US Forest Service Office of International Programs via the Sustainable Landscapes Brazil Project (Keller, M. 2018).
Keller, M. 2018. Available online: https://www.paisagenslidar.cnptia.embrapa.br/webgis/
Isenburg, M. LAStools—Efficient Tools for Lidar Processing. 2018. Available online: http://www.cs.unc. edu/~isenburg/lastools/ (accessed on 3 October 2018).
library(raster) data(ALS_CHM_CAU_2014) plot(ALS_CHM_CAU_2014)
library(raster) data(ALS_CHM_CAU_2014) plot(ALS_CHM_CAU_2014)
The Airborne Laser Scanning (ALS)-derived Canopy Height Model - (CHM) provided as an example dataset collected in 2012 at the Adolpho Ducke Forest Reserve in Municipality of Manaus of State of Amazonas, Brazil, in central Amazon.
data(ALS_CHM_DUC)
data(ALS_CHM_DUC)
The format is:'RasterLayer'
The 1-m ALS-CHM was generated using Lastools software (Isenburg 2016)
ALS data were acquired with support from USAID and the US Department of State with the technical assistance of the Brazilian Corporation for Agricultural Research (EMBRAPA) and the US Forest Service Office of International Programs via the Sustainable Landscapes Brazil Project (Keller, M. 2018).
Keller, M. 2018. Available online: https://www.paisagenslidar.cnptia.embrapa.br/webgis/
Isenburg, M. LAStools—Efficient Tools for Lidar Processing. 2018. Available online: http://www.cs.unc. edu/~isenburg/lastools/ (accessed on 3 October 2018).
library(raster) data(ALS_CHM_DUC) plot(ALS_CHM_DUC)
library(raster) data(ALS_CHM_DUC) plot(ALS_CHM_DUC)
This function detects forest canopy gap changes across two forest gap raster::RasterLayer
objects
GapChangeDec(gap_layer1,gap_layer2)
GapChangeDec(gap_layer1,gap_layer2)
gap_layer1 |
ALS-derived gap as an |
gap_layer2 |
ALS-derived gap as an |
A raster::RasterLayer
object representing forest gap change area
Carlos Alberto Silva.
## Not run: # Loading raster and viridis libraries library(raster) library(viridis) # ALS-derived CHM from Fazenda Cauxi - Brazilian tropical forest data(ALS_CHM_CAU_2012) data(ALS_CHM_CAU_2014) # set height thresholds (e.g. 10 meters) threshold <- 10 size <- c(1, 10^4) # m2 # Detecting forest gaps gaps_cau2012 <- getForestGaps(chm_layer = ALS_CHM_CAU_2012, threshold = threshold, size = size) gaps_cau2014 <- getForestGaps(chm_layer = ALS_CHM_CAU_2014, threshold = threshold, size = size) # Detecting forest gaps changes Gap_changes <- GapChangeDec(gap_layer1 = gaps_cau2012, gap_layer2 = gaps_cau2014) # Plotting ALS-derived CHM and forest gaps oldpar <- par(mfrow = c(1, 3)) plot(ALS_CHM_CAU_2012, main = "Forest Canopy Gap - 2012", col = viridis(10)) plot(gaps_cau2012, add = TRUE, col = "red", legend = FALSE) plot(ALS_CHM_CAU_2014, main = "Forest Canopy Gap - 2014", col = viridis(10)) plot(gaps_cau2014, add = TRUE, col = "red", legend = FALSE) plot(ALS_CHM_CAU_2014, main = "Forest Gap Changes Detected", col = viridis(10)) plot(Gap_changes, add = TRUE, col = "orange", legend = FALSE) par(oldpar) ## End(Not run)
## Not run: # Loading raster and viridis libraries library(raster) library(viridis) # ALS-derived CHM from Fazenda Cauxi - Brazilian tropical forest data(ALS_CHM_CAU_2012) data(ALS_CHM_CAU_2014) # set height thresholds (e.g. 10 meters) threshold <- 10 size <- c(1, 10^4) # m2 # Detecting forest gaps gaps_cau2012 <- getForestGaps(chm_layer = ALS_CHM_CAU_2012, threshold = threshold, size = size) gaps_cau2014 <- getForestGaps(chm_layer = ALS_CHM_CAU_2014, threshold = threshold, size = size) # Detecting forest gaps changes Gap_changes <- GapChangeDec(gap_layer1 = gaps_cau2012, gap_layer2 = gaps_cau2014) # Plotting ALS-derived CHM and forest gaps oldpar <- par(mfrow = c(1, 3)) plot(ALS_CHM_CAU_2012, main = "Forest Canopy Gap - 2012", col = viridis(10)) plot(gaps_cau2012, add = TRUE, col = "red", legend = FALSE) plot(ALS_CHM_CAU_2014, main = "Forest Canopy Gap - 2014", col = viridis(10)) plot(gaps_cau2014, add = TRUE, col = "red", legend = FALSE) plot(ALS_CHM_CAU_2014, main = "Forest Gap Changes Detected", col = viridis(10)) plot(Gap_changes, add = TRUE, col = "orange", legend = FALSE) par(oldpar) ## End(Not run)
This function quantifies forest canopy gap size-frequency distributions and estimates power-law exponent (λ) from the Zeta distribution.
GapSizeFDist(gaps_stats,method,...)
GapSizeFDist(gaps_stats,method,...)
gaps_stats |
A data.frame containing basic statistics of forest gaps. Output of |
method |
If method='Asner_2013' the λ is computed following the method described Asner et al. (2013) and if methods='Hanel_2017' the λ is computed following the method described in Hanel et al. (2017) |
... |
Supplementary parameters for [graphics::plot()). |
A log-log plot of gap-size Frequency Distributions and a list containing: i) λ, ii) the gap-size Frequency Distributions and ii) method used. The λ parameter is derived for the Zeta distribution using a maximum likelihood estimator. See details section.
Hanel,R., Corominas-Murtra, B., Liu, B., Thurner, S. (2013). Fitting power-laws in empirical data with estimators that work for all exponents, PloS one, vol. 12, no. 2, p. e0170920.https://doi.org/10.1371/journal.pone.0170920
Asner, G.P., Kellner, J.R., Kennedy-Bowdoin, T., Knapp, D.E., Anderson, C. & Martin, R.E. (2013). Forest canopy gap distributions in the Southern Peruvian Amazon. PLoS One, 8, e60875.https://doi.org/10.1371/journal.pone.0060875
White, E.P, Enquist, B.J, Green, J.L. (2008) On estimating the exponent of power law frequency distributions. Ecology 89,905-912. https://doi.org/10.1890/07-1288.1
# Loading raster library library(raster) # ALS-derived CHM over Adolpho Ducke Forest Reserve - Brazilian tropical forest data(ALS_CHM_DUC) # set height thresholds (e.g. 10 meters) threshold <- 10 size <- c(1, 10^4) # m2 # Detecting forest gaps gaps_duc <- getForestGaps(chm_layer = ALS_CHM_DUC, threshold = threshold, size = size) # Computing basic statistics of forest gap gaps_stats <- GapStats(gap_layer = gaps_duc, chm_layer = ALS_CHM_DUC) # Gap-size Frequency Distributions GapSizeFDist( gaps_stats = gaps_stats, method = "Hanel_2017", col = "forestgreen", pch = 16, cex = 1, axes = FALSE, ylab = "Gap Frequency", xlab = as.expression(bquote("Gap Size" ~ (m^2))) ) axis(1) axis(2) grid(4, 4)
# Loading raster library library(raster) # ALS-derived CHM over Adolpho Ducke Forest Reserve - Brazilian tropical forest data(ALS_CHM_DUC) # set height thresholds (e.g. 10 meters) threshold <- 10 size <- c(1, 10^4) # m2 # Detecting forest gaps gaps_duc <- getForestGaps(chm_layer = ALS_CHM_DUC, threshold = threshold, size = size) # Computing basic statistics of forest gap gaps_stats <- GapStats(gap_layer = gaps_duc, chm_layer = ALS_CHM_DUC) # Gap-size Frequency Distributions GapSizeFDist( gaps_stats = gaps_stats, method = "Hanel_2017", col = "forestgreen", pch = 16, cex = 1, axes = FALSE, ylab = "Gap Frequency", xlab = as.expression(bquote("Gap Size" ~ (m^2))) ) axis(1) axis(2) grid(4, 4)
This function converts forest canopy gaps as raster::RasterLayer
to
sp::SpatialPointsDataFrame
objects
GapSPDF(gap_layer)
GapSPDF(gap_layer)
gap_layer |
ALS-derived gap layer (output of |
A sp::SpatialPointsDataFrame
object of the forest canopy gaps.
The result can be exported as a ESRI shapefile using
raster::shapefile()
function in the raster package.
Carlos Alberto Silva.
# Loading raster and viridis libraries library(raster) library(viridis) # ALS-derived CHM over Adolpho Ducke Forest Reserve - Brazilian tropical forest data(ALS_CHM_DUC) # set height thresholds (e.g. 10 meters) threshold <- 10 size <- c(1, 10^4) # m2 # Detecting forest gaps gaps_duc <- getForestGaps(chm_layer = ALS_CHM_DUC, threshold = threshold, size = size) # Converting raster layer to SpatialPolygonsDataFrame gaps_spdf <- GapSPDF(gap_layer = gaps_duc) # Plotting ALS-derived CHM and forest gaps plot(ALS_CHM_DUC, col = viridis(10), xlim = c(173025, 173125), ylim = c(9673100, 96731200)) plot(gaps_spdf, add = TRUE, border = "red", lwd = 2) # Populating the attribute table of Gaps_spdf with gaps statistics gaps_stats <- GapStats(gap_layer = gaps_duc, chm_layer = ALS_CHM_DUC) gaps_spdf <- merge(gaps_spdf, gaps_stats, by = "gap_id") head(gaps_spdf@data)
# Loading raster and viridis libraries library(raster) library(viridis) # ALS-derived CHM over Adolpho Ducke Forest Reserve - Brazilian tropical forest data(ALS_CHM_DUC) # set height thresholds (e.g. 10 meters) threshold <- 10 size <- c(1, 10^4) # m2 # Detecting forest gaps gaps_duc <- getForestGaps(chm_layer = ALS_CHM_DUC, threshold = threshold, size = size) # Converting raster layer to SpatialPolygonsDataFrame gaps_spdf <- GapSPDF(gap_layer = gaps_duc) # Plotting ALS-derived CHM and forest gaps plot(ALS_CHM_DUC, col = viridis(10), xlim = c(173025, 173125), ylim = c(9673100, 96731200)) plot(gaps_spdf, add = TRUE, border = "red", lwd = 2) # Populating the attribute table of Gaps_spdf with gaps statistics gaps_stats <- GapStats(gap_layer = gaps_duc, chm_layer = ALS_CHM_DUC) gaps_spdf <- merge(gaps_spdf, gaps_stats, by = "gap_id") head(gaps_spdf@data)
This function computes second order statistics of forest canopy gaps (raster::RasterLayer
) to
sp::SpatialPointsDataFrame
objects
GapsSpatPattern(gap_SPDF_layer, chm_layer)
GapsSpatPattern(gap_SPDF_layer, chm_layer)
gap_SPDF_layer |
A |
chm_layer |
ALS-derived Canopy Height Model (CHM) ( |
A plot with Ripley's K- and L-functions. Value of Clark-Evans index (R) and test for randomness (R=1), aggregation (R<1) or uniform distribution (R>1).
Ruben Valbuena and Carlos Alberto Silva.
spatstat.explore-package
, see
Lest
,
Kest
and
clarkevans.test
# This takes > 5 seconds! # Loading raster and viridis libraries library(raster) library(viridis) # ALS-derived CHM from Fazenda Cauxi - Brazilian tropical forest data(ALS_CHM_CAU_2012) data(ALS_CHM_CAU_2014) # set height thresholds (e.g. 10 meters) threshold <- 10 size <- c(1, 1000) # m2 # Detecting forest gaps gaps_cau2012 <- getForestGaps(chm_layer = ALS_CHM_CAU_2012, threshold = threshold, size = size) gaps_cau2014 <- getForestGaps(chm_layer = ALS_CHM_CAU_2014, threshold = threshold, size = size) # Converting raster layers to SpatialPolygonsDataFrame gaps_cau2012_spdf <- GapSPDF(gap_layer = gaps_cau2012) gaps_cau2014_spdf <- GapSPDF(gap_layer = gaps_cau2014) # Spatial pattern analysis of each year gaps_cau2012_SpatPattern <- GapsSpatPattern(gaps_cau2012_spdf, ALS_CHM_CAU_2012) gaps_cau2014_SpatPattern <- GapsSpatPattern(gaps_cau2014_spdf, ALS_CHM_CAU_2014)
# This takes > 5 seconds! # Loading raster and viridis libraries library(raster) library(viridis) # ALS-derived CHM from Fazenda Cauxi - Brazilian tropical forest data(ALS_CHM_CAU_2012) data(ALS_CHM_CAU_2014) # set height thresholds (e.g. 10 meters) threshold <- 10 size <- c(1, 1000) # m2 # Detecting forest gaps gaps_cau2012 <- getForestGaps(chm_layer = ALS_CHM_CAU_2012, threshold = threshold, size = size) gaps_cau2014 <- getForestGaps(chm_layer = ALS_CHM_CAU_2014, threshold = threshold, size = size) # Converting raster layers to SpatialPolygonsDataFrame gaps_cau2012_spdf <- GapSPDF(gap_layer = gaps_cau2012) gaps_cau2014_spdf <- GapSPDF(gap_layer = gaps_cau2014) # Spatial pattern analysis of each year gaps_cau2012_SpatPattern <- GapsSpatPattern(gaps_cau2012_spdf, ALS_CHM_CAU_2012) gaps_cau2014_SpatPattern <- GapsSpatPattern(gaps_cau2014_spdf, ALS_CHM_CAU_2014)
This function computes a series of forest canopy gap statistics
GapStats(gap_layer, chm_layer)
GapStats(gap_layer, chm_layer)
gap_layer |
ALS-derived gap as |
chm_layer |
ALS-derived Canopy Height Model (CHM) |
A data.frame containing forest canopy gap statistics
gap_id: gap id
gap_area - area of gap (m2)
chm_max - Maximum canopy height (m) within gap boundary
chm_min - Minimum canopy height (m) within gap boundary
chm_mean - Mean canopy height (m) within gap boundary
chm_sd - Standard Deviation of canopy heights (m) within gap boundary
chm_gini - Gini Coefficient of canopy heights (m) within gap boundary
chm_range - Range of canopy heights (m) within gap boundary
Carlos Alberto Silva.
# Loading raster library library(raster) # ALS-derived CHM over Adolpho Ducke Forest Reserve - Brazilian tropical forest data(ALS_CHM_CAU_2012) # set height thresholds (e.g. 10 meters) threshold <- 10 size <- c(5, 10^4) # m2 # Detecting forest gaps gaps_duc <- getForestGaps(chm_layer = ALS_CHM_DUC, threshold = threshold, size = size) # Computing basic statistis of forest gap gaps_stats <- GapStats(gap_layer = gaps_duc, chm_layer = ALS_CHM_DUC)
# Loading raster library library(raster) # ALS-derived CHM over Adolpho Ducke Forest Reserve - Brazilian tropical forest data(ALS_CHM_CAU_2012) # set height thresholds (e.g. 10 meters) threshold <- 10 size <- c(5, 10^4) # m2 # Detecting forest gaps gaps_duc <- getForestGaps(chm_layer = ALS_CHM_DUC, threshold = threshold, size = size) # Computing basic statistis of forest gap gaps_stats <- GapStats(gap_layer = gaps_duc, chm_layer = ALS_CHM_DUC)
This function detects forest canopy gaps on Airborne Laser Scanning(ALS)-derived Canopy Height Model (CHM).
getForestGaps(chm_layer, threshold=10, size=c(1,10^4))
getForestGaps(chm_layer, threshold=10, size=c(1,10^4))
chm_layer |
ALS-derived Canopy Height Model (CHM) ( |
threshold |
Height threshold for gap detection. Default is 10 m. |
size |
A vector containing the minimum and maximum gap size - area (m2). Gaps with area < size[1] or area > size[2] are not considered. Default is 1 m2 and 1ha. |
Forest Gaps. An object of the class RasterLayer.
Carlos Alberto Silva.
# =======================================================================# # Importing ALS-derived Canopy Height Model (CHM) # =======================================================================# # Loading raster and viridis libraries library(raster) library(viridis) # ALS-derived CHM over Adolpho Ducke Forest Reserve - Brazilian tropical forest data(ALS_CHM_DUC) # Plotting chm plot(ALS_CHM_DUC, col = viridis(10), main = "ALS CHM") grid() # =======================================================================# # Example 1: Forest Gap detection using a fixed canopy height thresholds # =======================================================================# # set height thresholds (e.g. 10 meters) threshold <- 10 size <- c(1, 10^4) # m2 # Detecting forest gaps gaps_duc <- getForestGaps(chm_layer = ALS_CHM_DUC, threshold = threshold, size = size) # Ploting gaps plot(gaps_duc, col = "red", add = TRUE, main = "Forest Canopy Gap", legend = FALSE) # =======================================================================# # Example 2: Gap detection using multiple canopy height thresholds # =======================================================================# # set the height thresholds nthresholds <- c(10, 15, 20, 25) size <- c(1, 10^4) # m2 # creating an empy raster stack to store multiple gaps as RasterLayers gaps_stack <- stack() # Gap detection for (i in nthresholds) { gaps_i <- getForestGaps(chm_layer = ALS_CHM_DUC, threshold = i, size = size) names(gaps_i) <- paste0("gaps_", i, "m") gaps_stack <- stack(gaps_stack, gaps_i) } # plot gaps oldpar <- par(no.readonly = TRUE) par(mfrow = c(2, 2)) plot(ALS_CHM_DUC, col = viridis(10), main = "Height threshold 10m") plot(gaps_stack$gaps_10m, col = "red", add = TRUE, legend = FALSE) plot(ALS_CHM_DUC, col = viridis(10), main = "Height threshold 15m") plot(gaps_stack$gaps_15m, col = "red", add = TRUE, legend = FALSE) plot(ALS_CHM_DUC, col = viridis(10), main = "Height threshold 20m") plot(gaps_stack$gaps_20m, col = "red", add = TRUE, legend = FALSE) plot(ALS_CHM_DUC, col = viridis(10), main = "Height threshold 25m") plot(gaps_stack$gaps_25m, col = "red", add = TRUE, legend = FALSE) par(oldpar)
# =======================================================================# # Importing ALS-derived Canopy Height Model (CHM) # =======================================================================# # Loading raster and viridis libraries library(raster) library(viridis) # ALS-derived CHM over Adolpho Ducke Forest Reserve - Brazilian tropical forest data(ALS_CHM_DUC) # Plotting chm plot(ALS_CHM_DUC, col = viridis(10), main = "ALS CHM") grid() # =======================================================================# # Example 1: Forest Gap detection using a fixed canopy height thresholds # =======================================================================# # set height thresholds (e.g. 10 meters) threshold <- 10 size <- c(1, 10^4) # m2 # Detecting forest gaps gaps_duc <- getForestGaps(chm_layer = ALS_CHM_DUC, threshold = threshold, size = size) # Ploting gaps plot(gaps_duc, col = "red", add = TRUE, main = "Forest Canopy Gap", legend = FALSE) # =======================================================================# # Example 2: Gap detection using multiple canopy height thresholds # =======================================================================# # set the height thresholds nthresholds <- c(10, 15, 20, 25) size <- c(1, 10^4) # m2 # creating an empy raster stack to store multiple gaps as RasterLayers gaps_stack <- stack() # Gap detection for (i in nthresholds) { gaps_i <- getForestGaps(chm_layer = ALS_CHM_DUC, threshold = i, size = size) names(gaps_i) <- paste0("gaps_", i, "m") gaps_stack <- stack(gaps_stack, gaps_i) } # plot gaps oldpar <- par(no.readonly = TRUE) par(mfrow = c(2, 2)) plot(ALS_CHM_DUC, col = viridis(10), main = "Height threshold 10m") plot(gaps_stack$gaps_10m, col = "red", add = TRUE, legend = FALSE) plot(ALS_CHM_DUC, col = viridis(10), main = "Height threshold 15m") plot(gaps_stack$gaps_15m, col = "red", add = TRUE, legend = FALSE) plot(ALS_CHM_DUC, col = viridis(10), main = "Height threshold 20m") plot(gaps_stack$gaps_20m, col = "red", add = TRUE, legend = FALSE) plot(ALS_CHM_DUC, col = viridis(10), main = "Height threshold 25m") plot(gaps_stack$gaps_25m, col = "red", add = TRUE, legend = FALSE) par(oldpar)