rr-leaflet

How to shift the view to the central coordinates of an addRasterImage()?


I use addRasterImage() to display an image within a group that is later selected through addLayersControl(). The initial setView() is defined for a relatively large region, which is not centered on my small satellite image.

This example is close to what I have:

library(RStoolbox) #for the example satellite image
library(terra)
library(leaflet)
B4  <- project(rast(system.file("external/landsat/LT52240631988227CUB02_B4.TIF", package="RStoolbox")), "EPSG:4326")
ext(B4)
leaflet() %>% 
  setView(lng = -50.5, lat=-3.4 , zoom = 9) %>%
  addTiles() %>% 
  addProviderTiles(providers$Esri.WorldImagery, group = "Satview") %>%
  addRasterImage(B4, group = "Landsat") %>% 
  addLayersControl(
    #baseGroups = c("Satview","OSM","r1","a"),
    baseGroups = c("Satview","Landsat"),
    options = layersControlOptions(collapsed = FALSE, autoZIndex = TRUE))

Desired behavior:

As addRasterImage() is intended for relatively small images such as mine, I would like the display to shift to the center of the image once its group ("Landsat" in this example) is selected in the menu.

Is there a way to achieve this? I do not see an option within addRasterImage() and do not see how to repeat setView() for a given group.


Solution

  • You can add some JS here (see Custom JavaScript with htmlwidgets::onRender() in the leaflet docs) which attaches a baselayerchange event to your map. This event checks whether one has chosen Landsat and if so, setView is invoked where lng and lat are defined by the center of the image. The coordinates are previously calculated from the SpatExtent.

    library(RStoolbox)
    library(terra)
    library(leaflet)
    
    B4 <- project(
      rast(
        system.file("external/landsat/LT52240631988227CUB02_B4.TIF", 
                    package = "RStoolbox")
      ), "EPSG:4326")
    
    vars <- ext(B4) |> as.list()
    
    lngCenter <- (vars$xmax - vars$xmin) / 2 + vars$xmin
    latCenter <- (vars$ymax - vars$ymin) / 2 + vars$ymin
    
    leaflet() |>
      setView(lng = -50.5,
              lat = -3.4,
              zoom = 9) |>
      addTiles() |>
      addProviderTiles(providers$Esri.WorldImagery, group = "Satview") |>
      addRasterImage(B4, group = "Landsat") |>
      addLayersControl(
        baseGroups = c("Satview", "Landsat"),
        options = layersControlOptions(collapsed = FALSE, autoZIndex = TRUE)
      ) |>
      htmlwidgets::onRender(
        sprintf(
          "function(el, x) {
             var map = this;
             map.on('baselayerchange', function(e) {
               if (e.name === 'Landsat') {
                 map.setView([%s, %s], 12)
               }
             });
           }",
          latCenter,
          lngCenter
        )
      )
    

    enter image description here