rgoogle-mapsopenstreetmapr-mapviewr-leaflet

How can I make my two R leaflet maps synchronise with each other?


I have had some nice success implementing Leaflet package in R for some data.

I have also managed to put two maps side by side as a lattice, and as a sync.

I have two issues:

1) Sync...does not sync the maps at all

I am using Mapview and Raster to attempt sync but the two maps side by side do not zoom in/out together.

See the code below:

library(leaflet)
library(ggmap)
library(mapview)
library(raster)
library(magrittr)
UK <- ggmap::geocode("United Kingdom")

#FILE1 <- read.csv("DATASET1.csv")
#FILE2 <- read.csv("DATASET2.csv")
FILE1 <- data.frame('lat' = c(51.31, 51.52, 51.53), 'lon' = c(0.06, 0.11, 0.09))
FILE2 <- data.frame('lat' = c(52.20, 52.25, 52.21), 'lon' = c(0.12, 0.12, 0.12))

map1 <- leaflet(FILE1)%>%
  addTiles()%>%
  addMarkers(clusterOptions = markerClusterOptions())

map2 <- leaflet(FILE2)%>%
  addTiles()%>%
  addMarkers(clusterOptions = markerClusterOptions())

sync(map1,map2)

I am sure I am missing something simple here but hopefully someone can help me in seeing that :)

2) Ideally I want one leaflet map to overlap the other one

I want to differentiate them by using different markets for each map. I have attempted to research this on the internet and through reading the manuals for leaflet but to no success

any guidance greatly appreciated!


Solution

  • 1) Syncing two maps

    Installing the development version solved this for me

    # Dependencies
    # If your devtools is not the latest version
    # then you might have to install "units" manually
    install.packages('units') 
    install.packages('devtools')
    library(devtools)
    
    devtools::install_github("environmentalinformatics-marburg/mapview", ref = "develop")
    

    The code I used:

    library(leaflet)
    library(ggmap)
    library(mapview)
    library(raster)
    library(magrittr)
    UK <- ggmap::geocode("United Kingdom")
    
    #FILE1 <- read.csv("DATASET1.csv")
    #FILE2 <- read.csv("DATASET2.csv")
    FILE1 <- data.frame('lat' = c(51.31, 51.52, 51.53), 'lon' = c(0.06, 0.11, 0.09))
    FILE2 <- data.frame('lat' = c(52.20, 52.25, 52.21), 'lon' = c(0.12, 0.12, 0.12))
    
    map1 <- leaflet(FILE1)%>%
      addTiles()%>%
      addMarkers(clusterOptions = markerClusterOptions())
    
    map2 <- leaflet(FILE2)%>%
      addTiles()%>%
      addMarkers(clusterOptions = markerClusterOptions())
    
    mapview::latticeView(map1, map2, ncol = 2, sync = list(c(1, 2)), sync.cursor = FALSE, no.initial.sync = FALSE)
    # Or:
    sync(map1, map2)
    

    2) Overlaying two maps

    You can use two separate data frames as data sources and add them to the same map separately. Change the symbol style to be able to differentiate between them.

    map3 <- leaflet(FILE2)%>%
      addTiles() %>%
      addCircleMarkers(data = FILE1) %>%
      addCircleMarkers(data = FILE2,
                       color = '#0FF')
    map3
    

    If you want to do something similar for the cluster markers, there is some good documentation on that here and here. Based on some of the code from those posts I created a suggestion below where I use the pre-existing styles to differentiate between clusters of different types:

    FILE1 <- data.frame('lat' = rnorm(n = 1000, mean = 51.4, sd = 0.5), 
                        'lon' = rnorm(n = 1000, mean = 0.8, sd = 0.5))
    FILE2 <- data.frame('lat' = rnorm(n = 1000, mean = 53, sd = 0.5), 
                        'lon' = rnorm(n = 1000, mean = -0.5, sd = 0.5))
    
    map3 <- leaflet(rbind(FILE1, FILE2)) %>%
      addTiles() %>%
      addCircleMarkers(data = FILE1,
        color = '#FA5',
        opacity = 1,
        clusterOptions = markerClusterOptions(iconCreateFunction = JS("function (cluster) {    
          var childCount = cluster.getChildCount(); 
          var c = ' marker-cluster-';  
          if (childCount < 3) {  
            c += 'large';  
          } else if (childCount < 5) {  
            c += 'large';  
          } else { 
            c += 'large';  
          }    
          return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', 
          className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });
      
        }"))) %>%
      addCircleMarkers(data = FILE2,
        color = '#9D7',
        opacity = 1,
        clusterOptions = markerClusterOptions(iconCreateFunction = JS("function (cluster) {    
          var childCount = cluster.getChildCount(); 
          var c = ' marker-cluster-';  
          if (childCount < 3) {  
            c += 'small';  
          } else if (childCount < 5) {  
            c += 'small';  
          } else { 
            c += 'small';  
          }    
          return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', 
          className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });
      
        }")))
    

    example map