Pete
Pete

Reputation: 321

How do I click on a leaflet map, create a marker, and then delete that marker when I click elsewhere in R

I have created a shiny application the displays a leaflet map of points in a data frame.

I want to allow the user to click anywhere on the map to get some information on nearby points and leave a marker on that point.

It is possible that they might want to click elsewhere. When they click elsewhere, I would like a new marker to be left, and the old marker to be deleted.

I have written a working Shiny application but I cannot get it to work.

  1. I tried using clearMarkers, but this deletes ALL of the marker, both the one that I created and the ones in the underlying dataframe.

  2. I tried specifying the id of the clicked point so that clearMarkers might simply just delete that one, but I have no idea who to find out the id of the clicked point.

How can I get this to work?

Here is my toy code:

library(shiny)
library(sp)
library(shinydashboard)
library(leaflet)

#### Make a spatial data frame 
lats<-c(37.38,39)
lons<-c(-94,-95,-96)
df<-data.frame(cbind(lons,lats))
coordinates(df)<-~lons+lats

#### Define UI for application that draws a histogram
ui <- dashboardPage(

    dashboardHeader(
    ),

    # Sidebar layout with input and output definitions 
    dashboardSidebar(
    ),

    # Main panel for displaying outputs 
    dashboardBody(
                     h2("My Map", align="center"),
                     h5("Click anywhere to draw a circle", align="center"),
                     leafletOutput("mymap", width="100%", height="500px")
        ),
    )



#### Define server logic required to draw a histogram
server <- function(input, output) {

    output$mymap <- renderLeaflet({
                 m = leaflet(df,width="100%",height="100%") %>% 
                 addTiles()    %>%
                 addCircleMarkers()
    })

    observeEvent(input$mymap_click, {

        click <- input$mymap_click
        text<-paste("Latitude ", round(click$lat,2), "Longtitude ", round(click$lng,2))

        proxy <- leafletProxy("mymap")

        ## This displays the pin drop circle
        proxy %>% 
            #clearPopups() %>%
            #clearMarkers(layerId=input$mymap_click$id) %>%
            #addPopups(click$lng, click$lat) %>%
            addCircles(click$lng, click$lat, radius=100, color="red")

    })


}

# Run the application 
shinyApp(ui = ui, server = server)

Upvotes: 3

Views: 1474

Answers (1)

Shree
Shree

Reputation: 11140

You can use group argument of addCircles along with clearGroup for this -

library(shiny)
library(sp)
library(shinydashboard)
library(leaflet)

#### Make a spatial data frame 
lats<-c(37.38,39)
lons<-c(-94,-95,-96)
df<-data.frame(cbind(lons,lats))
coordinates(df)<-~lons+lats

#### Define UI for application that draws a histogram
ui <- dashboardPage(

    dashboardHeader(
    ),

    # Sidebar layout with input and output definitions 
    dashboardSidebar(
    ),

    # Main panel for displaying outputs 
    dashboardBody(
                     h2("My Map", align="center"),
                     h5("Click anywhere to draw a circle", align="center"),
                     leafletOutput("mymap", width="100%", height="500px")
        ),
    )



#### Define server logic required to draw a histogram
server <- function(input, output) {

    output$mymap <- renderLeaflet({
                 m = leaflet(df,width="100%",height="100%") %>% 
                 addTiles()    %>%
                 addCircleMarkers()
    })


    observeEvent(input$mymap_click, {

        click <- input$mymap_click
        text<-paste("Latitude ", round(click$lat,2), "Longtitude ", round(click$lng,2))

        proxy <- leafletProxy("mymap")

        ## This displays the pin drop circle
        proxy %>% 
            clearGroup("new_point") %>%
            #clearMarkers(layerId=input$mymap_click$id) %>%
            #addPopups(click$lng, click$lat) %>%
            addCircles(click$lng, click$lat, radius=100, color="red", group = "new_point")

    })


}

# Run the application 
shinyApp(ui = ui, server = server)

Upvotes: 7

Related Questions