This question is a follow-up to the questions How to save a leaflet map in Shiny, and Save leaflet map in Shiny.
I add a toolbar to draw shapes/points on the map that is addDrawToolbar
in the leaflet.extras package. That lets users to draw lines, shapes, ... interactively. In the end I want one to be able to save the map with the drawn shapes as a pdf or png.
I have coded up the following making use of the answer to the question: How to save a leaflet map in Shiny. But it does not help achieve my goal.
Is there anyone who can help me?
library(shiny)
library(leaflet)
library(leaflet.extras)
library(mapview)
ui <- fluidPage(
leafletOutput("map"),
br(),
downloadButton("download_pdf", "Download .pdf")
)
server <- function(input, output, session) {
foundational_map <- reactive({
leaflet() %>%
addTiles()%>%
addMeasure(
primaryLengthUnit = "kilometers",
secondaryAreaUnit = FALSE
)%>%
addDrawToolbar(
targetGroup='draw',
editOptions = editToolbarOptions(selectedPathOptions =
selectedPathOptions()),
polylineOptions = filterNULL(list(shapeOptions =
drawShapeOptions(lineJoin = "round",
weight = 3))),
circleOptions = filterNULL(list(shapeOptions =
drawShapeOptions(),
repeatMode = F,
showRadius = T,
metric = T,
feet = F,
nautic = F))) %>%
setView(lat = 45, lng = 9, zoom = 3) %>%
addStyleEditor(position = "bottomleft",
openOnLeafletDraw = TRUE)
})
output$map <- renderLeaflet({
foundational_map()
})
user_created_map <- reactive({
foundational_map() %>%
setView(lng = input$map_center$lng, lat = input$map_center$lat,
zoom = input$map_zoom)
})
output$download_pdf <- downloadHandler(
filename = paste0("map_", Sys.time(), ".pdf"),
content = function(file) {
mapshot(user_created_map(), file = file)
}
)
}
shinyApp(ui = ui, server = server)
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.
Yes, you can save leaflet objects as images. In the viewer tab, above the map, you will find an export button to save leaflets as an image.
Apparently the mapshot
function is not aware of drawn polygons and just stores the clean leaflet-map, as it launches an isolated background process which captures the webshot.
I would propose this workaround, which captures the whole screen (using this batch-file) and saves it as png. (only for Windows)
This is not very beautiful as it will also capture the windows and browser menu bars, although that could be adapted in the batch-file.
The batch-file must be in the same directory and must be named screenCapture.bat .
library(shiny)
library(leaflet)
library(leaflet.extras)
library(mapview)
ui <- fluidPage(
leafletOutput("map"),
actionButton("download_pdf", "Download .pdf")
)
server <- function(input, output, session) {
foundational_map <- reactive({
leaflet() %>%
addTiles()%>%
addMeasure(
primaryLengthUnit = "kilometers",
secondaryAreaUnit = FALSE
)%>%
addDrawToolbar(
targetGroup='draw',
editOptions = editToolbarOptions(selectedPathOptions =
selectedPathOptions()),
polylineOptions = filterNULL(list(shapeOptions =
drawShapeOptions(lineJoin = "round",
weight = 3))),
circleOptions = filterNULL(list(shapeOptions =
drawShapeOptions(),
repeatMode = F,
showRadius = T,
metric = T,
feet = F,
nautic = F))) %>%
setView(lat = 45, lng = 9, zoom = 3) %>%
addStyleEditor(position = "bottomleft",
openOnLeafletDraw = TRUE)
})
output$map <- renderLeaflet({
foundational_map()
})
user_created_map <- reactive({
foundational_map()
})
## observeEvent which makes a call to the Batch-file and saves the image as .png
observeEvent(input$download_pdf, {
img = paste0("screen", runif(1,0,1000), ".png")
str = paste('call screenCapture ', img)
shell(str)
})
}
shinyApp(ui = ui, server = server)
To remove the browser and Windows toolbar, I manipulated the .bat-file like this:
Line 66:
int height = windowRect.bottom - windowRect.top - 37;
Line 75:
GDI32.BitBlt(hdcDest, 0, -80, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
This works on my machine, but you will have to adapt the values or even come up with a better solution, since I have to admit that I'm not too good at batch scripting. This will hide the toolbars, but there will be a black strip at the bottom.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With