Layers overview
layers-overview.Rmd
Using layers: an overview
In Mapbox GL JS and MapLibre, datasets are added to maps as sources which are then styled as layers. mapgl aims to expose the sources and layers APIs to R users in ways that honor the deep customization available in the JavaScript libraries but also accommodate R users’ typical workflows.
Geospatial practitioners in R will typically work with objects from
the sf package. The initial release of
mapgl natively supports sf
objects, and
will aim to support other geospatial formats (such as objects from the
terra package) in the future.
Objects of class sf
can be specified as sources for the
map either through the add_source()
function or via the
source
parameter in one of mapgl’s layer
functions. The add_fill_layer()
function calls the Mapbox
GL JS addLayer()
function internally with a
fill
type, and enumerates the available options for styling
the layer as function arguments.
mapgl users will often want to use the
bounds
argument when initializing the map, or alternatively
the fit_bounds()
function, to fix the map view to a given
layer’s bounding box.
## Reading layer `nc' from data source
## `/Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/library/sf/shape/nc.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 100 features and 14 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
## Geodetic CRS: NAD27
mapboxgl(bounds = nc) |>
add_fill_layer(id = "nc_data",
source = nc,
fill_color = "blue",
fill_opacity = 0.5)
An overview of available layers in mapgl are below.
Layers can be used with either mapboxgl()
or
maplibre()
maps.
Line layers
## To enable caching of data, set `options(tigris_use_cache = TRUE)`
## in your R script or .Rprofile.
options(tigris_use_cache = TRUE)
loving_roads <- roads("TX", "Loving")
maplibre(style = maptiler_style("backdrop"),
bounds = loving_roads) |>
add_line_layer(
id = "roads",
source = loving_roads,
line_color = "navy",
line_opacity = 0.7
)
Circle layers
Circle layers are typically used to represent point data on
your map. Circle clustering is implemented with the
cluster_options
argument, to which a list generated by the
cluster_options()
function can be passed.
library(mapgl)
library(sf)
library(dplyr)
# Set seed for reproducibility
set.seed(1234)
# Define the bounding box for Washington DC (approximately)
bbox <- st_bbox(c(
xmin = -77.119759,
ymin = 38.791645,
xmax = -76.909393,
ymax = 38.995548
),
crs = st_crs(4326))
# Generate 30 random points within the bounding box
random_points <- st_as_sf(
data.frame(
id = 1:30,
lon = runif(30, bbox["xmin"], bbox["xmax"]),
lat = runif(30, bbox["ymin"], bbox["ymax"])
),
coords = c("lon", "lat"),
crs = 4326
)
# Assign random categories
categories <- c('music', 'bar', 'theatre', 'bicycle')
random_points <- random_points %>%
mutate(category = sample(categories, n(), replace = TRUE))
# Map with circle layer
mapboxgl(style = mapbox_style("dark"),
bounds = random_points) %>%
add_circle_layer(
id = "poi-layer",
source = random_points,
circle_color = match_expr(
"category",
values = c("music", "bar", "theatre",
"bicycle"),
stops = c("#1f78b4", "#33a02c",
"#e31a1c", "#ff7f00")
),
circle_radius = 8,
circle_stroke_color = "#ffffff",
circle_stroke_width = 2,
circle_opacity = 0.8,
tooltip = "category",
hover_options = list(circle_radius = 12,
circle_color = "#ffff99")
) %>%
add_categorical_legend(
legend_title = "Points of Interest",
values = c("Music", "Bar", "Theatre", "Bicycle"),
colors = c("#1f78b4", "#33a02c", "#e31a1c", "#ff7f00"),
circular_patches = TRUE
)
Symbol layers
Symbol layers offer a wide range of arguments for customizing icon
and label appearance; however not all arguments will work with all
icons. The icon_image
argument will look for a string that
represents an icon found in the map style’s sprite. Read more
about sprites here.
mapboxgl(style = mapbox_style("light"),
bounds = random_points) |>
add_symbol_layer(
id = "points-of-interest",
source = random_points,
icon_image = get_column("category"),
icon_allow_overlap = TRUE,
tooltip = "category"
)
Heatmap layers
Heatmap layers take an object of geometry type POINT and visualize
the density of those points in a visually attractive way.
add_heatmap_layer()
takes sf POINT
objects; the example below shows how to read in a remote GeoJSON file as
a source as well.
library(mapgl)
mapboxgl(style = mapbox_style("dark"),
center = c(-120, 50),
zoom = 2) |>
add_heatmap_layer(
id = "earthquakes-heat",
source = list(
type = "geojson",
data = "https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson"
),
heatmap_weight = interpolate(
column = "mag",
values = c(0, 6),
stops = c(0, 1)
),
heatmap_intensity = interpolate(
property = "zoom",
values = c(0, 9),
stops = c(1, 3)
),
heatmap_color = interpolate(
property = "heatmap-density",
values = seq(0, 1, 0.2),
stops = c('rgba(33,102,172,0)', 'rgb(103,169,207)',
'rgb(209,229,240)', 'rgb(253,219,199)',
'rgb(239,138,98)', 'rgb(178,24,43)')
),
heatmap_opacity = 0.7
)
Fill-extrusion layers
library(mapgl)
maplibre(
style = maptiler_style("basic"),
center = c(-74.0066, 40.7135),
zoom = 15.5,
pitch = 45,
bearing = -17.6
) |>
add_vector_source(
id = "openmaptiles",
url = paste0("https://api.maptiler.com/tiles/v3/tiles.json?key=",
Sys.getenv("MAPTILER_API_KEY"))
) |>
add_fill_extrusion_layer(
id = "3d-buildings",
source = 'openmaptiles',
source_layer = 'building',
fill_extrusion_color = interpolate(
column = 'render_height',
values = c(0, 200, 400),
stops = c('lightgray', 'royalblue', 'lightblue')
),
fill_extrusion_height = list(
'interpolate',
list('linear'),
list('zoom'),
15,
0,
16,
list('get', 'render_height')
)
)
Raster layers
mapgl supports rasters from the
terra package when passed to the data
argument in the add_image_source()
function, then
visualized with add_raster_layer()
. Remote raster sources
(as shown below) can also be added through
add_image_source()
for remotely-hosted image files, or
add_raster_source()
for remotely-hosted raster tiles.
mapboxgl(style = mapbox_style("dark"),
zoom = 5,
center = c(-75.789, 41.874)) |>
add_image_source(
id = "radar",
url = "https://docs.mapbox.com/mapbox-gl-js/assets/radar.gif",
coordinates = list(
c(-80.425, 46.437),
c(-71.516, 46.437),
c(-71.516, 37.936),
c(-80.425, 37.936)
)
) |>
add_raster_layer(
id = 'radar-layer',
source = 'radar',
raster_fade_duration = 0
)
Markers
Markers represent a unique visual component in Mapbox GL JS and
MapLibre GL JS, as they highlight locations but do not count as map
layers. In mapgl, users can add markers using
the add_markers()
function. A single marker can be added as
a length-2 vector of longitude and latitude; a list of length-2 vectors
or an sf POINT object will add multiple markers.
mapboxgl(
style = mapbox_style("streets"),
center = c(-74.006, 40.7128),
zoom = 10
) |>
add_markers(
c(-74.006, 40.7128),
color = "blue",
rotation = 45,
popup = "A marker"
)