I am trying to make a leaflet output, where I can click the neighbor boundaries (in red) that are visible initially on selecting a city. The clicking should generate all the polygons in that neighborhood with blue boundaries. My code is working fine except that when I click another neighborhood, the polygons of the previously selected neighborhood will still be there and these previously selected neighborhoods are not clickable anymore.
What, I am trying to get here is when I select the next neighborhood's boundary, the polygons of the last selected boundary disappear and all the neighborhood boundaries remain clickable.
Here is the server code that I am using
# SERVER
server <- function(input, output) {
current_neighborhood <- reactiveVal(NULL)
previous_neighborhood <- reactiveVal(NULL)
output$dynamic_bg <- renderUI({
city_choice <- tolower(input$city) # Convert the city name to lowercase
css_str <- paste0("
body {
background-image: url('background", city_choice, ".jpg');
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
}
")
tags$style(HTML(css_str))
})
# Reactive expression that filters the Geojson_sf_list based on the selected city
filtered_sf_list <- reactive({
indices <- which(cleaned_data$residing_city == input$city)
list(sf_objects = geojson_sf_list[indices], neighborhoods = cleaned_data$NeighborhoodName[indices])
})
output$map <- renderLeaflet({
map <- leaflet() %>% addTiles() %>%
setView(lng = -73.9939, lat = 40.7336, zoom = 12)
# Extracting the filtered data
sf_objects <- filtered_sf_list()$sf_objects
neighborhoods <- filtered_sf_list()$neighborhoods
# Add each neighborhood to the map for the selected city with popups
for (i in seq_along(sf_objects)) {
sf_obj <- sf_objects[[i]]
neighborhood_name <- neighborhoods[i]
map <- map %>% addPolygons(data = sf_obj, color = "red", weight = 1,
fill = FALSE,
label = as.character(neighborhood_name),
highlightOptions = highlightOptions(color = "#000000", bringToFront = TRUE, weight = 2),
layerId = as.character(neighborhood_name) # Assign layerId for click event
)
}
# If there are polygons for the selected city, zoom to their bounds
if(length(sf_objects) > 0) {
bounds <- lapply(sf_objects, st_bbox)
all_bounds <- do.call(rbind, bounds)
map <- map %>% fitBounds(
lng1 = min(all_bounds[, "xmin"]),
lat1 = min(all_bounds[, "ymin"]),
lng2 = max(all_bounds[, "xmax"]),
lat2 = max(all_bounds[, "ymax"])
)
}
map
})
observeEvent(input$map_shape_click, {
click_data <- input$map_shape_click
clicked_neighborhood <- click_data$id
# Store the current clicked neighborhood
previous_neighborhood(current_neighborhood())
current_neighborhood(clicked_neighborhood)
proxy <- leafletProxy("map")
# Reset the previously clicked neighborhood, if any
if (!is.null(previous_neighborhood())) {
indices_prev <- which(cleaned_data$NeighborhoodName == previous_neighborhood())
sf_objects_prev <- geojson_sf_list[indices_prev]
for (sf_obj in sf_objects_prev) {
proxy %>% addPolygons(data = sf_obj, color = "red", weight = 1, fill = FALSE)
}
}
# Highlight the currently clicked neighborhood
indices <- which(cleaned_data$NeighborhoodName == clicked_neighborhood)
selected_sf_objects <- geojson_sf_list[indices]
for (sf_obj in selected_sf_objects) {
proxy %>% addPolygons(data = sf_obj, color = "blue", weight = 1, fill = FALSE)
}
})
}
shinyApp(ui, server)