2

I have a Shiny app with a Leaflet map filled with various elements : polygons, polylines, markers ... The dataframe containing the elements to display on the map is obtained by querying a database. Everytime the user moves on the map (left, right, up, down, zoom, unzoom), the dataframe is changed.

The question here is : how to display only the elements that are in the dataframe without :

  • removing all the previous displayed elements (so no use of clearGroup() or similar functions)
  • keeping in memory the previous dataframe

I cannot use a removeShape() because I cannot know what elements were in the dataframe and are not anymore after the user moves.

An idea I have to solve this problem is to find a way to obtain the values of the IDs (layerId) of all elements displayed on the map, and then remove all of them that are not in the current dataset. But is this possible to obtain somewhere the information of all the IDs of the currently displayed elements on the map ?

Or another idea would be to use a function that does the opposite of removeShape() ( = remove all shapes except the one whose IDs are passed in argument) but I don't know if such a function exists ?

Here is a little reprex example. I have a shiny app with markers. If I click on a button, I remove 3 markers from my dataset. I want them to be removed from the map, but without clearing all other markers.

library(shiny)
library(leaflet)

data("quakes")
df <- quakes
df$id <- 1:nrow(df)

markers_to_remove <- c(159, 15, 888)

ui <- fluidPage(
           leafletOutput("map"),
           actionButton("btn", "Remove markers")
)

server <- function(input, output, session) {
    
df <- reactiveValues(markers = df)

# Init map
output$map <- renderLeaflet({
    leaflet() %>%
        addProviderTiles(provider = providers$CartoDB.Positron) %>%
        setView(lat = -20.9, lng =  169.84, zoom = 8)
})

# Display markers data
# I need to avoid the markers "blink" produced by clearMarkers()
# But I need to not display anymore the markers that are not in 
# df$markers anymore
observe({
    leafletProxy("map") %>%
        # clearMarkers() %>% # 
        addMarkers(
            data = df$markers,
            layerId = ~id,
            label = ~id
        )
})

# Delete clicked marker from data
observeEvent(input$btn,{
    # I get my data from a query and I cannot know which markers
    # were in the dataframe and are not anymore
    new_markers_from_query <- df$markers[!(df$markers$id %in% markers_to_remove),]
    df$markers <- new_markers_from_query

})

}
shinyApp(ui = ui, server = server)
gdevaux
  • 2,308
  • 2
  • 10
  • 19

1 Answers1

1

Addressing

is this possible to obtain somewhere the information of all the IDs of the currently displayed elements on the map ?

We may retrieve the bounds with input$map_bounds, and infer IDs accordingly.

Aurèle
  • 12,545
  • 1
  • 31
  • 49
  • 2
    There are answers that deal with retrieving markers in current bounds directly in JS at https://stackoverflow.com/questions/22081680/get-a-list-of-markers-layers-within-current-map-bounds-in-leaflet – Aurèle Nov 25 '20 at 19:08