markercluster 是否与 LeafletProxy() 和选项 iconCreateFunction 一起使用?

我做错了什么,或者为什么下面的例子不起作用?我正在尝试使用选项 iconCreateFunction 使 Leaflet markercluster 插件在 R Shiny 应用程序中与 leafletProxy() 一起使用.插件是否无法使用 leafletProxy() 向地图添加自定义图标标记?

当我按下第一个按钮并在下面的示例中缩小时,我收到一条错误消息:

<块引用>

TypeError: this._group.options.iconCreateFunction 不是函数

我尝试从 markercluster 复制

解决方案

修改方案

iconCreateFunction 的行为在 leafletProxy 中使用时绝对是 flakey.虽然我认为某些浏览器中存在缓存,因此难以直观地跟踪.

为了消除您遇到的 javascript 错误,应用 layerIdclusterId 值以及使用 removeMarker 代替 clearMarkers.

<块引用>

注意我的解决方案的一个奇怪的副作用是重新绘制时会掉下一个标记,我有点累了,稍后再看看.这个问题可能是微不足道的,也可能不是微不足道的.

app.R

库(闪亮)图书馆(dplyr)图书馆(传单)ui <-流体页面(titlePanel("你好闪亮!"),侧边栏布局(侧边栏面板(actionButton(inputId = "my_button1",label = "使用leafletProxy()"),actionButton(inputId = "my_button2",label = "使用 renderLeaflet()")),主面板(传单输出(outputId = "我的地图",宽度 = "100%",高度 = "300 像素"))))服务器 <- 功能(输入,输出,会话){some_data <- data.frame(lon = c(4.905167, 4.906357, 4.905831),纬度 = c(52.37712, 52.37783, 52.37755),number_var = c(5, 9, 7),名称 = c(简"、哈罗德"、迈克")、字符串AsFactors = FALSE)marker_js <- JS("函数(簇){var html = '<div 样式="背景色:rgba(77,77,77,0.5)"><span>'+ cluster.getChildCount() + '</div><span>'return new L.DivIcon({html: html, className: 'marker-cluster'});}")output$mymap <- renderLeaflet({传单(一些数据)%>%addProviderTiles(providers$CartoDB.Positron) %>%适合边界(〜分钟(经度),〜分钟(纬度),〜最大(经度),〜最大(纬度))%>%添加标记(layerId = "我的图层",clusterId = "我的集群",lng = ~lon,纬度=〜纬度,clusterOptions = markerClusterOptions(iconCreateFunction = marker_js))})观察事件(输入$my_button1,{leafletProxy("mymap", data = some_data) %>%removeMarker(layerId = "mylayer") %>%清除瓷砖 %>%addProviderTiles(providers$CartoDB.Positron) %>%适合边界(〜分钟(经度),〜分钟(纬度),〜最大(经度),〜最大(纬度))%>%添加标记(layerId = "我的图层",clusterId = "我的集群",lng = ~lon,纬度=〜纬度,clusterOptions = markerClusterOptions(iconCreateFunction = marker_js))})观察事件(输入$my_button2,{output$mymap <- renderLeaflet({传单(一些数据)%>%addProviderTiles(providers$CartoDB.Positron) %>%适合边界(〜分钟(经度),〜分钟(纬度),〜最大(经度),〜最大(纬度))%>%添加标记(layerId = "我的图层",clusterId = "我的集群",lng = ~lon,纬度=〜纬度,clusterOptions = markerClusterOptions(iconCreateFunction = marker_js))})})}闪亮应用(用户界面 = 用户界面,服务器 = 服务器)

浏览器内

<块引用>

没有发现其他 javascript 错误.

Am I doing something wrong, or why does the below example not work? I am trying to make leaflet markercluster plugin work with leafletProxy() in an R Shiny app, using the option iconCreateFunction. Is the plugin not capable of adding customized icon markers to the map using leafletProxy()?

When I press the first button and zoom out in below example, I get an error saying:

TypeError: this._group.options.iconCreateFunction is not a function

I tried to copy the original example from the markercluster documentation:

library(shiny)
library(dplyr)
library(leaflet)

ui <- fluidPage(
  titlePanel("Hello Shiny!"),
  sidebarLayout(
    sidebarPanel(
      actionButton(inputId = "my_button1",
                   label = "Use leafletProxy()"),
      actionButton(inputId = "my_button2",
                   label = "Use renderLeaflet()")
    ),
    mainPanel(
      leafletOutput(
        outputId = "map",
        width = "100%",
        height = "300px"
      )
    )
  )
)

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

  some_data <- data.frame(
    "lon"=c(4.905167,4.906357,4.905831),
    "lat"=c(52.37712,52.37783,52.37755),
    "number_var"=c(5,9,7),
    "name"=c("Jane","Harold","Mike"),
    stringsAsFactors = F
  )

  output$map <- renderLeaflet({
    return(
      leaflet(data = some_data[0,]) %>%
         addProviderTiles(providers$CartoDB.Positron) %>%
        fitBounds(
          min(some_data$lon),
          min(some_data$lat),
          max(some_data$lon),
          max(some_data$lat)
        ) %>%
        addMarkers(
          lng = ~lon,
          lat = ~lat,
          clusterOptions = markerClusterOptions(
            iconCreateFunction = JS(paste0("function(cluster) {",
                                           "return new L.DivIcon({",
                                           "html: '<div style="background-color:rgba(77,77,77,0.5)"><span>' + cluster.getChildCount() + '</div><span>',",
                                           "className: 'marker-cluster'",
                                           "});",
                                           "}"))



          )
        )
    )
  })

  observeEvent(input$my_button1,{
      leafletProxy(mapId = "map",
                   session = session,
                   data = some_data) %>%
        addProviderTiles(providers$CartoDB.Positron) %>%
        clearMarkerClusters() %>%
        clearMarkers() %>%
        fitBounds(
          min(some_data$lon),
          min(some_data$lat),
          max(some_data$lon),
          max(some_data$lat)
        ) %>%
        addMarkers(
          lng = ~lon,
          lat = ~lat,
          clusterOptions = markerClusterOptions(
            iconCreateFunction = JS(paste0("function(cluster) {",
                                           "console.log('Here comes cluster',cluster); ",
                                           "return new L.DivIcon({",
                                           "html: '<div style="background-color:rgba(77,77,77,0.5)"><span>' + cluster.getChildCount() + '</div><span>',",
                                           "className: 'marker-cluster'",
                                           "});",
                                           "}"))
          )
        )
  })

  observeEvent(input$my_button2,{
    output$map <- renderLeaflet({

      leaflet(data = some_data) %>%
        addProviderTiles(providers$CartoDB.Positron) %>%
        fitBounds(
          min(some_data$lon),
          min(some_data$lat),
          max(some_data$lon),
          max(some_data$lat)
        ) %>%
        addMarkers(
          lng = ~lon,
          lat = ~lat,
          clusterOptions = markerClusterOptions(
            iconCreateFunction = JS(paste0("function(cluster) {",
                                           "console.log('Here comes cluster',cluster); ",
                                           "return new L.DivIcon({",
                                           "html: '<div style="background-color:rgba(77,77,77,0.5)"><span>' + cluster.getChildCount() + '</div><span>',",
                                           "className: 'marker-cluster'",
                                           "});",
                                           "}"))
          )
        )
    })
  })
}

shinyApp(ui = ui, server = server)

Package versions:

dplyr_0.7.4
leaflet_1.1.0
shiny_1.0.5
R version 3.4.3 (2017-11-30)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 16.04.3 LTS

Browser version: Firefox Quantum 57.0.1 (64-bit)

解决方案

Revised solution

The behaviour of iconCreateFunction is definitely flakey when used within leafletProxy. Although I think there is caching in some browsers making it difficult to track visually.

In order to eliminate the javascript error you were experiencing, it is important to apply layerId and clusterId values as well as using removeMarker in lieu of clearMarkers.

N.B. A strange side-effect of my solution is that a marker is dropped when re-drawn, I'm getting a bit tired and will have another look later. That problem may or may not be trivial.

app.R

library(shiny)
library(dplyr)
library(leaflet)

ui <- fluidPage(
  titlePanel("Hello Shiny!"),
  sidebarLayout(
    sidebarPanel(
      actionButton(inputId = "my_button1",
                   label = "Use leafletProxy()"),
      actionButton(inputId = "my_button2",
                   label = "Use renderLeaflet()")
    ),
    mainPanel(
      leafletOutput(
        outputId = "mymap",
        width = "100%",
        height = "300px"
    ))
))

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

  some_data <- data.frame(
    lon = c(4.905167, 4.906357, 4.905831),
    lat = c(52.37712, 52.37783, 52.37755),
    number_var = c(5, 9, 7),
    name = c("Jane", "Harold", "Mike"),
    stringsAsFactors = FALSE
  )

  marker_js <- JS("function(cluster) {
                  var html = '<div style="background-color:rgba(77,77,77,0.5)"><span>' + cluster.getChildCount() + '</div><span>'
                  return new L.DivIcon({html: html, className: 'marker-cluster'});
                  }")

  output$mymap <- renderLeaflet({

    leaflet(some_data) %>%
      addProviderTiles(providers$CartoDB.Positron) %>%
      fitBounds(
        ~min(lon),
        ~min(lat),
        ~max(lon),
        ~max(lat)
      ) %>%
      addMarkers(
        layerId = "mylayer",
        clusterId = "mycluster",
        lng = ~lon,
        lat = ~lat,
        clusterOptions = markerClusterOptions(
          iconCreateFunction = marker_js
        )
      )

  })

  observeEvent(input$my_button1, {

    leafletProxy("mymap", data = some_data) %>%
      removeMarker(layerId = "mylayer") %>%
      clearTiles %>%
      addProviderTiles(providers$CartoDB.Positron) %>%
      fitBounds(
        ~min(lon),
        ~min(lat),
        ~max(lon),
        ~max(lat)
      ) %>%
      addMarkers(
        layerId = "mylayer",
        clusterId = "mycluster",
        lng = ~lon,
        lat = ~lat,
        clusterOptions = markerClusterOptions(
          iconCreateFunction = marker_js
        )
      )

  })

  observeEvent(input$my_button2,{

    output$mymap <- renderLeaflet({

      leaflet(some_data) %>%
        addProviderTiles(providers$CartoDB.Positron) %>%
        fitBounds(
          ~min(lon),
          ~min(lat),
          ~max(lon),
          ~max(lat)
        ) %>%
        addMarkers(
          layerId = "mylayer",
          clusterId = "mycluster",
          lng = ~lon,
          lat = ~lat,
          clusterOptions = markerClusterOptions(
            iconCreateFunction = marker_js
          )
        )
    })

  })

}

shinyApp(ui = ui, server = server)

in-browser

No other javascript errors were noted.

相关文章