@massif-maps/style-tools 6.1.0-rc.1
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 +58 -0
- package/dist/cli.js +436 -0
- package/dist/cli.js.map +1 -0
- package/dist/generated/properties.json +2488 -0
- package/dist/legend-svg.js +142 -0
- package/dist/legend-svg.js.map +1 -0
- package/dist/mapbox2css/browser-host.js +27 -0
- package/dist/mapbox2css/browser-host.js.map +1 -0
- package/dist/mapbox2css/casing.js +84 -0
- package/dist/mapbox2css/casing.js.map +1 -0
- package/dist/mapbox2css/config.js +212 -0
- package/dist/mapbox2css/config.js.map +1 -0
- package/dist/mapbox2css/contour.js +61 -0
- package/dist/mapbox2css/contour.js.map +1 -0
- package/dist/mapbox2css/coverage.js +56 -0
- package/dist/mapbox2css/coverage.js.map +1 -0
- package/dist/mapbox2css/emissive.js +192 -0
- package/dist/mapbox2css/emissive.js.map +1 -0
- package/dist/mapbox2css/expression.js +606 -0
- package/dist/mapbox2css/expression.js.map +1 -0
- package/dist/mapbox2css/filter.js +285 -0
- package/dist/mapbox2css/filter.js.map +1 -0
- package/dist/mapbox2css/fold.js +588 -0
- package/dist/mapbox2css/fold.js.map +1 -0
- package/dist/mapbox2css/host.js +13 -0
- package/dist/mapbox2css/host.js.map +1 -0
- package/dist/mapbox2css/index.js +3599 -0
- package/dist/mapbox2css/index.js.map +1 -0
- package/dist/mapbox2css/narrow.js +284 -0
- package/dist/mapbox2css/narrow.js.map +1 -0
- package/dist/mapbox2css/node-host.js +36 -0
- package/dist/mapbox2css/node-host.js.map +1 -0
- package/dist/mapbox2css/placement.js +62 -0
- package/dist/mapbox2css/placement.js.map +1 -0
- package/dist/mapbox2css/png.js +264 -0
- package/dist/mapbox2css/png.js.map +1 -0
- package/dist/mapbox2css/properties.js +155 -0
- package/dist/mapbox2css/properties.js.map +1 -0
- package/dist/mapbox2css/schema.js +865 -0
- package/dist/mapbox2css/schema.js.map +1 -0
- package/dist/mapbox2css/shield.js +118 -0
- package/dist/mapbox2css/shield.js.map +1 -0
- package/dist/mapbox2css/split.js +380 -0
- package/dist/mapbox2css/split.js.map +1 -0
- package/dist/mapbox2css/sprite.js +882 -0
- package/dist/mapbox2css/sprite.js.map +1 -0
- package/dist/mapbox2css/types.js +2 -0
- package/dist/mapbox2css/types.js.map +1 -0
- package/dist/mapbox2css/variables.js +273 -0
- package/dist/mapbox2css/variables.js.map +1 -0
- package/dist/wasm.js +43 -0
- package/dist/wasm.js.map +1 -0
- package/package.json +48 -0
- package/wasm/massif-style.mjs +2 -0
- package/wasm/massif-style.wasm +0 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { Untranslatable, conjunction, translateExpression, zoomOffsetLevels } from './expression.js';
|
|
2
|
+
import { negatedSet } from './narrow.js';
|
|
3
|
+
const LEGACY_COMPARISON = {
|
|
4
|
+
'==': '=', '!=': '!=', '<': '<', '<=': '<=', '>': '>', '>=': '>=',
|
|
5
|
+
};
|
|
6
|
+
// MapBox's $type names against mapnik::geometry_type, which is what the decoder exposes.
|
|
7
|
+
const GEOMETRY_TYPE = {
|
|
8
|
+
Point: 1, MultiPoint: 1, LineString: 2, MultiLineString: 2, Polygon: 3, MultiPolygon: 3,
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A MapBox filter -> CartoCSS selector fragments, already complete: either a bracketed test
|
|
12
|
+
* (`[class = 'motorway']`) or a `when(...)`. `selector = *predicate` in the grammar, so the caller
|
|
13
|
+
* concatenates them and the result means AND.
|
|
14
|
+
*
|
|
15
|
+
* A bracketed test only takes a CONSTANT on the right, so anything comparing two fields, or nesting
|
|
16
|
+
* an or, falls back to when() - which carries a whole expression.
|
|
17
|
+
*/
|
|
18
|
+
export function translateFilter(filter) {
|
|
19
|
+
if (filter === undefined || filter === null)
|
|
20
|
+
return [];
|
|
21
|
+
if (!Array.isArray(filter) || filter.length === 0)
|
|
22
|
+
throw new Untranslatable('malformed filter');
|
|
23
|
+
const head = filter[0];
|
|
24
|
+
if (typeof head !== 'string')
|
|
25
|
+
throw new Untranslatable('non-string filter operator');
|
|
26
|
+
if (head === 'all') {
|
|
27
|
+
return filter.slice(1).flatMap((sub) => translateFilter(sub));
|
|
28
|
+
}
|
|
29
|
+
const zoomParam = translateZoomParameter(filter);
|
|
30
|
+
if (zoomParam !== null)
|
|
31
|
+
return [zoomParam];
|
|
32
|
+
const bracketed = translateBracketed(filter);
|
|
33
|
+
if (bracketed !== null)
|
|
34
|
+
return [bracketed];
|
|
35
|
+
// "None of these" is a conjunction, so it brackets one test per value and the compiler keeps
|
|
36
|
+
// its grip on the rule. The positive set test is a disjunction and has no bracketed form.
|
|
37
|
+
const excluded = translateExcluded(filter);
|
|
38
|
+
return excluded ?? [`when(${filterExpression(filter)})`];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* `["zoom"]` against a live config: a zoom threshold an app sets, as `[zoom >= 'param::name']` - a
|
|
42
|
+
* selector the decoder prunes per tile, where the expression form was a when() read per feature.
|
|
43
|
+
* Only when the two zooms agree (512 px tiles): the selector has no room for an offset.
|
|
44
|
+
*/
|
|
45
|
+
function translateZoomParameter(filter) {
|
|
46
|
+
const [head, zoom, config] = filter;
|
|
47
|
+
if (filter.length !== 3 || typeof head !== 'string' || !['>=', '>', '<', '<='].includes(head))
|
|
48
|
+
return null;
|
|
49
|
+
if (!Array.isArray(zoom) || zoom.length !== 1 || zoom[0] !== 'zoom')
|
|
50
|
+
return null;
|
|
51
|
+
if (!Array.isArray(config) || config[0] !== 'config' || typeof config[1] !== 'string')
|
|
52
|
+
return null;
|
|
53
|
+
return zoomOffsetLevels() === 0 ? `[zoom ${head} 'param::${config[1]}']` : null;
|
|
54
|
+
}
|
|
55
|
+
function translateExcluded(filter) {
|
|
56
|
+
const clause = negatedSet(filter);
|
|
57
|
+
if (clause === null)
|
|
58
|
+
return null;
|
|
59
|
+
const tests = clause.values.map((v) => {
|
|
60
|
+
const value = expressionConstant(clause.field, v);
|
|
61
|
+
return value === null ? null : `[${predicateKey(clause.field)} != ${value}]`;
|
|
62
|
+
});
|
|
63
|
+
return tests.every((test) => test !== null) ? tests : null;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A filter as one CartoCSS boolean expression, for when().
|
|
67
|
+
*
|
|
68
|
+
* The legacy forms and the expression forms mean DIFFERENT things by the same shape:
|
|
69
|
+
* `["==", "class", "x"]` compares the FIELD class, while `["==", ["get", "class"], "x"]` is an
|
|
70
|
+
* expression whose first argument happens to be a get. Handing a legacy filter to the expression
|
|
71
|
+
* translator reads its field name as a string literal, so the two are kept apart here.
|
|
72
|
+
*/
|
|
73
|
+
function filterExpression(filter) {
|
|
74
|
+
const [head, ...args] = filter;
|
|
75
|
+
if (head === 'all' || head === 'any') {
|
|
76
|
+
const parts = args.map((a) => filterExpression(a));
|
|
77
|
+
// '&&' is unparseable here - see conjunction() in expression.ts.
|
|
78
|
+
return head === 'any' ? `(${parts.join(' || ')})` : conjunction(parts);
|
|
79
|
+
}
|
|
80
|
+
if (head === '!' && args.length === 1) {
|
|
81
|
+
return `(!${filterExpression(args[0])})`;
|
|
82
|
+
}
|
|
83
|
+
if (isLegacy(filter)) {
|
|
84
|
+
const key = fieldRef(args[0]);
|
|
85
|
+
if (key === null)
|
|
86
|
+
throw new Untranslatable(`filter key ${String(args[0])}`);
|
|
87
|
+
const field = `[${key}]`;
|
|
88
|
+
if (head === 'has')
|
|
89
|
+
return `(${field} != null)`;
|
|
90
|
+
if (head === '!has')
|
|
91
|
+
return `(${field} = null)`;
|
|
92
|
+
if (head === 'in' || head === '!in') {
|
|
93
|
+
const op = head === 'in' ? '=' : '!=';
|
|
94
|
+
const tests = args.slice(1).map((v) => `${field} ${op} ${literalFor(args[0], v)}`);
|
|
95
|
+
return head === 'in' ? `(${tests.join(' || ')})` : conjunction(tests);
|
|
96
|
+
}
|
|
97
|
+
return `(${field} ${LEGACY_COMPARISON[head]} ${literalFor(args[0], args[1])})`;
|
|
98
|
+
}
|
|
99
|
+
const chain = setTestChain(filter);
|
|
100
|
+
if (chain !== null)
|
|
101
|
+
return chain;
|
|
102
|
+
return translateExpression(filter);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* "input is one of these", in the two spellings a style writes it in: `["match", input, labels,
|
|
106
|
+
* true, false]` (MapTiler's) and `["in", input, ["literal", labels]]`. The generic translation
|
|
107
|
+
* wraps the first in `? true : false` - noise the decoder re-evaluates for every feature. As a
|
|
108
|
+
* filter each is just the chain. The operands the other way round is the NEGATION, which is a
|
|
109
|
+
* conjunction rather than an or-chain.
|
|
110
|
+
*
|
|
111
|
+
* The labels go through the same constant translation a bracketed test uses.
|
|
112
|
+
* `mapnik::geometry_type` is a NUMBER (mapnikvt ExpressionContext.cpp), so a label naming it
|
|
113
|
+
* `'LineString'` was a type mismatch, which `EQ` answers false for - the chain was false for every
|
|
114
|
+
* feature and the rule never drew. 20 rules in OpenFreeMap Liberty and 11 in MapTiler streets-v4
|
|
115
|
+
* were dead this way.
|
|
116
|
+
*/
|
|
117
|
+
function setTestChain(filter) {
|
|
118
|
+
const test = setTest(filter);
|
|
119
|
+
if (test === null)
|
|
120
|
+
return null;
|
|
121
|
+
const input = translateExpression(test.input);
|
|
122
|
+
const key = expressionKey(test.input);
|
|
123
|
+
const values = (key === null ? null : distinctConstants(key, test.labels))
|
|
124
|
+
?? test.labels.map((label) => translateExpression(label));
|
|
125
|
+
const tests = values.map((value) => `${input} ${test.positive ? '=' : '!='} ${value}`);
|
|
126
|
+
return test.positive ? `(${tests.join(' || ')})` : conjunction(tests);
|
|
127
|
+
}
|
|
128
|
+
function setTest(filter) {
|
|
129
|
+
const [head, ...args] = filter;
|
|
130
|
+
if (head === 'match' && filter.length === 5 && typeof filter[3] === 'boolean' && filter[4] === !filter[3]) {
|
|
131
|
+
const labels = Array.isArray(filter[2]) ? filter[2] : [filter[2]];
|
|
132
|
+
return { input: args[0], labels, positive: filter[3] === true };
|
|
133
|
+
}
|
|
134
|
+
// The legacy `["in", "class", "a", "b"]` names its field bare and is handled with the other
|
|
135
|
+
// legacy forms; this is the expression spelling.
|
|
136
|
+
if ((head === 'in' || head === '!in') && filter.length === 3 && typeof args[0] !== 'string') {
|
|
137
|
+
const literal = filter[2];
|
|
138
|
+
if (!Array.isArray(literal) || literal[0] !== 'literal' || !Array.isArray(literal[1]))
|
|
139
|
+
return null;
|
|
140
|
+
return { input: args[0], labels: literal[1], positive: head === 'in' };
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The labels of a set test as DISTINCT constants, or null when one of them is not a constant.
|
|
146
|
+
* Several labels can name one constant - LineString and MultiLineString are both geometry type 2 -
|
|
147
|
+
* and collapsed to one, the test brackets.
|
|
148
|
+
*/
|
|
149
|
+
function distinctConstants(key, labels) {
|
|
150
|
+
const values = labels.map((label) => expressionConstant(key, label));
|
|
151
|
+
return values.some((value) => value === null) ? null : [...new Set(values)];
|
|
152
|
+
}
|
|
153
|
+
/** MapBox's own test: a legacy filter names its field as a bare string. */
|
|
154
|
+
function isLegacy(filter) {
|
|
155
|
+
const [head, ...args] = filter;
|
|
156
|
+
if (typeof head !== 'string' || typeof args[0] !== 'string')
|
|
157
|
+
return false;
|
|
158
|
+
return head in LEGACY_COMPARISON || ['has', '!has', 'in', '!in'].includes(head);
|
|
159
|
+
}
|
|
160
|
+
/** $type compares against the numeric mapnik geometry type, everything else against the literal. */
|
|
161
|
+
function literalFor(key, value) {
|
|
162
|
+
if (key === '$type' && typeof value === 'string' && value in GEOMETRY_TYPE) {
|
|
163
|
+
return String(GEOMETRY_TYPE[value]);
|
|
164
|
+
}
|
|
165
|
+
return translateExpression(value);
|
|
166
|
+
}
|
|
167
|
+
/** The legacy forms that have a `[field op constant]` equivalent. Null when they do not. */
|
|
168
|
+
function translateBracketed(filter) {
|
|
169
|
+
const [head, ...args] = filter;
|
|
170
|
+
// `["!", ["has", f]]` is `!has`, which brackets; left as a negation it became a when().
|
|
171
|
+
if (head === '!' && args.length === 1 && Array.isArray(args[0])) {
|
|
172
|
+
const inner = args[0];
|
|
173
|
+
if (inner[0] === 'has')
|
|
174
|
+
return translateBracketed(['!has', inner[1]]);
|
|
175
|
+
if (inner[0] === '!has')
|
|
176
|
+
return translateBracketed(['has', inner[1]]);
|
|
177
|
+
}
|
|
178
|
+
if (typeof head === 'string' && LEGACY_COMPARISON[head] && args.length === 2 && typeof args[0] === 'string') {
|
|
179
|
+
const key = fieldRef(args[0]);
|
|
180
|
+
const value = constant(args[0], args[1]);
|
|
181
|
+
return key !== null && value !== null ? `[${predicateKey(key)} ${LEGACY_COMPARISON[head]} ${value}]` : null;
|
|
182
|
+
}
|
|
183
|
+
if ((head === 'has' || head === '!has') && args.length === 1 && typeof args[0] === 'string') {
|
|
184
|
+
const key = fieldRef(args[0]);
|
|
185
|
+
return key === null ? null : `[${predicateKey(key)} ${head === 'has' ? '!=' : '='} null]`;
|
|
186
|
+
}
|
|
187
|
+
if (head === 'in' && args.length === 2 && typeof args[0] === 'string') {
|
|
188
|
+
const key = fieldRef(args[0]);
|
|
189
|
+
const value = constant(args[0], args[1]);
|
|
190
|
+
return key !== null && value !== null ? `[${predicateKey(key)} = ${value}]` : null;
|
|
191
|
+
}
|
|
192
|
+
// The EXPRESSION spelling of the same tests. A bracketed predicate is a plain filter the
|
|
193
|
+
// decoder can decide per rule; when() carries a whole expression it has to evaluate per
|
|
194
|
+
// feature, so a style written in expressions - which is every modern one - was paying for a
|
|
195
|
+
// when() on tests that are ordinary comparisons.
|
|
196
|
+
if (typeof head === 'string' && LEGACY_COMPARISON[head] && args.length === 2) {
|
|
197
|
+
const key = expressionKey(args[0]);
|
|
198
|
+
const value = key === null ? null : expressionConstant(key, args[1]);
|
|
199
|
+
return key !== null && value !== null ? `[${predicateKey(key)} ${LEGACY_COMPARISON[head]} ${value}]` : null;
|
|
200
|
+
}
|
|
201
|
+
// A set test naming ONE distinct constant is an equality test - which is every
|
|
202
|
+
// `["LineString", "MultiLineString"]` geometry test, both being mapnik geometry type 2.
|
|
203
|
+
const test = setTest(filter);
|
|
204
|
+
const setKey = test?.positive ? expressionKey(test.input) : null;
|
|
205
|
+
const setValues = setKey === null ? null : distinctConstants(setKey, test.labels);
|
|
206
|
+
if (setKey !== null && setValues !== null && setValues.length === 1) {
|
|
207
|
+
return `[${predicateKey(setKey)} = ${setValues[0]}]`;
|
|
208
|
+
}
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* `["get", k]`, `["geometry-type"]`, `["id"]` and a LIVE config as the field a bracketed predicate
|
|
213
|
+
* names.
|
|
214
|
+
*
|
|
215
|
+
* A config left live (see convert's liveConfig) is a style parameter, and one in a filter is what
|
|
216
|
+
* lets a style carry two layer sets and switch between them: the decoder pre-evaluates a parameter
|
|
217
|
+
* comparison with no feature in hand (PredicatePreEvaluator), so the losing set is pruned whole
|
|
218
|
+
* rather than tested per feature. Left to the generic path it became a when(), which prunes nothing.
|
|
219
|
+
*/
|
|
220
|
+
function expressionKey(node) {
|
|
221
|
+
if (!Array.isArray(node))
|
|
222
|
+
return null;
|
|
223
|
+
if (node[0] === 'get' && node.length === 2 && typeof node[1] === 'string')
|
|
224
|
+
return node[1];
|
|
225
|
+
if (node[0] === 'geometry-type' && node.length === 1)
|
|
226
|
+
return 'mapnik::geometry_type';
|
|
227
|
+
if (node[0] === 'id' && node.length === 1)
|
|
228
|
+
return 'mapnik::feature_id';
|
|
229
|
+
if (node[0] === 'config' && node.length >= 2 && typeof node[1] === 'string')
|
|
230
|
+
return `param::${node[1]}`;
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
/** The right-hand side of one of those, as a constant. geometry-type compares against a number. */
|
|
234
|
+
function expressionConstant(key, value) {
|
|
235
|
+
if (key === 'mapnik::geometry_type') {
|
|
236
|
+
return typeof value === 'string' && value in GEOMETRY_TYPE ? String(GEOMETRY_TYPE[value]) : null;
|
|
237
|
+
}
|
|
238
|
+
if (value === null || typeof value === 'boolean' || typeof value === 'number')
|
|
239
|
+
return String(value);
|
|
240
|
+
if (typeof value === 'string')
|
|
241
|
+
return `'${value.replace(/'/g, "\\'")}'`;
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
/** MapBox legacy filter keys, including the two special ones. */
|
|
245
|
+
function fieldRef(key) {
|
|
246
|
+
if (key === '$type')
|
|
247
|
+
return 'mapnik::geometry_type';
|
|
248
|
+
if (key === '$id')
|
|
249
|
+
return 'mapnik::feature_id';
|
|
250
|
+
if (key.startsWith('$'))
|
|
251
|
+
return null;
|
|
252
|
+
return key;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* A field name as a bracketed predicate spells it. The grammar there is `(fieldid | string)`, and
|
|
256
|
+
* a namespaced name is not a fieldid - it has to be quoted, the way the round-trip fixture writes
|
|
257
|
+
* `#hillshade['param::relief' = false]`. Expression context (`[view::zoom]`) is the opposite.
|
|
258
|
+
*/
|
|
259
|
+
function predicateKey(key) {
|
|
260
|
+
return key.includes('::') ? `'${key}'` : key;
|
|
261
|
+
}
|
|
262
|
+
/** A filter's right-hand side, as the constant a bracketed predicate requires. */
|
|
263
|
+
function constant(key, value) {
|
|
264
|
+
if (key === '$type') {
|
|
265
|
+
return typeof value === 'string' && value in GEOMETRY_TYPE ? String(GEOMETRY_TYPE[value]) : null;
|
|
266
|
+
}
|
|
267
|
+
if (value === null || typeof value === 'boolean' || typeof value === 'number')
|
|
268
|
+
return String(value);
|
|
269
|
+
if (typeof value === 'string')
|
|
270
|
+
return `'${value.replace(/'/g, "\\'")}'`;
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* minzoom/maxzoom -> the zoom predicates CartoCSS understands natively. maxzoom is exclusive.
|
|
275
|
+
* Shifted by a level for the same reason the ramps are - see ZOOM_INPUT.
|
|
276
|
+
*/
|
|
277
|
+
export function zoomPredicates(minzoom, maxzoom) {
|
|
278
|
+
const out = [];
|
|
279
|
+
if (typeof minzoom === 'number')
|
|
280
|
+
out.push(`[zoom >= ${Math.floor(minzoom) + zoomOffsetLevels()}]`);
|
|
281
|
+
if (typeof maxzoom === 'number')
|
|
282
|
+
out.push(`[zoom < ${Math.ceil(maxzoom) + zoomOffsetLevels()}]`);
|
|
283
|
+
return out;
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../src/mapbox2css/filter.ts"],"names":[],"mappings":"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"}
|