R闪亮传单:单击形状并缩放到边界(使用地图包)

R闪亮传单:单击形状并缩放到边界(使用地图包),r,shiny,maps,leaflet,mouseevent,R,Shiny,Maps,Leaflet,Mouseevent,出于各种原因,我仅限于使用“地图”包为以传单为中心的R Shining应用程序生成地图(即,我不能使用形状文件、光栅等,它必须是地图对象);然而,我遇到了一堵墙,我想添加一些功能 我的目标是允许用户点击美国的一个州,并让应用程序缩放到该州的边界。我找到了一个并非真正的解决方案,但我真正需要的是使用fitBounds()或setMaxBounds();但是,我不知道如何检索从鼠标单击事件中选择的状态的边界 到目前为止,我发现使用setView()可以为许多州提供“相当好”的缩放级别。但是,对于大国

出于各种原因,我仅限于使用“地图”包为以传单为中心的R Shining应用程序生成地图(即,我不能使用形状文件、光栅等,它必须是地图对象);然而,我遇到了一堵墙,我想添加一些功能

我的目标是允许用户点击美国的一个州,并让应用程序缩放到该州的边界。我找到了一个并非真正的解决方案,但我真正需要的是使用fitBounds()或setMaxBounds();但是,我不知道如何检索从鼠标单击事件中选择的状态的边界

到目前为止,我发现使用setView()可以为许多州提供“相当好”的缩放级别。但是,对于大国和小国来说,这是行不通的

代码如下:

用户界面

服务器.R

 library(shiny)
 library(leaflet)
 library(maps)

 shinyServer(function(input, output){
      output$livemap <- renderLeaflet({
          mapStates <- map("state", fill = TRUE, plot = FALSE)

          leaflet(mapStates) %>%
               addTiles() %>%
               addPolygons(color = "#444444",
                           weight = 1,
                           smoothFactor = 0.5,
                           opacity = 1.0,
                           fillOpacity = 0.5,
                           fillColor = terrain.colors(50, alpha = 1),
                           highlightOptions = highlightOptions(color = "black", weight = 2, bringToFront = TRUE))
      })
      observe({
           click <- input$livemap_shape_click
           proxy <- leafletProxy("livemap")
           if(is.null(click))
                return()
           proxy %>% setView(lng = click$lng, lat = click$lat, zoom = 7)
      })
 })
  library(shiny)
  library(leaflet)
  library(maps)

  shinyServer(function(input, output){
       output$livemap <- renderLeaflet({
            mapStates <- map("state", fill = TRUE, plot = FALSE)
            mapStates$zoom <- c(7.3, 7.1, 7.5, 6.2, 7.2, 9.2, 4.0, 7.0,
                                7.3, 6.5, 7.0, 7.4, 7.5, 7.5, 7.8, 7.4,
                                7.1, 8.3, 8.6, 8.6, 8.6, 7.0, 7.0, 6.7,
                                7.3, 7.2, 7.0, 7.5, 6.6, 7.8, 8.0, 7.0,
                                7.2, 7.2, 7.2, 7.2, 7.6, 7.6, 7.6, 7.4,
                                7.6, 7.6, 7.2, 7.6, 9.4, 7.8, 7.4, 7.6,
                                6.2, 7.0, 8.0, 7.6, 7.6, 7.6, 7.3, 7.3,
                                7.3, 7.3, 7.3, 7.6, 7.2, 7.2)
           leaflet(mapStates) %>%
                addTiles() %>%
                addPolygons(color = "#444444",
                            weight = 1,
                            layer = ~mapStates$names,
                            smoothFactor = 0.5,
                            opacity = 1.0,
                            fillOpacity = 0.5,
                            fillColor = terrain.colors(50, alpha = 1),
                            highlightOptions = highlightOptions(color = "black",
                                                                weight = 2,
                                                                bringToFront = TRUE))
       })
       # Observe click on shapes (i.e., states)
       observe({
            click <- input$livemap_shape_click
            if(is.null(click))
                 return()
            idx <- which(mapStates$names == click$id)
            # Get zoom level for the state
            z <- mapStates$zoom[[idx]]
            # Get state name to render new map
            idx <- mapStates$names[[idx]]
            mapInd <- map("county", idx, fill = TRUE, plot = FALSE)

            leafletProxy("livemap") %>%
                 clearShapes() %>%
                 addPolygons(data = mapInd,
                             color = "#444444",
                             weight = 1,
                             smoothFactor = 0.5,
                             opacity = 1.0,
                             fillOpacity = 0.5,
                             fillColor = terrain.colors(10, alpha = 1)) %>%
                 setView(lng = ((mapInd$range[[1]] + mapInd$range[[2]])/2),
                         lat = ((mapInd$range[[3]] + mapInd$range[[4]])/2),
                         zoom = z)
       })
       # Observe click outside of shapes (i.e., reset the map to the "USA" original)
       observe({
            click <- input$livemap_click
            if(is.null(click))
                 return()
            leafletProxy("livemap") %>%
                 clearShapes() %>%
                 addPolygons(data = mapStates,
                             color = "#444444",
                             weight = 1,
                             layer = ~mapStates$names,
                             smoothFactor = 0.5,
                             opacity = 1.0,
                             fillOpacity = 0.5,
                             fillColor = terrain.colors(50, alpha = 1),
                             highlightOptions = highlightOptions(color = "black",
                                                                 weight = 2,
                                                                 bringToFront = TRUE)) %>%
                 setView(lng = ((mapStates$range[[1]] + mapStates$range[[2]])/2),
                         lat = ((mapStates$range[[3]] + mapStates$range[[4]])/2),
                         zoom = 4)
       })

  })
库(闪亮)
图书馆(单张)
图书馆(地图)
shinyServer(功能(输入、输出){
输出$livemap%
添加多边形(颜色=“#4444”,
重量=1,
平滑因子=0.5,
不透明度=1.0,
填充不透明度=0.5,
填充颜色=地形颜色(50,alpha=1),
highlightOptions=highlightOptions(color=“black”,weight=2,bringToFront=TRUE))
})
观察({

点击@johnfreel建议的展开,您可以通过为每个状态设置缩放级别,然后使用点击获得该缩放级别来实现

为此,您需要指定
layerId
值(在
addPolygons中)
,以便传单知道您单击了哪个形状。然后您可以从此id访问
zoom

请参阅我添加到代码中的注释以了解更改

library(shiny)
library(leaflet)
library(maps)

ui <- shinyUI(fluidPage(
    fluidRow(
        tags$style(type = "text/css", "#livemap {height: calc(100vh - 80px) !important;}"),
        leafletOutput("livemap")
    )
))


server <- shinyServer(function(input, output){
    output$livemap <- renderLeaflet({
        mapStates <- map("state", fill = TRUE, plot = FALSE)

        ## chuck on a zoom
        mapStates$zoom <- sample(5:8, size = length(mapStates$name), replace = T)

        leaflet(mapStates) %>%
            addTiles() %>%
            addPolygons(color = "#444444",
                                    weight = 1,
                                    layerId = ~mapStates$name,   ## LayerID defined
                                    smoothFactor = 0.5,
                                    opacity = 1.0,
                                    fillOpacity = 0.5,
                                    fillColor = terrain.colors(50, alpha = 1),
                                    highlightOptions = highlightOptions(color = "black", weight = 2, 
                                                                                                            bringToFront = TRUE))
    })

    observe({
        click <- input$livemap_shape_click
        if(is.null(click))
            return()

        ## use the click to access the zoom and set the view according to these
        ## the click$id is now returned with the 'name' of the state
        ## because we specified it in the LayerId argument
        idx <- which(mapStates$name == click$id)
        z <- mapStates$zoom[[idx]]

        leafletProxy("livemap") %>% 
            setView(lng = click$lng, lat = click$lat, zoom = z)
    })
})

shinyApp(ui, server)
库(闪亮)
图书馆(单张)
图书馆(地图)

ui多亏了@symbolxau和@johnfrieel,我才能够实现我想要的功能。关键是设置“层”ID。下面的代码允许我缩放到每个状态的适当级别。此外,当用户在形状区域之外单击时,地图将恢复为默认的“美国”地图和缩放级别

用户界面

服务器.R

 library(shiny)
 library(leaflet)
 library(maps)

 shinyServer(function(input, output){
      output$livemap <- renderLeaflet({
          mapStates <- map("state", fill = TRUE, plot = FALSE)

          leaflet(mapStates) %>%
               addTiles() %>%
               addPolygons(color = "#444444",
                           weight = 1,
                           smoothFactor = 0.5,
                           opacity = 1.0,
                           fillOpacity = 0.5,
                           fillColor = terrain.colors(50, alpha = 1),
                           highlightOptions = highlightOptions(color = "black", weight = 2, bringToFront = TRUE))
      })
      observe({
           click <- input$livemap_shape_click
           proxy <- leafletProxy("livemap")
           if(is.null(click))
                return()
           proxy %>% setView(lng = click$lng, lat = click$lat, zoom = 7)
      })
 })
  library(shiny)
  library(leaflet)
  library(maps)

  shinyServer(function(input, output){
       output$livemap <- renderLeaflet({
            mapStates <- map("state", fill = TRUE, plot = FALSE)
            mapStates$zoom <- c(7.3, 7.1, 7.5, 6.2, 7.2, 9.2, 4.0, 7.0,
                                7.3, 6.5, 7.0, 7.4, 7.5, 7.5, 7.8, 7.4,
                                7.1, 8.3, 8.6, 8.6, 8.6, 7.0, 7.0, 6.7,
                                7.3, 7.2, 7.0, 7.5, 6.6, 7.8, 8.0, 7.0,
                                7.2, 7.2, 7.2, 7.2, 7.6, 7.6, 7.6, 7.4,
                                7.6, 7.6, 7.2, 7.6, 9.4, 7.8, 7.4, 7.6,
                                6.2, 7.0, 8.0, 7.6, 7.6, 7.6, 7.3, 7.3,
                                7.3, 7.3, 7.3, 7.6, 7.2, 7.2)
           leaflet(mapStates) %>%
                addTiles() %>%
                addPolygons(color = "#444444",
                            weight = 1,
                            layer = ~mapStates$names,
                            smoothFactor = 0.5,
                            opacity = 1.0,
                            fillOpacity = 0.5,
                            fillColor = terrain.colors(50, alpha = 1),
                            highlightOptions = highlightOptions(color = "black",
                                                                weight = 2,
                                                                bringToFront = TRUE))
       })
       # Observe click on shapes (i.e., states)
       observe({
            click <- input$livemap_shape_click
            if(is.null(click))
                 return()
            idx <- which(mapStates$names == click$id)
            # Get zoom level for the state
            z <- mapStates$zoom[[idx]]
            # Get state name to render new map
            idx <- mapStates$names[[idx]]
            mapInd <- map("county", idx, fill = TRUE, plot = FALSE)

            leafletProxy("livemap") %>%
                 clearShapes() %>%
                 addPolygons(data = mapInd,
                             color = "#444444",
                             weight = 1,
                             smoothFactor = 0.5,
                             opacity = 1.0,
                             fillOpacity = 0.5,
                             fillColor = terrain.colors(10, alpha = 1)) %>%
                 setView(lng = ((mapInd$range[[1]] + mapInd$range[[2]])/2),
                         lat = ((mapInd$range[[3]] + mapInd$range[[4]])/2),
                         zoom = z)
       })
       # Observe click outside of shapes (i.e., reset the map to the "USA" original)
       observe({
            click <- input$livemap_click
            if(is.null(click))
                 return()
            leafletProxy("livemap") %>%
                 clearShapes() %>%
                 addPolygons(data = mapStates,
                             color = "#444444",
                             weight = 1,
                             layer = ~mapStates$names,
                             smoothFactor = 0.5,
                             opacity = 1.0,
                             fillOpacity = 0.5,
                             fillColor = terrain.colors(50, alpha = 1),
                             highlightOptions = highlightOptions(color = "black",
                                                                 weight = 2,
                                                                 bringToFront = TRUE)) %>%
                 setView(lng = ((mapStates$range[[1]] + mapStates$range[[2]])/2),
                         lat = ((mapStates$range[[3]] + mapStates$range[[4]])/2),
                         zoom = 4)
       })

  })
库(闪亮)
图书馆(单张)
图书馆(地图)
shinyServer(功能(输入、输出){

输出$livemap这只是一个想法:创建一个名为
zoomize
的新列,并使您的
zoom=单击$zoomize
。可能必须手动输入数据(如果只有50行输入数据,这似乎不太困难)。每个州都会有一个特定的缩放。谢谢你的建议!我会尝试一下。我想,理想情况下,我希望检索该缩放所需的信息以用于其他目的,但我可能会找到其他解决方法。谢谢!传单似乎不喜欢这样。按照你建议中的步骤,leaf让我们转到全局缩放视图。回到绘图板!这确实实现了@johnfreel提出的答案。一些小而琐碎的编辑:“layerID”应该是“layer”,而“mapStates$name”应该是“mapStates$name”。这也让我知道了如何通过缩放到每个状态的边界来实现我的最终目标。谢谢!@sehock你确定它应该是
?addPolygons
的参数列表显示它是
是。
对我不起作用,但
对我有效。我的包都是最新版本,我正在为Linux使用
R版本3.2.5