diff options
author | tobrun <tobrun.van.nuland@gmail.com> | 2018-07-05 11:53:48 +0200 |
---|---|---|
committer | tobrun <tobrun.van.nuland@gmail.com> | 2018-08-13 16:37:07 +0200 |
commit | 53af7a633468a59aefb7f99bc7a4c5f99094b473 (patch) | |
tree | 6c6e65b4e24cce0ee9a8bb886b876bee0ee92d12 | |
parent | fdc287ec3608850654196e3b3a682ca3c5039676 (diff) | |
download | qtlocation-mapboxgl-upstream/tvn-wip-collator.tar.gz |
[android] - add collator supportupstream/tvn-wip-collator
5 files changed, 415 insertions, 8 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 1aa0ce9093..64f2605683 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 @@ -14,7 +14,9 @@ import com.mapbox.mapboxsdk.style.layers.PropertyValue; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * The value for any layout property, paint property, or filter may be specified as an expression. @@ -386,6 +388,31 @@ public class Expression { /** * Returns true if the input values are equal, false otherwise. + * The inputs must be numbers, strings, or booleans, and both of the same type. + * <p> + * Example usage: + * </p> + * <pre> + * {@code + * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); + * fillLayer.setFilter( + * eq(get("keyToValue"), get("keyToOtherValue")) + * ); + * } + * </pre> + * + * @param compareOne the first expression + * @param compareTwo the second expression + * @param collator the string collator + * @return expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-==">Style specification</a> + */ + public static Expression eq(@NonNull Expression compareOne, @NonNull Expression compareTwo, @NonNull Expression collator) { + return new Expression("==", compareOne, compareTwo, collator); + } + + /** + * Returns true if the input values are equal, false otherwise. * <p> * Example usage: * </p> @@ -422,7 +449,7 @@ public class Expression { * </pre> * * @param compareOne the first expression - * @param compareTwo the second number + * @param compareTwo the second string * @return expression * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-==">Style specification</a> */ @@ -439,6 +466,30 @@ public class Expression { * {@code * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); * fillLayer.setFilter( + * eq(get("keyToValue"), "value") + * ); + * } + * </pre> + * + * @param compareOne the first expression + * @param compareTwo the second string + * @param collator the string collator + * @return expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-==">Style specification</a> + */ + public static Expression eq(@NonNull Expression compareOne, @NonNull String compareTwo, @NonNull Expression collator) { + return eq(compareOne, literal(compareTwo), collator); + } + + /** + * Returns true if the input values are equal, false otherwise. + * <p> + * Example usage: + * </p> + * <pre> + * {@code + * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); + * fillLayer.setFilter( * eq(get("keyToValue"), 2.0f) * ); * } @@ -477,6 +528,32 @@ public class Expression { return new Expression("!=", compareOne, compareTwo); } + + /** + * Returns true if the input values are not equal, false otherwise. + * The inputs must be numbers, strings, or booleans, and both of the same type. + * <p> + * Example usage: + * </p> + * <pre> + * {@code + * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); + * fillLayer.setFilter( + * neq(get("keyToValue"), get("keyToOtherValue")) + * ); + * } + * </pre> + * + * @param compareOne the first expression + * @param compareTwo the second expression + * @param collator the string collator + * @return expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-!=">Style specification</a> + */ + public static Expression neq(@NonNull Expression compareOne, @NonNull Expression compareTwo, @NonNull Expression collator) { + return new Expression("!=", compareOne, compareTwo, collator); + } + /** * Returns true if the input values are equal, false otherwise. * <p> @@ -532,6 +609,30 @@ public class Expression { * {@code * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); * fillLayer.setFilter( + * neq(get("keyToValue"), "value")) + * ); + * } + * </pre> + * + * @param compareOne the first expression + * @param compareTwo the second string + * @param collator the string collator + * @return expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-!=">Style specification</a> + */ + public static Expression neq(@NonNull Expression compareOne, @NonNull String compareTwo, @NonNull Expression collator) { + return new Expression("!=", compareOne, literal(compareTwo), collator); + } + + /** + * Returns `true` if the input values are not equal, `false` otherwise. + * <p> + * Example usage: + * </p> + * <pre> + * {@code + * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); + * fillLayer.setFilter( * neq(get("keyToValue"), 2.0f)) * ); * } @@ -572,6 +673,31 @@ public class Expression { /** * Returns true if the first input is strictly greater than the second, false otherwise. + * The inputs must be numbers or strings, and both of the same type. + * <p> + * Example usage: + * </p> + * <pre> + * {@code + * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); + * fillLayer.setFilter( + * gt(get("keyToValue"), get("keyToOtherValue")) + * ); + * } + * </pre> + * + * @param compareOne the first expression + * @param compareTwo the second expression + * @param collator the string collator + * @return expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-%3E">Style specification</a> + */ + public static Expression gt(@NonNull Expression compareOne, @NonNull Expression compareTwo, @NonNull Expression collator) { + return new Expression(">", compareOne, compareTwo, collator); + } + + /** + * Returns true if the first input is strictly greater than the second, false otherwise. * <p> * Example usage: * </p> @@ -617,6 +743,30 @@ public class Expression { } /** + * Returns true if the first input is strictly greater than the second, false otherwise. + * <p> + * Example usage: + * </p> + * <pre> + * {@code + * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); + * fillLayer.setFilter( + * gt(get("keyToValue"), "value") + * ); + * } + * </pre> + * + * @param compareOne the first expression + * @param compareTwo the second string + * @param collator the string collator + * @return expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-%3E">Style specification</a> + */ + public static Expression gt(@NonNull Expression compareOne, @NonNull String compareTwo, @NonNull Expression collator) { + return new Expression(">", compareOne, literal(compareTwo), collator); + } + + /** * Returns true if the first input is strictly less than the second, false otherwise. * The inputs must be numbers or strings, and both of the same type. * <p> @@ -640,6 +790,32 @@ public class Expression { return new Expression("<", compareOne, compareTwo); } + + /** + * Returns true if the first input is strictly less than the second, false otherwise. + * The inputs must be numbers or strings, and both of the same type. + * <p> + * Example usage: + * </p> + * <pre> + * {@code + * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); + * fillLayer.setFilter( + * lt(get("keyToValue"), get("keyToOtherValue")) + * ); + * } + * </pre> + * + * @param compareOne the first expression + * @param compareTwo the second number + * @param collator the string collator + * @return expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-%3C">Style specification</a> + */ + public static Expression lt(@NonNull Expression compareOne, @NonNull Expression compareTwo, @NonNull Expression collator) { + return new Expression("<", compareOne, compareTwo, collator); + } + /** * Returns true if the first input is strictly less than the second, false otherwise. * <p> @@ -686,6 +862,31 @@ public class Expression { return new Expression("<", compareOne, literal(compareTwo)); } + + /** + * Returns true if the first input is strictly less than the second, false otherwise. + * <p> + * Example usage: + * </p> + * <pre> + * {@code + * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); + * fillLayer.setFilter( + * lt(get("keyToValue"), "value")) + * ); + * } + * </pre> + * + * @param compareOne the first expression + * @param compareTwo the second string + * @param collator the string collator + * @return expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-%3C">Style specification</a> + */ + public static Expression lt(@NonNull Expression compareOne, @NonNull String compareTwo, @NonNull Expression collator) { + return new Expression("<", compareOne, literal(compareTwo), collator); + } + /** * Returns true if the first input is greater than or equal to the second, false otherwise. * The inputs must be numbers or strings, and both of the same type. @@ -712,6 +913,31 @@ public class Expression { /** * Returns true if the first input is greater than or equal to the second, false otherwise. + * The inputs must be numbers or strings, and both of the same type. + * <p> + * Example usage: + * </p> + * <pre> + * {@code + * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); + * fillLayer.setFilter( + * gte(get("keyToValue"), get("keyToOtherValue")) + * ); + * } + * </pre> + * + * @param compareOne the first expression + * @param compareTwo the second expression + * @param collator the string collator + * @return expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-%3E%3D">Style specification</a> + */ + public static Expression gte(@NonNull Expression compareOne, @NonNull Expression compareTwo, @NonNull Expression collator) { + return new Expression(">=", compareOne, compareTwo, collator); + } + + /** + * Returns true if the first input is greater than or equal to the second, false otherwise. * <p> * Example usage: * </p> @@ -757,6 +983,30 @@ public class Expression { } /** + * Returns true if the first input is greater than or equal to the second, false otherwise. + * <p> + * Example usage: + * </p> + * <pre> + * {@code + * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); + * fillLayer.setFilter( + * neq(get("keyToValue"), "value") + * ); + * } + * </pre> + * + * @param compareOne the first expression + * @param compareTwo the second string + * @param collator the string collator + * @return expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-%3E%3D">Style specification</a> + */ + public static Expression gte(@NonNull Expression compareOne, @NonNull String compareTwo, @NonNull Expression collator) { + return new Expression(">=", compareOne, literal(compareTwo), collator); + } + + /** * Returns true if the first input is less than or equal to the second, false otherwise. * The inputs must be numbers or strings, and both of the same type. * <p> @@ -782,6 +1032,31 @@ public class Expression { /** * Returns true if the first input is less than or equal to the second, false otherwise. + * The inputs must be numbers or strings, and both of the same type. + * <p> + * Example usage: + * </p> + * <pre> + * {@code + * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); + * fillLayer.setFilter( + * lte(get("keyToValue"), get("keyToOtherValue")) + * ); + * } + * </pre> + * + * @param compareOne the first expression + * @param compareTwo the second expression + * @param collator the string collator + * @return expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-%3C%3D">Style specification</a> + */ + public static Expression lte(@NonNull Expression compareOne, @NonNull Expression compareTwo, @NonNull Expression collator) { + return new Expression("<=", compareOne, compareTwo, collator); + } + + /** + * Returns true if the first input is less than or equal to the second, false otherwise. * <p> * Example usage: * </p> @@ -827,6 +1102,30 @@ public class Expression { } /** + * Returns true if the first input is less than or equal to the second, false otherwise. + * <p> + * Example usage: + * </p> + * <pre> + * {@code + * FillLayer fillLayer = new FillLayer("layer-id", "source-id"); + * fillLayer.setFilter( + * lte(get("keyToValue"), "value") + * ); + * } + * </pre> + * + * @param compareOne the first expression + * @param compareTwo the second string + * @param collator the string collator + * @return expression + * @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-%3C%3D">Style specification</a> + */ + public static Expression lte(@NonNull Expression compareOne, @NonNull String compareTwo, @NonNull Expression collator) { + return new Expression("<=", compareOne, literal(compareTwo), collator); + } + + /** * Returns `true` if all the inputs are `true`, `false` otherwise. * <p> * The inputs are evaluated in order, and evaluation is short-circuiting: @@ -2737,6 +3036,60 @@ public class Expression { return new Expression("to-string", input); } + + /** + * Returns a `collator` for use in locale-dependent comparison operations. + * The `caseSensitive` and `diacriticSensitive` options default to `false`. + * The `locale` argument specifies the IETF language tag of the locale to use. + * If none is provided, the default locale is used. + * If the requested locale is not available, the `collator` will use a system-defined fallback locale. + * Use `resolved-locale` to test the results of locale fallback behavior. + */ + public static Expression collator(Expression caseSensitive, Expression diacriticSensitive, Expression locale) { + //["collator", {"case-sensitive": false, "diacritic-sensitive": true, "locale": "en"}] +// JsonObject jsonObject = new JsonObject(); +// jsonObject.addProperty("caseSensitive",false); +// jsonObject.addProperty("diacriticSensitive",true); +// jsonObject.addProperty("locale","en"); +// Map<String, Object> map = new HashMap<String, Object>() { +// { +// put("caseSensitive", false); +// put("diacriticSensitive", true); +// put("locale", "en"); +// } +// }; + return new Expression("collator", literal(new Collator())); + } + private static class Collator { + private boolean caseSensitive = false; + private boolean diacriticSensitive = true; + private String locale = "en"; + } + +// public static Expression collator(boolean caseSensitive, boolean diacriticSensitive, boolean locale) { +// //["collator", {"case-sensitive": false, "diacritic-sensitive": true, "locale": "en"}] +// return new Expression("collator", new Expression[] {literal(caseSensitive), literal(diacriticSensitive), literal(locale)}); +// } + + // todo add boolean variant + public static Expression caseSensitive(Expression caseSensitive) { + return new Expression("case-sensitive", caseSensitive); + } + + // todo add boolean variant + public static Expression diacriticSensitive(Expression diacriticSensitive) { + return new Expression("diacritic-sensitive", diacriticSensitive); + } + + // todo add String variant + public static Expression locale(Expression locale) { + return new Expression("locale", locale); + } + + public static Expression resolvedLocale(Expression collator) { + return new Expression("resolved-locale", collator); + } + /** * Converts the input value to a number, if possible. * If the input is null or false, the result is 0. @@ -3567,6 +3920,27 @@ public class Expression { this.literal = object; } + private Object unwrapMapToString(Map<String, Object> map) { + // {"case-sensitive": false, "diacritic-sensitive": true, "locale": "en"} + StringBuilder builder = new StringBuilder("{"); + String templateValue = "\"%s\": %s"; + String templateString = "\"%s\": \"%s\""; + for (Map.Entry<String, Object> objectEntry : map.entrySet()) { + Object value = objectEntry.getValue(); + if (value instanceof String) { + builder.append(String.format(templateString, objectEntry.getKey(), value)); + } else { + builder.append(String.format(templateValue, objectEntry.getKey(), value)); + } + builder.append(","); + } + + if(!map.entrySet().isEmpty()){ + builder.deleteCharAt(builder.length()-1); + } + return builder.append("}").toString(); + } + /** * Get the literal object. * 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 fb74904f96..c11c049391 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 @@ -17,12 +17,14 @@ import static com.mapbox.mapboxsdk.style.expressions.Expression.asin; 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.caseSensitive; 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; import static com.mapbox.mapboxsdk.style.expressions.Expression.cos; import static com.mapbox.mapboxsdk.style.expressions.Expression.cubicBezier; +import static com.mapbox.mapboxsdk.style.expressions.Expression.diacriticSensitive; import static com.mapbox.mapboxsdk.style.expressions.Expression.division; import static com.mapbox.mapboxsdk.style.expressions.Expression.downcase; import static com.mapbox.mapboxsdk.style.expressions.Expression.e; @@ -43,6 +45,7 @@ import static com.mapbox.mapboxsdk.style.expressions.Expression.linear; import static com.mapbox.mapboxsdk.style.expressions.Expression.literal; import static com.mapbox.mapboxsdk.style.expressions.Expression.ln; import static com.mapbox.mapboxsdk.style.expressions.Expression.ln2; +import static com.mapbox.mapboxsdk.style.expressions.Expression.locale; import static com.mapbox.mapboxsdk.style.expressions.Expression.log10; import static com.mapbox.mapboxsdk.style.expressions.Expression.log2; import static com.mapbox.mapboxsdk.style.expressions.Expression.lt; @@ -907,6 +910,19 @@ public class ExpressionTest { } @Test + public void testCollator() throws Exception { + Object[] expected = new Object[]{"collator", + new Object[]{"case-sensitive","false","diacritic-sensitive","true", "locale","en"} + }; + Object[] actual = Expression.collator( + caseSensitive(literal(false)), + diacriticSensitive(literal(true)), + locale(literal("en")) + ).toArray(); + assertTrue("expression should match", Arrays.deepEquals(expected, actual)); + } + + @Test public void testToNumber() throws Exception { Object[] expected = new Object[] {"to-number", "3"}; Object[] actual = toNumber(literal("3")).toArray(); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java index 13913de26e..aeb8a82220 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java @@ -30,11 +30,14 @@ import java.util.Arrays; import java.util.List; import static com.mapbox.mapboxsdk.style.expressions.Expression.any; +import static com.mapbox.mapboxsdk.style.expressions.Expression.collator; import static com.mapbox.mapboxsdk.style.expressions.Expression.get; import static com.mapbox.mapboxsdk.style.expressions.Expression.has; import static com.mapbox.mapboxsdk.style.expressions.Expression.literal; import static com.mapbox.mapboxsdk.style.expressions.Expression.lte; import static com.mapbox.mapboxsdk.style.expressions.Expression.not; +import static com.mapbox.mapboxsdk.style.expressions.Expression.resolvedLocale; +import static com.mapbox.mapboxsdk.style.expressions.Expression.string; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAnchor; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconColor; @@ -77,8 +80,10 @@ public class SymbolLayerActivity extends AppCompatActivity implements MapboxMap. // Add a source FeatureCollection markers = FeatureCollection.fromFeatures(new Feature[] { - Feature.fromGeometry(Point.fromLngLat(4.91638, 52.35673), featureProperties("Marker 1")), - Feature.fromGeometry(Point.fromLngLat(4.91638, 52.34673), featureProperties("Marker 2")) + Feature.fromGeometry(Point.fromLngLat(4.91638, 52.35673), featureProperties("Marker 1","ä","a")), + Feature.fromGeometry(Point.fromLngLat(4.91638, 52.34673), featureProperties("Marker 2","A","a")), + Feature.fromGeometry(Point.fromLngLat(4.90655, 52.35673), featureProperties("Marker 3", "a", "a")), + Feature.fromGeometry(Point.fromLngLat(4.90655, 52.34673), featureProperties("Marker 4", "ä", "b")), }); mapboxMap.addSource(new GeoJsonSource(MARKER_SOURCE, markers)); @@ -89,16 +94,22 @@ public class SymbolLayerActivity extends AppCompatActivity implements MapboxMap. iconImage("my-layers-image"), iconAllowOverlap(true), iconAnchor(Property.ICON_ANCHOR_BOTTOM), - textField(get("title")), + textField(resolvedLocale(collator(literal(false),literal(true),literal("en")))), iconColor(Color.RED), textColor(Color.RED), textAnchor(Property.TEXT_ANCHOR_TOP), textSize(10f) - ).withFilter((any(not(has("price")), lte(get("price"), literal(25))))) + ).withFilter( + lte( + string(get("lhs")), + string(get("rhs")), + collator(literal(false),literal(true),literal("en")) + ) + ) ); // Show - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(52.35273, 4.91638), 14)); + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(52.35273, 4.91638), 13)); // Set a click-listener so we can manipulate the map mapboxMap.setOnMapClickListener(SymbolLayerActivity.this); @@ -141,9 +152,11 @@ public class SymbolLayerActivity extends AppCompatActivity implements MapboxMap. } } - private JsonObject featureProperties(String title) { + private JsonObject featureProperties(String title, String lhs, String rhs) { JsonObject object = new JsonObject(); object.add("title", new JsonPrimitive(title)); + object.add("lhs", new JsonPrimitive(lhs)); + object.add("rhs", new JsonPrimitive(rhs)); return object; } diff --git a/platform/android/src/style/android_conversion.hpp b/platform/android/src/style/android_conversion.hpp index 510a9f8444..80891f70c7 100644 --- a/platform/android/src/style/android_conversion.hpp +++ b/platform/android/src/style/android_conversion.hpp @@ -95,7 +95,10 @@ public: return { value.toString() }; } else if (value.isNumber()) { auto doubleVal = value.toDouble(); - return { doubleVal - (int) doubleVal > 0.0 ? doubleVal : value.toLong() }; + return {doubleVal - (int) doubleVal > 0.0 ? doubleVal : value.toLong()}; + } else if (value.isObject()) { + auto caseSensitive = objectMember(value, "caseSensitive"); + return {}; } else { return {}; } diff --git a/platform/android/src/style/layers/layer.cpp b/platform/android/src/style/layers/layer.cpp index c7a6bcd3a3..34af3501af 100644 --- a/platform/android/src/style/layers/layer.cpp +++ b/platform/android/src/style/layers/layer.cpp @@ -132,6 +132,7 @@ namespace android { return; } + layer.accept(SetFilterEvaluator {std::move(*converted)}); } |