r-spatial/leafem

Shiny: ImageQuery doesn't update itself in new leaflet map

kokbent opened this issue ยท 7 comments

Hi I came across this issue #15 when troubleshoot my current issue with ImageQuery; thought I'll give this a try and see if this is a feature problem or that I should seek for workaround. My Shiny app starts out displaying a RasterLayer and the user can "update" the RasterLayer by, say moving the slider left or right. In my Shiny code, since I use renderLeaflet, my idea is that everytime user move the slider, a new leaflet map is created with the raster values updated. However, the ImageQuery doesn't update according to this new raster and leaflet map. Here's a simplified example of the problem:

library(leaflet)
library(plainview)
library(leafem)
library(shiny)

ras <- poppendorf[[1]]

ui <- fluidPage(
  fluidRow(
    sliderInput("factor", "Factor for raster values",
                min = 0.5, max = 2, value = 1),
    leafletOutput("map")
  )
)

server <- function(input, output) {
  output$map <- renderLeaflet({
    ras1 <- ras * input$factor
    
    leaflet() %>%
      addRasterImage(ras1, project = TRUE, group = "poppendorf",
                     layerId = "poppendorf") %>%
      addImageQuery(ras1, project = TRUE,
                    layerId = "poppendorf",position="bottomleft",prefix = "") %>%
      addLayersControl(overlayGroups = "poppendorf")
    
  })
}

shinyApp(ui, server)

The shiny app starts out with a leaflet map with raster. Mouseover shows the values are around 9000 something. Now when I slide to factor of 2, the raster values would be updated to 18000 something. However, when mouseover the layer, those values remain at 9000 something. It seems like ImageQuery retains its memory even if a new leaflet map is created and a new raster is used. Is this an expected behaviour? Am I doing my leaflet right? (I'm relatively new to this...)

Thanks!

Ben

Not being able to test right now. But I think you'd need to update your layerId to update the query data.

Or we need to provide a removeImageQuery function that you'd call before adding it again.

@trafficonese thoughts on this one?

Yes, updating the layerId would work like in the example below.

library(leaflet)
library(plainview)
library(leafem)
library(shiny)

ras <- poppendorf[[1]]

ui <- fluidPage(
  fluidRow(
    sliderInput("factor", "Factor for raster values",
                min = 0, max = 2, value = 1, step = 1),
    leafletOutput("map")
  )
)

server <- function(input, output) {
  output$map <- renderLeaflet({
    ras1 <- ras * input$factor
    lid <- paste0("poppendorf", input$factor)
    leaflet() %>%
      addRasterImage(ras1, project = TRUE, group = lid,
                     layerId = lid) %>%
      addImageQuery(ras1, project = TRUE,
                    layerId = lid,position="bottomleft",prefix = "") %>%
      addLayersControl(overlayGroups = lid)
  })
}

shinyApp(ui, server)

This adds a new script tag for every selected value of input$factor. Not too optimal, and I dont know how to update a specific script tag.

If the layerId doesn't change, the textfile is not added to the HTML header. I am not really sure why though or "who" is restricting that, so the data is not available for rasterpicker. A removeImageQuery would probably solve this, if we can find out how to remove/update a htmlDependency by name.

Thank you! This is definitely a good workaround for it. I create a global layer id variable that changes everytime the leaflet map gets updated. Only issue is the layerId is always displayed in that bubble so I have "prefix l1 yyy", "prefix l2 yyy",..., "prefix l25 yyy" which may confuse user. A little price to pay over functionality~

A removeImageQuery would be ideal but I can certainly see the technical difficulty in it.

You can adjust the prefix in the "bubble" with the prefix = argument in addImageQuery.

I think what @kokbent means is that the layer-name in the popup also changes and displays the name + integer.

I plan on looking more into this and hopefully come up with a better solution. But unfortunately, that could take me some time.

@trafficonese no problem & no rush! Without your contributions this would still be only a rudimentary function.

Will be looking forward to that! :)