You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny使用leafletProxy添加分类图标报错:metaData不适用于NULL对象

问题:LeafletProxy中使用awesomeIconList报错no applicable method for 'metaData' applied to an object of class "NULL"

背景信息

我尝试给地图标记按分类添加不同图标,已通过以下代码获取分类:

category <- data() %>%
  dplyr::select(category) %>%
  distinct()

分类示例:

$ category: chr "Traffic" "Livelihood" "Waste" ....

同时定义了对应分类的图标列表:

logos <- awesomeIconList(
  "Pothole" = makeAwesomeIcon(
    icon = "road",
    markerColor = "black"
  ),
  "Garbage Collection" = makeAwesomeIcon(
    icon = "trash",
    markerColor = "green"
  ),
  "Air Quality" = makeAwesomeIcon(
    icon = "cloud",
    markerColor = "blue"
  )
)

此前在renderLeaflet函数中该逻辑可正常运行,但将逻辑移至observe函数并使用leafletProxy后出现报错:Error in UseMethod: no applicable method for 'metaData' applied to an object of class "NULL"

相关observe代码如下:

observe({
    filtered_data <- bqdata() %>%
      dplyr::filter(
        if ("All" %in% input$category) {
          category != ""
        } else {
          category %in% input$category
        }
      )
    
    proxy <- leafletProxy("layer_data")
    if (input$cluster) {
      proxy %>% addAwesomeMarkers(
        lat = filtered_data$lat,
        icon = ~logos[category],
        lng = filtered_data$long,
        popup = paste0(
          "<b>Title: </b>", filtered_data$title, "<br>",
          "<b>Type: </b>", filtered_data$type, "<br>",
          "<b>Category: </b>", filtered_data$category, "<br>",
          "<b>Status: </b>", filtered_data$status, "<br>",
          "<b>Description: </b>", filtered_data$description, "<br>",
          "<b>Address: </b>", filtered_data$address, "<br>",
          "<b>City Name: </b>", filtered_data$city, "<br>",
          "<b>State Name: </b>", filtered_data$state, "<br>"
        ),
        clusterOptions = markerClusterOptions()
      )
    } else {
      proxy %>% clearMarkerClusters()
    }
  })

报错原因&修复方案

这个错误的核心是leafletProxy没有正确绑定数据上下文,且缺少空数据判断,具体修复点如下:

  1. 必须通过data参数传入filtered_data,公式语法才能正确解析变量
  2. 每次更新前先清除旧标记,避免残留内容导致冲突
  3. 空数据时跳过添加标记操作,防止触发报错
  4. 补充清除普通标记的逻辑,避免非集群标记残留

修复后的代码

observe({
  filtered_data <- bqdata() %>%
    dplyr::filter(
      if ("All" %in% input$category) {
        !is.na(category) & category != ""
      } else {
        category %in% input$category
      }
    )
  
  proxy <- leafletProxy("layer_data")
  
  # 先清除所有旧标记和集群
  proxy %>% clearMarkers() %>% clearMarkerClusters()
  
  if (input$cluster && nrow(filtered_data) > 0) {
    proxy %>% addAwesomeMarkers(
      data = filtered_data,  # 关键:传入数据绑定上下文
      lat = ~lat,
      lng = ~long,
      icon = ~logos[category],  # 现在可正确解析category变量
      popup = ~paste0(
        "<b>Title: </b>", title, "<br>",
        "<b>Type: </b>", type, "<br>",
        "<b>Category: </b>", category, "<br>",
        "<b>Status: </b>", status, "<br>",
        "<b>Description: </b>", description, "<br>",
        "<b>Address: </b>", address, "<br>",
        "<b>City Name: </b>", city, "<br>",
        "<b>State Name: </b>", state, "<br>"
      ),
      clusterOptions = markerClusterOptions()
    )
  }
})

关键修改说明

  • 添加data = filtered_data:让leafletProxy识别公式中的变量,解决上下文缺失问题
  • 前置clearMarkers()和clearMarkerClusters():彻底清除旧内容,避免新旧标记冲突
  • 增加nrow(filtered_data) > 0判断:空数据时不执行添加逻辑,直接跳过
  • 弹窗改用公式语法~paste0(...):贴合leaflet数据流逻辑,避免直接引用列名的上下文问题
  • 优化筛选条件:增加!is.na(category),避免空值导致的筛选异常

内容的提问来源于stack exchange,提问作者Siddhant Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 19:36:31