Reputation: 133
I want to sync two maps in an R shiny web app(zooming in on one map should zoom in on the other map and panning etc), I managed to do this interactively using the code shown below but I can't figure out how to do this in a Shiny web app.
my_map <- function(x){
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=x[1], lat=x[2], popup="The birthplace of R")
m
}
y <- c(174.968, 37.852)
x <- c(0.112281, 51.523001)
sync(my_map(x), my_map(y), no.initial.sync = TRUE)
Upvotes: 3
Views: 1709
Reputation: 121
Using sync()
as an UI output, not as leafletOutput
worked for me.
In ui
:
uiOutput("synced_maps")
In server
:
output$synced_maps <- renderUI({
m1 <- leaflet() %>% addTiles() %>% addMarkers(~lon1, ~lat1)
m2 <- leaflet() %>% addTiles() %>% addMarkers(~lon2, ~lat2)
sync(m1, m2)
})
Upvotes: 6
Reputation: 30474
Will the maps always be made prior to user interface creation? If so:
library(leaflet)
library(leafsync)
library(shiny)
my_map <- function(x){
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=x[1], lat=x[2], popup="The birthplace of R")
m
}
y <- c(174.968, 37.852)
x <- c(0.112281, 51.523001)
ui <- sync(my_map(x), my_map(y), no.initial.sync = TRUE)
server = function(input,output){
}
shinyApp(ui, server)
Edit:
In response to your comment, I have looked at options to sync maps including a javascript approach (https://github.com/jieter/Leaflet.Sync) and syncWith (https://github.com/rte-antares-rpackage/leaflet.minicharts). I have not spent time with these.
A quick workaround could be this below (one map's bounds matches the other map's bounds, but not vice versa). It requires adding observe to the server function and setting the bounds from one map to the other. From http://rstudio.github.io/leaflet/shiny.html:
input$MAPID_bounds provides the latitude/longitude bounds of the currently visible map area; the value is a list() that has named elements north, east, south, and west
library(leaflet)
library(leafsync)
library(shiny)
my_map <- function(x){
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=x[1], lat=x[2], popup="The birthplace of R")
m
}
y <- c(174.968, 37.852)
x <- c(0.112281, 51.523001)
ui <- fluidPage(
leafletOutput("mymap1"),
leafletOutput("mymap2")
)
server = function(input, output){
output$mymap1 = renderLeaflet({
my_map(x)
})
output$mymap2 = renderLeaflet({
my_map(y)
})
observe({
coords <- input$mymap1_bounds
if (!is.null(coords)) {
leafletProxy("mymap2") %>%
fitBounds(coords$west,
coords$south,
coords$east,
coords$north)
}
})
}
shinyApp(ui, server)
Upvotes: 2