Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change circles size based on zoom level?

Tags:

r

shiny

r-leaflet

I'm creating a Shiny app with a Leaflet map. It has thousands of small circles plotted on it, and the colors of the circles tells a story. When zoomed out, the circles are kept small (weight=1) so they overlap less. However, when the user zooms in, the small circles become hard to see. I would like the circles to increase in size depending on the zoom level. I understand that there is a input$MAPID_zoom feature that returns a zoom level as an integer.

Below is some reproducible code that plots 15 random points in Dallas, TX onto a leaflet map with the zoom set to 6. How would I go about changing the weight of the circles from 1 to 2 when the zoom level increases to 8, and from 2 to 3 when the zoom increases to 10?

I've seen some discussion online but nothing that has worked for me. See code below.

## app.R ##
library(leaflet)

ui <- dashboardPage(
  dashboardHeader(title = "Basic dashboard"),
  dashboardSidebar(),
  dashboardBody(
    leafletOutput("Map", width = "100%", height = "500px")
    
  )
)

server <- function(input, output) {

  df <- data.frame("Lat"=c(32.921821,32.910853,32.793803,32.995084,32.683745,32.759999,32.800652,32.958861,32.835963,32.762578,32.649651,32.862843,32.862217,32.936876,32.963381),
                   "Long"=c(-96.840609,-96.738831,-96.689232,-96.857858,-96.825345,-96.684475,-96.794144,-96.816111,-96.676371,-96.897331,-96.944426,-96.754719,-96.856976,-96.752718,-96.770249))

   output$Map <- renderLeaflet({
     leaflet(df) %>%
       addTiles(urlTemplate = "//{s}.tiles.mapbox.com/v3/jcheng.map-5ebohr46/{z}/{x}/{y}.png",
                attribution = 'Maps by <a href="http://www.mapbox.com/">Mapbox</a>') %>% 
       setView(lng = -96.84, lat = 32.92, zoom = 6) %>%
       addCircles(lng = ~Long, lat = ~Lat, weight = 1,
                        opacity = 1, fill = TRUE,  fillOpacity = 1 )
   })
}
shinyApp(ui, server)
like image 336
Jason Avatar asked Nov 30 '25 08:11

Jason


1 Answers

Alright, this ended up being more involved than I thought but I finally got it to work. There is an observer that is the key. I also had to learn what leafletProxy() is (research it if you don't know). Finally, clearing the shapes with clearShapes() in the observer was key to getting this working when zooming both in and out. See code below.

## app.R ##
library(leaflet)
library(shinydashboard)
library(shinydashboardPlus)
library(dplyr)
ui <- dashboardPage(
  dashboardHeader(title = "Basic dashboard"),
  dashboardSidebar(),
  dashboardBody(
    leafletOutput("map", width = "100%", height = "500px")
    
  )
)

server <- function(input, output,session) {
  
  df <- data.frame("Lat"=c(32.921821,32.910853,32.793803,32.995084,32.683745,32.759999,32.800652,32.958861,32.835963,32.762578,32.649651,32.862843,32.862217,32.936876,32.963381),
                   "Long"=c(-96.840609,-96.738831,-96.689232,-96.857858,-96.825345,-96.684475,-96.794144,-96.816111,-96.676371,-96.897331,-96.944426,-96.754719,-96.856976,-96.752718,-96.770249))
  
  observeEvent(
    eventExpr = input$map_zoom, {
      print(input$map_zoom)           # Display zoom level in the console
      leafletProxy(
        mapId = "map", 
        session = session
      )%>% clearShapes() %>%
        addCircles(data=df,lng = ~Long, lat = ~Lat, 
                   weight = case_when(input$map_zoom <=4 ~1, 
                                      input$map_zoom ==5 ~2, 
                                      input$map_zoom ==6 ~3, 
                                      input$map_zoom ==7 ~5, 
                                      input$map_zoom ==8 ~7, 
                                      input$map_zoom ==9 ~9, 
                                      input$map_zoom >9 ~11),
                   opacity = 1, fill = TRUE, fillOpacity = 1 )
    }
  )
  
  output$map <- renderLeaflet({
    leaflet() %>%
      addTiles(urlTemplate = "//{s}.tiles.mapbox.com/v3/jcheng.map-5ebohr46/{z}/{x}/{y}.png",
               attribution = 'Maps by <a href="http://www.mapbox.com/">Mapbox</a>') %>%
      setView(lng = -96.84, lat = 32.92, zoom = 6) 
  })
}
shinyApp(ui, server)
like image 169
Jason Avatar answered Dec 01 '25 23:12

Jason