0

I am trying to change the base layer in my Shiny App in a programatic way. Since I don't want to use the LayerControl of 'Leaflet' and rather want to have all the controls in one panel. I decided to use shinyjs and go with the toggleState for a button to switch forth and back between two base layers.

At the moment I am in the phase to figure out the principles of changing the base layer, and since there can be only one base layer visible it seem like I have to remove the tiles of the initially loaded base layer.

Doing so I can change the base layer at display, but at the same time the base layer is changed I am loosing the overlay. How can I avoid that?

When using the button again I can see in the flicker that the overlay is still there, but not on top of the base layer anymore.

Here an example:

library(shiny)
library(leaflet)
library(shinydashboard)

# Definition of Sidebar elements
sidebar <- dashboardSidebar(
  sidebarMenu(
    menuItem("Maps", tabName = "maps", icon = icon("globe"),
      menuSubItem(
        HTML(paste("Diffuse kilder NH", tags$sub("3"), sep = "")),
        tabName = "map_dif_nh3", icon = icon("map-o"), selected = TRUE
      )
    )
  )
)

# Definition of body elements
body <- dashboardBody(
  tabItems(
    tabItem(tabName = "map_dif_nh3",
      box(
        width = 12,
        div(style = "height: calc(100vh - 80px);",
          leafletOutput(
            "m_dif_nh3", width = "100%", height = "100%"
          ),
          absolutePanel(id = "nh3_panel", class = "panel panel-default",
            fixed = TRUE, style = "opacity: 0.87",
            top = 80, left = "auto", right = 50, bottom = "auto",
            width = 285, height = "auto",
            fluidRow(
              column(width = 10, offset = 1,
                actionButton(inputId = 'btn_bgr_nh3', label = "", icon = icon("globe", class = "fa-lg"))
              )
            )
          )
        )
      )
    )
  )
)

ui <- dashboardPage(
  dashboardHeader(title = "Mixed layout"),
  sidebar,
  body
)


server <- function(input, output) {

  init_lat <- 56.085935208960585
  init_lon <- 10.29481415546154
  init_zoom <- 7

  output$m_dif_nh3 <- renderLeaflet({
    leaflet(height = "100%") %>%
    addProviderTiles("Stamen.Toner", layerId = 'mb_osm', group = "base") %>%
    setView(init_lon, init_lat, init_zoom) %>%
    addWMSTiles(
      "http://gis.au.dk/geoserver_test/PRTR/gwc/service/wms",
      layers = "PRTR:prtr_nh3_2014",
      layerId = "nh3_2014",
      group = "overlay",
      options = WMSTileOptions(format = "image/png",
        transparent = TRUE, opacity = 0.8
      )
    )
  })

  observeEvent(
    input$btn_bgr_nh3, {
      leafletProxy("m_dif_nh3") %>%
        addProviderTiles("Esri.WorldImagery", layerId = 'mb_pic', group = 'base')
      leafletProxy("m_dif_nh3") %>%
        removeTiles(layerId = 'mb_osm')
    }
  )
}

shinyApp(ui, server)
TomGeo
  • 1,213
  • 2
  • 12
  • 24

2 Answers2

0

I think what you can do is reset the value of ID the action button to 0 after clicking the button. Therefore, every time you toggle the ID value will be replaced by 0. It worked for me. Hope it work for you as well.

Bhushan Pant
  • 1,445
  • 2
  • 13
  • 29
  • Not sure what you mean. As far as I can see the button isn't the problem. The problem is that the overlay layer isn't visible anymore, even though it is still loaded. The toggleState functionality isn't implemented in the code above, but you can use it, based on a condition, and check for the layerId of base layer. I need to keep the overlay layer visible. – TomGeo Jul 19 '16 at 12:02
  • See, the value of inputId = 'btn_bgr_nh3' changes when you click the button. And when the button is not clicked the value is default 0. – Bhushan Pant Jul 19 '16 at 12:22
  • Can you elaborate on how the value of the inputId is connected to the visibility of the nh3_2014 layer in the 'overlay' group? – TomGeo Jul 19 '16 at 12:28
0

In Leaflet JS (I don't know about R), if myTileLayer is already part of your base layers, then myTileLayer.addTo(map) does the switching job. It doesn't add on top; and you don't need to remove the current layer. The overlay remains unaffected.

Ref: https://stackoverflow.com/a/33762133/4355695

Nikhil VJ
  • 5,630
  • 7
  • 34
  • 55