I have built a leaflet map in a Shiny application that shows different layers depending on what zoom you have.
I have built this combining leafletProxy
with observeEvent
and leaflet's input$MAPID_zoom
.
server <- shinyServer(function(input, output, session) {
output$map <- renderLeaflet({
leaflet() |>
addTiles() |>
mapOptions(zoomToLimits="first") |>
setView(lat = 47.218637, lng = -1.554136, zoom = 7)
})
observeEvent(
eventExpr = input$map_zoom, {
map_proxy <- leafletProxy(mapId = "map", session = session)
if(input$map_zoom < 8){
map_proxy |>
clearMarkers() |>
addMarkers(
data = df, lng = ~lng, lat = ~lat
)
} else {
map_proxy |>
clearMarkers() |>
addMarkers(
data = df_2, lng = ~lng, lat = ~lat
)
}
}
)
})
However, this rerenders the leaflet map every time the zoom changes. I would like the map to only render when the threshold in the if-statement is surpassed. What would be a way to approach this?
Code for UI and data:
library(shiny)
library(leaflet)
df <- data.frame(
location_name = c('S1', 'S2'),
lng = c(-1.554136, -2.10401),
lat = c(47.218637, 47.218637),
stringsAsFactors = FALSE
)
df_2 <- data.frame(
location_name = c('S3', 'S4'),
lng = c(-1.654136, -2.2401),
lat = c(47.218637, 47.218637),
stringsAsFactors = FALSE
)
ui <- shinyUI(
fluidPage(
leafletOutput(outputId = 'map')
)
)
I can't reproduce your problem but here is a solution. You have to create both layers and play with visibility.
server <- shinyServer(function(input, output, session) {
output$map <- renderLeaflet({
leaflet() |>
addTiles() |>
mapOptions(zoomToLimits="first") |>
setView(lat = 47.218637, lng = -1.554136, zoom = 7) |>
addMarkers(
data = df, lng = ~lng, lat = ~lat, group = "S1S2"
) |>
addMarkers(
data = df_2, lng = ~lng, lat = ~lat, group="S3S4")
})
observeEvent(
eventExpr = input$map_zoom, {
map_proxy <- leafletProxy(mapId = "map", session = session)
if(input$map_zoom < 8){
map_proxy |>
showGroup("S1S2") |>
hideGroup("S3S4")
} else {
map_proxy |>
showGroup("S3S4") |>
hideGroup("S1S2")
}
}
)
})
Here each layer gets a different group id and depending of the zoom level we hide or show corresponding group.