Skip to content

Commit

Permalink
createcanopy and treefromthesky functions #38 #39
Browse files Browse the repository at this point in the history
  • Loading branch information
Vincyane Badouard committed Aug 16, 2021
1 parent fac865b commit 8bcb7b8
Show file tree
Hide file tree
Showing 10 changed files with 352 additions and 31 deletions.
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
export("%>%")
export(ONFGuyafortaxojoin)
export(addtreedim)
export(createcanopy)
export(directionalfellingsuccessdef)
export(exploitablefuelwoodvolume)
export(futurereserve)
Expand All @@ -16,6 +17,7 @@ export(selected)
export(st_tree)
export(timberharvestedvolume)
export(treefelling)
export(treefromthesky)
export(treeselection)
importFrom(BIOMASS,computeAGB)
importFrom(BIOMASS,getWoodDensity)
Expand Down
72 changes: 72 additions & 0 deletions R/Crowns_draft.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
title: "Crowns_draft"
author: "Vincyane Badouard"
date: "16/08/2021"
output: html_document
---

```{r}
inventory <- addtreedim(inventorycheckformat(Paracou6_2016))
dat <- inventory[679,]
```


```{r}
# The crown
treefromthesky <- function(dat){
Crown <- dat %>%
mutate(xCrown = Xutm, # X centroid
yCrown = Yutm, # Y ventroid
exCrown = CrownDiameter/2,
eyCrown = CrownHeight/2) %>%
st_as_sf(coords = c("xCrown", "yCrown")) # ellipse centroid coordinates
Crown <- st_ellipse(Crown, Crown$exCrown, Crown$eyCrown) # create the ellipse
}
```

```{r}
library(ggplot2)
g <- ggplot() +
geom_sf(data = st_as_sf(inventory, coords = c("Xutm", "Yutm")), aes(label = ScientificName)) +
geom_sf(data = Crown, fill = "forestgreen") # trees polygons
plotly::ggplotly(g)
```

```{r}
Canopy <- inventory %>%
group_by(idTree) %>% # for each tree
do(Crowns = # inform geometry. # Filling a column from a function whose input is a table
treefromthesky(.) %>%
st_as_text()) %>% # as text to easy join with a non spacial table
tidyr::unnest(Crowns) # here to pass from list to character
inventory <- left_join(inventory, Canopy, by = "idTree") # join spatial filtered inventory and non spatial complete inventory
```

```{r}
#The small ones first so that they are behind the big ones on the plot
inventory <- arrange(inventory, TreeHeight)
ggplot() +
geom_sf(data = getgeometry(inventory, Crowns),
aes(alpha = TreeHeight), # label = paste(idTree, Species),
fill = "forestgreen")
```

# Plotly version
```{r}
#The small ones first so that they are behind the big ones on the plot
inventory <- arrange(inventory, TreeHeight) %>%
filter(TreeHeight >30)
g <- ggplot() +
geom_sf(data = getgeometry(inventory, Crowns),
aes(label = paste(idTree, Species), alpha = 1/2),
fill = "forestgreen") # trees polygons
plotly::ggplotly(g)
```

105 changes: 105 additions & 0 deletions R/createcanopy.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#' createcanopy
#'
#' @param inventory (data.frame)
#'
#' @return a dataframe with a column 'Crowns' containing the ellipses
#' (sfc_POLYGON) as trees crown, with their diameter and height filled in,
#' representing trees from the sky.
#' @export
#'
#' @importFrom dplyr group_by do left_join
#' @importFrom sf st_as_text
#' @importFrom tidyr unnest
#'
#' @examples
#' data(Paracou6_2016)
#' Paracou6_2016 <- dplyr::slice(Paracou6_2016, 1:10)
#'
#' inventory <- addtreedim(inventorycheckformat(Paracou6_2016))
#'
#' inventory <- createcanopy(inventory)
#'
#' # The small ones first so that they are behind the big ones on the plot
#' inventory <- dplyr::arrange(inventory, TreeHeight)
#' library(ggplot2)
#' ggplot() +
#' geom_sf(data = getgeometry(inventory, Crowns),
#' aes(alpha = TreeHeight),
#' fill = "forestgreen")
#'
createcanopy <- function(inventory){

# Arguments check

if(!inherits(inventory, "data.frame"))
stop("The 'inventory' argument of the 'createcanopy' function must be a data.frame")

# Global variables
idTree <- Crowns <- . <- NULL

# Function

Canopy <- inventory %>%

group_by(idTree) %>% # for each tree

do(Crowns = # inform geometry. # do: filling a column from a function whose input is a table
treefromthesky(.) %>%

st_as_text()) %>% # as text to easy join with a non spacial table
tidyr::unnest(Crowns) # here to pass from list to character

inventory <- left_join(inventory, Canopy, by = "idTree") # join the column 'Crowns' to the inventory

}

#' treefromthesky
#'
#' @param dat 1 row data.frame with columns:
#' Xutm, Yutm (Tree coordinates), CrownDiameter, CrownHeight
#'
#' @return an ellipse (sfc_POLYGON) as a crown, with its diameter and height
#' filled in, representing the tree from the sky.
#' @export
#'
#' @importFrom dplyr mutate
#' @importFrom sf st_as_sf
#' @importFrom nngeo st_ellipse
#'
#' @examples
#' inventory <- addtreedim(inventorycheckformat(Paracou6_2016))
#' dat <- inventory[679,]
#'
#' Crown <- treefromthesky(dat)
#'
#' library(ggplot2)
#' ggplot() +
#' geom_sf(data = st_as_sf(inventory, coords = c("Xutm", "Yutm"))) +
#' geom_sf(data = Crown, fill = "forestgreen") # trees polygons
#'
treefromthesky <- function(dat){

# Arguments check

if(!inherits(dat, "data.frame"))
stop("The 'dat' argument of the 'treefromthesky' function must be a data.frame")

if(nrow(dat)!=1)
stop("the data.frame given in the 'dat' argument
of the 'treefromthesky' function must contain only 1 row")

# Global variables
Xutm <- Yutm <- CrownDiameter <- CrownHeight <- NULL

# Function

Crown <- dat %>%
mutate(xCrown = Xutm, # X centroid
yCrown = Yutm, # Y ventroid
exCrown = CrownDiameter/2, # crown radius
eyCrown = CrownHeight/2) %>% # half crown height
st_as_sf(coords = c("xCrown", "yCrown")) # ellipse centroid coordinates

Crown <- st_ellipse(Crown, Crown$exCrown, Crown$eyCrown) # create the ellipse

}
57 changes: 36 additions & 21 deletions R/treefelling.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@
#' "DamageTreesPoints", "DeadTreesPoints" vectors
#' @export
#'
#' @importFrom dplyr filter
#' @importFrom dplyr group_by
#' @importFrom dplyr do
#' @importFrom dplyr left_join
#' @importFrom dplyr group_by do left_join
#' @importFrom sf st_as_text
#' @importFrom tidyr unnest
#'
Expand Down Expand Up @@ -401,12 +398,16 @@ rotatepolygon <- function(
#' grapple (see the \code{GrappleLength} argument of the
#' \code{\link{loggingparameters}} function). In other cases, the fall will be
#' made from the base of the tree towards the trail. The orientation of the
#' fall succeeds or fails according to a Bernoulli law where the probability of success
#' is by default 60%, and can be changed with the \code{advancedloggingparameters} argument.
#' fall succeeds or fails according to a Bernoulli law where the probability
#' of success is by default 60%, and can be changed with the
#' \code{advancedloggingparameters} argument.
#'
#' @param dat 1 row data.frame with columns: Xutm, Yutm, CrownDiameter,
#' CrownHeight, DBH, TrunkHeight, TreeHeight, TreeFellingOrientationSuccess
#'
#' @param dat (dataframe)
#' @param MainTrail (sfg)
#' @param ScndTrail (sfg)
#'
#' @param fuel Fuel wood exploitation: no exploitation = "0", damage
#' exploitation in fuelwood = "1", exploitation of hollow trees and damage in
#' fuelwood = "2"
Expand Down Expand Up @@ -499,6 +500,10 @@ st_tree <- function(
if(!inherits(dat, "data.frame"))
stop("The 'dat' argument of the 'st_tree' function must be data.frame")

if(nrow(dat)!=1)
stop("the data.frame given in the 'dat' argument
of the 'st_tree' function must contain only 1 row")

if (!any(fuel == "0" || fuel == "1"|| fuel == "2"|| is.null(fuel)))
stop("The 'fuel' argument of the 'st_tree' function must be '0', '1', '2' or NULL")

Expand Down Expand Up @@ -574,10 +579,11 @@ st_tree <- function(
))
}

# To direct only to avoid damage to future and reserve trees. Winching: Foot before.

# # To direct only to avoid damage to future and reserve trees. Winching: Foot before.
# if (directionalfelling == "1"&& (fuel !="1" || fuel !="2")) {
# if(dat$TreeFellingOrientationSuccess == "1"){

#
# }else{ # else random felling
# RandomAngle <- as.numeric(sample(c(0:359.9), size = 1))
# A <- st_difference(st_union(
Expand All @@ -588,16 +594,25 @@ st_tree <- function(
#
# }


# Scenarios with track orientation:
# Compute the last angle of the right-angled triangle (see vignette figure)
# TreefallOrientation is between the mimimun (30°) and the maximum (45°) angle
TreefallOrientation <- as.numeric(sample(c(advancedloggingparameters$MinTreefallOrientation:
advancedloggingparameters$MaxTreefallOrientation), size = 1))
OppAng <- 180-(90 + TreefallOrientation)


# To direct !!to avoid damage to future and reserve trees!! + track orientation. Winching: Foot before.
if(directionalfelling == "2"&& (fuel !="1" || fuel !="2")){
if(dat$TreeFellingOrientationSuccess == "1"){
A <- st_difference(st_union(
rotatepolygon(Trunk, angle = 240 + theta, fixed = Foot), # turned trunk
rotatepolygon(Crown, angle = 240 + theta, fixed = Foot) # turned crown
rotatepolygon(Trunk, angle = 180 + OppAng + theta, fixed = Foot), # turned trunk
rotatepolygon(Crown, angle = 180 + OppAng + theta, fixed = Foot) # turned crown
))
B <- st_difference(st_union(
rotatepolygon(Trunk, angle = 120 + theta, fixed = Foot), # turned trunk
rotatepolygon(Crown, angle = 120 + theta, fixed = Foot) # turned crown
rotatepolygon(Trunk, angle = 180 - OppAng + theta, fixed = Foot), # turned trunk
rotatepolygon(Crown, angle = 180 - OppAng + theta, fixed = Foot) # turned crown
))
}else{ # else random felling
RandomAngle <- as.numeric(sample(c(0:359.9), size = 1))
Expand All @@ -621,21 +636,21 @@ st_tree <- function(

if(TrailDist <= advancedloggingparameters$GrappleLength){ # <= 6m (= grapple length) -> winching by grapple -> crown to trail
A <- st_difference(st_union(
rotatepolygon(Trunk, angle = theta + 60 , fixed = Foot), # turned trunk
rotatepolygon(Crown, angle = theta + 60 , fixed = Foot) # turned crown
rotatepolygon(Trunk, angle = theta + OppAng , fixed = Foot), # turned trunk
rotatepolygon(Crown, angle = theta + OppAng , fixed = Foot) # turned crown
))
B <- st_difference(st_union(
rotatepolygon(Trunk, angle = 300 + theta, fixed = Foot), # turned trunk
rotatepolygon(Crown, angle = 300 + theta, fixed = Foot) # turned crown
rotatepolygon(Trunk, angle = 360 - OppAng + theta, fixed = Foot), # turned trunk
rotatepolygon(Crown, angle = 360 - OppAng + theta, fixed = Foot) # turned crown
))
} else { # > 6m -> winching by cable -> foot to trail
A <- st_difference(st_union(
rotatepolygon(Trunk, angle = 240 + theta, fixed = Foot), # turned trunk
rotatepolygon(Crown, angle = 240 + theta, fixed = Foot) # turned crown
rotatepolygon(Trunk, angle = 180 + OppAng + theta, fixed = Foot), # turned trunk
rotatepolygon(Crown, angle = 180 + OppAng + theta, fixed = Foot) # turned crown
))
B <- st_difference(st_union(
rotatepolygon(Trunk, angle = 120 + theta, fixed = Foot), # turned trunk
rotatepolygon(Crown, angle = 120 + theta, fixed = Foot) # turned crown
rotatepolygon(Trunk, angle = 180 - OppAng + theta, fixed = Foot), # turned trunk
rotatepolygon(Crown, angle = 180 - OppAng + theta, fixed = Foot) # turned crown
))
}
}else{ # else random felling
Expand Down
36 changes: 36 additions & 0 deletions man/createcanopy.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions man/st_tree.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8bcb7b8

Please sign in to comment.