Synchronizing two leaflet maps in R / Rmarkdown

旧巷老猫 提交于 2019-12-03 18:55:39

Note, we have implemented the answer provided by @timelyportfolio in package mapview so that this is now easily achievable using mapview::sync(). See ?mapview::sync for instructions and examples.

Here is a way to sync the two leaflet maps, but unfortunately it does not work in RStudio Viewer. This does work in Chrome and Firefox. There are lots of ways to make this much more robust. I tried to add comments in the R code below to explain what is happening.

---
title: "How to sync 2 leaflet maps"
author: "me"
date: "2 April 2016"
output: html_document
---

```{r SETUP, include=FALSE}
#  get the latest htmlwidgets
#   devtools::install_github("ramnathv/htmlwidgets")
library("htmlwidgets")
library("htmltools")
library("mapview")
library("sp")

# load example data
data(meuse)
coordinates(meuse) <- ~x+y
proj4string(meuse) <- CRS("+init=epsg:28992")
```

```{r MAPS}
mapView(meuse, zcol="copper")@map # MAP 1
mapview(meuse, zcol="soil")@map # MAP 2
```

```{r}
#  crudely add the leaflet-sync plugin
#   attachDependency with the rawgit gave me
#   errors so just do this for now
#   could easily add to a package
#   or make a mini package to import this
#   dependency
tags$script(
  type="text/javascript",
  src="https://cdn.rawgit.com/turban/Leaflet.Sync/master/L.Map.Sync.js"
)
```

```{r}
# this is one of the new htmlwidgets methods
#  to add some code after all htmlwidgets are rendered
#  this is very useful since we need all htmlwidgets rendered
#  before we can sync
onStaticRenderComplete(
'
var leaf_widgets = Array.prototype.map.call(
  document.querySelectorAll(".leaflet"),
  function(ldiv){
    return HTMLWidgets.find("#" + ldiv.id);
  }
);

// make this easy since we know only two maps
leaf_widgets[0].sync(leaf_widgets[1]);
leaf_widgets[1].sync(leaf_widgets[0]);
'
)
```

Here is how we can do the same thing in straight R code.

#  http://stackoverflow.com/questions/36373842/synchronizing-two-leaflet-maps-in-r-rmarkdown

#  get the latest htmlwidgets
#   devtools::install_github("ramnathv/htmlwidgets")
library("htmlwidgets")
library("htmltools")
library("mapview")
library("sp")

# load example data
data(meuse)
coordinates(meuse) <- ~x+y
proj4string(meuse) <- CRS("+init=epsg:28992")
map1 <- mapView(meuse, zcol="copper")@map # MAP 1
map2 <- mapview(meuse, zcol="soil")@map # MAP 2

tagList(
  tags$head(tags$script(
    type="text/javascript",
    src="https://cdn.rawgit.com/turban/Leaflet.Sync/master/L.Map.Sync.js"
  )),
  map1,
  map2,
  onStaticRenderComplete(
'
var leaf_widgets = Array.prototype.map.call(
  document.querySelectorAll(".leaflet"),
  function(ldiv){
    return HTMLWidgets.find("#" + ldiv.id);
  }
);

// make this easy since we know only two maps
leaf_widgets[0].sync(leaf_widgets[1]);
leaf_widgets[1].sync(leaf_widgets[0]);
'
  )
) %>%
  browsable

And if you want it side-by-side, here is the basic way to accomplish. We could leverage shiny::fluidPage, fluidRow, and column to get boostrap, but the css/js is really heavy for just side-by-side placement.

#  get the latest htmlwidgets
#   devtools::install_github("ramnathv/htmlwidgets")
library("htmlwidgets")
library("htmltools")
library("shiny")
library("mapview")
library("sp")

# load example data
data(meuse)
coordinates(meuse) <- ~x+y
proj4string(meuse) <- CRS("+init=epsg:28992")
map1 <- mapView(meuse, zcol="copper")@map # MAP 1
map2 <- mapview(meuse, zcol="soil")@map # MAP 2

tagList(
  tags$head(tags$script(
    type="text/javascript",
    src="https://cdn.rawgit.com/turban/Leaflet.Sync/master/L.Map.Sync.js"
  )),
  tags$div(style="display:inline;width:50%;float:left;",map1),
  tags$div(style="display:inline;width:50%;float:left;",map2),
  onStaticRenderComplete(
'
var leaf_widgets = Array.prototype.map.call(
  document.querySelectorAll(".leaflet"),
  function(ldiv){
    return HTMLWidgets.find("#" + ldiv.id);
  }
);

// make this easy since we know only two maps
leaf_widgets[0].sync(leaf_widgets[1]);
leaf_widgets[1].sync(leaf_widgets[0]);
'
  )
) %>%
  browsable
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!