89_Simple
89_Simple

Reputation: 3805

shiny return data based on click

I have a global database of grid ID, lat and long at 100-km resolution and associated data for each 100-km grid. Something like this

grid_ID    Lat    Lon   data1    data2    data3 ...  data4

I want to develop a shiny app that allows the user to:

  1. click anywhere on the map

  2. return corresponding lat and lon

  3. based on the returned lat and lon, find which 100-km grid does it fall into

  4. show the data associated with that 100-km grid as a pop-up window or as a table (either will do)

     library(shiny)
     library(leaflet)
     library(shinythemes)
    
     ui <- fluidPage(theme = shinytheme('superhero'),
                     leafletOutput("map"),
                     verbatimTextOutput("out")
     )
    
     server <- function(input, output, session) {
        output$map <- renderLeaflet({
        leaflet() %>% addProviderTiles('Esri.WorldImagery')
      })
    
      output$out <- renderPrint({
        validate(need(input$map_click, FALSE))
        str(input$map_click)
      })
    }
    
    shinyApp(ui, server)
    

This is now returning lat and long of the location that I clicked on which is my step 1 and 2. How do I go about doing step 3 and 4. For step 3, usually if it was not an shiny app, I would do

  coordinates(dat) <- ~ Longitude + Latitude
  proj4string(dat) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
  GRID <- over(dat, grid_shp)

where grid_shp is my global 100-km grid shapefile and dat has the returned lat lon from the click.

Upvotes: 0

Views: 385

Answers (2)

eevee
eevee

Reputation: 24

I assume your dataset is called "data". You have to find the grid which intersects with the coordinates of the click.

     library(shiny)
     library(leaflet)
     library(shinythemes)

  
  ui <- fluidPage(theme = shinytheme('superhero'),
                    leafletOutput("map"),
                    verbatimTextOutput("out"))
    
    server <- function(input, output, session) {
      output$map <- renderLeaflet({
        leaflet() %>% addProviderTiles('Esri.WorldImagery')
      })
      
      output$out <- renderPrint({
        validate(need(input$map_click, FALSE))
        str(input$map_click)
        # create a dataframe from the clicked point
        xy <-
          data.frame(longitude = input$map_click$lng,
                     latitude = input$map_click$lat)
        # transform this dataframe to spatialpointsdataframe
        spdf <-
          SpatialPointsDataFrame(
            coords = xy,
            data = xy,
            proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs")
          )
        # find the grid that intersects with the point
        selected_raster <- spdf %over% data
        # here you will see the information you need
        as.data.frame(selected_raster)
      })
    }
    
    shinyApp(ui, server)

Upvotes: 0

Merion
Merion

Reputation: 215

Probably not the most elegant solution and also not sure if it's in leaflet for R, but you could define each grid rectangle as a polygon, loop through the polygons and do if(Polygon.getBounds().contains(LatLng) == true); then you know which grid square you're in. Then return the feature properties of the grid square aka polygon object.

Upvotes: 0

Related Questions