9  Map display

9.1 leaflet in R

Leaflet is a powerful, open-source JavaScript library designed specifically for creating interactive maps on websites.

How it Works (very basically)

  • Leaflet uses map tiles (small image sections) from a provider like OpenStreetMap.
  • It assembles these tiles to create a seamless map within an HTML container on a webpage.
  • JavaScript code lets you customize the map’s appearance, add interactive elements, and respond to user actions.

Getting Started

  • The easiest way to start is often with the leaflet package for R

9.1.1 Leaflet in R Tutorial

  1. Installation

Make sure you have the leaflet package installed. Use the following code in your R console:

if(!require("leaflet")) install.packages("leaflet")
if(!require("tidyverse")) install.packages("tidyverse")
  1. Basic Map Creation

Here’s a minimal example of how to create a simple Leaflet map in R:

library(tidyverse)
library(leaflet)

leaflet() %>% 
  addTiles() 
  • library(leaflet): Loads the Leaflet package for use.
  • leaflet(): Creates a new Leaflet map object.
  • addTiles(): Adds the default OpenStreetMap base tiles to your map.
  1. key Function

Here’s a more tailored example:

library(leaflet)

leaflet() %>%
  addTiles() %>%
  setView(lat = 37.56, lng = 126.9780,  zoom = 7.5) %>%  # Seoul in Korea
  addMarkers(lat = 37.56, lng = 126.9780, popup = "I am Here !")
  1. Add Provider

What are Providers?

  • Providers are sources of map tile data. Think of map tiles as the small image squares that get pieced together to form the full map you see in Leaflet.
  • Each provider offers a different visual style or type of map data. This could be standard street maps, satellite imagery, terrain maps, artistic styles, and more.

Common Providers

  • OpenStreetMap:

    • OpenStreetMap: The standard, crowd-sourced map style.
    • OpenTopoMap: A map highlighting topographic features.
  • CartoDB:

    • CartoDB.Positron: A light and minimalist map.
    • CartoDB.DarkMatter: A dark-themed map.
  • Esri:

    • Esri.WorldImagery: High-resolution satellite imagery.
    • Esri.WorldStreetMap: A standard street map from Esri.
    • Esri.NatGeoWorldMap: National Geographic style.
  • Stamen:

    • Stamen.Toner: Black and white stylized map.
    • Stamen.Watercolor: Artistic watercolor style.
    • Stamen.Terrain: Emphasizes terrain and elevation.
leaflet() %>%
  addProviderTiles("CartoDB.Positron", group = 'Positron') %>%
  addProviderTiles("Esri.WorldImagery", group = 'WorldImagery') %>%
  addProviderTiles("OpenStreetMap", group = 'OpenStreetMap') %>%
  addLayersControl(
    baseGroups = c('Positron','WorldImagery', 'OpenStreetMap'), 
    options = layersControlOptions(collapsed = TRUE)
  ) %>%
  setView(lng = 127.5, 36.5, zoom = 7.5)
  1. Marker
leaflet() %>%
  addProviderTiles("CartoDB.Positron", group = 'Positron') %>%
  addProviderTiles("Esri.WorldImagery", group = 'WorldImagery') %>%
  addProviderTiles("OpenStreetMap", group = 'OpenStreetMap') %>%
  addLayersControl(
    baseGroups = c('Positron','WorldImagery', 'OpenStreetMap'),
    options = layersControlOptions(collapsed = TRUE)
  ) %>%
  setView(lng = 127.5, lat = 36.5, zoom = 5) %>%
  addMarkers(lng = 126.9780, lat = 37.5665, popup = "<b>Seoul</b>") %>% 
  addMarkers(lng = 129.0756, lat = 35.1796, popup = "<b>Busan</b>") 
  • addMarkers(…): We’ve added multiple instances of the addMarkers function to place markers at different locations.
    • lng and lat: Specify the longitude and latitude coordinates of each marker.
    • popup: This optional argument lets you add a popup that appears when the marker is clicked. You can customize this with HTML content.
  1. Adding Circle Markers Circle markers are useful for indicating areas or regions rather than just points. Here’s how to add them:
leaflet() %>%
  addProviderTiles("CartoDB.Positron") %>%
  setView(lng = 127.5, lat = 36.5, zoom = 7) %>%
  addCircleMarkers(lng = 126.9780, lat = 37.5665, radius = 10, color = "blue", popup = "Seoul Circle") %>%
  addCircleMarkers(lng = 129.0756, lat = 35.1796, radius = 10, color = "red", popup = "Busan Circle")
  1. Adding Polygons Polygons can be used to highlight specific areas on the map:
leaflet() %>%
  addProviderTiles("CartoDB.Positron") %>%
  setView(lng = 127.5, lat = 36.5, zoom = 7) %>%
  addPolygons(
    lng = c(126.9780, 126.9780, 129.0756, 129.0756), 
    lat = c(37.5665, 35.1796, 35.1796, 37.5665), 
    color = "green", 
    weight = 2, 
    fillOpacity = 0.5
  )
  1. Adding Popups with HTML Content Popups can include more than just text. You can add HTML content for richer information display or hyperlink:
leaflet() %>%
  addProviderTiles("CartoDB.Positron") %>%
  setView(lng = 127.5, lat = 36.5, zoom = 7) %>%
  addMarkers(
    lng = 126.9780, 
    lat = 37.5665, 
    popup = "<b>SEHnR <br> We are here </b><br><a href='https://sehnr.org' ><img src='https://sehnr.org/static/assets/img/researcher.png' width='100%'>" 
  )
  1. Adding GeoJSON Data GeoJSON is a format for encoding geographic data structures. You can add GeoJSON data to your map:
if(!require("geojsonio")) install.packages("geojsonio")
library(geojsonio)
library(geojsonio)
library(sp)

# GeoJSON data for an example region
geojson <- '{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 126.9780, 37.5665 ], [ 127.9780, 37.5665 ], [ 127.9780, 36.5665 ], [ 126.9780, 36.5665 ], [ 126.9780, 37.5665 ] ] ] } } ] }'

# Convert GeoJSON string to spatial object
geojson_sp <- geojsonio::geojson_sp(geojson)

# Set CRS to WGS 84
proj4string(geojson_sp) <- CRS("+proj=longlat +datum=WGS84 +no_defs")

# Create leaflet map
leaflet() %>%
  addProviderTiles("CartoDB.Positron") %>%
  setView(lng = 127.5, lat = 36.5, zoom = 7) %>%
  addPolygons(data = geojson_sp, color = "blue", weight = 2, fillOpacity = 0.5)
  1. Custom Icons for Markers Custom icons can make your markers more visually appealing or informative:
library(leaflet)

# Define the custom icon
seoul_icon <- makeIcon(
  iconUrl = "https://sehnr.org/media/post_images/books_chart.png",
  iconWidth = 30, iconHeight = 30
)

leaflet() %>%
  addProviderTiles("CartoDB.Positron") %>%
  setView(lng = 127.5, lat = 36.5, zoom = 7) %>%
  addMarkers(
    lng = 126.9780, 
    lat = 37.5665, 
    icon = seoul_icon, 
    popup = "<b>Seoul</b>"
  )

9.2 Handling Shapefiles and Visualizing Polygons with Leaflet

  1. Installation and Setup First, ensure that the required packages are installed and loaded. This includes sf for handling spatial data, leaflet for creating interactive maps, and leafgl for rendering large datasets efficiently.
if(!require("sf")) install.packages("sf", dependencies = TRUE)
if(!require("leaflet")) install.packages("leaflet")
if(!require("leafgl")) install.packages("leafgl")
library(sf)
library(leaflet)
library(leafgl)
  1. Reading Shapefiles Assume that your shapefiles are stored in the “data” directory. Use list.files to identify the shapefiles and st_read to load a specific shapefile.
shp.data <- "https://raw.githubusercontent.com/jinhaslab/opendata/main/data/shp_korea.zip"
if (!dir.exists("data/shp_korea")) {dir.create("data/shp_korea",  recursive = TRUE)}
download.file(shp.data, "data/shp_korea/shp_korea.zip")
unzip("data/shp_korea/shp_korea.zip", exdir = "data/shp_korea") 
file.remove("data/shp_korea/shp_korea.zip")

Use list.files to identify the shapefiles and st_read to load a specific shapefile.

files <- list.files(path="data/shp_korea", pattern="\\.shp$", full.names = TRUE)
print(files)
[1] "data/shp_korea/ctprvn_short.shp" "data/shp_korea/emd_short.shp"   
[3] "data/shp_korea/sig_short.shp"   
sf = st_read("data/shp_korea/ctprvn_short.shp")
Reading layer `ctprvn_short' from data source 
  `/home/dspub/books/dashboard_project/data/shp_korea/ctprvn_short.shp' 
  using driver `ESRI Shapefile'
Simple feature collection with 17 features and 4 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 746110.3 ymin: 1458756 xmax: 1387898 ymax: 2068439
Projected CRS: Korea 2000 / Unified CS

CRS stands for Coordinate Reference System. It is a system that uses coordinates to relate spatial data to specific locations on the earth. Different CRSs are used to project the 3D surface of the earth onto a 2D plane, which is essential for accurate mapping and spatial analysis. When you use st_crs(sf) <- 5179, This ensures that the data is correctly interpreted in the context of South Korea’s specific projected coordinate system.

EPSG:4326 is another CRS known as WGS 84 (World Geodetic System 1984). 4326 is an EPSG code for this global geographic coordinate system. EPSG:4326 uses degrees of latitude and longitude, making it ideal for global positioning and web mapping applications.

st_crs(sf) <- 5179
sf_tr <- st_transform(sf, 4326)
# Add an order column for color scaling
sf_tr$order <- 1:nrow(sf_tr)
  1. Visualizing with Leaflet

Visualize the simplified shapefile using Leaflet. Use a color palette to highlight different regions or properties.

# General coordinates for Korea
korea_lat <- 36
korea_lng <- 128

# Create a color palette based on the order
pal <- colorQuantile("YlOrRd", sf_tr$order, n = 9)

# Create a Leaflet map
leaflet(data = sf_tr) %>%
  addProviderTiles("CartoDB.Positron") %>%  # Adds a light-themed base map from CartoDB
  setView(lng = korea_lng, lat = korea_lat, zoom = 6.4) %>%
  addPolygons(
    fillColor = ~pal(order),
    color = "#444444",   # Border color of the polygons
    weight = 1,          # Border width
    opacity = 1,
    fillOpacity = 0.7,   # Fill opacity of the polygons
    smoothFactor = 0.5,
    highlightOptions = highlightOptions(
      color = "white", 
      weight = 2,
      bringToFront = TRUE
    )
  )