Shiny应用中拖动标记/圆形后获取坐标并显示为表格的问题
解决Shiny中Leaflet拖动标记/圆形获取坐标并显示表格的问题
一、拖动标记(Marker)后显示坐标表格
核心是用reactiveValues存储实时坐标,再通过renderTable渲染成表格。你之前用observe能监听到坐标,说明事件捕获没问题,只是没把数据存好用于渲染。
完整可运行代码:
library(shiny) library(leaflet) ui <- fluidPage( leafletOutput("map"), h3("标记当前坐标"), tableOutput("marker_coords") ) server <- function(input, output, session) { # 初始化响应式变量存坐标 marker_pos <- reactiveValues(lat = NULL, lng = NULL) output$map <- renderLeaflet({ leaflet() %>% addTiles() %>% # 添加可拖动标记,初始位置设为北京 addMarkers(lng = 116.4074, lat = 39.9042, options = markerOptions(draggable = TRUE)) }) # 监听标记拖动结束事件,更新坐标 observeEvent(input$map_marker_dragend, { marker_pos$lat <- input$map_marker_dragend$lat marker_pos$lng <- input$map_marker_dragend$lng }) # 渲染坐标表格 output$marker_coords <- renderTable({ if (!is.null(marker_pos$lat)) { data.frame( 维度 = c("纬度(Lat)", "经度(Lng)"), 坐标值 = c(marker_pos$lat, marker_pos$lng) ) } else { data.frame( 维度 = c("纬度(Lat)", "经度(Lng)"), 坐标值 = c("未拖动标记", "未拖动标记") ) } }) } shinyApp(ui, server)
input$map_marker_dragend是Leaflet内置的拖动结束事件,拿到坐标后存到reactiveValues里,再用renderTable把数据转成表格展示。
二、拖动圆形(Circle)获取坐标
Leaflet的addCircles默认没有内置的拖动结束事件输入,得自己写JS代码把坐标传给Shiny。关键是在addCircles的options里添加onDragend事件,用Shiny.setInputValue把坐标发送到Shiny的input对象中。
完整扩展代码(包含标记和圆形的处理):
library(shiny) library(leaflet) ui <- fluidPage( leafletOutput("map"), h3("标记当前坐标"), tableOutput("marker_coords"), h3("圆形当前坐标"), tableOutput("circle_coords") ) server <- function(input, output, session) { # 初始化响应式变量存坐标 marker_pos <- reactiveValues(lat = NULL, lng = NULL) circle_pos <- reactiveValues(lat = NULL, lng = NULL) output$map <- renderLeaflet({ leaflet() %>% addTiles() %>% # 添加可拖动标记 addMarkers(lng = 116.4074, lat = 39.9042, options = markerOptions(draggable = TRUE)) %>% # 添加可拖动圆形,自定义拖动事件 addCircles(lng = 116.5, lat = 39.9, radius = 500, options = circleOptions( draggable = TRUE, # JS代码:拖动结束时把坐标传给Shiny onDragend = JS("function(e) { Shiny.setInputValue('circle_dragend', {lat: e.target.getLatLng().lat, lng: e.target.getLatLng().lng}, {priority: 'event'}); }") )) }) # 监听标记拖动 observeEvent(input$map_marker_dragend, { marker_pos$lat <- input$map_marker_dragend$lat marker_pos$lng <- input$map_marker_dragend$lng }) # 监听圆形拖动 observeEvent(input$circle_dragend, { circle_pos$lat <- input$circle_dragend$lat circle_pos$lng <- input$circle_dragend$lng }) # 渲染标记坐标表格 output$marker_coords <- renderTable({ if (!is.null(marker_pos$lat)) { data.frame( 维度 = c("纬度(Lat)", "经度(Lng)"), 坐标值 = c(marker_pos$lat, marker_pos$lng) ) } else { data.frame( 维度 = c("纬度(Lat)", "经度(Lng)"), 坐标值 = c("未拖动标记", "未拖动标记") ) } }) # 渲染圆形坐标表格 output$circle_coords <- renderTable({ if (!is.null(circle_pos$lat)) { data.frame( 维度 = c("纬度(Lat)", "经度(Lng)"), 坐标值 = c(circle_pos$lat, circle_pos$lng) ) } else { data.frame( 维度 = c("纬度(Lat)", "经度(Lng)"), 坐标值 = c("未拖动圆形", "未拖动圆形") ) } }) } shinyApp(ui, server)
这里通过Shiny.setInputValue将JS中获取的圆形坐标,转换成Shiny可识别的input$circle_dragend对象,后续处理逻辑和标记完全一致。
内容的提问来源于stack exchange,提问作者Haribo
相关产品推荐
相关产品推荐

