rshinyr-leaflet

How to prevent leaflet map from resetting zoom in shiny app?


Myself and others have built a prototype of an online application to assist transport planners in prioritising new funding for bicycle paths:

https://robinlovelace.shinyapps.io/fixMyPath/

We are happy with the result and impressed with Shiny's ability to rapidly prototype concepts for web deployment without having to write a single line of JavaScript. However, the app has a major problem that you will see by zooming in and then adjusting the transparency sliders: the zoom resets every time you do this. The question is therefore a simple one: how can a re-write server.R so that the map does not reset it's zoom settings?

The entire app can be seen in the link below and should be reproducible on any R installation, provided you have the right packages (e.g. rgdal, leaflet, ggmap):

https://github.com/nikolai-b/hackMyRoute/tree/master/R/fixMyPath

For more context, please see here.


Solution

  • I had the same question and I think I found something that worked:

    Change the way that you generate the map by using LeafletProxy as described here on the Leaflet for R page and shown here on the SuperZip example. First, try setting up your renderLeaflet function like this:

    output$map = renderLeaflet(leaflet() %>% 
      addTiles(urlTemplate = "http://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png") %>%
      setView(...) # add the parameters as appropriate set the view or use fitBounds  
    

    Then use an observe function with LeafletProxy to draw the lines and circles like this:

    observe({
      leafletProxy("map") %>%
      clearShapes() %>%
      addPolygons(layerId= "layer1"
                , data = leeds
                , fillOpacity = 0.4
                , opacity = (input$transp_zones)*.4
                , fillColor = leeds$color_pcycle
      ) %>%
      addPolyLines(layerId = "layer2"
                 , data = lfast, color = "red"
                 , opacity = input$transp_fast
                 , popup = sprintf("<dl><dt>Distance </dt><dd>%s km</dd><dt>Journeys by bike</dt><dd>%s%%</dd>", round(flows$fastest_distance_in_m / 1000, 1), round(flows$p_cycle * 100, 2))
      ) %>%
    # and so on in a similar fashion for the rest of your shapes
    
    })
    

    You need to add layer IDs to make sure that the new shapes replace old ones when you change the arguments. This way you should not need the mapOptions(zoomToLimits = "first") that you had.