rstudio / leaflet

R Interface to Leaflet Maps
http://rstudio.github.io/leaflet/
Other
805 stars 508 forks source link

Moving and zooming update layer.control info, but select changes in visible layers do not in Shiny #600

Open NHPatterson opened 5 years ago

NHPatterson commented 5 years ago

I have modified the leaflet.js to return the visible layers information when it is queried along with the view center point issue because I'd like to rerender the map with new information (using a htmlwidgets::onRender(...), which in my instance, does not work via leafletProxy. However, I'd like keep the same view both in terms of location and visible layers. The problem is the list of visible layers does not update when different layers are selected on the control, but only when the map is zoomed upon or moved by the mouse. So if I changed some information to rerender the map, but did not move/zoom the map between changing the initial render, and rerender, but DID change the visible layers, this information can't be captured.

Here is what I changed in the leaflet.js:

function updateBounds(map) {
  var id = map.getContainer().id;
  var bounds = map.getBounds();
  var throwaway = Math.random();
  _shiny2.default.onInputChange(id + "_bounds", {
    north: bounds.getNorthEast().lat,
    east: bounds.getNorthEast().lng,
    south: bounds.getSouthWest().lat,
    west: bounds.getSouthWest().lng
  });
  _shiny2.default.onInputChange(id + "_center", {
    lng: map.getCenter().lng,
    lat: map.getCenter().lat,
    layer: map.layerManager.getVisibleGroups() //added this to get layer info in '_center' return
  });
  _shiny2.default.onInputChange(id + "_zoom", map.getZoom());
}

Here is a reproducible example:

ui <- fluidPage(
  leafletOutput("mymap"),
  p(),
  actionButton("map_info", "print map info")

)

server <- function(input, output, session) {
  output$mymap <- renderLeaflet({

    m <- leaflet() %>% setView(lng = -71.0589, lat = 42.3601, zoom = 12) %>%
      addProviderTiles(providers$Stamen.Toner, group='tiles1')%>%
      addProviderTiles(providers$CartoDB.Positron, group='tiles2') %>%
      addProviderTiles(providers$Esri.NatGeoWorldMap, group='tiles3')%>%
      addLayersControl(
        overlayGroups = c("tiles1", "tiles2","tiles3"),
        options = layersControlOptions(collapsed = FALSE)
      )
    m
  })
  observeEvent(input$map_info ,{

    cent_lng  <- input$mymap_center$lat
    cent_lat  <- input$mymap_center$lng
    cent_zoom <- input$mymap_zoom[1]
    visibleLayers <- input$mymap_center$layer
    #log some stuff to console for demonstration
    cat(format(Sys.time(), "%a %b %d %X %Y"),': \n')
    cat(paste0('center lng: ',cent_lng),'\n')
    cat(paste0('center lat: ',cent_lat),'\n')
    cat(paste0('center zoom: ',cent_zoom),'\n')
    cat(paste0('visible: ', unlist(visibleLayers)),'\n\n')

  })
}

shinyApp(ui, server)

Here I walk through what I see and what the console prints after hitting the 'print map info' button.

initial map (all visible)

stack-10001

Wed Dec 05 12:46:41 PM 2018 : 
center lng: 42.3600660748082 
center lat: -71.0588836669922 
center zoom: 12 
visible: tiles1 visible: tiles2 visible: tiles3 

tiles 1 and 3 visible

stack-10002

Wed Dec 05 12:46:58 PM 2018 : 
center lng: 42.3600660748082 
center lat: -71.0588836669922 
center zoom: 12 
visible: tiles1 visible: tiles2 visible: tiles3 

tiles 1 and 3 visible, zoomed in by one mag.

stack-10003

Wed Dec 05 12:47:16 PM 2018 : 
center lng: 42.3589244602817 
center lat: -71.0592269897461 
center zoom: 13 
visible: tiles1 visible: tiles3 

tiles 1 set visible, no zooming or map movement

stack-10004

Wed Dec 05 12:47:26 PM 2018 : 
center lng: 42.3589244602817 
center lat: -71.0592269897461 
center zoom: 13 
visible: tiles1 visible: tiles3 

tiles 1 set visible, move map slightly

stack-10005

Wed Dec 05 12:47:42 PM 2018 : 
center lng: 42.3589244602817 
center lat: -71.0672950744629 
center zoom: 13 
visible: tiles1 

Any help would be appreciated to update the map whenever layers are changed.

NHPatterson commented 5 years ago

404

This issue demonstrates what was described here. I added js code to get layer information, but that information doesn't update dynamically with layer selection, only with map movements and zooms.