Search code examples
rshinyr-leaflet

Remove specific Layers in R Leaflet


My shinyApp is composed of two zone, a map and a chart. You can select an area in the chart which will update data on the map coresponding to the selected chart area. So the map is using an observe and a leafletProxy to add filtered Data so as a ClearMarkers() to remove previous filtered data.

The problem is : I have an other MarkersLayer part of an overlayGroup and which can be displayed by the overlayGroupWidget but it doesn't show up. Why? Due of the ClearMarkers() which remove every markers on the map (T0New and T1New)

So I would like to remove specific layers which are T0New and MapData. I tried removeMarker() and clearGroup() but it didn't worked out...

Any ideas?

Here is an example of my code whith sample data :

library(shiny)
library(leaflet)
library(leaflet.extras)
library(tidyverse)
library(sf)



#Create T0New data
lat <- c(49.823, 58.478, 57.478, 45.823)
lng <- c(-10.854,-10.854,2.021,2.02)
date_start_min <- c(125,135,168,149)
T0New <- data.frame(lat,lng)

#Create T1New data
lat <- c(48.956, 56.356, 57.445, 45.253)
lng <- c(-9.762,-8.884,1.971,2.17)
T1New <- data.frame(lat,lng)

ui <- fluidPage(

              leafletOutput("map", height = "50vh"),
              plotOutput("distribPlot", height = "47vh",
                         brush = brushOpts(id = "distribPlot_brush", direction = "x", resetOnNew = FALSE))
  )


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



  #filtrer les données par attribut du graphique
  filteredGraphData <- reactive({

    noSelection <- TRUE
    currentlyFiltered <- T0New

    if(!is.null(input$distribPlot_brush)){
      thisSel <- input$distribPlot_brush
      currentlyFiltered <- currentlyFiltered %>% 
        filter(date_start_min >= thisSel$xmin, date_start_min <= thisSel$xmax)
      noSelection <- FALSE
    }
    if(!noSelection){
      return(currentlyFiltered)
    }
  })

  #Sortie map
  output$map <- renderLeaflet({
    leaflet()%>%
      addLayersControl(
        position = "bottomright",
        overlayGroups = "T1New",
        options = layersControlOptions(collapsed = F)
      ) %>% 
      hideGroup("T1New") %>% 
      addProviderTiles(providers$CartoDB.Positron) %>% 
      addCircleMarkers(
        lat = T0New$lat,
        lng = T0New$lng,
        radius = 4,
        color = 'red',
        stroke = FALSE,
        fillOpacity = 1
      )%>%
      addCircleMarkers(
        lat = T1New$lat,
        lng = T1New$lng,
        radius = 5,
        color = 'blue',
        stroke = FALSE,
        fillOpacity = 1,
        group = "T1New"
      )
  })

  observe({
    if(length(filteredGraphData()) > 1){
      mapData <- filteredGraphData()
      mapProxy <- leafletProxy("map", session = session, data = c(mapData, T0New))
      mapProxy %>%
        clearMarkers() %>% 
        addCircleMarkers(
          data = T0New,
          lat = T0New$lat,
          lng = T0New$lng,
          radius = 1,
          color = 'black',
          stroke = FALSE,
          fillOpacity = 1
        ) %>%
        addCircleMarkers(
          data = mapData,
          lat = mapData$lat,
          lng = mapData$lng,
          radius = 4,
          color = 'red',
          stroke = FALSE,
          fillOpacity = 1
        )
    }else{
      mapProxy <- leafletProxy("map", session = session, data = T0New)
      mapProxy %>%
        clearMarkers() %>% 
        addCircleMarkers(
          radius = 4,
          color = 'red',
          stroke = FALSE,
          fillOpacity = 1
        )
    }
  })

  #Sortie graph
  output$distribPlot <- renderPlot({

    distribPlot <- ggplot(T0New,aes(date_start_min)) +
      geom_density(col = "#053144", fill = "#43a2ca", alpha = 0.3, adjust = 0.75)

    return(distribPlot)
  })

}

# Create Shiny app ----
shinyApp(ui = ui, server = server)

Solution

  • I finally was able to find a solution : it is in clearGroup() I don't know why it didn't worked in the first place, her it is :

    library(shiny)
    library(leaflet)
    library(leaflet.extras)
    library(tidyverse)
    library(sf)
    
    
    
    #Create T0New data
    lat <- c(49.823, 58.478, 57.478, 45.823)
    lng <- c(-10.854,-10.854,2.021,2.02)
    date_start_min <- c(125,135,168,149)
    T0New <- data.frame(lat,lng)
    
    #Create T1New data
    lat <- c(48.956, 56.356, 57.445, 45.253)
    lng <- c(-9.762,-8.884,1.971,2.17)
    T1New <- data.frame(lat,lng)
    
    ui <- fluidPage(
    
                  leafletOutput("map", height = "50vh"),
                  plotOutput("distribPlot", height = "47vh",
                             brush = brushOpts(id = "distribPlot_brush", direction = "x", resetOnNew = FALSE))
      )
    
    
    server <- function(input, output, session) {
    
    
    
      #filtrer les données par attribut du graphique
      filteredGraphData <- reactive({
    
        noSelection <- TRUE
        currentlyFiltered <- T0New
    
        if(!is.null(input$distribPlot_brush)){
          thisSel <- input$distribPlot_brush
          currentlyFiltered <- currentlyFiltered %>% 
            filter(date_start_min >= thisSel$xmin, date_start_min <= thisSel$xmax)
          noSelection <- FALSE
        }
        if(!noSelection){
          return(currentlyFiltered)
        }
      })
    
      #Sortie map
      output$map <- renderLeaflet({
        leaflet()%>%
          addLayersControl(
            position = "bottomright",
            overlayGroups = "T1New",
            options = layersControlOptions(collapsed = F)
          ) %>% 
          hideGroup("T1New") %>% 
          addProviderTiles(providers$CartoDB.Positron) %>% 
          addCircleMarkers(
            lat = T0New$lat,
            lng = T0New$lng,
            radius = 4,
            color = 'red',
            stroke = FALSE,
            fillOpacity = 1,
            group = 'A'
          )%>%
          addCircleMarkers(
            lat = T1New$lat,
            lng = T1New$lng,
            radius = 5,
            color = 'blue',
            stroke = FALSE,
            fillOpacity = 1,
            group = "T1New"
          )
      })
    
      observe({
        if(length(filteredGraphData()) > 1){
          mapData <- filteredGraphData()
          mapProxy <- leafletProxy("map", session = session, data = c(mapData, T0New))
          mapProxy %>%
            clearGroup('A') %>% 
            addCircleMarkers(
              data = T0New,
              lat = T0New$lat,
              lng = T0New$lng,
              radius = 1,
              color = 'black',
              stroke = FALSE,
              fillOpacity = 1,
              group = 'A'
            ) %>%
            addCircleMarkers(
              data = mapData,
              lat = mapData$lat,
              lng = mapData$lng,
              radius = 4,
              color = 'red',
              stroke = FALSE,
              fillOpacity = 1,
              group = 'reactive'
            )
        }else{
          mapProxy <- leafletProxy("map", session = session, data = T0New)
          mapProxy %>%
            clearGroup('A') %>% 
            addCircleMarkers(
              radius = 4,
              color = 'red',
              stroke = FALSE,
              fillOpacity = 1,
              group = 'A'
            )
        }
      })
    
      #Sortie graph
      output$distribPlot <- renderPlot({
    
        distribPlot <- ggplot(T0New,aes(date_start_min)) +
          geom_density(col = "#053144", fill = "#43a2ca", alpha = 0.3, adjust = 0.75)
    
        return(distribPlot)
      })
    
    }
    
    # Create Shiny app ----
    shinyApp(ui = ui, server = server)