summaryrefslogtreecommitdiff
path: root/platform/darwin/docs/guides/Predicates and Expressions.md
diff options
context:
space:
mode:
Diffstat (limited to 'platform/darwin/docs/guides/Predicates and Expressions.md')
-rw-r--r--platform/darwin/docs/guides/Predicates and Expressions.md414
1 files changed, 414 insertions, 0 deletions
diff --git a/platform/darwin/docs/guides/Predicates and Expressions.md b/platform/darwin/docs/guides/Predicates and Expressions.md
new file mode 100644
index 0000000000..19d98fd4c1
--- /dev/null
+++ b/platform/darwin/docs/guides/Predicates and Expressions.md
@@ -0,0 +1,414 @@
+# Predicates and expressions
+
+Style layers use predicates and expressions to determine what to display and how
+to format it. _Predicates_ are represented by the same `NSPredicate` class that
+filters results from Core Data or items in an `NSArray` in Objective-C.
+Predicates are based on _expressions_, represented by the `NSExpression` class.
+Somewhat unusually, style layers also use expressions on their own.
+
+This document discusses the specific subset of the predicate and expression
+syntax supported by this SDK. For a more general introduction to predicates and
+expressions, consult the
+_[Predicate Programming Guide](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html)_
+in Apple developer documentation.
+
+## Using predicates to filter vector data
+
+Most style layer classes display `MGLFeature` objects that you can show or hide
+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.
+
+The following comparison operators are supported:
+
+`NSPredicateOperatorType` | Format string syntax
+----------------------------------------------|---------------------
+`NSEqualToPredicateOperatorType` | `key = value`<br />`key == value`
+`NSGreaterThanOrEqualToPredicateOperatorType` | `key >= value`<br />`key => value`
+`NSLessThanOrEqualToPredicateOperatorType` | `key <= value`<br />`key =< value`
+`NSGreaterThanPredicateOperatorType` | `key > value`
+`NSLessThanPredicateOperatorType` | `key < value`
+`NSNotEqualToPredicateOperatorType` | `key != value`<br />`key <> value`
+`NSBetweenPredicateOperatorType` | `key BETWEEN { 32, 212 }`
+
+The following compound operators are supported:
+
+`NSCompoundPredicateType` | Format string syntax
+--------------------------|---------------------
+`NSAndPredicateType` | `predicate1 AND predicate2`<br />`predicate1 && predicate2`
+`NSOrPredicateType` | `predicate1 OR predicate2`<br />`predicate1 || predicate2`
+`NSNotPredicateType` | `NOT predicate`<br />`!predicate`
+
+The following aggregate operators are supported:
+
+`NSPredicateOperatorType` | Format string syntax
+----------------------------------|---------------------
+`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.
+
+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.
+
+The predicate's left-hand expression must be a string that identifies a feature
+attribute or, alternatively, one of the following special attributes:
+
+<table>
+<thead>
+<tr><th>Attribute</th><th>Meaning</th></tr>
+</thead>
+<tbody>
+<tr>
+ <td><code>$id</code></td>
+ <td>
+ 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 <code>MGLFeature</code> protocol’s
+ <code>identifier</code> property.
+ </td>
+</tr>
+<tr>
+ <td><code>$type</code></td>
+ <td>
+ The type of geometry represented by the feature. A feature’s type is
+ guaranteed to be one of the following strings:
+ <ul>
+ <li>
+ <code>Point</code> for point features, corresponding to the
+ <code>MGLPointAnnotation</code> class
+ </li>
+ <li>
+ <code>LineString</code> for polyline features, corresponding to
+ the <code>MGLPolyline</code> class
+ </li>
+ <li>
+ <code>Polygon</code> for polygon features, corresponding to the
+ <code>MGLPolygon</code> class
+ </li>
+ </ul>
+ </td>
+</tr>
+<tr>
+ <td><code>point_count</code></td>
+ <td>The number of point features in a given cluster.</td>
+</tr>
+</tbody>
+</table>
+
+The predicate’s right-hand expression must 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. 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 `$id` and `$type` special
+style attributes and also `hyphen-minus` and `tag:subtag`. However, you must use
+`%K` in the format string to represent these variables:
+`@"%K == 'LineString'", @"$type"`.
+
+## Using expressions to configure layout and paint attributes
+
+### Functions
+
+#### Key paths
+
+A key path expression refers to an attribute of the `MGLFeature` object being
+evaluated for display. For example, if a polygon’s `MGLFeature.attributes`
+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
+
+Of the
+[functions predefined by the `+[NSExpression expressionForFunction:arguments:]` method](https://developer.apple.com/documentation/foundation/nsexpression/1413747-init#discussion),
+the following subset is supported in layer attribute values:
+
+Initializer parameter | Format string syntax
+----------------------|---------------------
+`average:` | `average({1, 2, 2, 3, 4, 7, 9})`
+`sum:` | `sum({1, 2, 2, 3, 4, 7, 9})`
+`count:` | `count({1, 2, 2, 3, 4, 7, 9})`
+`min:` | `min({1, 2, 2, 3, 4, 7, 9})`
+`max:` | `max({1, 2, 2, 3, 4, 7, 9})`
+`add:to:` | `1 + 2`
+`from:subtract:` | `2 - 1`
+`multiply:by:` | `1 * 2`
+`divide:by:` | `1 / 2`
+`modulus:by:` | `modulus:by:(1, 2)`
+`sqrt:` | `sqrt(2)`
+`log:` | `log(10)`
+`ln:` | `ln(2)`
+`raise:toPower:` | `2 ** 2`
+`exp:` | `exp(0)`
+`ceiling:` | `ceiling(0.99999)`
+`abs:` | `abs(-1)`
+`trunc:` | `trunc(6378.1370)`
+`floor:` | `floor(-0.99999)`
+`uppercase:` | `uppercase('Elysian Fields')`
+`lowercase:` | `lowercase('DOWNTOWN')`
+`noindex:` | `noindex(0 + 2 + c)`
+
+The following predefined functions are not supported:
+
+Initializer parameter | Format string syntax
+----------------------|---------------------
+`median:` | `median({1, 2, 2, 3, 4, 7, 9})`
+`mode:` | `mode({1, 2, 2, 3, 4, 7, 9})`
+`stddev:` | `stddev({1, 2, 2, 3, 4, 7, 9})`
+`random` | `random()`
+`randomn:` | `randomn(10)`
+`now` | `now()`
+`bitwiseAnd:with:` | `bitwiseAnd:with:(5, 3)`
+`bitwiseOr:with:` | `bitwiseOr:with:(5, 3)`
+`bitwiseXor:with:` | `bitwiseXor:with:(5, 3)`
+`leftshift:by:` | `leftshift:by:(23, 1)`
+`rightshift:by:` | `rightshift:by:(23, 1)`
+`onesComplement:` | `onesComplement(255)`
+`distanceToLocation:fromLocation:` | `distanceToLocation:fromLocation:(there, here)`
+
+#### Mapbox-specific functions
+
+For compatibility with the Mapbox Style Specification, the following functions
+are defined by this SDK for use with style layers. Because these functions are
+not predefined by `NSExpression`, you must use the
+`+[NSExpression expressionForFunction:selectorName:arguments:]` method or the
+`FUNCTION()` format string syntax instead.
+
+<table>
+<thead>
+<tr><th>Selector name</th><th>Target</th><th>Arguments</th><th>Returns</th></tr>
+</thead>
+<tbody>
+<tr>
+ <td><code>boolValue</code></td>
+ <td>
+ An `NSExpression` that evaluates to a number or string.
+ </td>
+ <td></td>
+ <td>
+ A Boolean representation of the target: `FALSE` when then input is an
+ empty string, 0, `FALSE`, `NIL`, or NaN, otherwise `TRUE`.
+ </td>
+</tr>
+<tr>
+ <td><code>mgl_expressionWithContext:</code></td>
+ <td>
+ An `NSExpression` that may contain references to the variables defined in
+ the context dictionary.
+ </td>
+ <td>
+ An `NSDictionary` with `NSString`s as keys and `NSExpression`s as values.
+ Each key is a variable name and each value is the variable’s value within
+ the target expression.
+ </td>
+ <td>
+ The target expression with variable subexpressions replaced with the
+ values defined in the context dictionary.
+ </td>
+</tr>
+<tr>
+ <td><code>mgl_interpolateWithCurveType:parameters:stops:</code></td>
+ <td>
+ An `NSExpression` that evaluates to a number and contains a variable or
+ key path expression.
+ </td>
+ <td>
+ 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:
+
+ <ul>
+ <li>If the curve type is `linear`, the argument is `NIL`.</li>
+ <li>
+ If the curve type is `exponential`, the argument is an expression
+ that evaluates to a number, specifying the base of the exponential
+ interpolation.
+ </li>
+ <li>
+ 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.
+ </li>
+ </ul>
+
+ The third argument is an `NSDictionary` object representing the
+ interpolation’s stops, with numeric zoom levels as keys and expressions as
+ values.
+ </td>
+ <td>
+ A value interpolated along the continuous mathematical function defined by
+ the arguments, with the target as the input to the function.
+ </td>
+</tr>
+<tr>
+ <td>
+ <code>mgl_numberWithFallbackValues:</code>,
+ <code>doubleValue</code>,
+ <code>floatValue</code>,
+ <code>decimalValue</code>
+ </td>
+ <td>
+ An `NSExpression` that evaluates to a Boolean value, number, or string.
+ </td>
+ <td>
+ Zero or more `NSExpression`s, each evaluating to a Boolean value or
+ string.
+ </td>
+ <td>
+ A numeric representation of the target:
+ <ul>
+ <li>If the target is `NIL` or `FALSE`, the result is 0.</li>
+ <li>If the target is true, the result is 1.</li>
+ <li>
+ If the target is a string, it is converted to a number as specified
+ by the
+ “<a href="https://tc39.github.io/ecma262/#sec-tonumber-applied-to-the-string-type">ToNumber Applied to the String Type</a>”
+ algorithm of the ECMAScript Language Specification.
+ </li>
+ <li>
+ If multiple values are provided, each one is evaluated in order
+ until the first successful conversion is obtained.
+ </li>
+ </ul>
+ </td>
+</tr>
+<tr>
+ <td><code>mgl_stepWithMinimum:stops:</code></td>
+ <td>
+ An `NSExpression` that evaluates to a number and contains a variable or
+ key path expression.
+ </td>
+ <td>
+ 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.
+ </td>
+ <td>
+ 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.
+ </td>
+</tr>
+<tr>
+ <td><code>stringByAppendingString:</code></td>
+ <td>
+ An `NSExpression` that evaluates to a string.
+ </td>
+ <td>
+ One or more `NSExpression`s, each evaluating to a string.
+ </td>
+ <td>
+ The target string with each of the argument strings appended in order.
+ </td>
+</tr>
+<tr>
+ <td><code>stringValue</code></td>
+ <td>
+ An `NSExpression` that evaluates to a Boolean value, number, or string.
+ </td>
+ <td></td>
+ <td>
+ A string representation of the target:
+ <ul>
+ <li>If the target is `NIL`, the result is the string `null`.</li>
+ <li>
+ If the target is a Boolean value, the result is the string `true` or
+ `false`.
+ </li>
+ <li>
+ If the target is a number, it is converted to a string as specified
+ by the
+ “<a href="https://tc39.github.io/ecma262/#sec-tostring-applied-to-the-number-type">NumberToString</a>”
+ algorithm of the ECMAScript Language Specification.
+ </li>
+ <li>
+ If the target is a color, it is converted to a string of the form
+ `rgba(r,g,b,a)`, where <var>r</var>, <var>g</var>, and <var>b</var>
+ are numerals ranging from 0 to 255 and <var>a</var> ranges from 0 to
+ 1.
+ </li>
+ <li>
+ 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.
+ </li>
+ </ul>
+ </td>
+</tr>
+</tbody>
+</table>
+
+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.
+
+### Variables
+
+The following variables are defined by this SDK for use with style layers:
+
+<table>
+<thead>
+<tr><th>Variable</th><th>Type</th><th>Meaning</th></tr>
+</thead>
+<tbody>
+<tr>
+ <td><code>$heatmapDensity</code></td>
+ <td>Number</td>
+ <td>
+ The
+ <a href="https://en.wikipedia.org/wiki/Kernel_density_estimation">kernel density estimation</a>
+ 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.
+ </td>
+</tr>
+<tr>
+ <td><code>$zoomLevel</code></td>
+ <td>Number</td>
+ <td>
+ 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.
+ </td>
+</tr>
+</tbody>
+</table>
+
+In addition to these variables, you can define your own variables and refer to
+them elsewhere in the expression. The syntax for defining a variable makes use
+of a [Mapbox-specific function](#mapbox-specific-functions) that takes an
+`NSDictionary` as an argument:
+
+```objc
+[NSExpression expressionWithFormat:@"FUNCTION($floorCount + 1, 'mgl_expressionWithContext:', %@)",
+ {@"floorCount": @2}];
+```
+
+```swift
+NSExpression(format: "FUNCTION($floorCount + 1, 'mgl_expressionWithContext:', %@)",
+ ["floorCount": 2])
+```