3

I am trying to plot a map with multiple layers. However, when selecting the group I want to show in the controlLayer panel, it changes the map but not the legend. In fact, the 2 legends are always displayed together on the map, but I only want one of them at a time.

Here is the code I use :

leaflet(data) %>%
  addProviderTiles("Esri.WorldStreetMap") %>%
  addRasterImage(r, opacity = 1, colors = cb, group = "Predictions") %>%
  addLegend(pal = cb, values = wind_speed_range, title = "Wind Speed", opacity = 1, group = "Predictions", position = "topright") %>%
  addCircles(radius = ~ residual*7000, color = "black", fillColor = ~ cb(predictions), fillOpacity = 1, label = ~ paste(as.character(residual), " / ", as.character(vitesse_vent), " / ", as.character(predictions)), weight = 2, group = "Predictions") %>%
  addRasterImage(raster_difference, opacity = 1, colors = cb_correction, group = "Corrections") %>%
  addLegend(pal = cb_correction, values = correction_range, title = "Corrections", opacity = 1, group = "Corrections", position = "topright") %>%
  addLayersControl(
    baseGroups = c("Prédictions", "Corrections"),
    options = layersControlOptions(collapsed = FALSE),
    position = "topleft"
  )

As you can see, I already tried the solution of this post. I also tried with overlayGroup instead of baseGroup, but the problem is still here.

The image below is what I get using this code : enter image description here

You can clearly see the two legends.

pietrodito
  • 1,783
  • 15
  • 24
hitaton
  • 103
  • 2
  • 15

1 Answers1

7

Code

Unfortunately, you did not provide a reprex, so I show it with a made up example:

library(leaflet)

cities1 <- data.frame(City = factor(c("Boston", "Hartford", 
                                      "New York City", "Philadelphia", "Pittsburgh", "Providence")),
                      Lat = c(42.3601, 41.7627, 40.7127, 39.95, 40.4397, 41.8236),
                      Long = c(-71.0589, -72.6743, -74.0059, -75.1667, -79.9764, -71.4222), 
                      Pop = c(645966L, 125017L, 8406000L, 1553000L, 305841L, 177994L),
                      Type = factor(c("C", "D", "A", "A", "B", "C")))

cities2 <- data.frame(City = factor(c("Baltimore", "Ithaca", "Wareham")),
                      Lat = c(39.299236, 42.443962, 41.761452), 
                      Long = c(-76.609383, -76.501884, -70.719734), 
                      Pop = c(609032L, 30569L, 22666L),
                      Type = factor(letters[1:3]))




pal1 <- colorFactor("viridis", domain = cities1$Type)
pal2 <- colorFactor("Set1", domain = cities2$Type)

leaflet(cities1) %>% 
   addTiles() %>%
   addCircles(data = cities1, lng = ~Long, lat = ~Lat, weight = 1, group="one",
              radius = ~sqrt(Pop) * 30, popup = ~City, color = ~pal1(Type), opacity = .9
   ) %>%
   addLegend(pal = pal1, values = ~Type, group  = "one", layerId = "one") %>%
   addCircles(data = cities2, lng = ~Long, lat = ~Lat, weight = 1, group = "two",
              radius = ~sqrt(Pop) * 30, popup = ~City, color = ~pal2(Type), opacity = .9
              
   ) %>%
   addLegend(pal = pal2, values = ~Type, data = cities2, group = "two", layerId = "two") %>%
   addLayersControl(
      baseGroups = c("one", "two"),
      options = layersControlOptions(collapsed = FALSE),
      position = "topleft"
   ) %>% 
   htmlwidgets::onRender("
    function() { 
      var map = this;
      var legends = map.controls._controlsById;
      function addActualLegend() {
         var sel = $('.leaflet-control-layers-base').find('input[type=\"radio\"]:checked').siblings('span').text().trim();
         $.each(map.controls._controlsById, (nm) => map.removeControl(map.controls.get(nm)));
         map.addControl(legends[sel]);
      }
      $('.leaflet-control-layers-base').on('click', addActualLegend);
      addActualLegend();
   }")

Explanation

You can define some custom JavaScript which reacts upon the changes of the radio buttons. When they change, I basically delete all controls and add the selected. In order for this to work, I need to save a copy of the controls first. This is of course a bit hackish (especially since I am accessing the "private" _controlsById slot of the map), but from my quick scan of the leaflet API I did not find a better entry point.

Screenshot

Dynamic Legend

thothal
  • 16,690
  • 3
  • 36
  • 71