@versatiles/style 3.4.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.
Files changed (41) hide show
  1. package/LICENSE.md +24 -0
  2. package/README.MD +94 -0
  3. package/dist/index.d.ts +4 -0
  4. package/dist/index.js +3 -0
  5. package/dist/index.test.d.ts +1 -0
  6. package/dist/index.test.js +38 -0
  7. package/dist/lib/decorator.d.ts +3 -0
  8. package/dist/lib/decorator.js +123 -0
  9. package/dist/lib/decorator.test.d.ts +1 -0
  10. package/dist/lib/decorator.test.js +56 -0
  11. package/dist/lib/recolor.d.ts +13 -0
  12. package/dist/lib/recolor.js +92 -0
  13. package/dist/lib/recolor.test.d.ts +1 -0
  14. package/dist/lib/recolor.test.js +179 -0
  15. package/dist/lib/shortbread/layers.d.ts +7 -0
  16. package/dist/lib/shortbread/layers.js +508 -0
  17. package/dist/lib/shortbread/layers.test.d.ts +1 -0
  18. package/dist/lib/shortbread/layers.test.js +27 -0
  19. package/dist/lib/shortbread/properties.d.ts +7 -0
  20. package/dist/lib/shortbread/properties.js +124 -0
  21. package/dist/lib/shortbread/properties.test.d.ts +1 -0
  22. package/dist/lib/shortbread/properties.test.js +36 -0
  23. package/dist/lib/shortbread/template.d.ts +2 -0
  24. package/dist/lib/shortbread/template.js +339 -0
  25. package/dist/lib/shortbread/template.test.d.ts +1 -0
  26. package/dist/lib/shortbread/template.test.js +57 -0
  27. package/dist/lib/style_builder.d.ts +32 -0
  28. package/dist/lib/style_builder.js +84 -0
  29. package/dist/lib/style_builder.test.d.ts +1 -0
  30. package/dist/lib/style_builder.test.js +77 -0
  31. package/dist/lib/utils.d.ts +4 -0
  32. package/dist/lib/utils.js +106 -0
  33. package/dist/lib/utils.test.d.ts +1 -0
  34. package/dist/lib/utils.test.js +97 -0
  35. package/dist/styles/colorful.d.ts +53 -0
  36. package/dist/styles/colorful.js +871 -0
  37. package/dist/styles/graybeard.d.ts +5 -0
  38. package/dist/styles/graybeard.js +9 -0
  39. package/dist/styles/neutrino.d.ts +24 -0
  40. package/dist/styles/neutrino.js +356 -0
  41. package/package.json +60 -0
@@ -0,0 +1,124 @@
1
+ const propertyLookup = new Map();
2
+ const propertyDefs = [
3
+ { parent: 'layer', types: 'background,fill,line,symbol', key: 'filter', valueType: 'filter' },
4
+ { parent: 'layer', types: 'background,fill,line,symbol', key: 'maxzoom', valueType: 'number' },
5
+ { parent: 'layer', types: 'background,fill,line,symbol', key: 'minzoom', valueType: 'number' },
6
+ { parent: 'layout', types: 'background,fill,line,symbol', key: 'visibility', valueType: 'enum' },
7
+ { parent: 'layout', types: 'fill', key: 'fill-sort-key', valueType: 'number' },
8
+ { parent: 'layout', types: 'line', key: 'line-cap', valueType: 'enum' },
9
+ { parent: 'layout', types: 'line', key: 'line-join', valueType: 'enum' },
10
+ { parent: 'layout', types: 'line', key: 'line-miter-limit', valueType: 'number' },
11
+ { parent: 'layout', types: 'line', key: 'line-round-limit', valueType: 'number' },
12
+ { parent: 'layout', types: 'line', key: 'line-sort-key', valueType: 'number' },
13
+ { parent: 'layout', types: 'symbol', key: 'icon-allow-overlap', valueType: 'boolean' },
14
+ { parent: 'layout', types: 'symbol', key: 'icon-anchor', valueType: 'enum' },
15
+ { parent: 'layout', types: 'symbol', key: 'icon-ignore-placement', valueType: 'boolean' },
16
+ { parent: 'layout', types: 'symbol', key: 'icon-image', short: 'image', valueType: 'resolvedImage' },
17
+ { parent: 'layout', types: 'symbol', key: 'icon-keep-upright', valueType: 'boolean' },
18
+ { parent: 'layout', types: 'symbol', key: 'icon-offset', valueType: 'array' },
19
+ { parent: 'layout', types: 'symbol', key: 'icon-optional', valueType: 'boolean' },
20
+ { parent: 'layout', types: 'symbol', key: 'icon-overlap', valueType: 'enum' },
21
+ { parent: 'layout', types: 'symbol', key: 'icon-padding', valueType: 'padding' },
22
+ { parent: 'layout', types: 'symbol', key: 'icon-pitch-alignment', valueType: 'enum' },
23
+ { parent: 'layout', types: 'symbol', key: 'icon-rotate', valueType: 'number' },
24
+ { parent: 'layout', types: 'symbol', key: 'icon-rotation-alignment', valueType: 'enum' },
25
+ { parent: 'layout', types: 'symbol', key: 'icon-size', valueType: 'number' },
26
+ { parent: 'layout', types: 'symbol', key: 'icon-text-fit-padding', valueType: 'array' },
27
+ { parent: 'layout', types: 'symbol', key: 'icon-text-fit', valueType: 'enum' },
28
+ { parent: 'layout', types: 'symbol', key: 'symbol-avoid-edges', valueType: 'boolean' },
29
+ { parent: 'layout', types: 'symbol', key: 'symbol-placement', valueType: 'enum' },
30
+ { parent: 'layout', types: 'symbol', key: 'symbol-sort-key', valueType: 'number' },
31
+ { parent: 'layout', types: 'symbol', key: 'symbol-spacing', valueType: 'number' },
32
+ { parent: 'layout', types: 'symbol', key: 'symbol-z-order', valueType: 'enum' },
33
+ { parent: 'layout', types: 'symbol', key: 'text-allow-overlap', valueType: 'boolean' },
34
+ { parent: 'layout', types: 'symbol', key: 'text-anchor', valueType: 'enum' },
35
+ { parent: 'layout', types: 'symbol', key: 'text-field', short: 'text', valueType: 'formatted' },
36
+ { parent: 'layout', types: 'symbol', key: 'text-font', short: 'font', valueType: 'fonts' },
37
+ { parent: 'layout', types: 'symbol', key: 'text-ignore-placement', valueType: 'boolean' },
38
+ { parent: 'layout', types: 'symbol', key: 'text-justify', valueType: 'enum' },
39
+ { parent: 'layout', types: 'symbol', key: 'text-keep-upright', valueType: 'boolean' },
40
+ { parent: 'layout', types: 'symbol', key: 'text-letter-spacing', valueType: 'number' },
41
+ { parent: 'layout', types: 'symbol', key: 'text-line-height', valueType: 'number' },
42
+ { parent: 'layout', types: 'symbol', key: 'text-max-angle', valueType: 'number' },
43
+ { parent: 'layout', types: 'symbol', key: 'text-max-width', valueType: 'number' },
44
+ { parent: 'layout', types: 'symbol', key: 'text-offset', valueType: 'array' },
45
+ { parent: 'layout', types: 'symbol', key: 'text-optional', valueType: 'boolean' },
46
+ { parent: 'layout', types: 'symbol', key: 'text-overlap', valueType: 'enum' },
47
+ { parent: 'layout', types: 'symbol', key: 'text-padding', valueType: 'number' },
48
+ { parent: 'layout', types: 'symbol', key: 'text-pitch-alignment', valueType: 'enum' },
49
+ { parent: 'layout', types: 'symbol', key: 'text-radial-offset', valueType: 'number' },
50
+ { parent: 'layout', types: 'symbol', key: 'text-rotate', valueType: 'number' },
51
+ { parent: 'layout', types: 'symbol', key: 'text-rotation-alignment', valueType: 'enum' },
52
+ { parent: 'layout', types: 'symbol', key: 'text-size', short: 'size', valueType: 'number' },
53
+ { parent: 'layout', types: 'symbol', key: 'text-transform', valueType: 'enum' },
54
+ { parent: 'layout', types: 'symbol', key: 'text-variable-anchor-offset', valueType: 'variableAnchorOffsetCollection' },
55
+ { parent: 'layout', types: 'symbol', key: 'text-variable-anchor', valueType: 'array' },
56
+ { parent: 'layout', types: 'symbol', key: 'text-writing-mode', valueType: 'array' },
57
+ { parent: 'paint', types: 'background', key: 'background-color', short: 'color', valueType: 'color' },
58
+ { parent: 'paint', types: 'background', key: 'background-opacity', short: 'opacity', valueType: 'number' },
59
+ { parent: 'paint', types: 'background', key: 'background-pattern', short: 'image', valueType: 'resolvedImage' },
60
+ { parent: 'paint', types: 'fill', key: 'fill-antialias', valueType: 'boolean' },
61
+ { parent: 'paint', types: 'fill', key: 'fill-color', short: 'color', valueType: 'color' },
62
+ { parent: 'paint', types: 'fill', key: 'fill-extrusion-base', valueType: 'number' },
63
+ { parent: 'paint', types: 'fill', key: 'fill-extrusion-color', valueType: 'color' },
64
+ { parent: 'paint', types: 'fill', key: 'fill-extrusion-height', valueType: 'number' },
65
+ { parent: 'paint', types: 'fill', key: 'fill-extrusion-opacity', valueType: 'number' },
66
+ { parent: 'paint', types: 'fill', key: 'fill-extrusion-pattern', valueType: 'resolvedImage' },
67
+ { parent: 'paint', types: 'fill', key: 'fill-extrusion-translate-anchor', valueType: 'enum' },
68
+ { parent: 'paint', types: 'fill', key: 'fill-extrusion-translate', valueType: 'array' },
69
+ { parent: 'paint', types: 'fill', key: 'fill-extrusion-vertical-gradient', valueType: 'boolean' },
70
+ { parent: 'paint', types: 'fill', key: 'fill-opacity', short: 'opacity', valueType: 'number' },
71
+ { parent: 'paint', types: 'fill', key: 'fill-outline-color', valueType: 'color' },
72
+ { parent: 'paint', types: 'fill', key: 'fill-pattern', short: 'image', valueType: 'resolvedImage' },
73
+ { parent: 'paint', types: 'fill', key: 'fill-translate-anchor', valueType: 'enum' },
74
+ { parent: 'paint', types: 'fill', key: 'fill-translate', valueType: 'array' },
75
+ { parent: 'paint', types: 'line', key: 'line-blur', valueType: 'number' },
76
+ { parent: 'paint', types: 'line', key: 'line-color', short: 'color', valueType: 'color' },
77
+ { parent: 'paint', types: 'line', key: 'line-dasharray', valueType: 'array' },
78
+ { parent: 'paint', types: 'line', key: 'line-gap-width', valueType: 'number' },
79
+ { parent: 'paint', types: 'line', key: 'line-gradient', valueType: 'color' },
80
+ { parent: 'paint', types: 'line', key: 'line-offset', valueType: 'number' },
81
+ { parent: 'paint', types: 'line', key: 'line-opacity', short: 'opacity', valueType: 'number' },
82
+ { parent: 'paint', types: 'line', key: 'line-pattern', short: 'image', valueType: 'resolvedImage' },
83
+ { parent: 'paint', types: 'line', key: 'line-translate-anchor', valueType: 'enum' },
84
+ { parent: 'paint', types: 'line', key: 'line-translate', valueType: 'array' },
85
+ { parent: 'paint', types: 'line', key: 'line-width', short: 'size', valueType: 'number' },
86
+ { parent: 'paint', types: 'symbol', key: 'icon-color', short: 'color', valueType: 'color' },
87
+ { parent: 'paint', types: 'symbol', key: 'icon-halo-blur', valueType: 'number' },
88
+ { parent: 'paint', types: 'symbol', key: 'icon-halo-color', valueType: 'color' },
89
+ { parent: 'paint', types: 'symbol', key: 'icon-halo-width', valueType: 'number' },
90
+ { parent: 'paint', types: 'symbol', key: 'icon-opacity', short: 'opacity', valueType: 'number' },
91
+ { parent: 'paint', types: 'symbol', key: 'icon-translate-anchor', valueType: 'enum' },
92
+ { parent: 'paint', types: 'symbol', key: 'icon-translate', valueType: 'array' },
93
+ { parent: 'paint', types: 'symbol', key: 'text-color', short: 'color', valueType: 'color' },
94
+ { parent: 'paint', types: 'symbol', key: 'text-halo-blur', valueType: 'number' },
95
+ { parent: 'paint', types: 'symbol', key: 'text-halo-color', valueType: 'color' },
96
+ { parent: 'paint', types: 'symbol', key: 'text-halo-width', valueType: 'number' },
97
+ { parent: 'paint', types: 'symbol', key: 'text-opacity', short: 'opacity', valueType: 'number' },
98
+ { parent: 'paint', types: 'symbol', key: 'text-translate-anchor', valueType: 'enum' },
99
+ { parent: 'paint', types: 'symbol', key: 'text-translate', valueType: 'array' },
100
+ ];
101
+ propertyDefs.forEach((propertyDef) => {
102
+ const types = propertyDef.types;
103
+ types.split(',').forEach((type) => {
104
+ function add(propertyKey) {
105
+ const key = type + '/' + propertyKey;
106
+ const property = {
107
+ key: propertyDef.key,
108
+ parent: propertyDef.parent,
109
+ valueType: propertyDef.valueType,
110
+ };
111
+ const propertyList = propertyLookup.get(key);
112
+ if (propertyList) {
113
+ propertyList.push(property);
114
+ }
115
+ else {
116
+ propertyLookup.set(key, [property]);
117
+ }
118
+ }
119
+ add(propertyDef.key);
120
+ if (propertyDef.short != null)
121
+ add(propertyDef.short);
122
+ });
123
+ });
124
+ export default propertyLookup;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ import propertyLookup from './properties.js';
2
+ describe('propertyLookup', () => {
3
+ it('should be a Map', () => {
4
+ expect(propertyLookup).toBeInstanceOf(Map);
5
+ });
6
+ it('should contain keys for each type and property', () => {
7
+ const expectedTypes = ['background', 'fill', 'line', 'symbol'];
8
+ expectedTypes.forEach(type => {
9
+ propertyLookup.forEach((value, key) => {
10
+ if (key.startsWith(type)) {
11
+ expect(key).toMatch(new RegExp(`^${type}\/`));
12
+ }
13
+ });
14
+ });
15
+ });
16
+ it('should contain the correct properties for each type', () => {
17
+ const expectedProps = ['filter', 'maxzoom', 'minzoom', 'visibility'];
18
+ expectedProps.forEach(prop => {
19
+ propertyLookup.forEach((value, key) => {
20
+ if (key.endsWith(prop)) {
21
+ expect(value.some((p) => p.key === prop)).toBeTruthy();
22
+ }
23
+ });
24
+ });
25
+ });
26
+ it('should store properties with the correct structure', () => {
27
+ propertyLookup.forEach(properties => {
28
+ properties.forEach((prop) => {
29
+ expect(prop).toHaveProperty('key');
30
+ expect(prop).toHaveProperty('parent');
31
+ expect(prop).toHaveProperty('valueType');
32
+ expect(['layer', 'layout', 'paint']).toContain(prop.parent);
33
+ });
34
+ });
35
+ });
36
+ });
@@ -0,0 +1,2 @@
1
+ import type { MaplibreStyle } from '../style_builder.js';
2
+ export default function getTemplate(): MaplibreStyle;
@@ -0,0 +1,339 @@
1
+ /* eslint-disable @typescript-eslint/naming-convention */
2
+ const maxzoom = 14;
3
+ export default function getTemplate() {
4
+ return {
5
+ version: 8,
6
+ name: 'versatiles',
7
+ metadata: {
8
+ 'maputnik:renderer': 'mbgljs',
9
+ license: 'https://creativecommons.org/publicdomain/zero/1.0/',
10
+ },
11
+ glyphs: 'https://tiles.versatiles.org/fonts/{fontstack}/{range}.pbf',
12
+ sprite: 'https://tiles.versatiles.org/sprites/sprites',
13
+ sources: {
14
+ 'versatiles-shortbread': {
15
+ attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
16
+ tiles: [
17
+ 'https://tiles.versatiles.org/tiles/osm/{z}/{x}/{y}',
18
+ ],
19
+ type: 'vector',
20
+ scheme: 'xyz',
21
+ format: 'pbf',
22
+ bounds: [
23
+ -180,
24
+ -85.0511287798066,
25
+ 180,
26
+ 85.0511287798066,
27
+ ],
28
+ minzoom: 0,
29
+ maxzoom,
30
+ vector_layers: [
31
+ {
32
+ id: 'place_labels',
33
+ fields: {
34
+ kind: 'String',
35
+ name: 'String',
36
+ name_de: 'String',
37
+ name_en: 'String',
38
+ population: 'Number',
39
+ },
40
+ minzoom: 3,
41
+ maxzoom,
42
+ },
43
+ {
44
+ id: 'boundaries',
45
+ fields: {
46
+ admin_level: 'Number',
47
+ coastline: 'Boolean',
48
+ disputed: 'Boolean',
49
+ maritime: 'Boolean',
50
+ },
51
+ minzoom: 0,
52
+ maxzoom,
53
+ },
54
+ {
55
+ id: 'boundary_labels',
56
+ fields: {
57
+ admin_level: 'Number',
58
+ land_area: 'Number',
59
+ name: 'String',
60
+ name_de: 'String',
61
+ name_en: 'String',
62
+ name_single: 'String',
63
+ way_area: 'Number',
64
+ },
65
+ minzoom: 2,
66
+ maxzoom,
67
+ },
68
+ {
69
+ id: 'addresses',
70
+ fields: {
71
+ housename: 'String',
72
+ housenumber: 'String',
73
+ },
74
+ minzoom: 14,
75
+ maxzoom,
76
+ },
77
+ {
78
+ id: 'water_lines',
79
+ fields: {
80
+ bridge: 'Boolean',
81
+ kind: 'String',
82
+ tunnel: 'Boolean',
83
+ },
84
+ minzoom: 4,
85
+ maxzoom,
86
+ },
87
+ {
88
+ id: 'water_lines_labels',
89
+ fields: {
90
+ bridge: 'Boolean',
91
+ kind: 'String',
92
+ name: 'String',
93
+ name_de: 'String',
94
+ name_en: 'String',
95
+ tunnel: 'Boolean',
96
+ },
97
+ minzoom: 4,
98
+ maxzoom,
99
+ },
100
+ {
101
+ id: 'dam_lines',
102
+ fields: {
103
+ kind: 'String',
104
+ },
105
+ minzoom: 12,
106
+ maxzoom,
107
+ },
108
+ {
109
+ id: 'dam_polygons',
110
+ fields: {
111
+ kind: 'String',
112
+ },
113
+ minzoom: 12,
114
+ maxzoom,
115
+ },
116
+ {
117
+ id: 'pier_lines',
118
+ fields: {
119
+ kind: 'String',
120
+ },
121
+ minzoom: 12,
122
+ maxzoom,
123
+ },
124
+ {
125
+ id: 'pier_polygons',
126
+ fields: {
127
+ kind: 'String',
128
+ },
129
+ minzoom: 12,
130
+ maxzoom,
131
+ },
132
+ {
133
+ id: 'bridges',
134
+ fields: {
135
+ kind: 'String',
136
+ },
137
+ minzoom: 12,
138
+ maxzoom,
139
+ },
140
+ {
141
+ id: 'street_polygons',
142
+ fields: {
143
+ bridge: 'Boolean',
144
+ kind: 'String',
145
+ rail: 'Boolean',
146
+ service: 'String',
147
+ surface: 'String',
148
+ tunnel: 'Boolean',
149
+ },
150
+ minzoom: 11,
151
+ maxzoom,
152
+ },
153
+ {
154
+ id: 'streets_polygons_labels',
155
+ fields: {
156
+ kind: 'String',
157
+ name: 'String',
158
+ name_de: 'String',
159
+ name_en: 'String',
160
+ },
161
+ minzoom: 14,
162
+ maxzoom,
163
+ },
164
+ {
165
+ id: 'ferries',
166
+ fields: {
167
+ kind: 'String',
168
+ name: 'String',
169
+ name_de: 'String',
170
+ name_en: 'String',
171
+ },
172
+ minzoom: 8,
173
+ maxzoom,
174
+ },
175
+ {
176
+ id: 'streets',
177
+ fields: {
178
+ bicycle: 'String',
179
+ bridge: 'Boolean',
180
+ horse: 'String',
181
+ kind: 'String',
182
+ link: 'Boolean',
183
+ oneway: 'Boolean',
184
+ oneway_reverse: 'Boolean',
185
+ rail: 'Boolean',
186
+ service: 'String',
187
+ surface: 'String',
188
+ tracktype: 'String',
189
+ tunnel: 'Boolean',
190
+ },
191
+ minzoom: 5,
192
+ maxzoom,
193
+ },
194
+ {
195
+ id: 'street_labels',
196
+ fields: {
197
+ kind: 'String',
198
+ name: 'String',
199
+ name_de: 'String',
200
+ name_en: 'String',
201
+ ref: 'String',
202
+ ref_cols: 'Number',
203
+ ref_rows: 'Number',
204
+ tunnel: 'Boolean',
205
+ },
206
+ minzoom: 10,
207
+ maxzoom,
208
+ },
209
+ {
210
+ id: 'street_labels_points',
211
+ fields: {
212
+ kind: 'String',
213
+ name: 'String',
214
+ name_de: 'String',
215
+ name_en: 'String',
216
+ ref: 'String',
217
+ },
218
+ minzoom: 12,
219
+ maxzoom,
220
+ },
221
+ {
222
+ id: 'aerialways',
223
+ fields: {
224
+ kind: 'String',
225
+ },
226
+ minzoom: 12,
227
+ maxzoom,
228
+ },
229
+ {
230
+ id: 'public_transport',
231
+ fields: {
232
+ iata: 'String',
233
+ kind: 'String',
234
+ name: 'String',
235
+ name_de: 'String',
236
+ name_en: 'String',
237
+ station: 'String',
238
+ },
239
+ minzoom: 11,
240
+ maxzoom,
241
+ },
242
+ {
243
+ id: 'buildings',
244
+ fields: {
245
+ amenity: 'String',
246
+ dummy: 'Number',
247
+ name: 'String',
248
+ name_de: 'String',
249
+ name_en: 'String',
250
+ },
251
+ minzoom: 14,
252
+ maxzoom,
253
+ },
254
+ {
255
+ id: 'water_polygons',
256
+ fields: {
257
+ kind: 'String',
258
+ way_area: 'Number',
259
+ },
260
+ minzoom: 4,
261
+ maxzoom,
262
+ },
263
+ {
264
+ id: 'ocean',
265
+ fields: {
266
+ x: 'Number',
267
+ y: 'Number',
268
+ },
269
+ minzoom: 0,
270
+ maxzoom,
271
+ },
272
+ {
273
+ id: 'water_polygons_labels',
274
+ fields: {
275
+ kind: 'String',
276
+ name: 'String',
277
+ name_de: 'String',
278
+ name_en: 'String',
279
+ way_area: 'Number',
280
+ },
281
+ minzoom: 14,
282
+ maxzoom,
283
+ },
284
+ {
285
+ id: 'land',
286
+ fields: {
287
+ kind: 'String',
288
+ },
289
+ minzoom: 7,
290
+ maxzoom,
291
+ },
292
+ {
293
+ id: 'sites',
294
+ fields: {
295
+ amenity: 'String',
296
+ kind: 'String',
297
+ name: 'String',
298
+ name_de: 'String',
299
+ name_en: 'String',
300
+ },
301
+ minzoom: 14,
302
+ maxzoom,
303
+ },
304
+ {
305
+ id: 'pois',
306
+ fields: {
307
+ amenity: 'String',
308
+ atm: 'Boolean',
309
+ cuisine: 'String',
310
+ denomination: 'String',
311
+ emergency: 'String',
312
+ highway: 'String',
313
+ historic: 'String',
314
+ information: 'String',
315
+ leisure: 'String',
316
+ man_made: 'String',
317
+ name: 'String',
318
+ name_de: 'String',
319
+ name_en: 'String',
320
+ 'recycling:clothes': 'Boolean',
321
+ 'recycling:glass_bottles': 'Boolean',
322
+ 'recycling:paper': 'Boolean',
323
+ 'recycling:scrap_metal': 'Boolean',
324
+ religion: 'String',
325
+ shop: 'String',
326
+ sport: 'String',
327
+ tourism: 'String',
328
+ 'tower:type': 'String',
329
+ vending: 'String',
330
+ },
331
+ minzoom: 14,
332
+ maxzoom,
333
+ },
334
+ ],
335
+ },
336
+ },
337
+ layers: [],
338
+ };
339
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,57 @@
1
+ /* eslint-disable @typescript-eslint/naming-convention */
2
+ import getTemplate from './template.js';
3
+ describe('getTemplate', () => {
4
+ const styleTemplate = getTemplate();
5
+ it('returns a style object with the correct version', () => {
6
+ expect(styleTemplate).toHaveProperty('version', 8);
7
+ });
8
+ it('has the expected name for the style', () => {
9
+ expect(styleTemplate).toHaveProperty('name', 'versatiles');
10
+ });
11
+ it('contains metadata with expected properties', () => {
12
+ expect(styleTemplate).toHaveProperty('metadata');
13
+ expect(styleTemplate.metadata).toHaveProperty('maputnik:renderer', 'mbgljs');
14
+ expect(styleTemplate.metadata).toHaveProperty('license', 'https://creativecommons.org/publicdomain/zero/1.0/');
15
+ });
16
+ it('specifies glyphs and sprite URLs correctly', () => {
17
+ expect(styleTemplate).toHaveProperty('glyphs', 'https://tiles.versatiles.org/fonts/{fontstack}/{range}.pbf');
18
+ expect(styleTemplate).toHaveProperty('sprite', 'https://tiles.versatiles.org/sprites/sprites');
19
+ });
20
+ it('defines sources with required properties', () => {
21
+ expect(styleTemplate).toHaveProperty('sources');
22
+ const sources = styleTemplate.sources['versatiles-shortbread'];
23
+ expect(sources).toHaveProperty('type', 'vector');
24
+ expect(sources).toHaveProperty('scheme', 'xyz');
25
+ expect(sources).toHaveProperty('format', 'pbf');
26
+ expect(sources).toHaveProperty('tiles');
27
+ expect(sources.tiles).toContain('https://tiles.versatiles.org/tiles/osm/{z}/{x}/{y}');
28
+ });
29
+ it('sets bounds to the expected global extent', () => {
30
+ const expectedBounds = [-180, -85.0511287798066, 180, 85.0511287798066];
31
+ expect(styleTemplate.sources['versatiles-shortbread']).toHaveProperty('bounds', expectedBounds);
32
+ });
33
+ it('has layers array initialized as empty', () => {
34
+ expect(styleTemplate).toHaveProperty('layers');
35
+ expect(styleTemplate.layers).toEqual([]);
36
+ });
37
+ describe('sources vector_layers validation', () => {
38
+ expect(styleTemplate).toBeDefined();
39
+ expect(styleTemplate.sources).toBeDefined();
40
+ const { vector_layers } = styleTemplate.sources['versatiles-shortbread'];
41
+ expect(typeof vector_layers).toBe('object');
42
+ if (!vector_layers)
43
+ return;
44
+ it('contains vector_layers with id and fields', () => {
45
+ expect(Array.isArray(vector_layers)).toBeTruthy();
46
+ vector_layers.forEach(layer => {
47
+ expect(layer).toHaveProperty('id');
48
+ expect(layer).toHaveProperty('fields');
49
+ });
50
+ });
51
+ it('has maxzoom set to 14 for all vector layers', () => {
52
+ vector_layers.forEach(layer => {
53
+ expect(layer).toHaveProperty('maxzoom', 14);
54
+ });
55
+ });
56
+ });
57
+ });
@@ -0,0 +1,32 @@
1
+ import Color from 'color';
2
+ import type { RecolorOptions } from './recolor.js';
3
+ import type { Style } from 'mapbox-gl';
4
+ export type MaplibreStyle = Style;
5
+ export type StyleRuleValue = boolean | number | object | string;
6
+ export type StyleRule = Record<string, StyleRuleValue>;
7
+ export type StyleRules = Record<string, StyleRule>;
8
+ export type StylemakerColorLookup = Record<string, Color>;
9
+ export type StylemakerStringLookup = Record<string, string>;
10
+ export type LanguageSuffix = '_de' | '_en' | '';
11
+ export interface StyleRulesOptions {
12
+ colors: StylemakerColorLookup;
13
+ fonts: StylemakerStringLookup;
14
+ languageSuffix: string;
15
+ }
16
+ export default abstract class StyleBuilder {
17
+ #private;
18
+ baseUrl: string;
19
+ glyphsUrl: string;
20
+ spriteUrl: string;
21
+ tilesUrls: string[];
22
+ hideLabels: boolean;
23
+ languageSuffix: LanguageSuffix;
24
+ recolor: RecolorOptions;
25
+ abstract readonly name: string;
26
+ abstract fonts: Record<string, string>;
27
+ abstract colors: Record<string, string>;
28
+ constructor();
29
+ build(): MaplibreStyle;
30
+ protected resetColors(callback: (color: Color) => Color): void;
31
+ protected abstract getStyleRules(opt: StyleRulesOptions): StyleRules;
32
+ }