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.
Downloads
6
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:
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 specialon
property defined in the overlay object. Typically returned fromprocessOverlays
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 tooverlayOptions
when loading the map.inertOverlayIds
layerid
orgroupId
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)}
/>
);