是否可以在R Shiny中更改Leaflet地图屏幕快照的大小?

 2021-04-09 

Is it possible to change leaflet map screenshot size in R Shiny?

我发现了两个有关将Leaflet地图保存为闪亮的答案:

  • 如何在Shiny中保存Leaflet地图

  • 如何将R map中的Leaflet保存为png或jpg文件?

  • 它们的核心思想是使用mapshot()代替webshot()。在这种情况下,使用cliprect参数设置屏幕截图大小。它定义了一个与高度匹配的裁剪矩形


    编辑:原始答案下载了最初渲染的地图,而没有考虑用户与地图的交互。我使用此答案更新了答案,因此下载内容反映了用户所看到的地图。

  • 使用js获取地图div的当前大小(基于此)
  • 根据当前缩放比例和地图中心更新地图
  • 使用vwidthvheight更改屏幕截图的大小
  • 基于此的示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    library(leaflet)
    library(mapview)
    library(shiny)

    ui <- fluidPage(
      # 1. js to get width/height of map div
      tags$head(tags$script('
                            var dimension = [0, 0];
                            $(document).on("shiny:connected", function(e) {
                            dimension[0] = document.getElementById("map").clientWidth;
                            dimension[1] = document.getElementById("map").clientHeight;
                            Shiny.onInputChange("dimension", dimension);
                            });
                            $(window).resize(function(e) {
                            dimension[0] = document.getElementById("map").clientWidth;
                            dimension[1] = document.getElementById("map").clientHeight;
                            Shiny.onInputChange("dimension", dimension);
                            });
                            ')),
      leafletOutput("map"),
      downloadButton("dl","Download Map")
      )

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

      # reactive values to store map
      vals <- reactiveValues()

      # create base map  
      output$map <- renderLeaflet({
        vals$base <- leaflet() %>%
          addProviderTiles(providers$OpenStreetMap) %>%
          addTiles()
      })

      # create map as viewed by user
      observeEvent({
        input$map_zoom
        input$map_center
        }, {
          vals$current <- vals$base %>%
            setView(lng = input$map_center$lng,
                    lat = input$map_center$lat,
                    zoom = input$map_zoom)
        }
      )

      # create download
      output$dl <- downloadHandler(
        filename ="map.png",

        content = function(file) {
          mapshot(vals$current, file = file,
                  # 2. specify size of map based on div size
                  vwidth = input$dimension[1], vheight = input$dimension[2])
        }
      )

    }
    shinyApp(ui = ui, server = server)