rgoogle-mapsshinyr-leaflet

Use the dynamic value from selectinput in R leaflet setview


I'm creating a shiny leaflet map to record where I have been. I have a dataset contains coordinates and time. In my shiny app I've got 2 widgets-- a sliderbard for time line, a dropdown box to show the current countries that I have been. The country choices in the dropdown box is based on the time line sliderbar. Say for example: before 2016 all coordinates on the map are in country A then in the dropdown box there will be only one option in the dropdown box (country A). After 2016-01-01, the number of countries that I have been increased to 2 then in the dropdown box there will be 2 options (country A and country B) and currently this function works well.

Now I want to further develop my shiny app, the function I want is when I have multiple countries in the dropdown box, the app should allow me to choose one of the countries and when the country is chosen, the leaflet map will focus on the country I choose. I think using if else in setview() should solve the problem.

Then I created a (partially) workable shiny script below:

global.R
df <-read.csv("https://dl.dropbox.com/s/5w09dayyeav7hzy/Coordinatestest.csv",
           header = T,
           stringsAsFactors = F)
df$Time <- as.Date(df$Time, "%m/%d/%Y")
countriesSP <- getMap(resolution='low')

and

ui.R
library(devtools)
library(leaflet)
library(htmlwidgets)
library(shiny)
library(shinydashboard)
library(sp)
library(rworldmap)
library(RCurl)

header <- dashboardHeader(
   title = 'Shiny Memery'
)
body <- dashboardBody(
fluidRow(
  tabBox(
  tabPanel("My Map", leafletOutput("mymap",height = 550)),
  width = 700
))

)


dashboardPage(
header,
dashboardSidebar(

sliderInput('Timeline Value','Time line',min = min(df$Time),max =    max(df$Time), value = min(df$Time)),

selectInput("select_country", label = "Select Country", 
            choices = NULL, 
            selected = NULL)

),
body
)

and

server.R

shinyServer(function(input, output, session) {



output$mymap <- renderLeaflet({

df <- subset(df, df$Time <= input$`Timeline Value`)

observe({
  
  pointsSP <- SpatialPoints(df[,c("lon", "lat")],  proj4string=CRS(proj4string(countriesSP)))
  
  indices <- over(pointsSP, countriesSP)
  
  part_choices <- as.list(c("All",  na.omit(unique(as.character(indices$ADMIN)))))
  
  updateSelectInput(session, "select_country", choices=part_choices)
})

  lng <- ifelse(input$select_country == "All", mean(df$lon), 0)
  lat <- ifelse(input$select_country == "All", mean(df$lat), 0)


  m <- leaflet(df) %>%
    addTiles(
    #urlTemplate = "http://otile4.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.png"
  ) %>%  # Add default OpenStreetMap map tiles
  #setView(mean(df$lon), mean(df$lat), zoom = 5) %>%
  setView(lng, lat, zoom = 5) %>%
  addMarkers(~lon, ~lat, 
             clusterOptions = markerClusterOptions())

 })

})

Please copy and paste the script into Rstudio and run it. You will see as you drag the time line till the end, the country option will increase but default is always All. Ideally when I select one country and as you see based on some simple logic as long as the selection is not All, the coordinates in setview() function should be (0,0) (this can be dynamic later, currently I just want setview() to change the focus of the map). This function is not really working currently, i.e. when I select other country, the focus of the map will change to (0,0) but again change back to the default focus (mean(df$lon), mean(df$lat)) immediately and the selection will change back to All as well.

So do you have any idea on how to alter my code to make this work?


Solution

  • I have changed the server.R part how I think this should be done. Let me know if this helps.

    server.R

         shinyServer(function(input, output, session) {
    
                dfs <- reactive({
                        tmp <- subset(df, df$Time <= input$`Timeline Value`)  
                        tmp
                })
    
                part_choices <- reactive({
                        tmp <- dfs()
                        pointsSP <- SpatialPoints(tmp[,c("lon", "lat")],  proj4string=CRS(proj4string(countriesSP)))
                        indices <- over(pointsSP, countriesSP)
                        as.list(c("All",  na.omit(unique(as.character(indices$ADMIN)))))
                })
    
                observe({
                        updateSelectInput(session, "select_country", choices=part_choices())
                })
                 output$mymap <- renderLeaflet({
                         lng <- ifelse(input$select_country == "All", mean(df$lon), 0)
                         lat <- ifelse(input$select_country == "All", mean(df$lat), 0)
                         m <- leaflet(dfs()) %>%
                                 addTiles(
                                         #urlTemplate = "http://otile4.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.png"
                                 ) %>%  # Add default OpenStreetMap map tiles
                                 #setView(mean(dfs()$lon), mean(dfs()$lat), zoom = 5) %>%
                                 setView(lng, lat, zoom = 5) %>%
                                 addMarkers(~lon, ~lat, 
                                            clusterOptions = markerClusterOptions())
    
                })
    
        })