Mapbox Layer Utilities
A collection of utilities to make working with custom layers easier in Mapbox.
Designed to be used in any framework/library.
See the Demos in React, Vue and Svelte.
Usage
Import utility functions:
import {
setupMapOverlays,
createMapHandlers,
toggleOverlays,
interpolateZoom,
} from 'mapbox-layers';
Add overlays:
const icons = {
'my-icon': {
width: 48,
height: 42,
path: '/icons/my-icon.svg',
},
};
const overlays = {
myOverlay: {
label: 'Custom Mapbox overlay',
insertBefore: 'hillshade',
elements: [
{
id: 'element-one',
insertBefore: 'hillshade',
source: {
type: 'geojson',
data: '<URL to a GeoJSON>',
},
layers: [
{
symbol: {
minzoom: 10,
layout: {
image: 'my-icon',
size: interpolateZoom({ 9: 0.01, 17: 2 }),
'allow-overlap': true,
},
paint: {
opacity: interpolateZoom({ 9: 0, 11: 1 }),
},
on: {
click(evt, { feature, popup }) {},
mouseover(evt, feature, popup) {},
leave(evt) {},
},
},
},
],
filter: {
filterId: {
options: {
option1: ['in', 'id', 'id-1', 'id-2'],
option2: ['in', 'name', 'One', 'Two'],
},
},
},
},
],
},
};
The overlays are comprised of a dictionary with keys that are used to identify
them in the Mapbox layers. The values have label
used in layer menu generation,
insertBefore
uses an ID of an existing Mapbox layer to insert it before and
elements
which is a collection of source/layer groups. This is to allow to associate
multiple layers with a source to enable the use of custom line strokes together with
fills (Mapbox only allows a simple 1px stroke by default).
Similarly to overlays, each element can be placed before a specific layer with
insertBefore
property. Layers also have a non-Mapbox API property on
which is
a shorthand to define map pointer events in one place. The on
property accepts:
mouseover(evt: MapLayerMouseEvent, { layer, feature, popup })
click(evt: MapLayerMouseEvent, { layer, feature, popup })
leave(evt: MapLayerMouseEvent)
A second callback parameter is an object which contains the current layer
and feature
objects derived from the interaction event. popup
is a
default popup preset constructed with new mapbox.Popup(...)
.
Create a Mapbox map:
const { sources, layers } = processOverlays(overlays);
const handleMapStyleLoad = setupMapOverlays(
{ sources, layers, icons },
function onLoadCallback() {
console.log('Map loaded and configured!');
}
);
const map = new mapboxgl.Map({
zoom: 14,
center: [0, 51.5],
container: 'map',
}).once('style.load', handleMapStyleLoad);
processOverlays(overlays)
Parse the overlays object and extract all sources and layers to be used
in the map into two separate properties: sources
and layers
.
Arguments:
overlay
Overlay object that configures the
overlays displayed on the map.
processFilter(overlays, selectedFilters)
Extract all filters from overlay elements. Return selected filters if given.
setupMapOverlays({ sources, layers, icons })
Create map load handler which adds sources, layers and registers
custom images on the map. The overlays are hidden by default.
toggleOverlays(map, layers, visibleOverlayIds)
Toggles visibility on the layers already loaded on the map. Use
visibleOverlayIds
to show layers with that ID on the map.
Arguments:
map
Mapbox map instancelayers
list of layers with special on
property defined in
the overlay object. Typically returned from processOverlays
method.visibleOverlayIds
list of preloaded overlay IDs (element groups) or elements (layer groups)
toggleFilters(map, overlays, selectedFilters)
Toggles data filters on element layers.
Arguments:
map
Mapbox map instanceoverlays
map overlay definitionsselectedFilters
list of active filters
buildOverlayList(overlays)
Build a hierarchical representation of the overlays object, to use
in building an overlay menu. Elements can be used to build sub menus
to control the sublayer visibility.
Arguments:
overlay
Overlay object that configures the
overlays displayed on the map.
getSelectedOverlays(currentOverlayIds, selectedId, selectedParentId)
A utility to return a new selection of IDs based on selected ID type (overlay
group or element - sublayer). When top-level overlay is selected, its elements
IDs (automatically prefixed with overlay ID) are excluded and vice-versa.
For example
Current selection ['o-1', 'o-2']
and new ID o-2-sub1
with parent
o-2
will erturn ['o-2', 'o-2-sub1']
.
createMapHandlers(layers, inertOverlayIds)
Parse layers defined in overlays object to extract layer event
handlers, set in on
property of each layer within overlay element.
const { onClick } = createMapHandlers(layers, ['my-inert-layer']);
map.on('click', onClick);
The event handlers in layer definitions provide the original Mapbox
event, the currently active feature for a given event and an instance
of Mapbox Popup
for that event which is automatically removed on mouse out.
Arguments:
layers
layer configuration that was passed to overlayOptions
when loading the map.inertOverlayIds
layer id
or groupId
s of the overlays tha should be made inert
(interactions disabled).
Tips
Use setDebug
method to set the debugging state to local storage for the library.
When the debugging is on, the cursor will turn to help (?), and any layer clicked will
show the currently clicked layers and all map layers. This can be useful when
deciding where to insert a new layer.
import { setDebug, isDebugging } from 'mapbox-layers';
const DebugToggle = () => (
<input
type="checkbox"
defaultChecked={isDebugging()}
onChange={(evt) => setDebug(evt.target.checked)}
/>
);