@superrouteca/smap-deckgl 0.0.0-stage → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ ## 1.1.0 — 2026-10-27
4
+
5
+ - First version.
6
+ - sMap as the basemap of deck.gl apps: an sMap map with deck.gl drawn interleaved with it (`createSMapDeck`), sMap's
7
+ vector tiles drawn by deck.gl in sMap's style (`createVectorBasemapLayer`, with labels in any language, custom styles
8
+ and 3D buildings), or sMap's raster tiles (`createRasterBasemapLayer`). Tiles come from the nearest map node, the
9
+ next one when a node fails, with a map key or a token that is renewed.
10
+ - deck.gl layers on an sMap map kept by id (`deckLayers`, over the map's `addDeckLayer` / `removeDeckLayer`).
11
+ - sMap's points, pins, lines and areas as deck.gl layers with the SDK's options (`pointsLayers`, `linesLayers`,
12
+ `polygonsLayers`), simplestyle colours, and popups as deck.gl tooltips (`popupTooltip`).
13
+ - kepler.gl map styles (`keplerMapStyles`, `keplerTransformRequest`).
14
+ - The sMap badge and the OpenStreetMap credit on maps drawn by deck.gl (`addAttribution`).
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Goodneo Solutions
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,175 @@
1
- # Temporary Holding Version
1
+ # @superrouteca/smap-deckgl
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ sMap and [deck.gl](https://deck.gl) both ways:
4
+
5
+ - **sMap as the basemap of a deck.gl app**: either an sMap map with deck.gl drawn interleaved with it (deck.gl's map
6
+ overlay), or sMap's vector tiles drawn by deck.gl itself (an `MVTLayer` coloured by sMap's style), or sMap's raster
7
+ tiles in a `TileLayer`. The five colour schemes and your saved custom styles, labels in any language, the nearest map
8
+ node with failover, and a map key or a token with refresh, all included.
9
+ - **deck.gl layers on an sMap map**, through the map's `addDeckLayer`, with helpers that keep layers by id.
10
+ - **sMap's points, pins, lines and areas as deck.gl layers**, with the options of the SDK's `addPoints` / `addLines` /
11
+ `addPolygons`.
12
+ - **kepler.gl**: sMap's styles as kepler.gl map styles (recipe below).
13
+
14
+ ```sh
15
+ npm install @superrouteca/smap-deckgl @deck.gl/core @deck.gl/layers @deck.gl/geo-layers @deck.gl/mapbox
16
+ ```
17
+
18
+ deck.gl 9 is a peer dependency. The adapter depends on `@superrouteca/smap` (1.1.0) for the map, the nodes, the key and
19
+ the token.
20
+
21
+ ## Access
22
+
23
+ Every call takes the options of the sMap JS client: `apiKey` (a map key, `smk_…`, whose allowlist names your site),
24
+ or `token` / `getToken` (short-lived tokens from your server), plus `baseUrl` (default `https://tile.srsr.ca`),
25
+ `nodes` and `nearest`. Make one `Session` and pass it as `session` to share it between layers:
26
+
27
+ ```js
28
+ import { createSession } from '@superrouteca/smap-deckgl';
29
+ const session = createSession({ apiKey: 'smk_…' });
30
+ ```
31
+
32
+ ## sMap as the deck.gl basemap
33
+
34
+ ### Interleaved with an sMap map
35
+
36
+ The basemap is a full sMap map (pins, popups, Auto Zoom, 3D buildings, `setStyle`, `setLanguage`, `setBasemap`, …)
37
+ and deck.gl draws between its layers, sharing its depth, through the map's own deck.gl overlay (`addDeckLayer`, deck.gl's
38
+ `MapboxOverlay`; one per map):
39
+
40
+ ```js
41
+ import { createSMapDeck } from '@superrouteca/smap-deckgl';
42
+ import { HexagonLayer } from '@deck.gl/aggregation-layers';
43
+
44
+ const { map, setLayers, setProps } = await createSMapDeck({
45
+ container: 'map', apiKey: 'smk_…', style: 'dark', language: 'en', center: [-79.38, 43.65], zoom: 11, pitch: 45,
46
+ layers: [new HexagonLayer({ id: 'orders', data, getPosition: (d) => d.position, extruded: true, radius: 200 })],
47
+ deck: { getTooltip: ({ object }) => object && `${object.count} orders` },
48
+ });
49
+ map.setBuildings3D(true); // the sMap map's own API
50
+ setLayers([/* new layers */]); // deck.gl's way of updating: new layers with the same ids
51
+ ```
52
+
53
+ Every option except `layers`, `deck` and `sMap` is the sMap map's. deck.gl's map overlay module is handed to the SDK
54
+ for you (`useDeck`).
55
+
56
+ ### Drawn by deck.gl (vector tiles)
57
+
58
+ For a deck.gl app with its own `Deck`, sMap's vector tiles are an `MVTLayer` coloured by sMap's style: fills, lines,
59
+ point labels and (with `buildings3D`) buildings raised by their height:
60
+
61
+ ```js
62
+ import { Deck } from '@deck.gl/core';
63
+ import { createVectorBasemapLayer, addAttribution } from '@superrouteca/smap-deckgl';
64
+
65
+ const basemap = await createVectorBasemapLayer({
66
+ apiKey: 'smk_…', style: 'custom:sms_…', language: 'fr', buildings3D: true,
67
+ basemap: { pois: { visible: false }, water: { color: '#9cc0e6' } }, // basemap options by class, as map.setBasemap
68
+ });
69
+ new Deck({
70
+ parent: document.getElementById('map'),
71
+ initialViewState: { longitude: 2.35, latitude: 48.86, zoom: 12, pitch: 40 },
72
+ controller: true,
73
+ layers: [basemap, myLayer],
74
+ });
75
+ addAttribution(document.getElementById('map')); // the sMap badge and the OpenStreetMap credit
76
+ ```
77
+
78
+ The colour behind the tiles is `basemap.smap.background` (`[r, g, b, a]`): give it to the page. Tiles are read
79
+ through the session: the nearest node, the next one when a node fails, with the key or token.
80
+
81
+ What deck.gl draws from sMap's style: fill, line, fill-extrusion and point-placed symbol text, with paint and layout
82
+ values evaluated at each tile's zoom (constants, zoom and property functions, and the common expressions). Not drawn:
83
+ icons from the style's sprite, labels placed along lines, label collision, dashes, and patterns. For the complete
84
+ look, use the interleaved map above or the raster layer below.
85
+
86
+ ### Drawn by deck.gl (raster tiles)
87
+
88
+ The exact sMap look as images, drawn on sMap's nodes:
89
+
90
+ ```js
91
+ import { createRasterBasemapLayer } from '@superrouteca/smap-deckgl';
92
+ const basemap = await createRasterBasemapLayer({ apiKey: 'smk_…', style: 'light', language: 'zh-Hans', retina: true });
93
+ ```
94
+
95
+ ## deck.gl layers on an sMap map
96
+
97
+ An sMap map (1.1.0) takes deck.gl layers with `map.addDeckLayer(layer, { slot, before })` /
98
+ `map.removeDeckLayer(id)`. `deckLayers(map)` hands deck.gl to the SDK and keeps the layers it added by id, so updating
99
+ a layer is adding a new one with the same id, and `set` replaces them all:
100
+
101
+ ```js
102
+ import * as sMap from '@superrouteca/smap';
103
+ import { deckLayers } from '@superrouteca/smap-deckgl';
104
+ import { ArcLayer } from '@deck.gl/layers';
105
+
106
+ const map = new sMap.Map({ container: 'map', apiKey: 'smk_…' });
107
+ const deck = deckLayers(map);
108
+ deck.add(new ArcLayer({ id: 'flows', data, getSourcePosition: (d) => d.from, getTargetPosition: (d) => d.to }));
109
+ deck.add(new ArcLayer({ id: 'flows', data: next, /* … */ }), { slot: 'labels' }); // replaces 'flows', under the labels
110
+ deck.set([]); // removes every layer it added
111
+ ```
112
+
113
+ A layer without a slot draws on top, in the order added.
114
+
115
+ ## sMap's layers as deck.gl layers
116
+
117
+ `pointsLayers`, `linesLayers` and `polygonsLayers` take the data and options of the SDK's `addPoints`, `addLines` and
118
+ `addPolygons` and return deck.gl layers (bottom first), for a map drawn by deck.gl:
119
+
120
+ ```js
121
+ import { pointsLayers, linesLayers, polygonsLayers, popupTooltip } from '@superrouteca/smap-deckgl';
122
+ import { popupTemplate } from '@superrouteca/smap';
123
+
124
+ const layers = [
125
+ ...polygonsLayers('zones', zones, { fill: '#2563eb', opacity: 0.2, outline: '#2563eb' }),
126
+ ...linesLayers('route', route, { color: { property: 'color' }, width: 5, casing: true }),
127
+ ...pointsLayers('stops', stops, {
128
+ marker: { text: { property: 'seq' }, border: { property: 'color' } }, label: 'name',
129
+ popup: popupTemplate('<b>{name}</b><br>{address}'),
130
+ }),
131
+ ];
132
+ new Deck({ /* … */ layers: [basemap, ...layers], getTooltip: popupTooltip() });
133
+ ```
134
+
135
+ Points: circles, an icon, or route-map pins (`pin` and `circle` shapes, fill, border, number); lines: colour per
136
+ feature, width, opacity, casing, shadow; areas: fill, outline, opacity, and extrusion from a height property. GeoJSON
137
+ simplestyle properties (`marker-color`, `marker-size`, `stroke`, `stroke-width`, `stroke-opacity`, `fill`,
138
+ `fill-opacity`) colour a layer that gives no colour of its own. On a map drawn by deck.gl, popups are deck.gl tooltips
139
+ (HTML strings); clustering, Auto Zoom, dashes, arrows, count badges and zoom ranges are the sMap map's own and are not
140
+ drawn by these layers: put the layers on an sMap map (`map.addPoints`, …) for those.
141
+
142
+ ## kepler.gl
143
+
144
+ kepler.gl reads Style Specification styles from a URL, so sMap's styles are kepler.gl map styles:
145
+
146
+ ```jsx
147
+ import KeplerGl from '@kepler.gl/components';
148
+ import { keplerMapStyles, keplerTransformRequest } from '@superrouteca/smap-deckgl';
149
+
150
+ const access = { apiKey: 'smk_…' }; // or { getToken }
151
+ const mapStyles = await keplerMapStyles({ ...access, language: 'en', styles: ['light', 'dark', 'custom:sms_…'] });
152
+
153
+ <KeplerGl
154
+ id="map"
155
+ mapStyles={mapStyles}
156
+ mapStylesReplaceDefault
157
+ transformRequest={keplerTransformRequest(access)}
158
+ width={width}
159
+ height={height}
160
+ />;
161
+ ```
162
+
163
+ Then pick a style by its id (`smap-light`, `smap-dark`, `smap-custom-sms_…`), e.g.
164
+ `dispatch(addDataToMap({ datasets, config: { version: 'v1', config: { mapStyle: { styleType: 'smap-dark' } } } }))`.
165
+ A map key goes in the style URL itself, so a key is enough even where `transformRequest` is not passed; a token needs
166
+ `transformRequest`. kepler.gl shows the OpenStreetMap credit from the style's sources.
167
+
168
+ ## Example
169
+
170
+ [`examples/index.html`](examples/index.html): serve the repository root (`npx serve .`) and open
171
+ `/deckgl/examples/?key=smk_…` (`&mode=vector`, `raster` or `interleaved`).
172
+
173
+ ## Licence
174
+
175
+ MIT. The map data is © OpenStreetMap contributors; the credit stays visible on every map.
package/package.json CHANGED
@@ -1,6 +1,64 @@
1
1
  {
2
2
  "name": "@superrouteca/smap-deckgl",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.1.0",
4
+ "description": "sMap for deck.gl: sMap as the basemap of deck.gl apps (interleaved or drawn by deck.gl), deck.gl layers on sMap maps, and kepler.gl map styles.",
5
+ "license": "MIT",
6
+ "author": "Goodneo Solutions",
7
+ "homepage": "https://github.com/Goodneo-Solutions/smap-sdk/tree/main/deckgl#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Goodneo-Solutions/smap-sdk.git",
11
+ "directory": "deckgl"
12
+ },
13
+ "keywords": [
14
+ "map",
15
+ "maps",
16
+ "deck.gl",
17
+ "kepler.gl",
18
+ "vector-tiles",
19
+ "smap",
20
+ "superroute"
21
+ ],
22
+ "type": "module",
23
+ "sideEffects": false,
24
+ "main": "./src/index.js",
25
+ "module": "./src/index.js",
26
+ "types": "./types/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./types/index.d.ts",
30
+ "default": "./src/index.js"
31
+ },
32
+ "./package.json": "./package.json"
33
+ },
34
+ "files": [
35
+ "src",
36
+ "types",
37
+ "README.md",
38
+ "CHANGELOG.md",
39
+ "LICENSE"
40
+ ],
41
+ "engines": {
42
+ "node": ">=18"
43
+ },
44
+ "scripts": {
45
+ "test": "node --import ./test/setup.mjs --test test/*.test.mjs",
46
+ "typecheck": "tsc -p test/tsconfig.json"
47
+ },
48
+ "dependencies": {
49
+ "@superrouteca/smap": "1.1.0"
50
+ },
51
+ "peerDependencies": {
52
+ "@deck.gl/core": "^9.0.0",
53
+ "@deck.gl/layers": "^9.0.0",
54
+ "@deck.gl/geo-layers": "^9.0.0",
55
+ "@deck.gl/mapbox": "^9.0.0"
56
+ },
57
+ "devDependencies": {
58
+ "@deck.gl/core": "9.4.0",
59
+ "@deck.gl/layers": "9.4.0",
60
+ "@deck.gl/geo-layers": "9.4.0",
61
+ "@deck.gl/mapbox": "9.4.0",
62
+ "typescript": "6.0.3"
63
+ }
64
+ }
package/src/basemap.js ADDED
@@ -0,0 +1,129 @@
1
+ // sMap as the basemap of a deck.gl app drawn by deck.gl itself: its vector tiles through deck.gl's MVTLayer, coloured
2
+ // by sMap's style (schemes and custom styles, any label language), or its raster tiles through a TileLayer.
3
+ import { MVTLayer, TileLayer } from '@deck.gl/geo-layers';
4
+ import { GeoJsonLayer, TextLayer, BitmapLayer } from '@deck.gl/layers';
5
+ import { applyBasemapOverrides } from '@superrouteca/smap';
6
+ import { createSession, ATTRIBUTION } from './session.js';
7
+ import { compileStyle, drawTile } from './style.js';
8
+
9
+ async function vectorSource(session, doc, sourceId) {
10
+ const sources = doc.sources || {};
11
+ const id = sourceId || Object.keys(sources).find((k) => sources[k].type === 'vector');
12
+ if (!id) { throw new Error('sMap: the style has no vector source'); }
13
+ const src = sources[id];
14
+ if (src.tiles && src.tiles.length) { return { id, tiles: src.tiles, minzoom: src.minzoom, maxzoom: src.maxzoom, attribution: src.attribution }; }
15
+ if (!src.url) { throw new Error('sMap: vector source "' + id + '" has neither tiles nor url'); }
16
+ const tj = await session.fetch(src.url).then((r) => r.json());
17
+ return { id, tiles: tj.tiles, minzoom: tj.minzoom ?? src.minzoom, maxzoom: tj.maxzoom ?? src.maxzoom, attribution: tj.attribution };
18
+ }
19
+
20
+ /** The sub layers drawn for one tile (exported for tests and for apps that draw tiles their own way). */
21
+ export function tileSubLayers(props, compiled, options = {}) {
22
+ const z = props.tile && props.tile.index ? props.tile.index.z : (props.tile && props.tile.zoom) || 0;
23
+ const drawn = drawTile(compiled, props.data || [], z, options);
24
+ const { data: _data, ...base } = props;
25
+ const sub = [];
26
+ if (drawn.fills.length) {
27
+ sub.push(new GeoJsonLayer({
28
+ ...base, id: props.id + '-fills', data: drawn.fills.map((d) => ({ type: 'Feature', geometry: d.geometry, properties: d })),
29
+ filled: true, stroked: false, getFillColor: (f) => f.properties.color, pickable: options.pickable || false,
30
+ }));
31
+ }
32
+ if (drawn.lines.length) {
33
+ sub.push(new GeoJsonLayer({
34
+ ...base, id: props.id + '-lines', data: drawn.lines.map((d) => ({ type: 'Feature', geometry: d.geometry, properties: d })),
35
+ filled: false, stroked: true, lineWidthUnits: 'pixels', lineCapRounded: true, lineJointRounded: true,
36
+ getLineColor: (f) => f.properties.color, getLineWidth: (f) => f.properties.width, pickable: options.pickable || false,
37
+ }));
38
+ }
39
+ if (drawn.extrusions.length) {
40
+ sub.push(new GeoJsonLayer({
41
+ ...base, id: props.id + '-buildings', data: drawn.extrusions.map((d) => ({ type: 'Feature', geometry: d.geometry, properties: d })),
42
+ filled: true, stroked: false, extruded: true, getFillColor: (f) => f.properties.color,
43
+ getElevation: (f) => Math.max(0, f.properties.height - f.properties.base), material: true, pickable: options.pickable || false,
44
+ }));
45
+ }
46
+ if (drawn.labels.length && options.labels !== false) {
47
+ sub.push(new TextLayer({
48
+ ...base, id: props.id + '-labels', data: drawn.labels,
49
+ getPosition: (d) => d.position, getText: (d) => d.text, getColor: (d) => d.color, getSize: (d) => d.size,
50
+ sizeUnits: 'pixels', characterSet: 'auto', fontFamily: options.fontFamily || 'Noto Sans, Helvetica, Arial, sans-serif',
51
+ fontSettings: { sdf: true }, outlineWidth: 2, outlineColor: drawn.labels[0].halo,
52
+ getTextAnchor: (d) => (d.anchor.includes('left') ? 'start' : d.anchor.includes('right') ? 'end' : 'middle'),
53
+ getAlignmentBaseline: (d) => (d.anchor.startsWith('top') ? 'top' : d.anchor.startsWith('bottom') ? 'bottom' : 'center'),
54
+ billboard: true, pickable: false,
55
+ }));
56
+ }
57
+ return sub;
58
+ }
59
+
60
+ /**
61
+ * The sMap basemap as a deck.gl MVTLayer: sMap's vector tiles drawn by deck.gl in the scheme or custom style chosen,
62
+ * labels in `language`, `basemap` overrides by class (as the SDK's setBasemap); tiles read from the nearest node, the
63
+ * next one on failure, with the map key or token.
64
+ *
65
+ * @returns {Promise<MVTLayer>} also carrying `smap: { session, style, background, attribution }`
66
+ */
67
+ export async function createVectorBasemapLayer(options = {}) {
68
+ const session = createSession(options.session || options);
69
+ await session.ready();
70
+ const style = options.style || 'light';
71
+ let doc = options.styleDocument || await session.style(style, options.language);
72
+ // Basemap options (contract §1: show, hide and recolour by class), applied by the SDK's own function.
73
+ if (options.basemap && Object.keys(options.basemap).length) { doc = applyBasemapOverrides(doc, options.basemap); }
74
+ const compiled = compileStyle(doc, { source: options.source });
75
+ const src = await vectorSource(session, doc, compiled.sources[0]);
76
+ const drawOptions = { labels: options.labels !== false, buildings3D: Boolean(options.buildings3D), fontFamily: options.fontFamily, pickable: options.pickable };
77
+ const tileFetch = (url, init) => session.fetch(url, init);
78
+ const layer = new MVTLayer({
79
+ id: options.id || 'smap-basemap',
80
+ data: src.tiles,
81
+ minZoom: src.minzoom ?? 0,
82
+ maxZoom: src.maxzoom ?? 15,
83
+ binary: false,
84
+ // loaders.gl reads every tile with this fetch: the session's, so nearest node, failover, key and token apply.
85
+ loadOptions: { fetch: tileFetch, core: { fetch: tileFetch }, mvt: { layerProperty: 'layerName' } },
86
+ renderSubLayers: (props) => tileSubLayers(props, compiled, drawOptions),
87
+ pickable: Boolean(options.pickable),
88
+ ...(options.layerProps || {}),
89
+ });
90
+ layer.smap = { session, style, background: compiled.background, attribution: src.attribution || ATTRIBUTION };
91
+ return layer;
92
+ }
93
+
94
+ /** Bytes of a raster tile through the session (nearest node, failover, key, token) as an ImageBitmap. */
95
+ async function loadRaster(session, url, signal) {
96
+ const res = await session.fetch(url, { signal });
97
+ const blob = await res.blob();
98
+ if (typeof createImageBitmap === 'function') { return createImageBitmap(blob); }
99
+ return blob;
100
+ }
101
+
102
+ /**
103
+ * The sMap basemap as raster tiles (contract §5) in a deck.gl TileLayer: what deck.gl shows where vector drawing is
104
+ * not wanted, the same scheme or custom style and language. `retina` reads 512 px tiles.
105
+ */
106
+ export async function createRasterBasemapLayer(options = {}) {
107
+ const session = createSession(options.session || options);
108
+ await session.ready();
109
+ const style = options.style || 'light';
110
+ const template = session.rasterTemplate(style, { language: options.language, retina: options.retina });
111
+ const layer = new TileLayer({
112
+ id: options.id || 'smap-raster',
113
+ data: template,
114
+ tileSize: 256,
115
+ minZoom: 0,
116
+ maxZoom: options.maxZoom ?? 19,
117
+ getTileData: ({ index, signal }) => {
118
+ const url = template.replace('{z}', index.z).replace('{x}', index.x).replace('{y}', index.y);
119
+ return loadRaster(session, url, signal);
120
+ },
121
+ renderSubLayers: (props) => {
122
+ const bb = props.tile.bbox;
123
+ return new BitmapLayer({ ...props, data: undefined, image: props.data, bounds: [bb.west, bb.south, bb.east, bb.north] });
124
+ },
125
+ ...(options.layerProps || {}),
126
+ });
127
+ layer.smap = { session, style, attribution: ATTRIBUTION };
128
+ return layer;
129
+ }
package/src/index.js ADDED
@@ -0,0 +1,8 @@
1
+ // @superrouteca/smap-deckgl — sMap and deck.gl both ways.
2
+ export { Session, createSession, FLAVORS, ATTRIBUTION } from './session.js';
3
+ export { createVectorBasemapLayer, createRasterBasemapLayer, tileSubLayers } from './basemap.js';
4
+ export { createSMapDeck, deckLayers, registerDeck, addAttribution } from './overlay.js';
5
+ export { pointsLayers, linesLayers, polygonsLayers, popupTooltip, toFeatures, accessor } from './layers.js';
6
+ export { keplerMapStyles, keplerTransformRequest } from './kepler.js';
7
+ export { parseColor, evaluate, compileStyle, drawTile } from './style.js';
8
+ export const version = '1.1.0';
package/src/kepler.js ADDED
@@ -0,0 +1,31 @@
1
+ // kepler.gl with sMap's styles as its map styles (see the README's kepler.gl recipe).
2
+ import { createSession, FLAVORS } from './session.js';
3
+
4
+ /**
5
+ * kepler.gl map styles for sMap's schemes (and custom styles): `{ id, label, url, icon }` each, for the KeplerGl
6
+ * component's `mapStyles` prop. Waits for the nearest node, so every URL points at it.
7
+ *
8
+ * @param {object} options session options (apiKey / token / getToken, baseUrl, …) or `{ session }`, plus `styles`
9
+ * (default every scheme; `custom:<id>` too), `language` and `labels` ({ styleId: label })
10
+ */
11
+ export async function keplerMapStyles(options = {}) {
12
+ const session = createSession(options.session || options);
13
+ await session.ready();
14
+ const styles = options.styles || FLAVORS;
15
+ return styles.map((style) => ({
16
+ id: 'smap-' + style.replace(':', '-'),
17
+ label: (options.labels && options.labels[style]) || 'sMap ' + style.replace(/^custom:/, ''),
18
+ url: session.styleUrl(style, options.language),
19
+ icon: session.rasterTemplate(style, { language: options.language }).replace('{z}', '3').replace('{x}', '2').replace('{y}', '2'),
20
+ }));
21
+ }
22
+
23
+ /**
24
+ * A transformRequest for kepler.gl's map (the KeplerGl `transformRequest` prop): sMap URLs get the token and the map
25
+ * key as headers; other URLs pass unchanged.
26
+ */
27
+ export function keplerTransformRequest(options = {}) {
28
+ const session = createSession(options.session || options);
29
+ session.ready().catch(() => {});
30
+ return (url) => (session.nodeOf(url) ? { url, headers: session.headers() } : { url });
31
+ }