使用 downloadHandler() 在 tempdir() 中创建和读取的图像不起作用

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

我想在 Shiny 中下载一个地理参考 PDF 文件 (geoPDF),为此需要一些步骤,例如将 ggplot 格式的绘图转换为 tiff、填充空间坐标、创建地理 tiff,最后是我的地理PDF。但是 tempdir() 目录中的 downloadHandler() 函数中的几个步骤总是导致错误:

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

我的代码是:

# 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)
##

有人可以帮我吗?

提前致谢。

我注意到的一件事是您在下载处理程序中没有输出到 file。也许你的台词:

#Save map as GeoPDF
      open.file<-paste0(tempdir(),currentvariable4(),".tif", sep="")
      save.file<-paste0(tempdir(),currentvariable4(),".pdf", sep="")
      gdalUtils::gdal_translate(open.file,save.file,of="PDF", ot="Byte",
                                co="TILED=YES",verbose=TRUE, overwrite=T, a_srs="+proj=longlat +ellps=GRS80 +towgs84=0,0,0 +no_defs")

实际上应该是

#Save map as GeoPDF
      open.file<-paste0(tempdir(),currentvariable4(),".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")

我也不确定您是否需要使用 tempdir()。无论如何,一切都建立在会话的临时目录中。

你做不到output$myplot()。这是您得到的错误的来源。如果你想得到情节,在反应导体中生成它:

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

然后做

output$myplot <- renderPlot(MyPlot())

并且在 downloadHandler 中,您可以通过调用 MyPlot().

来获取绘图

downloadHandlercontent函数中,要保存的文件必须是filecontent函数的参数。 save.file <- file.

也是如此