Search code examples
rshinyr-leaflet

Download leaflet map from a shiny app hosted on shiny.io


I have a shiny app that displays a map from the leaflet package. I am interested in saving the map from the shiny app as either a PNG file or HTML file. I have managed to save it as PNG file when running locally and opening the shiny app on the browser with the code below:

library(shiny)
library(leaflet)
library( mapview)


ui <- fluidPage(
      leafletOutput(outputId = "eiffelmap")
       , downloadButton(outputId = "savemap")
       )

server <- function(input, output, server){




   name <- 'EIFFEL TOWER'
   longitude <- 2.2945
   latitude <- 48.8583
   location <- data.frame(name,longitude,latitude)

   icon.pop <- awesomeIcons(icon = 'thumb-tack',
                         markerColor = 'blue',
                         library = 'fa',
                         iconColor = 'black')
  map <- reactive({  
  name <- 'EIFFEL TOWER'
  longitude <- 2.2945
  latitude <- 48.8583
  location <- data.frame(name,longitude,latitude)
  
  icon.pop <- awesomeIcons(icon = 'thumb-tack',
                           markerColor = 'blue',
                           library = 'fa',
                           iconColor = 'black')
  
  leaflet(location) %>%
  addProviderTiles(providers$Stamen.TonerLite,
                   options = providerTileOptions(noWrap = TRUE)
  ) %>%
  
  addAwesomeMarkers(~longitude, ~latitude, label = ~name, icon=icon.pop) 

})

output$eiffelmap <- renderLeaflet({

          map()

       })

output$savemap <- downloadHandler(
    filename = "eiffelmap.png",
    content = function(file){
  
  
     mapshot(
      x = map()
      , file = file
    )
  }
)

}

shinyApp(ui, server)

My question is why the download does not work when the app is hosted on shiny.io but works when opened locally on a browser? What is wrong with my code? Also any insight on how to save the leaflet map as an interactive HTML that can be zoomed in and out?


Solution

  • I am not sure if you were asking this independently or as part of the app but if you want to save the map as an interactive HTML just run this part of your code and select the Export option in the Viewer pane and then Save as Web Page...

    library(leaflet)
    name <- 'EIFFEL TOWER'
    longitude <- 2.2945
    latitude <- 48.8583
    location <- data.frame(name,longitude,latitude)
    
    icon.pop <- awesomeIcons(icon = 'thumb-tack',
                             markerColor = 'blue',
                             library = 'fa',
                             iconColor = 'black')
    
    leaflet(location) %>%
      addProviderTiles(providers$Stamen.TonerLite,
                       options = providerTileOptions(noWrap = TRUE)
      ) %>%
    
      addAwesomeMarkers(~longitude, ~latitude, label = ~name, icon=icon.pop) 
    

    enter image description here

    Update:

    Please try this (using htmlwidgets::saveWidget())

    library(shiny)
    library(leaflet)
    library(htmlwidgets)
    
    
    ui <- fluidPage(
      leafletOutput(outputId = "eiffelmap")
      , downloadButton(outputId = "savemap")
    )
    
    server <- function(input, output, server){
    
    
    
    
      name <- 'EIFFEL TOWER'
      longitude <- 2.2945
      latitude <- 48.8583
      location <- data.frame(name,longitude,latitude)
    
      icon.pop <- awesomeIcons(icon = 'thumb-tack',
                               markerColor = 'blue',
                               library = 'fa',
                               iconColor = 'black')
      map <- reactive({  
        name <- 'EIFFEL TOWER'
        longitude <- 2.2945
        latitude <- 48.8583
        location <- data.frame(name,longitude,latitude)
    
        icon.pop <- awesomeIcons(icon = 'thumb-tack',
                                 markerColor = 'blue',
                                 library = 'fa',
                                 iconColor = 'black')
    
        leaflet(location) %>%
          addProviderTiles(providers$Stamen.TonerLite,
                           options = providerTileOptions(noWrap = TRUE)
          ) %>%
    
          addAwesomeMarkers(~longitude, ~latitude, label = ~name, icon=icon.pop) 
    
      })
    
      output$eiffelmap <- renderLeaflet({
    
        map()
    
      })
    
      output$savemap <- downloadHandler(
        filename = "eiffelmap.html",
        content = function(file){
    
    
          saveWidget(
            widget = map()
            , file = file
          )
        }
      )
    
    }
    
    shinyApp(ui, server)