在Shinydashboard中基于计时器更新传单标记

时间:2018-06-14 05:42:35

标签: r shiny leaflet

我的数据框df有两个变量latlon,现在我需要创建一个Shinydashboard,通过从数据框中获取下一行值来更新地图每10 seconds

df

 df <- data.frame("Lat" = c(12.8882, 12.890, 12.891), "Lon" = c(77.58195,77.58190,77.581958))

Ui.R

library(shiny)
library(leaflet)
shinyUI( fluidPage(
                leafletOutput("map1")
                   )
        )

server.R

library(shiny)

 shinyServer(function(input, output, session) {

 output$mymap <- renderLeaflet({
                      leaflet() %>%
                        addTiles() %>%  # Add default OpenStreetMap map tiles
                        addMarkers(lng=df$lon, lat=df$lat)})
                               })

我唯一知道的是我可以使用invalidateLater()来调用计时器,但我不知道如何实现增量读取数据帧中的行。

Expected Result

我需要一张地图,其中marker在每10 Seconds后移动到下一个位置,移动标记的坐标是通过数据框df给出的。

1 个答案:

答案 0 :(得分:4)

您可以使用reactiveVal()跟踪当前显示的标记,并将observe()invalidateLater()leafletProxy()结合使用,以删除之前的标记并添加新的一个。为此,我们可以在每次添加标记时为图层添加layerId,然后我们可以在绘制下一个标记时再次删除标记。

下面给出了一个工作示例,我添加了一些注释来说明正在发生的事情。希望这有帮助!

enter image description here

library(shiny)
library(leaflet)
set.seed(1)

df <- cbind(rnorm(40) * 2 + 13, rnorm(40) + 48)

ui <- fluidPage(
  leafletOutput("mymap")
)

server <- function(input, output, session) {

  # Create the base map
  output$mymap <- renderLeaflet({
    leaflet() %>%
      addProviderTiles(providers$Stamen.TonerLite,
                       options = providerTileOptions(noWrap = TRUE)
      ) %>%
      setView(lng = mean(rnorm(1000) * 2 + 13), lat =  mean(rnorm(1000) + 48), zoom = 7)
  })

  # Initialize a reactiveVal to keep track of which point is currently selected
  point_to_plot <- reactiveVal(1)

  observe({
    # invalidate every 2 seconds
    invalidateLater(2000)
    isolate({
      # update point_to_plot() to next value. If next value is higher than the amount of rows
      # in df, set it to 1.
      point_to_plot(ifelse(point_to_plot()+1<=nrow(df),point_to_plot()+1,1))
      # Use leafletProxy to remove our previous marker, and add the new one.
      leafletProxy('mymap') %>%
        removeMarker('my_marker') %>%
        addMarkers(layerId = 'my_marker',data = df[point_to_plot(),,drop=F])
    })
  })

}

shinyApp(ui, server)
  

编辑:您的数据的工作示例:

library(shiny)
library(leaflet)
set.seed(1)

df <- data.frame("Lat" = c(12.8882, 12.890, 12.891), "Lon" = c(77.58195,77.58190,77.581958))

ui <- fluidPage(
  leafletOutput("mymap")
)

server <- function(input, output, session) {

  # Create the base map
  output$mymap <- renderLeaflet({
    leaflet() %>%
      addProviderTiles(providers$Stamen.TonerLite,
                       options = providerTileOptions(noWrap = TRUE)
      ) %>%
      setView(lat = 12.89, lng = 77.58195, zoom = 14)
  })

  # Initialize a reactieVal to keep trakc of which point is currently selected
  point_to_plot <- reactiveVal(1)

  observe({
    # invalidate every 2 seconds
    invalidateLater(2000)
    isolate({
      # update point_to_plot() to next value. If next value is higher than the amount of rows
      # in df, set it to 1.
      point_to_plot(ifelse(point_to_plot()+1<=nrow(df),point_to_plot()+1,1))
      # Use leafletProxy to remove our previous marker, and add the new one.
      leafletProxy('mymap') %>%
        removeMarker('my_marker') %>%
        addMarkers(layerId = 'my_marker',data = df[point_to_plot(),,drop=F])
    })
  })

}

shinyApp(ui, server)