I want to add a feature for users to export a map, produced by Tmap, in Shiny. I understand that tmap converts the map to leaflet but it doesn't work with mapview::mapshot as many answers give for saving Leaflet maps in Shiny.
None of the following work:
map_expr <- reactive({
tm_shape(water1) +
tm_fill(col = "darkblue") +
tm_shape(county_outlines) +
tm_borders(col = "black") +
tm_shape(herd_summary) +
tm_symbols(col = "green", size = "REACTORS", scale = 0.15, alpha = 0.7) +
tm_shape(water1) +
tm_fill(col = "darkblue")
})
observe({
output$map <- renderTmap({
map_expr()
})
})
output$downloadData <- downloadHandler(
filename = "test.png",
content = function(file) {
# mapshot(map_expr(), file = file, cliprect = "viewport")
# tmap_save(map_expr(), file = file)
tmapProxy("map", session, {}) %>%
mapview::mapshot(file = file)
}
)
After some trial and error, I eventually got it to work, and have included a reproducible example here as follows:
library(shiny)
library(tmap)
library(mapview)
data("World")
pal <- leaflet::colorBin(palette = grDevices::heat.colors(20), domain = World$HPI)
ui <- fluidPage(
titlePanel("Tmap Example"),
sidebarLayout(
sidebarPanel(
downloadButton("downloadData")
),
mainPanel(
tmapOutput("map")
)
)
)
server <- function(input, output) {
map_expr <- reactive({
tm_shape(World) +
tm_polygons("HPI")
})
output$map <- renderTmap({
map_expr()
})
output$downloadData <- downloadHandler(
filename = "test.png",
content = function(file) {
mapview::mapshot(tmap_leaflet(map_expr()), file = file)
}
)
}
shinyApp(ui = ui, server = server)
So the tmap expression must be saved to an object (I am saving it to a reactive object called map_expr, so you must include the brackets when calling this object elsewhere within the code).
Using the function mapshot from the package mapview, you can save a leaflet object, and there is a function called tamp_leaflet within tmap that will convert the tmap object to a leaflet object.
Make sure that mapshot is working by first testing it outside of the application. To get it to work, I had to install the package webshot and had to install phantomJS which can be done via the following function: webshot::install_phantomjs()
Hope this helps!