Overview
An implementation of a subset of the Mapbox Style Specification using deck.gl layers and helpers.
A work in progress.
Overview
The package is split into two surfaces:
@deck.gl-community/basemap-layersRuntime helpers and theBasemapLayerCompositeLayer@deck.gl-community/basemap-layers/map-styleMap-style parsing, validation, loading, and style-expression helpers
Exported runtime helpers:
BasemapLayergetBasemapLayersgetGlobeBaseLayersgetGlobeTopLayersresolveBasemapStyle
Exported pure style helpers:
filterFeaturesfindFeaturesStyledByLayerparsePropertiesresolveBasemapStyleMapStyleLoaderBasemapSourceSchema,BasemapStyleLayerSchema,BasemapStyleSchema,ResolvedBasemapStyleSchema
The runtime surface is designed for backdrop basemaps and globe rendering, not for full replacement of a production basemap engine.
Mapbox Style Spec Primer
The Mapbox Style Specification is a JSON document with two main parts, a sources object, and a layers array.
The sources object describes how to load each source. For example, a
"satellite streets" style might have two sources: one a raster source with
satellite imagery and the other a vector tile source with items to display on
top of the imagery. Such an object might look like:
"sources": {
"vector-source": {
"type": "vector",
"url": "https://example.com/tiles/vector-tiles.json"
},
"satellite-source": {
"type": "raster",
"url": "https://example.com/tiles/satellite-tiles.json"
}
}
Here the keys vector-source and satellite-source describe each source that
can later be referenced from the layers object. Each url points to a
TileJSON file, which contains metadata describing how to load each
individual tile of the dataset.
layers contains an array of objects, where each object defines an individual layer to render.
"layers": [
{
"id": "satellite-layer",
"type": "raster",
"source": "satellite-source",
"minzoom": 0,
"maxzoom": 18,
"paint": {"raster-opacity": 1}
},
{
"id": "landuse_residential",
"type": "fill",
"source": "vector-source",
"source-layer": "landuse",
"maxzoom": 8,
"filter": ["==", "class", "residential"],
"paint": {
"fill-color": {
"base": 1,
"stops": [
[9, "hsla(0, 3%, 85%, 0.84)"],
[12, "hsla(35, 57%, 88%, 0.49)"]
]
}
}
},
{
"id": "waterway_river",
"type": "line",
"source": "vector-source",
"source-layer": "waterway",
"filter": ["all", ["==", "class", "river"], ["!=", "brunnel", "tunnel"]],
"layout": {"line-cap": "round"},
"paint": {
"line-color": "#a0c8f0",
"line-width": {"base": 1.2, "stops": [[11, 0.5], [20, 6]]}
}
}
]
The above describes a sequence of three layers. Later layers are rendered on top of earlier layers, so this would show two vector layers on top of a satellite layer.
Overview of each key:
id: must be unique to each layertype: one of:background,fill,line,symbol,raster,circle,fill,-extrusionheatmap,hillshade,sky(v2 only).source: must be one of the keys defined in the initialsourcesobject. So here each must be eithersatellite-sourceorvector-source.source-layer: For vector sources, each styling layer is rendered on only a single vector tile layer within the source. So whensource-layerislanduse, the vector tiles provided by thevector-sourcesource are expected to contain a layer namedlanduse, and this styling layer will apply only to that layer. This is required for vector sources.minzoom,maxzoom: zoom range for layer. Falls back to source's available zoom range, but can be a narrower range than the source providesfilter: A filter expression that is tested against every object within the vector tile layer.layout: A layout expression. These are less commonly used, and usually don't have a great equivalent in deck.gl.paint: Properties used for styling. Each layer type has a list of available paint properties. All properties exceptvisibilityare prefixed by the layer's type, hencefill-colorandline-width. The value of each paint property can be either a constant value or color, or a styling expression that changes appearance based on zoom.
Implementation Notes
The simplest approach would be to map each Mapbox layer to a deck.gl layer. Most Mapbox layers have a deck.gl equivalent:
| Mapbox Layer Type | deck.gl Layer |
|---|---|
background | BitmapLayer |
fill | MVTLayer (PolygonLayer) |
line | MVTLayer (LineLayer) |
symbol | IconLayer/TextLayer |
raster | BitmapLayer |
circle | MVTLayer ? |
fill-extrusion | MVTLayer (PolygonLayer) |
heatmap | HeatmapLayer |
hillshade | N/A |
sky (v2 only) | N/A |
Mapbox GL JS exposes a standalone parser for their style specification. (This is apparently still open source in v2). This parser is quite helpful, it:
- parses all permissible color descriptions into an rgba array
- Evaluates filter expressions for each GeoJSON
Featureinput - Evaluates paint expressions given the zoom level