I have been trying this but I couldn't manage to get it done. Online resources for R leaflet are not enough too. Really need to get this done.
ui.R -->
library(shiny)
library(ggmap)
library(leaflet)
shinyUI(bootstrapPage(
leafletOutput("map"),
br(),
verbatimTextOutput("out")
)
)
server.R -->
library(shiny)
library(ggmap)
library(leaflet)
shinyServer(function(input, output, session) {
output$map <- renderLeaflet({
p <- input$map_click
if(is.null(p)){
leaflet() %>% setView(lng = -43.1729, lat = -22.9068, zoom = 11) %>%
addTiles(options = providerTileOptions(noWrap = TRUE))
}
else{
address <- revgeocode(c(p$lng,p$lat))
leaflet() %>% setView(lng = p$lng, lat = p$lat, zoom = 16) %>%
addTiles(options = providerTileOptions(noWrap = TRUE)) %>%
addCircles(p$lng, p$lat, weight = 1, radius = 100, color = "black",
fillColor = "orange", popup = address, fillOpacity=0.5, opacity=1)
}
})
output$out <- renderPrint({
validate(need(input$map_click, FALSE))
click <- input$map_click
clat <- click$lat
clng <- click$lng
address <- revgeocode(c(clng,clat))
print(clat)
print(clng)
print(address)
})
})
TL; DR
leafletProxy
to update the map without rendering everything all over again.I would do this by making your original map and using the leafletProxy
function to update the map when the user clicks on locations. There is a tutorial on the Rstudio site somewhere where they show how to do this. It will hopefully save some computation, since the map won't be re-rendered every time a circle is added.
I also add a couple additional things I would consider: putting the circle data in a reactive dataset, and maintaining the circles in a group, thus allowing you to easily hide/show them with an additional observer/button.
Here, is a working example. For the record, I'm using the leaflet version from github (and recommend this since this package is under active development). You can get it with devtools::install_github('rstudio/leaflet')
. There are at least a couple new features that I don't think are on CRAN yet -- like easily being able to create custom markers.
library(shiny)
library(ggmap)
library(leaflet)
ui <- shinyUI(bootstrapPage(
leafletOutput("map")
))
server <- shinyServer(function(input, output, session) {
## One alternative: store circles data?
## I dont actually implement this, but you would do this in the observer as well
dat <- reactiveValues(circs = data.frame(lng=numeric(), lat=numeric()))
## Make your initial map
output$map <- renderLeaflet({
leaflet() %>%
setView(lng = -43.1729, lat = -22.9068, zoom = 11) %>%
addTiles(options = providerTileOptions(noWrap = TRUE))
})
## Observe mouse clicks and add circles
observeEvent(input$map_click, {
## Get the click info like had been doing
click <- input$map_click
clat <- click$lat
clng <- click$lng
address <- revgeocode(c(clng,clat))
## Add the circle to the map proxy
## so you dont need to re-render the whole thing
## I also give the circles a group, "circles", so you can
## then do something like hide all the circles with hideGroup('circles')
leafletProxy('map') %>% # use the proxy to save computation
addCircles(lng=clng, lat=clat, group='circles',
weight=1, radius=100, color='black', fillColor='orange',
popup=address, fillOpacity=0.5, opacity=1)
})
})
shinyApp(ui=ui, server=server)
The result should look something like this (I've zoomed in, added some circles and activated a popup).