source("funcs/functions.R", local = TRUE)
options(shiny.maxRequestSize=5000*1024^2)
shinyServer(function(input, output, session) {
# disable download buttons
shinyjs::disable("dlDbOccs")
shinyjs::disable("dlProcOccs")
# shinyjs::disable("dlEnvs")
shinyjs::disable("dlMskEnvs")
shinyjs::disable("dlPart")
shinyjs::disable("downloadEvalcsv")
shinyjs::disable("downloadEvalPlots")
shinyjs::disable("dlPred")
shinyjs::disable("dlProj")
shinyjs::disable("dlRMD")
# initialize module parameters list
rvs <- reactiveValues(logs = logInit(), comp1='', comp2='', comp3='', comp4.shp='', comp4.buf=0,
comp5='', comp6='', comp7.type='', comp7='', comp8.pj='', comp8.esim='')
# observeEvent(input$load, {
# f <- read.csv('C:/Users/gepin/Desktop/maxnet_files/Canis lupus_partitioned_occs.csv')
# rvs$occs <- f %>% dplyr::filter(name != 'background')
# rvs$occs$pop <- unlist(apply(rvs$occs, 1, popUpContent))
# rvs$occsGrp <- rvs$occs$group
# rvs$bgPts <- f %>% dplyr::filter(name == 'background')
# rvs$bgGrp <- rvs$bgPts$group
# rvs$bgShp <- rgdal::readOGR('C:/Users/gepin/Desktop/maxnet_files/box.shp')
# rvs$bgPts <- rvs$bgPts %>% dplyr::select(longitude, latitude)
# rvs$envs <- raster::stack(list.files('C:/Users/gepin/Desktop/maxnet_files/bio_10m_bil', 'bil$', full.names=TRUE))
# rvs$bgMsk <- raster::stack(list.files('C:/Users/gepin/Desktop/maxnet_files/mskEnvs', 'tif$', full.names = TRUE))
# print('HACKING DONE')
# })
# for RMD
curWD <- getwd()
# logs <- reactiveValues(entries=logInit())
gtext <- reactiveValues()
# load modules
for (f in list.files('./modules')) {
source(file.path('modules', f), local=TRUE)
}
# initialize log window
output$log <- renderUI({tags$div(id='logHeader', tags$div(id='logContent',
HTML(paste0(rvs$logs, "<br>", collapse = ""))))})
######################## #
### GUIDANCE TEXT ####
######################## #
# UI for component guidance text
output$gtext_comp <- renderUI({
shiny::includeMarkdown(file.path('Rmd', gtext$cur_comp))
})
# UI for module guidance text
output$gtext_mod <- renderUI({
shiny::includeMarkdown(file.path('Rmd', gtext$cur_mod))
})
# guidance text and tab behavior
observe({
if (input$tabs == 1) {
updateTabsetPanel(session, 'main', selected = 'Map')
gtext$cur_comp <- 'gtext_comp1.Rmd'
if (input$occSel == 'db') gtext$cur_mod <- "gtext_comp1_dbOccs.Rmd"
if (input$occSel == 'user') gtext$cur_mod <- "gtext_comp1_userOccs.Rmd"
}
if (input$tabs == 2) {
updateTabsetPanel(session, 'main', selected = 'Map')
gtext$cur_comp <- "gtext_comp2.Rmd"
# if Module: Select Localities, populate guidance text and select legend
if (input$procOccSel == 'selOccs') gtext$cur_mod <- "gtext_comp2_selectOccsOnMap.Rmd"
if (input$procOccSel == 'remID') gtext$cur_mod <- "gtext_comp2_removeByID.Rmd"
if (input$procOccSel == 'spthin') gtext$cur_mod <- "gtext_comp2_spatialThin.Rmd"
}
if (input$tabs == 3) {
updateTabsetPanel(session, 'main', selected = 'Results')
gtext$cur_comp <- "gtext_comp3.Rmd"
if (input$envDataSel == 'wcbc') gtext$cur_mod <- "gtext_comp3_worldclim.Rmd"
if (input$envDataSel == 'user') gtext$cur_mod <- "gtext_comp3_userEnvs.Rmd"
}
if (input$tabs == 4) {
updateTabsetPanel(session, 'main', selected = 'Map')
gtext$cur_comp <- "gtext_comp4.Rmd"
if (input$envProcSel == 'bgSel') gtext$cur_mod <- "gtext_comp4_backg.Rmd"
if (input$envProcSel == 'bgUser') gtext$cur_mod <- "gtext_comp4_userBg.Rmd"
}
if (input$tabs == 5) {
updateTabsetPanel(session, 'main', selected = 'Map')
gtext$cur_comp <- "gtext_comp5.Rmd"
if (input$partSel == 'sp') gtext$cur_mod <- "gtext_comp5_spatial.Rmd"
if (input$partSel == 'nsp') gtext$cur_mod <- "gtext_comp5_nonspatial.Rmd"
}
if (input$tabs == 6) {
updateTabsetPanel(session, 'main', selected = 'Results')
gtext$cur_comp <- "gtext_comp6.Rmd"
if (input$enmSel == 'BIOCLIM') gtext$cur_mod <- "gtext_comp6_bioclim.Rmd"
if (input$enmSel == 'Maxent') gtext$cur_mod <- "gtext_comp6_maxent.Rmd"
}
if (input$tabs == 7) {
gtext$cur_comp <- "gtext_comp7.Rmd"
if (input$visSel == 'map') {
updateTabsetPanel(session, 'main', selected = 'Map')
gtext$cur_mod <- "gtext_comp7_map.Rmd"
} else {
updateTabsetPanel(session, 'main', selected = 'Results')
if (input$visSel == 'bcPlots') gtext$cur_mod <- "gtext_comp7_bcPlots.Rmd"
if (input$visSel == 'mxEval') gtext$cur_mod <- "gtext_comp7_mxEvalPlots.Rmd"
if (input$visSel == 'response') gtext$cur_mod <- "gtext_comp7_respCurves.Rmd"
}
}
if (input$tabs == 8) {
updateTabsetPanel(session, 'main', selected = 'Map')
gtext$cur_comp <- "gtext_comp8.Rmd"
if (input$projSel == 'projArea') gtext$cur_mod <- "gtext_comp8_pjArea.Rmd"
if (input$projSel == 'projTime') gtext$cur_mod <- "gtext_comp8_pjTime.Rmd"
if (input$projSel == 'mess') gtext$cur_mod <- "gtext_comp8_mess.Rmd"
}
})
######################## #
### MAPPING ####
######################## #
# create map
m <- leaflet() %>% setView(0, 0, zoom = 2) %>% addProviderTiles('Esri.WorldTopoMap')
output$map <- renderLeaflet(m)
# create map proxy to make further changes to existing map
map <- leafletProxy("map")
# initialize provider tile option
observe({map %>% addProviderTiles(input$bmap)})
# initialize draw toolbar for c2_selectOccs and c8
observe({
if ((input$tabs == 2 & input$procOccSel == 'selOccs') | input$tabs == 8) {
map %>% leaflet.extras::addDrawToolbar(targetGroup='draw', polylineOptions = FALSE,
rectangleOptions = FALSE, circleOptions = FALSE,
markerOptions = FALSE, circleMarkerOptions = FALSE,
editOptions = leaflet.extras::editToolbarOptions())
} else {
map %>% leaflet.extras::removeDrawToolbar(clearFeatures = TRUE)
}
})
observeEvent(input$map_draw_new_feature, {
coords <- unlist(input$map_draw_new_feature$geometry$coordinates)
xy <- matrix(c(coords[c(TRUE,FALSE)], coords[c(FALSE,TRUE)]), ncol=2)
id <- input$map_draw_new_feature$properties$`_leaflet_id`
if (input$tabs == 2 & input$procOccSel == 'selOccs') {
rvs$polySelXY <- xy
rvs$polySelID <- id
} else if (input$tabs == 8) {
rvs$polyPjXY <- xy
rvs$polyPjID <- id
}
})
########################################## #
### COMPONENT 1: OBTAIN OCCURRENCE DATA ####
########################################## #
# module Query Database
dbOccs <- callModule(queryDb_MOD, 'c1_queryDb', rvs)
spName <- reactive(rvs$spName)
observeEvent(input$goDbOccs, {
rvs$occs <- dbOccs()
rvs$occsPreProc <- rvs$occs
# record for RMD
rvs$comp1 <- 'db'
map %>%
clearMarkers() %>%
clearShapes() %>%
clearImages() %>%
map_plotLocs(rvs$occs) %>%
zoom2Occs(rvs$occs)
shinyjs::enable("dlDbOccs")
shinyjs::enable("dlRMD")
})
# module User Occurrence Data
userOccs <- callModule(userOccs_MOD, 'c1_userOccs', rvs)
observeEvent(input$goUserOccs, {
rvs$occs <- userOccs()
rvs$occsPreProc <- rvs$occs
# record for RMD
rvs$comp1 <- 'csv'
map %>%
clearMarkers() %>%
clearShapes() %>%
clearImages() %>%
map_plotLocs(rvs$occs) %>%
zoom2Occs(rvs$occs)
shinyjs::disable("dlDbOccs")
shinyjs::enable("dlRMD")
})
# TABLE
options <- list(autoWidth = TRUE, columnDefs = list(list(width = '40%', targets = 7)),
scrollX=TRUE, scrollY=400)
output$occTbl <- DT::renderDataTable({
req(rvs$occs)
occsDT <- rvs$occs %>% dplyr::mutate(longitude = round(as.numeric(longitude), digits = 2),
latitude = round(as.numeric(latitude), digits = 2))
occsDT %>% dplyr::select(name, occID, longitude:elevation)
}, rownames = FALSE)
# handle downloading of original GBIF records after cleaning
output$dlDbOccs <- downloadHandler(
filename = function() {paste0(formatSpName(spName()), '_original_', rvs$occDb, ".csv")},
content = function(file) {
write_csv_robust(rvs$occsOrig, file, row.names=FALSE)
}
)
########################################### #
### COMPONENT 2: PROCESS OCCURRENCE DATA ####
########################################### #
# module Remove Occurrences By ID
remByID <- callModule(removeByID_MOD, 'c2_removeByID', rvs)
observeEvent(input$goRemoveByID, {
rvs$occs <- remByID()
# record for RMD
rvs$comp2 <- c(rvs$comp2, 'rem')
map %>%
clearMarkers() %>%
map_plotLocs(rvs$occs) %>%
zoom2Occs(rvs$occs)
shinyjs::enable("dlProcOccs")
})
# module Select Occurrences on Map
selOccs <- callModule(selectOccs_MOD, 'c2_selOccs', rvs)
observeEvent(input$goSelectOccs, {
rvs$occs <- selOccs()
# record for RMD
rvs$comp2 <- c(rvs$comp2, 'sel')
map %>%
clearMarkers() %>%
map_plotLocs(rvs$occs) %>%
zoom2Occs(rvs$occs) %>%
drawToolbarRefresh()
shinyjs::enable("dlProcOccs")
})
# module Spatial Thin
thinOccs <- callModule(thinOccs_MOD, 'c2_thinOccs', rvs)
observeEvent(input$goThinOccs, {
occsPreThin <- rvs$occs
rvs$occs <- thinOccs()
# stop if no occurrence data
req(rvs$occs)
# record for RMD
rvs$comp2 <- c(rvs$comp2, 'thin')
# MAPPING - blue pts for remove, red pts for keep
map %>%
addCircleMarkers(data = occsPreThin, lat = ~latitude, lng = ~longitude,
radius = 5, color = 'red', fillColor = 'blue',
fillOpacity = 1, weight = 2, popup = ~pop,
group = 'comp2') %>%
addCircleMarkers(data = rvs$occs, lat = ~latitude, lng = ~longitude,
radius = 5, color = 'red', fillColor = 'red',
fillOpacity = 1, weight = 2, popup = ~pop,
group = 'comp2') %>%
addLegend("bottomright", colors = c('red', 'blue'),
title = "Occ Records", labels = c('retained', 'removed'),
opacity = 1, layerId = 'leg')
shinyjs::enable("dlProcOccs")
})
# handle download for thinned records csv
output$dlProcOccs <- downloadHandler(
filename = function() {ifelse(rvs$comp1 == 'csv',
"user_processed_occs.csv",
paste0(formatSpName(spName()), "_processed_occs.csv"))},
content = function(file) {
# thinned_rowNums <- as.numeric(thinOccs()$occID)
# origThinned <- rvs$occsOrig[thinned_rowNums,]
write_csv_robust(rvs$occs %>% dplyr::select(-pop), file, row.names = FALSE)
}
)
# Reset Occs button functionality
observeEvent(input$goResetOccs, {
rvs$occs <- rvs$occsPreProc
# reset for RMD
rvs$comp2 <- NULL
rvs %>% writeLog("Reset occurrences.")
map %>%
clearMarkers() %>%
map_plotLocs(rvs$occs) %>%
zoom2Occs(rvs$occs)
})
############################################# #
### COMPONENT 3: OBTAIN ENVIRONMENTAL DATA ####
############################################# #
# map center coordinates for 30 arcsec download
mapCntr <- reactive(mapCenter(input$map_bounds))
output$ctrLatLon <- renderText({
paste('Using map center', paste(mapCntr(), collapse=', '))
})
# module WorldClim Bioclims
wcBioclims <- callModule(wcBioclims_MOD, 'c3_wcBioclims', rvs, mapCntr)
observeEvent(input$goEnvData, {
# load into envs
rvs$envs <- wcBioclims()
# stop if no occurrence data
req(rvs$occs)
req(rvs$envs)
# record for RMD
rvs$comp3 <- 'bc'
# remove occurrences with NA values for variables
rvs$occs <- remEnvsValsNA(rvs)
# MAPPING - Plot the remaining occs after of removing NA
map %>%
clearMarkers() %>%
clearControls() %>%
map_plotLocs(rvs$occs) %>%
zoom2Occs(rvs$occs)
# switch to Results tab
updateTabsetPanel(session, 'main', selected = 'Results')
# enable download button
# shinyjs::enable("dlEnvs")
})
# module User-defined Environmental Predictors
userEnvs <- callModule(userEnvs_MOD, 'c3_userEnvs', rvs)
observeEvent(input$goUserEnvs, {
rvs$envs <- userEnvs()
# stop if no occurrence data
req(rvs$occs)
# record for RMD
rvs$comp3 <- 'user'
# remove occurrences with NA values for variables
rvs$occs <- remEnvsValsNA(rvs)
# make project to new time module unavailable for user envs
updateRadioButtons(session, "projSel",
choices = list("Project to New Extent" = 'projArea',
"Calculate Environmental Similarity" = 'mess'))
# MAPPING - Plot the remaining occs after of removing NA
map %>%
clearMarkers() %>%
map_plotLocs(rvs$occs) %>%
zoom2Occs(rvs$occs)
# switch to Results tab
updateTabsetPanel(session, 'main', selected = 'Results')
})
output$envsPrint <- renderPrint({
req(rvs$envs)
rvs$envs
# mins <- sapply(envs()@layers, function(x) x@data@min)
# maxs <- sapply(envs()@layers, function(x) x@data@max)
# names <- sapply(strsplit(names(envs()), '[.]'), function(x) x[-2])
# mins <- round(cellStats(envs(), stat = min), digits = 3)
# maxs <- round(cellStats(envs(), stat = max), digits = 3)
# DT::datatable(data.frame(name=names, min=mins, max=maxs),
# rownames = FALSE, options = list(pageLength = raster::nlayers(envs())))
})
############################################## #
### COMPONENT 4: PROCESS ENVIRONMENTAL DATA ####
############################################## #
# module Background Extent
bgExt <- callModule(bgExtent_MOD, 'c4_bgExtent', rvs)
bgShpXY <- reactive({
polys <- rvs$bgShp@polygons[[1]]@Polygons
if (length(polys) == 1) {
xy <- list(rvs$bgShp@polygons[[1]]@Polygons[[1]]@coords)
} else {
xy <- sapply(polys, function(x) x@coords)
}
return(xy)
})
observeEvent(input$goBgExt, {
rvs$bgShp <- bgExt()
# stop if no environmental variables
req(rvs$envs)
map %>% clearShapes()
for (shp in bgShpXY()) {
map %>%
addPolygons(lng=shp[,1], lat=shp[,2],
weight=4, color="gray", group='bgShp')
}
map %>%
fitBounds(rvs$bgShp@bbox[1], rvs$bgShp@bbox[2], rvs$bgShp@bbox[3], rvs$bgShp@bbox[4])
})
# module User-defined Background Extent
userBg <- callModule(userBgExtent_MOD, 'c4_userBgExtent', rvs)
observeEvent(input$goUserBg, {
rvs$bgShp <- userBg()
# stop if no environmental variables
req(rvs$envs)
req(rvs$bgShp)
coords <- rvs$bgShp@polygons[[1]]@Polygons[[1]]@coords
map %>% clearShapes()
for (shp in bgShpXY()) {
map %>%
addPolygons(lng=shp[,1], lat=shp[,2],
weight=4, color="gray", group='bgShp')
}
map %>%
fitBounds(rvs$bgShp@bbox[1], rvs$bgShp@bbox[2], rvs$bgShp@bbox[3], rvs$bgShp@bbox[4])
})
# module Background Mask and Sample Points
observeEvent(input$goBgMask, {
bgMskPts.call <- callModule(bgMskAndSamplePts_MOD, 'c4_bgMskAndSamplePts', rvs)
bgMskPts <- bgMskPts.call()
# stop if no background shape
req(rvs$bgShp)
rvs$bgMsk <- bgMskPts$msk
rvs$bgPts <- bgMskPts$pts
shinyjs::enable('dlMskEnvs')
})
# handle download for masked predictors, with file type as user choice
output$dlMskEnvs <- downloadHandler(
filename = function() {'mskEnvs.zip'},
content = function(file) {
tmpdir <- tempdir()
owd <- setwd(tmpdir)
on.exit(setwd(owd))
type <- input$bgMskFileType
nm <- names(rvs$bgMsk)
raster::writeRaster(rvs$bgMsk, file.path(tmpdir, 'msk'), bylayer = TRUE,
suffix = nm, format = type, overwrite = TRUE)
ext <- switch(type, raster = 'grd', ascii = 'asc', GTiff = 'tif')
fs <- paste0('msk_', nm, '.', ext)
if (ext == 'grd') {
fs <- c(fs, paste0('msk_', nm, '.gri'))
}
zip::zip(zipfile=file, files=fs)
if (file.exists(paste0(file, ".zip"))) {file.rename(paste0(file, ".zip"), file)}
},
contentType = "application/zip"
)
############################################# #
### COMPONENT 5: PARTITION OCCURRENCE DATA ####
############################################# #
# module Non-spatial Occurrence Partitions
partNsp.call <- callModule(partNsp_MOD, 'c5_partNsp', rvs)
observeEvent(input$goPartNsp, {
partNsp <- partNsp.call()
# stop if no background mask
req(rvs$bgMsk)
rvs$occsGrp <- partNsp[[1]]
rvs$bgGrp <- partNsp[[2]]
map %>% comp5_map(rvs$occs, rvs$occsGrp)
shinyjs::enable("dlPart")
})
# module Spatial Occurrence Partitions
partSp.call <- callModule(partSp_MOD, 'c5_partSp', rvs)
observeEvent(input$goPartSp, {
partSp <- partSp.call()
# stop if no background mask
req(rvs$bgMsk)
rvs$occsGrp <- partSp[[1]]
rvs$bgGrp <- partSp[[2]]
map %>% comp5_map(rvs$occs, rvs$occsGrp)
shinyjs::enable("dlPart")
})
# download for partitioned occurrence records csv
output$dlPart <- downloadHandler(
filename = function() paste0(spName(), "_partitioned_occs.csv"),
content = function(file) {
bg.bind <- data.frame(rep('background', nrow(rvs$bgPts)), rvs$bgPts)
names(bg.bind) <- c('name', 'longitude', 'latitude')
occs.bg.bind <-rbind(rvs$occs[,1:3], bg.bind)
all.bind <- cbind(occs.bg.bind, c(rvs$occsGrp, rvs$bgGrp))
names(all.bind)[4] <- "group"
write_csv_robust(all.bind, file, row.names = FALSE)
}
)
######################### #
### COMPONENT 6: MODEL ####
######################### #
# module Maxent
mod.maxent <- callModule(maxent_MOD, 'c6_maxent', rvs)
observeEvent(input$goMaxent, {
# stop if no occurrence partition group
req(rvs$occsGrp)
# get model evaluations
e <- mod.maxent()
# if e is NULL, let the c6_maxent module throw the proper error and stop
req(e)
rvs$comp6 <- 'maxent' # record the enm selected
rvs$mods <- e@models
rvs$modPreds <- e@predictions
rvs$modRes <- e@results
# x <- callModule(mapPreds_MOD, 'c7_mapPreds', rvs)
ncols <- ncol(rvs$modRes)
modRes.round <- cbind(rvs$modRes[,1:3], round(rvs$modRes[,4:ncols], digits=3))
nBinsCols <- ncols - 16
# render both full model and partition avg datatable, and individual partition datatable
output$evalTbls <- renderUI({
tabsetPanel(
tabPanel("Evaluation",
tagList(
br(),
div("Full model and partition bin average evaluation statistics", id="stepText"), br(), br(),
DT::dataTableOutput('evalTbl'), br(),
div("Individual partition bin evaluation statistics", id="stepText"), br(), br(),
DT::dataTableOutput('evalTblBins')
)),
tabPanel("Lambdas",
br(),
div("Maxent Lambdas File", id="stepText"), br(), br(),
verbatimTextOutput("lambdas")
)
)
})
output$evalTbl <- DT::renderDataTable(modRes.round[,1:16],
options = list(scrollX = TRUE,
sDom = '<"top">rtp<"bottom">'))
output$evalTblBins <- DT::renderDataTable(modRes.round[,17:(nBinsCols+16)],
options = list(scrollX = TRUE,
sDom = '<"top">rtp<"bottom">'))
output$lambdas <- renderPrint({
modCur <- rvs$mods[[rvs$modSel]]
if (rvs$algMaxent == "maxnet") {
modCur$betas
} else if (rvs$algMaxent == "maxent.jar") {
modCur@lambdas
}
})
shinyjs::show(id = "evalTblBins")
# switch to Results tab
updateTabsetPanel(session, 'main', selected = 'Results')
# customize visualizations for maxent
updateRadioButtons(session, "visSel",
choices = list("Maxent Evaluation Plots" = 'mxEval',
"Plot Response Curves" = 'response',
"Map Prediction" = 'map'))
})
# module BIOCLIM
mod.bioclim <- callModule(bioclim_MOD, 'c6_bioclim', rvs)
observeEvent(input$goBioclim, {
e <- mod.bioclim()
# stop if no occurrence partition group
req(rvs$occsGrp)
rvs$comp6 <- 'bioclim' # record the enm selected
rvs$mods <- e$models
rvs$modPreds <- e$predictions
rvs$modRes <- e$results
output$evalTbls <- renderUI({
tagList(
br(),
div("Full model, partition bin average and individual evaluation statistics", id="stepText"), br(), br(),
DT::dataTableOutput('evalTbl')
)
})
output$evalTbl <- DT::renderDataTable(round(rvs$modRes, digits=3), options = list(scrollX = TRUE,
sDom = '<"top">rtp<"bottom">'))
# switch to Results tab
updateTabsetPanel(session, 'main', selected = 'Results')
updateRadioButtons(session, "visSel",
choices = list("BIOCLIM Envelope Plots" = 'bcPlots',
"Map Prediction" = 'map'))
shinyjs::hide(id = "evalTblBins")
})
# download for partitioned occurrence records csv
output$dlEvalTbl <- downloadHandler(
filename = function() {
if (rvs$comp6 == "bioclim") {
paste0(spName(), "_bioclim_evalTbl.csv")
} else if (rvs$comp6 == "maxent") {
paste0(spName(), "_maxent_evalTbl.csv")
}
},
content = function(file) {
write_csv_robust(rvs$modRes, file, row.names = FALSE)
}
)
########################################### #
### COMPONENT 7: VISUALIZE MODEL RESULTS ####
########################################### #
# ui that populates with the names of models that were run
output$modSelUI <- renderUI({
req(rvs$modPreds)
n <- names(rvs$modPreds)
modsNameList <- setNames(as.list(n), n)
selectInput('modSel', label = "Current Model",
choices = modsNameList, selected = modsNameList[[1]])
})
# ui that populates with the names of environmental predictors used
output$envSelUI <- renderUI({
req(rvs$modPreds)
# for Maxent, only display the environmental predictors with non-zero beta coefficients
# from the lambdas file (the predictors that were not removed via regularization)
if (rvs$comp6 == "maxent") {
modCur <- rvs$mods[[rvs$modSel]]
if (rvs$algMaxent == "maxnet") {
nonZeroCoefs <- mxNonzeroCoefs(modCur, maxentVersion = "maxnet")
} else if(rvs$algMaxent == "maxent.jar") {
nonZeroCoefs <- mxNonzeroCoefs(modCur, maxentVersion = "maxent.jar")
}
envsNames <- names(rvs$bgMsk[[nonZeroCoefs]])
rvs$mxNonZeroCoefs <- envsNames
} else {
envsNames <- names(rvs$bgMsk)
}
envsNamesList <- setNames(as.list(envsNames), envsNames)
selectInput("envSel", "Current Env Variable",
choices = envsNamesList, selected = envsNamesList[[1]])
})
# always update the selected model and environmental predictor in rvs
observe({
rvs$modSel <- input$modSel
rvs$envSel <- input$envSel
})
# module BIOCLIM Plots
bcPlots <- callModule(bcPlots_MOD, 'c7_bcPlots', rvs)
output$bcEnvelPlot <- renderPlot({
bcPlots()
})
# module Maxent Evaluation Plots
mxEvalPlots <- callModule(mxEvalPlots_MOD, 'c7_mxEvalPlots', rvs)
output$mxEvalPlots <- renderPlot({
mxEvalPlots()
updateTabsetPanel(session, 'main', selected = 'Results')
})
# module Response Curve Plots
respPlots <- callModule(respPlots_MOD, 'c7_respPlots', rvs)
output$respPlots <- renderPlot({
respPlots()
updateTabsetPanel(session, 'main', selected = 'Results')
})
# module Map Prediction (restricted to background extent)
observeEvent(input$goMapPreds, {
if (rvs$comp6 == 'maxent') {
mapPreds <- callModule(mapPredsMaxent_MOD, 'c7_mapPredsMaxent', rvs)
} else {
mapPreds <- callModule(mapPreds_MOD, 'c7_mapPreds', rvs)
}
# stop if mapPreds is NULL
rvs$predCur <- mapPreds()
req(rvs$predCur)
# stop if no models
req(rvs$mods)
rvs$predCurVals <- getVals(rvs$predCur, rvs$comp7.type)
updateTabsetPanel(session, 'main', selected = 'Map')
# MAPPING
if (rvs$comp7.thr != 'noThresh') {
rasPal <- c('gray', 'blue')
map %>% addLegend("bottomright", colors = c('gray', 'blue'),
title = "Thresholded Suitability", labels = c("predicted absence", "predicted presence"),
opacity = 1, layerId = 'leg')
} else {
rasCols <- c("#2c7bb6", "#abd9e9", "#ffffbf", "#fdae61", "#d7191c")
legendPal <- colorNumeric(rev(rasCols), rvs$predCurVals, na.color='transparent')
rasPal <- colorNumeric(rasCols, rvs$predCurVals, na.color='transparent')
map %>% addLegend("bottomright", pal = legendPal, title = "Predicted Suitability",
values = rvs$predCurVals, layerId = 'leg',
labFormat = reverseLabels(2, reverse_order=TRUE))
}
map %>%
clearMarkers() %>% clearImages() %>% clearShapes() %>%
map_plotLocs(rvs$occs) %>%
addRasterImage(rvs$predCur, colors = rasPal, opacity = 0.7,
group = 'c7', layerId = 'r1ID', project = TRUE)
for (shp in bgShpXY()) {
map %>%
addPolygons(lng=shp[,1], lat=shp[,2], fill = FALSE,
weight=4, color="red", group='c7')
}
shinyjs::enable("dlPred")
})
# download for model predictions (restricted to background extent)
output$dlPred <- downloadHandler(
filename = function() {
ext <- switch(input$predFileType, raster = 'zip', ascii = 'asc', GTiff = 'tif', png = 'png')
paste0(names(rvs$predCur), '.', ext)},
content = function(file) {
# browser()
if (require(rgdal)) {
if (input$predFileType == 'png') {
png(file)
raster::image(rvs$predCur)
dev.off()
} else if (input$predFileType == 'raster') {
fileName <- names(rvs$predCur)
tmpdir <- tempdir()
raster::writeRaster(rvs$predCur, file.path(tmpdir, fileName), format = input$predFileType, overwrite = TRUE)
owd <- setwd(tmpdir)
fs <- paste0(fileName, c('.grd', '.gri'))
zip::zip(zipfile=file, files=fs)
setwd(owd)
} else {
r <- raster::writeRaster(rvs$predCur, file, format = input$predFileType, overwrite = TRUE)
file.rename(r@file@name, file)
}
} else {
rvs %>% writeLog("Please install the rgdal package before downloading rasters.")
}
}
)
########################################### #
### COMPONENT 8: PROJECT MODEL ####
########################################### #
# module Project to New Area
projArea <- callModule(projectArea_MOD, 'c8_projectArea', rvs)
observeEvent(input$goProjectArea, {
projArea.call <- projArea()
req(projArea.call)
# stop if no model prediction
req(rvs$predCur)
# unpack
rvs$projMsk <- projArea.call[[1]]
rvs$projCur <- projArea.call[[2]]
rvs$projCurVals <- getVals(rvs$projCur, rvs$comp7.type)
rvs$comp8.pj <- 'area'
rasVals <- c(rvs$predCurVals, rvs$projCurVals)
rasCols <- c("#2c7bb6", "#abd9e9", "#ffffbf", "#fdae61", "#d7191c")
rasPal <- colorNumeric(rasCols, rvs$predCurVals, na.color='transparent')
map %>%
addRasterImage(rvs$predCur, colors = rasPal, opacity = 0.7,
group = 'c7', layerId = 'r1ID') %>%
comp8_map(rvs$projCur, rvs$polyPjXY, bgShpXY, rasVals,
rasCols, "Predicted Suitability",
addID = 'rProjArea', clearID = c('rProjArea', 'rProjTime', 'rProjMESS'))
map %>% drawToolbarRefresh()
shinyjs::enable("dlProj")
})
# module Project to New Time
projTime <- callModule(projectTime_MOD, 'c8_projectTime', rvs)
observeEvent(input$goProjectTime, {
projTime.call <- projTime()
req(projTime.call)
# stop if no model prediction
req(rvs$predCur)
# unpack
rvs$projMsk <- projTime.call[[1]]
rvs$projCur <- projTime.call[[2]]
req(rvs$projCur)
rvs$projCurVals <- getVals(rvs$projCur, rvs$comp7.type)
rvs$comp8.pj <- 'time'
raster::crs(rvs$projCur) <- raster::crs(rvs$bgMsk)
rasVals <- c(rvs$predCurVals, rvs$projCurVals)
rasCols <- c("#2c7bb6", "#abd9e9", "#ffffbf", "#fdae61", "#d7191c")
map %>% comp8_map(rvs$projCur, rvs$polyPjXY, bgShpXY, rasVals,
rasCols, "Predicted Suitability",
addID = 'rProjTime', clearID = c('r1ID', 'rProjArea', 'rProjTime', 'rProjMESS'))
map %>% drawToolbarRefresh()
shinyjs::enable("dlProj")
})
# module Environmental Similarity
envSimilarity <- callModule(envSimilarity_MOD, 'c8_envSimilarity', rvs)
observeEvent(input$goEnvSimilarity, {
rvs$mess <- envSimilarity()
req(rvs$mess)
# stop if no model projection
req(rvs$projCur)
rvs$comp8.esim <- 'mess'
# set infinite values to NA
rvs$mess[is.infinite(rvs$mess)] <- NA
# extract values
rvs$messVals <- getVals(rvs$mess)
rasVals <- rvs$messVals
# define colorRamp for mess
if (max(rasVals) > 0 & min(rasVals) < 0) {
rc1 <- colorRampPalette(colors = rev(RColorBrewer::brewer.pal(n = 3, name = 'Reds')),
space = "Lab")(abs(min(rasVals)))
rc2 <- colorRampPalette(colors = RColorBrewer::brewer.pal(n = 3, name = 'Blues'),
space = "Lab")(max(rasVals))
rasCols <- c(rc1, rc2)
} else if (max(rasVals) < 0 & min(rasVals) < 0) {
rasCols <- colorRampPalette(colors = rev(RColorBrewer::brewer.pal(n = 3, name = 'Reds')),
space = "Lab")(abs(min(rasVals)))
} else if (max(rasVals) > 0 & min(rasVals) > 0) {
rasCols <- colorRampPalette(colors = RColorBrewer::brewer.pal(n = 3, name = 'Blues'),
space = "Lab")(max(rasVals))
}
map %>% comp8_map(rvs$mess, rvs$polyPjXY, bgShpXY, rasVals, rasCols, "MESS Values",
addID = 'rProjMESS', clearID = c('r1ID', 'rProjArea', 'rProjTime', 'rProjMESS'))
shinyjs::enable("dlProj")
})
# Reset Projection Extent button functionality
observeEvent(input$goResetProj, {
map %>%
removeShape("projExt") %>%
removeImage(c("rProjArea", "rProjTime", "rProjMESS"))
rvs %>% writeLog("Reset projection extent.")
})
# download for model predictions (restricted to background extent)
output$dlProj <- downloadHandler(
filename = function() {
ext <- switch(input$projFileType, raster = 'zip', ascii = 'asc', GTiff = 'tif', PNG = 'png')
paste0(names(rvs$projCur), '.', ext)},
content = function(file) {
if (require(rgdal)) {
if (input$projFileType == 'png') {
png(file)
raster::image(rvs$projCur)
dev.off()
} else if (input$projFileType == 'raster') {
fileName <- names(rvs$projCur)
tmpdir <- tempdir()
raster::writeRaster(rvs$projCur, file.path(tmpdir, fileName), format = input$projFileType, overwrite = TRUE)
owd <- setwd(tmpdir)
fs <- paste0(fileName, c('.grd', '.gri'))
zip::zip(zipfile=file, files=fs)
setwd(owd)
} else {
r <- raster::writeRaster(rvs$projCur, file, format = input$projFileType, overwrite = TRUE)
file.rename(r@file@name, file)
}
} else {
rvs %>% writeLog("Please install the rgdal package before downloading rasters.")
}
}
)
########################################### #
### MARKDOWN FUNCTIONALITY ####
########################################### #
# handler for R Markdown download
output$dlRMD <- downloadHandler(
filename = function() {
paste0("wallace-session-", Sys.Date(), ".", switch(
input$rmdFileType, Rmd = 'Rmd', PDF = 'pdf', HTML = 'html', Word = 'docx'
))},
content = function(file) {
# convert removed occIDs to characters of vectors
if (!is.null(rvs$removedIDs)) {
rvs$occsRem <- printVecAsis(rvs$removedIDs)
}
# convert polygon coordinates to characters of vectors
if (!is.null(rvs$polySelXY)) {
polySelX <- printVecAsis(round(rvs$polySelXY[,1], digits=4))
polySelY <- printVecAsis(round(rvs$polySelXY[,2], digits=4))
} else {
polySelX <- polySelY <- NULL
}
if (!is.null(rvs$polyPjXY)) {
polyPjX <- printVecAsis(round(rvs$polyPjXY[,1], digits=4))
polyPjY <- printVecAsis(round(rvs$polyPjXY[,2], digits=4))
} else {
polyPjX <- polyPjY <- NULL
}
bcSels <- printVecAsis(rvs$bcSels)
exp <- knitr::knit_expand("Rmd/userReport.Rmd",
curWD = curWD,
# comp 1
spName = spName(),
dbName = rvs$occDb,
occNum = rvs$occNum,
occsCSV = rvs$userCSV$name,
# comp 2
thinDist = rvs$thinDist,
occsRemoved = rvs$occsRem,
occsSelX = polySelX,
occsSelY = polySelY,
# comp 3
bcRes = rvs$bcRes,
bcLat = rvs$bcLat,
bcLon = rvs$bcLon,
userEnvs = printVecAsis(rvs$userEnvs$name),
bcSels = bcSels,
# comp 4
bgSel = rvs$comp4.shp,
bgBuf = rvs$comp4.buf,
#bgUserCSVname = rvs$bgUserCSVname,
#bgUserCSVpath = rvs$bgUserCSVpath,
bgUserShpPath = rvs$bgUserShpPar$dsn,
bgUserShpName = rvs$bgUserShpPar$layer,
bgPtsNum = rvs$bgPtsNum,
# comp 5
partSel = rvs$partSel,
kfolds = rvs$kfolds,
aggFact = rvs$aggFact,
# comp 6
enmSel = rvs$comp6,
algMaxent = rvs$algMaxent,
clamp = rvs$clamp,
rms1 = rvs$rms[1],
rms2 = rvs$rms[2],
rmsStep = rvs$rmsStep,
fcs = printVecAsis(rvs$fcs),
# comp 7
modSel = rvs$modSel,
mxNonZeroCoefs = printVecAsis(rvs$mxNonZeroCoefs),
envSel = rvs$envSel,
bcPlot1 = rvs$bcPlotsPar$bc1,
bcPlot2 = rvs$bcPlotsPar$bc2,
bcPlotP = rvs$bcPlotsPar$p,
mxEvalSel = rvs$mxEvalSel,
predType = rvs$comp7.type,
comp7.thresh = rvs$comp7.thr,
# comp 8
occsPjX = polyPjX,
occsPjY = polyPjY,
pjRCP = rvs$pjTimePar$rcp,
pjGCM = rvs$pjTimePar$gcm,
pjYear = rvs$pjTimePar$year,
comp8.thresh = rvs$comp8.thr)
# temporarily switch to the temp dir, in case you do not have write
# permission to the current working directory
owd <- setwd(tempdir())
on.exit(setwd(owd))
writeLines(exp, 'userReport2.Rmd')
if (input$rmdFileType == 'Rmd') {
out <- rmarkdown::render('userReport2.Rmd', rmarkdown::md_document(variant="markdown_github"))
writeLines(gsub('``` r', '```{r}', readLines(out)), 'userReport3.Rmd')
out <- 'userReport3.Rmd'
} else {
out <- rmarkdown::render('userReport2.Rmd',
switch(input$rmdFileType,
PDF = rmarkdown::pdf_document(latex_engine='xelatex'),
HTML = rmarkdown::html_document(),
Word = rmarkdown::word_document())
)
}
file.rename(out, file)
}
)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.