diff options
author | Anand Thakker <anandthakker@users.noreply.github.com> | 2018-04-11 12:03:56 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-11 12:03:56 -0400 |
commit | f0f67b4788f967ee34f307312db302cecb68dd0b (patch) | |
tree | 90f207635e1c6a67aed11655e9e03b058c556665 /platform/darwin | |
parent | 797486bc5f4d064821865c72425911994fa9fe22 (diff) | |
download | qtlocation-mapboxgl-f0f67b4788f967ee34f307312db302cecb68dd0b.tar.gz |
Add abs, round, floor, ceil operators (#11653)
* Add abs, round, floor, ceil operators
Port of https://github.com/mapbox/mapbox-gl-js/pull/6496
* [ios, macos] Simplified abs, ceiling, floor expressions
* [ios, macos] Added rounding expression function
* [android] - binding integration for round, ceil, floor and abs expressions
* Update mapbox-gl-js to include non-integer rounding test
* Drop extra braces
* mapbox-gl-js -> master
* Update style-spec docs -> PropertyFactory.java
Diffstat (limited to 'platform/darwin')
4 files changed, 56 insertions, 27 deletions
diff --git a/platform/darwin/docs/guides/For Style Authors.md.ejs b/platform/darwin/docs/guides/For Style Authors.md.ejs index d61b292148..857d03d6e7 100644 --- a/platform/darwin/docs/guides/For Style Authors.md.ejs +++ b/platform/darwin/docs/guides/For Style Authors.md.ejs @@ -379,11 +379,14 @@ In style specification | Method, function, or predicate type | Format string syn `%` | `modulus:by:` | `^` | `raise:toPower:` | `2 ** 2` `+` | `add:to:` | `1 + 2` +`abs` | `abs:` | `abs(-1)` `acos` | | `asin` | | `atan` | | +`ceil` | `ceiling:` | `ceiling(0.99999)` `cos` | | `e` | | `%@` representing `NSNumber` containing `M_E` +`floor` | `floor:` | `floor(-0.99999)` `ln` | `ln:` | `ln(2)` `ln2` | | `%@` representing `NSNumber` containing `M_LN2` `log10` | `log:` | `log(1)` @@ -391,6 +394,7 @@ In style specification | Method, function, or predicate type | Format string syn `max` | `max:` | `max({1, 2, 2, 3, 4, 7, 9})` `min` | `min:` | `min({1, 2, 2, 3, 4, 7, 9})` `pi` | | `%@` representing `NSNumber` containing `M_PI` +`round` | `mgl_round:` | `mgl_round(1.5)` `sin` | | `sqrt` | `sqrt:` | `sqrt(2)` `tan` | | diff --git a/platform/darwin/docs/guides/Predicates and Expressions.md b/platform/darwin/docs/guides/Predicates and Expressions.md index 13204b09a6..1b8714811d 100644 --- a/platform/darwin/docs/guides/Predicates and Expressions.md +++ b/platform/darwin/docs/guides/Predicates and Expressions.md @@ -196,6 +196,7 @@ Initializer parameter | Format string syntax | Description `mgl_interpolate:withCurveType:parameters:stops:` | `mgl_interpolate:withCurveType:parameters:stops:(x, 'linear', nil, %@)` | Produces continuous, smooth results by interpolating between pairs of input and output values (“stops”). Compared to the `mgl_interpolateWithCurveType:parameters:stops:` custom function, the input expression (that function’s target) is instead passed in as the first argument to this function. `mgl_step:from:stops:` | `mgl_step:from:stops:(x, 11, %@)` | Produces discrete, stepped results by evaluating a piecewise-constant function defined by pairs of input and output values ("stops"). Compared to the `mgl_stepWithMinimum:stops:` custom function, the input expression (that function’s target) is instead passed in as the first argument to this function. `mgl_join:` | `mgl_join({'Old', 'MacDonald'})` | Returns the result of concatenating together all the elements of an array in order. Compared to the `stringByAppendingString:` custom function, this function takes only one argument, which is an aggregate expression containing the strings to concatenate. +`mgl_round:` | `mgl_round(1.5)` | Returns the number rounded to the nearest integer. If the number is halfway between two integers, this function rounds it away from zero. `mgl_coalesce:` | `mgl_coalesce({x, y, z})` | Returns the first non-`nil` value from an array of expressions. `MGL_LET` | `MGL_LET('age', uppercase('old'), 'name', uppercase('MacDonald'), mgl_join({$age, $name}))` | Any number of variable names interspersed with their assigned `NSExpression` values, followed by an `NSExpression` that may contain references to those variables. Compared to the `mgl_expressionWithContext:` custom function, this function takes the variable names and values inline before the expression that contains references to those variables. `MGL_MATCH` | `MGL_MATCH(x, 0, 'zero match', 1, 'one match', 'two match', 'default')` | Evaluates the first expression and returns the value that matches the initial condition. After the first expression condition a pair of matching/return value should be added and a default value. diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm index 8c82c84c7d..6a61dd9abb 100644 --- a/platform/darwin/src/NSExpression+MGLAdditions.mm +++ b/platform/darwin/src/NSExpression+MGLAdditions.mm @@ -58,6 +58,7 @@ // Install method-like functions, taking the number of arguments implied by // the selector name. INSTALL_METHOD(mgl_join:); + INSTALL_METHOD(mgl_round:); INSTALL_METHOD(mgl_interpolate:withCurveType:parameters:stops:); INSTALL_METHOD(mgl_step:from:stops:); INSTALL_METHOD(mgl_coalesce:); @@ -84,6 +85,14 @@ } /** + Rounds the given number to the nearest integer. If the number is halfway + between two integers, this method rounds it away from zero. + */ +- (NSNumber *)mgl_round:(NSNumber *)number { + return @(round(number.doubleValue)); +} + +/** A placeholder for a method that evaluates an interpolation expression. */ - (id)mgl_interpolate:(id)inputExpression withCurveType:(NSString *)curveType parameters:(NSDictionary *)params stops:(NSDictionary *)stops { @@ -487,6 +496,10 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { @"sqrt": @"sqrt:", @"log10": @"log:", @"ln": @"ln:", + @"abs": @"abs:", + @"round": @"mgl_round:", + @"floor": @"floor:", + @"ceil": @"ceiling:", @"^": @"raise:toPower:", @"upcase": @"uppercase:", @"downcase": @"lowercase:", @@ -720,9 +733,13 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { @"log:": @"log10", @"ln:": @"ln", @"raise:toPower:": @"^", + @"ceiling:": @"ceil", + @"abs:": @"abs", + @"floor:": @"floor", @"uppercase:": @"upcase", @"lowercase:": @"downcase", @"length:": @"length", + @"mgl_round:": @"round", // Vararg aftermarket expressions need to be declared with an explicit and implicit first argument. @"MGL_LET": @"let", @"MGL_LET:": @"let", @@ -826,18 +843,9 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { return [@[@"max"] arrayByAddingObjectsFromArray:arguments]; } else if ([function isEqualToString:@"exp:"]) { return [NSExpression expressionForFunction:@"raise:toPower:" arguments:@[@(M_E), self.arguments.firstObject]].mgl_jsonExpressionObject; - } else if ([function isEqualToString:@"ceiling:"]) { - return [NSExpression expressionWithFormat:@"trunc:(%@) + TERNARY(modulus:by:(%@, 1) > 0, 1, 0)", - self.arguments.firstObject, self.arguments.firstObject].mgl_jsonExpressionObject; } else if ([function isEqualToString:@"trunc:"]) { return [NSExpression expressionWithFormat:@"%@ - modulus:by:(%@, 1)", self.arguments.firstObject, self.arguments.firstObject].mgl_jsonExpressionObject; - } else if ([function isEqualToString:@"abs:"]) { - return [NSExpression expressionWithFormat:@"%@ * TERNARY(%@ > 0, 1, -1)", - self.arguments.firstObject, self.arguments.firstObject].mgl_jsonExpressionObject; - } else if ([function isEqualToString:@"floor:"]) { - return [NSExpression expressionWithFormat:@"trunc:(%@) - TERNARY(modulus:by:(%@, 1) < 0, 1, 0)", - self.arguments.firstObject, self.arguments.firstObject].mgl_jsonExpressionObject; } else if ([function isEqualToString:@"mgl_join:"]) { NSArray *arguments = [self.arguments.firstObject.collection valueForKeyPath:@"mgl_jsonExpressionObject"]; return [@[@"concat"] arrayByAddingObjectsFromArray:arguments]; diff --git a/platform/darwin/test/MGLExpressionTests.mm b/platform/darwin/test/MGLExpressionTests.mm index 579d2505f2..236c8d1ad9 100644 --- a/platform/darwin/test/MGLExpressionTests.mm +++ b/platform/darwin/test/MGLExpressionTests.mm @@ -393,29 +393,25 @@ using namespace std::string_literals; } { NSExpression *expression = [NSExpression expressionForFunction:@"ceiling:" arguments:@[MGLConstantExpression(@1.5)]]; - NSArray *jsonTruncation = @[@"-", @1.5, @[@"%", @1.5, @1]]; - NSArray *jsonExpression = @[@"+", jsonTruncation, @[@"case", @[@">", @[@"%", @1.5, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"ceil", @1.5]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @2); } { NSExpression *expression = [NSExpression expressionForFunction:@"ceiling:" arguments:@[MGLConstantExpression(@-1.5)]]; - NSArray *jsonTruncation = @[@"-", @-1.5, @[@"%", @-1.5, @1]]; - NSArray *jsonExpression = @[@"+", jsonTruncation, @[@"case", @[@">", @[@"%", @-1.5, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"ceil", @-1.5]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @-1); } { NSExpression *expression = [NSExpression expressionForFunction:@"ceiling:" arguments:@[MGLConstantExpression(@2)]]; - NSArray *jsonTruncation = @[@"-", @2, @[@"%", @2, @1]]; - NSArray *jsonExpression = @[@"+", jsonTruncation, @[@"case", @[@">", @[@"%", @2, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"ceil", @2]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @2); } { NSExpression *expression = [NSExpression expressionForFunction:@"ceiling:" arguments:@[MGLConstantExpression(@-2)]]; - NSArray *jsonTruncation = @[@"-", @-2, @[@"%", @-2, @1]]; - NSArray *jsonExpression = @[@"+", jsonTruncation, @[@"case", @[@">", @[@"%", @-2, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"ceil", @-2]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @-2); } @@ -433,44 +429,64 @@ using namespace std::string_literals; } { NSExpression *expression = [NSExpression expressionForFunction:@"abs:" arguments:@[MGLConstantExpression(@2)]]; - NSArray *jsonExpression = @[@"*", @2, @[@"case", @[@">", @2, @0], @1, @-1]]; + NSArray *jsonExpression = @[@"abs", @2]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @2); } { NSExpression *expression = [NSExpression expressionForFunction:@"abs:" arguments:@[MGLConstantExpression(@-2)]]; - NSArray *jsonExpression = @[@"*", @-2, @[@"case", @[@">", @-2, @0], @1, @-1]]; + NSArray *jsonExpression = @[@"abs", @-2]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @2); } { NSExpression *expression = [NSExpression expressionForFunction:@"floor:" arguments:@[MGLConstantExpression(@1.5)]]; - NSArray *jsonTruncation = @[@"-", @1.5, @[@"%", @1.5, @1]]; - NSArray *jsonExpression = @[@"-", jsonTruncation, @[@"case", @[@"<", @[@"%", @1.5, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"floor", @1.5]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @1); } { NSExpression *expression = [NSExpression expressionForFunction:@"floor:" arguments:@[MGLConstantExpression(@-1.5)]]; - NSArray *jsonTruncation = @[@"-", @-1.5, @[@"%", @-1.5, @1]]; - NSArray *jsonExpression = @[@"-", jsonTruncation, @[@"case", @[@"<", @[@"%", @-1.5, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"floor", @-1.5]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @-2); } { NSExpression *expression = [NSExpression expressionForFunction:@"floor:" arguments:@[MGLConstantExpression(@2)]]; - NSArray *jsonTruncation = @[@"-", @2, @[@"%", @2, @1]]; - NSArray *jsonExpression = @[@"-", jsonTruncation, @[@"case", @[@"<", @[@"%", @2, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"floor", @2]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @2); } { NSExpression *expression = [NSExpression expressionForFunction:@"floor:" arguments:@[MGLConstantExpression(@-2)]]; - NSArray *jsonTruncation = @[@"-", @-2, @[@"%", @-2, @1]]; - NSArray *jsonExpression = @[@"-", jsonTruncation, @[@"case", @[@"<", @[@"%", @-2, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"floor", @-2]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @-2); } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_round:" arguments:@[MGLConstantExpression(@1.5)]]; + NSArray *jsonExpression = @[@"round", @1.5]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @2); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_round:" arguments:@[MGLConstantExpression(@-1.5)]]; + NSArray *jsonExpression = @[@"round", @-1.5]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @-2); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_round:" arguments:@[MGLConstantExpression(@2.5)]]; + NSArray *jsonExpression = @[@"round", @2.5]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @3); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_round:" arguments:@[MGLConstantExpression(@-2.5)]]; + NSArray *jsonExpression = @[@"round", @-2.5]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @-3); + } } - (void)testTrigonometricExpressionObject { |