Support +/- unary operators for literals
This commit is contained in:
@@ -2,11 +2,27 @@ goog.provide('ol.expression');
|
|||||||
|
|
||||||
goog.require('ol.Extent');
|
goog.require('ol.Extent');
|
||||||
goog.require('ol.Feature');
|
goog.require('ol.Feature');
|
||||||
|
goog.require('ol.expression.Expression');
|
||||||
goog.require('ol.expression.Parser');
|
goog.require('ol.expression.Parser');
|
||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.geom.GeometryType');
|
goog.require('ol.geom.GeometryType');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate an expression with a feature. The feature attributes will be used
|
||||||
|
* as the evaluation scope. The `ol.expression.lib` functions will be used as
|
||||||
|
* function scope. The feature itself will be used as the `this` argument.
|
||||||
|
*
|
||||||
|
* @param {ol.expression.Expression} expr The expression.
|
||||||
|
* @param {ol.Feature} feature The feature.
|
||||||
|
* @return {*} The result of the expression.
|
||||||
|
*/
|
||||||
|
ol.expression.evaluateFeature = function(expr, feature) {
|
||||||
|
return expr.evaluate(
|
||||||
|
feature.getAttributes(), ol.expression.lib, feature);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse an expression
|
* Parse an expression
|
||||||
* @param {string} source The expression source (e.g. `'foo + 2'`).
|
* @param {string} source The expression source (e.g. `'foo + 2'`).
|
||||||
|
|||||||
@@ -199,16 +199,33 @@ ol.expression.Parser.prototype.createMemberExpression_ = function(object,
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a unary expression.
|
* Create a unary expression. The only true unary operator supported here is
|
||||||
|
* "!". For +/-, we apply the operator to literal expressions and return
|
||||||
|
* another literal.
|
||||||
*
|
*
|
||||||
* @param {string} op Operator.
|
* @param {ol.expression.Token} op Operator.
|
||||||
* @param {ol.expression.Expression} argument Expression.
|
* @param {ol.expression.Expression} argument Expression.
|
||||||
* @return {ol.expression.Not} The logical not of the input expression.
|
* @return {ol.expression.Expression} The unary expression.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.expression.Parser.prototype.createUnaryExpression_ = function(op, argument) {
|
ol.expression.Parser.prototype.createUnaryExpression_ = function(op, argument) {
|
||||||
goog.asserts.assert(op === '!');
|
goog.asserts.assert(op.value === '!' || op.value === '+' || op.value === '-');
|
||||||
return new ol.expression.Not(argument);
|
var expr;
|
||||||
|
if (op.value === '!') {
|
||||||
|
expr = new ol.expression.Not(argument);
|
||||||
|
} else if (!(argument instanceof ol.expression.Literal)) {
|
||||||
|
throw new ol.expression.UnexpectedToken(op);
|
||||||
|
} else {
|
||||||
|
// we've got +/- literal
|
||||||
|
if (op.value === '+') {
|
||||||
|
expr = this.createLiteral_(
|
||||||
|
+ /** @type {number|string|boolean|null} */ (argument.evaluate()));
|
||||||
|
} else {
|
||||||
|
expr = this.createLiteral_(
|
||||||
|
- /** @type {number|string|boolean|null} */ (argument.evaluate()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -440,10 +457,11 @@ ol.expression.Parser.prototype.parseUnaryExpression_ = function(lexer) {
|
|||||||
var operator = lexer.peek();
|
var operator = lexer.peek();
|
||||||
if (operator.type !== ol.expression.TokenType.PUNCTUATOR) {
|
if (operator.type !== ol.expression.TokenType.PUNCTUATOR) {
|
||||||
expr = this.parseLeftHandSideExpression_(lexer);
|
expr = this.parseLeftHandSideExpression_(lexer);
|
||||||
} else if (operator.value === '!') {
|
} else if (operator.value === '!' || operator.value === '-' ||
|
||||||
|
operator.value === '+') {
|
||||||
lexer.skip();
|
lexer.skip();
|
||||||
expr = this.parseUnaryExpression_(lexer);
|
expr = this.parseUnaryExpression_(lexer);
|
||||||
expr = this.createUnaryExpression_('!', expr);
|
expr = this.createUnaryExpression_(operator, expr);
|
||||||
} else {
|
} else {
|
||||||
expr = this.parseLeftHandSideExpression_(lexer);
|
expr = this.parseLeftHandSideExpression_(lexer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -524,12 +524,8 @@ describe('ol.expression.parse', function() {
|
|||||||
|
|
||||||
describe('ol.expression.lib', function() {
|
describe('ol.expression.lib', function() {
|
||||||
|
|
||||||
var lib = ol.expression.lib;
|
|
||||||
var parse = ol.expression.parse;
|
var parse = ol.expression.parse;
|
||||||
|
var evaluate = ol.expression.evaluateFeature;
|
||||||
function evaluate(expression, feature) {
|
|
||||||
return expression.evaluate(feature.getAttributes(), lib, feature);
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('extent()', function() {
|
describe('extent()', function() {
|
||||||
|
|
||||||
@@ -550,21 +546,73 @@ describe('ol.expression.lib', function() {
|
|||||||
var east = parse('extent(80, 100, -50, 50)');
|
var east = parse('extent(80, 100, -50, 50)');
|
||||||
var west = parse('extent(-100, -80, -50, 50)');
|
var west = parse('extent(-100, -80, -50, 50)');
|
||||||
|
|
||||||
expect(evaluate(north, nw), true);
|
it('evaluates to true for features within given extent', function() {
|
||||||
expect(evaluate(south, nw), false);
|
|
||||||
expect(evaluate(east, nw), false);
|
|
||||||
expect(evaluate(west, nw), true);
|
|
||||||
|
|
||||||
expect(evaluate(north, se), false);
|
expect(evaluate(north, nw), true);
|
||||||
expect(evaluate(south, se), true);
|
expect(evaluate(south, nw), false);
|
||||||
expect(evaluate(east, se), true);
|
expect(evaluate(east, nw), false);
|
||||||
expect(evaluate(west, se), false);
|
expect(evaluate(west, nw), true);
|
||||||
|
|
||||||
|
expect(evaluate(north, se), false);
|
||||||
|
expect(evaluate(south, se), true);
|
||||||
|
expect(evaluate(east, se), true);
|
||||||
|
expect(evaluate(west, se), false);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('geometryType()', function() {
|
||||||
|
|
||||||
|
var point = new ol.Feature({
|
||||||
|
geom: new ol.geom.Point([0, 0])
|
||||||
|
});
|
||||||
|
|
||||||
|
var line = new ol.Feature({
|
||||||
|
geom: new ol.geom.LineString([[180, -90], [-180, 90]])
|
||||||
|
});
|
||||||
|
|
||||||
|
var poly = new ol.Feature({
|
||||||
|
geom: new ol.geom.Polygon([[
|
||||||
|
[180, -90], [0, -90], [0, 0], [180, 0], [180, -90]
|
||||||
|
]])
|
||||||
|
});
|
||||||
|
|
||||||
|
var isPoint = parse('geometryType("point")');
|
||||||
|
var isLine = parse('geometryType("linestring")');
|
||||||
|
var isPoly = parse('geometryType("polygon")');
|
||||||
|
var pointOrPoly = parse('geometryType("point") || geometryType("polygon")');
|
||||||
|
|
||||||
|
it('distinguishes point features', function() {
|
||||||
|
expect(evaluate(isPoint, point), true);
|
||||||
|
expect(evaluate(isPoint, line), false);
|
||||||
|
expect(evaluate(isPoint, poly), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('distinguishes line features', function() {
|
||||||
|
expect(evaluate(isLine, point), false);
|
||||||
|
expect(evaluate(isLine, line), true);
|
||||||
|
expect(evaluate(isLine, poly), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('distinguishes polygon features', function() {
|
||||||
|
expect(evaluate(isPoly, point), false);
|
||||||
|
expect(evaluate(isPoly, line), false);
|
||||||
|
expect(evaluate(isPoly, poly), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can be composed in a logical expression', function() {
|
||||||
|
expect(evaluate(pointOrPoly, point), true);
|
||||||
|
expect(evaluate(pointOrPoly, line), false);
|
||||||
|
expect(evaluate(pointOrPoly, poly), true);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
goog.require('ol.Feature');
|
||||||
goog.require('ol.expression');
|
goog.require('ol.expression');
|
||||||
goog.require('ol.expression.Call');
|
goog.require('ol.expression.Call');
|
||||||
goog.require('ol.expression.Comparison');
|
goog.require('ol.expression.Comparison');
|
||||||
@@ -577,3 +625,6 @@ goog.require('ol.expression.Member');
|
|||||||
goog.require('ol.expression.Not');
|
goog.require('ol.expression.Not');
|
||||||
goog.require('ol.expression.TokenType');
|
goog.require('ol.expression.TokenType');
|
||||||
goog.require('ol.expression.UnexpectedToken');
|
goog.require('ol.expression.UnexpectedToken');
|
||||||
|
goog.require('ol.geom.LineString');
|
||||||
|
goog.require('ol.geom.Point');
|
||||||
|
goog.require('ol.geom.Polygon');
|
||||||
|
|||||||
Reference in New Issue
Block a user