Expressions form a little language that can be used to compute values for various layer properties.
It is recommended to import them in the following fashion:
import Mapbox.Expression as E exposing (Expression, CameraExpression, DataExpression, str, float, int, true, false)
This way you can use the language without much syntactic fuss and you have easy access to the literals.
You'd like to adjust font size of a town based on the number of people who live there. In plain Elm, you might wright the following function:
sizeByPopulation : Dict String Int -> Int
sizeByPopulation properties =
Dict.get "population" properties
|> Maybe.withDefault 1000
|> scale ( 0, 1000 ) ( 9, 20 )
In the expression language you can do this in a similar fassion:
sizeByPopulation : Expression DataExpression Float
sizeByPopulation =
E.getProperty "population"
|> E.toFloat 1000
|> E.interpolate E.Linear
[ ( 0, int 9 )
, ( 1000, int 20 )
]
Note: If you are familiar with the JS version of the style spec, we have made a few changes. Argument order has been switched for many functions to support using pipeline style more naturally. Some functions use overloading in the original, these have been renamed to not be overloaded. Finally, we have chosen not to represent some parts of the spec that are superflous (especially when used from Elm), namely functions and let-in expressions.
Internal.Expression exprType resultType
Expressions are zero overhead wrappers over the underlying JSON language that attempt to provide some type safety.
Note however, that while being a strictly typed language, it has slighlty different semantics tham Elm:
Float
. You will notice that the int
function takes an Elm int
value and converts it to an Expression expr Float
.null
. There is no Maybe
type. You can use the coalesce
function to handle this.List
, Array
, and tuples. Hence all collections are labeled as Array
.Object
. The keys are always String
, but the values can be of mixed types. Hence retrieving
values from them makes code untyped.assert...
functions. This will generate a runtime error if the type doesn't
match. This should be necessary only rarely.The exprType
can be:
CameraExpression
DataExpression
The intent is to help you not break your style by using a DataExpression (for example) where it isn't supported. However, this isn't entirely foolproof, so some caution is advised.
A data expression is any expression that access feature data -- that is, any expression that uses one of the data operators: getProperty
, hasProperty
, id
, geometryType
, or properties
. Data expressions allow a feature's properties to determine its appearance. They can be used to differentiate features within the same layer and to create data visualizations.
makeRGBColor
-- red is higher when feature.properties.temperature is higher
(getProperty "temperature")
-- green is always zero
(int 0)
-- blue is higher when feature.properties.temperature is lower
(getProperty "temperature" |> minus 100)
|> Layer.circleColor
This example uses the getProperty
operator to obtain the temperature value of each feature. That value is used to compute arguments to the makeRGBColor
operator, defining a color in terms of its red, green, and blue components.
A camera expression is any expression that uses the zoom operator. Such expressions allow the appearance of a layer to change with the map's zoom level. Camera expressions can be used to create the appearance of depth and to control data density.
zoom
|> interpolate Linear
[ ( 5, int 1 )
, ( 10, int 5 )
]
|> Layer.circleRadius
This example uses the interpolate
operator to define a linear relationship between zoom level and circle size using a set of input-output pairs. In this case, the expression indicates that the circle radius should be 1 pixel when the zoom level is 5 or below, and 5 pixels when the zoom is 10 or above. In between, the radius will be linearly interpolated between 1 and 5 pixels
Camera expressions are allowed anywhere an expression may be used. However, when a camera expression used as the value of a layout or paint property, the zoom
operator must appear only as the input to an outer interpolate
or step
expression
There is an important difference between layout and paint properties in the timing of camera expression evaluation. Paint property camera expressions are re-evaluated whenever the zoom level changes, even fractionally. For example, a paint property camera expression will be re-evaluated continuously as the map moves between zoom levels 4.1 and 4.6. On the other hand, a layout property camera expression is evaluated only at integer zoom levels. It will not be re-evaluated as the zoom changes from 4.1 to 4.6 -- only if it goes above 5 or below 4.
encode : Expression exprType a -> Json.Encode.Value
Turns an expression into JSON
All of the types used as expression results are phantom (i.e. they don't have any runtime values but are used purely for compile-time checking). As such we use a mix of standard elm types for their familiarty:
Float
String
Array
Bool
We introduce the following types:
Represents a color value
Represents a mixed-type dictionary where keys are always strings
Used for locale sensitive string comparisons.
true : Expression exprType Basics.Bool
false : Expression exprType Basics.Bool
bool : Basics.Bool -> Expression exprType Basics.Bool
int : Basics.Int -> Expression exprType Basics.Float
float : Basics.Float -> Expression exprType Basics.Float
str : String -> Expression exprType String
rgba : Basics.Float -> Basics.Float -> Basics.Float -> Basics.Float -> Expression exprType Color
floats : List Basics.Float -> Expression exprType (Array Basics.Float)
strings : List String -> Expression exprType (Array String)
object : List ( String, Json.Encode.Value ) -> Expression exprType Object
Takes a list of key value pairs. The values are JSON Values, therefore allowing for mixed types.
collator : Expression e1 Basics.Bool -> Expression e2 Basics.Bool -> Expression e3 String -> Expression e4 Collator
Returns a Collator
for use in locale-dependent comparison operations. The first argument specifies if the comparison should be case sensitive. The second specifies if it is diacritic sensitive. The final locale argument specifies the IETF language tag of the locale to use.
assertArray : Expression exprType any -> Expression exprType (Array any)
assertArrayOfStrings : Expression exprType any -> Expression exprType (Array String)
assertArrayOfFloats : Expression exprType any -> Expression exprType (Array Basics.Float)
assertArrayOfBools : Expression exprType any -> Expression exprType (Array Basics.Bool)
assertBool : Expression exprType any -> Expression exprType Basics.Bool
assertFloat : Expression exprType any -> Expression exprType Basics.Float
assertObject : Expression exprType any -> Expression exprType Object
toBool : Expression exprType any -> Expression exprType Basics.Bool
Converts the input value to a boolean. The result is false when then input is an empty string, 0, false, null, or NaN; otherwise it is true.
toColor : Expression exprType2 Color -> Expression exprType any -> Expression exprType Color
Converts the input value to a color. If it can't be converted, the falback value will be used.
input
|> toColor (rgba 0 0 0 1) -- fallback color
toFloat : Basics.Float -> Expression exprType any -> Expression exprType Basics.Float
Converts the input value to a number, if possible. If the input is null or false, the result is 0. If the input is true, the result is 1. If the input 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 this fails, the fallback value is used.
input
|> toFloat 0 -- fallback
toString : Expression exprType any -> Expression exprType String
Converts the input value to a string. If the input is null
, the result is ""
. If the input is a boolean, the result is "true"
or "false"
. If the input is a number, it is converted to a string as specified by the "NumberToString" algorithm of the ECMAScript Language Specification. If the input 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 input is converted to a string in the format specified by the JSON.stringify
function of the ECMAScript Language Specification.
toFormattedText : Expression exprType any -> Expression exprType FormattedText
Just like toString
, but outputs a formatted string useable for displaying to users.
formatNumber : List NumberFormatOption -> Expression exprType Basics.Float -> Expression exprType String
Converts the input number into a string representation following locale dependent formatting rules.
locale : Expression exprType String -> NumberFormatOption
Specifies the locale to use as a BCP 47 language tag. Defaults to the current locale.
currency : Expression exprType String -> NumberFormatOption
If set, will include a currency symbol in the resulting number (such as "JP¥" or "€"). Should be a ISO 4217 currency code.
minFractionDigits : Expression exprType Basics.Float -> NumberFormatOption
Formatter will include at least this many digits after the decimal point. Defaults to 0.
maxFractionDigits : Expression exprType Basics.Float -> NumberFormatOption
Formatter will include at most this many digits after the decimal point. Defaults to 3.
typeof : Expression exprType any -> Expression exprType String
Returns a string describing the type of the given value.
at : Expression exprType1 Basics.Float -> Expression exprType2 (Array a) -> Expression exprType2 a
Retrieves an item from an array.
get : Expression exprType1 String -> Expression exprType2 Object -> Expression exprType2 any
Retrieves a property value from an object. Returns null if the requested property is missing.
has : Expression exprType1 String -> Expression exprType2 Object -> Expression exprType2 Basics.Bool
Tests for the presence of an property value in an object.
count : Expression exprType (Array any) -> Expression exprType Basics.Float
Gets the length of an array.
length : Expression exprType String -> Expression exprType Basics.Float
Gets the length of a string.
featureState : Expression exprType String -> Expression DataExpression any
Retrieves a property value from the current feature's state. Returns null if the requested property is not present on the feature's state. A feature's state is not part of the GeoJSON or vector tile data, and must be set programmatically on each feature. Note that featureState
can only be used with paint properties that support data-driven styling.
geometryType : Expression DataExpression String
Gets the feature's geometry type: Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon.
id : Expression DataExpression any
Gets the feature's id, if it has one.
properties : Expression DataExpression Object
Gets the feature properties object. Note that in some cases, it may be more efficient to use getProperty (str "property-name")
directly.
getProperty : Expression exprType String -> Expression DataExpression any
Retrieves a property value from the current feature's properties. Returns null if the requested property is missing.
hasProperty : Expression exprType String -> Expression DataExpression Basics.Bool
Tests for the presence of an property value in the current feature's properties.
The expressions in this section can be used to add conditional logic to your styles.
isEqual : Expression exprType1 a -> Expression exprType2 a -> Expression exprType1 Basics.Bool
Returns true if the input values are equal, false otherwise.
notEqual : Expression exprType1 a -> Expression exprType2 a -> Expression exprType1 Basics.Bool
Returns true if the input values are not equal, false otherwise.
lessThan : Expression exprType1 comparable -> Expression exprType2 comparable -> Expression exprType1 Basics.Bool
Returns true if the first input is strictly less than the second, false otherwise.
lessThanOrEqual : Expression exprType1 comparable -> Expression exprType2 comparable -> Expression exprType1 Basics.Bool
Returns true if the first input is less than or equal to the second, false otherwise.
greaterThan : Expression exprType1 comparable -> Expression exprType2 comparable -> Expression exprType1 Basics.Bool
Returns true if the first input is strictly greater than the second, false otherwise.
isEqualWithCollator : Expression exprType1 String -> Expression exprType2 String -> Expression exprType3 Collator -> Expression exprType1 Basics.Bool
notEqualWithCollator : Expression exprType1 String -> Expression exprType2 String -> Expression exprType3 Collator -> Expression exprType1 Basics.Bool
lessThanWithCollator : Expression exprType1 String -> Expression exprType2 String -> Expression exprType3 Collator -> Expression exprType1 Basics.Bool
lessThanOrEqualWithCollator : Expression exprType1 String -> Expression exprType2 String -> Expression exprType3 Collator -> Expression exprType1 Basics.Bool
greaterThanWithCollator : Expression exprType1 String -> Expression exprType2 String -> Expression exprType3 Collator -> Expression exprType1 Basics.Bool
not : Expression exprType Basics.Bool -> Expression exprType Basics.Bool
Logical negation. Returns true if the input is false, and false if the input is true.
all : List (Expression exprType Basics.Bool) -> Expression exprType Basics.Bool
Returns true if all the inputs are true, false otherwise. The inputs are evaluated in order, and evaluation is short-circuiting: once an input expression evaluates to false, the result is false and no further input expressions are evaluated.
ifElse : Expression exprType1 Basics.Bool -> Expression exprType2 output -> Expression exprType3 output -> Expression exprType1 output
The ternary operator:
Layer.iconImage <|
ifElse
(greaterThan (getProperty (str "size")) (float 30))
(str "hospital-32")
(str "clinic-32")
conditionally : List ( Expression exprType1 Basics.Bool, Expression exprType2 output ) -> Expression exprType2 output -> Expression exprType1 output
Selects the first output whose condition evaluates to true
matchesStr : List ( String, Expression exprType2 output ) -> Expression exprType1 output -> Expression exprType3 String -> Expression exprType3 output
Selects the output whose label value matches the input value, or the fallback value if no match is found.
getProperty (str "type")
|> matchesStr
[ ( "hospital", str "icon-hospital" )
, ( "clinic", str "icon-medical" )
]
(str "icon-generic")
-- fallback value
|> Layer.iconImage
matchesFloat : List ( Basics.Float, Expression exprType2 output ) -> Expression exprType1 output -> Expression exprType3 Basics.Float -> Expression exprType3 output
Selects the output whose label value matches the input value, or the fallback value if no match is found.
getProperty (str "size")
|> matchesFloat
[ ( 1, str "icon-hospital" )
, ( 2, str "icon-medical" )
]
(str "icon-generic")
-- fallback value
|> Layer.iconImage
coalesce : List (Expression exprType outputType) -> Expression exprType outputType
Evaluates each expression in turn until the first non-null value is obtained, and returns that value.
interpolate : Interpolation -> List ( Basics.Float, Expression exprType2 outputType ) -> Expression exprType1 Basics.Float -> Expression exprType1 outputType
Produces continuous, smooth results by interpolating between pairs of input and output values ("stops"). The output type must be Float
, Array Float
, or Color
.
zoom
|> interpolate Linear
[ ( 5, int 1 )
, ( 10, int 5 )
]
|> Layer.circleRadius
Interpolation types:
Linear
: interpolates linearly between the pair of stops just less than and just greater than the input.Exponential base
: interpolates exponentially between the stops just less than and just greater than the input. base
controls the rate at which the output increases: higher values make the output increase more towards the high end of the range. With values close to 1 the output increases linearly.CubicBezier (x1, y1) (x2, y2)
: interpolates using the cubic bezier curve defined by the given control points.step : Expression exprType1 output -> List ( Basics.Float, Expression exprType1 output ) -> Expression exprType2 Basics.Float -> Expression exprType2 output
Produces discrete, stepped results by evaluating a piecewise-constant function defined by pairs of input and output values ("stops"). Stop inputs must be Floats in strictly ascending order. Returns the output value of the stop just less than the input, or the first input if the input is less than the first stop.
zoom
|> step (int 1)
[ ( 5, int 3 )
, ( 10, int 5 )
]
|> Layer.circleRadius
append : Expression exprType String -> Expression exprType String -> Expression exprType String
Returns a string consisting of the concatenation of the inputs.
Argument order designed for pipelines:
a |> append b --> a ++ b
downcase : Expression exprType String -> Expression exprType String
Returns the input string converted to lowercase. Follows the Unicode Default Case Conversion algorithm and the locale-insensitive case mappings in the Unicode Character Database.
upcase : Expression exprType String -> Expression exprType String
Returns the input string converted to uppercase. Follows the Unicode Default Case Conversion algorithm and the locale-insensitive case mappings in the Unicode Character Database.
isSupportedScript : Expression exprType String -> Expression exprType Basics.Bool
Returns true if the input string is expected to render legibly. Returns false if the input string contains sections that cannot be rendered without potential loss of meaning (e.g. Indic scripts that require complex text shaping, or right-to-left scripts if the mapbox-gl-rtl-text plugin is not in use in Mapbox GL JS).
resolvedLocale : Expression exprType Collator -> Expression exprType String
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.
format : List FormattedString -> Expression exprType FormattedText
Returns formatted text containing annotations for use in mixed-format text-field entries.
Layer.textField <|
E.format
[ E.getProperty (str "name_en")
|> E.formatted
|> E.fontScaledBy (float 1.2)
, E.formatted (str "\n")
, E.getProperty (str "name")
|> E.formatted
|> E.fontScaledBy (float 0.8)
|> E.withFont (E.strings [ "DIN Offc Pro Medium" ])
A FormattedText is composed of a list of FormattedString which essentially are a tuple of a string expression and some formatting information that applies to that string.
formatted : Expression exprType String -> FormattedString
Takes a String Expression and turns it into a FormattedString with default formatting.
fontScaledBy : Expression exprType Basics.Float -> FormattedString -> FormattedString
Specifies a scaling factor relative to the text-size specified in the root layout properties.
Note: this is indempotent, so calling str "hi" |> formatted |> fontScaledBy 1.2 |> fontScaledBy 1.2
is equivalent to str "hi" |> formatted |> fontScaledBy 1.2
rather than str "hi" |> formatted |> fontScaledBy 1.44
.
withFont : Expression exprType (Array String) -> FormattedString -> FormattedString
Overrides the font specified by the root layout properties.
makeRGBColor : Expression exprType Basics.Float -> Expression exprType Basics.Float -> Expression exprType Basics.Float -> Expression exprType Color
Creates a color value from red, green, and blue components, which must range between 0 and 255, and an alpha component of 1. If any component is out of range, the expression is an error.
makeRGBAColor : Expression exprType Basics.Float -> Expression exprType Basics.Float -> Expression exprType Basics.Float -> Expression exprType Basics.Float -> Expression exprType Color
Creates a color value from red, green, blue components, which must range between 0 and 255, and an alpha component which must range between 0 and 1. If any component is out of range, the expression is an error.
rgbaChannels : Expression exprType Color -> Expression exprType (Array Basics.Float)
Returns a four-element array containing the input color's red, green, blue, and alpha components, in that order.
minus : Expression exprType Basics.Float -> Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the result of subtracting the first input from the second.
a |> minus b --> a - b
multiply : Expression exprType Basics.Float -> Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the product of the inputs.
divideBy : Expression exprType Basics.Float -> Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the result of floating point division of the second input by the first.
a |> divideBy b --> a / b
modBy : Expression exprType Basics.Float -> Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the remainder after integer division of the second input by the first.
a |> modBy b --> a % b
plus : Expression exprType Basics.Float -> Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the sum of the inputs.
raiseBy : Expression exprType Basics.Float -> Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the result of raising the second input to the power specified by the first.
a |> raiseBy b --> a ^ b
sqrt : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the square root of the input.
abs : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the absolute value of the input.
ceil : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the smallest integer that is greater than or equal to the input.
floor : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the largest integer that is less than or equal to the input.
round : Expression exprType Basics.Float -> Expression exprType Basics.Float
Rounds the input to the nearest integer. Halfway values are rounded away from zero. For example, round (float -1.5)
evaluates to -2.
cos : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the cosine of the input.
sin : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the sine of the input.
tan : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the tangent of the input.
acos : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the arccosine of the input.
asin : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the arcsine of the input.
atan : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the arctangent of the input.
e : Expression exprType Basics.Float
Returns the mathematical constant e.
pi : Expression exprType Basics.Float
ln : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the natural logarithm of the input.
ln2 : Expression exprType Basics.Float
Returns mathematical constant ln(2).
log10 : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the base-ten logarithm of the input.
log2 : Expression exprType Basics.Float -> Expression exprType Basics.Float
Returns the base-two logarithm of the input.
zoom : Expression CameraExpression Basics.Float
Gets the current zoom level. Note that in style layout and paint properties, zoom
may only appear as the input to a top-level step
or interpolate
expression.
heatmapDensity : Expression exprType Basics.Float
Gets the kernel density estimation of a pixel in a heatmap layer, which is a relative measure of how many data points are crowded around a particular pixel. Can only be used in the heatmapColor
property.
lineProgress : Expression exprType Basics.Float
Gets the progress along a gradient line. Can only be used in the lineGradient
property.
These are required for various layer properties. They are not documented here as they are overloaded - you will find descriptions of their effects at the relevant layer property.
Note: You may notice that these have slightly odd types. These types allow them to be overloaded for multiple properties, but still remain type safe. Don't worry about these too much!
map : Expression exprType { a | map : Internal.Supported }
viewport : Expression exprType { a | viewport : Internal.Supported }
auto : Expression exprType { a | auto : Internal.Supported }
center : Expression exprType { a | center : Internal.Supported }
left : Expression exprType { a | left : Internal.Supported }
right : Expression exprType { a | right : Internal.Supported }
top : Expression exprType { a | top : Internal.Supported }
bottom : Expression exprType { a | bottom : Internal.Supported }
topLeft : Expression exprType { a | topLeft : Internal.Supported }
topRight : Expression exprType { a | topRight : Internal.Supported }
bottomLeft : Expression exprType { a | bottomLeft : Internal.Supported }
bottomRight : Expression exprType { a | bottomRight : Internal.Supported }
none : Expression exprType { a | none : Internal.Supported }
width : Expression exprType { a | width : Internal.Supported }
height : Expression exprType { a | height : Internal.Supported }
both : Expression exprType { a | both : Internal.Supported }
butt : Expression exprType { a | butt : Internal.Supported }
rounded : Expression exprType { a | rounded : Internal.Supported }
square : Expression exprType { a | square : Internal.Supported }
bevel : Expression exprType { a | bevel : Internal.Supported }
miter : Expression exprType { a | miter : Internal.Supported }
point : Expression exprType { a | point : Internal.Supported }
lineCenter : Expression exprType { a | lineCenter : Internal.Supported }
line : Expression exprType { a | line : Internal.Supported }
uppercase : Expression exprType { a | uppercase : Internal.Supported }
lowercase : Expression exprType { a | lowercase : Internal.Supported }
linear : Expression exprType { a | linear : Internal.Supported }
nearest : Expression exprType { a | nearest : Internal.Supported }
viewportY : Expression exprType { a | viewportY : Internal.Supported }
source : Expression exprType { a | source : Internal.Supported }