允许用户上传闪亮的 shapefile

Allow user to upload a shapefile in shiny

我正在制作一个闪亮的应用程序,允许用户使用 sf 包上传 shapefile。当我通过浏览 window select .shp 文件时,我得到一个 error。我怎样才能让用户上传一个 shapefile,然后让 st_read' or readOGR. 读取它而且,我不知道为什么 st_read 会变成 C:\Users\Ed\AppData...,因为这不是形状文件。

library(shiny)
library(shinydahsboard)
library(sf)

UI

ui = navbarPage("Project Eddy", theme = shinytheme("sandstone"),
                tabPanel("Location",
                sidebarLayout(sidebarPanel(fileInput("shp", "Please choose a Shapefile",
                                                      multiple = F,
                                                      ".shp")),
                mainPanel(plotlyOutput(outputId = "Area")))))

服务器

server = function(input, output, session) {
    
    myshp.df = reactive({
              
              # input$shp will be NULL initially. After the user selects
              # and uploads a file, head of that data file by default,
              # or all rows if selected, will be shown.
              
              req(input$shp)
              
              df = st_read(dsn = input$shp$datapath,
                           quite = T)
                                                             
              if(input$disp == "head") {
                return(head(df))
              }
              else {
                return(df)
              }
              
            })                                               
            
        output$Area = renderPlotly({
          req(myshp.df())
          a = myshp.df
          c = leaflet(a) %>%
            addPolygons(stroke = FALSE, fillOpacity = 0.5, smoothFactor = 0.5) %>%
            addProviderTiles('Esri.WorldImagery') 
        })
    })

错误

    Warning in CPL_read_ogr(dsn, layer, query, as.character(options), quiet,  :
      GDAL Error 4: Unable to open C:\Users\Ed\AppData\Local\Temp\RtmpioUU3m\b0cd5b1eb5c4fe4219e6c114[=13=].shx or C:\Users\Ed\AppData\Local\Temp\RtmpioUU3m\b0cd5b1eb5c4fe4219e6c114[=13=].SHX. Set SHAPE_RESTORE_SHX config option to YES to restore or create it.
    Warning: Error in : Cannot open "C:\Users\Ed\AppData\Local\Temp\RtmpioUU3m\b0cd5b1eb5c4fe4219e6c114[=13=].shp"; The source could be corrupt or not supported. See `st_drivers()` for a list of supported formats.
      128:

ESRI shapefile 是众所周知的麻烦制造者,因为它们存在于多个文件中 - 单个 *.shp 文件不足以让您闪亮的应用程序使用。

考虑用户 fiorepalombina 在 RStudio 社区论坛上提出的解决方案:https://community.rstudio.com/t/shinyfiles-and-shapefiles/89099

要读入 shapefile,用户必须至少提交必需的文件(.shp、.shx 和 .dbf)。上传文件后,您可以通过 $datapath$name.

访问位置和名称

默认情况下,闪亮的名称文件输入如下: C:\Users\DWISME~1\AppData\Local\Temp\RtmpiOjVGv/6903ae29a41daccceee4b8a5/0.dbf
C:\Users\DWISME~1\AppData\Local\Temp\RtmpiOjVGv/6903ae29a41daccceee4b8a5/1.prj
C:\Users\DWISME~1\AppData\Local\Temp\RtmpiOjVGv/6903ae29a41daccceee4b8a5/2.sbn
C:\Users\DWISME~1\AppData\Local\Temp\RtmpiOjVGv/6903ae29a41daccceee4b8a5/3.sbx
C:\Users\DWISME~1\AppData\Local\Temp\RtmpiOjVGv/6903ae29a41daccceee4b8a5/4.shp
C:\Users\DWISME~1\AppData\Local\Temp\RtmpiOjVGv/6903ae29a41daccceee4b8a5/5.shx

我的方法是创建一个访问文件输入位置并更改目录的函数:

library(shiny)
library(sf)
library(purrr)

ui <- fluidPage(
        br(),
        fluidRow(column(6, offset = 3,
        fileInput("shp", label = "Input Shapfile (.shp,.dbf,.sbn,.sbx,.shx,.prj)",
        width = "100%",
        accept = c(".shp",".dbf",".sbn",".sbx",".shx",".prj"), multiple=TRUE))),
          
        br(),
        fluidRow(column(8, offset = 2,
        p("input$shp$datapath" , style = "font-weight: bold"),                              
        verbatimTextOutput("shp_location", placeholder = T))),
          
        br(),
        fluidRow(column(8, offset = 2,
        p("input$shp$name" , style = "font-weight: bold"),                              
        verbatimTextOutput("shp_name", placeholder = T)))   
        )

server <- function(input, output, session) {
    
    # Read-in shapefile function
    Read_Shapefile <- function(shp_path) {
        infiles <- shp_path$datapath # get the location of files
        dir <- unique(dirname(infiles)) # get the directory
        outfiles <- file.path(dir, shp_path$name) # create new path name
        name <- strsplit(shp_path$name[1], "\.")[[1]][1] # strip name 
        purrr::walk2(infiles, outfiles, ~file.rename(.x, .y)) # rename files
        x <- read_sf(file.path(dir, paste0(name, ".shp"))) # read-in shapefile
        return(x)
    }

    # Read-shapefile once user submits files
    observeEvent(input$shp, {
        user_shp <- Read_Shapefile(input$shp)
        plot(user_shp) # plot to R console
    

        # Print original file path location and file name to UI
        output$shp_location <- renderPrint({
            full_path <- strsplit(input$shp$datapath," ")
            purrr::walk(full_path, ~cat(.x, "\n")) 
            })
                
        output$shp_name <- renderPrint({
            name_split <- strsplit(input$shp$name," ")
            purrr::walk(name_split, ~cat(.x, "\n")) 
        })
    })  
}

shinyApp(ui, server)