我的数据框df
有两个变量lat
和lon
,现在我需要创建一个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
给出的。
答案 0 :(得分:4)
您可以使用reactiveVal()
跟踪当前显示的标记,并将observe()
与invalidateLater()
和leafletProxy()
结合使用,以删除之前的标记并添加新的一个。为此,我们可以在每次添加标记时为图层添加layerId
,然后我们可以在绘制下一个标记时再次删除标记。
下面给出了一个工作示例,我添加了一些注释来说明正在发生的事情。希望这有帮助!
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)