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

求助:Shiny应用上传缺失经纬度值数据时地图崩溃的处理方案

问题解决:Shiny Leaflet应用处理空经纬度数据

问题背景

开发的Shiny应用加载初始Leaflet地图,上传含有效经纬度的数据(如下df1)时可正常绘制标记:

df1 <- data.frame(Category = c("Dining", "Master", "Breakfast", "Hidden"), 
                  latitude = c(28.7041, 19.0760, 12.9716, 17.3850), 
                  longitude = c(77.1025, 72.8777, 77.5946, 78.4867))

但上传含空值经纬度的文件(如下df2)时,应用崩溃并抛出错误:Warning: Error in validateCoords: addCircleMarkers requires numeric longitude/latitude values

df2 <- data.frame(Category = c("Dining", "Master", "Breakfast", "Hidden"), 
                  latitude = c("", "", "", ""), 
                  longitude = c("", "", "", ""))

需求:

  • 上传文件有经纬度列但无数据时,地图保持无标记状态,跳过标记绘制;
  • 显示可关闭的警告提示,告知用户因缺失经纬度信息无法绘制标记,不影响后续操作。

解决方案

1. 数据验证与处理

在读取上传数据后,完成以下验证:

  • 检查经纬度列是否存在;
  • 将经纬度列转换为数值类型,空值自动转为NA;
  • 过滤掉经纬度为NA的无效行,仅保留有效数据用于标记绘制。

2. 添加可关闭警告提示

使用shinyalert包实现可关闭的弹窗警告,当检测到无有效经纬度数据时触发提示。

修改后的完整代码

library(shiny)
library(shinydashboard)
library(leaflet)
library(tidyverse)
library(DT)
library(shinyalert)

ui <- dashboardPage(
  dashboardHeader(title = "Map Data"),
  dashboardSidebar(
    fileInput("file1", "Upload Data file", accept = ".csv")
  ),
  dashboardBody(
    useShinyalert(), # 加载shinyalert依赖
    DT::dataTableOutput("table1"),
    leafletOutput("map1")
  )
)

server <- function(input, output, session) {
  data <- reactive({
    req(input$file1)
    df <- read.csv(input$file1$datapath, header = TRUE, sep = ",", row.names = NULL)
    
    # 验证并转换经纬度列为数值类型
    if(all(c("latitude", "longitude") %in% colnames(df))){
      df <- df %>%
        mutate(across(c(latitude, longitude), as.numeric))
    }
    df
  })
  
  output$table1 <- renderDataTable(data())
  
  # 过滤出含有效经纬度的数据
  mapdata <- reactive({
    req(data())
    data() %>%
      filter(!is.na(latitude) & !is.na(longitude) & !is.nan(latitude) & !is.nan(longitude))
  })
  
  observe({
    # 先清除已有标记
    leafletProxy("map1") %>% clearShapes()
    
    valid_data <- mapdata()
    if(nrow(valid_data) > 0){
      # 有有效数据时绘制标记
      leafletProxy("map1", data = valid_data) %>%
        addCircleMarkers(lng = ~longitude, lat = ~latitude, radius = 8, weight = 1, 
                         color = "blue", fillOpacity = 0.5, label = ~Category,
                         labelOptions = labelOptions(noHide = FALSE, textsize = "15px"))
    } else {
      # 无有效数据时弹出可关闭警告
      shinyalert(
        title = "提示",
        text = "上传数据中无有效经纬度信息,无法绘制标记",
        type = "warning",
        closeOnEsc = TRUE,
        closeOnClickOutside = TRUE
      )
    }
  })
  
  output$map1 <- renderLeaflet({
    leaflet() %>%
      addProviderTiles(providers$Esri.WorldImagery) %>%
      addProviderTiles(providers$Stamen.TonerHybrid) %>%
      setView(100.46, 23, 4)
  })
}

shinyApp(ui, server)

关键修改说明

  • 引入shinyalert包实现可关闭的警告弹窗,不阻塞后续操作;
  • 在data()响应式函数中统一转换经纬度列为数值类型,空值自动转为NA;
  • 新增mapdata()过滤无效数据,仅保留可用于绘制标记的行;
  • 在observe逻辑中判断有效数据行数,动态决定绘制标记或弹出警告;
  • 修复原代码中label = mapdata()$Subsite的错误(原数据无该列,改为Category)。

内容的提问来源于stack exchange,提问作者Sandeep Patil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 14:23:09