mapbox-layers
v0.8.1
Published
A collection of utilities to make working with custom layers easier in Mapbox. Designed to be used in any framework/library.
Readme
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 = {
// load custom map icons referenced within layers
'my-icon': {
width: 48,
height: 42,
path: '/icons/my-icon.svg',
},
};
const overlays = {
myOverlay: {
label: 'Custom Mapbox overlay',
// All layers in the overlay group can be inserted before
// and existing layer id
insertBefore: 'hillshade',
// Overlay contains one or more elements, each with
// its own source.
elements: [
{
id: 'element-one', // custom id, autogenerated by default
// All layers in the element group can be inserted before
// an existing layer id
insertBefore: 'hillshade',
source: {
type: 'geojson',
data: '<URL to a GeoJSON>',
},
// Elements contain one or more layers, linked with
// the source
layers: [
{
symbol: {
minzoom: 10,
layout: {
image: 'my-icon',
// The size of the icon will vary depending on map zoom
size: interpolateZoom({ 9: 0.01, 17: 2 }),
'allow-overlap': true,
},
paint: {
// The opacity of the icon will vary depending on map zoom
opacity: interpolateZoom({ 9: 0, 11: 1 }),
},
// event handlers for each layer
on: {
click(evt, { feature, popup }) {},
mouseover(evt, feature, popup) {},
leave(evt) {},
},
},
},
],
filter: {
filterId: {
options: {
// Build layer filters with options, where option key
// is used to identify and toggle the filter
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:
// Extract sources and layers from overlays object
const { sources, layers } = processOverlays(overlays);
// Create map/style load handler
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:
overlayOverlay 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:
mapMapbox map instancelayerslist of layers with specialonproperty defined in the overlay object. Typically returned fromprocessOverlaysmethod.visibleOverlayIdslist of preloaded overlay IDs (element groups) or elements (layer groups)
toggleFilters(map, overlays, selectedFilters)
Toggles data filters on element layers.
Arguments:
mapMapbox map instanceoverlaysmap overlay definitionsselectedFilterslist 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:
overlayOverlay 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:
layerslayer configuration that was passed tooverlayOptionswhen loading the map.inertOverlayIdslayeridorgroupIds 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)}
/>
);