Use expressions
You can change the appearance of a layer based on properties in the layer's data source or zoom level. For example, you might create a data-driven style rule that sets the color of states in the United States based on the population of each state.
Work with expressions
In the Maps SDK, you can specify the value for any layout property, paint property, or filter as an expression. Expressions define how one or more feature property value or the current zoom level are combined using logical, mathematical, string, or color operations to produce the appropriate style property value or filter decision.
A property expression is any expression defined using a reference to feature property data. Property expressions allow the appearance of a feature to change with its properties. They can be used to visually differentiate types of features within the same layer or create data visualizations.
A camera expression is any expression defined using ['zoom']
. Such expressions allow the appearance of a layer to change with the map’s zoom level. Zoom expressions can be used to create the illusion of depth and control data density.
There are countless ways to apply property expressions to your application, including:
- Data-driven styling: Specify style rules based on one or more data attribute.
- Arithmetic: Do arithmetic on source data, for example performing calculations to convert units.
- Conditional logic: Use if-then logic, for example to decide exactly what text to display for a label based on which properties are available in the feature or even the length of the name.
- String manipulation: Take control over label text with things like uppercase, lowercase, and title case transforms without having to edit, re-prepare and re-upload your data.
An expression defines a formula for computing the value of the property using the operators described in this section.
Syntax
The Maps SDK's Style
domain-specific language (DSL) allows you to write expressions in a block that is applied to a receiver class. DSL functions for expressions are provided to construct the instances. Expressions follow this format:
expression_name {
argument_0
argument_1
}
The expression_name
is the expression operator, for example, you would use product
to multiply two arguments or switchCase
to create conditional logic.
The arguments are either literal (numbers, strings, or boolean values) or else themselves expressions. The number of arguments varies based on the expression.
Here's one example using an expression to calculate an arithmetic expression (π * 32):
product {
pi()
pow {
literal(3)
literal(2)
}
}
This example uses a product
expression to multiply two arguments. The first argument is pi
, which is an expression that returns the mathematical constant pi. The second arguement is another expression: a pow
expression with two arguments of its own. It will return 32, and the result will be multiplied by π.
Expression types
- Mathematical operators for performing arithmetic and other operations on numeric values
- Logical operators for manipulating boolean values and making conditional decisions
- String operators for manipulating strings
- Data operators for providing access to the properties of source features
- Camera operators for providing access to the parameters defining the current map view
Data-driven styling at runtime
You can use expressions to determine the style of features in a layer based on data properties in the source data. For example, if you have a source containing point data from individual responses to the 2010 U.S. Census and each point has an "ethnicity" data property, you can use expressions to specify the color of each circle based on reported ethnicity.
The example below uses the match
expression to compare the value of the "ethnicity"
data property for each point in the source to several possible values. The first argument of the match
expression is the value of the "ethnicity"
data property. There are several arguments that specify what to do if the value of the data property matches a given string and a final argument that specifies what to do if the value of the data property does not match any of the strings provided.
To read the values of the "ethnicity"
data property, this example uses the get
expression with "ethnicity"
as the sole argument.
Then, it uses stop
expressions for the next several arguments for the match
expression. Each stop
has two arguments: the first is the value to compare to the value of the "ethnicity"
data property and the second is the value that should be applied to the layer's circleColor
property if the value of the data property matches the first argument.
The second argument of the stop
expression is a color, which is constructed using the rgb
expression.
The final argument of the match
expression is a fallback value that should be applied to circleColor
if the value of the "ethnicity"
data property does not match any of the strings provided.
style {
+circleLayer("population", "ethnicity-source") {
sourceLayer("sf2010")
...
circleColor(
// Compare value of the "ethnicity" data property
// to several possible values
match {
// Read the value of the "ethnicity" data property
get("ethnicity")
// If the value of the data property
// matches "white", then apply this color.
stop {
literal("white")
rgb(251.0, 176.0, 59.0)
}
// If the value of the data property
// matches "Black", then apply this color.
stop {
literal("Black")
rgb(34.0, 59.0, 83.0)
}
// If the value of the data property
// matches "Hispanic", then apply this color.
stop {
literal("Hispanic")
rgb(229.0, 94.0, 94.0)
}
// If the value of the data property
// matches "Asian", then apply this color.
stop {
literal("Asian")
rgb(59.0, 59.0, 208.0)
}
// If the value of the data property
// matches "Other", then apply this color.
stop {
literal("Other")
rgb(204.0, 204.0, 204.0)
}
// If the value of the "ethnicity" property does
// not match any of the above strings, use this color
rgb(0.0, 0.0, 0.0)
}
)
}
}
Add point data to a style from a vector tileset and use the match and get expressions to assign the color of each point in a CircleLayer
based on a data property.
For more examples of expressions for data-driven styling, see the Maps SDK test application on GitHub.
Zoom-driven styling at runtime
You can use expressions to determine the style of features in a layer based on the camera position, including the zoom level. For example, if you have dense point data displayed using a circle layer, you may want to adjust the radius of circles based on the zoom level to make the data more readable at low zoom levels.
The example below uses the interpolate
expression to produce a continuous, smooth series of values between pairs of input and output values ("stops"). Its first argument sets the interpolation type, the second is the value of the zoom level, and the remaining arguments specify the size of the circle radius that should be applied based on the value of the zoom level.
"Exponential" is one of a few types of interpolation available Mapbox expressions. The exponential
expression has one argument: the base
, which controls the rate at which the output increases.
The zoom
expression does not require any arguments. It will return the value of the current zoom level of the map.
The remaining arguments of the interpolate
expression are stop
s. They represent points along the exponential curve. When a user is viewing the map at zoom level 12
or below, the circles will have a radius of 2
. When viewing it at zoom level 22
and above, the circles will have a radius of 180
. For all zoom levels between, the radius will be determined by an exponential function and the value will fall somewhere between 2
and 180
.
style {
+circleLayer("population", "ethnicity-source") {
sourceLayer("sf2010")
...
circleRadius(
// Produce a continuous, smooth series of values
// between pairs of input and output values
interpolate {
// Set the interpolation type
exponential {
literal(1.75)
}
// Get current zoom level
zoom()
// If the map is at zoom level 12 or below,
// set circle radius to 2
stop {
literal(12)
literal(2)
}
// If the map is at zoom level 22 or above,
// set circle radius to 180
stop {
literal(22)
literal(180)
}
}
)
}
}
For more examples of expressions for zoom-driven styling, see the Maps SDK test application on GitHub.