Reputation: 21
I'm working with a R Shiny app that takes two shapefiles in input and then intersects them together and calculates the area.
I want to reset and remove the second shapefile in input when the first shapefile is uploaded so at the new analysis I want to set the second shapefile (file2
) as NULL.
I tried using shinyjs::reset("file2")
but the second shapefile (input$file2
) is still in memory and when I upload a new shapefile (file1
, input$file1
) and then click on analysis button (whithout upload another file2
) the app starts analysis such as file2
was not resetted.
This is the code that I'm using:
library(shiny)
library(shinyjs)
library(leaflet)
library(mapview)
library(rgdal)
library(rgeos)
library(maptools)
library(DT)
fIntersect<-function(file1,file2){
CRSfrom <- CRS("+proj=utm +zone=33 +datum=WGS84 +units=m+no_defs")
CRSto <- CRS("+proj=longlat +datum=WGS84")
shpInt <- disaggregate(intersect(file1, file2))
shpInt@data$area<- round(gArea(shpInt, byid = TRUE) / 10000,digits= 2)
IntData<-data.table(shpInt@data)
return(list("IntData"=IntData))
}
ui <- fluidPage(
useShinyjs(),
fileInput('file1', 'Choose File',multiple = TRUE),
fileInput('file2', 'Choose File',multiple = TRUE),
actionButton("Analize", "Analize"),
box(leafletOutput("Map",width ="100%")),
box(dataTableOutput("IntData"))),
server <- function(input, output) {
#CRS setting
CRSfrom <- CRS("+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs")
CRSto <- CRS("+proj=longlat +datum=WGS84")
#Render Input file and upload
output$Map <- renderLeaflet({
leaflet() %>%setView(16,40,zoom=6)%>%
addTiles() })
output$file1 <- renderText({
file1 <- input$file1
if (is.null(input$file1))
return(NULL)
})
output$file2 <- renderText({
file2 <- input$file2
if (is.null(file2))
return(NULL)
})
uploadfile1 <- reactive({
if (!is.null(input$file1)) {
shpDF <- input$file1
prevWD <- getwd()
uploadDirectory <- dirname(shpDF$datapath[1])
setwd(uploadDirectory)
for (i in 1:nrow(shpDF)) {
file.rename(shpDF$datapath[i], shpDF$name[i])
}
shpName <- shpDF$name[grep(x = shpDF$name, pattern = "*.shp")]
shpPath <- paste(uploadDirectory, shpName, sep = "/")
setwd(prevWD)
file <- readShapePoly(shpPath,
proj4string =CRS("+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs"))
return(file)
} else {
return(NULL)
}
})
uploadfile2 <- reactive({
if (!is.null(input$file2)) {
shpDF <- input$file2
prevWD <- getwd()
uploadDirectory <- dirname(shpDF$datapath[1])
setwd(uploadDirectory)
for (i in 1:nrow(shpDF)) {
file.rename(shpDF$datapath[i], shpDF$name[i])
}
shpName <- shpDF$name[grep(x = shpDF$name, pattern = "*.shp")]
shpPath <- paste(uploadDirectory, shpName, sep = "/")
setwd(prevWD)
file <- readShapePoly(shpPath,
proj4string =CRS("+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs"))
return(file)
}
else {
return(NULL)
}
})
output$IntData <- renderDataTable(datatable(data.table("id" = "0")))
observeEvent(input$file1, {
# Show upload polygon on Map
shinyjs::reset('file2')
leafletProxy("Map")%>%clearGroup(c("file1")) ####
shpUpload <- spTransform(uploadfile1(), CRSto)
leafletProxy("Map") %>%
addPolygons(data = shpUpload,
color = "#33a02c",
group = "file1",
fill = FALSE,
weight = 2.5)
})
observeEvent(input$file2, {
# Show upload polygon on Map
leafletProxy("Map")%>%clearGroup(c("file2")) ####
shpUpload <- spTransform(uploadfile2(), CRSto)
leafletProxy("Map") %>%
addPolygons(data = shpUpload,
color = "#33a02c",
group = "file2",
fill = FALSE,
weight = 2.5)
})
#Start analysis
observeEvent(input$Analize,{
if(input$Analize>0){ withProgress(message = "Sto eseguendo l'analisi...",
value =0, {
Intersection<-fIntersect(uploadfile1(),uploadfile2())
observe({
output$IntData<-renderDataTable({
datatable(Intersection$IntData)
})
})
}
)
}else{}
}
)
#End Analysis
}
shinyApp(ui, server)
Thanks for any advice.
Upvotes: 1
Views: 2025
Reputation: 1502
This code shows how to create your own reativeValues to gain the control you want. First create your own writable reactive values, then use those instead of input.
library(shiny)
library(DT)
library(shinyjs)
# Define UI for application that draws a histogram
ui <- fluidPage(
fileInput('file1', 'Choose File',multiple = TRUE),
fileInput('file2', 'Choose File',multiple = TRUE),
actionButton("Analize", "Analize"),
# Show the state of the input files
verbatimTextOutput('file1'),
verbatimTextOutput('file2'),
# This will change only when the action button is used
verbatimTextOutput('look_at_input')
)
# Define server logic required to draw a histogram
server <- function(input, output) {
# Create your own reactive values that you can modify because input is read only
rv <- reactiveValues()
# Do something when input$file1 changes
# * set rv$file1, remove rv$file2
observeEvent(input$file1, {
rv$file1=input$file1
rv$file2=NULL
})
# Do something when input$file2 changes
# * Set rv$file2
observeEvent(input$file2, {
rv$file2=input$file2
})
# Show the value of rv$file1
output$file1 <- renderPrint ({ str(rv$file1) })
# Show the value of rv$file2
output$file2 <- renderPrint({ str(rv$file2) })
#Start analysis
# Do something when the Analize button is selected
look_at_input<-eventReactive(input$Analize,{
list(rv$file1,rv$file2)
})
output$look_at_input <-renderPrint({ str( look_at_input() )})
#End Analysis
}
# Run the application
shinyApp(ui = ui, server = server)
Upvotes: 2