diff --git a/platform/darwin/docs/guides/Predicates and Expressions.md b/platform/darwin/docs/guides/Predicates and Expressions.md index 6b191720b..b45434053 100644 --- a/platform/darwin/docs/guides/Predicates and Expressions.md +++ b/platform/darwin/docs/guides/Predicates and Expressions.md @@ -19,6 +19,8 @@ based on the feature’s attributes. Use the `MGLVectorStyleLayer.predicate` property to include only the features in the source layer that satisfy a condition that you define. +### Operators + The following comparison operators are supported: `NSPredicateOperatorType` | Format string syntax @@ -31,8 +33,10 @@ The following comparison operators are supported: `NSNotEqualToPredicateOperatorType` | `key != value`
`key <> value` `NSBetweenPredicateOperatorType` | `key BETWEEN { 32, 212 }` -The `key` may be cast explicitly into the key's type. Example: `CAST(key, 'NSNumber')` or -`CAST(key, 'NSString')` +To test whether a feature has or lacks a specific attribute, compare the +attribute to `NULL` or `NIL`. Predicates created using the +`+[NSPredicate predicateWithValue:]` method are also supported. String +operators and custom operators are not supported. The following compound operators are supported: @@ -49,82 +53,53 @@ The following aggregate operators are supported: `NSInPredicateOperatorType` | `key IN { 'iOS', 'macOS', 'tvOS', 'watchOS' }` `NSContainsPredicateOperatorType` | `{ 'iOS', 'macOS', 'tvOS', 'watchOS' } CONTAINS key` -To test whether a feature has or lacks a specific attribute, compare the -attribute to `NULL` or `NIL`. Predicates created using the -`+[NSPredicate predicateWithValue:]` method are also supported. String -operators and custom operators are not supported. +Operator modifiers such as `c` (for case insensitivity), `d` (for diacritic +insensitivity), and `l` (for locale sensitivity) are unsupported for comparison +and aggregate operators that are used in the predicate. + +### Operands + +Operands in predicates can be [variables](#variables), [key paths](#key-paths), +or almost anything else that can appear +[inside an expression](#using-expressions-to-configure-layout-and-paint-attributes). + +Automatic type casting is not performed. Therefore, a feature only matches a +predicate if its value for the attribute in question is of the same type as the +value specified in the predicate. Use the `CAST()` operator to convert a key +path or variable into a matching type: + +* To cast a value to a number, use `CAST(key, 'NSNumber')`. +* To cast a value to a string, use `CAST(key, 'NSString')`. For details about the predicate format string syntax, consult the “Predicate Format String Syntax” chapter of the _[Predicate Programming Guide](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html)_ in Apple developer documentation. -Either the predicate’s left-hand or right-hand expression can be an `NSString` -(to match strings) or `NSNumber` (to match numbers, including Boolean values) -or an array of `NSString`s or `NSNumber`s, depending on the operator and the -type of values expected for the attribute being tested or, alternatively, -one of the following special attributes: - - - - - - - - - - - - - - - - - - - -
AttributeMeaning
$featureIdentifier - A value that uniquely identifies the feature in the containing source. - For details on the types of values that may be associated with this key, - consult the documentation for the MGLFeature protocol’s - identifier property. -
$geometryType - The type of geometry represented by the feature. A feature’s type is - guaranteed to be one of the following strings: -
    -
  • - Point for point features, corresponding to the - MGLPointAnnotation class -
  • -
  • - LineString for polyline features, corresponding to - the MGLPolyline class -
  • -
  • - Polygon for polygon features, corresponding to the - MGLPolygon class -
  • -
-
point_countThe number of point features in a given cluster.
- -For floating-point values, use `-[NSNumber numberWithDouble:]` instead of -`-[NSNumber numberWithFloat:]` to avoid precision issues. - -Automatic type casting is not performed. Therefore, a feature only matches this -predicate if its value for the attribute in question is of the same type as the -value specified in the predicate. Also, operator modifiers such as `c` (for -case insensitivity), `d` (for diacritic insensitivity), and `l` (for locale -sensitivity) are unsupported for comparison and aggregate operators that are -used in the predicate. - -It is possible to create expressions that contain special characters in the -predicate format syntax. This includes the `$` in the `$featureIdentifier` and -`$geometryType` special style attributes and also `hyphen-minus` and `tag:subtag`. -However, you must use `%@` in the format string to represent these variables: -`@"$geometryType == 'LineString'"`. - ## Using expressions to configure layout and paint attributes +An expression can contain subexpressions of various types. Each of the supported +types of expressions is discussed below. + +### Constant values + +A constant value can be of any of the following types: + +In Objective-C | In Swift +----------------------|--------- +`NSColor` (macOS)
`UIColor` (iOS) | `NSColor` (macOS)
`UIColor` (iOS) +`NSString` | `String` +`NSString` | `String` +`NSNumber.boolValue` | `NSNumber.boolValue` +`NSNumber.doubleValue` | `NSNumber.doubleValue` +`NSArray` | `[Float]` +`NSArray` | `[String]` +`NSValue.CGVectorValue` (iOS)
`NSValue` containing `CGVector` (macOS) | `NSValue.cgVectorValue` (iOS)
`NSValue` containing `CGVector` (macOS) +`NSValue.UIEdgeInsetsValue` (iOS)
`NSValue.edgeInsetsValue` (macOS) | `NSValue.uiEdgeInsetsValue` (iOS)
`NSValue.edgeInsetsValue` (macOS) + +For literal floating-point values, use `-[NSNumber numberWithDouble:]` instead +of `-[NSNumber numberWithFloat:]` to avoid precision issues. + ### Key paths A key path expression refers to an attribute of the `MGLFeature` object being @@ -133,10 +108,46 @@ dictionary contains the `floorCount` key, then the key path `floorCount` refers to the value of the `floorCount` attribute when evaluating that particular polygon. -### Predefined functions +The following special attribute is also available on features that are produced +as a result of clustering multiple point features together in a shape source: + + + + + + + + + + + + +
AttributeTypeMeaning
point_countNumberThe number of point features in a given cluster.
+ +Some characters may not be used directly as part of a key path in a format +string. For example, if a feature’s attribute is named `ISO 3166-1:2006`, an +expression format string of `lowercase(ISO 3166-1:2006)` or a predicate format +string of `ISO 3166-1:2006 == 'US-OH'` would raise an exception. Instead, use a +`%K` placeholder or the `+[NSExpression expressionForKeyPath:]` initializer: + +```objc +[NSPredicate predicateWithFormat:@"%K == 'US-OH'", @"ISO 3166-1:2006"]; +[NSExpression expressionForFunction:@"lowercase:" + arguments:@[[NSExpression expressionForKeyPath:@"ISO 3166-1:2006"]]] +``` + +```swift +NSPredicate(format: "%K == 'US-OH'", "ISO 3166-1:2006") +NSExpression(forFunction: "lowercase:", + arguments: [NSExpression(forKeyPath: "ISO 3166-1:2006")]) +``` + +### Functions Of the -[functions predefined by the `+[NSExpression expressionForFunction:arguments:]` method](https://developer.apple.com/documentation/foundation/nsexpression/1413747-init#discussion), +[functions predefined](https://developer.apple.com/documentation/foundation/nsexpression/1413747-init#discussion) +by the +[`+[NSExpression expressionForFunction:arguments:]` method](https://developer.apple.com/documentation/foundation/nsexpression/1413747-init), the following subset is supported in layer attribute values: Initializer parameter | Format string syntax @@ -166,7 +177,10 @@ Initializer parameter | Format string syntax `length:` | `length('Wapakoneta')` `castObject:toType:` | `CAST(ele, 'NSString')`
`CAST(ele, 'NSNumber')` -The following predefined functions are not supported: +A number of [Mapbox-specific functions](#mapbox-specific-functions) are also +available. + +The following predefined functions are **not** supported: Initializer parameter | Format string syntax ----------------------|--------------------- @@ -184,220 +198,19 @@ Initializer parameter | Format string syntax `onesComplement:` | `onesComplement(255)` `distanceToLocation:fromLocation:` | `distanceToLocation:fromLocation:(there, here)` -### Mapbox-specific functions +### Conditionals -For compatibility with the Mapbox Style Specification, the following functions -are defined by this SDK. When setting a style layer property, you can call these -functions just like the predefined functions above, using either the -`+[NSExpression expressionForFunction:arguments:]` method or a convenient format -string syntax: +Conditionals are supported via the built-in +`+[NSExpression expressionForConditional:trueExpression:falseExpression:]` +method and `TERNARY()` operator. If you need to express multiple cases +(“else-if”), you can either nest a conditional within a conditional or use the +[`MGL_IF()`](#code-mgl_if-code) or [`MGL_MATCH()`](#code-mgl_match-code) function. -Initializer parameter | Format string syntax | Description -----------------------|----------------------|------------ -`mgl_does:have:` | `mgl_does:have:(SELF, 'key')` or `mgl_does:have:(%@, 'key')` | Returns a Boolean value indicating whether the dictionary has a value for the key or whether the evaluated object (`SELF`) has a value for the feature attribute. Compared to the `mgl_has:` custom function, that function’s target is instead passed in as the first argument to this function. Both functions are equivalent to the syntax `key != NIL` or `%@[key] != NIL` but can be used outside of a predicate. -`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. -`MGL_IF` | `MGL_IF(1 = 2, YES, 2 = 2, YES, NO)` | Returns the first value that meets the condition otherwise a default value. The expression conditions should be added in pairs of conditional/return value. Unlike `+[NSExpression expressionForConditional:trueExpression:falseExpression:]` or the `TERNARY()` syntax, this function can accept multiple “if else” conditions and is supported on iOS 8._x_ and macOS 10.10._x_; however, each conditional passed into this function must be wrapped in a constant expression. +### Aggregates -The following custom functions are also available with the -`+[NSExpression expressionForFunction:selectorName:arguments:]` method or the -`FUNCTION()` format string syntax: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Selector nameTargetArgumentsReturns
boolValue - An NSExpression that evaluates to a number or string. - - A Boolean representation of the target: FALSE when then input is an - empty string, 0, FALSE, NIL, or NaN, otherwise TRUE. -
mgl_has: - An NSExpression that evaluates to an NSDictionary or the evaluated object (SELF). - - An NSExpression that evaluates to an NSString representing the key to look up in the dictionary or the feature attribute to look up in the evaluated object (see MGLFeature.attributes). - - true if the dictionary has a value for the key or if the evaluated object has a value for the feature attribute. -
mgl_expressionWithContext: - An NSExpression that may contain references to the variables defined in - the context dictionary. - - An NSDictionary with NSStrings as keys and NSExpressions as values. - Each key is a variable name and each value is the variable’s value within - the target expression. - - The target expression with variable subexpressions replaced with the - values defined in the context dictionary. -
mgl_interpolateWithCurveType:parameters:stops: - An NSExpression that evaluates to a number and contains a variable or - key path expression. - - The first argument is one of the following strings denoting curve types: - linear, exponential, or cubic-bezier. - - The second argument is an expression providing parameters for the curve: - -
    -
  • If the curve type is linear, the argument is NIL.
  • -
  • - If the curve type is exponential, the argument is an expression - that evaluates to a number, specifying the base of the exponential - interpolation. -
  • -
  • - If the curve type is cubic-bezier, the argument is an array or - aggregate expression containing four expressions, each evaluating to - a number. The four numbers are control points for the cubic Bézier - curve. -
  • -
- - The third argument is an NSDictionary object representing the - interpolation’s stops, with numeric zoom levels as keys and expressions as - values. -
- A value interpolated along the continuous mathematical function defined by - the arguments, with the target as the input to the function. -
- mgl_numberWithFallbackValues:, - doubleValue, - floatValue, - decimalValue - - An NSExpression that evaluates to a Boolean value, number, or string. - - Zero or more NSExpressions, each evaluating to a Boolean value or - string. - - A numeric representation of the target: -
    -
  • If the target is NIL or FALSE, the result is 0.
  • -
  • If the target is true, the result is 1.
  • -
  • - If the target is a string, it is converted to a number as specified - by the - “ToNumber Applied to the String Type” - algorithm of the ECMAScript Language Specification. -
  • -
  • - If multiple values are provided, each one is evaluated in order - until the first successful conversion is obtained. -
  • -
-
mgl_stepWithMinimum:stops: - An NSExpression that evaluates to a number and contains a variable or - key path expression. - - The first argument is an expression that evaluates to a number, specifying - the minimum value in case the target is less than any of the stops in the - second argument. - - The second argument is an NSDictionary object representing the - interpolation’s stops, with numeric zoom levels as keys and expressions as - values. - - The output value of the stop whose key is just less than the evaluated - target, or the minimum value if the target is less than the least of the - stops’ keys. -
stringByAppendingString: - An NSExpression that evaluates to a string. - - One or more NSExpressions, each evaluating to a string. - - The target string with each of the argument strings appended in order. -
stringValue - An NSExpression that evaluates to a Boolean value, number, or string. - - A string representation of the target: -
    -
  • If the target is NIL, the result is the string null.
  • -
  • - If the target is a Boolean value, the result is the string true or - false. -
  • -
  • - If the target is a number, it is converted to a string as specified - by the - “NumberToString” - algorithm of the ECMAScript Language Specification. -
  • -
  • - If the target is a color, it is converted to a string of the form - rgba(r,g,b,a), where r, g, and b - are numerals ranging from 0 to 255 and a ranges from 0 to - 1. -
  • -
  • - Otherwise, the target is converted to a string in the format - specified by the - JSON.stringify() - function of the ECMAScript Language Specification. -
  • -
-
- -Some of these functions are defined as methods on their respective target -classes, but you should not call them directly outside the context of an -expression, because the result may differ from the evaluated expression’s result -or may result in undefined behavior. - -The Mapbox Style Specification defines some operators for which no custom -function is available. To use these operators in an `NSExpression`, call the -`MGL_FUNCTION()` function with the same arguments that the operator expects. +Aggregate expressions can contain arrays of expressions. In some cases, it is +possible to use the array itself instead of wrapping the array in an aggregate +expression. ### Variables @@ -408,6 +221,42 @@ The following variables are defined by this SDK for use with style layers: VariableTypeMeaning + + $featureIdentifier + + Any + GeoJSON data type + + + A value that uniquely identifies the feature in the containing source. + This variable corresponds to the + NSExpression.featureIdentifierVariableExpression property. + + + + $geometryType + String + + The type of geometry represented by the feature. A feature’s type is one + of the following strings: + + This variable corresponds to the + NSExpression.geometryTypeVariableExpression property. + + $heatmapDensity Number @@ -417,6 +266,8 @@ The following variables are defined by this SDK for use with style layers: of a screen point in a heatmap layer; in other words, a relative measure of how many data points are crowded around a particular pixel. This variable can only be used with the heatmapColor property. + This variable corresponds to the + NSExpression.heatmapDensityVariableExpression property. @@ -425,7 +276,8 @@ The following variables are defined by this SDK for use with style layers: The current zoom level. In style layout and paint properties, this variable may only appear as the target of a top-level interpolation or - step expression. + step expression. This variable corresponds to the + NSExpression.zoomLevelVariableExpression property. @@ -443,3 +295,595 @@ of a [Mapbox-specific function](#mapbox-specific-functions) that takes an ```swift NSExpression(format: "MGL_LET(floorCount, 2, $floorCount + 1)") ``` + +## Mapbox-specific functions + +For compatibility with the Mapbox Style Specification, the following functions +are defined by this SDK. When setting a style layer property, you can call these +functions just like the predefined functions above, using either the +`+[NSExpression expressionForFunction:arguments:]` method or a convenient format +string syntax: + +### `mgl_does:have:` + +
+
Selector:
+
mgl_does:have:
+
Format string syntax:
+
mgl_does:have:(SELF, '🧀🍔') or mgl_does:have:(%@, '🧀🍔')
+
+ +Returns a Boolean value indicating whether the dictionary has a value for the +key or whether the evaluated object (`SELF`) has a value for the feature +attribute. Compared to the [`mgl_has:`](#code-mgl_has-code) custom function, +that function’s target is instead passed in as the first argument to this +function. Both functions are equivalent to the syntax `key != NIL` or +`%@[key] != NIL` but can be used outside of a predicate. + +### `mgl_interpolate:withCurveType:parameters:stops:` + +
+
Selector:
+
mgl_interpolate:withCurveType:parameters:stops:
+
Format string syntax:
+
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:`](#code-mgl_interpolatewithcurvetype-parameters-stops-code) +custom function, the input expression (that function’s target) is instead passed +in as the first argument to this function. + +### `mgl_step:from:stops:` + +
+
Selector:
+
mgl_step:from:stops:
+
Format string syntax:
+
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:`](#code-mgl_stepwithminimum-stops-code) custom +function, the input expression (that function’s target) is instead passed in as +the first argument to this function. + +### `mgl_join:` + +
+
Selector:
+
mgl_join:
+
Format string syntax:
+
mgl_join({'Old', 'MacDonald'})
+
+ +Returns the result of concatenating together all the elements of an array in +order. Compared to the +[`stringByAppendingString:`](#code-stringbyappendingstring-code) custom +function, this function takes only one argument, which is an aggregate +expression containing the strings to concatenate. + +### `mgl_acos:` + +
+
Selector:
+
mgl_acos:
+
Format string syntax:
+
mgl_acos(1)
+
+ +Returns the arccosine of the number. + +This function corresponds to the +[`acos`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-acos) +operator in the Mapbox Style Specification. + +### `mgl_asin:` + +
+
Selector:
+
mgl_asin:
+
Format string syntax:
+
mgl_asin(0)
+
+ +Returns the arcsine of the number. + +This function corresponds to the +[`asin`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-asin) +operator in the Mapbox Style Specification. + +### `mgl_atan:` + +
+
Selector:
+
mgl_atan:
+
Format string syntax:
+
mgl_atan(20)
+
+ +Returns the arctangent of the number. + +This function corresponds to the +[`atan`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-atan) +operator in the Mapbox Style Specification. + +### `mgl_cos:` + +
+
Selector:
+
mgl_cos:
+
Format string syntax:
+
mgl_cos(0)
+
+ +Returns the cosine of the number. + +This function corresponds to the +[`cos`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-cos) +operator in the Mapbox Style Specification. + +### `mgl_log2:` + +
+
Selector:
+
mgl_log2:
+
Format string syntax:
+
mgl_log2(1024)
+
+ +Returns the base-2 logarithm of the number. + +This function corresponds to the +[`log2`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-log2) +operator in the Mapbox Style Specification. + +### `mgl_round:` + +
+
Selector:
+
mgl_round:
+
Format string syntax:
+
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. + +This function corresponds to the +[`round`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-round) +operator in the Mapbox Style Specification. + +### `mgl_sin:` + +
+
Selector:
+
mgl_sin:
+
Format string syntax:
+
mgl_sin(0)
+
+ +Returns the sine of the number. + +This function corresponds to the +[`sin`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-sin) +operator in the Mapbox Style Specification. + +### `mgl_tan:` + +
+
Selector:
+
mgl_tan:
+
Format string syntax:
+
mgl_tan(0)
+
+ +Returns the tangent of the number. + +This function corresponds to the +[`tan`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-tan) +operator in the Mapbox Style Specification. + +### `mgl_coalesce:` + +
+
Selector:
+
mgl_coalesce:
+
Format string syntax:
+
mgl_coalesce({x, y, z})
+
+ +Returns the first non-`nil` value from an array of expressions. + +This function corresponds to the +[`coalesce`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-coalesce) +operator in the Mapbox Style Specification. + +### `MGL_LET` + +
+
Selector:
+
MGL_LET:
+
Format string syntax:
+
MGL_LET('age', uppercase('old'), 'name', uppercase('MacDonald'), mgl_join({$age, $name}))
+
Arguments:
+
+ Any number of variable names interspersed with their assigned + NSExpression values, followed by an NSExpression + that may contain references to those variables. +
+
+ +Returns the result of evaluating an expression with the given variable values. +Compared to the +[`mgl_expressionWithContext:`](#code-mgl_expressionwithcontext-code) custom +function, this function takes the variable names and values inline before the +expression that contains references to those variables. + +### `MGL_MATCH` + +
+
Selector:
+
MGL_MATCH:
+
Format string syntax:
+
MGL_MATCH(x, 0, 'zero match', 1, 'one match', 'two match', 'default')
+
Arguments:
+
+ An input expression, then any number of argument pairs, followed by a default + expression. Each argument pair consists of a constant value followed by an + expression to produce as a result of matching that constant value. +
+
+ +Returns the result of matching the input expression against the given constant +values. + +This function corresponds to the +`+[NSExpression(MGLAdditions) mgl_expressionForMatchingExpression:inDictionary:defaultExpression:]` +method and the +[`match`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-match) +operator in the Mapbox Style Specification. + +### `MGL_IF` + +
+
Selector:
+
MGL_IF:
+
Format string syntax:
+
MGL_IF(1 = 2, YES, 2 = 2, YES, NO)
+
Arguments:
+
+ Alternating NSPredicate conditionals and resulting expressions, + followed by a default expression. +
+
+ +Returns the first expression that meets the condition; otherwise, the default +value. Unlike +`+[NSExpression expressionForConditional:trueExpression:falseExpression:]` or +the `TERNARY()` syntax, this function can accept multiple “if else” conditions +and is supported on iOS 8._x_ and macOS 10.10._x_; however, each conditional +passed into this function must be wrapped in a constant expression. + +This function corresponds to the +`+[NSExpression(MGLAdditions) mgl_expressionForConditional:trueExpression:falseExpresssion:]` +method and the +[`case`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-case) +operator in the Mapbox Style Specification. + +### `MGL_FUNCTION` + +
+
Selector:
+
MGL_FUNCTION:
+
Format string syntax:
+
MGL_FUNCTION('typeof', mystery)
+
Arguments:
+
+ Any arguments required by the expression operator. +
+
+ +An expression exactly as defined by the +[Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions). + +## Custom functions + +The following custom functions are also available with the +`+[NSExpression expressionForFunction:selectorName:arguments:]` method or the +`FUNCTION()` format string syntax. + +Some of these functions are defined as methods on their respective target +classes, but you should not call them directly outside the context of an +expression, because the result may differ from the evaluated expression’s result +or may result in undefined behavior. + +The Mapbox Style Specification defines some operators for which no custom +function is available. To use these operators in an `NSExpression`, call the +[`MGL_FUNCTION()`](#code-mgl_function-code) function with the same arguments +that the operator expects. + +### `boolValue` + +
+
Selector:
+
boolValue
+
Format string syntax:
+
FUNCTION(1, 'boolValue')
+
Target:
+
+ An NSExpression that evaluates to a number or string. +
+
Arguments:
+
None.
+
+ +A Boolean representation of the target: FALSE when then input is an +empty string, 0, FALSE, NIL, or NaN, +otherwise TRUE. + +### `mgl_has:` + +
+
Selector:
+
mgl_has:
+
Format string syntax:
+
FUNCTION($featureProperties, 'mgl_has:', '🧀🍔')
+
Target:
+
+ An NSExpression that evaluates to an NSDictionary + or the evaluated object (SELF). +
+
Arguments:
+
+ An NSExpression that evaluates to an NSString + representing the key to look up in the dictionary or the feature attribute to + look up in the evaluated object (see MGLFeature.attributes). +
+
+ +true if the dictionary has a value for the key or if the evaluated +object has a value for the feature attribute. + +This function corresponds to the +[`has`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-has) +operator in the Mapbox Style Specification. See also the +[`mgl_does:have:`](#code-mgl_does-have-code) function, which is used on its own +without the `FUNCTION()` operator. You can also check whether an object has an +attribute by comparing the key path to `NIL`, for example `cheeseburger != NIL` +or `burger.cheese != NIL` + +### `mgl_expressionWithContext:` + +
+
Selector:
+
mgl_expressionWithContext:
+
Format string syntax:
+
+ FUNCTION($ios + $macos, 'mgl_expressionWithContext:', %@) with + a dictionary containing ios and macos keys +
+
Target:
+
+ An NSExpression that may contain references to the variables + defined in the context dictionary. +
+
Arguments:
+
+ An NSDictionary with NSStrings as keys and + NSExpressions as values. Each key is a variable name and each + value is the variable’s value within the target expression. +
+
+ +The target expression with variable subexpressions replaced with the values +defined in the context dictionary. + +This function corresponds to the +[`let`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-let) +operator in the Mapbox Style Specification. See also the +[`MGL_LET`](#code-mgl_let-code) function, which is used on its own without the +`FUNCTION()` operator. + +### `mgl_interpolateWithCurveType:parameters:stops:` + +
+
Selector:
+
mgl_interpolateWithCurveType:parameters:stops:
+
Format string syntax:
+
+ FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', NIL, %@) + with a dictionary containing zoom levels or other constant values as keys +
+
Target:
+
+ An NSExpression that evaluates to a number and contains a + variable or key path expression. +
+
Arguments:
+
+ The first argument is one of the following strings denoting curve types: + linear, exponential, or cubic-bezier. + + The second argument is an expression providing parameters for the curve: + +
    +
  • If the curve type is linear, the argument is NIL.
  • +
  • + If the curve type is exponential, the argument is an + expression that evaluates to a number, specifying the base of the + exponential interpolation. +
  • +
  • + If the curve type is cubic-bezier, the argument is an + array or aggregate expression containing four expressions, each + evaluating to a number. The four numbers are control points for the + cubic Bézier curve. +
  • +
+ + The third argument is an NSDictionary object representing the + interpolation’s stops, with numeric zoom levels as keys and expressions as + values. +
+
+ +A value interpolated along the continuous mathematical function defined by the +arguments, with the target as the input to the function. + +The input expression is matched against the keys in the stop dictionary. The +keys may be feature attribute values, zoom levels, or heatmap densities. The +values may be constant values or `NSExpression` objects. For example, you can +use a stop dictionary with the zoom levels 0, 10, and 20 as keys and the colors +yellow, orange, and red as the values. + +This function corresponds to the +`+[NSExpression(MGLAdditions) mgl_expressionForInterpolatingExpression:withCurveType:parameters:stops:]` +method and the +[`interpolate`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-interpolate) +operator in the Mapbox Style Specification. See also the +[`mgl_interpolate:withCurveType:parameters:stops:`](#code-mgl_interpolate-withcurvetype-parameters-stops-code) +function, which is used on its own without the `FUNCTION()` operator. + +### `mgl_numberWithFallbackValues:` + +
+
Selector:
+
+ mgl_numberWithFallbackValues:, + doubleValue, + floatValue, or + decimalValue +
+
Format string syntax:
+
FUNCTION(ele, 'mgl_numberWithFallbackValues:', 0)
+
Target:
+
+ An NSExpression that evaluates to a Boolean value, number, or + string. +
+
Arguments:
+
+ Zero or more NSExpressions, each evaluating to a Boolean value + or string. +
+
+ +A numeric representation of the target: + +* If the target is NIL or FALSE, the result is 0. +* If the target is true, the result is 1. + * If the target is a string, it is converted to a number as specified by the + “[ToNumber Applied to the String Type](https://tc39.github.io/ecma262/#sec-tonumber-applied-to-the-string-type)” + algorithm of the ECMAScript Language Specification. + * If multiple values are provided, each one is evaluated in order until the + first successful conversion is obtained. + +This function corresponds to the +[`to-number`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-types-to-number) +operator in the Mapbox Style Specification. You can also cast a value to a +number by passing the value and the string `NSNumber` into the `CAST()` +operator. + +### `mgl_stepWithMinimum:stops:` + +
+
Selector:
+
mgl_stepWithMinimum:stops:
+
Format string syntax:
+
+ FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', 0, %@) with + a dictionary with zoom levels or other constant values as keys +
+
Target:
+
+ An NSExpression that evaluates to a number and contains a + variable or key path expression. +
+
Arguments:
+
+ The first argument is an expression that evaluates to a number, specifying + the minimum value in case the target is less than any of the stops in the + second argument. + + The second argument is an NSDictionary object representing the + interpolation’s stops, with numeric zoom levels as keys and expressions as + values. +
+
+ +The output value of the stop whose key is just less than the evaluated target, +or the minimum value if the target is less than the least of the stops’ keys. + +The input expression is matched against the keys in the stop dictionary. The +keys may be feature attribute values, zoom levels, or heatmap densities. The +values may be constant values or `NSExpression` objects. For example, you can +use a stop dictionary with the zoom levels 0, 10, and 20 as keys and the colors +yellow, orange, and red as the values. + +This function corresponds to the +`+[NSExpression(MGLAdditions) mgl_expressionForSteppingExpression:fromExpression:stops:]` +method and the +[`step`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-step) +operator in the Mapbox Style Specification. + +### `stringByAppendingString:` + +
+
Selector:
+
stringByAppendingString:
+
Format string syntax:
+
FUNCTION('Old', 'stringByAppendingString:', 'MacDonald')
+
Target:
+
An NSExpression that evaluates to a string.
+
Arguments:
+
One or more NSExpressions, each evaluating to a string.
+
+ +The target string with each of the argument strings appended in order. + +This function corresponds to the +`-[NSExpression(MGLAdditions) mgl_expressionByAppendingExpression:]` +method and is similar to the +[`concat`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-concat) +operator in the Mapbox Style Specification. See also the +[`mgl_join:`](#code-mgl_join-code) function, which concatenates multiple +expressions and is used on its own without the `FUNCTION()` operator. + +### `stringValue` + +
+
Selector:
+
stringValue
+
Format string syntax:
+
FUNCTION(ele, 'stringValue')
+
Target:
+
+ An NSExpression that evaluates to a Boolean value, number, or + string. +
+
Arguments:
+
None.
+
+ +A string representation of the target: + +* If the target is NIL, the result is the empty string. +* If the target is a Boolean value, the result is the string `true` or `false`. +* If the target is a number, it is converted to a string as specified by the + “[NumberToString](https://tc39.github.io/ecma262/#sec-tostring-applied-to-the-number-type)” + algorithm of the ECMAScript Language Specification. +* If the target is a color, it is converted to a string of the form + `rgba(r,g,b,a)`, where r, g, and b are + numerals ranging from 0 to 255 and a ranges from 0 to 1. +* Otherwise, the target is converted to a string in the format specified by the + [`JSON.stringify()`](https://tc39.github.io/ecma262/#sec-json.stringify) + function of the ECMAScript Language Specification. + +This function corresponds to the +[`to-string`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-types-to-string) +operator in the Mapbox Style Specification. You can also cast a value to a +string by passing the value and the string `NSString` into the `CAST()` +operator. diff --git a/platform/darwin/docs/theme/assets/css/jazzy.css.scss b/platform/darwin/docs/theme/assets/css/jazzy.css.scss index ad0a3b708..ff6d2a374 100644 --- a/platform/darwin/docs/theme/assets/css/jazzy.css.scss +++ b/platform/darwin/docs/theme/assets/css/jazzy.css.scss @@ -113,7 +113,12 @@ h2 { } h3 { - @include heading(14px, 1em 0 0.3em); + @include heading(1.2rem, 1em 0 0.3em); +} + +h3 > code { + font-weight: bold; + font-size: 1.2rem; } h4 { diff --git a/platform/darwin/src/NSExpression+MGLAdditions.h b/platform/darwin/src/NSExpression+MGLAdditions.h index 39a841543..64cbe9741 100644 --- a/platform/darwin/src/NSExpression+MGLAdditions.h +++ b/platform/darwin/src/NSExpression+MGLAdditions.h @@ -16,7 +16,7 @@ typedef NSString *MGLExpressionInterpolationMode NS_TYPED_ENUM; This attribute corresponds to the `linear` value in the interpolate - expression reference in the Mapbox Style Specification. + expression operator in the Mapbox Style Specification. */ extern MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionInterpolationModeLinear; @@ -25,7 +25,7 @@ extern MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionInterpolatio This attribute corresponds to the `exponential` value in the interpolate - expression reference in the Mapbox Style Specification. + expression operator in the Mapbox Style Specification. */ extern MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionInterpolationModeExponential; @@ -34,50 +34,55 @@ extern MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionInterpolatio This attribute corresponds to the `cubic-bezier` value in the interpolate - expression reference in the Mapbox Style Specification. + expression operator in the Mapbox Style Specification. */ extern MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier; -@interface NSExpression (MGLVariableAdditions) +/** + Methods for creating expressions that use Mapbox-specific functionality and for + converting to and from the JSON format defined in the + Mapbox Style Specification. + */ +@interface NSExpression (MGLAdditions) + +#pragma mark Creating Variable Expressions /** `NSExpression` variable that corresponds to the zoom - expression reference in the Mapbox Style Specification. + expression operator in the Mapbox Style Specification. */ @property (class, nonatomic, readonly) NSExpression *zoomLevelVariableExpression; /** `NSExpression` variable that corresponds to the heatmap-density - expression reference in the Mapbox Style Specification. + expression operator in the Mapbox Style Specification. */ @property (class, nonatomic, readonly) NSExpression *heatmapDensityVariableExpression; /** `NSExpression` variable that corresponds to the geometry-type - expression reference in the Mapbox Style Specification. + expression operator in the Mapbox Style Specification. */ @property (class, nonatomic, readonly) NSExpression *geometryTypeVariableExpression; /** `NSExpression` variable that corresponds to the id - expression reference in the Mapbox Style Specification. + expression operator in the Mapbox Style Specification. */ @property (class, nonatomic, readonly) NSExpression *featureIdentifierVariableExpression; /** `NSExpression` variable that corresponds to the properties - expression reference in the Mapbox Style Specification. + expression operator in the Mapbox Style Specification. */ @property (class, nonatomic, readonly) NSExpression *featurePropertiesVariableExpression; -@end - -@interface NSExpression (MGLInitializerAdditions) +#pragma mark Creating Conditional Expressions /** Returns a conditional function expression specifying the string predicate, and @@ -89,6 +94,8 @@ extern MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionInterpolatio */ + (instancetype)mgl_expressionForConditional:(nonnull NSPredicate *)conditionPredicate trueExpression:(nonnull NSExpression *)trueExpression falseExpresssion:(nonnull NSExpression *)falseExpression NS_SWIFT_NAME(init(forMGLConditional:trueExpression:falseExpression:)); +#pragma mark Creating Ramp, Scale, and Curve Expressions + /** Returns a step function expression specifying the stepping, from expression and stops. @@ -121,6 +128,9 @@ extern MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionInterpolatio @param defaultExpression The defaultValue expression to be used in case there is no match. */ + (instancetype)mgl_expressionForMatchingExpression:(nonnull NSExpression *)inputExpression inDictionary:(nonnull NSDictionary *)matchedExpressions defaultExpression:(nonnull NSExpression *)defaultExpression NS_SWIFT_NAME(init(forMGLMatchingKey:in:default:)); + +#pragma mark Concatenating String Expressions + /** Returns a constant expression appending the passed expression. @@ -131,9 +141,7 @@ extern MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionInterpolatio */ - (instancetype)mgl_expressionByAppendingExpression:(nonnull NSExpression *)expression NS_SWIFT_NAME(mgl_appending(_:)); -@end - -@interface NSExpression (MGLAdditions) +#pragma mark Converting JSON Expressions /** Returns an expression equivalent to the given Foundation object deserialized @@ -168,6 +176,8 @@ extern MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionInterpolatio */ @property (nonatomic, readonly) id mgl_jsonExpressionObject; +#pragma mark Localizing the Expression + /** Returns a copy of the receiver localized into the given locale. diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm index 46a463430..df7e3e98f 100644 --- a/platform/darwin/src/NSExpression+MGLAdditions.mm +++ b/platform/darwin/src/NSExpression+MGLAdditions.mm @@ -621,7 +621,24 @@ NS_DICTIONARY_OF(NSNumber *, NSExpression *) *MGLStopDictionaryByReplacingTokens } @end -@implementation NSExpression (MGLVariableAdditions) + +@implementation NSExpression (MGLExpressionAdditions) + +- (NSExpression *)mgl_expressionWithContext:(NSDictionary *)context { + [NSException raise:NSInternalInconsistencyException + format:@"Assignment expressions lack underlying Objective-C implementations."]; + return self; +} + +- (id)mgl_has:(id)element { + [NSException raise:NSInvalidArgumentException + format:@"Has expressions lack underlying Objective-C implementations."]; + return nil; +} + +@end + +@implementation NSExpression (MGLAdditions) + (NSExpression *)zoomLevelVariableExpression { return [NSExpression expressionForVariable:@"zoomLevel"]; @@ -643,10 +660,6 @@ NS_DICTIONARY_OF(NSNumber *, NSExpression *) *MGLStopDictionaryByReplacingTokens return [NSExpression expressionForVariable:@"featureProperties"]; } -@end - -@implementation NSExpression (MGLInitializerAdditions) - + (instancetype)mgl_expressionForConditional:(nonnull NSPredicate *)conditionPredicate trueExpression:(nonnull NSExpression *)trueExpression falseExpresssion:(nonnull NSExpression *)falseExpression { if (@available(iOS 9.0, *)) { return [NSExpression expressionForConditional:conditionPredicate trueExpression:trueExpression falseExpression:falseExpression]; @@ -655,12 +668,12 @@ NS_DICTIONARY_OF(NSNumber *, NSExpression *) *MGLStopDictionaryByReplacingTokens } } -+ (instancetype)mgl_expressionForSteppingExpression:(nonnull NSExpression*)steppingExpression fromExpression:(nonnull NSExpression *)minimumExpression stops:(nonnull NSExpression*)stops { ++ (instancetype)mgl_expressionForSteppingExpression:(nonnull NSExpression *)steppingExpression fromExpression:(nonnull NSExpression *)minimumExpression stops:(nonnull NSExpression *)stops { return [NSExpression expressionForFunction:@"mgl_step:from:stops:" arguments:@[steppingExpression, minimumExpression, stops]]; } -+ (instancetype)mgl_expressionForInterpolatingExpression:(nonnull NSExpression*)inputExpression withCurveType:(nonnull MGLExpressionInterpolationMode)curveType parameters:(nullable NSExpression *)parameters stops:(nonnull NSExpression*)stops { ++ (instancetype)mgl_expressionForInterpolatingExpression:(nonnull NSExpression *)inputExpression withCurveType:(nonnull MGLExpressionInterpolationMode)curveType parameters:(nullable NSExpression *)parameters stops:(nonnull NSExpression *)stops { NSExpression *sanitizeParams = parameters ? parameters : [NSExpression expressionForConstantValue:nil]; return [NSExpression expressionForFunction:@"mgl_interpolate:withCurveType:parameters:stops:" arguments:@[inputExpression, [NSExpression expressionForConstantValue:curveType], sanitizeParams, stops]]; @@ -685,26 +698,6 @@ NS_DICTIONARY_OF(NSNumber *, NSExpression *) *MGLStopDictionaryByReplacingTokens return [NSExpression expressionForFunction:@"mgl_join:" arguments:@[subexpression]]; } -@end - -@implementation NSExpression (MGLExpressionAdditions) - -- (NSExpression *)mgl_expressionWithContext:(NSDictionary *)context { - [NSException raise:NSInternalInconsistencyException - format:@"Assignment expressions lack underlying Objective-C implementations."]; - return self; -} - -- (id)mgl_has:(id)element { - [NSException raise:NSInvalidArgumentException - format:@"Has expressions lack underlying Objective-C implementations."]; - return nil; -} - -@end - -@implementation NSExpression (MGLAdditions) - static NSDictionary *MGLFunctionNamesByExpressionOperator; static NSDictionary *MGLExpressionOperatorsByFunctionNames;