Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace no-op style filter expressions #62

Merged
merged 10 commits into from
Jul 29, 2024
Merged
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## v0.3.3
- Replace no-op style filter expressions with `true` [#62](https://github.com/mapbox/vtshaver/pull/62).

## v0.3.2
- Add missing symbol implementations for `downcase`, `upcase`, and `number-formatter` expressions. The implementation for `number-formatter` is a basic `to_string` and uses no config options. [#58](https://github.com/mapbox/vtshaver/pull/58)

Expand Down
40 changes: 35 additions & 5 deletions lib/styleToFilters.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,23 @@ function styleToFilters(style) {
if (layers[layerName].filters === true || !style.layers[i].filter) {
layers[layerName].filters = true;
} else {
layers[layerName].filters.push(style.layers[i].filter);
let filter = replaceNoOpExpressions(style.layers[i].filter);
layers[layerName].filters.push(filter === 'noop' ? ['literal', true] : filter);
}
} else {
// otherwise create the layer & filter array, with min/max zoom
layers[layerName] = {};
layers[layerName].filters = style.layers[i].filter ? ['any', style.layers[i].filter] : true;
if (style.layers[i].filter) {
let filter = replaceNoOpExpressions(style.layers[i].filter);
layers[layerName].filters = ['any', filter === 'noop' ? ['literal', true] : filter]
} else {
layers[layerName].filters = true;
}
layers[layerName].minzoom = style.layers[i].minzoom || 0;
layers[layerName].maxzoom = style.layers[i].maxzoom || 22;
}

// Collect the used properties
// Collect the used properties
// 1. from paint, layout, and filter
layers[layerName].properties = layers[layerName].properties || [];
['paint', 'layout'].forEach(item => {
Expand Down Expand Up @@ -105,7 +111,6 @@ function getPropertyFromFilter(filter, properties) {
if (filter[1].indexOf('$') === -1) {
properties.push(filter[1]);
}

}
}
// }
Expand Down Expand Up @@ -143,6 +148,31 @@ function getPropertyFromLayoutAndPainter(propertyObj, properties) {
}


function replaceNoOpExpressions(exp) {
if (exp instanceof Array) {
switch (exp[0]) {
case 'pitch':
case 'distance-from-center':
return 'noop';
}

let newExp = exp.map(sub => sub instanceof Array ? replaceNoOpExpressions(sub) : sub);

if (newExp.includes('noop')) {
switch (newExp[0]) {
case 'any':
case 'all':
return newExp.map(sub => sub === 'noop' ? ['literal', true] : sub);
default:
return 'noop';
}
}
else return newExp;
}
else return exp;
}


function getPropertyFromExpression(exp, properties) {
// now we care about the expression like:
// ["get", string] not ["get", string, Object],
Expand Down Expand Up @@ -173,4 +203,4 @@ function getPropertyFromExpression(exp, properties) {
}
}

module.exports = styleToFilters;
module.exports = styleToFilters;
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mapbox/vtshaver",
"version": "0.3.2",
"version": "0.3.3",
"description": "Creates style-optimized vector tiles",
"main": "./lib/index.js",
"repository": {
Expand Down
16 changes: 14 additions & 2 deletions test/fixtures/styles/cafe.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"version": 1,
"name": "cafe",
"center": [
"center": [
-122.51238479904751,
37.77981694417855
],
Expand All @@ -15,7 +15,19 @@
"source": "composite",
"id": "poi-scalerank1",
"source-layer": "poi_label"
},
{
"filter": [
"all",
["==","maki","cafe"],
["<=", ["pitch"], 45],
["<=", ["distance-from-center"], 1]
],
"type": "symbol",
"source": "composite",
"id": "poi-landmarks",
"source-layer": "poi_label"
}
],
"owner": "greta"
}
}
61 changes: 57 additions & 4 deletions test/styleToFilter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,67 @@ test('simple style layers', function(t) {
t.deepEqual(styleToFilter({
layers: [{
'source-layer': 'water',
filter: ['!=', 'color', 'blue']
filter: [
'all',
[
'case',
['>=', ['distance-from-center'], 5], // test no-op in case condition
false,
['>=', ['pitch'], 45],
false,
true
],
[
'match',
['get', 'distance'],
[1, 4, ['distance-from-center']], // test no-op in match value
false,
true
],
[
'coalesce',
['get', 'display'],
['>=', ['distance-from-center'], 3] // test no-op in coalesce
],
[
'any',
['boolean', false],
['>=', ['pitch'], 5] // test no-op in any
],
[
'all',
['boolean', true],
['<', ['pitch'], 5] // test no-op in all
],
['==', 'color', 'blue']
]
},
{
'source-layer': 'landcover',
filter: ['==', 'color', 'blue']
filter: [
'>=',
['distance-from-center'],
[
'case',
['==', 'color', 'blue'],
2,
4
]
]
},
{
'source-layer': 'landuse_overlay',
filter: [
'case',
['<=', ['pitch'], 10],
['==', ['distance-from-center'], 4], // test no-op in value
['to-boolean', ['get', 'display']],
true,
false
]
}
]
}), { water: { filters: ['any', ['!=', 'color', 'blue']], minzoom: 0, maxzoom: 22, properties: ['color'] }, landcover: { filters: ['any', ['==', 'color', 'blue']], minzoom: 0, maxzoom: 22, properties: ['color'] } }, 'returns right filters for multiple layers with filters');
}), { water: { filters: ['any', ['all', ['literal', true], ['literal', true], ['literal', true], ['any', ['boolean', false], ['literal', true]], ['all', ['boolean', true], ['literal', true]], ['==', 'color', 'blue']]], minzoom: 0, maxzoom: 22, properties: ['distance', 'display', 'color'] }, landcover: { filters: ['any', ['literal', true]], minzoom: 0, maxzoom: 22, properties: ['color'] }, landuse_overlay: { filters: ['any', ['literal', true]], minzoom: 0, maxzoom: 22, properties: ['display'] } }, 'returns right filters for no-op expressions');

t.end();
});
Expand Down Expand Up @@ -173,4 +226,4 @@ test('v8 streets style with legacy+expressions filter combo', function(t) {
t.deepEquals(filters, require(filter_result_expressions), 'expressions filter is extracted correctly');

t.end();
});
});