
Layers overview
layers-overview.RmdUsing 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
fit_bounds(animate = FALSE) 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() |>
fit_bounds(nc, animate = FALSE) |>
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")) |>
fit_bounds(loving_roads, animate = FALSE) |>
add_line_layer(
id = "roads",
source = loving_roads,
line_color = "navy",
line_opacity = 0.7
)Circle layers
At the time of this writing, circle clustering is not yet implemented; however, this is on the roadmap for the package.
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")) %>%
fit_bounds(random_points, animate = FALSE) %>%
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")) |>
fit_bounds(random_points, animate = FALSE) |>
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 does not natively support R rasters in its
initial release, but aims to do so in the future. Raster sources can 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"
)