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

在Leaflet中能否连续执行两次flyTo方法?相关报错如何解决?

Leaflet地图平滑平移功能报错排查

功能需求

创建Leaflet地图,初始默认位置缩放等级为4渲染,用户点击go按钮后,从下拉选择框选中的起点位置平滑平移到选中的终点位置。

实现效果参考

效果图

问题代码

library(sf)
library(tigris)
library(shiny)
library(shinydashboard)
library(tidyverse)
library(leaflet)

# 数据加载与处理
USA <- st_read(dsn = 'data/cb_2018_us_county_5m.shp')
counties_sf <- st_as_sf(USA)
counties_reproject_sf <- st_transform(counties_sf, 4326) %>% filter(COUNTYFP < 60010)

emp_rate <- read_csv('data/synthetic_emp_rate_pred.csv')
emp_rate$countyfips <- sprintf("%05d", emp_rate$countyfips)
states_sf_coef <- geo_join(counties_reproject_sf, emp_rate, "GEOID", "countyfips", how='inner')

ui <- fluidPage(
  dashboardPage(
    dashboardHeader(title="Employee Rate Data"),
    dashboardSidebar(
      sidebarMenu(
        menuItem(
          "Maps",
          tabName = "maps",
          icon=icon("globe")
        )
      )
    ),
    dashboardBody(
      tabItems(
        tabItem(
          tabName = "maps",
          tags$style(type="text/css","#all_airports {height:calc(100vh - 80px) !important;}"),
          fluidRow(column(4),
                   column(8,
                          selectInput(inputId = "FromCounty",
                                      label="from",
                                      choices=c(unique(emp_rate$countyname)),
                                      selected = 'Travis County, Texas'
                          ),
                          selectInput(inputId = "ToCounty",
                                      label = "to",
                                      choices=c(unique(emp_rate$countyname))
                          ))),
          actionButton("zoomer","go"),
          leafletOutput("map")
          
        )
      )
    )
  )
)

server <- function(input, output, session) {
  
  # 地图渲染
  output$map <- renderLeaflet({
    mypal <- colorNumeric(palette="viridis", domain=states_sf_coef$rand_pred, na.color="transparent")
    
    leaflet() %>%
      addProviderTiles("OpenStreetMap.Mapnik") %>%
      setView(lat = 38.2393,
              lng = -96.3795,
              zoom = 4) %>%
      addPolygons(
        data = states_sf_coef,
        fillColor = ~mypal(rand_pred),
        stroke = FALSE,
        smoothFactor = 0.2,
        fillOpacity = 0.3,
        popup = paste(
          "Region: ",
          states_sf_coef$countyname,
          "<br>",
          "Social Index: ",
          states_sf_coef$rand_pred,
          "<br>"
        )
      )  
  })
  
  map_proxy <- leafletProxy("map")
  
  observeEvent(input$zoomer, {
    # 起点处理
    fromCountyInput <- reactive({
      states_sf_coef %>% dplyr::filter(countyname == input$FromCounty)
    })
    fromData <- fromCountyInput()
    fromCoords <- st_coordinates(st_centroid(fromData$geometry))
    
    # 终点处理
    toCountyInput <- reactive({
      states_sf_coef %>% dplyr::filter(countyname == input$ToCounty)
    })
    toData <- toCountyInput()
    toCoords <- st_coordinates(st_centroid(toData$geometry))
    
    
    map_proxy %>%
      flyTo(lng = fromCoords[1], lat = fromCoords[2], zoom = 10)
      flyTo(lng = toCoords[1], lat = toCoords[2], zoom = 10)
  })
}

# 启动应用
shinyApp(ui = ui, server = server)

报错信息

Warning: Error in dispatch: argument "map" is missing, with no default

问题成因

  1. 核心错误是observeEvent中调用flyTo的链式语法错误:第一次flyTo调用结束后没有补充管道符%>%,导致第二个flyTo没有接收到map_proxy传入的地图对象作为必填参数,触发参数缺失报错。
  2. 隐藏问题:连续调用两次flyTo会导致动画冲突,默认只会生效最后一次飞行,无法实现先定位起点再平移到终点的效果。
  3. 冗余代码:在observeEvent内部嵌套定义reactive表达式属于不必要的写法,会增加额外的响应式开销。

解决方法

直接替换原有observeEvent代码段即可:

observeEvent(input$zoomer, {
  # 直接过滤获取起点数据
  fromData <- states_sf_coef %>% dplyr::filter(countyname == input$FromCounty)
  fromCoords <- st_coordinates(st_centroid(fromData$geometry))
  # 直接过滤获取终点数据
  toData <- states_sf_coef %>% dplyr::filter(countyname == input$ToCounty)
  toCoords <- st_coordinates(st_centroid(toData$geometry))
  
  # 先飞到起点
  map_proxy %>%
    flyTo(lng = fromCoords[1], lat = fromCoords[2], zoom = 10)
  
  # 延迟2秒后飞到终点,避免动画冲突,可根据需求调整延迟时长
  invalidateLater(2000, session)
  map_proxy %>%
    flyTo(lng = toCoords[1], lat = toCoords[2], zoom = 10)
})

如果不需要停留展示起点,直接从当前位置平滑飞到终点,直接保留一次flyTo调用即可:

observeEvent(input$zoomer, {
  toData <- states_sf_coef %>% dplyr::filter(countyname == input$ToCounty)
  toCoords <- st_coordinates(st_centroid(toData$geometry))
  map_proxy %>% flyTo(lng = toCoords[1], lat = toCoords[2], zoom = 10)
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 20:24:03