basemapkit 0.1.2 → 0.1.4

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/index.html CHANGED
@@ -6,6 +6,7 @@
6
6
  <title>basemapkit</title>
7
7
  </head>
8
8
  <body>
9
+ <div id="basemapkit-version"></div>
9
10
  <div id="style-editor" class="hidden">
10
11
  <textarea
11
12
  id="code-editor"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "basemapkit",
3
3
  "private": false,
4
- "version": "0.1.2",
4
+ "version": "0.1.4",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": {
@@ -30,6 +30,7 @@
30
30
  },
31
31
  "devDependencies": {
32
32
  "@biomejs/biome": "^2.0.0",
33
+ "@types/node": "^24.0.13",
33
34
  "typescript": "~5.8.3",
34
35
  "vite": "^6.3.5",
35
36
  "vite-plugin-dts": "^4.5.4"
package/readme.md CHANGED
@@ -9,9 +9,13 @@ Basemaps for <a href="https://maplibre.org/maplibre-gl-js/docs/">Maplibre GL JS<
9
9
  <img src="https://img.shields.io/npm/v/basemapkit"></img>
10
10
  </p>
11
11
 
12
- Basemapkit generates customizable styles compatible with **Maplibre GL JS** that relies on the **Protomaps** Planet schemas when it comes to [vector layers and feature properties](https://docs.protomaps.com/basemaps/layers). You can download your own PMtiles copy of the planet on the official [Protomaps build page](https://maps.protomaps.com/builds/).
12
+ **Basemapkit** generates customizable styles compatible with **Maplibre GL JS** that relies on the **Protomaps** Planet schemas when it comes to [vector layers and feature properties](https://docs.protomaps.com/basemaps/layers). You can download your own PMtiles copy of the planet on the official [Protomaps build page](https://maps.protomaps.com/builds/).
13
13
 
14
- ![Showing the Basemapkit's Versatile style](./public/versatile.jpg)
14
+ | | | |
15
+ | :----------------: | :------: | ----: |
16
+ | ![](./public/screenshots/eu-avenue.jpg) | ![](./public/screenshots/eu-avenue-pop.jpg) | ![](./public/screenshots/eu-avenue-night.jpg) |
17
+ | ![](./public/screenshots/eu-avenue-bright.jpg) | ![](./public/screenshots/eu-avenue-saturated.jpg)| ![](./public/screenshots/eu-avenue-warm.jpg) |
18
+ | ![](./public/screenshots/eu-avenue-vintage.jpg) | ![](./public/screenshots/eu-avenue-bnw.jpg) | ![](./public/screenshots/eu-avenue-blueprint.jpg) |
15
19
 
16
20
  ## Getting started
17
21
  ### Install
@@ -21,7 +25,7 @@ npm install basemapkit
21
25
  ```
22
26
 
23
27
  ### Add some style
24
- The following example add a Maplibre `Map`, add the Protomaps protocol and then generates a style:
28
+ The following example instantiates a Maplibre `Map`, then initializes the Protomaps protocol and then generates a style with Basemapkit:
25
29
 
26
30
  ```ts
27
31
  import "maplibre-gl/dist/maplibre-gl.css";
@@ -35,21 +39,21 @@ maplibregl.addProtocol("pmtiles", new Protocol().tile);
35
39
 
36
40
  // Build the Basemapkit style
37
41
  const style = getStyle(
38
- // One of the main syle:
39
- "versatile",
40
- {
41
- // URL to the pmtiles
42
- pmtiles: "https://my-s3-bucket.com/planet.pmtiles",
42
+ // One of the main syle:
43
+ "avenue",
44
+ {
45
+ // URL to the pmtiles
46
+ pmtiles: "https://my-s3-bucket.com/planet.pmtiles",
43
47
 
44
- // URL to the sprites (for POIs)
45
- sprite: "https://raw.githubusercontent.com/jonathanlurie/phosphor-mlgl-sprite/refs/heads/main/sprite/phosphor-diecut",
48
+ // URL to the sprites (for POIs)
49
+ sprite: "https://raw.githubusercontent.com/jonathanlurie/phosphor-mlgl-sprite/refs/heads/main/sprite/phosphor-diecut",
46
50
 
47
- // URL to the glyphs (for labels)
48
- glyphs: "https://protomaps.github.io/basemaps-assets/fonts/{fontstack}/{range}.pbf";
51
+ // URL to the glyphs (for labels)
52
+ glyphs: "https://protomaps.github.io/basemaps-assets/fonts/{fontstack}/{range}.pbf";
49
53
 
50
- // Language (you can ommit to use the platform language)
51
- lang: "en",
52
- }),
54
+ // Language (you can ommit to use the platform language)
55
+ lang: "en",
56
+ });
53
57
 
54
58
  // Instantiate the Map:
55
59
  const map = new maplibregl.Map({
@@ -62,8 +66,29 @@ const map = new maplibregl.Map({
62
66
  });
63
67
  ```
64
68
 
69
+ If using a traditional `tile.json` and `z/x/y` tiles instead of http-range-requesting a `pmtiles` file, then replace the option `pmtiles` by `tilejson`, as in the example below:
70
+ ```ts
71
+ const style = getStyle(
72
+ // One of the main syle:
73
+ "avenue",
74
+ {
75
+ // URL to the tile.json
76
+ tilejson: "https://example.com/tile.json",
77
+
78
+ // URL to the sprites (for POIs)
79
+ sprite: "https://raw.githubusercontent.com/jonathanlurie/phosphor-mlgl-sprite/refs/heads/main/sprite/phosphor-diecut",
80
+
81
+ // URL to the glyphs (for labels)
82
+ glyphs: "https://protomaps.github.io/basemaps-assets/fonts/{fontstack}/{range}.pbf";
83
+
84
+ // Language (you can ommit to use the platform language)
85
+ lang: "en",
86
+ });
87
+ ```
88
+ This can get particularly handy when using the [Protomaps CLI](https://docs.protomaps.com/pmtiles/cli) or [Martin](https://martin.maplibre.org/) to serve `z/x/y` vector tiles.
89
+
65
90
  ## Language
66
- Basemakit styles are compatible with Protomaps languages properties and under the hood even uses [`@protomaps/basemaps`](https://docs.protomaps.com/basemaps/flavors).
91
+ Basemakit styles are compatible with Protomaps languages properties and uses [`@protomaps/basemaps`](https://docs.protomaps.com/basemaps/flavors) under the hood.
67
92
 
68
93
  The only addition from **Basemapkit** is the capability to detect the end user's platform language, so if the `lang` option is omitted, it will automatically use the language set by the user at the browser or OS level.
69
94
 
@@ -72,94 +97,274 @@ Here is the list of supported languages:
72
97
  "ar" | "cs" | "bg" | "da" | "de" | "el" | "en" | "es" | "et" | "fa" | "fi" | "fr" | "ga" | "he" | "hi" | "hr" | "hu" | "id" | "it" | "ja" | "ko" | "lt" | "lv" | "ne" | "nl" | "no" | "mr" | "mt" | "pl" | "pt" | "ro" | "ru" | "sk" | "sl" | "sv" | "tr" | "uk" | "ur" | "vi" | "zh-Hans" | "zh-Hant"
73
98
  ```
74
99
 
75
- ## Styles available
76
- ###
100
+ ## POIs and labels
101
+ There are options to hide the points of interests and labels. By default, both are shown, meaning the options goes like this:
102
+ ```ts
103
+ getStyle(
104
+ "avenue",
105
+ {
106
+ pmtiles: "...",
107
+ sprite: "...",
108
+ glyphs: "...",
109
+
110
+ hidePOIs: false,
111
+ hideLabels: false,
112
+ });
113
+ ```
114
+ So by default, London looks like this:
115
+ ![a part of the city of London with both POIs and labels](./public/screenshots/hide-nothing.jpg)
116
+
117
+ But POIs can be hidden by doing this:
118
+ ```ts
119
+ getStyle(
120
+ "avenue",
121
+ {
122
+ pmtiles: "...",
123
+ sprite: "...",
124
+ glyphs: "...",
125
+
126
+ hidePOIs: true,
127
+ hideLabels: false,
128
+ });
129
+ ```
130
+ Then the same locations looks like this:
131
+ ![a part of the city of London with both POIs hidden](./public/screenshots/hide-pois.jpg)
132
+
133
+ Alternatively, the labels can be hidden, this includes POIs' labels, so only POIs' icons will be shown by doing this:
134
+ ```ts
135
+ getStyle(
136
+ "avenue",
137
+ {
138
+ pmtiles: "...",
139
+ sprite: "...",
140
+ glyphs: "...",
141
+
142
+ hidePOIs: false,
143
+ hideLabels: true,
144
+ });
145
+ ```
146
+ here is how it looks like:
147
+ ![a part of the city of London with labels hidden](./public/screenshots/hide-labels.jpg)
148
+
149
+ And finally, both labels and POIs can be hidden, resulting in a somewhat mysterious map:
150
+ ```ts
151
+ getStyle(
152
+ "avenue",
153
+ {
154
+ pmtiles: "...",
155
+ sprite: "...",
156
+ glyphs: "...",
157
+
158
+ hidePOIs: true,
159
+ hideLabels: true,
160
+ });
161
+ ```
162
+ ![a part of the city of London with labels and POIs hidden](./public/screenshots/hide-pois-labels.jpg)
163
+
164
+ Note that the corresponding layers are removed from the style and not just made invisible. If hiding POIs or label, the options `sprite` and `glyph` are unnecessary.
165
+
166
+ ## Getting creative with `buildStyle()`
167
+ In addition to language and hiding POIs/labels, Basmapkit exposes some methods to modify the colors of the original style (`avenue`) to create *presets*. When the style is generated with some non-default `colorEdit`, a brand new Maplibre style is created and can be directly injected into a Maplibre `Map` instance's `.setStyle()` method, or even written as a static json file.
168
+
169
+ ```ts
170
+
171
+ buildStyle({
172
+ pmtiles: "...",
173
+ sprite: "...",
174
+ glyphs: "...",
175
+ hidePOIs: false,
176
+ hideLabels: false,
177
+
178
+ // At the moment, "avenue" is the only style to start from
179
+ baseStyleName: "avenue",
180
+
181
+ colorEdit: {
182
+ // Invert the colors:
183
+ negate: false,
184
+
185
+ // In the range [-1, 1]:
186
+ brightness: 0,
187
+
188
+ // In the range [-1, 1]:
189
+ brightnessShift: 0,
190
+
191
+ // In the range [-1, 1]:
192
+ exposure: 0,
193
+
194
+ contrast: [
195
+ // intensity in the range [-1, 1]:
196
+ 0,
197
+ // Midpoint in [0, 255]
198
+ 127
199
+ ],
200
+
201
+ // Rotate around the hue wheel, in range [0, 360]
202
+ hueRotation: 0,
203
+
204
+ // In the range [-1, 1]
205
+ // with -1 being gray levels and 1 being extra boosted colors
206
+ saturation: 0,
207
+
208
+ // Color blending with a multiply method
209
+ multiplyColor: [
210
+ // Color to multiply with
211
+ "#ff0000",
212
+
213
+ // blending factor in [0, 1]
214
+ // with 0 being the original color and 1 being the the color above
215
+ 0
216
+ ],
217
+
218
+ // Linear color blending
219
+ mixColor: [
220
+ // Color to blend with
221
+ "#ff0000",
222
+
223
+ // blending factor in [0, 1]
224
+ // with 0 being the original color and 1 being the the color above
225
+ 0
226
+ ]
227
+ }
228
+
229
+ }
230
+ );
231
+ ```
232
+ For instance, let's create a TMNT toxic N.Y.C. kind of map:
233
+ ```json
234
+ {
235
+ "baseStyleName": "avenue",
236
+ "lang": "en",
237
+ "hidePOIs": true,
238
+ "hideLabels": false,
239
+ "colorEdit": {
240
+ "negate": true,
241
+ "brightness": 0.4,
242
+ "brightnessShift": 0,
243
+ "exposure": 0.8,
244
+ "contrast": [
245
+ 0.4,
246
+ 160
247
+ ],
248
+ "hueRotation": 80,
249
+ "saturation": 0.12,
250
+ "multiplyColor": [
251
+ "#ff00ff",
252
+ 0.6
253
+ ],
254
+ "mixColor": [
255
+ "#00ff00",
256
+ 0.3
257
+ ]
258
+ }
259
+ }
260
+ ```
261
+ And here is the result:
262
+ ![](./public/screenshots/tmnt-toxic-nyc.jpg)
263
+
264
+ You can live play with these on [basemapkit.jnth.io](https://s.jnth.io/s/basemapkit) and selecting the style `🖌️ custom 🎨`.
265
+ And from this "color editor" were created the built-in styles available below...
266
+
77
267
 
78
268
 
79
- ### `versatile` ⤵️
269
+ ## Style presets available
270
+ Some custom `colorEdit` recipes are already built in Basemapkit and can be accessed directly from the `getStyle()` function.
271
+ ### `avenue` ⤵️
272
+ This one is the default, with all the `colorEdit` options set to default:
80
273
  ```ts
81
274
  // Create the style
82
- const style = getStyle("versatile", options);
275
+ const style = getStyle("avenue", options);
83
276
  ```
84
- ![](./public/screenshots/usa-versatile.jpeg)
85
- ![](./public/screenshots/alps-versatile.jpeg)
86
- ![](./public/screenshots/manhattan-versatile.jpeg)
87
- ![](./public/screenshots/na-versatile.jpeg)
88
- ![](./public/screenshots/paris-versatile.jpeg)
277
+ ![](./public/screenshots/eu-avenue.jpg)
278
+ ![](./public/screenshots/nyc-avenue.jpg)
279
+ ![](./public/screenshots/jp-avenue.jpg)
280
+ ![](./public/screenshots/eiffel-avenue.jpg)
281
+ ![](./public/screenshots/alps-avenue.jpg)
282
+
283
+ ### `avenue-pop` ⤵️
284
+ ```ts
285
+ // Create the style
286
+ const style = getStyle("avenue-pop", options);
287
+ ```
288
+ ![](./public/screenshots/eu-avenue-pop.jpg)
289
+ ![](./public/screenshots/nyc-avenue-pop.jpg)
290
+ ![](./public/screenshots/jp-avenue-pop.jpg)
291
+ ![](./public/screenshots/eiffel-avenue-pop.jpg)
292
+ ![](./public/screenshots/alps-avenue-pop.jpg)
293
+
89
294
 
90
- ### `versatile-night` ⤵️
295
+ ### `avenue-night` ⤵️
91
296
  ```ts
92
297
  // Create the style
93
- const style = getStyle("versatile-night", options);
298
+ const style = getStyle("avenue-night", options);
94
299
  ```
95
- ![](./public/screenshots/usa-versatile-night.jpeg)
96
- ![](./public/screenshots/alps-versatile-night.jpeg)
97
- ![](./public/screenshots/manhattan-versatile-night.jpeg)
98
- ![](./public/screenshots/na-versatile-night.jpeg)
99
- ![](./public/screenshots/paris-versatile-night.jpeg)
300
+ ![](./public/screenshots/eu-avenue-night.jpg)
301
+ ![](./public/screenshots/nyc-avenue-night.jpg)
302
+ ![](./public/screenshots/jp-avenue-night.jpg)
303
+ ![](./public/screenshots/eiffel-avenue-night.jpg)
304
+ ![](./public/screenshots/alps-avenue-night.jpg)
100
305
 
101
- ### `versatile-bright` ⤵️
306
+ ### `avenue-bright` ⤵️
102
307
  ```ts
103
308
  // Create the style
104
- const style = getStyle("versatile-bright", options);
309
+ const style = getStyle("avenue-bright", options);
105
310
  ```
106
- ![](./public/screenshots/usa-versatile-bright.jpeg)
107
- ![](./public/screenshots/alps-versatile-bright.jpeg)
108
- ![](./public/screenshots/manhattan-versatile-bright.jpeg)
109
- ![](./public/screenshots/na-versatile-bright.jpeg)
110
- ![](./public/screenshots/paris-versatile-bright.jpeg)
311
+ ![](./public/screenshots/eu-avenue-bright.jpg)
312
+ ![](./public/screenshots/nyc-avenue-bright.jpg)
313
+ ![](./public/screenshots/jp-avenue-bright.jpg)
314
+ ![](./public/screenshots/eiffel-avenue-bright.jpg)
315
+ ![](./public/screenshots/alps-avenue-bright.jpg)
111
316
 
112
- ### `versatile-saturated` ⤵️
317
+ ### `avenue-saturated` ⤵️
113
318
  ```ts
114
319
  // Create the style
115
- const style = getStyle("versatile-saturated", options);
320
+ const style = getStyle("avenue-saturated", options);
116
321
  ```
117
- ![](./public/screenshots/usa-versatile-saturated.jpeg)
118
- ![](./public/screenshots/alps-versatile-saturated.jpeg)
119
- ![](./public/screenshots/manhattan-versatile-saturated.jpeg)
120
- ![](./public/screenshots/na-versatile-saturated.jpeg)
121
- ![](./public/screenshots/paris-versatile-saturated.jpeg)
322
+ ![](./public/screenshots/eu-avenue-saturated.jpg)
323
+ ![](./public/screenshots/nyc-avenue-saturated.jpg)
324
+ ![](./public/screenshots/jp-avenue-saturated.jpg)
325
+ ![](./public/screenshots/eiffel-avenue-saturated.jpg)
326
+ ![](./public/screenshots/alps-avenue-saturated.jpg)
122
327
 
123
- ### `versatile-warm` ⤵️
328
+ ### `avenue-warm` ⤵️
124
329
  ```ts
125
330
  // Create the style
126
- const style = getStyle("versatile-warm", options);
331
+ const style = getStyle("avenue-warm", options);
127
332
  ```
128
- ![](./public/screenshots/usa-versatile-warm.jpeg)
129
- ![](./public/screenshots/alps-versatile-warm.jpeg)
130
- ![](./public/screenshots/manhattan-versatile-warm.jpeg)
131
- ![](./public/screenshots/na-versatile-warm.jpeg)
132
- ![](./public/screenshots/paris-versatile-warm.jpeg)
333
+ ![](./public/screenshots/eu-avenue-warm.jpg)
334
+ ![](./public/screenshots/nyc-avenue-warm.jpg)
335
+ ![](./public/screenshots/jp-avenue-warm.jpg)
336
+ ![](./public/screenshots/eiffel-avenue-warm.jpg)
337
+ ![](./public/screenshots/alps-avenue-warm.jpg)
133
338
 
134
- ### `versatile-vintage` ⤵️
339
+ ### `avenue-vintage` ⤵️
135
340
  ```ts
136
341
  // Create the style
137
- const style = getStyle("versatile-vintage", options);
342
+ const style = getStyle("avenue-vintage", options);
138
343
  ```
139
- ![](./public/screenshots/usa-versatile-vintage.jpeg)
140
- ![](./public/screenshots/alps-versatile-vintage.jpeg)
141
- ![](./public/screenshots/manhattan-versatile-vintage.jpeg)
142
- ![](./public/screenshots/na-versatile-vintage.jpeg)
143
- ![](./public/screenshots/paris-versatile-vintage.jpeg)
344
+ ![](./public/screenshots/eu-avenue-vintage.jpg)
345
+ ![](./public/screenshots/nyc-avenue-vintage.jpg)
346
+ ![](./public/screenshots/jp-avenue-vintage.jpg)
347
+ ![](./public/screenshots/eiffel-avenue-vintage.jpg)
348
+ ![](./public/screenshots/alps-avenue-vintage.jpg)
144
349
 
145
- ### `versatile-bnw` ⤵️
350
+ ### `avenue-bnw` ⤵️
146
351
  ```ts
147
352
  // Create the style
148
- const style = getStyle("versatile-bnw", options);
353
+ const style = getStyle("avenue-bnw", options);
149
354
  ```
150
- ![](./public/screenshots/usa-versatile-bnw.jpeg)
151
- ![](./public/screenshots/alps-versatile-bnw.jpeg)
152
- ![](./public/screenshots/manhattan-versatile-bnw.jpeg)
153
- ![](./public/screenshots/na-versatile-bnw.jpeg)
154
- ![](./public/screenshots/paris-versatile-bnw.jpeg)
355
+ ![](./public/screenshots/eu-avenue-bnw.jpg)
356
+ ![](./public/screenshots/nyc-avenue-bnw.jpg)
357
+ ![](./public/screenshots/jp-avenue-bnw.jpg)
358
+ ![](./public/screenshots/eiffel-avenue-bnw.jpg)
359
+ ![](./public/screenshots/alps-avenue-bnw.jpg)
155
360
 
156
- ### `versatile-blueprint` ⤵️
361
+ ### `avenue-blueprint` ⤵️
157
362
  ```ts
158
363
  // Create the style
159
- const style = getStyle("versatile-blueprint", options);
364
+ const style = getStyle("avenue-blueprint", options);
160
365
  ```
161
- ![](./public/screenshots/usa-versatile-blueprint.jpeg)
162
- ![](./public/screenshots/alps-versatile-blueprint.jpeg)
163
- ![](./public/screenshots/manhattan-versatile-blueprint.jpeg)
164
- ![](./public/screenshots/na-versatile-blueprint.jpeg)
165
- ![](./public/screenshots/paris-versatile-blueprint.jpeg)
366
+ ![](./public/screenshots/eu-avenue-blueprint.jpg)
367
+ ![](./public/screenshots/nyc-avenue-blueprint.jpg)
368
+ ![](./public/screenshots/jp-avenue-blueprint.jpg)
369
+ ![](./public/screenshots/eiffel-avenue-blueprint.jpg)
370
+ ![](./public/screenshots/alps-avenue-blueprint.jpg)