[android] "collator" and "resolved-locale" expressions support
This commit is contained in:
committed by
Łukasz Paczos
parent
67f6891ea7
commit
87f73bb0a2
@@ -4,17 +4,22 @@ import android.support.annotation.ColorInt;
|
||||
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.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.mapbox.mapboxsdk.style.layers.PropertyFactory;
|
||||
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.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The value for any layout property, paint property, or filter may be specified as an expression.
|
||||
@@ -345,7 +350,8 @@ public class Expression {
|
||||
* @return expression
|
||||
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-rgba">Style specification</a>
|
||||
*/
|
||||
public static Expression rgba(@NonNull Number red, @NonNull Number green, @NonNull Number blue, @NonNull Number alpha) {
|
||||
public static Expression rgba(@NonNull Number red, @NonNull Number green, @NonNull Number blue, @NonNull Number
|
||||
alpha) {
|
||||
return rgba(literal(red), literal(green), literal(blue), literal(alpha));
|
||||
}
|
||||
|
||||
@@ -384,6 +390,32 @@ public class Expression {
|
||||
return new Expression("==", compareOne, compareTwo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second expression
|
||||
* @param collator the collator expression
|
||||
* @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>
|
||||
@@ -430,6 +462,32 @@ public class Expression {
|
||||
return eq(compareOne, literal(compareTwo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second String
|
||||
* @param collator the collator expression
|
||||
* @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>
|
||||
@@ -477,6 +535,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"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second expression
|
||||
* @param collator the collator expression
|
||||
* @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>
|
||||
@@ -523,6 +607,32 @@ public class Expression {
|
||||
return new Expression("!=", compareOne, literal(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"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second String
|
||||
* @param collator the collator expression
|
||||
* @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>
|
||||
@@ -570,6 +680,32 @@ public class Expression {
|
||||
return new Expression(">", compareOne, compareTwo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second expression
|
||||
* @param collator the collator expression
|
||||
* @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>
|
||||
@@ -616,6 +752,32 @@ public class Expression {
|
||||
return new Expression(">", compareOne, literal(compareTwo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second String
|
||||
* @param collator the collator expression
|
||||
* @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.
|
||||
@@ -626,18 +788,44 @@ public class Expression {
|
||||
* {@code
|
||||
* FillLayer fillLayer = new FillLayer("layer-id", "source-id");
|
||||
* fillLayer.setFilter(
|
||||
* lt(get("keyToValue"), get("keyToOtherValue"))
|
||||
* lt(get("keyToValue"), get("keyToOtherValue"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second expression
|
||||
* @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) {
|
||||
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"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second number
|
||||
* @param collator the collator expression
|
||||
* @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) {
|
||||
return new Expression("<", compareOne, compareTwo);
|
||||
public static Expression lt(@NonNull Expression compareOne, @NonNull Expression compareTwo,
|
||||
@NonNull Expression collator) {
|
||||
return new Expression("<", compareOne, compareTwo, collator);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -686,6 +874,32 @@ public class Expression {
|
||||
return new Expression("<", compareOne, literal(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"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second String
|
||||
* @param collator the collator expression
|
||||
* @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.
|
||||
@@ -710,6 +924,32 @@ public class Expression {
|
||||
return new Expression(">=", compareOne, compareTwo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second expression
|
||||
* @param collator the collator expression
|
||||
* @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>
|
||||
@@ -756,6 +996,32 @@ public class Expression {
|
||||
return new Expression(">=", compareOne, literal(compareTwo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second String
|
||||
* @param collator the collator expression
|
||||
* @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.
|
||||
@@ -780,6 +1046,32 @@ public class Expression {
|
||||
return new Expression("<=", compareOne, compareTwo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second expression
|
||||
* @param collator the collator expression
|
||||
* @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>
|
||||
@@ -826,6 +1118,32 @@ public class Expression {
|
||||
return new Expression("<=", compareOne, literal(compareTwo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"), collator(true, false))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param compareOne the first expression
|
||||
* @param compareTwo the second String
|
||||
* @param collator the collator expression
|
||||
* @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>
|
||||
@@ -2478,6 +2796,32 @@ public class Expression {
|
||||
return floor(literal(number));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IETF language tag of the locale being used by the provided collator.
|
||||
* This can be used to determine the default system locale,
|
||||
* or to determine if a requested locale was successfully loaded.
|
||||
* <p>
|
||||
* Example usage:
|
||||
* </p>
|
||||
* <pre>
|
||||
* {@code
|
||||
* CircleLayer circleLayer = new CircleLayer("layer-id", "source-id");
|
||||
* circleLayer.setProperties(
|
||||
* circleColor(switchCase(
|
||||
eq(literal("it"), resolvedLocale(collator(true, true, "it"))), literal(ColorUtils.colorToRgbaString(Color.GREEN)),
|
||||
literal(ColorUtils.colorToRgbaString(Color.RED))))
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param collator the collator expression
|
||||
* @return expression
|
||||
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-resolved-locale">Style specification</a>
|
||||
*/
|
||||
public static Expression resolvedLocale(Expression collator) {
|
||||
return new Expression("resolved-locale", collator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the input string converted to uppercase.
|
||||
* <p>
|
||||
@@ -2696,6 +3040,104 @@ public class Expression {
|
||||
return new Expression("boolean", input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collator for use in locale-dependent comparison operations.
|
||||
* The case-sensitive and diacritic-sensitive 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.
|
||||
*
|
||||
* @param caseSensitive case sensitive flag
|
||||
* @param diacriticSensitive diacritic sensitive flag
|
||||
* @param locale locale
|
||||
* @return expression
|
||||
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-types-collator">Style specification</a>
|
||||
*/
|
||||
public static Expression collator(boolean caseSensitive, boolean diacriticSensitive, Locale locale) {
|
||||
Map<String, Expression> map = new HashMap<>();
|
||||
map.put("case-sensitive", literal(caseSensitive));
|
||||
map.put("diacritic-sensitive", literal(diacriticSensitive));
|
||||
|
||||
StringBuilder localeStringBuilder = new StringBuilder();
|
||||
|
||||
String language = locale.getLanguage();
|
||||
if (language != null && !language.isEmpty()) {
|
||||
localeStringBuilder.append(language);
|
||||
}
|
||||
|
||||
String country = locale.getCountry();
|
||||
if (country != null && !country.isEmpty()) {
|
||||
localeStringBuilder.append("-");
|
||||
localeStringBuilder.append(country);
|
||||
}
|
||||
|
||||
map.put("locale", literal(localeStringBuilder.toString()));
|
||||
return new Expression("collator", new ExpressionMap(map));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collator for use in locale-dependent comparison operations.
|
||||
* The case-sensitive and diacritic-sensitive 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.
|
||||
*
|
||||
* @param caseSensitive case sensitive flag
|
||||
* @param diacriticSensitive diacritic sensitive flag
|
||||
* @return expression
|
||||
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-types-collator">Style specification</a>
|
||||
*/
|
||||
public static Expression collator(boolean caseSensitive, boolean diacriticSensitive) {
|
||||
Map<String, Expression> map = new HashMap<>();
|
||||
map.put("case-sensitive", literal(caseSensitive));
|
||||
map.put("diacritic-sensitive", literal(diacriticSensitive));
|
||||
return new Expression("collator", new ExpressionMap(map));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collator for use in locale-dependent comparison operations.
|
||||
* The case-sensitive and diacritic-sensitive 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.
|
||||
*
|
||||
* @param caseSensitive case sensitive flag
|
||||
* @param diacriticSensitive diacritic sensitive flag
|
||||
* @param locale locale
|
||||
* @return expression
|
||||
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-types-collator">Style specification</a>
|
||||
*/
|
||||
public static Expression collator(Expression caseSensitive, Expression diacriticSensitive, Expression locale) {
|
||||
Map<String, Expression> map = new HashMap<>();
|
||||
map.put("case-sensitive", caseSensitive);
|
||||
map.put("diacritic-sensitive", diacriticSensitive);
|
||||
map.put("locale", locale);
|
||||
return new Expression("collator", new ExpressionMap(map));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collator for use in locale-dependent comparison operations.
|
||||
* The case-sensitive and diacritic-sensitive 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.
|
||||
*
|
||||
* @param caseSensitive case sensitive flag
|
||||
* @param diacriticSensitive diacritic sensitive flag
|
||||
* @return expression
|
||||
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-types-collator">Style specification</a>
|
||||
*/
|
||||
public static Expression collator(Expression caseSensitive, Expression diacriticSensitive) {
|
||||
Map<String, Expression> map = new HashMap<>();
|
||||
map.put("case-sensitive", caseSensitive);
|
||||
map.put("diacritic-sensitive", diacriticSensitive);
|
||||
return new Expression("collator", new ExpressionMap(map));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the input value is an object. If it is not, the expression is an error
|
||||
* The asserted input value is returned as result.
|
||||
@@ -3422,8 +3864,8 @@ public class Expression {
|
||||
array.add(operator);
|
||||
if (arguments != null) {
|
||||
for (Expression argument : arguments) {
|
||||
if (argument instanceof Expression.ExpressionLiteral) {
|
||||
array.add(toValue((ExpressionLiteral) argument));
|
||||
if (argument instanceof ValueExpression) {
|
||||
array.add(((ValueExpression) argument).toValue());
|
||||
} else {
|
||||
array.add(argument.toArray());
|
||||
}
|
||||
@@ -3432,22 +3874,6 @@ public class Expression {
|
||||
return array.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the expression value to an Object.
|
||||
*
|
||||
* @param expressionValue the expression value to convert
|
||||
* @return the converted object expression
|
||||
*/
|
||||
private Object toValue(ExpressionLiteral expressionValue) {
|
||||
Object value = expressionValue.toValue();
|
||||
if (value instanceof PropertyValue) {
|
||||
throw new IllegalArgumentException("PropertyValue are not allowed as an expression literal, use value instead.");
|
||||
} else if (value instanceof Expression.ExpressionLiteral) {
|
||||
return toValue((ExpressionLiteral) value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the object that matches the definition set in the style specification.
|
||||
* <p>
|
||||
@@ -3549,7 +3975,7 @@ public class Expression {
|
||||
* {@link #literal(String)} and {@link #literal(Object)}.
|
||||
* </p>
|
||||
*/
|
||||
public static class ExpressionLiteral extends Expression {
|
||||
public static class ExpressionLiteral extends Expression implements ValueExpression {
|
||||
|
||||
protected Object literal;
|
||||
|
||||
@@ -3572,7 +3998,14 @@ public class Expression {
|
||||
*
|
||||
* @return the literal object
|
||||
*/
|
||||
Object toValue() {
|
||||
@Override
|
||||
public Object toValue() {
|
||||
if (literal instanceof PropertyValue) {
|
||||
throw new IllegalArgumentException(
|
||||
"PropertyValue are not allowed as an expression literal, use value instead.");
|
||||
} else if (literal instanceof Expression.ExpressionLiteral) {
|
||||
return ((ExpressionLiteral) literal).toValue();
|
||||
}
|
||||
return literal;
|
||||
}
|
||||
|
||||
@@ -3589,7 +4022,13 @@ public class Expression {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return literal.toString();
|
||||
String string;
|
||||
if (literal instanceof String) {
|
||||
string = "\"" + literal + "\"";
|
||||
} else {
|
||||
string = literal.toString();
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3627,7 +4066,7 @@ public class Expression {
|
||||
return result;
|
||||
}
|
||||
|
||||
private String unwrapStringLiteral(String value) {
|
||||
private static String unwrapStringLiteral(String value) {
|
||||
if (value.length() > 1 &&
|
||||
value.charAt(0) == '\"' && value.charAt(value.length() - 1) == '\"') {
|
||||
return value.substring(1, value.length() - 1);
|
||||
@@ -3727,19 +4166,35 @@ public class Expression {
|
||||
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 if (jsonElement instanceof JsonNull) {
|
||||
arguments.add(new Expression.ExpressionLiteral(""));
|
||||
} else {
|
||||
throw new RuntimeException("Unsupported expression conversion for " + jsonElement.getClass());
|
||||
}
|
||||
arguments.add(convert(jsonElement));
|
||||
}
|
||||
return new Expression(operator, arguments.toArray(new Expression[arguments.size()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a JsonElement to an expression
|
||||
*
|
||||
* @param jsonElement the json element to convert
|
||||
* @return the expression
|
||||
*/
|
||||
private static Expression convert(@NonNull JsonElement jsonElement) {
|
||||
if (jsonElement instanceof JsonArray) {
|
||||
return convert((JsonArray) jsonElement);
|
||||
} else if (jsonElement instanceof JsonPrimitive) {
|
||||
return convert((JsonPrimitive) jsonElement);
|
||||
} else if (jsonElement instanceof JsonNull) {
|
||||
return new Expression.ExpressionLiteral("");
|
||||
} else if (jsonElement instanceof JsonObject) {
|
||||
Map<String, Expression> map = new HashMap<>();
|
||||
for (String key : ((JsonObject) jsonElement).keySet()) {
|
||||
map.put(key, convert(((JsonObject) jsonElement).get(key)));
|
||||
}
|
||||
return new ExpressionMap(map);
|
||||
} else {
|
||||
throw new RuntimeException("Unsupported expression conversion for " + jsonElement.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a JsonPrimitive to an expression literal
|
||||
*
|
||||
@@ -3815,6 +4270,79 @@ public class Expression {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an expression value stored in a Map.
|
||||
*/
|
||||
private static class ExpressionMap extends Expression implements ValueExpression {
|
||||
private Map<String, Expression> map;
|
||||
|
||||
ExpressionMap(Map<String, Expression> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toValue() {
|
||||
Map<String, Object> unwrappedMap = new HashMap<>();
|
||||
for (String key : map.keySet()) {
|
||||
Expression expression = map.get(key);
|
||||
if (expression instanceof Expression.ExpressionLiteral) {
|
||||
unwrappedMap.put(key, ((ExpressionLiteral) expression).toValue());
|
||||
} else {
|
||||
unwrappedMap.put(key, expression.toArray());
|
||||
}
|
||||
}
|
||||
|
||||
return unwrappedMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("{");
|
||||
for (String key : map.keySet()) {
|
||||
builder.append("\"").append(key).append("\": ");
|
||||
builder.append(map.get(key));
|
||||
builder.append(", ");
|
||||
}
|
||||
|
||||
if (map.size() > 0) {
|
||||
builder.delete(builder.length() - 2, builder.length());
|
||||
}
|
||||
|
||||
builder.append("}");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
ExpressionMap that = (ExpressionMap) o;
|
||||
return map.equals(that.map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + (map == null ? 0 : map.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface used to describe expressions that hold a Java value.
|
||||
*/
|
||||
private interface ValueExpression {
|
||||
Object toValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an object that is a primitive array to an Object[]
|
||||
*
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package com.mapbox.mapboxsdk.style.expressions;
|
||||
|
||||
import android.graphics.Color;
|
||||
|
||||
import com.mapbox.mapboxsdk.style.layers.PropertyFactory;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.abs;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.acos;
|
||||
@@ -19,6 +23,7 @@ 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.collator;
|
||||
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;
|
||||
@@ -60,6 +65,7 @@ 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.resolvedLocale;
|
||||
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;
|
||||
@@ -1290,4 +1296,75 @@ public class ExpressionTest {
|
||||
String alpha = color.substring(0, color.length() - 1);
|
||||
assertEquals("alpha value should match", 0.254f, Float.valueOf(alpha), 0.001f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCollator() {
|
||||
Object[] expected = new Object[] {"collator",
|
||||
new HashMap<String, Object>() {
|
||||
{
|
||||
put("case-sensitive", true);
|
||||
put("diacritic-sensitive", true);
|
||||
put("locale", "it-IT");
|
||||
}
|
||||
}
|
||||
};
|
||||
Object[] actual = collator(true, true, Locale.ITALY).toArray();
|
||||
assertTrue("expression should match", Arrays.deepEquals(expected, actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringCollator() {
|
||||
String expected = "[\"collator\", {\"diacritic-sensitive\": true, \"case-sensitive\": true, \"locale\": "
|
||||
+ "\"it\"}]";
|
||||
String actual = collator(true, true, Locale.ITALIAN).toString();
|
||||
assertEquals("expression should match", expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolvedLocale() {
|
||||
Object[] expected = new Object[] {"resolved-locale",
|
||||
new Object[] {"collator",
|
||||
new HashMap<String, Object>() {
|
||||
{
|
||||
put("case-sensitive", false);
|
||||
put("diacritic-sensitive", false);
|
||||
put("locale", "it");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Object[] actual = resolvedLocale(collator(false, false, Locale.ITALIAN)).toArray();
|
||||
assertTrue("expression should match", Arrays.deepEquals(expected, actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRawCollator() {
|
||||
Object[] expected = new Object[] {"collator",
|
||||
new HashMap<String, Object>() {
|
||||
{
|
||||
put("case-sensitive", true);
|
||||
put("diacritic-sensitive", true);
|
||||
put("locale", "it-IT");
|
||||
}
|
||||
}
|
||||
};
|
||||
Object[] actual = raw("[\"collator\", {\"diacritic-sensitive\": true, \"case-sensitive\": true, \"locale\": "
|
||||
+ "\"it-IT\"}]").toArray();
|
||||
assertTrue("expression should match", Arrays.deepEquals(expected, actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRawCollatorDoubleConversion() {
|
||||
Expression expected = collator(false, false, Locale.ITALIAN);
|
||||
Object[] actual = raw(expected.toString()).toArray();
|
||||
assertTrue("expression should match", Arrays.deepEquals(expected.toArray(), actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringNestedCollator() {
|
||||
String expected = "[\"collator\", {\"diacritic-sensitive\": [\"==\", 2.0, 1.0], \"case-sensitive\": false,"
|
||||
+ " \"locale\": \"it\"}]";
|
||||
String actual = collator(literal(false), eq(literal(2), literal(1)), literal("it")).toString();
|
||||
assertEquals("expression should match", expected, actual);
|
||||
}
|
||||
}
|
||||
@@ -2,20 +2,30 @@ package com.mapbox.mapboxsdk.testapp.style;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.mapbox.geojson.Point;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.style.expressions.Expression;
|
||||
import com.mapbox.mapboxsdk.style.layers.CircleLayer;
|
||||
import com.mapbox.mapboxsdk.style.layers.FillLayer;
|
||||
import com.mapbox.mapboxsdk.style.layers.Layer;
|
||||
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
|
||||
import com.mapbox.mapboxsdk.style.sources.Source;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
|
||||
import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.ResourceUtils;
|
||||
import com.mapbox.mapboxsdk.utils.ColorUtils;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import timber.log.Timber;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.collator;
|
||||
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.get;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.interpolate;
|
||||
@@ -26,13 +36,16 @@ import static com.mapbox.mapboxsdk.style.expressions.Expression.rgba;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.step;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.stop;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.string;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.switchCase;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.toColor;
|
||||
import static com.mapbox.mapboxsdk.style.expressions.Expression.zoom;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillAntialias;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillColor;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillOutlineColor;
|
||||
import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExpressionTest extends BaseActivityTest {
|
||||
@@ -204,6 +217,54 @@ public class ExpressionTest extends BaseActivityTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCollatorExpression() {
|
||||
validateTestSetup();
|
||||
setupStyle();
|
||||
invoke(mapboxMap, (uiController, mapboxMap) -> {
|
||||
LatLng latLng = new LatLng(51, 17);
|
||||
|
||||
Expression expression1 = eq(literal("Łukasz"), literal("lukasz"), collator(true, true));
|
||||
Expression expression2 = eq(literal("Łukasz"), literal("lukasz"), collator(literal(false), eq(literal(1),
|
||||
literal(1)), literal("en")));
|
||||
Expression expression3 = eq(literal("Łukasz"), literal("lukasz"), collator(literal(false), eq(literal(2),
|
||||
literal(1))));
|
||||
|
||||
mapboxMap.addSource(new GeoJsonSource("source", Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude())));
|
||||
Layer layer = new CircleLayer("layer", "source")
|
||||
.withProperties(circleColor(
|
||||
switchCase(
|
||||
expression1, literal(ColorUtils.colorToRgbaString(Color.GREEN)),
|
||||
literal(ColorUtils.colorToRgbaString(Color.RED))
|
||||
)
|
||||
));
|
||||
mapboxMap.addLayer(layer);
|
||||
uiController.loopMainThreadForAtLeast(1000);
|
||||
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
|
||||
.isEmpty());
|
||||
|
||||
layer.setProperties(circleColor(
|
||||
switchCase(
|
||||
expression2, literal(ColorUtils.colorToRgbaString(Color.GREEN)),
|
||||
literal(ColorUtils.colorToRgbaString(Color.RED))
|
||||
)
|
||||
));
|
||||
uiController.loopMainThreadForAtLeast(1000);
|
||||
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
|
||||
.isEmpty());
|
||||
|
||||
layer.setProperties(circleColor(
|
||||
switchCase(
|
||||
expression3, literal(ColorUtils.colorToRgbaString(Color.GREEN)),
|
||||
literal(ColorUtils.colorToRgbaString(Color.RED))
|
||||
)
|
||||
));
|
||||
uiController.loopMainThreadForAtLeast(1000);
|
||||
assertFalse(mapboxMap.queryRenderedFeatures(mapboxMap.getProjection().toScreenLocation(latLng), "layer")
|
||||
.isEmpty());
|
||||
});
|
||||
}
|
||||
|
||||
private void setupStyle() {
|
||||
invoke(mapboxMap, (uiController, mapboxMap) -> {
|
||||
// Add a source
|
||||
|
||||
Reference in New Issue
Block a user