rshinyr-leaflet

Filter out areas from json file


I'm trying to make a feature on my app where I can choose a dropdown menu of the neighborhoods within a city. With the default selection being the entire city itself SURREY. It is expected that when I select a neighborhood from the dropdown menu other than SURREY, I expect it to filter out the other neighborhoods and thus, only showing the outline of the selected neighbourhood. However, when I try to do this, my map stops rendering entirely. The JSON File is here and I extracted it and put it in my relative data path. My full code is listed below:

library(shiny)
library(shinydashboard)
library(shinyjs)
library(leaflet)
library(leaflet.extras)
library(sf)
library(ggplot2)
library(dplyr)
library(lubridate)
library(rgdal)

##constants

SURREY_LAT <- 49.15
SURREY_LNG <- -122.8
ZOOM_MIN = 10
ZOOM_MAX = 18
##

neighbourhood <- st_read("data/surrey_city_boundary.json", quiet = TRUE) %>%
  st_transform(crs = 4326)%>%
  select(NAME,geometry)

neighbourhood_names <- neighbourhood$NAME %>%
  as.character(.) %>%
  sort()
##basemap

basemap<-leaflet() %>%
  addProviderTiles(providers$CartoDB.Positron)%>%
  setView(lng = SURREY_LNG,lat =SURREY_LAT, zoom= 10)

ui <- bootstrapPage(
  tags$style(type = "text/css", "html,
             body {width:100%;height:100%}"),
  leafletOutput("basemap", width = "100%", height = "100%"),
  
  absolutePanel(id = "controls", class = "panel panel-default",
                top = 60, left = 55, width = 250, fixed = TRUE,
                draggable = TRUE, height = "auto",
    selectInput(
      "neighbourhood_names",
      label = "Select a Neighbourhood:",
      choices=(neighbourhood_names),
      selected= "SURREY")
  )
)



#server
server <- function(input, output) {
  
  output$mymap <- renderLeaflet(basemap)
  
  observeEvent(input$neighbourhood_names,{
    
    if(input$neighbourhood_names =="SURREY"){
      data<- neighbourhood %>%
        filter(NAME %in% c("CITY CENTRE", "CLOVERDALE", "FLEETWOOD", "GUILDFORD",
                                    "NEWTON", "SOUTH SURREY", "WHALLEY"))}
    
    else{
      data <- neighbourhood %>% 
        filter(NAME == input$neighbourhood_names)}
    
    leafletProxy("mymap", data= neighbourhood) %>%
      setView(lng = ifelse(input$neighbourhood_names == "Surrey", -122.7953,  49.15),
              lat = ifelse(input$neighbourhood_names == "Surrey", 49.10714,  49.15),
              zoom = ifelse(input$neighbourhood_names == "Surrey", 11, 12)) %>%
      clearShapes() %>%
      addPolygons(color = "#141722", weight = 3, smoothFactor = 0.5,
                  fillOpacity = 0.1, opacity = 1)

    
  })
  
}


shinyApp(ui = ui, server = server)


Solution

  • You had some typos. Also, you need to put lng and lat in your dataframe, so that each selection has its own coordinates. At the moment, you are defining it as 49.15 in setView. Once you fix your dataframe, this should work.

    SURREY_LAT <- 49.15
    SURREY_LNG <- -122.8
    ZOOM_MIN = 10
    ZOOM_MAX = 18
    ##
    
    neighbourhood <- st_read("./surrey_city_boundary.json", quiet = TRUE) %>%
      st_transform(crs = 4326) %>%
      select(NAME,geometry)
    
    neighbourhood_names <- neighbourhood$NAME %>%
      as.character(.) %>%
      sort()
    ##basemap
    
    basemap<-leaflet() %>%
      addProviderTiles(providers$CartoDB.Positron)%>%
      setView(lng = SURREY_LNG,lat =SURREY_LAT, zoom= 10)
    
    ui <- bootstrapPage(
      tags$style(type = "text/css", "html,
                 body {width:100%;height:100%}"),
      leafletOutput("mymap", width = "100%", height = "100%"),
      
      absolutePanel(id = "controls", class = "panel panel-default",
                    top = 60, left = 55, width = 250, fixed = TRUE,
                    draggable = FALSE, height = "auto",
                    shiny::selectInput(
                      "neighbourhood_names",
                      label = "Select a Neighbourhood:",
                      choices=(neighbourhood_names),
                      selected= "SURREY"
                      
                      )
                    
      )
    )
    
    #server
    server <- function(input, output) {
      
      output$mymap <- renderLeaflet(basemap)
      
      observeEvent(input$neighbourhood_names,{
        req(input$neighbourhood_names)
        if(input$neighbourhood_names =="SURREY"){
          data<- neighbourhood %>%
            dplyr::filter(NAME %in% c("CITY CENTRE", "CLOVERDALE", "FLEETWOOD", "GUILDFORD",
                               "NEWTON", "SOUTH SURREY", "WHALLEY"))
        } else{
          data <- neighbourhood %>% 
            dplyr::filter(NAME == input$neighbourhood_names)}
        
        leafletProxy("mymap", data= data) %>%
          setView(lng = ifelse(input$neighbourhood_names == "SURREY", -122.7953,  49.15),
                  lat = ifelse(input$neighbourhood_names == "SURREY", 49.10714,  49.15),
                  zoom = ifelse(input$neighbourhood_names == "SURREY", 11, 12)) %>%
          clearShapes() %>%
          addPolygons(color = "#141722", weight = 3, smoothFactor = 0.5,
                      fillOpacity = 0.1, opacity = 1)
        
        
      })
      
    }
    
    shinyApp(ui = ui, server = server)