I'm starting a Shiny app with a leaflet map in it.
I need the user to be able to place two separate markers (origin & destination) on the map, and potentially replace them later on.
So what I did is create an origin button and a destination button, so that when the user clicks one of them, they'll place or update the corresponding marker with their next click on the map.
library(shiny)
library(shinyWidgets)
library(leaflet)
library(RColorBrewer)
library(osrm)
ui <- bootstrapPage(
tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
leafletOutput("map", width = "100%", height = "100%"),
absolutePanel(top = 10, right = 10,
actionButton("change_orig", "Origine"),
actionButton("change_dest", "Destination"),
)
)
server <- function(input, output, session) {
origin_icon = makeIcon("https://static.thenounproject.com/png/1477944-200.png",
iconWidth=24, iconHeight=30)
destination_icon = makeIcon("https://static.thenounproject.com/png/924206-200.png",
iconWidth=24, iconHeight=30)
output$map <- renderLeaflet({
leaflet() %>% addTiles(providers$OpenStreetMap) %>%
addProviderTiles(providers$OpenStreetMap, group="Open Street Map") %>%
addProviderTiles(providers$OpenTopoMap, group="Open Topo Map") %>%
fitBounds(2.907730, 45.856550, 3.310954, 45.714034) %>%
addLayersControl(
baseGroups = c("Open Street Map", "Open Topo Map")
)
})
# When "Origin" is selected,
# a click on the map will (re)place the origin marker.
observeEvent(input$change_orig, {
observeEvent(input$map_click, {
click = input$map_click
leafletProxy('map')%>%
clearGroup("origin") %>%
addMarkers(lng=click$lng, lat=click$lat, icon=origin_icon,
group="origin")
})
})
# When "Destination" is selected,
# a click on the map will (re)place the destination marker.
observeEvent(input$change_dest, {
observeEvent(input$map_click, {
click = input$map_click
leafletProxy('map') %>%
clearGroup("destination") %>%
addMarkers(lng=click$lng, lat=click$lat, icon=destination_icon,
group="destination")
})
})
}
shinyApp(ui, server)
And I'm facing a couple problems here.
clearGroup
deletes both destination and origin markers and recreates both at the same location.How could I make sure to only create or replace one marker without affecting the other?
And how could I only listen to the click event after button's been selected?
So I ended up going for a radioButtons
instead of two actionButton
s.
Then in the observeEvent
for map_click
, I used a simple if
to check which of the radio buttons was selected:
library(shiny)
library(shinyWidgets)
library(leaflet)
library(RColorBrewer)
library(osrm)
ui <- bootstrapPage(
tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
leafletOutput("map", width = "100%", height = "100%"),
absolutePanel(top = 10, right = 10,
radioButtons(
'orig_dest_switch',
"Changer l'origine ou la destination",
choices = c("Origine", "Destination"),
choiceValues = c("orig", "dest"),
inline = TRUE),
)
)
server <- function(input, output, session) {
origin_icon = makeIcon("https://static.thenounproject.com/png/1477944-200.png",
iconWidth=24, iconHeight=30)
destination_icon = makeIcon("https://static.thenounproject.com/png/924206-200.png",
iconWidth=24, iconHeight=30)
output$map <- renderLeaflet({
leaflet() %>% addTiles(providers$OpenStreetMap) %>%
addProviderTiles(providers$OpenStreetMap, group="Open Street Map") %>%
addProviderTiles(providers$OpenTopoMap, group="Open Topo Map") %>%
fitBounds(2.907730, 45.856550, 3.310954, 45.714034) %>%
addLayersControl(
baseGroups = c("Open Street Map", "Open Topo Map")
)
})
observeEvent(input$map_click, {
click = input$map_click
# Vérifier si l'on update le marker d'origine ou de destination
if(input$orig_dest_switch=="Origine"){
origin = list(lng=click$lng, lat=click$lat)
leafletProxy('map')%>%
clearGroup("origin") %>%
addMarkers(lng=click$lng, lat=click$lat, icon=origin_icon,
group="origin")
} else {
destination = list(lng=click$lng, lat=click$lat)
leafletProxy('map')%>%
clearGroup("destination") %>%
addMarkers(lng=click$lng, lat=click$lat, icon=destination_icon,
group="destination")
}
})
}
shinyApp(ui, server)