【问题标题】:How to set Leaflet layerId using mapview如何使用 mapview 设置 Leaflet layerId
【发布时间】:2018-09-21 03:17:18
【问题描述】:

在我闪亮的应用程序中,我想单击我的 mapview 地图的多边形,并能够使用 input$map_shape_click 将 layerId 属性提取到变量中。在以下代码中,当您单击多边形时,它会打印出 id,但在 mapview 中默认设置为 null。

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

ui <- bootstrapPage(
  title = "Standardized Crop Production Index",
  tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
  mapview::mapviewOutput("map", width = "100%", height = "100%")
)

data("World") #from the tmap library

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

  out_plot <- observeEvent(input$map_shape_click, {
    p <- input$map_shape_click
    print(p)
  })

  output$map <- renderLeaflet({

    test <- mapview(World)
    test@map
  })
}

shinyApp(ui = ui, server = server)

有没有办法设置 mapview 对象的 layerId?我知道如果我只使用 Leaflet 而不是 mapview,我可以使用 addPolygons() 设置它。但是,我最终想使用通过单击多边形收集的数据作为 mapview 的popupGraph() 的输入。

如果有一种方法可以从单击多边形时弹出的表中检索属性,那就更好了。比如我点击南极洲,弹出如下属性表:Antarctica Attribute Table。有没有办法在单击多边形时检索“名称”属性并将其存储为变量?

谢谢!

【问题讨论】:

    标签: r shiny leaflet


    【解决方案1】:

    不完全确定您的第一个问题,因为我不知道可以使用 mapview() 分配的任何方式。但是,这是使用addPolygons() 的可重现解决方案:

    library(dplyr)
    library(shiny)
    library(leaflet)
    library(leaflet.extras)
    library(rgdal)
    library(sp)
    library(tigris)
    library(htmltools)
    
    setwd(dirname(rstudioapi::getActiveDocumentContext()$path))  # set your working directory
    
    philly <- tracts(state = 'PA', county = c('Philadelphia'))
    
    ui <- fluidPage(
      title = "Test Map",
      leafletOutput("mymap", width = 600)
    )
    
    
    server <- function(input, output, session) {
    
      RV <- reactiveValues(Clicks=list()) # used for storing leaflet variables
    
      tract_labels <- sprintf( # labels for mouseover tooltip
        "<strong>%s</strong>, <strong>%s</strong>
        <br/><b>Land Area:</b> %s",
        philly$COUNTYFP,
        philly$STATEFP,
        philly$ALAND
      ) %>% lapply(htmltools::HTML)
    
    
      output$mymap <- renderLeaflet({  # leaflet map
        leaflet(data = philly) %>%
          setView(-75.16, 39.9523, zoom = 10) %>%
          addTiles(urlTemplate = "https://{s}.tile.openstreetmap.se/hydda/full/{z}/{x}/{y}.png",
                   attribution = NULL) %>%
          addPolygons(data = philly,
                      layerId = philly@data$ALAND,
                      group = "regions",
                      fillColor = "#bdd7e7",
                      weight = 1,
                      opacity = 1.0, 
                      fillOpacity = 0.5,
                      smoothFactor = 0.5,
                      label = tract_labels,
                      labelOptions = labelOptions(
                        style = list("font-weight" = "normal", padding = "3px 8px"),
                        textsize = "12px",
                        direction = "auto"),
                      highlightOptions = highlightOptions(color = "white",
                                                          weight = 2,
                                                          bringToFront = TRUE))
      })
    
    
      observeEvent({input$mymap_shape_click}, {
    
        #create object for clicked polygon
        click <- input$mymap_shape_click
        RV$Clicks <- c(RV$Clicks,click$id)
    
        #define leaflet proxy for second regional level map
        proxy <- leafletProxy("mymap")
    
        #subset regions shapefile by the clicked on polygons
        selectedReg <- philly[philly@data$ALAND == click$id,]
    
        #map clicked on polygons
        proxy %>% addPolygons(data = selectedReg,
                              fillColor = "red",
                              fillOpacity = 1,
                              weight = 1,
                              color = "black",
                              stroke = T,
                              group = "selected",
                              layerId = selectedReg@data$ALAND)
    
        # remove polygon group that are clicked twice
        if(click$group == "selected"){
          proxy %>%
            clearGroup(group = "selected")
    
          RV$Clicks <- 0  # resets values if polygons are clicked twice
        }
    
        mean.land <- mean(as.numeric(RV$Clicks))  # stores the values of polygons that are clicked
        print(mean.land)
    
      })
    
    
    }
    
    shinyApp(ui, server)
    

    基本上地图有两层:基本区域层和另一个区域多边形,突出显示您单击的内容。您可以单击每个多边形以从每个多边形中“检索”一个值(在本例中为土地面积或变量 ALAND)并对其进行计算。这里我选择了三个多边形,并使用了mean.land 变量来显示所有三个的平均土地面积。

    reactiveValues RV 对象用于在您单击的任何多边形上存储 layerId 变量的数值。这允许您存储和“检索”它以用于您可能想要进行的其他计算。

    [1] 717210  # first click, first value
    [1] 571940  # second click, averaged value
    [1] 488678.3  # third click, averaged value
    

    您可以通过更改代码中对变量 ALAND 的任何引用来更改提取 layerId 属性。

    【讨论】:

      【解决方案2】:

      有点晚了,但可以在地图视图中设置layerId。 mapview 将通过... 参数(包括layerId)将任何其他(有效)参数传递给相应的传单函数。唯一的区别是您不能将公式表示法与 mapview 一起使用,因为它只会将几何部分传递给(在这种情况下)addPolygons。因此,在评估公式时,几何图形没有附加数据,因此它失败了。但是,您可以将相应的向量传递给layerId

      综上所述,以下应该在input$map_shape_click上返回layerId

      library(shiny)
      library(tmap)
      library(leaflet)
      library(mapview)
      
      ui <- bootstrapPage(
        title = "Standardized Crop Production Index",
        tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
        mapview::mapviewOutput("map", width = "100%", height = "100%")
      )
      
      data("World") #from the tmap library
      
      server <- function(input, output, session) {
      
        out_plot <- observeEvent(input$map_shape_click, {
          p <- input$map_shape_click
          print(p)
        })
      
        output$map <- renderLeaflet({
      
          test <- mapview(World, layerId = World$iso_a3)
          test@map
        })
      }
      
      shinyApp(ui = ui, server = server)
      

      【讨论】:

        猜你喜欢
        • 2016-11-18
        • 2011-08-07
        • 1970-01-01
        • 1970-01-01
        • 2021-08-08
        • 2011-04-05
        • 1970-01-01
        • 2014-05-22
        • 1970-01-01
        相关资源
        最近更新 更多