@versatiles/style 5.8.3 → 5.8.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/README.md +14 -14
- package/dist/index.d.ts +1 -1
- package/dist/index.js +570 -338
- package/dist/index.js.map +1 -1
- package/package.json +12 -7
- package/src/color/abstract.ts +1 -1
- package/src/color/hsl.test.ts +10 -16
- package/src/color/hsl.ts +11 -15
- package/src/color/hsv.test.ts +4 -10
- package/src/color/hsv.ts +38 -22
- package/src/color/index.test.ts +2 -4
- package/src/color/index.ts +1 -1
- package/src/color/random.test.ts +1 -1
- package/src/color/random.ts +127 -25
- package/src/color/rgb.test.ts +55 -36
- package/src/color/rgb.ts +35 -48
- package/src/color/utils.test.ts +4 -6
- package/src/color/utils.ts +1 -3
- package/src/guess_style/guess_style.test.ts +49 -43
- package/src/guess_style/guess_style.ts +64 -21
- package/src/guess_style/index.ts +0 -1
- package/src/index.test.ts +34 -7
- package/src/index.ts +29 -19
- package/src/lib/utils.test.ts +2 -2
- package/src/lib/utils.ts +2 -1
- package/src/shortbread/index.ts +0 -1
- package/src/shortbread/layers.test.ts +15 -1
- package/src/shortbread/layers.ts +204 -199
- package/src/shortbread/properties.test.ts +3 -4
- package/src/shortbread/properties.ts +18 -4
- package/src/shortbread/template.test.ts +7 -2
- package/src/shortbread/template.ts +7 -14
- package/src/style_builder/decorator.test.ts +4 -4
- package/src/style_builder/decorator.ts +29 -21
- package/src/style_builder/recolor.test.ts +6 -31
- package/src/style_builder/recolor.ts +20 -20
- package/src/style_builder/style_builder.test.ts +50 -13
- package/src/style_builder/style_builder.ts +29 -31
- package/src/style_builder/types.ts +85 -2
- package/src/styles/LICENSE.md +15 -15
- package/src/styles/colorful.test.ts +91 -0
- package/src/styles/colorful.ts +229 -122
- package/src/styles/eclipse.ts +1 -1
- package/src/styles/empty.ts +1 -1
- package/src/styles/graybeard.ts +2 -2
- package/src/styles/index.ts +0 -3
- package/src/styles/neutrino.ts +14 -16
- package/src/styles/shadow.ts +2 -2
- package/src/types/index.ts +0 -1
- package/src/types/maplibre.ts +17 -3
- package/src/types/tilejson.test.ts +8 -5
- package/src/types/tilejson.ts +13 -13
- package/src/types/vector_layer.test.ts +4 -1
- package/src/types/vector_layer.ts +7 -7
|
@@ -10,7 +10,7 @@ describe('propertyLookup', () => {
|
|
|
10
10
|
it('should contain keys for each type and property', () => {
|
|
11
11
|
const expectedTypes = ['background', 'fill', 'line', 'symbol'];
|
|
12
12
|
|
|
13
|
-
expectedTypes.forEach(type => {
|
|
13
|
+
expectedTypes.forEach((type) => {
|
|
14
14
|
propertyLookup.forEach((value, key) => {
|
|
15
15
|
if (key.startsWith(type)) {
|
|
16
16
|
expect(key).toMatch(new RegExp(`^${type}/`));
|
|
@@ -22,7 +22,7 @@ describe('propertyLookup', () => {
|
|
|
22
22
|
it('should contain the correct properties for each type', () => {
|
|
23
23
|
const expectedProps = ['filter', 'maxzoom', 'minzoom', 'visibility'];
|
|
24
24
|
|
|
25
|
-
expectedProps.forEach(prop => {
|
|
25
|
+
expectedProps.forEach((prop) => {
|
|
26
26
|
propertyLookup.forEach((value, key) => {
|
|
27
27
|
if (key.endsWith(prop)) {
|
|
28
28
|
expect(value.some((p: ShortbreadProperty) => p.key === prop)).toBeTruthy();
|
|
@@ -32,7 +32,7 @@ describe('propertyLookup', () => {
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
it('should store properties with the correct structure', () => {
|
|
35
|
-
propertyLookup.forEach(properties => {
|
|
35
|
+
propertyLookup.forEach((properties) => {
|
|
36
36
|
properties.forEach((prop: ShortbreadProperty) => {
|
|
37
37
|
expect(prop).toHaveProperty('key');
|
|
38
38
|
expect(prop).toHaveProperty('parent');
|
|
@@ -42,4 +42,3 @@ describe('propertyLookup', () => {
|
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
44
|
});
|
|
45
|
-
|
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
|
|
2
1
|
export interface ShortbreadProperty {
|
|
3
2
|
readonly key: string;
|
|
4
3
|
readonly parent: 'layer' | 'layout' | 'paint';
|
|
5
|
-
readonly valueType:
|
|
4
|
+
readonly valueType:
|
|
5
|
+
| 'array'
|
|
6
|
+
| 'boolean'
|
|
7
|
+
| 'color'
|
|
8
|
+
| 'enum'
|
|
9
|
+
| 'filter'
|
|
10
|
+
| 'fonts'
|
|
11
|
+
| 'formatted'
|
|
12
|
+
| 'number'
|
|
13
|
+
| 'padding'
|
|
14
|
+
| 'resolvedImage'
|
|
15
|
+
| 'variableAnchorOffsetCollection';
|
|
6
16
|
}
|
|
7
17
|
|
|
8
18
|
type ShortbreadPropertyDef = ShortbreadProperty & {
|
|
@@ -65,7 +75,12 @@ const propertyDefs: ShortbreadPropertyDef[] = [
|
|
|
65
75
|
{ parent: 'layout', types: 'symbol', key: 'text-rotation-alignment', valueType: 'enum' },
|
|
66
76
|
{ parent: 'layout', types: 'symbol', key: 'text-size', short: 'size', valueType: 'number' },
|
|
67
77
|
{ parent: 'layout', types: 'symbol', key: 'text-transform', valueType: 'enum' },
|
|
68
|
-
{
|
|
78
|
+
{
|
|
79
|
+
parent: 'layout',
|
|
80
|
+
types: 'symbol',
|
|
81
|
+
key: 'text-variable-anchor-offset',
|
|
82
|
+
valueType: 'variableAnchorOffsetCollection',
|
|
83
|
+
},
|
|
69
84
|
{ parent: 'layout', types: 'symbol', key: 'text-variable-anchor', valueType: 'array' },
|
|
70
85
|
{ parent: 'layout', types: 'symbol', key: 'text-writing-mode', valueType: 'array' },
|
|
71
86
|
|
|
@@ -118,7 +133,6 @@ propertyDefs.forEach((propertyDef: ShortbreadPropertyDef) => {
|
|
|
118
133
|
const types: string = propertyDef.types;
|
|
119
134
|
|
|
120
135
|
types.split(',').forEach((type: string) => {
|
|
121
|
-
|
|
122
136
|
function add(propertyKey: string): void {
|
|
123
137
|
const key = type + '/' + propertyKey;
|
|
124
138
|
const property: ShortbreadProperty = {
|
|
@@ -19,8 +19,13 @@ describe('getShortbreadTemplate', () => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
it('specifies glyphs and sprite URLs correctly', () => {
|
|
22
|
-
expect(styleTemplate).toHaveProperty(
|
|
23
|
-
|
|
22
|
+
expect(styleTemplate).toHaveProperty(
|
|
23
|
+
'glyphs',
|
|
24
|
+
'https://tiles.versatiles.org/assets/glyphs/{fontstack}/{range}.pbf'
|
|
25
|
+
);
|
|
26
|
+
expect(styleTemplate).toHaveProperty('sprite', [
|
|
27
|
+
{ id: 'basics', url: 'https://tiles.versatiles.org/assets/sprites/basics/sprites' },
|
|
28
|
+
]);
|
|
24
29
|
});
|
|
25
30
|
|
|
26
31
|
it('defines sources with required properties', () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { StyleSpecification } from
|
|
2
|
-
import { VectorLayer } from
|
|
1
|
+
import { StyleSpecification } from '@maplibre/maplibre-gl-style-spec';
|
|
2
|
+
import { VectorLayer } from '../types/vector_layer.js';
|
|
3
3
|
|
|
4
4
|
const maxzoom = 14;
|
|
5
5
|
|
|
@@ -15,19 +15,12 @@ export function getShortbreadTemplate(): StyleSpecification {
|
|
|
15
15
|
sources: {
|
|
16
16
|
'versatiles-shortbread': {
|
|
17
17
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
|
18
|
-
tiles: [
|
|
19
|
-
'https://tiles.versatiles.org/tiles/osm/{z}/{x}/{y}',
|
|
20
|
-
],
|
|
18
|
+
tiles: ['https://tiles.versatiles.org/tiles/osm/{z}/{x}/{y}'],
|
|
21
19
|
type: 'vector',
|
|
22
20
|
scheme: 'xyz',
|
|
23
|
-
bounds: [
|
|
24
|
-
-180,
|
|
25
|
-
-85.0511287798066,
|
|
26
|
-
180,
|
|
27
|
-
85.0511287798066,
|
|
28
|
-
],
|
|
21
|
+
bounds: [-180, -85.0511287798066, 180, 85.0511287798066],
|
|
29
22
|
minzoom: 0,
|
|
30
|
-
maxzoom
|
|
23
|
+
maxzoom,
|
|
31
24
|
},
|
|
32
25
|
},
|
|
33
26
|
layers: [],
|
|
@@ -339,5 +332,5 @@ export function getShortbreadVectorLayers(): VectorLayer[] {
|
|
|
339
332
|
minzoom: 14,
|
|
340
333
|
maxzoom,
|
|
341
334
|
},
|
|
342
|
-
]
|
|
343
|
-
}
|
|
335
|
+
];
|
|
336
|
+
}
|
|
@@ -11,11 +11,11 @@ describe('decorate function', () => {
|
|
|
11
11
|
];
|
|
12
12
|
|
|
13
13
|
const mockRules = {
|
|
14
|
-
|
|
14
|
+
layer1: {
|
|
15
15
|
color: '#ff0000',
|
|
16
16
|
visibility: 'none',
|
|
17
17
|
},
|
|
18
|
-
|
|
18
|
+
layer2: {
|
|
19
19
|
color: 'rgba(0, 255, 0, 0.5)',
|
|
20
20
|
visibility: 'visible',
|
|
21
21
|
},
|
|
@@ -31,7 +31,7 @@ describe('decorate function', () => {
|
|
|
31
31
|
it('should apply styles from rules to the corresponding layers', () => {
|
|
32
32
|
const result = decorate(mockLayers, mockRules, noRecolor);
|
|
33
33
|
|
|
34
|
-
result.forEach(layer => {
|
|
34
|
+
result.forEach((layer) => {
|
|
35
35
|
if (layer.id === 'layer1') {
|
|
36
36
|
expect(layer.paint).toHaveProperty('fill-color', 'rgb(255,0,0)');
|
|
37
37
|
expect(layer.layout).toHaveProperty('visibility', 'none');
|
|
@@ -45,7 +45,7 @@ describe('decorate function', () => {
|
|
|
45
45
|
|
|
46
46
|
it('should handle color conversion correctly', () => {
|
|
47
47
|
const colorRule = {
|
|
48
|
-
|
|
48
|
+
layer1: {
|
|
49
49
|
paintColor: Color.parse('#ff0000'),
|
|
50
50
|
},
|
|
51
51
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import { Color } from '../color/index.js';
|
|
3
2
|
import expandBraces from 'brace-expansion';
|
|
4
3
|
import maplibreProperties from '../shortbread/properties.js';
|
|
@@ -7,10 +6,8 @@ import type { MaplibreLayer } from '../types/index.js';
|
|
|
7
6
|
import type { StyleRule, StyleRuleValue, StyleRules } from './types.js';
|
|
8
7
|
import type { CachedRecolor } from './recolor.js';
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
9
|
export function decorate(layers: MaplibreLayer[], rules: StyleRules, recolor: CachedRecolor): MaplibreLayer[] {
|
|
13
|
-
const layerIds = layers.map(l => l.id);
|
|
10
|
+
const layerIds = layers.map((l) => l.id);
|
|
14
11
|
const layerIdSet = new Set(layerIds);
|
|
15
12
|
|
|
16
13
|
// Initialize a new map to hold final styles for layers
|
|
@@ -21,24 +18,24 @@ export function decorate(layers: MaplibreLayer[], rules: StyleRules, recolor: Ca
|
|
|
21
18
|
if (layerStyle == null) return;
|
|
22
19
|
|
|
23
20
|
// Expand any braces in IDs and filter them through a RegExp if necessary
|
|
24
|
-
const ids = expandBraces(idDef).flatMap(id => {
|
|
21
|
+
const ids = expandBraces(idDef).flatMap((id) => {
|
|
25
22
|
if (!id.includes('*')) return id;
|
|
26
|
-
const regExpString = id.replace(/[^a-z_:-]/g, c => {
|
|
23
|
+
const regExpString = id.replace(/[^a-z_:-]/g, (c) => {
|
|
27
24
|
if (c === '*') return '[a-z_-]*';
|
|
28
25
|
throw new Error('unknown char to process. Do not know how to make a RegExp from: ' + JSON.stringify(c));
|
|
29
26
|
});
|
|
30
27
|
const regExp = new RegExp(`^${regExpString}$`, 'i');
|
|
31
|
-
return layerIds.filter(layerId => regExp.test(layerId));
|
|
28
|
+
return layerIds.filter((layerId) => regExp.test(layerId));
|
|
32
29
|
});
|
|
33
30
|
|
|
34
|
-
ids.forEach(id => {
|
|
31
|
+
ids.forEach((id) => {
|
|
35
32
|
if (!layerIdSet.has(id)) return;
|
|
36
33
|
layerStyles.set(id, deepMerge(layerStyles.get(id) ?? {}, layerStyle));
|
|
37
34
|
});
|
|
38
35
|
});
|
|
39
36
|
|
|
40
37
|
// Deep clone the original layers and apply styles
|
|
41
|
-
return layers.flatMap(layer => {
|
|
38
|
+
return layers.flatMap((layer) => {
|
|
42
39
|
// Get the id and style of the layer
|
|
43
40
|
const layerStyle = layerStyles.get(layer.id);
|
|
44
41
|
|
|
@@ -52,30 +49,36 @@ export function decorate(layers: MaplibreLayer[], rules: StyleRules, recolor: Ca
|
|
|
52
49
|
|
|
53
50
|
// Function to process each style attribute for the layer
|
|
54
51
|
function processStyling(layer: MaplibreLayer, styleRule: StyleRule): void {
|
|
55
|
-
|
|
56
52
|
for (const [ruleKeyCamelCase, ruleValue] of Object.entries(styleRule)) {
|
|
57
53
|
if (ruleValue == null) continue;
|
|
58
54
|
|
|
59
55
|
// CamelCase to not-camel-case
|
|
60
|
-
const ruleKey = ruleKeyCamelCase.replace(/[A-Z]/g, c => '-' + c.toLowerCase());
|
|
56
|
+
const ruleKey = ruleKeyCamelCase.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase());
|
|
61
57
|
|
|
62
58
|
const propertyDefs = maplibreProperties.get(layer.type + '/' + ruleKey);
|
|
63
59
|
if (!propertyDefs) continue;
|
|
64
60
|
|
|
65
|
-
propertyDefs.forEach(propertyDef => {
|
|
61
|
+
propertyDefs.forEach((propertyDef) => {
|
|
66
62
|
const { key } = propertyDef;
|
|
67
63
|
let value: StyleRuleValue = ruleValue;
|
|
68
64
|
|
|
69
65
|
switch (propertyDef.valueType) {
|
|
70
|
-
case 'color':
|
|
71
|
-
|
|
66
|
+
case 'color':
|
|
67
|
+
value = processExpression(value, processColor);
|
|
68
|
+
break;
|
|
69
|
+
case 'fonts':
|
|
70
|
+
value = processExpression(value, processFont);
|
|
71
|
+
break;
|
|
72
72
|
case 'resolvedImage':
|
|
73
73
|
case 'formatted':
|
|
74
74
|
case 'array':
|
|
75
75
|
case 'boolean':
|
|
76
76
|
case 'enum':
|
|
77
|
-
case 'number':
|
|
78
|
-
|
|
77
|
+
case 'number':
|
|
78
|
+
value = processExpression(value);
|
|
79
|
+
break;
|
|
80
|
+
default:
|
|
81
|
+
throw new Error(`unknown propertyDef.valueType "${propertyDef.valueType}" for key "${key}"`);
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
switch (propertyDef.parent) {
|
|
@@ -94,7 +97,6 @@ export function decorate(layers: MaplibreLayer[], rules: StyleRules, recolor: Ca
|
|
|
94
97
|
layer.paint[key] = value;
|
|
95
98
|
break;
|
|
96
99
|
default:
|
|
97
|
-
|
|
98
100
|
throw new Error(`unknown parent "${propertyDef.parent}" for key "${key}"`);
|
|
99
101
|
}
|
|
100
102
|
});
|
|
@@ -104,7 +106,7 @@ export function decorate(layers: MaplibreLayer[], rules: StyleRules, recolor: Ca
|
|
|
104
106
|
if (typeof value === 'string') value = Color.parse(value);
|
|
105
107
|
if (value instanceof Color) {
|
|
106
108
|
const color = recolor.do(value as Color);
|
|
107
|
-
return color.asString()
|
|
109
|
+
return color.asString();
|
|
108
110
|
}
|
|
109
111
|
throw new Error(`unknown color type "${typeof value}"`);
|
|
110
112
|
}
|
|
@@ -114,7 +116,10 @@ export function decorate(layers: MaplibreLayer[], rules: StyleRules, recolor: Ca
|
|
|
114
116
|
throw new Error(`unknown font type "${typeof value}"`);
|
|
115
117
|
}
|
|
116
118
|
|
|
117
|
-
function processExpression(
|
|
119
|
+
function processExpression(
|
|
120
|
+
value: StyleRuleValue,
|
|
121
|
+
cbValue?: (value: StyleRuleValue) => StyleRuleValue
|
|
122
|
+
): StyleRuleValue {
|
|
118
123
|
if (typeof value === 'object') {
|
|
119
124
|
if (value instanceof Color) return processColor(value);
|
|
120
125
|
if (!Array.isArray(value)) {
|
|
@@ -124,7 +129,10 @@ export function decorate(layers: MaplibreLayer[], rules: StyleRules, recolor: Ca
|
|
|
124
129
|
return cbValue ? cbValue(value) : value;
|
|
125
130
|
}
|
|
126
131
|
|
|
127
|
-
function processZoomStops(
|
|
132
|
+
function processZoomStops(
|
|
133
|
+
obj: Record<string, StyleRuleValue>,
|
|
134
|
+
cbValue?: (value: StyleRuleValue) => StyleRuleValue
|
|
135
|
+
): { stops: StyleRuleValue[] } {
|
|
128
136
|
return {
|
|
129
137
|
stops: Object.entries(obj)
|
|
130
138
|
.map(([z, v]) => [parseInt(z, 10), cbValue ? cbValue(v) : v] as [number, StyleRuleValue])
|
|
@@ -132,4 +140,4 @@ export function decorate(layers: MaplibreLayer[], rules: StyleRules, recolor: Ca
|
|
|
132
140
|
};
|
|
133
141
|
}
|
|
134
142
|
}
|
|
135
|
-
}
|
|
143
|
+
}
|
|
@@ -2,7 +2,6 @@ import { describe, expect, it } from 'vitest';
|
|
|
2
2
|
import { Color } from '../color/index.js';
|
|
3
3
|
import { CachedRecolor, getDefaultRecolorFlags, recolorArray, recolorObject } from './recolor.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
describe('recolor', () => {
|
|
7
6
|
describe('getDefaultRecolorFlags', () => {
|
|
8
7
|
it('should return the default color transformer flags', () => {
|
|
@@ -120,7 +119,7 @@ describe('recolor', () => {
|
|
|
120
119
|
recolorArray(colors, { contrast: Infinity });
|
|
121
120
|
expect(colors2string(colors)).toBe('FFFF0000,00FFFF55,0000FFAA,FF0000,FF0000');
|
|
122
121
|
});
|
|
123
|
-
})
|
|
122
|
+
});
|
|
124
123
|
|
|
125
124
|
describe('brightness', () => {
|
|
126
125
|
it('should remove any brightness', () => {
|
|
@@ -266,13 +265,7 @@ describe('recolorArray', () => {
|
|
|
266
265
|
it('should recolor an array of colors with valid options', () => {
|
|
267
266
|
const colors = getTestColors();
|
|
268
267
|
recolorArray(colors, { rotate: 120 });
|
|
269
|
-
expect(colors.map((c) => c.asHex())).toEqual([
|
|
270
|
-
'#55FFAA00',
|
|
271
|
-
'#AA00FF55',
|
|
272
|
-
'#FF5500AA',
|
|
273
|
-
'#00AA55',
|
|
274
|
-
'#55AA77',
|
|
275
|
-
]);
|
|
268
|
+
expect(colors.map((c) => c.asHex())).toEqual(['#55FFAA00', '#AA00FF55', '#FF5500AA', '#00AA55', '#55AA77']);
|
|
276
269
|
});
|
|
277
270
|
|
|
278
271
|
it('should not alter the array if options are invalid', () => {
|
|
@@ -285,22 +278,10 @@ describe('recolorArray', () => {
|
|
|
285
278
|
it('should handle multiple transformations on the same array', () => {
|
|
286
279
|
const colors = getTestColors();
|
|
287
280
|
recolorArray(colors, { saturate: 0.5 });
|
|
288
|
-
expect(colors.map((c) => c.asHex())).toEqual([
|
|
289
|
-
'#FFAA5500',
|
|
290
|
-
'#00FFAA55',
|
|
291
|
-
'#5500FFAA',
|
|
292
|
-
'#AA5500',
|
|
293
|
-
'#BF7340',
|
|
294
|
-
]);
|
|
281
|
+
expect(colors.map((c) => c.asHex())).toEqual(['#FFAA5500', '#00FFAA55', '#5500FFAA', '#AA5500', '#BF7340']);
|
|
295
282
|
|
|
296
283
|
recolorArray(colors, { brightness: 0.5 });
|
|
297
|
-
expect(colors.map((c) => c.asHex())).toEqual([
|
|
298
|
-
'#FFD5AA00',
|
|
299
|
-
'#80FFD555',
|
|
300
|
-
'#AA80FFAA',
|
|
301
|
-
'#D5AA80',
|
|
302
|
-
'#DFB99F',
|
|
303
|
-
]);
|
|
284
|
+
expect(colors.map((c) => c.asHex())).toEqual(['#FFD5AA00', '#80FFD555', '#AA80FFAA', '#D5AA80', '#DFB99F']);
|
|
304
285
|
});
|
|
305
286
|
});
|
|
306
287
|
|
|
@@ -339,15 +320,9 @@ describe('CachedRecolor', () => {
|
|
|
339
320
|
});
|
|
340
321
|
|
|
341
322
|
function getTestColors(): Color[] {
|
|
342
|
-
return [
|
|
343
|
-
Color.parse('#FA50'),
|
|
344
|
-
Color.parse('#0FA5'),
|
|
345
|
-
Color.parse('#50FA'),
|
|
346
|
-
Color.parse('#A50F'),
|
|
347
|
-
Color.parse('#A75F'),
|
|
348
|
-
];
|
|
323
|
+
return [Color.parse('#FA50'), Color.parse('#0FA5'), Color.parse('#50FA'), Color.parse('#A50F'), Color.parse('#A75F')];
|
|
349
324
|
}
|
|
350
325
|
|
|
351
326
|
function colors2string(colors: Color[]): string {
|
|
352
|
-
return colors.map(c => c.asHex().slice(1)).join(',');
|
|
327
|
+
return colors.map((c) => c.asHex().slice(1)).join(',');
|
|
353
328
|
}
|
|
@@ -7,7 +7,7 @@ import { Color } from '../color/index.js';
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Configuration options for recoloring all map colors.
|
|
10
|
-
*
|
|
10
|
+
*
|
|
11
11
|
* The transformations (if specified) are done in the following order:
|
|
12
12
|
* 1. [Invert brightness](#invertbrightness)
|
|
13
13
|
* 2. [Rotate hue](#rotate)
|
|
@@ -29,7 +29,7 @@ import { Color } from '../color/index.js';
|
|
|
29
29
|
* }
|
|
30
30
|
* };
|
|
31
31
|
* ```
|
|
32
|
-
*
|
|
32
|
+
*
|
|
33
33
|
* If you want do make you map simply brighter or darker, you can use the `blend` option:
|
|
34
34
|
* ```typescript
|
|
35
35
|
* const style = VersaTilesStyle.colorful({
|
|
@@ -40,77 +40,77 @@ import { Color } from '../color/index.js';
|
|
|
40
40
|
* }
|
|
41
41
|
* };
|
|
42
42
|
* ```
|
|
43
|
-
*
|
|
43
|
+
*
|
|
44
44
|
*/
|
|
45
45
|
|
|
46
46
|
export interface RecolorOptions {
|
|
47
|
-
/**
|
|
47
|
+
/**
|
|
48
48
|
* If true, inverts all colors' brightness.
|
|
49
49
|
* See also {@link HSL.invertLuminosity}
|
|
50
|
-
|
|
50
|
+
*/
|
|
51
51
|
invertBrightness?: boolean;
|
|
52
52
|
|
|
53
|
-
/**
|
|
53
|
+
/**
|
|
54
54
|
* Rotate the hue of all colors in degrees (0-360).
|
|
55
55
|
* See also {@link HSL.rotateHue}
|
|
56
56
|
*/
|
|
57
57
|
rotate?: number;
|
|
58
58
|
|
|
59
|
-
/**
|
|
59
|
+
/**
|
|
60
60
|
* Adjust the saturation level. Positive values increase, negative values decrease saturation.
|
|
61
61
|
* |value|effect |
|
|
62
62
|
* |----:|-----------------|
|
|
63
63
|
* | -1|grayscale |
|
|
64
64
|
* | 0|no effect |
|
|
65
65
|
* | 1|double saturation|
|
|
66
|
-
*
|
|
66
|
+
*
|
|
67
67
|
* See also {@link HSL.saturate}
|
|
68
68
|
*/
|
|
69
69
|
saturate?: number;
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
|
-
* Adjust the gamma (non-linear brightness adjustment).
|
|
73
|
-
* Defaults to 1.
|
|
72
|
+
* Adjust the gamma (non-linear brightness adjustment).
|
|
73
|
+
* Defaults to 1.
|
|
74
74
|
* See also {@link RGB.gamma}
|
|
75
75
|
*/
|
|
76
76
|
gamma?: number;
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
|
-
* Adjust the contrast level.
|
|
80
|
-
* Values > 1 increase contrast, values < 1 decrease it.
|
|
81
|
-
* Defaults to 1.
|
|
79
|
+
* Adjust the contrast level.
|
|
80
|
+
* Values > 1 increase contrast, values < 1 decrease it.
|
|
81
|
+
* Defaults to 1.
|
|
82
82
|
* See also {@link RGB.contrast}
|
|
83
83
|
*/
|
|
84
84
|
contrast?: number;
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
|
-
* Adjust the brightness level.
|
|
88
|
-
* Positive values make it brighter, negative values make it darker.
|
|
89
|
-
* Defaults to 0.
|
|
87
|
+
* Adjust the brightness level.
|
|
88
|
+
* Positive values make it brighter, negative values make it darker.
|
|
89
|
+
* Defaults to 0.
|
|
90
90
|
* See also {@link RGB.brightness}
|
|
91
91
|
*/
|
|
92
92
|
brightness?: number;
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
|
-
* Intensity of the tinting effect (0 = none, 1 = full effect).
|
|
95
|
+
* Intensity of the tinting effect (0 = none, 1 = full effect).
|
|
96
96
|
* See also {@link RGB.tint}
|
|
97
97
|
*/
|
|
98
98
|
tint?: number;
|
|
99
99
|
|
|
100
100
|
/**
|
|
101
|
-
* The tinting color in hex format (default: '#FF0000').
|
|
101
|
+
* The tinting color in hex format (default: '#FF0000').
|
|
102
102
|
* See also {@link RGB.tint}
|
|
103
103
|
*/
|
|
104
104
|
tintColor?: string;
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
|
-
* Intensity of the blending effect (0 = none, 1 = full effect).
|
|
107
|
+
* Intensity of the blending effect (0 = none, 1 = full effect).
|
|
108
108
|
* See also {@link RGB.blend}
|
|
109
109
|
*/
|
|
110
110
|
blend?: number;
|
|
111
111
|
|
|
112
112
|
/**
|
|
113
|
-
* The blending color in hex format (default: '#000000').
|
|
113
|
+
* The blending color in hex format (default: '#000000').
|
|
114
114
|
* See also {@link RGB.blend}
|
|
115
115
|
*/
|
|
116
116
|
blendColor?: string;
|
|
@@ -12,7 +12,7 @@ class MockStyleBuilder extends Colorful {
|
|
|
12
12
|
public defaultFonts = { regular: 'Arial', bold: 'Courier' };
|
|
13
13
|
|
|
14
14
|
public invertColors(): void {
|
|
15
|
-
this.transformDefaultColors(color => color.invert());
|
|
15
|
+
this.transformDefaultColors((color) => color.invert());
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
protected getStyleRules(opt: StyleRulesOptions): StyleRules {
|
|
@@ -59,18 +59,55 @@ describe('StyleBuilder', () => {
|
|
|
59
59
|
|
|
60
60
|
it('should create default options', () => {
|
|
61
61
|
expect(builder.getDefaultOptions()).toStrictEqual({
|
|
62
|
-
baseUrl: '',
|
|
63
|
-
bounds: [
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
62
|
+
baseUrl: 'https://tiles.versatiles.org',
|
|
63
|
+
bounds: [-180, -85.0511287798066, 180, 85.0511287798066],
|
|
64
|
+
colors: {
|
|
65
|
+
agriculture: '#F0E7D1',
|
|
66
|
+
boundary: '#A6A6C8',
|
|
67
|
+
building: '#F2EAE2',
|
|
68
|
+
buildingbg: '#DFDBD7',
|
|
69
|
+
burial: '#DDDBCA',
|
|
70
|
+
commercial: '#F7DEED40',
|
|
71
|
+
construction: '#A9A9A9',
|
|
72
|
+
cycle: '#EFF9FF',
|
|
73
|
+
danger: '#FF0000',
|
|
74
|
+
disputed: '#BEBCCF',
|
|
75
|
+
education: '#FFFF80',
|
|
76
|
+
foot: '#FBEBFF',
|
|
77
|
+
glacier: '#FFFFFF',
|
|
78
|
+
grass: '#D8E8C8',
|
|
79
|
+
hospital: '#FF6666',
|
|
80
|
+
industrial: '#FFF4C255',
|
|
81
|
+
label: '#333344',
|
|
82
|
+
labelHalo: '#FFFFFFCC',
|
|
83
|
+
land: '#F9F4EE',
|
|
84
|
+
leisure: '#E7EDDE',
|
|
85
|
+
motorway: '#FFCC88',
|
|
86
|
+
motorwaybg: '#E9AC77',
|
|
87
|
+
park: '#D9D9A5',
|
|
88
|
+
parking: '#EBE8E6',
|
|
89
|
+
poi: '#555555',
|
|
90
|
+
prison: '#FDF2FC',
|
|
91
|
+
rail: '#B1BBC4',
|
|
92
|
+
residential: '#EAE6E133',
|
|
93
|
+
rock: '#E0E4E5',
|
|
94
|
+
sand: '#FAFAED',
|
|
95
|
+
shield: '#FFFFFF',
|
|
96
|
+
street: '#FFFFFF',
|
|
97
|
+
streetbg: '#CFCDCA',
|
|
98
|
+
subway: '#A6B8C7',
|
|
99
|
+
symbol: '#66626A',
|
|
100
|
+
trunk: '#FFEEAA',
|
|
101
|
+
trunkbg: '#E9AC77',
|
|
102
|
+
waste: '#DBD6BD',
|
|
103
|
+
water: '#BEDDF3',
|
|
104
|
+
wetland: '#D3E6DB',
|
|
105
|
+
wood: '#66AA44',
|
|
106
|
+
},
|
|
70
107
|
fonts: { regular: 'Arial', bold: 'Courier' },
|
|
71
|
-
glyphs: '',
|
|
108
|
+
glyphs: '/assets/glyphs/{fontstack}/{range}.pbf',
|
|
72
109
|
hideLabels: false,
|
|
73
|
-
language:
|
|
110
|
+
language: '',
|
|
74
111
|
recolor: {
|
|
75
112
|
brightness: 0,
|
|
76
113
|
contrast: 1,
|
|
@@ -83,8 +120,8 @@ describe('StyleBuilder', () => {
|
|
|
83
120
|
blend: 0,
|
|
84
121
|
blendColor: '#000000',
|
|
85
122
|
},
|
|
86
|
-
sprite: '',
|
|
87
|
-
tiles: [],
|
|
123
|
+
sprite: [{ id: 'basics', url: '/assets/sprites/basics/sprites' }],
|
|
124
|
+
tiles: ['/tiles/osm/{z}/{x}/{y}'],
|
|
88
125
|
});
|
|
89
126
|
});
|
|
90
127
|
|