R Shiny中mapedit的editMod重置问题:绘制多边形无法清除求助
问题描述
- 基于R Shiny开发应用,利用
mapedit包的editMod()工具实现多边形绘制与面积计算功能 - 自定义的Refresh按钮仅能重置表格和Leaflet地图,无法清除已绘制的多边形
- 问题重现:
- 在地图上绘制多边形
- 点击「Calculate area」计算面积
- 点击「Refresh」按钮
- 再次点击「Calculate area」,仍会计算之前绘制的多边形面积——
edits()$finished始终保留旧的绘制数据
- 尝试手动修改
edits()$finished失败,系统提示无法手动更改该对象
解决方案
问题根源在于editMod模块的状态未被正确重置。我们需要通过reactiveValues管理绘制数据,并在Refresh触发时重新初始化模块实例,具体调整如下:
- 用
reactiveValues存储多边形绘制数据,便于重置时直接清空 - 将
editMod的初始化逻辑封装为函数,点击Refresh按钮时重新创建模块实例 - 面积计算逻辑基于
reactiveValues中的数据,确保重置后数据为空
修改后的完整代码
### 加载依赖包 library(dplyr) library(plyr) library(shiny) library(leaflet) library(mapedit) library(sf) library(shinycssloaders) library(leaflet.extras) library(DT) ################# ### 构建UI ### ################# ui<-shinyUI( fluidPage( fluidRow(column(6, align="center", offset = 3, actionButton("refresh", "Refresh", icon=icon("rotate-right")) )), sidebarLayout( # 地图面板 mainPanel( editModUI("map", height=600), ), # 结果面板 sidebarPanel( uiOutput("calc"), conditionalPanel(condition = "input.calc_button >= 1", withSpinner(DT::DTOutput('TableIndex')) ) ) ) ) ) ##################### ### 构建Server ### ##################### server <- function(input, output, session) { # 初始化响应式变量存储绘制数据 draw_data <- reactiveValues(finished = NULL) # 渲染计算按钮 output$calc <- renderUI({ actionButton("calc_button", "Calculate area", icon=icon("arrow-right")) }) # 封装地图编辑模块初始化逻辑 init_map_edit <- function() { Leaf<-leaflet(options = leafletOptions(minZoom = 4)) %>% addTiles(group="OpenStreetMap") %>% addDrawToolbar( polylineOptions = FALSE, polygonOptions = drawPolygonOptions(), circleOptions = FALSE, rectangleOptions = FALSE, markerOptions = FALSE, circleMarkerOptions = FALSE, editOptions=editToolbarOptions(edit=TRUE, remove=TRUE) ) edits <- callModule( editMod, leafmap = Leaf, id = "map" ) # 将模块输出同步到响应式变量 observe({ draw_data$finished <- edits()$finished }) } # 首次初始化地图编辑模块 init_map_edit() # 计算面积并渲染表格 observeEvent(input$calc_button, { req(draw_data$finished) # 确保有绘制数据才执行计算 Area <- st_area(draw_data$finished) %>% as.numeric(.) %>% round(.) output$TableIndex <- DT::renderDataTable({ datatable(data.frame(Index="Area (km2)", Value=Area), options = list(dom = 't'), rownames = FALSE, escape = FALSE) }) }) # 重置应用逻辑 observeEvent(input$refresh, { # 清空表格输出 output$TableIndex <- DT::renderDataTable({data.frame()}) # 清空存储的绘制数据 draw_data$finished <- NULL # 重新初始化地图编辑模块 init_map_edit() }) } ########### ### 运行应用 ### ########### shinyApp(ui = ui, server = server)
内容的提问来源于stack exchange,提问作者Victor Cz
相关产品推荐
相关产品推荐

