如何让Tmap重绘时保持原有视口(中心坐标与缩放级别)?
解决Tmap重绘时保留地图中心与缩放级别的问题
问题核心在于原代码里的map.center和map.zoom是普通变量,不属于响应式状态,所以修改后无法触发renderTmap感知变化,重绘时会复用初始值。只需把这两个变量放到reactiveValues中,让它们的变更能被Shiny的响应式系统捕捉即可,修改后的完整代码如下:
library(shiny) library(tmap) data(World) world_vars <- setdiff(names(World), c("iso_a3", "name", "sovereignt", "geometry")) ui <- fluidPage( tmapOutput("map"), actionButton("randVar", "Random") ) server <- function(input, output, session) { # 将地图中心和缩放级别放到响应式状态中 rv <- reactiveValues( var = 1, map_center = c(lon=-2.460938, lat=54.444492), map_zoom = 4 ) output$map <- renderTmap({ tmap_mode("view") tm_shape(World) + tm_polygons(world_vars[rv$var]) + tm_view(set.view = c(rv$map_center['lon'], rv$map_center['lat'], zoom=rv$map_zoom)) }) ## 监听地图视野变化,更新响应式状态里的中心和缩放 observeEvent(input$map_bounds, { rv$map_zoom <- input$map_zoom rv$map_center['lon'] <- input$map_center[['lng']] rv$map_center['lat'] <- input$map_center[['lat']] print(rv$map_center) print(rv$map_zoom) }) ## 切换随机变量 observeEvent(input$randVar, { rv$var <- sample(1:length(world_vars), 1) }) } shinyApp(ui, server)
关键改动说明:
- 把原本独立的
map.center、map.zoom和var合并到同一个reactiveValues对象rv中,统一管理响应式状态 renderTmap里的tm_view改为引用rv中的响应式变量,这样变量更新时会自动触发地图重绘并使用最新值observeEvent(input$map_bounds)中直接修改rv里的map_zoom和map_center,确保变更能被响应式系统捕获
内容的提问来源于stack exchange,提问作者Polonium
相关产品推荐
相关产品推荐

