diff options
4 files changed, 157 insertions, 9 deletions
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 44ad5e83ed..70aa46fc6a 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,8 +5,10 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.Size; +import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; +import com.google.gson.JsonNull; import com.google.gson.JsonPrimitive; import com.mapbox.mapboxsdk.style.layers.PropertyFactory; import com.mapbox.mapboxsdk.style.layers.PropertyValue; @@ -210,7 +212,8 @@ public class Expression { * @return the color expression */ public static Expression color(@ColorInt int color) { - return toColor(literal(PropertyFactory.colorToRgbaString(color))); + int[] rgba = PropertyFactory.colorToRgbaArray(color); + return rgba(rgba[0], rgba[1], rgba[2], rgba[3]); } /** @@ -2426,6 +2429,7 @@ public class Expression { * ); * } * </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> @@ -3452,6 +3456,9 @@ public class Expression { /** * Returns a string representation of the object that matches the definition set in the style specification. + * <p> + * If this expression contains a coma (,) delimited literal, like 'rgba(r, g, b, a)`, + * it will be enclosed with double quotes ("). * * @return a string representation of the object. */ @@ -3463,7 +3470,17 @@ public class Expression { for (Object argument : arguments) { builder.append(", "); if (argument instanceof ExpressionLiteral) { - builder.append(((ExpressionLiteral) argument).toValue()); + Object literalValue = ((ExpressionLiteral) argument).toValue(); + + // special case for handling unusual input like 'rgba(r, g, b, a)' + if (literalValue instanceof String) { + if (((String) literalValue).contains(",")) { + builder.append("\"").append(literalValue).append("\""); + continue; + } + } + + builder.append(literalValue); } else { builder.append(argument.toString()); } @@ -3474,6 +3491,25 @@ public class Expression { } /** + * Returns a DSL equivalent of a raw expression. + * <p> + * If your raw expression contains a coma (,) delimited literal it has to be enclosed with double quotes ("), + * for example + * <pre> + * {@code + * ["to-color", "rgba(255, 0, 0, 255)"] + * } + * </pre> + * + * @param rawExpression the raw expression + * @return the resulting expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/">Style specification</a> + */ + public static Expression raw(@NonNull String rawExpression) { + return Converter.convert(rawExpression); + } + + /** * Indicates whether some other object is "equal to" this one. * * @param o the other object @@ -3527,6 +3563,15 @@ public class Expression { * @param object the object to be treated as literal */ public ExpressionLiteral(@NonNull Object object) { + if (object instanceof String) { + String string = (String) object; + if (string.length() > 1 && + string.charAt(0) == '\"' && string.charAt(string.length() - 1) == '\"') { + object = string.substring(1, string.length() - 1); + } + } else if (object instanceof Number) { + object = ((Number) object).floatValue(); + } this.literal = object; } @@ -3652,10 +3697,12 @@ public class Expression { } /** - * Converts a JsonArray to an expression. + * Converts a JsonArray or a raw expression to a Java expression. */ public final static class Converter { + private static Gson gson; + /** * Converts a JsonArray to an expression * @@ -3677,6 +3724,8 @@ public class Expression { arguments.add(convert((JsonArray) jsonElement)); } else if (jsonElement instanceof JsonPrimitive) { arguments.add(convert((JsonPrimitive) jsonElement)); + } else if (jsonElement instanceof JsonNull) { + arguments.add(new Expression.ExpressionLiteral("")); } else { throw new RuntimeException("Unsupported expression conversion for " + jsonElement.getClass()); } @@ -3701,6 +3750,21 @@ public class Expression { throw new RuntimeException("Unsupported literal expression conversion for " + jsonPrimitive.getClass()); } } + + /** + * Converts a raw expression to a DSL equivalent. + * + * @param rawExpression the raw expression to convert + * @return the resulting expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/">Style specification</a> + */ + public static Expression convert(@NonNull String rawExpression) { + return convert(getGsonInstance().fromJson(rawExpression, JsonArray.class)); + } + + private static Gson getGsonInstance() { + return gson = gson != null ? gson : new Gson(); + } } /** diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java index 1dd8eddab9..57638920be 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java @@ -2375,9 +2375,24 @@ public class PropertyFactory { return new LayoutPropertyValue<>("text-optional", value); } - public static String colorToRgbaString(@ColorInt int value) { - return String.format(Locale.US,"rgba(%d, %d, %d, %d)", - (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, (value >> 24) & 0xFF); + /** + * Converts Android color int to "rbga(r, g, b, a)" String equivalent. + * + * @param color Android color int + * @return String rgba color + */ + public static String colorToRgbaString(@ColorInt int color) { + return String.format(Locale.US, "rgba(%d, %d, %d, %d)", + (color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF, (color >> 24) & 0xFF); } + /** + * Converts Android color int to rgba int array. + * + * @param color Android color int + * @return int rgba array + */ + public static int[] colorToRgbaArray(@ColorInt int color) { + return new int[] {(color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF, (color >> 24) & 0xFF}; + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs index 6480dde3c8..ce0489409c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs @@ -85,9 +85,24 @@ public class PropertyFactory { } <% } -%> - public static String colorToRgbaString(@ColorInt int value) { - return String.format(Locale.US,"rgba(%d, %d, %d, %d)", - (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, (value >> 24) & 0xFF); + /** + * Converts Android color int to "rbga(r, g, b, a)" String equivalent. + * + * @param color Android color int + * @return String rgba color + */ + public static String colorToRgbaString(@ColorInt int color) { + return String.format(Locale.US, "rgba(%d, %d, %d, %d)", + (color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF, (color >> 24) & 0xFF); } + /** + * Converts Android color int to rgba int array. + * + * @param color Android color int + * @return int rgba array + */ + public static int[] colorToRgbaArray(@ColorInt int color) { + return new int[] {(color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF, (color >> 24) & 0xFF}; + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/style/expressions/ExpressionTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/style/expressions/ExpressionTest.java index 45833e8556..327cd33b37 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/style/expressions/ExpressionTest.java +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/style/expressions/ExpressionTest.java @@ -2,6 +2,8 @@ package com.mapbox.mapboxsdk.style.expressions; import android.graphics.Color; +import com.mapbox.mapboxsdk.style.layers.PropertyFactory; + import org.junit.Test; import java.util.Arrays; @@ -57,6 +59,7 @@ import static com.mapbox.mapboxsdk.style.expressions.Expression.pi; import static com.mapbox.mapboxsdk.style.expressions.Expression.pow; import static com.mapbox.mapboxsdk.style.expressions.Expression.product; import static com.mapbox.mapboxsdk.style.expressions.Expression.properties; +import static com.mapbox.mapboxsdk.style.expressions.Expression.raw; 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; @@ -1165,4 +1168,55 @@ public class ExpressionTest { Object[] actual = floor(literal(2.2f)).toArray(); assertTrue("expression should match", Arrays.deepEquals(expected, actual)); } + + @Test + public void testRaw() { + String raw = "[\"get\", ]"; + Expression expected = get(""); + assertEquals("expressions should match", raw(raw), expected); + + raw = "[\"get\", key]"; + expected = get("key"); + assertEquals("expressions should match", raw(raw), expected); + + expected = interpolate(linear(), zoom(), + stop(12, step(get("stroke-width"), + color(Color.BLACK), + stop(1f, color(Color.RED)), + stop(2f, color(Color.WHITE)), + stop(3f, color(Color.BLUE)) + )), + stop(15, step(get("stroke-width"), + color(Color.BLACK), + stop(1f, color(Color.YELLOW)), + stop(2f, color(Color.LTGRAY)), + stop(3f, color(Color.CYAN)) + )), + stop(18, step(get("stroke-width"), + color(Color.BLACK), + stop(1f, color(Color.WHITE)), + stop(2f, color(Color.GRAY)), + stop(3f, color(Color.GREEN)) + )) + ); + assertEquals("expressions should match", expected, raw(expected.toString())); + + expected = interpolate( + exponential(2f), zoom(), + literal(5f), literal("rgba(0, 0, 0, 255)"), + literal(10.5f), literal("rgb(255, 0, 0)"), + literal(15), color(Color.GREEN), + literal(20), literal(PropertyFactory.colorToRgbaString(Color.BLUE))); + assertEquals("expressions should match", expected, raw(expected.toString())); + + expected = match(get("property"), literal(""), + stop("layer1", "image1"), + stop("layer2", "image2")); + assertEquals("expressions should match", expected, raw(expected.toString())); + + expected = match(get("property"), literal(""), + stop("layer1", 2), + stop("layer2", 2.7)); + assertEquals("expressions should match", expected, raw(expected.toString())); + } }
\ No newline at end of file |