Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
Add abs, round, floor, ceil operators (#11653)
Browse files Browse the repository at this point in the history
* Add abs, round, floor, ceil operators

Port of mapbox/mapbox-gl-js#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
  • Loading branch information
anandthakker authored Apr 11, 2018
1 parent 797486b commit f0f67b4
Show file tree
Hide file tree
Showing 11 changed files with 317 additions and 33 deletions.
2 changes: 1 addition & 1 deletion mapbox-gl-js
Submodule mapbox-gl-js updated 36 files
+6 −0 CHANGELOG.md
+1 −0 docs/components/example.js
+7 −0 docs/components/expression-metadata.js
+1 −1 docs/pages/example/animate-point-along-route.html
+0 −1 docs/pages/example/check-for-support.html
+2 −2 docs/pages/example/filter-features-within-map-view.html
+1 −1 docs/pages/example/mapbox-gl-geocoder-limit-region.js
+7 −4 docs/pages/example/mapbox-gl-geocoder-local-geocoder.html
+1 −1 docs/pages/example/mapbox-gl-geocoder-local-geocoder.js
+1 −1 docs/pages/example/mapbox-gl-geocoder-outside-the-map.js
+1 −1 docs/pages/example/mapbox-gl-geocoder-proximity-bias.js
+1 −0 docs/pages/example/mapbox-gl-geocoder.js
+1 −1 docs/pages/example/mapbox-gl-rtl-text.html
+12 −2 docs/pages/example/popup-on-click.html
+12 −2 docs/pages/example/popup-on-hover.html
+28 −31 docs/pages/example/third-party.html
+1 −1 docs/pages/example/third-party.js
+16 −14 docs/pages/style-spec.js
+2 −2 package.json
+1 −1 src/index.js
+26 −0 src/style-spec/expression/definitions/index.js
+42 −6 src/style-spec/reference/v8.json
+18 −5 src/ui/control/geolocate_control.js
+33 −4 src/ui/map.js
+15 −1 src/ui/marker.js
+18 −0 test/integration/expression-tests/abs/basic/test.json
+23 −0 test/integration/expression-tests/ceil/basic/test.json
+23 −0 test/integration/expression-tests/floor/basic/test.json
+23 −0 test/integration/expression-tests/round/basic/test.json
+7 −2 test/integration/lib/expression.js
+25 −0 test/unit/ui/control/geolocate.test.js
+77 −0 test/unit/ui/marker.test.js
+1 −1 vendor/dotcom-page-shell/page-shell-script.js
+22 −2 vendor/dotcom-page-shell/page-shell-styles.css
+482 −424 vendor/dotcom-page-shell/react-page-shell.js
+1 −1 yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@
* )
* }
* </pre>
*
*/
public class Expression {

Expand Down Expand Up @@ -1061,6 +1060,7 @@ public static Expression coalesce(@NonNull Expression... input) {
* );
* }
* </pre>
*
* @return expression
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-properties">Style specification</a>
*/
Expand All @@ -1081,6 +1081,7 @@ public static Expression properties() {
* );
* }
* </pre>
*
* @return expression
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-geometry-types">Style specification</a>
*/
Expand Down Expand Up @@ -2294,6 +2295,185 @@ public static Expression max(@Size(min = 1) Number... numbers) {
return max(numberExpression);
}

/**
* Rounds the input to the nearest integer.
* Halfway values are rounded away from zero.
* For example `[\"round\", -1.5]` evaluates to -2.
* <p>
* Example usage:
* </p>
* <pre>
* {@code
* CircleLayer circleLayer = new CircleLayer("layer-id", "source-id");
* circleLayer.setProperties(
* circleRadius(round(pi()))
* );
* }
* </pre>
*
* @param expression number expression to round
* @return expression
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-round">Style specification</a>
*/
public static Expression round(Expression expression) {
return new Expression("round", expression);
}

/**
* Rounds the input to the nearest integer.
* Halfway values are rounded away from zero.
* For example `[\"round\", -1.5]` evaluates to -2.
* <p>
* Example usage:
* </p>
* <pre>
* {@code
* CircleLayer circleLayer = new CircleLayer("layer-id", "source-id");
* circleLayer.setProperties(
* circleRadius(round(3.14159265359f))
* );
* }
* </pre>
*
* @param number number to round
* @return expression
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-round">Style specification</a>
*/
public static Expression round(Number number) {
return round(literal(number));
}

/**
* Returns the absolute value of the input.
* <p>
* Example usage:
* </p>
* <pre>
* {@code
* CircleLayer circleLayer = new CircleLayer("layer-id", "source-id");
* circleLayer.setProperties(
* circleRadius(abs(subtract(pi())))
* );
* }
* </pre>
*
* @param expression number expression to get absolute value from
* @return expression
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-abs">Style specification</a>
*/
public static Expression abs(Expression expression) {
return new Expression("abs", expression);
}

/**
* Returns the absolute value of the input.
* <p>
* Example usage:
* </p>
* <pre>
* {@code
* CircleLayer circleLayer = new CircleLayer("layer-id", "source-id");
* circleLayer.setProperties(
* circleRadius(abs(-3.14159265359f))
* );
* }
* </pre>
*
* @param number number to get absolute value from
* @return expression
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-abs">Style specification</a>
*/
public static Expression abs(Number number) {
return abs(literal(number));
}

/**
* Returns the smallest integer that is greater than or equal to the input.
* <p>
* Example usage:
* </p>
* <pre>
* {@code
* CircleLayer circleLayer = new CircleLayer("layer-id", "source-id");
* circleLayer.setProperties(
* circleRadius(ceil(pi()))
* );
* }
* </pre>
*
* @param expression number expression to get value from
* @return expression
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-abs">Style specification</a>
*/
public static Expression ceil(Expression expression) {
return new Expression("ceil", expression);
}

/**
* Returns the smallest integer that is greater than or equal to the input.
* <p>
* Example usage:
* </p>
* <pre>
* {@code
* CircleLayer circleLayer = new CircleLayer("layer-id", "source-id");
* circleLayer.setProperties(
* circleRadius(ceil(3.14159265359))
* );
* }
* </pre>
* @param number number to get value from
* @return expression
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-abs">Style specification</a>
*/
public static Expression ceil(Number number) {
return ceil(literal(number));
}

/**
* Returns the largest integer that is less than or equal to the input.
* <p>
* Example usage:
* </p>
* <pre>
* {@code
* CircleLayer circleLayer = new CircleLayer("layer-id", "source-id");
* circleLayer.setProperties(
* circleRadius(floor(pi()))
* );
* }
* </pre>
*
* @param expression number expression to get value from
* @return expression
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-abs">Style specification</a>
*/
public static Expression floor(Expression expression) {
return new Expression("floor", expression);
}

/**
* Returns the largest integer that is less than or equal to the input.
* <p>
* Example usage:
* </p>
* <pre>
* {@code
* CircleLayer circleLayer = new CircleLayer("layer-id", "source-id");
* circleLayer.setProperties(
* circleRadius(floor(pi()))
* );
* }
* </pre>
*
* @param number number to get value from
* @return expression
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-abs">Style specification</a>
*/
public static Expression floor(Number number) {
return floor(literal(number));
}

/**
* Returns the input string converted to uppercase.
* <p>
Expand Down Expand Up @@ -3128,6 +3308,7 @@ public static Interpolator exponential(@NonNull Number base) {
* );
* }
* </pre>
*
* @param expression base number expression
* @return expression
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-interpolate">Style specification</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1856,7 +1856,7 @@ public static PropertyValue<Expression> iconTextFitPadding(Expression value) {
}

/**
* Name of image in sprite to use for drawing an image background. Within literal values and zoom functions, property names enclosed in curly brackets (e.g. `{token}`) are replaced with the value of the named property. Expressions and property functions do not support this syntax; for equivalent functionality in expressions, use the [`concat`](#expressions-concat) and [`get`](#expressions-get) operators.
* Name of image in sprite to use for drawing an image background.
*
* @param value a String value
* @return property wrapper around String
Expand All @@ -1866,7 +1866,7 @@ public static PropertyValue<String> iconImage(String value) {
}

/**
* Name of image in sprite to use for drawing an image background. Within literal values and zoom functions, property names enclosed in curly brackets (e.g. `{token}`) are replaced with the value of the named property. Expressions and property functions do not support this syntax; for equivalent functionality in expressions, use the [`concat`](#expressions-concat) and [`get`](#expressions-get) operators.
* Name of image in sprite to use for drawing an image background.
*
* @param value a String value
* @return property wrapper around String
Expand Down Expand Up @@ -2036,7 +2036,7 @@ public static PropertyValue<Expression> textRotationAlignment(Expression value)
}

/**
* Value to use for a text label. Within literal values and zoom functions, property names enclosed in curly brackets (e.g. `{token}`) are replaced with the value of the named property. Expressions and property functions do not support this syntax; for equivalent functionality in expressions, use the [`concat`](#expressions-concat) and [`get`](#expressions-get) operators.
* Value to use for a text label.
*
* @param value a String value
* @return property wrapper around String
Expand All @@ -2046,7 +2046,7 @@ public static PropertyValue<String> textField(String value) {
}

/**
* Value to use for a text label. Within literal values and zoom functions, property names enclosed in curly brackets (e.g. `{token}`) are replaced with the value of the named property. Expressions and property functions do not support this syntax; for equivalent functionality in expressions, use the [`concat`](#expressions-concat) and [`get`](#expressions-get) operators.
* Value to use for a text label.
*
* @param value a String value
* @return property wrapper around String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.util.Arrays;

import static com.mapbox.mapboxsdk.style.expressions.Expression.abs;
import static com.mapbox.mapboxsdk.style.expressions.Expression.acos;
import static com.mapbox.mapboxsdk.style.expressions.Expression.all;
import static com.mapbox.mapboxsdk.style.expressions.Expression.any;
Expand All @@ -14,6 +15,7 @@
import static com.mapbox.mapboxsdk.style.expressions.Expression.at;
import static com.mapbox.mapboxsdk.style.expressions.Expression.atan;
import static com.mapbox.mapboxsdk.style.expressions.Expression.bool;
import static com.mapbox.mapboxsdk.style.expressions.Expression.ceil;
import static com.mapbox.mapboxsdk.style.expressions.Expression.coalesce;
import static com.mapbox.mapboxsdk.style.expressions.Expression.color;
import static com.mapbox.mapboxsdk.style.expressions.Expression.concat;
Expand All @@ -24,6 +26,7 @@
import static com.mapbox.mapboxsdk.style.expressions.Expression.e;
import static com.mapbox.mapboxsdk.style.expressions.Expression.eq;
import static com.mapbox.mapboxsdk.style.expressions.Expression.exponential;
import static com.mapbox.mapboxsdk.style.expressions.Expression.floor;
import static com.mapbox.mapboxsdk.style.expressions.Expression.geometryType;
import static com.mapbox.mapboxsdk.style.expressions.Expression.get;
import static com.mapbox.mapboxsdk.style.expressions.Expression.gt;
Expand Down Expand Up @@ -56,6 +59,7 @@
import static com.mapbox.mapboxsdk.style.expressions.Expression.properties;
import static com.mapbox.mapboxsdk.style.expressions.Expression.rgb;
import static com.mapbox.mapboxsdk.style.expressions.Expression.rgba;
import static com.mapbox.mapboxsdk.style.expressions.Expression.round;
import static com.mapbox.mapboxsdk.style.expressions.Expression.sin;
import static com.mapbox.mapboxsdk.style.expressions.Expression.sqrt;
import static com.mapbox.mapboxsdk.style.expressions.Expression.step;
Expand Down Expand Up @@ -1105,4 +1109,60 @@ public void testThrowIllegalArgumentExceptionForPropertyValueLiteral() {
);
expression.toArray();
}

@Test
public void testRound() {
Object[] expected = new Object[] {"round", 2.2f};
Object[] actual = round(2.2f).toArray();
assertTrue("expression should match", Arrays.deepEquals(expected, actual));
}

@Test
public void testRoundLiteral() {
Object[] expected = new Object[] {"round", 2.2f};
Object[] actual = round(literal(2.2f)).toArray();
assertTrue("expression should match", Arrays.deepEquals(expected, actual));
}

@Test
public void testAbs() {
Object[] expected = new Object[] {"abs", -2.2f};
Object[] actual = abs(-2.2f).toArray();
assertTrue("expression should match", Arrays.deepEquals(expected, actual));
}

@Test
public void testAbsLiteral() {
Object[] expected = new Object[] {"abs", -2.2f};
Object[] actual = abs(literal(-2.2f)).toArray();
assertTrue("expression should match", Arrays.deepEquals(expected, actual));
}

@Test
public void testCeil() {
Object[] expected = new Object[] {"ceil", 2.2f};
Object[] actual = ceil(2.2f).toArray();
assertTrue("expression should match", Arrays.deepEquals(expected, actual));
}

@Test
public void testCeilLiteral() {
Object[] expected = new Object[] {"ceil", 2.2f};
Object[] actual = ceil(literal(2.2f)).toArray();
assertTrue("expression should match", Arrays.deepEquals(expected, actual));
}

@Test
public void testFloor() {
Object[] expected = new Object[] {"floor", 2.2f};
Object[] actual = floor(2.2f).toArray();
assertTrue("expression should match", Arrays.deepEquals(expected, actual));
}

@Test
public void testFloorLiteral() {
Object[] expected = new Object[] {"floor", 2.2f};
Object[] actual = floor(literal(2.2f)).toArray();
assertTrue("expression should match", Arrays.deepEquals(expected, actual));
}
}
4 changes: 4 additions & 0 deletions platform/darwin/docs/guides/For Style Authors.md.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -379,18 +379,22 @@ 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)`
`log2` | |
`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` | |
Expand Down
1 change: 1 addition & 0 deletions platform/darwin/docs/guides/Predicates and Expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading

0 comments on commit f0f67b4

Please sign in to comment.