Search code examples
rpdfshinygeolocationmaps

Images created and read inside tempdir() using downloadHandler() doesn't work


I'd like to download inside Shiny a georeferenced PDF file (geoPDF) and for this a need some steps like convert the plot in ggplot format to tiff, populate the spatial coordinates, create a geo tiff, and finally my geoPDF. But several steps in downloadHandler() function in tempdir() directory results always in the error:

Listening on http://127.0.0.1:6096
Checking gdal_installation...
GDAL version 3.1.4
GDAL command being used: "C:\OSGeo4W64\bin\gdal_translate.exe" -ot "Byte" -of "PDF" -a_srs "+proj=longlat +ellps=GRS80 +towgs84=0,0,0 +no_defs" -co "TILED=YES" "CERROCOROADO001G.tif" "C:\Users\fores\AppData\Local\Temp\RtmpiQIcHS\file1117c7099730a.pdf"
Warning in system(cmd, intern = TRUE) :
  execução do comando '"C:\OSGeo4W64\bin\gdal_translate.exe" -ot "Byte" -of "PDF" -a_srs "+proj=longlat +ellps=GRS80 +towgs84=0,0,0 +no_defs" -co "TILED=YES" "CERROCOROADO001G.tif" "C:\Users\fores\AppData\Local\Temp\RtmpiQIcHS\file1117c7099730a.pdf"' teve status 1
ERROR 4: CERROCOROADO001G.tif: No such file or directory

My code is:

# Packages
require(rgdal)
require(shiny)
require(ggplot2)
require(ggpubr) 
require(dplyr)
require(shinythemes)
require(ggspatial)
require(sf)
require(maptools)
require(lubridate)


# get AOI
download.file(
  "https://github.com/Leprechault/trash/raw/main/stands_example.zip",
  zip_path <- tempfile(fileext = ".zip")
)
unzip(zip_path, exdir = tempdir())

# Open the files
setwd(tempdir())
stands_extent <- readOGR(".", "stands_target") # Border
stands_ds <- read.csv("pred_target_stands.csv", sep=";") # Data set
stands_ds <- stands_ds %>%
  mutate(DATA_S2 = ymd(DATA_S2))


# Create the shiny dash
ui <- fluidPage(
  theme = shinytheme("cosmo"),
  titlePanel(title="My Map Dashboard"),  
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "selectedvariable0",
                  label = "Type", 
                  choices = c(unique(stands_ds$PEST)),selected = TRUE ),
      selectInput(inputId = "selectedvariable1",
                  label = "Date", 
                  choices = c(unique(stands_ds$DATA_S)),uiOutput("selectedvariable0")),
      selectInput(inputId = "selectedvariable2",
                  label = "Project", 
                  choices = c(unique(stands_ds$PROJETO)),uiOutput("selectedvariable1")),
      selectInput(inputId = "selectedvariable3",
                  label = "Stand", 
                  choices = c(unique(stands_ds$CD_TALHAO)),selected = TRUE),
      selectInput(inputId = "selectedvariable4",
                  label = "Unique ID", 
                  choices = c(unique(stands_ds$ID_UNIQUE)),selected = TRUE),
      downloadButton("download1", "Save as *geoPDF")
    ),
    mainPanel(
      textOutput("idSaida"),
      fluidRow(
        splitLayout(plotOutput("myplot"))),
      dateInput(inputId = "Dates selection", label = "Time")
    )
  )
)
server <- function(input, output){
  
  currentvariable0 <- reactive({input$selectedvariable0})
  currentvariable1 <- reactive({input$selectedvariable1})
  currentvariable2 <- reactive({input$selectedvariable2})
  currentvariable3 <- reactive({input$selectedvariable3})
  currentvariable4 <- reactive({input$selectedvariable4})
  
  output$myplot <- renderPlot({
    
    #Subset stand
    stands_sel <- subset(stands_extent, stands_extent@data$ID_UNIQUE==currentvariable4())
    
    #Subset for input$var and assign this subset to new object, "fbar"
    ds_sel<- stands_ds[stands_ds$ID_UNIQUE==currentvariable4(),]
    
    #Create a map
    polys <- st_as_sf(stands_sel)
    ggplot() +
      geom_sf(data=polys) +
      geom_point(data=ds_sel,
                 aes(x=X, y=Y), color="red") +
      xlab("Longitude") + ylab("Latitude") +
      coord_sf() +
      theme_bw() +
      theme(text = element_text(size=10)) 
  }) 
  
  MyPlot <- reactive({
    
    #Subset stand
    stands_sel <- subset(stands, stands@data$UNIQUE==currentvariable4())
    #Subset data set
    stands_actual<-pred_attack[pred_attack$ID_UNIQUE==currentvariable4(),]
    #Create a map
    polys <- st_as_sf(stands_sel)
    ggplot() +
      ggtitle(currentvariable4()) +
      geom_sf(data=polys) +
      geom_point(data=stands_actual,
                 aes(x=x, y=y), color="red") +
      ggspatial::annotation_north_arrow(location = "bl", which_north = "true", 
                                        pad_x = unit(0.3, "in"), pad_y = unit(0.5, "in"),
                                        style = north_arrow_fancy_orienteering) + #Add a north arrow
      ggspatial::annotation_scale(location = "bl", width_hint = 0.55) + #Add a scale bar
      xlab("Longitude") + ylab("Latitude") +
      coord_sf() +
      theme_bw() +
      theme(text = element_text(size=10))
    # Save the plot
    
    ggsave(MyPlot(), gsub("[[:punct:]]", "", iconv(currentvariable4(), from = '', to = 'ASCII//TRANSLIT')),device = "tiff")
    
    # Create a StackedRaster object from the saved plot
    stackedRaster <- stack(paste0(gsub("[[:punct:]]", "", iconv(currentvariable4(), from = '', to = 'ASCII//TRANSLIT')),".tiff"))
    
    # Get the GeoSpatial Components
    lat_long <- ggplot_build(MyPlot())$layout$panel_params[[1]][c("x_range","y_range")] 
    
    # Supply GeoSpatial  data to the StackedRaster 
    extent(stackedRaster) <- c(lat_long$x_range,lat_long$y_range)
    projection(stackedRaster) <- CRS("+proj=longlat +ellps=GRS80 +towgs84=0,0,0 +no_defs")
    
    # Create the GeoTiff
    writeRaster(stackedRaster, paste0(gsub("[[:punct:]]", "", iconv(currentvariable4(), from = '', to = 'ASCII//TRANSLIT')),".tif",sep=""), options="PHOTOMETRIC=RGB", datatype="INT1U",overwrite=TRUE)
      
  })
  
  output$myplot3 <- renderPlot(MyPlot())
  
  output$download1 <- downloadHandler(
    filename = function() {
      paste0(currentvariable4(),"-",Sys.Date(),".pdf",sep="")
    },
    content = function(file) {
      
      
      #Save map as GeoPDF
      open.file<-paste0(gsub("[[:punct:]]", "", iconv(currentvariable4(), from = '', to = 'ASCII//TRANSLIT')),".tif", sep="")
      gdalUtils::gdal_translate(open.file, file, of="PDF", ot="Byte",
                                co="TILED=YES",verbose=TRUE, overwrite=T, a_srs="+proj=longlat +ellps=GRS80 +towgs84=0,0,0 +no_defs")
    }
  )
}
shinyApp(ui, server)
##

Could someone help me, please?

Thanks in advance.


Solution

  • You cannot do output$myplot(). This is the source of the error you get. If you want to get the plot, generate it in a reactive conductor:

    MyPlot <- reactive({
      # code which generates the ggplot
    })
    

    then do

    output$myplot <- renderPlot(MyPlot())
    

    and in the downloadHandler you can get the plot by calling MyPlot().

    In the content function of the downloadHandler, the file to be saved must be file, the argument of the content function. So do save.file <- file.