From 6179110b6bfe8ee0880a055a31c12a88f9bd9b20 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Thu, 8 Mar 2018 16:27:02 +0100 Subject: [android] - add expression conversion, add getters (#11352) --- .../mapboxsdk/style/expressions/Expression.java | 280 +++++++++++++-------- 1 file changed, 180 insertions(+), 100 deletions(-) (limited to 'platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java') diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java index 0cd5aa9d6c..f6caa0b8e3 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java @@ -5,9 +5,13 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.Size; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; import com.mapbox.mapboxsdk.style.layers.PropertyFactory; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -101,10 +105,6 @@ public class Expression { return new ExpressionLiteral(bool); } - // - // Types - // - /** * Create a literal object expression. * @@ -159,10 +159,6 @@ public class Expression { return rgb(literal(red), literal(green), literal(blue)); } - // - // Literals - // - /** * Creates a color value from red, green, blue components, which must range between 0 and 255, * and an alpha component which must range between 0 and 1. @@ -224,10 +220,6 @@ public class Expression { return new Expression("==", compareOne, compareTwo); } - // - // Color - // - /** * Returns true if the input values are equal, false otherwise. * @@ -301,10 +293,6 @@ public class Expression { return new Expression("!=", literal(compareOne), literal(compareTwo)); } - // - // Decision - // - /** * Returns `true` if the input values are not equal, `false` otherwise. * @@ -477,7 +465,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression all(@NonNull Expression... input) { return new Expression("all", input); } @@ -494,7 +481,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression any(@NonNull Expression... input) { return new Expression("any", input); } @@ -532,7 +518,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression switchCase(@NonNull @Size(min = 1) Expression... input) { return new Expression("case", input); } @@ -661,10 +646,6 @@ public class Expression { return new Expression("get", input); } - // - // FeatureData - // - /** * Retrieves a property value from the current feature's properties, * or from another object if a second argument is provided. @@ -704,10 +685,6 @@ public class Expression { return get(literal(key), object); } - // - // Heatmap - // - /** * Tests for the presence of an property value in the current feature's properties. * @@ -719,10 +696,6 @@ public class Expression { return new Expression("has", key); } - // - // Lookup - // - /** * Tests for the presence of an property value in the current feature's properties. * @@ -817,7 +790,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression sum(@Size(min = 2) Expression... numbers) { return new Expression("+", numbers); } @@ -829,7 +801,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression sum(@Size(min = 2) Number... numbers) { Expression[] numberExpression = new Expression[numbers.length]; for (int i = 0; i < numbers.length; i++) { @@ -845,7 +816,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression product(@Size(min = 2) Expression... numbers) { return new Expression("*", numbers); } @@ -857,7 +827,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression product(@Size(min = 2) Number... numbers) { Expression[] numberExpression = new Expression[numbers.length]; for (int i = 0; i < numbers.length; i++) { @@ -866,10 +835,6 @@ public class Expression { return product(numberExpression); } - // - // Math - // - /** * Returns the result of subtracting a number from 0. * @@ -1215,7 +1180,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression min(@Size(min = 1) Expression... numbers) { return new Expression("min", numbers); } @@ -1227,7 +1191,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression min(@Size(min = 1) Number... numbers) { Expression[] numberExpression = new Expression[numbers.length]; for (int i = 0; i < numbers.length; i++) { @@ -1243,7 +1206,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression max(@Size(min = 1) Expression... numbers) { return new Expression("max", numbers); } @@ -1255,7 +1217,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression max(@Size(min = 1) Number... numbers) { Expression[] numberExpression = new Expression[numbers.length]; for (int i = 0; i < numbers.length; i++) { @@ -1331,7 +1292,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression concat(@NonNull Expression... input) { return new Expression("concat", input); } @@ -1343,7 +1303,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression concat(@NonNull String... input) { Expression[] stringExpression = new Expression[input.length]; for (int i = 0; i < input.length; i++) { @@ -1365,10 +1324,6 @@ public class Expression { return new Expression("array", input); } - // - // String - // - /** * Returns a string describing the type of the given value. * @@ -1448,10 +1403,6 @@ public class Expression { return new Expression("to-string", input); } - // - // Types - // - /** * Converts the input value to a number, if possible. * If the input is null or false, the result is 0. @@ -1501,7 +1452,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression let(@Size(min = 1) Expression... input) { return new Expression("let", input); } @@ -1565,7 +1515,6 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression step(@NonNull Number input, @NonNull Expression expression, Expression... stops) { return step(literal(input), expression, stops); } @@ -1582,15 +1531,10 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression step(@NonNull Expression input, @NonNull Expression expression, Expression... stops) { return new Expression("step", join(new Expression[] {input, expression}, stops)); } - // - // Variable binding - // - /** * Produces discrete, stepped results by evaluating a piecewise-constant function defined by pairs of * input and output values (\"stops\"). The `input` may be any numeric expression (e.g., `[\"get\", \"population\"]`). @@ -1603,14 +1547,8 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression step(@NonNull Number input, @NonNull Expression expression, Stop... stops) { - Expression[] expressions = new Expression[stops.length * 2]; - for (int i = 0; i < stops.length; i++) { - expressions[i * 2] = literal(stops[i].value); - expressions[i * 2 + 1] = literal(stops[i].output); - } - return step(literal(input), expression, expressions); + return step(literal(input), expression, Stop.toExpressionArray(stops)); } /** @@ -1625,14 +1563,8 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression step(@NonNull Expression input, @NonNull Expression expression, Stop... stops) { - Expression[] expressions = new Expression[stops.length * 2]; - for (int i = 0; i < stops.length; i++) { - expressions[i * 2] = literal(stops[i].value); - expressions[i * 2 + 1] = literal(stops[i].output); - } - return step(input, expression, expressions); + return step(input, expression, Stop.toExpressionArray(stops)); } /** @@ -1647,16 +1579,11 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression interpolate(@NonNull Interpolator interpolation, @NonNull Expression number, Expression... stops) { return new Expression("interpolate", join(new Expression[] {interpolation, number}, stops)); } - // - // Zoom - // - /** * Produces continuous, smooth results by interpolating between pairs of input and output values (\"stops\"). * The `input` may be any numeric expression (e.g., `[\"get\", \"population\"]`). @@ -1669,21 +1596,11 @@ public class Expression { * @return expression * @see Style specification */ - public static Expression interpolate(@NonNull Interpolator interpolation, @NonNull Expression number, Stop... stops) { - Expression[] expressions = new Expression[stops.length * 2]; - for (int i = 0; i < stops.length; i++) { - expressions[i * 2] = literal(stops[i].value); - expressions[i * 2 + 1] = literal(stops[i].output); - } - return interpolate(interpolation, number, expressions); + return interpolate(interpolation, number, Stop.toExpressionArray(stops)); } - - // - // Ramps, scales, curves - // - + /** * interpolates linearly between the pair of stops just less than and just greater than the input. * @@ -1834,6 +1751,43 @@ public class Expression { return builder.toString(); } + /** + * Indicates whether some other object is "equal to" this one. + * + * @param o the other object + * @return true if equal, false if not + */ + @Override + public boolean equals(Object o) { + super.equals(o); + if (this == o) { + return true; + } + + if (o == null || !(o instanceof Expression)) { + return false; + } + + Expression that = (Expression) o; + + if (operator != null ? !operator.equals(that.operator) : that.operator != null) { + return false; + } + return Arrays.deepEquals(arguments, that.arguments); + } + + /** + * Returns a hash code value for the expression. + * + * @return a hash code value for this expression + */ + @Override + public int hashCode() { + int result = operator != null ? operator.hashCode() : 0; + result = 31 * result + Arrays.hashCode(arguments); + return result; + } + /** * ExpressionLiteral wraps an object to be used as a literal in an expression. *

@@ -1841,27 +1795,72 @@ public class Expression { * {@link #literal(String)} and {@link #literal(Object)}. *

*/ - private static class ExpressionLiteral extends Expression { + public static class ExpressionLiteral extends Expression { protected Object literal; /** - * Create an ExpressionValue wrapper. + * Create an expression literal. * - * @param object the object to be wrapped + * @param object the object to be treated as literal */ - ExpressionLiteral(@NonNull Object object) { + public ExpressionLiteral(@NonNull Object object) { this.literal = object; } /** - * Get the wrapped object. + * Get the literal object. * - * @return the wrapped object + * @return the literal object */ Object toValue() { return literal; } + + /** + * Returns a string representation of the expression literal. + * + * @return a string representation of the object. + */ + @Override + public String toString() { + return literal.toString(); + } + + /** + * Indicates whether some other object is "equal to" this one. + * + * @param o the other object + * @return true if equal, false if not + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + + ExpressionLiteral that = (ExpressionLiteral) o; + + return literal != null ? literal.equals(that.literal) : that.literal == null; + } + + /** + * Returns a hash code value for the expression literal. + * + * @return a hash code value for this expression literal + */ + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (literal != null ? literal.hashCode() : 0); + return result; + } } /** @@ -1896,9 +1895,9 @@ public class Expression { /** * Converts the int color to rgba(d, d, d, d) string representation * - * @return + * @return the string representation of a color */ - public String convertColor() { + String convertColor() { return PropertyFactory.colorToRgbaString(color); } } @@ -1921,9 +1920,90 @@ public class Expression { private Object value; private Object output; - public Stop(Object value, Object output) { + Stop(Object value, Object output) { this.value = value; this.output = output; } + + /** + * Converts a varargs of Stops to a Expression array. + * + * @param stops the stops to convert + * @return the converted stops as an expression array + */ + static Expression[] toExpressionArray(Stop... stops) { + Expression[] expressions = new Expression[stops.length * 2]; + Stop stop; + Object inputValue, outputValue; + for (int i = 0; i < stops.length; i++) { + stop = stops[i]; + inputValue = stop.value; + outputValue = stop.output; + + if (!(inputValue instanceof Expression)) { + inputValue = literal(inputValue); + } + + if (!(outputValue instanceof Expression)) { + outputValue = literal(outputValue); + } + + expressions[i * 2] = (Expression) inputValue; + expressions[i * 2 + 1] = (Expression) outputValue; + } + return expressions; + } + } + + /** + * Converts a JsonArray to an expression. + */ + public final static class Converter { + + /** + * Converts a JsonArray to an expression + * + * @param jsonArray the json array to convert + * @return the expression + */ + public static Expression convert(@NonNull JsonArray jsonArray) { + if (jsonArray.size() == 0) { + throw new IllegalArgumentException("Can't convert empty jsonArray expressions"); + } + + final String operator = jsonArray.get(0).getAsString(); + final List arguments = new ArrayList<>(); + + JsonElement jsonElement; + for (int i = 1; i < jsonArray.size(); i++) { + jsonElement = jsonArray.get(i); + if (jsonElement instanceof JsonArray) { + arguments.add(convert((JsonArray) jsonElement)); + } else if (jsonElement instanceof JsonPrimitive) { + arguments.add(convert((JsonPrimitive) jsonElement)); + } else { + throw new RuntimeException("Unsupported expression conversion for " + jsonElement.getClass()); + } + } + return new Expression(operator, arguments.toArray(new Expression[arguments.size()])); + } + + /** + * Converts a JsonPrimitive to an expression literal + * + * @param jsonPrimitive the json primitive to convert + * @return the expression literal + */ + private static Expression convert(@NonNull JsonPrimitive jsonPrimitive) { + if (jsonPrimitive.isBoolean()) { + return new Expression.ExpressionLiteral(jsonPrimitive.getAsBoolean()); + } else if (jsonPrimitive.isNumber()) { + return new Expression.ExpressionLiteral(jsonPrimitive.getAsFloat()); + } else if (jsonPrimitive.isString()) { + return new Expression.ExpressionLiteral(jsonPrimitive.getAsString()); + } else { + throw new RuntimeException("Unsupported literal expression conversion for " + jsonPrimitive.getClass()); + } + } } } \ No newline at end of file -- cgit v1.2.1