#' Adjusted secondary skidding trails layout
#'
#' @description In the FWE (Fuel Wood Exploitation) case, the layout of the
#' skidding trails is redefined to favour the recovery of trees through the
#' crown (only with a grapple) in order to use the crowns for fuel wood.
#'
#' @param topography Digital terrain model (DTM) of the inventoried plot (LiDAR
#' or SRTM) (\code{\link{DTMParacou}}) (RasterLayer **with a crs in UTM**)
#'
#' @param plotmask Inventoried plot mask
#' (SpatialPolygonsDataFrame **with a crs in UTM**)
#'
#' @param maintrails Main trails defined at the entire harvestable area (sf
#' linestring **with a crs in UTM**)
#'
#' @param inventory Input inventory with new columns:
#'- The tree felling success or fail("TreeFellingOrientationSuccess")
#'- The crowns of the future/reserve trees (Polygon)
#'- The fallen trees ("TreePolygon"): a MULTIPOLYGON of the tree oriented
#' according to the chosen scenario
#'- The dead trees under felled trees (*DeathCause* = "treefall2nd")
#'
#' @param harvestablepolygons Accessible zones of the inventoried plot
#' (default: \code{\link{harvestableareadefinition}}) (sfc_MULTIPOLYGON)
#'
#' @param machinepolygons Accessible zones for machines of the inventoried plot
#' (default: \code{\link{harvestableareadefinition}}) (sf polygons data.frame)
#'
#' @param maintrailsaccess Access point of maintrail for each PU (prospection
#' unit) (sf or sfc)
#'
#' @param plotslope Slopes (in radians) of the inventoried plot (with a
#' neighbourhood of 8 cells) (default:
#' \code{\link{HarvestableAreaOutputsCable}})
#' (RasterLayer **with a crs in UTM**)
#'
#'@param scenario Logging scenario among: "RIL1", "RIL2broken", "RIL2", "RIL3",
#' "RIL3fuel", "RIL3fuelhollow" or "manual"(character) (see the
#' vignette)
#'
#'@param winching
#' "0": no cable or grapple (trail to tree foot)
#' "1": only cable (default = 40m)
#' "2": grapple (default = 6m) + cable (grapple priority)
#' If grapple + cable (winching = "2") without fuel wood (fuel = "0")
#' recovery of the tree foot with grapple if possible (respected grapple
#' conditions) otherwise with cable with angle to the trail.
#' Avoidance of future/reserves if chosen.
#'
#'@param verbose Allow to provide messages from internal functions (boolean)
#'
#' @param advancedloggingparameters Other parameters of the logging simulator
#' \code{\link{loggingparameters}} (list)
#'
#' @return A list with :
#' - *inventory*: Updated inventory
#'
#' - *SmoothedTrails*: Smoothed secondary trails (MULTIPOLYGON with crs)
#'
#' - *TrailsDensity*: Secondary trails density (in m/ha)
#'
#' - *TrailsIdentity*: Information on sections of the trails (matrix) with:
#' - *LineID*:
#' - *LoggedTrees*: idTree of trees reached by the trails
#' - *TypeExpl*: type of winching
#'
#' - *MainTrailsAccess*: Random access point of main trail for each harvestable
#' zone (sfc_POINT with crs)
#'
#' - *RawSecondTrails*: Non-smoothed secondary trails (SpatialLines with crs)
#'
#' - *CostRasterAgg*: The cost raster (RasterLayer with crs)
#'
#' @importFrom sf st_cast st_as_sf st_as_sfc st_intersection st_union st_sample st_join
#' st_buffer as_Spatial st_centroid st_set_precision st_make_valid st_set_agr
#' st_geometry st_area st_is_empty st_set_crs st_crs sf_use_s2 st_geometry<-
#' st_as_sfc st_drop_geometry
#' @importFrom dplyr mutate row_number select as_tibble left_join if_else filter
#' arrange desc
#' @importFrom tidyr unnest
#' @importFrom raster raster extend extent focal res crs mask crop rasterize
#' rasterToPoints rasterToPolygons rasterFromXYZ aggregate values ncell
#' values<-
#' @importFrom sp proj4string<- coordinates<-
#'
#' @importFrom lwgeom st_snap_to_grid
#'
#' @importFrom smoothr smooth
#'
#'@importFrom gdistance transition geoCorrection
#'@importFrom raster adjacent aggregate resample ncol ncell
#'@importFrom utils txtProgressBar setTxtProgressBar
#'@importFrom stats na.exclude
#'
#' @export
#'
#' @examples
#' \dontrun{
#' data(DTMParacou)
#' data(PlotMask)
#' data(HarvestableAreaOutputsCable)
#' data(SecondaryTrails)
#'
#' scenario <- "manual"
#' winching <- "2"
#' fuel <- "2"
#' directionalfelling <- "2"
#'
#' PostLogInventory <- treefelling(SecondaryTrails$inventory, scenario = scenario,
#' fuel = fuel,
#' winching = winching,
#' directionalfelling = directionalfelling,
#' maintrailsaccess = SecondaryTrails$MainTrailsAccess,
#' scndtrail = SecondaryTrails$SmoothedTrails,
#' advancedloggingparameters = loggingparameters())
#'
#' ScdTrailsAdj <- secondtrailsadjusted(
#' inventory = PostLogInventory,
#' topography = DTMParacou,
#' plotmask = PlotMask,
#' maintrails = MainTrails,
#' plotslope = HarvestableAreaOutputsCable$PlotSlope,
#' harvestablepolygons = HarvestableAreaOutputsCable$HarvestablePolygons,
#' machinepolygons = HarvestableAreaOutputsCable$MachinePolygons,
#' maintrailsaccess = SecondaryTrails$MainTrailsAccess,
#' scenario = scenario,
#' winching = winching,
#' advancedloggingparameters = loggingparameters())
#'
#'
#' library(ggplot2)
#' library(sf)
#'
#' NewInventory <- PostLogInventory
#' NewInventory_crs <- PostLogInventory %>%
#' getgeometry(TreePolygon) %>%
#' sf::st_set_crs(sf::st_crs(MainTrails)) # set a crs
#'
#'
#' Harvestable <- sf::st_as_sf(
#' dplyr::filter(NewInventory, LoggingStatus == "harvestable"),
#' coords = c("Xutm", "Yutm")) %>%
#' st_set_crs(st_crs(MainTrails))
#'
#' HarvestableUp <- sf::st_as_sf(
#' dplyr::filter(NewInventory, LoggingStatus == "harvestableUp"),
#' coords = c("Xutm", "Yutm")) %>%
#' st_set_crs(st_crs(MainTrails))
#'
#' Selected <- sf::st_as_sf(
#' dplyr::filter(NewInventory, Selected == "1"), coords = c("Xutm", "Yutm")) %>%
#' st_set_crs(st_crs(MainTrails))
#'
#' Reserve <- sf::st_as_sf(
#' dplyr::filter(NewInventory, LoggingStatus == "reserve"),
#' coords = c("Xutm", "Yutm")) %>%
#' st_set_crs(st_crs(MainTrails))
#'
#' Future <- sf::st_as_sf(
#' dplyr::filter(NewInventory, LoggingStatus == "future"),
#' coords = c("Xutm", "Yutm")) %>%
#' st_set_crs(st_crs(MainTrails))
#'
#' ProbedHollow <- sf::st_as_sf(
#' dplyr::filter(NewInventory, ProbedHollow == "1"),
#' coords = c("Xutm", "Yutm")) %>%
#' st_set_crs(st_crs(MainTrails))
#'
#' VisibleDefect <- sf::st_as_sf(
#' dplyr::filter(NewInventory, VisibleDefect == "1"),
#' coords = c("Xutm", "Yutm")) %>%
#' st_set_crs(st_crs(MainTrails))
#'
#'
#' ggplot() +
#' # Harvestable zones
#' geom_sf(data = HarvestableAreaOutputsCable$HarvestablePolygons,
#' fill = "olivedrab", alpha = 0.1) +
#' geom_sf(data = HarvestableAreaOutputsCable$MachinePolygons,
#' fill = "olivedrab", alpha = 0.5) +
#' labs(alpha = "Harvestable") +
#' labs(title = "Paracou P6 - secondary trails adjusted for fuel wood") +
#'
#' geom_sf(data = VisibleDefect,
#' aes(colour = "Visible defect"), show.legend = "point") +
#' geom_sf(data = Future,
#' aes(colour = "Future"), show.legend = "point", size = 4) +
#' geom_sf(data = Reserve,
#' aes(colour = "Reserve"), show.legend = "point", size = 4) +
#' geom_sf(data = Harvestable,
#' aes(colour = "Harvestable"), show.legend = "point", size = 4) +
#' geom_sf(data = HarvestableUp,
#' aes(colour = "HarvestableUp"), show.legend = "point", size = 4) +
#' geom_sf(data = Selected,
#' aes(colour = "Selected"), show.legend = "point") +
#' geom_sf(data = ProbedHollow,
#' aes(colour = "Probed hollow"), show.legend = "point") +
#'
#' geom_sf(data = NewInventory_crs, # cuted trees
#' alpha = 0.5, fill = "red") +
#'
#' # 2ndary trails
#' geom_sf(data = st_as_sf(SecondaryTrails$SmoothedTrails),
#' aes(color = "Initial-trails"),alpha = 0.5) +
#' geom_sf(data = st_as_sf(SecondaryTrails$RawSecondTrails),
#' color = "green",alpha = 0.5) +
#'
#' # 2ndary trails adjusted
#' geom_sf(data = st_as_sf(ScdTrailsAdj$SmoothedTrails),
#' aes(color = "Adjusted-trails"),alpha = 0.5) +
#' geom_sf(data = st_as_sf(ScdTrailsAdj$RawSecondTrails),
#' color = "red",alpha = 0.5) +
#'
#' scale_colour_manual(values = c("Visible defect" = "pink",
#' "Harvestable" = "skyblue",
#' "HarvestableUp" = "blue", "Selected" = "red", "Future" = "orange",
#' "Reserve" = "purple", "Probed hollow" = "forestgreen",
#' "Harvestable area" = "olivedrab", "Initial-trails" = "darkgreen" ,
#' "Adjusted-trails" = "darkred"))
#'
#' ScdTrailsAdj$TrailsIdentity
#' }
#'
secondtrailsadjusted <- function(
inventory,
topography,
plotmask,
maintrails,
plotslope,
harvestablepolygons,
machinepolygons,
maintrailsaccess = NULL,
scenario,
winching = NULL,
verbose = FALSE,
advancedloggingparameters = loggingparameters()
){
# Arguments check
if(!inherits(inventory, "data.frame"))
stop("The 'inventory'argument of the 'secondtrailsadjusted' function must be data.frame")
if(!inherits(plotmask, "SpatialPolygonsDataFrame"))
stop("The 'plotmask' argument of the 'secondtrailsadjusted' function must be
SpatialPolygonsDataFrame")
# if(!any(unlist(lapply(list(maintrails), inherits, "sf" ))))
# stop("The 'maintrails' argument of the 'secondtrailsopening' function must be sf polygon")
if(!inherits(topography, "RasterLayer"))
stop("The 'topography' argument of the 'secondtrailsadjusted' function must
be RasterLayer")
if(!inherits(maintrailsaccess, c("sf", "sfc")))
stop("The 'maintrailsaccess' argument of the 'secondtrailsadjusted' function must be sf or sfc")
# initial inventory
inventory0 <- inventory
# Options
options("rgdal_show_exportToProj4_warnings"="none") # to avoid gdal warnings
# Global Variables
slope <- x <- y <- Harvestable <- idTree <- ID <- type <- ptAcc <- NULL
EstCost <- n.overlaps <- TypeAcc <- IDpts <- Logged <- AccessPolygons <- NULL
Selected <- DeathCause <- ID_Acc <- isEmpty <- gprlAcc <- cblAcc <- NULL
LoggingStatus <- TreePolygon <- DBH <- ID.y <- IdMachineZone <- Crownpts <- NULL
IdMachineZone.y <- IdMachineZone.x <- LineID <- LoggedTrees <- TypeExpl <- NULL
#### Redefinition of the parameters according to the chosen scenario ####
scenariosparameters <- scenariosparameters(scenario = scenario, winching = winching)
WinchingInit <- scenariosparameters$winching
winching <- WinchingInit
##################################
sf_use_s2(FALSE) # to deal with actual unresolved s2 issues in sf
CostMatrix <- advancedloggingparameters$CostMatrix
factagg <- floor(advancedloggingparameters$SlopeDistance/res(topography)[1])
advancedloggingparameters$CableLength <- advancedloggingparameters$CableLength + factagg
# Transformation of the DTM so that the maintrails are outside the plot
DTMExtExtended <- raster::extend(topography, c(factagg,factagg)) # extend the extent
fill.boundaries <- function(x) {
center = 0.5 + (factagg*factagg/2)
if( is.na(x)[center] ) {
return( round(mean(x, na.rm=T),5) )
} else {
return( x[center] )
}
}
DTMExtended <- raster::focal(DTMExtExtended,
matrix(1,factagg,factagg),
fun=fill.boundaries,
na.rm=F, pad=T)
# Generate accessible area from HarvestablePolygones and winching choice
AccessPolygons <- machinepolygons
# Generate accessible area from HarvestablePolygones and winching == "0"
if (!is.null(maintrailsaccess)) {
AccessMainTrails <- AccessPolygons %>% st_union() %>%
st_cast("POLYGON", warn = FALSE) %>%
st_as_sf() %>% st_join(maintrailsaccess) %>%
select(ID)
PartMainTrails <- st_intersection(st_geometry(maintrails %>%
st_buffer(dist = 2*factagg)),
st_geometry(AccessMainTrails %>%
st_buffer(dist = -0.5*factagg))) %>%
st_union(by_feature = T) %>%
st_buffer(dist = 0.5) %>%
st_intersection(st_as_sf(plotmask) %>% st_union()) %>%
st_cast("MULTIPOLYGON", warn = FALSE) %>% # "In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only"
st_as_sf() %>%
st_set_agr(value = "constant") %>%
st_join(AccessMainTrails)
PartMainTrails <- PartMainTrails %>% arrange(desc(st_area(PartMainTrails))) %>%
filter(duplicated(PartMainTrails$ID) == FALSE)
AccessPointAll <- maintrailsaccess
}else{
accesspts <- genaccesspts(topography = topography,
machinepolygons = machinepolygons,
maintrails = maintrails,
advancedloggingparameters = advancedloggingparameters)
PartMainTrails <- accesspts$PartMainTrails
# Generate point access in the intersections between accessible area and maintrails (ID = accessible area index)
AccessPointAll <- accesspts$AccessPointAll
}
# Generate spatial objects from inventory
# Points vector with coordinates of the harvestable trees:
HarvestableTreesPoints <- inventory %>%
filter(LoggingStatus == "harvestable"|
LoggingStatus == "harvestableUp"|
LoggingStatus == "harvestable2nd") # harvestableUp = DBH > MinFD individuals, harvestable2nd = eco2 individuals is specieslax
if (dim(HarvestableTreesPoints)[1] != 0) {
HarvestableTreesPoints <- st_as_sf(HarvestableTreesPoints, coords = c("Xutm", "Yutm"))%>%
sf::st_set_crs(sf::st_crs(topography)) # sp::coordinates(HarvestableTreesPoints) <- ~ Xutm + Yutm
# sp::proj4string(HarvestableTreesPoints) <- raster::crs(topography)
} else {HarvestableTreesPoints = st_point(x = c(NA_real_, NA_real_))} # empty
# Points vector with coordinates of the selected trees:
SelectedTreesPoints <- inventory %>%
filter(Selected == "1")
if (dim(SelectedTreesPoints)[1] != 0) {
SelectedTreesPoints <- st_as_sf(SelectedTreesPoints, coords = c("Xutm", "Yutm"))%>%
sf::st_set_crs(sf::st_crs(topography)) # sp::coordinates(SelectedTreesPoints) <- ~ Xutm + Yutm
# sp::proj4string(SelectedTreesPoints) <- raster::crs(topography)
} else {SelectedTreesPoints = st_point(x = c(NA_real_, NA_real_))} # empty
inventory_sf <- inventory %>%
filter(Selected == "1") %>% st_as_sf(coords = c("Xutm", "Yutm")) %>%
sf::st_set_crs(sf::st_crs(topography)) %>% # set a crs
mutate("CrownGeom" = st_point(x = c(NA_real_, NA_real_)) %>% st_as_text())
inventory_Tr <- inventory %>% getgeometry(TreePolygon)
Trunks <- st_cast(inventory_Tr$TreePolygon , "POLYGON", warn = FALSE)[seq(1, by = 2, len = nrow(inventory))]
Trunks <- Trunks %>% sf::st_set_crs(sf::st_crs(topography))
inventory_Tr <- inventory_sf
for (h in 1:nrow(inventory)) {
if (!st_is_empty(Trunks[h])) {
inventory_Tr$CrownGeom[h] <- st_difference(Trunks[h],inventory_sf[h,] %>%
st_buffer(dist =
(inventory_sf$TrunkHeight[h] * 0.95))) %>%
st_centroid() %>% st_union()%>% st_as_text()
}
}
Trunks <- Trunks %>%
sf::st_set_crs(sf::st_crs(topography))%>%
st_buffer(dist = 0.1) %>% st_as_sf()%>% st_join(SelectedTreesPoints) %>% dplyr::select(idTree)
# Points vector with coordinates of the selected trees:
SelectedCrownsPoints <- st_as_sfc(inventory_Tr$CrownGeom) %>%
sf::st_set_crs(sf::st_crs(topography)) %>% st_as_sf() %>% st_join(Trunks)
if(names(SelectedCrownsPoints)[2] == "x")
SelectedCrownsPoints <- SelectedCrownsPoints %>% st_set_geometry("geometry")
SelectedCrownsPoints <- SelectedCrownsPoints %>% filter(!st_is_empty(SelectedCrownsPoints))
# Points vector with coordinates of the future trees:
FutureTreesPoints <- inventory %>%
filter(LoggingStatus == "future")
if (dim(FutureTreesPoints)[1] != 0) {
FutureTreesPoints <- st_as_sf(FutureTreesPoints, coords = c("Xutm", "Yutm"))%>%
sf::st_set_crs(sf::st_crs(topography)) # sp::coordinates(FutureTreesPoints) <- ~ Xutm + Yutm
# sp::proj4string(FutureTreesPoints) <- raster::crs(topography)
} else {FutureTreesPoints = st_point(x = c(NA_real_, NA_real_))} # empty
# Points vector with coordinates of the reserve trees:
ReserveTreesPoints <- inventory %>%
filter(LoggingStatus == "reserve")
if (dim(ReserveTreesPoints)[1] != 0) {
ReserveTreesPoints <- st_as_sf(ReserveTreesPoints, coords = c("Xutm", "Yutm"))%>%
sf::st_set_crs(sf::st_crs(topography)) # sp::coordinates(ReserveTreesPoints) <- ~ Xutm + Yutm
# sp::proj4string(ReserveTreesPoints) <- raster::crs(topography)
} else {ReserveTreesPoints = st_point(x = c(NA_real_, NA_real_))} # empty
# Points vector with coordinates of the big trees (DBH >= 50 cm):
BigTreesPoints <- inventory %>%
filter(DBH >= advancedloggingparameters$BigTrees) # & (Selected != "1" & LoggingStatus != "harvestable") & LoggingStatus != "harvestableUp" & LoggingStatus != "harvestable2nd"
if (dim(BigTreesPoints)[1] != 0) {
sp::coordinates(BigTreesPoints) <- ~ Xutm + Yutm
sp::proj4string(BigTreesPoints) <- crs(topography)
BigTreesPoints <- BigTreesPoints %>% st_as_sf()
} else {BigTreesPoints = st_point(x = c(NA_real_, NA_real_))}
treeselectionoutputs <- list(inventory = inventory ,
HarvestableTreesPoints = HarvestableTreesPoints,
SelectedTreesPoints = SelectedTreesPoints,
SelectedCrownsPoints = SelectedCrownsPoints,
FutureTreesPoints = FutureTreesPoints,
ReserveTreesPoints = ReserveTreesPoints,
BigTreesPoints = BigTreesPoints)
# Generate Cost raster --> cf CostMatrix
CostRaster <- raster(extent(DTMExtended),resolution = res(DTMExtended), crs = crs(DTMExtended))
values(CostRaster) <- CostMatrix[[2]][[1]]$CostValue
#Generate weight according to slope conditions
# RastersToPoints
plotslopePoint <- as_tibble(rasterToPoints(plotslope))
CostRasterPoint <- as_tibble(rasterToPoints(CostRaster))
# left join par x et y
plotTib <-
left_join(plotslopePoint, CostRasterPoint, by = c('x', 'y'))
CostSlopeRaster <- plotTib %>%
mutate(Harvestable = if_else(
slope <= atan(CostMatrix[[1]][[1]]$Slope/100),
true = CostMatrix[[1]][[1]]$Cost,
false = if_else(
slope <= atan(CostMatrix[[1]][[2]]$Slope/100),
true = CostMatrix[[1]][[2]]$Cost,
false = if_else(
slope <= atan(CostMatrix[[1]][[3]]$Slope/100),
true = CostMatrix[[1]][[3]]$Cost,
false = if_else(
slope <= atan(CostMatrix[[1]][[4]]$Slope/100),
true = CostMatrix[[1]][[4]]$Cost,
false = if_else(
slope <= atan(CostMatrix[[1]][[5]]$Slope/100),
true = CostMatrix[[1]][[5]]$Cost,
false = CostMatrix[[1]][[6]]$Cost)
)
)
)
)) %>% dplyr::select(x,y,Harvestable)
CostRaster <- rasterFromXYZ(CostSlopeRaster, crs = crs(DTMExtended)) # Update weights from plotTib tibble
#Aggregation each raster to selected resolution
CostRasterMean <- aggregate(CostRaster, fact=factagg, fun=mean)
DTMmean <- aggregate(DTMExtended, fact=factagg, fun=mean)
plotmaskagg <- rasterToPolygons(DTMmean, dissolve=T) %>% st_as_sf() %>% st_union() %>% as_Spatial()
#Generate protection buffer for Big Trees (dist : ScndTrailWidth/2 + 2 m)
BigTreesRaster <- raster(extent(DTMmean),resolution = res(DTMmean), crs = crs(DTMmean))
values(BigTreesRaster) <- 0
BigTreesRaster <- rasterize(x = as_Spatial(treeselectionoutputs$BigTreesPoints %>%
st_buffer(dist = advancedloggingparameters$ScndTrailWidth/2 + 2) ),
y = BigTreesRaster,
field = CostMatrix[[2]][[3]]$CostValue,
update = TRUE)
BigTreesRaster <- crop(BigTreesRaster, CostRasterMean)
BigTreesRaster <- mask(BigTreesRaster, plotmaskagg)
#Generate protection buffer for Reserve Trees (dist : ScndTrailWidth/2 + 2 m)
ReserveRaster <- raster(extent(DTMmean),resolution = res(DTMmean), crs = crs(DTMmean))
values(ReserveRaster) <- 0
ReserveRaster <- rasterize(x = as_Spatial(treeselectionoutputs$HarvestableTreesPoints %>%
st_buffer(dist = advancedloggingparameters$ScndTrailWidth/2 + 2) ),
y = ReserveRaster,
field = CostMatrix[[2]][[4]]$CostValue,
update = TRUE)
ReserveRaster <- crop(ReserveRaster, CostRasterMean)
ReserveRaster <- mask(ReserveRaster, plotmaskagg)
#Generate protection buffer for Futures Trees (dist : ScndTrailWidth/2 + 2 m)
FutureRaster <- raster(extent(DTMmean),resolution = res(DTMmean), crs = crs(DTMmean))
values(FutureRaster ) <- 0
FutureRaster <- rasterize(x = as_Spatial(treeselectionoutputs$HarvestableTreesPoints %>%
st_buffer(dist = advancedloggingparameters$ScndTrailWidth/2 +2) ),
y = FutureRaster ,
field = CostMatrix[[2]][[5]]$CostValue,
update = TRUE)
FutureRaster <- crop(FutureRaster, CostRasterMean)
FutureRaster <- mask(FutureRaster, plotmaskagg)
#Update Cost Raster with protection buffers
#Generate protection buffer for selected Trees (dist : ScndTrailWidth/2 + 2 m)
SelectedRaster <- raster(extent(DTMmean),resolution = res(DTMmean), crs = crs(DTMmean))
values(SelectedRaster ) <- 0
SelectedRaster <- rasterize(x = as_Spatial(treeselectionoutputs$SelectedTreesPoints %>%
st_buffer(dist = 2) ),
y = SelectedRaster,
field = CostMatrix[[2]][[3]]$CostValue/2,
update = TRUE)
SelectedRaster <- crop(SelectedRaster, CostRasterMean)
SelectedRaster <- mask(SelectedRaster, plotmaskagg)
#Update Cost Raster with protection buffers
CostRasterMean <- CostRasterMean + BigTreesRaster + ReserveRaster + FutureRaster + SelectedRaster
#Generate maintrail intersection cost raster
CostRasterMean <- raster::rasterize(x = as_Spatial(AccessPointAll %>% st_buffer(dist = advancedloggingparameters$ScndTrailWidth+2)),
y = CostRasterMean ,
field = CostMatrix[[2]][[6]]$CostValue,
update = TRUE)
#Generate Slope accessibility for grapple machine
if (winching == "2") {
plotslopePointGrpl <- as_tibble(rasterToPoints(plotslope))
CostRasterPointGrpl <- as_tibble(rasterToPoints(CostRaster))
# left join par x et y
plotTibGrpl <-
left_join(plotslopePointGrpl, CostRasterPointGrpl, by = c('x', 'y'))
CostSlopeRasterGrpl <- plotTibGrpl %>%
mutate(Harvestable = if_else(
slope <= atan(advancedloggingparameters$GrappleMaxslope/100),
true = 0,
false = Inf
)) %>% dplyr::select(x,y,Harvestable)
CostRasterGrpl <- rasterFromXYZ(CostSlopeRasterGrpl, crs = crs(CostRasterMean))
PolygonGrpl <- rasterToPolygons(x = CostRasterGrpl,
n = 8,
dissolve = TRUE)
CostRasterMeanGrpl <- raster::rasterize(x = PolygonGrpl[PolygonGrpl$Harvestable == Inf,],
y = CostRasterMean ,
field = Inf,
update = TRUE)
CostRasterMeanGrpl <- raster::rasterize(x = as_Spatial(AccessPointAll %>% st_buffer(dist = advancedloggingparameters$ScndTrailWidth+2)),
y = CostRasterMeanGrpl ,
field = CostMatrix[[2]][[6]]$CostValue,
update = TRUE)
#Generate accessible weights raster
AccessRaster <- raster(extent(CostRaster),resolution = res(CostRaster), crs = crs(CostRaster))
values(AccessRaster) <- CostMatrix[[2]][[2]]$CostValue
AccessRaster <- raster::rasterize(x = as_Spatial(machinepolygons %>% st_buffer(dist = factagg)),
y = AccessRaster ,
field = 0,
update = TRUE)
AccessRaster <- aggregate(AccessRaster,fact=factagg, fun=min)
AccessRaster <- crop(AccessRaster, CostRasterMeanGrpl)
AccessRaster <- mask(AccessRaster, plotmaskagg)
#Update Cost Raster with accessible weights raster
CostRasterMeanGrpl <- CostRasterMeanGrpl + AccessRaster
}
#Generate accessible weights raster
AccessRaster <- raster(extent(CostRaster),resolution = res(CostRaster), crs = crs(CostRaster))
values(AccessRaster) <- CostMatrix[[2]][[2]]$CostValue
AccessRaster <- raster::rasterize(x = as_Spatial(machinepolygons %>% st_buffer(dist = factagg)),
y = AccessRaster ,
field = 0,
update = TRUE)
AccessRaster <- aggregate(AccessRaster,fact=factagg, fun=min)
AccessRaster <- crop(AccessRaster, CostRasterMean)
AccessRaster <- mask(AccessRaster,plotmaskagg)
#Update Cost Raster with accessible weights raster
CostRasterMean <- CostRasterMean + AccessRaster
pathLines <- list() #Initialize storage pathlines
Lines <- list() #Initialize storage logged trees
k <- 1 #Initialize pathlines index
l <- 1 #Initialize lines index
#Generate appropriate selected trees points format
ptsAllinit <- treeselectionoutputs$SelectedTreesPoints %>%
dplyr::select(idTree) %>%
st_cast("POINT", warn = FALSE) %>%
mutate(ID = NA) %>%
mutate(type = "Tree") %>%
st_set_crs(st_crs(AccessPointAll)) %>%
st_join(AccessMainTrails %>% st_buffer(dist = max((advancedloggingparameters$ScndTrailWidth/2),factagg)) %>%
mutate(ID_Acc = ID) %>% dplyr::select(-ID)) %>%
dplyr::select(ID,ID_Acc,type,idTree)
ptsAllNA <- ptsAllinit %>% filter(is.na(ID_Acc)) %>%
mutate(ID_Acc = AccessMainTrails$ID[c(max.col(-st_distance(ptsAllinit %>% filter(is.na(ID_Acc)),AccessMainTrails)))])
ptsAllNotNA <- ptsAllinit %>% filter(!is.na(ID_Acc))
ptsAll <- rbind(ptsAllNotNA,ptsAllNA)
ptsCrAllinit <- treeselectionoutputs$SelectedCrownsPoints %>%
dplyr::select(idTree) %>%
st_cast("POINT", warn = FALSE) %>%
mutate(ID = NA) %>%
mutate(type = "Crown") %>%
st_set_crs(st_crs(AccessPointAll))
ptsCrAll <- ptsCrAllinit %>% filter(ptsCrAllinit %>% st_intersects(AccessMainTrails %>% st_union(),sparse = FALSE)) %>%
left_join(ptsAll %>% select(ID_Acc,idTree) %>% st_drop_geometry(), by = "idTree" ) %>%
dplyr::select(ID,ID_Acc,type,idTree) %>% filter(!is.na(ID_Acc))
# Reassign Selected Tree values (= BigTrees) to the aggregated Cost raster
CostRasterMean <- raster::rasterize(x = as_Spatial(ptsAll %>% st_buffer(dist = factagg)),
y = CostRasterMean ,
field = CostMatrix[[2]][[3]]$CostValue,
update = TRUE)
if (winching == "2") {
# Reassign Selected Tree values (= BigTrees) to the aggregated Cost raster (Grpl)
CostRasterMeanGrpl <- raster::rasterize(x = as_Spatial(ptsAll %>%
st_buffer(dist = factagg)),
y = CostRasterMeanGrpl ,
field = CostMatrix[[2]][[3]]$CostValue,
update = TRUE)
CostRasterMeanGrpl <- crop(CostRasterMeanGrpl, CostRasterMean)
CostRasterMeanGrpl <- mask(CostRasterMeanGrpl, plotmaskagg)
}
#Generate maintrail intersection cost raster
CostRasterMean <- raster::rasterize(x = as_Spatial(AccessPointAll %>% st_buffer(dist = 3*factagg)),
y = CostRasterMean ,
field = CostMatrix[[2]][[6]]$CostValue,
update = TRUE)
CostRasterMean <- crop(CostRasterMean,DTMmean)
CostRasterMean <- mask(CostRasterMean,plotmaskagg)
DTMmean <- crop(DTMmean,CostRasterMean)
DTMmean <- mask(DTMmean,plotmaskagg)
#Compute conductance raster
CondSurf <- 1/CostRasterMean
########### Compute slope criteria transition graph ###############
if (winching == "2") {
#Compute adjacent transition layer according to slope conditions (winching = "2")
SlopeCondGrpl <- sloperdcond(topography = DTMmean,
advancedloggingparameters = advancedloggingparameters,
grapple = TRUE)
}
#Compute adjacent transition layer according to slope conditions (winching = "1")
SlopeCond <- sloperdcond(topography = DTMmean,advancedloggingparameters = advancedloggingparameters)
########### Compute LCP algorithm ###############
for (ID_Access in unique(ptsAll$ID_Acc)) {
if (verbose){
print(ID_Access)
}
winching <- WinchingInit
pts <- ptsAll %>% filter(ID_Acc == ID_Access) %>% dplyr::select(-ID_Acc)
ptsCr <- ptsCrAll %>% filter(ID_Acc == ID_Access) %>% dplyr::select(-ID_Acc)
AccessPoint <- AccessPointAll %>% filter(ID == ID_Access)
pathLinesWIP <- c()
ki <- 1
if (winching == "0") {
# winching 0 #########
pts <- st_set_crs(pts, st_crs(AccessPoint))# set crs
pts <- rbind(AccessPoint %>%
mutate(type = "Access") %>%
mutate(IPpts = paste0("A.",row_number())),
pts %>%
mutate(IPpts = paste0("T.",idTree)))
PointAcc <- pts %>%
filter(type == "Access") %>%
mutate(EstCost = NA)
#Compute Cost between points and Access points
CostDistEst <- adjtopolcp(costSurface = CondSurf,
topography = DTMmean ,
pts = pts %>%
as_Spatial(),
slopeRdCond = SlopeCond,
paths = FALSE) [,1:dim(AccessPoint)[1]]
CostDistEst <- CostDistEst[(length(PointAcc$ID)+1):length(CostDistEst)[1]]
CostDistEst <- matrix(CostDistEst,ncol = length(PointAcc$ID) )
#Attribute a least cost point access to each points
PointTree <- pts %>% filter(type == "Tree") %>%
mutate(ptAcc = max.col(-CostDistEst))
PointTree$ID <- as.factor(PointTree$ptAcc)
levels(PointTree$ID) <- as.character(AccessPoint$ID)
pts <- rbind(AccessPoint %>%
mutate(type = "Access") %>%
mutate(ptAcc = row_number()) %>%
mutate(IPpts = paste0("A.",row_number())),
PointTree %>%
mutate(IPpts = paste0("T.",idTree)))
PointAcc <- pts %>%
filter(type == "Access") %>%
mutate(EstCost = NA)
#Attribute a least cost point access to each points
PointTree <- pts %>% filter(type == "Tree") %>%
mutate(ptAcc = max.col(-CostDistEst))
if (length(PointAcc$ID) == 1) {
PointTree <- PointTree %>% mutate(EstCost = CostDistEst)
}else{PointTree <- PointTree %>% mutate(EstCost = apply(CostDistEst,1, min))}
selectedPoints <- rbind(PointAcc,PointTree)
accessPtId <- 1
TmpSelectedPts <- selectedPoints %>%
filter(ptAcc == accessPtId)
TmpAccPts <- TmpSelectedPts %>%
filter(type == "Access")
#Select Costliest selected tree
TmpTreePts <- TmpSelectedPts %>%
filter(type == "Tree") %>%
arrange(desc(EstCost))
if (dim(TmpTreePts)[1] != 0) {
for (TreeId in 1:dim(TmpTreePts)[1]){
#Compute Least cost path polygons to the WIP selected tree
TmpPtsWIP <- rbind(TmpAccPts,TmpTreePts[TreeId,])
TmpPathWIP <- adjtopolcp(costSurface = CondSurf,topography = DTMmean , pts = TmpPtsWIP %>% as_Spatial(),
slopeRdCond = SlopeCond,paths = TRUE)
if (TmpPathWIP[[1]][1,2] == 0) {
#Update Cost raster with LCP second trail
CostRasterMean <- raster::rasterize(x = TmpTreePts[TreeId,] ,
y = CostRasterMean ,
field = CostMatrix[[2]][[7]]$CostValue,update = TRUE)
}else{
#Update Cost raster with LCP second trail
CostRasterMean <- raster::rasterize(x = TmpPathWIP[[2]] ,
y = CostRasterMean ,
field = CostMatrix[[2]][[7]]$CostValue,update = TRUE)
}
CondSurf <- 1/CostRasterMean
#Store pathline
pathLines[[k]] <- TmpPathWIP[[2]]
pathLines[[k]]@lines[[1]]@ID <- paste("Path", TmpPtsWIP$idTree[2], sep = ".")
Lines[[k]] <- list("LineID" = k,"LoggedTrees" = TmpPtsWIP$idTree[2],"TypeExpl" = "FoT")
k <- k +1
}
}
}else{
# winching 1/2 #########
# Select intersection points from buffer polygons
PointAcc <- AccessPoint %>% #def Access Point
mutate(type = "Access") %>%
mutate(IDpts = paste0("A.",row_number())) %>%
mutate(n.overlaps = NA, origins = NA) %>%
dplyr::select(-ID)
TreePts <- pts %>% filter(type == "Tree")
CrownPts <- ptsCr %>% filter(type == "Crown")
if (winching == "2") {
if (dim(CrownPts)[1] == 0 ) {
Crown2FoT <- TRUE
ptsGrpl <- TreePts %>% #def Grpl point
st_buffer(dist = advancedloggingparameters$GrappleLength) %>%
st_snap_to_grid(size = .2) %>% # avoid GEOS error (st-intersection issue)
#st_set_precision(1) %>%
st_temporaryintersection(topography = topography,
plotmask = plotmask,
advancedloggingparameters = advancedloggingparameters) %>%
st_make_valid() %>%
mutate(type = "InterTr") %>%
dplyr::select(-ID)
for (OriginI in 1:length(ptsGrpl$origins)) {
for (OriginJ in 1:length(ptsGrpl$origins[[OriginI]])) {
IndexPts <- ptsGrpl$origins[[OriginI]][OriginJ]
ptsGrpl$origins[[OriginI]][OriginJ] <- TreePts$idTree[IndexPts]
}
}
ptsGrpl$isEmpty <- FALSE
for (h in 1:dim(ptsGrpl)[1]) {
if (ptsGrpl[h,] %>% st_intersects(AccessMainTrails %>% filter(ID == ID_Access),sparse = FALSE) == FALSE) {
ptsGrpl$isEmpty[h] <- TRUE
}else{
suppressWarnings(st_geometry(ptsGrpl[h,]) <- st_geometry(ptsGrpl[h,] %>% st_intersection(AccessMainTrails %>% filter(ID == ID_Access))))
}
}
#Filter polygons which intersect accessible area to second trails
ptsGrpl<- st_set_crs(ptsGrpl,st_crs(AccessPolygons)) # set crs from AccessPolygons
ptsGrpl <- ptsGrpl %>% filter(isEmpty == FALSE) %>% dplyr::select(-isEmpty) %>%
mutate(IDpts = paste0("I.", row_number()))
ptsWIP <- ptsGrpl %>% #def Grpl point as WIP point
st_set_agr("constant") %>%
st_centroid()
}else{
Crown2FoT <- FALSE
ptsGrpl <- CrownPts %>% #def Grpl point
st_buffer(dist = advancedloggingparameters$GrappleLength) %>%
st_snap_to_grid(size = .2) %>% # avoid GEOS error (st-intersection issue)
#st_set_precision(1) %>%
st_temporaryintersection(topography = topography,
plotmask = plotmask,
advancedloggingparameters = advancedloggingparameters) %>%
st_make_valid() %>%
mutate(type = "InterCr") %>%
dplyr::select(-ID)
for (OriginI in 1:length(ptsGrpl$origins)) {
for (OriginJ in 1:length(ptsGrpl$origins[[OriginI]])) {
IndexPts <- ptsGrpl$origins[[OriginI]][OriginJ]
ptsGrpl$origins[[OriginI]][OriginJ] <- CrownPts$idTree[IndexPts]
}
}
ptsGrpl$isEmpty <- FALSE
for (h in 1:dim(ptsGrpl)[1]) {
if (ptsGrpl[h,] %>% st_intersects(AccessMainTrails %>% filter(ID == ID_Access),sparse = FALSE) == FALSE) {
ptsGrpl$isEmpty[h] <- TRUE
}else{
suppressWarnings(st_geometry(ptsGrpl[h,]) <- st_geometry(ptsGrpl[h,] %>% st_intersection(AccessMainTrails %>% filter(ID == ID_Access))))
}
}
#Filter polygons which intersect accessible area to second trails
ptsGrpl<- st_set_crs(ptsGrpl,st_crs(AccessPolygons)) # set crs from AccessPolygons
ptsGrpl <- ptsGrpl %>% filter(isEmpty == FALSE) %>% dplyr::select(-isEmpty) %>%
mutate(IDpts = paste0("I.", row_number()))
ptsWIP <- ptsGrpl %>% #def Grpl point as WIP point
st_set_agr("constant") %>%
st_centroid()
}
ptsCbl <- TreePts %>% #def cbl polygons
st_buffer(dist = advancedloggingparameters$CableLength) %>%
st_snap_to_grid(size = 1) %>%# avoid GEOS error (st-intersection issue)
st_set_precision(1) %>%
st_temporaryintersection(topography = topography,
plotmask = plotmask,
advancedloggingparameters = advancedloggingparameters) %>%
st_make_valid() %>%
mutate(type = "InterTr")%>%
dplyr::select(-ID)
for (OriginI in 1:length(ptsCbl$origins)) {
for (OriginJ in 1:length(ptsCbl$origins[[OriginI]])) {
IndexPts <- ptsCbl$origins[[OriginI]][OriginJ]
ptsCbl$origins[[OriginI]][OriginJ] <- TreePts$idTree[IndexPts]
}
}
ptsCbl$isEmpty <- FALSE
for (h in 1:dim(ptsCbl)[1]) {
if (ptsCbl[h,] %>% st_intersects(AccessMainTrails %>% filter(ID == ID_Access),sparse = FALSE) == FALSE) {
ptsCbl$isEmpty[h] <- TRUE
}else{
suppressWarnings(st_geometry(ptsCbl[h,]) <- st_geometry(ptsCbl[h,] %>% st_intersection(AccessMainTrails %>% filter(ID == ID_Access))))
}
}
ptsCbl <- st_set_crs(ptsCbl,st_crs(AccessPolygons)) #set crs from AccessPolygons
ptsCbl <- ptsCbl %>% filter(isEmpty == FALSE) %>% dplyr::select(-isEmpty) %>%
mutate(IDpts = paste0("I.",row_number())) #Filter polygons which intersect accessible area to second trails
ptsWIPCbl <- ptsCbl %>%#Convert polygons to centroid
st_set_agr("constant") %>%
st_centroid()
ptsWIP <- ptsWIP %>%
arrange(desc(n.overlaps))
RemainTree <- dim(TreePts)[1]
#Select adjacent grpl graph
SlopeCondRd <- SlopeCondGrpl
}else{
Crown2FoT <- TRUE
ptsCbl <- TreePts %>% #def cbl point
st_buffer(dist = advancedloggingparameters$CableLength) %>%
st_snap_to_grid(size = 1) %>% # avoid GEOS error (st-intersection issue)
st_set_precision(1) %>%
st_temporaryintersection(topography = topography,
plotmask = plotmask,
advancedloggingparameters = advancedloggingparameters) %>%
st_make_valid() %>%
mutate(IDpts = paste0("I.",row_number())) %>%
mutate(type = "InterTr") %>% dplyr::select(-ID)
ptsCbl <- st_set_crs(ptsCbl,st_crs(AccessPolygons)) #set crs from AccessPolygons
for (OriginI in 1:length(ptsCbl$origins)) {
for (OriginJ in 1:length(ptsCbl$origins[[OriginI]])) {
IndexPts <- ptsCbl$origins[[OriginI]][OriginJ]
ptsCbl$origins[[OriginI]][OriginJ] <- TreePts$idTree[IndexPts]
}
}
ptsCbl$isEmpty <- FALSE
for (h in 1:dim(ptsCbl)[1]) {
if (st_geometry(ptsCbl[h,]) %>% st_intersects(AccessMainTrails %>% filter(ID == ID_Access),sparse = FALSE) == FALSE) {
ptsCbl$isEmpty[h] <- TRUE
}else{
suppressWarnings(st_geometry(ptsCbl[h,]) <- st_geometry(ptsCbl[h,] %>% st_intersection(AccessMainTrails %>% filter(ID == ID_Access))))
}
}
ptsWIP <- ptsCbl %>% filter(isEmpty == FALSE) %>% dplyr::select(-isEmpty) %>%#def cbl point as WIP point
st_set_agr("constant") %>%
st_centroid()
ptsWIP <- ptsWIP %>% #filter cbl intersection centroid point out plot
filter(st_intersects(st_geometry(ptsWIP),
st_geometry(plotmask %>%
st_as_sf()),
sparse = FALSE)) %>%
arrange(desc(n.overlaps))
RemainTree <- dim(TreePts)[1]
#Select adjacent cbl graph
SlopeCondRd <- SlopeCond
}
#Define a switch from grapple accessible tree exploitation to cable exploitation
if (winching == "2") {
WinchingSwitch <- FALSE
}else{
WinchingSwitch <- TRUE
}
steps <- 0
RemainTreeInit <- RemainTree
#Loop over possible intersection
while (RemainTree !=0L & steps < 5*RemainTreeInit) {
steps <- steps + 1
if (verbose) {
print(RemainTree)
print(paste0("Crown2FoT : ",Crown2FoT))
}
#Switch from grpl to cbl exploitation when grapple accessible tree != 0
Grpl2CblFlag <- FALSE
stoplog <- FALSE
if (length(unique(unlist(ptsGrpl$origins))) == 0 & WinchingSwitch == FALSE & winching == "2" & Crown2FoT) {
winching <- "1"
ptsWIP <- ptsWIPCbl
WinchingSwitch <- TRUE
}
if (!Crown2FoT & dim(CrownPts)[1] == 0) {
Crown2FoT <- TRUE
stoplog <- TRUE
}
if ((dim(ptsWIP)[1] != 0 & !Crown2FoT)| (dim(TreePts)[1] != 0 & Crown2FoT & !stoplog) | (dim(TreePts)[1] != 0 & (winching=="1")) ) {
ptsWIPmax <- rbind(PointAcc,ptsWIP %>%
filter(n.overlaps == max(ptsWIP$n.overlaps))) %>%
mutate(TypeAcc = NA) %>%
mutate(EstCost = NA) %>%
mutate(ptsAcc = NA)
if (!Crown2FoT) {
ptsTreeWIP <- rbind(PointAcc,CrownPts %>%
mutate(n.overlaps = NA, origins = idTree,IDpts = NA) %>%
dplyr::select(-ID)) %>%
mutate(TypeAcc = NA) %>%
mutate(EstCost = NA) %>%
mutate(ptsAcc = NA)
}else{
ptsTreeWIP <- rbind(PointAcc,TreePts %>%
mutate(n.overlaps = NA, origins = idTree,IDpts = NA) %>%
dplyr::select(-ID)) %>%
mutate(TypeAcc = NA) %>%
mutate(EstCost = NA) %>%
mutate(ptsAcc = NA)
}
if (k == 1 ) {
if (winching == "2") {
ptsDirAcc <- ptsTreeWIP %>% mutate(gprlAcc = c(FALSE,as.numeric(st_distance(ptsTreeWIP)[2:dim(ptsTreeWIP)[1],1]) < advancedloggingparameters$GrappleLength)) %>%
filter(gprlAcc == TRUE | type == "Access") %>% dplyr::select(-gprlAcc)
TmpTypeAcc <- "Grpl"
}else{
ptsDirAcc <- ptsTreeWIP %>% mutate(cblAcc = c(FALSE,as.numeric(st_distance(ptsTreeWIP)[2:dim(ptsTreeWIP)[1],1]) < advancedloggingparameters$CableLength)) %>%
filter(cblAcc == TRUE | type == "Access") %>% dplyr::select(-cblAcc)
TmpTypeAcc <- "Cbl"
}
}else{
# Set pathsWIP CRS
pathsWIP <- st_set_crs(pathsWIP, st_crs(ptsTreeWIP))
if (winching == "2") {
ptsDirAcc <- ptsTreeWIP %>% mutate(gprlAcc = c(FALSE,as.numeric(st_distance(ptsTreeWIP,st_union(pathsWIP,PointAcc))[2:dim(ptsTreeWIP)[1],1]) < advancedloggingparameters$GrappleLength)) %>%
filter(gprlAcc == TRUE | type == "Access") %>% dplyr::select(-gprlAcc)
TmpTypeAcc <- "Grpl"
}else{
ptsDirAcc <- ptsTreeWIP %>% mutate(cblAcc = c(FALSE,as.numeric(st_distance(ptsTreeWIP,st_union(pathsWIP,PointAcc))[2:dim(ptsTreeWIP)[1],1]) < advancedloggingparameters$CableLength)) %>%
filter(cblAcc == TRUE | type == "Access") %>% dplyr::select(-cblAcc)
TmpTypeAcc <- "Cbl"
}
}
if (dim(ptsDirAcc)[1] > 1) {
PointTreeWIP <- ptsDirAcc %>% filter(type == "Tree"| type == "Crown")
if (verbose){
print(paste0("LoggedTrees : ",PointTreeWIP$origins[[1]]))
}
Lines[[l]] <- list("LineID" = NA,"LoggedTrees" = PointTreeWIP$origins,"Crownpts" = !Crown2FoT,"TypeExpl" = TmpTypeAcc,"IdMachineZone" = ID_Access)
l <- l+1
}else{
#Compute Cost between points and Access points in cbl exploitation
CostDistEstCbl <- adjtopolcp(costSurface = CondSurf,
topography = DTMmean ,
pts = ptsWIPmax %>%
as_Spatial(),
slopeRdCond = SlopeCond,
paths = FALSE) [,1]
CostDistEstCbl <- CostDistEstCbl[(length(PointAcc$ID)+1):length(CostDistEstCbl)[1]]
CostDistEstCbl <- matrix(CostDistEstCbl,ncol = length(PointAcc$ID) )
#Attribute a least cost point access to each points
PointTree <- ptsWIPmax %>% filter(type != "Access" ) %>%
mutate(ptAccCbl = max.col(- CostDistEstCbl,ties.method = "first")) %>%
mutate(EstCostCbl = CostDistEstCbl)
if (winching == "2") {
CondSurfGrpl <- 1/CostRasterMeanGrpl
#Compute Cost between points and Access points in grpl exploitation
CostDistEstGrpl <- adjtopolcp(costSurface = CondSurfGrpl,
topography = DTMmean ,
pts = ptsWIPmax %>%
as_Spatial(),
slopeRdCond = SlopeCondGrpl,
paths = FALSE) [,1:length(PointAcc$ID)]
CostDistEstGrpl <- CostDistEstGrpl[(length(PointAcc$ID)+1):length(CostDistEstGrpl)[1]]
CostDistEstGrpl <- matrix(CostDistEstGrpl,ncol = length(PointAcc$ID) )
#Attribute a least cost point access to each points
PointTree <- PointTree %>%
mutate(ptAccGpl = max.col(-matrix(CostDistEstGrpl,ncol = length(PointAcc$ID) ),ties.method = "first")) %>%
mutate(EstCostGrpl = CostDistEstGrpl)
#Prioritize grpl exploitation if possible
CostDistEstGrpl[CostDistEstGrpl != Inf] <- 0
CostDistEstGrpl[CostDistEstGrpl == Inf] <- 1
for (j in 1:length(CostDistEstGrpl)[1]) {
PointTree[j,"TypeAcc"] <- as.character(prod(CostDistEstGrpl[j,]))
}
PointTree$TypeAcc[PointTree$TypeAcc == "0"] <- "Grpl"
PointTree$TypeAcc[PointTree$TypeAcc == "1"] <- "Cbl"
PointTree$ptsAcc[PointTree$TypeAcc == "Grpl"] <- PointTree$ptAccGpl[PointTree$TypeAcc == "Grpl"]
PointTree$ptsAcc[PointTree$TypeAcc != "Grpl"] <- PointTree$ptAccCbl[PointTree$TypeAcc != "Grpl"]
PointTree$EstCost[PointTree$TypeAcc == "Grpl"] <- PointTree$EstCostGrpl[PointTree$TypeAcc == "Grpl"]
PointTree$EstCost[PointTree$TypeAcc != "Grpl"] <- PointTree$EstCostCbl[PointTree$TypeAcc != "Grpl"]
PointTree <- PointTree %>% arrange(desc(TypeAcc),EstCost)
if (PointTree$TypeAcc[1] == "Grpl" & !Crown2FoT) {
TmpPtsWIP <- ptsGrpl %>%
filter(IDpts == PointTree$IDpts[1]) %>%
st_union() %>%
st_cast("POINT", warn = FALSE) %>%
st_as_sf() %>%
mutate(type = "Overlay") %>%
mutate(ptsAcc = PointTree$ptsAcc[1]) %>%
mutate(IDpts = PointTree$IDpts[1]) %>%
mutate(origins = PointTree$origins[1])%>%
mutate(n.overlaps = PointTree$n.overlaps[1])
TmpTypeAcc <- "Grpl"
#Select adjacent grpl graph
SlopeCondRd <- SlopeCondGrpl
}else{
if (PointTree$TypeAcc[1] == "Grpl" & Crown2FoT) {
#Reconstruct access points + selected tree in grpl exploitation
TmpPtsWIP <- ptsGrpl %>%
filter(IDpts == PointTree$IDpts[1]) %>%
st_union() %>%
st_cast("POINT", warn = FALSE) %>%
st_as_sf() %>%
mutate(type = "Overlay") %>%
mutate(ptsAcc = PointTree$ptsAcc[1]) %>%
mutate(IDpts = PointTree$IDpts[1]) %>%
mutate(origins = PointTree$origins[1])%>%
mutate(n.overlaps = PointTree$n.overlaps[1])
TmpTypeAcc <- "Grpl"
#Select adjacent grpl graph
SlopeCondRd <- SlopeCondGrpl
}else{
if (!Crown2FoT) {
stoplog <- TRUE
ptsWIP <- ptsWIP %>% filter(n.overlaps < max(ptsWIPmax$n.overlaps,na.rm = TRUE))
}else{
#if the selected point is not a grpl accessible point BUT not all grpl accessible point are done
#Shift to cbl exploitation
Grpl2CblFlag <- TRUE
#Reconstruct access points + selected tree in cbl exploitation
TmpPtsWIP <- ptsCbl %>%
filter(IDpts == PointTree$IDpts[1]) %>%
st_union() %>%
st_cast("POINT", warn = FALSE) %>%
st_as_sf() %>%
mutate(type = "Overlay") %>%
mutate(ptsAcc = PointTree$ptsAcc[1]) %>%
mutate(IDpts = PointTree$IDpts[1]) %>%
mutate(origins = PointTree$origins[1])%>%
mutate(n.overlaps = PointTree$n.overlaps[1])
#Select adjacent cbl graph
SlopeCondRd <- SlopeCond
TmpTypeAcc <- "Cbl"
}
}
}
}else{
#Reconstruct access points + selected tree in cbl exploitation
TmpPtsWIP <- ptsCbl %>%
filter(IDpts == PointTree$IDpts[1]) %>%
st_union() %>%
st_cast("POINT", warn = FALSE) %>%
st_as_sf() %>%
mutate(type = "Overlay") %>%
mutate(ptsAcc = PointTree$ptsAcc[1]) %>%
mutate(IDpts = PointTree$IDpts[1]) %>%
mutate(origins = PointTree$origins[1]) %>%
mutate(n.overlaps = PointTree$n.overlaps[1])
#Select adjacent cbl graph
SlopeCondRd <- SlopeCond
TmpTypeAcc <- "Cbl"
}
if (!stoplog) {
#filter WIP points in accessible scd trail area
# TmpPtsWIP <- st_set_crs(TmpPtsWIP,st_crs(ptsCbl)) # set crs from ptsCbl
TmpPtsWIP <- TmpPtsWIP %>%
filter(st_intersects(st_geometry(TmpPtsWIP),st_geometry(AccessPolygons %>% st_union()),sparse = FALSE))
#Reconstruct access points + selected points
TmpPtsWIP <- rbind( PointAcc %>%
st_union() %>%
st_cast("POINT", warn = FALSE)%>%
st_as_sf() %>%
mutate(type = "Access") %>%
mutate(ptsAcc = NA ) %>%
mutate(IDpts = NA) %>%
mutate(origins = NA)%>%
mutate(n.overlaps = NA),TmpPtsWIP)
#Compute Cost between all points and Access points
CostDistEstWIP <- adjtopolcp(costSurface = CondSurf,topography = DTMmean , pts = TmpPtsWIP %>% as_Spatial(),
slopeRdCond = SlopeCondRd,paths = FALSE)[,1]
CostDistEstWIP <- CostDistEstWIP[(length(PointAcc$ID)+1):length(CostDistEstWIP)[1]]
CostDistEstWIP <- matrix(CostDistEstWIP, ncol = length(PointAcc$ID))
PointTreeWIP <- TmpPtsWIP %>%
filter(type == "Overlay") %>%
mutate(EstCost = CostDistEstWIP) %>%
arrange(EstCost)
TmpPtsWIP <- rbind(TmpPtsWIP %>% filter(type == "Access") %>% mutate(EstCost = NA),PointTreeWIP[1,])
TmpPathWIP <- adjtopolcp(costSurface = CondSurf,topography = DTMmean , pts = TmpPtsWIP %>% as_Spatial(),
slopeRdCond = SlopeCondRd,paths = FALSE)
TmpPathWIPCost <- TmpPathWIP[1:length(PointAcc$ID),length(PointAcc$ID)+1]
LCPathWIP <- max.col(t(-TmpPathWIPCost))
TmpPtsWIP <- rbind(TmpPtsWIP[LCPathWIP,],PointTreeWIP[1,])
TmpPathWIP <- adjtopolcp(costSurface = CondSurf,topography = DTMmean , pts = TmpPtsWIP %>% as_Spatial(),
slopeRdCond = SlopeCondRd,paths = TRUE)
if (TmpPathWIP[[1]][2,1] != 0) {
if (TmpTypeAcc == "Grpl") {
CostRasterMean <- raster::rasterize(x = TmpPathWIP[[2]] ,
y = CostRasterMean ,
field = CostMatrix[[2]][[7]]$CostValue,update = TRUE)
CostRasterMeanGrpl <- raster::rasterize(x = TmpPathWIP[[2]] ,
y = CostRasterMeanGrpl ,
field = CostMatrix[[2]][[7]]$CostValue,update = TRUE)
}else{
CostRasterMean <- raster::rasterize(x = TmpPathWIP[[2]] ,
y = CostRasterMean ,
field = CostMatrix[[2]][[7]]$CostValue,update = TRUE)
}
}
pathLines[[k]] <- TmpPathWIP[[2]]
pathLines[[k]]@lines[[1]]@ID <- paste("Path",
"A",
LCPathWIP,
"NTree",
length(PointTreeWIP$origins[[1]]),
"T",
paste(as.character(unlist(PointTreeWIP$origins[[1]])),
collapse='-'),
sep = ".")
if (verbose) {
print(paste0("LoggedTrees : ",PointTreeWIP$origins[[1]]))
}
Lines[[l]] <- list("LineID" = k,"LoggedTrees" = PointTreeWIP$origins[[1]],"Crownpts" = !Crown2FoT,"TypeExpl" = TmpTypeAcc,"IdMachineZone" = ID_Access)
k <- k +1
l <- l+1
pathLinesWIP[[ki]] <- TmpPathWIP[[2]]
pathLinesWIP[[ki]]@lines[[1]]@ID <- paste("Path",
"A",
LCPathWIP,
"NTree",
length(PointTreeWIP$origins[[1]]),
"T",
paste(as.character(unlist(PointTreeWIP$origins[[1]])),
collapse='-'),
sep = ".")
ki <- ki +1
pathsWIP <- do.call(rbind, pathLinesWIP)
pathsWIP <- pathsWIP %>% st_as_sf() %>% st_make_valid() %>% filter(!st_is_empty(pathsWIP %>%
st_as_sf()))
if(dim(pathsWIP)[1]>0){
pathsWIP <- pathsWIP$geometry %>% as_Spatial()
if ( length(pathsWIP)==1) {
pathsWIP <- pathsWIP %>% st_as_sf() %>%
st_buffer(dist = advancedloggingparameters$ScndTrailWidth/2) %>% st_make_valid() %>%
st_union()
}else{
pathsWIP <- smoothtrails(paths = pathsWIP ,
plotmask = plotmask,
verbose = FALSE,
advancedloggingparameters = advancedloggingparameters)$SmoothedTrails %>%
st_union()
}
}else{
pathsWIP <- pathsWIP %>%
st_union()
}
###################
}
}
if (!stoplog) {
TreePts$Logged<- FALSE
for (j in 1:dim(TreePts)[1]) {
TreePts$Logged[j] <- any(PointTreeWIP$origins[[1]] %in% TreePts$idTree[j])
}
TreePts <- TreePts %>%
filter(Logged == FALSE)%>%
dplyr::select(-Logged)
if (dim(TreePts)[1]> 0) {
if (winching == "2") {
ptsGrpl <- TreePts %>% #def Grpl point
st_buffer(dist = advancedloggingparameters$GrappleLength) %>%
st_snap_to_grid(size = .2) %>% # avoid GEOS error (st-intersection issue)
#st_set_precision(1) %>%
st_temporaryintersection(topography = topography,
plotmask = plotmask,
advancedloggingparameters = advancedloggingparameters) %>%
st_make_valid() %>%
mutate(type = "InterTr") %>%
dplyr::select(-ID)
for (OriginI in 1:length(ptsGrpl$origins)) {
for (OriginJ in 1:length(ptsGrpl$origins[[OriginI]])) {
IndexPts <- ptsGrpl$origins[[OriginI]][OriginJ]
ptsGrpl$origins[[OriginI]][OriginJ] <- TreePts$idTree[IndexPts]
}
}
ptsGrpl$isEmpty <- FALSE
for (h in 1:dim(ptsGrpl)[1]) {
if (ptsGrpl[h,] %>% st_intersects(AccessMainTrails %>% filter(ID == ID_Access),sparse = FALSE) == FALSE) {
ptsGrpl$isEmpty[h] <- TRUE
}else{
suppressWarnings(st_geometry(ptsGrpl[h,]) <- st_geometry(ptsGrpl[h,] %>% st_intersection(AccessMainTrails %>% filter(ID == ID_Access))))
}
}
#Filter polygons which intersect accessible area to second trails
ptsGrpl<- st_set_crs(ptsGrpl,st_crs(AccessPolygons)) # set crs from AccessPolygons
ptsGrpl <- ptsGrpl %>% filter(isEmpty == FALSE) %>% dplyr::select(-isEmpty) %>%
mutate(IDpts = paste0("I.", row_number()))
ptsWIP <- ptsGrpl %>% #def Grpl point as WIP point
st_set_agr("constant") %>%
st_centroid()
ptsCbl <- TreePts %>% #def cbl polygons
st_buffer(dist = advancedloggingparameters$CableLength) %>%
st_snap_to_grid(size = 1) %>%# avoid GEOS error (st-intersection issue)
st_set_precision(1) %>%
st_temporaryintersection(topography = topography,
plotmask = plotmask,
advancedloggingparameters = advancedloggingparameters) %>%
st_make_valid() %>%
mutate(type = "Inter")%>%
dplyr::select(-ID)
for (OriginI in 1:length(ptsCbl$origins)) {
for (OriginJ in 1:length(ptsCbl$origins[[OriginI]])) {
IndexPts <- ptsCbl$origins[[OriginI]][OriginJ]
ptsCbl$origins[[OriginI]][OriginJ] <- TreePts$idTree[IndexPts]
}
}
ptsCbl$isEmpty <- FALSE
for (h in 1:dim(ptsCbl)[1]) {
if (ptsCbl[h,] %>% st_intersects(AccessMainTrails %>% filter(ID == ID_Access),sparse = FALSE) == FALSE) {
ptsCbl$isEmpty[h] <- TRUE
}else{
suppressWarnings(st_geometry(ptsCbl[h,]) <- st_geometry(ptsCbl[h,] %>% st_intersection(AccessMainTrails %>% filter(ID == ID_Access))))
}
}
ptsCbl <- st_set_crs(ptsCbl,st_crs(AccessPolygons)) #set crs from AccessPolygons
ptsCbl <- ptsCbl %>% filter(isEmpty == FALSE) %>% dplyr::select(-isEmpty) %>%
mutate(IDpts = paste0("I.",row_number())) #Filter polygons which intersect accessible area to second trails
ptsWIPCbl <- ptsCbl %>%#Convert polygons to centroid
st_set_agr("constant") %>%
st_centroid()
ptsWIP <- ptsWIP %>%
arrange(desc(n.overlaps))
#Select adjacent grpl graph
SlopeCondRd <- SlopeCondGrpl
}else{
ptsCbl <- TreePts %>% #def cbl point
st_buffer(dist = advancedloggingparameters$CableLength) %>%
st_snap_to_grid(size = 1) %>% # avoid GEOS error (st-intersection issue)
st_set_precision(1) %>%
st_temporaryintersection(topography = topography,
plotmask = plotmask,
advancedloggingparameters = advancedloggingparameters) %>%
st_make_valid() %>%
mutate(IDpts = paste0("I.",row_number())) %>%
mutate(type = "InterTr") %>% dplyr::select(-ID)
ptsCbl <- st_set_crs(ptsCbl,st_crs(AccessPolygons)) #set crs from AccessPolygons
for (OriginI in 1:length(ptsCbl$origins)) {
for (OriginJ in 1:length(ptsCbl$origins[[OriginI]])) {
IndexPts <- ptsCbl$origins[[OriginI]][OriginJ]
ptsCbl$origins[[OriginI]][OriginJ] <- TreePts$idTree[IndexPts]
}
}
ptsCbl$isEmpty <- FALSE
for (h in 1:dim(ptsCbl)[1]) {
if (ptsCbl[h,] %>% st_intersects(AccessMainTrails %>% filter(ID == ID_Access),sparse = FALSE) == FALSE) {
ptsCbl$isEmpty[h] <- TRUE
}else{
suppressWarnings(st_geometry(ptsCbl[h,]) <- st_geometry(ptsCbl[h,] %>% st_intersection(AccessMainTrails %>% filter(ID == ID_Access))))
}
}
ptsWIP <- ptsCbl %>% filter(isEmpty == FALSE) %>% dplyr::select(-isEmpty) %>%#def cbl point as WIP point
st_set_agr("constant") %>%
st_centroid()
ptsWIP <- ptsWIP %>% #filter cbl intersection centroid point out plot
filter(st_intersects(st_geometry(ptsWIP),
st_geometry(plotmask %>%
st_as_sf()),
sparse = FALSE)) %>%
arrange(desc(n.overlaps))
#Select adjacent cbl graph
SlopeCondRd <- SlopeCond
}
}
if (!Crown2FoT & winching == "2") {
CrownPts$Logged<- FALSE
for (j in 1:dim(CrownPts)[1]) {
CrownPts$Logged[j] <- any(PointTreeWIP$origins[[1]] %in% CrownPts$idTree[j])
}
CrownPts <- CrownPts %>%
filter(Logged == FALSE)%>%
dplyr::select(-Logged)
if (dim(CrownPts)[1]> 0) {
ptsGrpl <- CrownPts %>% #def Grpl point
st_buffer(dist = advancedloggingparameters$GrappleLength) %>%
st_snap_to_grid(size = .2) %>% # avoid GEOS error (st-intersection issue)
#st_set_precision(1) %>%
st_temporaryintersection(topography = topography,
plotmask = plotmask,
advancedloggingparameters = advancedloggingparameters) %>%
st_make_valid() %>%
mutate(type = "InterCr") %>%
dplyr::select(-ID)
for (OriginI in 1:length(ptsGrpl$origins)) {
for (OriginJ in 1:length(ptsGrpl$origins[[OriginI]])) {
IndexPts <- ptsGrpl$origins[[OriginI]][OriginJ]
ptsGrpl$origins[[OriginI]][OriginJ] <- CrownPts$idTree[IndexPts]
}
}
ptsGrpl$isEmpty <- FALSE
for (h in 1:dim(ptsGrpl)[1]) {
if (ptsGrpl[h,] %>% st_intersects(AccessMainTrails %>% filter(ID == ID_Access),sparse = FALSE) == FALSE) {
ptsGrpl$isEmpty[h] <- TRUE
}else{
suppressWarnings(st_geometry(ptsGrpl[h,]) <- st_geometry(ptsGrpl[h,] %>% st_intersection(AccessMainTrails %>% filter(ID == ID_Access))))
}
}
#Filter polygons which intersect accessible area to second trails
ptsGrpl<- st_set_crs(ptsGrpl,st_crs(AccessPolygons)) # set crs from AccessPolygons
ptsGrpl <- ptsGrpl %>% filter(isEmpty == FALSE) %>% dplyr::select(-isEmpty) %>%
mutate(IDpts = paste0("I.", row_number()))
ptsWIP <- ptsGrpl %>% #def Grpl point as WIP point
st_set_agr("constant") %>%
st_centroid()
}
RemainTree <- dim(TreePts)[1]
}
}
RemainTree <- dim(TreePts)[1]
}else{
Crown2FoT <- TRUE
ptsGrpl <- TreePts %>% #def Grpl point
st_buffer(dist = advancedloggingparameters$GrappleLength) %>%
st_snap_to_grid(size = .2) %>% # avoid GEOS error (st-intersection issue)
#st_set_precision(1) %>%
st_temporaryintersection(topography = topography,
plotmask = plotmask,
advancedloggingparameters = advancedloggingparameters) %>%
st_make_valid() %>%
mutate(type = "Inter") %>%
dplyr::select(-ID)
for (OriginI in 1:length(ptsGrpl$origins)) {
for (OriginJ in 1:length(ptsGrpl$origins[[OriginI]])) {
IndexPts <- ptsGrpl$origins[[OriginI]][OriginJ]
ptsGrpl$origins[[OriginI]][OriginJ] <- TreePts$idTree[IndexPts]
}
}
ptsGrpl$isEmpty <- FALSE
for (h in 1:dim(ptsGrpl)[1]) {
if (ptsGrpl[h,] %>% st_intersects(AccessMainTrails %>% filter(ID == ID_Access),sparse = FALSE) == FALSE) {
ptsGrpl$isEmpty[h] <- TRUE
}else{
suppressWarnings(st_geometry(ptsGrpl[h,]) <- st_geometry(ptsGrpl[h,] %>% st_intersection(AccessMainTrails %>% filter(ID == ID_Access))))
}
}
#Filter polygons which intersect accessible area to second trails
ptsGrpl<- st_set_crs(ptsGrpl,st_crs(AccessPolygons)) # set crs from AccessPolygons
ptsGrpl <- ptsGrpl %>% filter(isEmpty == FALSE) %>% dplyr::select(-isEmpty) %>%
mutate(IDpts = paste0("I.", row_number()))
ptsWIP <- ptsGrpl %>% #def Grpl point as WIP point
st_set_agr("constant") %>%
st_centroid()
ptsCbl <- TreePts %>% #def cbl polygons
st_buffer(dist = advancedloggingparameters$CableLength) %>%
st_snap_to_grid(size = 1) %>%# avoid GEOS error (st-intersection issue)
st_set_precision(1) %>%
st_temporaryintersection(topography = topography,
plotmask = plotmask,
advancedloggingparameters = advancedloggingparameters) %>%
st_make_valid() %>%
mutate(type = "InterTr")%>%
dplyr::select(-ID)
for (OriginI in 1:length(ptsCbl$origins)) {
for (OriginJ in 1:length(ptsCbl$origins[[OriginI]])) {
IndexPts <- ptsCbl$origins[[OriginI]][OriginJ]
ptsCbl$origins[[OriginI]][OriginJ] <- TreePts$idTree[IndexPts]
}
}
ptsCbl$isEmpty <- FALSE
for (h in 1:dim(ptsCbl)[1]) {
if (ptsCbl[h,] %>% st_intersects(AccessMainTrails %>% filter(ID == ID_Access),sparse = FALSE) == FALSE) {
ptsCbl$isEmpty[h] <- TRUE
}else{
suppressWarnings(st_geometry(ptsCbl[h,]) <- st_geometry(ptsCbl[h,] %>% st_intersection(AccessMainTrails %>% filter(ID == ID_Access))))
}
}
ptsCbl <- st_set_crs(ptsCbl,st_crs(AccessPolygons)) #set crs from AccessPolygons
ptsCbl <- ptsCbl %>% filter(isEmpty == FALSE) %>% dplyr::select(-isEmpty) %>%
mutate(IDpts = paste0("I.",row_number())) #Filter polygons which intersect accessible area to second trails
ptsWIPCbl <- ptsCbl %>%#Convert polygons to centroid
st_set_agr("constant") %>%
st_centroid()
ptsWIP <- ptsWIP %>%
arrange(desc(n.overlaps))
RemainTree <- dim(TreePts)[1]
}
}
if (RemainTree > 0L){
stop("Failed to compute 2nd trails")
}
###############END LOOP################"
}
}
paths <- do.call(rbind, pathLines)
MainTrailsAccess <- AccessPointAll %>%
st_set_crs(st_crs(topography))
inventory <- treeselectionoutputs$inventory
lines <- do.call(rbind, Lines)
paths <- paths %>% st_as_sf() %>% st_make_valid() %>% filter(!st_is_empty(paths %>% st_as_sf()))
if (dim(paths)[1]>0) {
paths <- paths$geometry %>% as_Spatial()
if ( length(paths)==1) {
SmoothedTrails <- paths %>% st_as_sf() %>%
st_buffer(dist = advancedloggingparameters$ScndTrailWidth/2) %>% st_make_valid() %>%
st_union()%>% st_set_crs(st_crs(topography))
TrailsDensity <- (SmoothedTrails %>% st_intersection(plotmask %>% st_as_sf()) %>% st_area / advancedloggingparameters$ScndTrailWidth)/(plotmask %>% st_as_sf() %>% st_area() /10000)
}else{
secondtrails <- smoothtrails(paths,
plotmask,
verbose = verbose,
advancedloggingparameters = advancedloggingparameters)
SmoothedTrails <- secondtrails$SmoothedTrails %>% st_set_crs(st_crs(topography))
TrailsDensity <- secondtrails$TrailsDensity
}
#
#
# # Records the dead trees
DeadTrees <- suppressWarnings(sf::st_intersection(
sf::st_make_valid(st_set_crs(st_as_sf(inventory, coords = c("Xutm", "Yutm")), st_crs(topography))),
sf::st_make_valid(st_as_sf(SmoothedTrails) %>% st_union()) # "make valid" to avoid self-intersection
)) %>%
add_column(DeadTrees = "1") %>%
dplyr::select(idTree, DeadTrees) %>% st_drop_geometry()
DeadTrees <- unique(DeadTrees)
inventory <- inventory %>%
left_join(DeadTrees, by = "idTree") %>%
mutate(DeathCause = ifelse(is.na(DeathCause) & Selected != "1" & DeadTrees == "1",
"2ndtrail", DeathCause)) %>% # Damage trees
dplyr::select(-DeadTrees)
}else{
paths <- NULL
SmoothedTrails <- MainTrailsAccess %>% st_union() %>%
st_buffer(dist = advancedloggingparameters$MaxMainTrailWidth/2) %>% st_set_crs(st_crs(topography))
TrailsDensity <- 0
DeadTrees <- suppressWarnings(sf::st_intersection(
sf::st_make_valid(st_set_crs(st_as_sf(inventory, coords = c("Xutm", "Yutm")), st_crs(topography))),
sf::st_make_valid(st_as_sf(SmoothedTrails) %>% st_union()) # "make valid" to avoid self-intersection
)) %>%
add_column(DeadTrees = "1") %>%
dplyr::select(idTree, DeadTrees) %>% st_drop_geometry()
DeadTrees <- unique(DeadTrees)
inventory <- inventory %>%
left_join(DeadTrees, by = "idTree") %>%
mutate(DeathCause = ifelse(is.na(DeathCause) & Selected != "1" & DeadTrees == "1",
"2ndtrail", DeathCause)) %>% # Damage trees
dplyr::select(-DeadTrees)
}
# WinchingMachine info in the inventory
TrailsIdentity_df <- as.data.frame(lines) %>%
unnest(cols = c(LineID, LoggedTrees, Crownpts, TypeExpl, IdMachineZone)) # unnesting flattens it back out into regular columns
TrailsIdentity_df <- TrailsIdentity_df %>%
select(LoggedTrees, TypeExpl, IdMachineZone, Crownpts) %>%
rename(idTree = LoggedTrees) %>%
rename(WinchingMachineAdjust = TypeExpl) %>%
rename(IdMachineZoneAdjust = IdMachineZone) %>%
rename(CollectedCrown = Crownpts) %>%
unique()
inventory <- inventory %>%
left_join(TrailsIdentity_df, by = "idTree")
# OUTPUTS
if(nrow(inventory) != nrow(inventory0))
stop("The number of rows between the input inventory and the output inventory
of the function secondtrailsadjusted() is not the same.The function must be corrected.")
if (WinchingInit == "2") {
secondtrails <- list("inventory" = inventory,
"SmoothedTrails" = SmoothedTrails,
"TrailsDensity" = TrailsDensity,
"TrailsIdentity" = lines, # "LineID","LoggedTrees", "TypeExpl"
"MainTrailsAccess" = MainTrailsAccess,
"RawSecondTrails" = paths,
"CostRasterAgg" = list("CostRasterMean" = CostRasterMean,"CostRasterMeanGrpl" = CostRasterMeanGrpl))
}else{
secondtrails <- list("inventory" = inventory,
"SmoothedTrails" = SmoothedTrails,
"TrailsDensity" = TrailsDensity,
"TrailsIdentity" = lines, # "LineID","LoggedTrees", "TypeExpl"
"MainTrailsAccess" = MainTrailsAccess,
"RawSecondTrails" = paths,
"CostRasterAgg" = list("CostRasterMean" = CostRasterMean,"CostRasterMeanGrpl" = NULL))
}
return(secondtrails)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.