2

I have a leaflet map which has the draggable markers and shapes, user drawn features (with leaflet.draw plugin). Now I want to programmably retrieve all features in a layer/group from the leaflet map.

How should I achieve this function? Thanks for any suggestions.

Here I provided a simple example, a random set of markers is added into leaflet map with group markers (codes directly copied from https://rstudio.github.io/leaflet/shiny.html and made some changes). My target here is to retrieve the position of all new markers.

My real question is for polygons and may be complicated than this, but method should be similar.

library(shiny)
library(leaflet)

r_colors <- rgb(t(col2rgb(colors()) / 255))
names(r_colors) <- colors()

ui <- fluidPage(
  leafletOutput("mymap"),
  p(),
  actionButton("recalc", "New points"),
  verbatimTextOutput('summary')
)

server <- function(input, output, session) {

  points <- eventReactive(input$recalc, {
    cbind(rnorm(40) * 2 + 13, rnorm(40) + 48)
  }, ignoreNULL = FALSE)

  output$mymap <- renderLeaflet({
    leaflet() %>%
      addProviderTiles("Stamen.TonerLite",
                       options = providerTileOptions(noWrap = TRUE)
      ) %>%
      addMarkers(data = points(), group = 'markers')
  })

  output$summary <- renderPrint({
    # Add some codes here
    # .....

  })
}

shinyApp(ui, server)
3
  • I don't think this example mimics what you want. You won't be able to get the points drawn using m$x$calls[[2]]$args[[1]] because this just holds the parameters of the addMarkers function of your example. You'll probably need to write some javascript and use Shiny.onInputChange to send data back to the server.R. This post might be helpful to figure where to call Shiny.onInputChange. How are you using the draw plugin with Shiny?
    – NicE
    Commented Feb 25, 2016 at 14:08
  • there are also a lot of useful events that could be used here
    – NicE
    Commented Feb 25, 2016 at 14:14
  • @NicE - I've updated my solution to store the map object in reactiveValues() , which stores the parametes of the markers each time the object is drawn (on the button press). In your opinion is this what the OP is after?
    – SymbolixAU
    Commented Feb 25, 2016 at 21:25

1 Answer 1

1

To get the points from the map object, you can still use reactiveValues() to store the map object, and update this by observe()ing the button press. Then you can access all its properties.

library(shiny)
library(leaflet)

r_colors <- rgb(t(col2rgb(colors()) / 255))
names(r_colors) <- colors()

ui <- fluidPage(
    leafletOutput("mymap"),
    p(),
    actionButton("recalc", "New points"),
    verbatimTextOutput('summary')
)

server <- function(input, output, session) {

    rv <- reactiveValues()
    rv$m <- NULL
    rv$p <- NULL

    points <- eventReactive(input$recalc, {
        cbind(rnorm(40) * 2 + 13, rnorm(40) + 48)
    }, ignoreNULL = FALSE)

    output$mymap <- renderLeaflet({
        m <- leaflet() %>%
            addProviderTiles("Stamen.TonerLite",
                    options = providerTileOptions(noWrap = TRUE)) %>%
            addMarkers(data = points(), group = 'markers')
        rv$m <- m
        return(m)
    })

    observe({
        input$recalc
        ## I'm 90% confident these are the arguments you want...
        rv$p <- data.frame(x = rv$m$x$calls[[2]]$args[[1]],
                           y = rv$m$x$calls[[2]]$args[[2]])
    })

    output$summary <- renderPrint({
        # print points
        rv$p
    })
}

shinyApp(ui, server) 

Old solution

I'm leaving this here as it may still be useful to others

You can make use of reactiveValues() to store your point data in, and then output that data in your print

server <- function(input, output, session) {

  rv <- reactiveValues()
  rv$points <- cbind(rnorm(40) * 2 + 13, rnorm(40) + 48)

  observe({

    if(input$recalc){
      p <-  cbind(rnorm(40) * 2 + 13, rnorm(40) + 48)
      rv$points <- p
    }
  })

  output$mymap <- renderLeaflet({
    leaflet() %>%
      addProviderTiles("Stamen.TonerLite",
                       options = providerTileOptions(noWrap = TRUE)
      ) %>%
      addMarkers(data = rv$points, group = 'markers')
  })

  output$summary <- renderPrint({
    # Add some codes here
    # .....
    rv$points
  })
}
shinyApp(ui, server)
5
  • Thanks for your reply I understand this method, but I really want to retrieve data from leaflet map as I have users drawn features which cannot put in the reactive objects
    – Bangyou
    Commented Feb 25, 2016 at 11:34
  • @Bangyou - ok, this slightly changes the question, but, I've added an update that gets you half-way. I've not yet worked out how to get the information from shiny yet.
    – SymbolixAU
    Commented Feb 25, 2016 at 11:52
  • @Bangyou - I've updated with a solution to retrieve data from the map
    – SymbolixAU
    Commented Feb 25, 2016 at 21:22
  • Great solution. Thanks for your help.
    – Bangyou
    Commented Feb 26, 2016 at 1:17
  • 1
    No problem - this question taught me something new too :)
    – SymbolixAU
    Commented Feb 26, 2016 at 1:31

Not the answer you're looking for? Browse other questions tagged or ask your own question.