diff --git a/src/ol/style/expressions.js b/src/ol/style/expressions.js index 02fc25f402..7b14e4c079 100644 --- a/src/ol/style/expressions.js +++ b/src/ol/style/expressions.js @@ -53,6 +53,8 @@ import {asArray, isStringColor} from '../color.js'; * * `['==', value1, value2]` returns `true` if `value1` equals `value2`, or `false` otherwise. * * `['!=', value1, value2]` returns `true` if `value1` does not equal `value2`, or `false` otherwise. * * `['!', value1]` returns `false` if `value1` is `true` or greater than `0`, or `true` otherwise. + * * `['all', value1, value2, ...]` returns `true` if all the inputs are `true`, `false` otherwise. + * * `['any', value1, value2, ...]` returns `true` if any of the inputs are `true`, `false` otherwise. * * `['between', value1, value2, value3]` returns `true` if `value1` is contained between `value2` and `value3` * (inclusively), or `false` otherwise. * @@ -494,7 +496,6 @@ Operators['^'] = { )})`; }, }; - Operators['>'] = { getReturnType: function (args) { return ValueTypes.BOOLEAN; @@ -590,6 +591,29 @@ Operators['!'] = { return `(!${expressionToGlsl(context, args[0])})`; }, }; + +function getDecisionOperator(operator) { + return { + getReturnType: function (args) { + return ValueTypes.BOOLEAN; + }, + toGlsl: function (context, args) { + assertArgsMinCount(args, 2); + for (let i = 0; i < args.length; i++) { + assertBoolean(args[i]); + } + let result = ''; + result = args + .map((arg) => expressionToGlsl(context, arg)) + .join(` ${operator} `); + result = `(${result})`; + return result; + }, + }; +} + +Operators['all'] = getDecisionOperator('&&'); +Operators['any'] = getDecisionOperator('||'); Operators['between'] = { getReturnType: function (args) { return ValueTypes.BOOLEAN; diff --git a/test/spec/ol/style/expressions.test.js b/test/spec/ol/style/expressions.test.js index b5f5622a00..e011d34eca 100644 --- a/test/spec/ol/style/expressions.test.js +++ b/test/spec/ol/style/expressions.test.js @@ -179,6 +179,12 @@ describe('ol.style.expressions', function () { expect(getValueType(['!=', 10, ['get', 'attr4']])).to.eql( ValueTypes.BOOLEAN ); + expect(getValueType(['all', true, ['get', 'attr4']])).to.eql( + ValueTypes.BOOLEAN + ); + expect(getValueType(['any', true, ['get', 'attr4']])).to.eql( + ValueTypes.BOOLEAN + ); expect(getValueType(['between', ['get', 'attr4'], -4.0, 5.0])).to.eql( ValueTypes.BOOLEAN ); @@ -244,6 +250,15 @@ describe('ol.style.expressions', function () { expect(expressionToGlsl(context, ['!=', 10, ['get', 'attr4']])).to.eql( '(10.0 != a_attr4)' ); + expect(expressionToGlsl(context, ['all', true, ['get', 'attr4']])).to.eql( + '(true && a_attr4)' + ); + expect(expressionToGlsl(context, ['any', true, ['get', 'attr4']])).to.eql( + '(true || a_attr4)' + ); + expect( + expressionToGlsl(context, ['any', true, ['get', 'attr4'], true]) + ).to.eql('(true || a_attr4 || true)'); expect( expressionToGlsl(context, ['between', ['get', 'attr4'], -4.0, 5.0]) ).to.eql('(a_attr4 >= -4.0 && a_attr4 <= 5.0)'); @@ -294,6 +309,22 @@ describe('ol.style.expressions', function () { } expect(thrown).to.be(true); + thrown = false; + try { + expressionToGlsl(context, ['any', ['var', 'aa'], 10]); + } catch (e) { + thrown = true; + } + expect(thrown).to.be(true); + + thrown = false; + try { + expressionToGlsl(context, ['all', ['var', 'aa'], 10]); + } catch (e) { + thrown = true; + } + expect(thrown).to.be(true); + thrown = false; try { expressionToGlsl(context, ['<', 0, 'aa']); @@ -336,6 +367,22 @@ describe('ol.style.expressions', function () { } expect(thrown).to.be(true); + thrown = false; + try { + expressionToGlsl(context, ['all', ['var', true], ['get', true], true]); + } catch (e) { + thrown = true; + } + expect(thrown).to.be(true); + + thrown = false; + try { + expressionToGlsl(context, ['any', ['var', true]]); + } catch (e) { + thrown = true; + } + expect(thrown).to.be(true); + thrown = false; try { expressionToGlsl(context, ['<', 4]);