How to save a leaflet map in Shiny

后端 未结 2 883
抹茶落季
抹茶落季 2020-12-06 15:05

Following on from this question, I am looking to save and download a leaflet map as a png or jpeg image. I have the following code but I keep getting an error.



        
相关标签:
2条回答
  • 2020-12-06 15:25

    Overview

    Since 'leaflet' maps are interactive, the leaflet object being used in mapview::mapshot() function must be interactive. Accounting for this allows for the user to save their version of a leaflet map within the Shiny app.

    # install necessary packages
    install.packages( c( "shiny", "leaflet", "mapview" ) )
    
    # load necessary packages
    library( shiny )
    library( leaflet )
    library( mapview )
    
    ui <- fluidPage(
      leafletOutput( outputId = "map"),
      downloadButton( outputId = "dl")
    )
    
    server <- function(input, output, session) {
    
      # Create foundational leaflet map
      # and store it as a reactive expression
      foundational.map <- reactive({
    
        leaflet() %>% # create a leaflet map widget
    
          addTiles( urlTemplate = "https://{s}.tile.openstreetmap.se/hydda/base/{z}/{x}/{y}.png" ) # specify provider tile and type
    
      }) # end of foundational.map()
    
      # render foundational leaflet map
      output$map <- leaflet::renderLeaflet({
    
        # call reactive map
        foundational.map()
    
      }) # end of render leaflet
    
      # store the current user-created version
      # of the Leaflet map for download in 
      # a reactive expression
      user.created.map <- reactive({
    
        # call the foundational Leaflet map
        foundational.map() %>%
    
          # store the view based on UI
          setView( lng = input$map_center$lng
                   ,  lat = input$map_center$lat
                   , zoom = input$map_zoom
          )
    
      }) # end of creating user.created.map()
    
    
    
      # create the output file name
      # and specify how the download button will take
      # a screenshot - using the mapview::mapshot() function
      # and save as a PDF
      output$dl <- downloadHandler(
        filename = paste0( Sys.Date()
                           , "_customLeafletmap"
                           , ".pdf"
        )
    
        , content = function(file) {
          mapshot( x = user.created.map()
                   , file = file
                   , cliprect = "viewport" # the clipping rectangle matches the height & width from the viewing port
                   , selfcontained = FALSE # when this was not specified, the function for produced a PDF of two pages: one of the leaflet map, the other a blank page.
          )
        } # end of content() function
      ) # end of downloadHandler() function
    
    } # end of server
    
    # run the Shiny app
    shinyApp(ui = ui, server = server)
    
    # end of script #
    

    Final result

    Once you run the Shiny app, open the app in a new window.

    Once in the browser, go ahead and click Download. It took about ~3 seconds.

    Once Download has been clicked, you'll promptly see a PDF file wherever your downloaded files are stored on your machine.

    References

    My ideas sprung from the following posts:

    • Save leaflet map in Shiny

    • How to save a leaflet map in Shiny

    • Input/Events - Leaflet for R

    • Thanks to @blondeclover, there is no need to store the bounds of the leaflet map when using setView(). Instead, simply use input$MAPID_center$lng and input$MAPID_center$lat when using setView().

      • To learn more about other leaflet inputs, please see list input handlers for a package shiny leaflet.
    0 讨论(0)
  • 2020-12-06 15:35

    May be this would help:

      server <- function(input, output, session) {
    
        map <- reactiveValues(dat = 0)
    
          output$map <- renderLeaflet({
            map$dat <- leaflet() %>% 
              addTiles()
          })
    
          output$dl <- downloadHandler(
            filename = "map.png",
    
            content = function(file) {
              mapshot(map$dat, file = file)
            }
          )
        }
    
    0 讨论(0)
提交回复
热议问题