Leaflet: When clicking a marker input$map_marker_click returns a NULL id

2,445 views
Skip to first unread message

Bastien Tran

unread,
Jun 25, 2015, 3:22:55 PM6/25/15
to shiny-...@googlegroups.com
Hi all,

I am trying to draw a polygon (and hopefully many later on!) by clicking on a leaflet map.

The general idea is that if I click on the map (input$map_click) a new spot is created and displayed (addMarkers) and stored in data.frame. If an already existing spot is selected (input$map_marker_click) it is simply added to that same data.frame. Once the first layerId matches the last layerId I assign the polygon an id, store it, draw it and clear the data.frame.

Now when I click back on a spot already listed in this data.frame the app crashes. At this stage I simply expect this point to be added to the data.frame, just like the others. I get the following error in the console:

"Avis : Unhandled error in observer: arguments imply differing number of rows: 1, 0"

After investigating a bit it seems that input$map_marker_click returns a NULL id. If this is my actual problem I have no idea why it occurs since I have no trouble retrieving a marker's id by clicking it outside of this polygon drawing context.

Any clues?

Best regards,
Bastien


Joe Cheng

unread,
Jun 25, 2015, 3:25:25 PM6/25/15
to Bastien Tran, shiny-...@googlegroups.com
Hi there,

Can you provide a reproducible example? Hard to guess what could be happening otherwise.

Thanks
--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shiny-discuss/84832a27-38be-45ca-9672-6787905dc9da%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Bastien Tran

unread,
Jun 25, 2015, 3:59:02 PM6/25/15
to Joe Cheng, shiny-...@googlegroups.com
Hi Joe,

Thank you for your reply and yes, of course, sorry if it is not the best way to share it:

ui.R
shinyUI(navbarPage("divRs", id="nav",
                  
                   tabPanel("Interactive map",
                            div(class="outer",
                                tags$head(
                                  includeCSS("styles.css")
                                ),
                                leafletOutput("map", width="100%", height="100%")
                            )
                   ),
                   absolutePanel(id = "controls", class = "panel panel-default", fixed = TRUE,
                                 draggable = TRUE, top = 60, left = "auto", right = 20, bottom = "auto",
                                 width = 330, height = "auto",
                                 h2("Controls"),
                                 textInput("user","User",value="user 1"),
                                 htmlOutput("selected"),
                                 checkboxInput('addMarkerOnClick', 'Add marker on click', FALSE),
                                 checkboxInput('addPolygonOnClick', 'Add polygon on clicks', TRUE),
                                 htmlOutput("buffer")
                   )
                  
)
)


server.R
library(shiny)
library(leaflet)
library(dplyr)
#######Functions and reactiveValues######
server <- reactiveValues(items=list(),
                         points=list(),
                         polygons=list(),
                         lines=list(),
                         polylines=list())
bindEvent <- function(eventExpr, callback, env=parent.frame(), quoted=FALSE) {
  eventFunc <- exprToFunction(eventExpr, env, quoted)
  initialized <- FALSE
  invisible(observe({
    eventVal <- eventFunc()
    if (!initialized)
      initialized <<- TRUE
    else
      isolate(callback())
  }))
}
#######Functions and reactiveValues######
shinyServer(function(input, output, session) {
  client<-reactiveValues(selected=NULL,
                         buffer=NULL,
                         events=list())
####Add marker###### 
  bindEvent(input$map_click, function() {
    if (!input$addMarkerOnClick)
      return()
    event <- input$map_click
    client$selected<-data.frame(lng=event$lng,
                                lat=event$lat,
                                layerId=as.character(as.integer(length(server$items)+1)),
                                pointId=as.character(as.integer(length(server$items)+1)),
                                user=as.character(input$user))
    server$items[[length(server$items)+1]]<-server$points[[length(server$points)+1]]<-client$selected
    leafletProxy("map") %>% addMarkers(lng=as.double(event$lng),lat=as.double(event$lat), layerId = client$selected$layerId)
    saveRDS(server$items,"items.Rds")
  })
####Add marker###### 
####Add polygon######
  #Creates a new point on the map and adds it to the list of points (buffer) that will later define the polygon
  bindEvent(input$map_click, function() {
    if (!input$addPolygonOnClick)
      return()
    #Saves the event for debugging
    client$events[[length(client$events)+1]]<-input$map_click
    saveRDS(client$events,"events.Rds")
    event <- input$map_click
    client$selected<-data.frame(lng=event$lng,
                                lat=event$lat,
                                layerId=NA,
                                pointId=as.character(as.integer(length(server$items)+1)),
                                user=as.character(input$user))
    server$items[[length(server$items)+1]]<-server$points[[length(server$points)+1]]<-client$selected
    leafletProxy("map") %>% addMarkers(lng=as.double(event$lng),
                                       lat=as.double(event$lat),
                                       layerId = client$selected$layerId)
    client$buffer<-rbind(client$buffer,client$selected)
    leafletProxy("map") %>% addPolygons(lng=client$buffer$lng,
                                        lat=client$buffer$lat,
                                        layerId = "buffer")
  })
  #Adds an existing point to the list of points (buffer) that will later define the polygon
  bindEvent(input$map_marker_click, function() {
    if (!input$addPolygonOnClick)
      return()
    #Saves the event for debugging
    client$events[[length(client$events)+1]]<-input$map_marker_click
    saveRDS(client$events,"events.Rds")
    #Then we add the point to the list
    event<-input$map_marker_click
    client$selected<-data.frame(lng=event$lng,
                                lat=event$lat,
                                layerId=NA,
                                pointId=event$id,
                                user=as.character(input$user))
    client$buffer<-rbind(client$buffer,client$selected)
    leafletProxy("map") %>% addPolygons(lng=client$buffer$lng,
                                        lat=client$buffer$lat,
                                        layerId = "buffer")
  })
####Add polygons####
####Output####
  output$selected <- renderTable({
    data<-client$selected
    data
  })
  output$map <- renderLeaflet({
    leaflet() %>%
      addTiles(urlTemplate = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", attribution = NULL, layerId = NULL, options = tileOptions()) %>%
      setView(2,46,6)  
  })
})
####Output####

I hope that helps.

All the best





  






Bastien Tran

unread,
Jun 25, 2015, 6:55:48 PM6/25/15
to Joe Cheng, shiny-...@googlegroups.com
Hi again Joe and All,

I have found what my trouble is:

The future polygon's layerId is used when displaying the markers that are created in the process.
This layerId is set to 'NA' until the polygon is closed which is why every marker created while designing the polygon returns a NULL id...
That's rather silly since I actually had another variable (pointId) for that purpose...

I am very sorry for the trouble :-/

Thank you for your help  and for all the cool tools you code!

Best,
Bastien

Alejandra Montiel Saavedra

unread,
Jan 27, 2018, 12:01:00 AM1/27/18
to Shiny - Web Framework for R
How to erase each marker?
Y. When a user "deletes" a hospital, what he is really doing is that he is deleting a line in the data.frame, how do I do it?
Reply all
Reply to author
Forward
0 new messages