dmwarn
dmwarn

Reputation: 13

Updating addImageQuery() value after change in reactive() choice

In a shiny app that includes a leaflet map with a raster, it is possible to get the value of a pixel at mouse position.

In that same shiny app it is possible to select from a list of rasters to decide which you want to display.

What I can't figure out how to do is make the shiny app continue to give the user the raster value at the mouse position after changing to a new raster layer. The code below is a sample of this.

When the shiny app opens and window is maximized, the raster value at the mouse cursor is displayed. Once you switch to a new raster, this no longer is displayed. I am stumped on how to change this so that the raster value at the mouse for the newly selected raster is shown. The closest I've come to this issue in previous posts is raster values on mouseover.

library(raster)
library(leaflet)
library(shiny)
library(mapview)
# Create raster data 
# Each raster represents the average of multiple rasters
# during a weekly period.  
# In this example, there are five weeks represented
# create an extent object
myext <- extent(707900, 980000,540000,1100000)
mycrs <-  "+proj=aea +lat_1=42.122774 +lat_2=49.01518 +lat_0=45.568977 
+lon_0=-84.455955 +x_0=1000000 +y_0=1000000 +ellps=GRS80 
+towgs84=0,0,0,0,0,0,0 +units=m +no_defs"

r1 <- raster(ncol=50, nrow=75, ext=myext, crs=mycrs)
values(r1) <-rnorm(3750, 0, 2)
r2 <- raster(ncol=50, nrow=75, ext=myext, crs=mycrs)
values(r2) <-rnorm(3750, 0, 2)
r3 <- raster(ncol=50, nrow=75, ext=myext, crs=mycrs)
values(r3) <-rnorm(3750, 0, 2)
r4 <- raster(ncol=50, nrow=75, ext=myext, crs=mycrs)
values(r4) <-rnorm(3750, 0, 2)
r5 <- raster(ncol=50, nrow=75, ext=myext, crs=mycrs)
values(r5) <-rnorm(3750, 0, 2)

# create list of rasters that the use can choose from in the shiny app
myras <- list(r1, r2, r3, r4, r5) 
modis.rasters <- stack(myras) 

# set up color display
# #this sets up the color palette and is the reverse Spectral with 10 levels
my.max<- 10
x <- -10:my.max # this is the observed range for chlorophyll in the data
names(modis.rasters) <- c("Week of 2016-04-01", "Week of 2016-04-08","Week of 
2016-04-15", "Week of 2016-04-22", "Week of 2016-04-29")
pal1 <- colorNumeric(palette = c("#5E4FA2", "#3288BD", "#66C2A5", "#ABDDA4", 
"#E6F598", "#FEE08B", "#FDAE61", "#F46D43", "#D53E4F", "#9E0142" ), domain = 
x,na.color = "transparent")

# Create a map for use in shiny app
map <- leaflet() %>% addTiles() %>%
  setView(lng = -86.0589, lat = 43, zoom =7) %>%
  addLegend(pal=pal1, values = values(modis.rasters), 
        title ='Random normal variate (mean=0, SD=2)', position="bottomleft",
        opacity=1)%>% 
  addMouseCoordinates(style = "basic")


# Now set up the UI 
ui <- shinyUI(fluidPage(

     titlePanel("Stuff"),

     # Generate a row with a sidebar
     sidebarLayout(      

       # Define the sidebar with one input
       # Here "period" is a weekly time period/raster
       sidebarPanel(
         selectInput("period", "Choose a time period:", 
                 choices=names(modis.rasters)),
         hr(),
         helpText("Some raster data that I will replace.",
              br(),
              width=8)
       ),
       # Create a spot for the map
       mainPanel(leafletOutput('raster_map', width=800,height=900))  
     )
)
)

# Define a server for the Shiny app
server <- shinyServer(function(input, output){ 

  # Fill in the spot we created for a map
  output$raster_map = renderLeaflet({ 
    map %>% 
      addRasterImage(reactiveRaster(), colors=pal1, layerId =input$period,
                 opacity=0.5)%>%
      addImageQuery(reactiveRaster(), type="mousemove", digits=2, 
                position="topright", layerId=input$period)
})

  reactiveRaster <- reactive({modis.rasters[[input$period]]}) 
  # add the selected raster to the map
  observe({ 
    leafletProxy("raster_map") %>% 
      clearImages() %>% 
      addRasterImage(reactiveRaster(), colors=pal1, layerId =input$period,
                     opacity=0.5)
  })
  })
shinyApp(ui = ui, server = server)

Upvotes: 0

Views: 826

Answers (1)

dmwarn
dmwarn

Reputation: 13

I am not sure how I figured this out. Maybe intuition? Actually trying different things. Repeatedly. No matter how, the fix to the issue was that I needed the primary map ("map") that gets built upon later to have a RasterLayer and addImageQuery(). I added these things and it works now. Refined code is below. The addition of lines 40-42 solved the problem.

library(raster)
library(leaflet)
library(shiny)
library(mapview)
# Create raster data 
# Each raster represents the average of multiple rasters
# during a weekly period.  
# In this example, there are five weeks represented
# create an extent object
myext <- extent(707900, 980000,540000,1100000)
mycrs <-  "+proj=aea +lat_1=42.122774 +lat_2=49.01518 +lat_0=45.568977 +lon_0=-84.455955 +x_0=1000000 +y_0=1000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"

r1 <- raster(ncol=50, nrow=75, ext=myext, crs=mycrs)
values(r1) <-rnorm(3750, 0, 2)
r2 <- raster(ncol=50, nrow=75, ext=myext, crs=mycrs)
values(r2) <-rnorm(3750, 0, 2)
r3 <- raster(ncol=50, nrow=75, ext=myext, crs=mycrs)
values(r3) <-rnorm(3750, 0, 2)
r4 <- raster(ncol=50, nrow=75, ext=myext, crs=mycrs)
values(r4) <-rnorm(3750, 0, 2)
r5 <- raster(ncol=50, nrow=75, ext=myext, crs=mycrs)
values(r5) <-rnorm(3750, 0, 2)

# create list of rasters that the use can choose from in the shiny app
myras <- list(r1, r2, r3, r4, r5) 
modis.rasters <- stack(myras) 
nmaps<-length(names(modis.rasters))

# set up color display
# #this sets up the color palette and is the reverse Spectral with 10 levels
my.max<- 10
x <- -10:my.max # this is the observed range for chlorophyll in the data
names(modis.rasters) <- c("Week of 2016-04-01", "Week of 2016-04-08","Week of 2016-04-15",
                          "Week of 2016-04-22", "Week of 2016-04-29")
pal1 <- colorNumeric(palette = c("#5E4FA2", "#3288BD", "#66C2A5", "#ABDDA4", "#E6F598", "#FEE08B", "#FDAE61", "#F46D43", "#D53E4F", "#9E0142" ), domain = x,na.color = "transparent")


map <- leaflet() %>% addTiles() %>%
  setView(lng = -86.0589, lat = 43, zoom =7) %>%
  addRasterImage(modis.rasters[[1]], colors=pal1, layerId ="values",
                 opacity=0.5) %>%
  addImageQuery(modis.rasters[[1]], type="mousemove", digits=2, position="topright", layerId="values") %>%
  addLegend(pal=pal1, values = values(modis.rasters), 
            title ='Random normal variate (mean=0, SD=2)', position="bottomleft",
            opacity=1)%>% 
  addMouseCoordinates(style = "basic")


# Now set up the UI 
ui <- shinyUI(fluidPage(

     titlePanel("Stuff"),

     # Generate a row with a sidebar
     sidebarLayout(      

       # Define the sidebar with one input
       # Here "period" is a weekly time period/raster
       sidebarPanel(
         selectInput("period", "Choose a time period:", 
                     choices=names(modis.rasters)),
         hr(),
         helpText("Some raster data that I will replace.",
                  br(),
                  width=8)
       ),
       # Create a spot for the map
       mainPanel(leafletOutput('raster_map', width=800,height=900))  
     )
)
)

# Define a server for the Shiny app
server <- shinyServer(function(input, output){ 

  # Fill in the spot we created for a map
  output$raster_map = renderLeaflet({ 
    map %>% 
      addRasterImage(reactiveRaster(), colors=pal1, layerId =input$period,
                     opacity=0.5)%>%
      addImageQuery(reactiveRaster(), type="mousemove", digits=2, position="topright", layerId=input$period)
})

  reactiveRaster <- reactive({modis.rasters[[input$period]]}) 
  # add the selected raster to the map
  observe({ 
    leafletProxy("raster_map") %>% 
      clearImages() %>% 
      addRasterImage(reactiveRaster(), colors=pal1, layerId =input$period,
                     opacity=0.5)
  })
  })


shinyApp(ui = ui, server = server) 

Upvotes: 0

Related Questions