1. Purpose

The purpose of this noteboook is to illustrate how the leaflet package can be used to create html maps.

2. Load relevant libraries and view practice datasets.

library(dplyr)
library(leaflet)
library(sf)
library(sp)
library(rgdal)
spData::nz
## Simple feature collection with 16 features and 6 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: 1090144 ymin: 4748537 xmax: 2089533 ymax: 6191874
## epsg (SRID):    2193
## proj4string:    +proj=tmerc +lat_0=0 +lon_0=173 +k=0.9996 +x_0=1600000 +y_0=10000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
## First 10 features:
##                 Name Island Land_area Population Median_income Sex_ratio
## 1          Northland  North 12500.561     175500         23400 0.9424532
## 2           Auckland  North  4941.573    1657200         29600 0.9442858
## 3            Waikato  North 23900.036     460100         27900 0.9520500
## 4      Bay of Plenty  North 12071.145     299900         26200 0.9280391
## 5           Gisborne  North  8385.827      48500         24400 0.9349734
## 6        Hawke's Bay  North 14137.524     164000         26100 0.9238375
## 7           Taranaki  North  7254.480     118000         29100 0.9569363
## 8  Manawatu-Wanganui  North 22220.608     234500         25000 0.9387734
## 9         Wellington  North  8048.553     513900         32700 0.9335524
## 10        West Coast  South 23245.456      32400         26900 1.0139072
##                              geom
## 1  MULTIPOLYGON (((1745493 600...
## 2  MULTIPOLYGON (((1803822 590...
## 3  MULTIPOLYGON (((1860345 585...
## 4  MULTIPOLYGON (((2049387 583...
## 5  MULTIPOLYGON (((2024489 567...
## 6  MULTIPOLYGON (((2024489 567...
## 7  MULTIPOLYGON (((1740438 571...
## 8  MULTIPOLYGON (((1866732 566...
## 9  MULTIPOLYGON (((1881590 548...
## 10 MULTIPOLYGON (((1557042 531...
spData::nz_height
## Simple feature collection with 101 features and 2 fields
## geometry type:  POINT
## dimension:      XY
## bbox:           xmin: 1204143 ymin: 5048309 xmax: 1822492 ymax: 5650492
## epsg (SRID):    2193
## proj4string:    +proj=tmerc +lat_0=0 +lon_0=173 +k=0.9996 +x_0=1600000 +y_0=10000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
## First 10 features:
##    t50_fid elevation                geometry
## 1  2353944      2723 POINT (1204143 5049971)
## 2  2354404      2820 POINT (1234725 5048309)
## 3  2354405      2830 POINT (1235915 5048745)
## 4  2369113      3033 POINT (1259702 5076570)
## 5  2362630      2749 POINT (1378170 5158491)
## 6  2362814      2822 POINT (1389460 5168749)
## 7  2362817      2778 POINT (1390166 5169466)
## 8  2363991      3004 POINT (1372357 5172729)
## 9  2363993      3114 POINT (1372062 5173236)
## 10 2363994      2882 POINT (1372810 5173419)

3. Ensure object is of sf class with CRS of WGS84 (i.e. longs and lats).

leaflet works easiest in longs and lats (i.e. WGS84), so we will work to get the data into this format. We need to use as(., "Spatial") %>% spTransform(CRS("+init=epsg:4326 +lon_wrap=180")) %>% st_as_sf() to ensure that there are no dateline issues when map data includes Chatham Islands.

#for a data.frame in WGS84 (i.e. longs and lats)
df <- read_csv("object_name.csv")

x_var <- "long"
y_var <- "lat"

df <- df %>%
  st_as_sf(coords = c(x_var, y_var)) %>% 
  st_set_crs(4326) %>% 
  as(., "Spatial") %>% 
  spTransform(CRS("+init=epsg:4326 +lon_wrap=180")) %>% 
  st_as_sf()

#for a data.frame in a different CRS (i.e. northing and easting)
df <- read_csv("object_name.csv")

x_var <- "nztmn"
y_var <- "nztme"

df <- df %>%
  st_as_sf(coords = c(x_var, y_var)) %>% 
  st_set_crs(2193) %>% #2193 for nztm or 27200 for nzmg
  as(., "Spatial") %>% 
  spTransform(CRS("+init=epsg:4326 +lon_wrap=180")) %>% 
  st_as_sf()

#for a shapefile in WGS84
df <- st_read("object_name.shp")

df <- df %>%  
  st_set_crs(4326) %>% 
  as(., "Spatial") %>% 
  spTransform(CRS("+init=epsg:4326 +lon_wrap=180")) %>% 
  st_as_sf()

#for a shapefile in a different CRS
df <- st_read("object_name.shp")

df <- df %>%  
  st_set_crs(2193) %>% #2193 for nztm or 27200 for nzmg
  as(., "Spatial") %>% 
  spTransform(CRS("+init=epsg:4326 +lon_wrap=180")) %>% 
  st_as_sf()

4. Create a point map using an sf object in WGS84.

#create a map using the an sf object in WGS84
df <- spData::nz_height %>% st_transform(4326)
z_var <- df$elevation
colour_no <- 4
colour_reverse <- T
legend_digits <- 0
#legend_title <- paste("Wind speed", "km/hr", "1975\u20132015", sep = "<br/>")

#adjust generic code only if necessary
if (is.character(z_var) | is.factor(z_var)) pal_col_name <- "Set1"
if (is.numeric(z_var)) pal_col_name <- "Spectral"
pal <- RColorBrewer::brewer.pal(colour_no, pal_col_name)
#pal <- c("#d73027","#A8A8A8","#4575b4") #manually add a colour vector in

if (is.character(z_var) | is.factor(z_var) | is.logical(z_var)) pal_fun <- colorFactor(palette = pal, domain = z_var, reverse = colour_reverse)
if (is.numeric(z_var)) pal_fun <- colorBin(palette = pal, domain = z_var, bins = colour_no, pretty = T, reverse = colour_reverse)
#if (is.numeric(z_var)) pal_fun <- colorBin(palette = pal, domain = z_var, bins=quantile(z_var, probs=seq(0, 1, 1/colour_no)), reverse = colour_reverse) #quantiles
#if (is.numeric(z_var)) pal_fun <- colorNumeric(palette = pal, domain = z_var, reverse = colour_reverse)

#if geometry type is POINT or MULTIPOINT
leaflet() %>% 
  addProviderTiles("Esri.WorldGrayCanvas") %>% 
  addCircleMarkers(data = df, 
    color = ~pal_fun(z_var),
    label = ~as.character(z_var),
    radius = 2, 
    opacity = 1, 
    fillOpacity = 1, 
    weight = 2
  ) %>% 
  addLegend(pal = pal_fun, 
    values = z_var, 
    #title = legend_title, 
    position = "bottomright", 
    opacity = 1, 
    labFormat = labelFormat(between = "&ndash;", digits = legend_digits)
  )

5. Create a polygon map using an sf object in WGS84.

#if geometry type is a POLYGON or MULTIPOLYGON, use the following code.
df <- spData::nz %>% st_transform(4326)
z_var <- df$Population
colour_no <- 10
colour_reverse <- T
legend_digits <- 0
#legend_title <- paste("Wind speed", "km/hr", "1975\u20132015", sep = "<br/>")

#adjust generic code only if necessary
if (is.character(z_var) | is.factor(z_var)) pal_col_name <- "Set1"
if (is.numeric(z_var)) pal_col_name <- "Spectral"
pal <- RColorBrewer::brewer.pal(colour_no, pal_col_name)
#pal <- c("#d73027","#A8A8A8","#4575b4") #manually add a colour vector in

if (is.character(z_var) | is.factor(z_var) | is.logical(z_var)) pal_fun <- colorFactor(palette = pal, domain = z_var, reverse = colour_reverse)
if (is.numeric(z_var)) pal_fun <- colorBin(palette = pal, domain = z_var, bins = colour_no, pretty = T, reverse = colour_reverse)
#if (is.numeric(z_var)) pal_fun <- colorBin(palette = pal, domain = z_var, bins=quantile(z_var, probs=seq(0, 1, 1/colour_no)), reverse = colour_reverse) #quantiles
#if (is.numeric(z_var)) pal_fun <- colorNumeric(palette = pal, domain = z_var, reverse = colour_reverse)
 
leaflet() %>%
  addProviderTiles("Esri.WorldGrayCanvas") %>%
  addPolygons(data = df,
     fillColor = ~pal_fun(z_var), color = "black",
     label = ~as.character(z_var),
     opacity = 1,
     fillOpacity = 1,
     weight = 0.5
  ) %>%
  addLegend(pal = pal_fun,
    values = z_var,
    #title = legend_title,
    position = "bottomright",
    opacity = 1,
    labFormat = labelFormat(between = "&ndash;", digits = legend_digits)
  )

6. Note you can adjust the format of labels to add comma’s or a +/- sign.

df <- spData::nz_height %>% st_transform(4326)
z_var <- df$elevation

str_paste_plus_sign <- function(x) {
    ifelse(stringr::str_sub(x, 1, 1) == "-", x, paste0("+", x))
  }

leaflet() %>% 
  addProviderTiles("Esri.WorldGrayCanvas") %>% 
  addCircleMarkers(data = df, radius = 1, weight = 2,
    label = ~formatC(z_var, format = "f", digits = 0, big.mark = ",")
    )

leaflet() %>% 
  addProviderTiles("Esri.WorldGrayCanvas") %>% 
  addCircleMarkers(data = df, radius = 1, weight = 2,
    label = ~str_paste_plus_sign(z_var)
    )

leaflet() %>% 
  addProviderTiles("Esri.WorldGrayCanvas") %>% 
  addCircleMarkers(data = df, radius = 1, weight = 2,
    label = ~str_paste_plus_sign(formatC(z_var, format = "f", digits = 0, big.mark = ","))
    )