# 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 expressions follow this format:

```
Exp(.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 (π * 3^{2}):

```
Exp(.product) {
Exp(.pi)
Exp(.power) {
3
2
}
}
```

This example uses the `product`

operator 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 3^{2}, 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`

operator 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`

operator with `"ethnicity"`

as the sole argument.

Then, it uses `stop`

s 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`

is a color, which is constructed using the `rgb`

operator.

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.

```
// Compare value of the "ethnicity" data property
// to several possible values
let circleColorExpression = Exp(.match) {
// Read the value of the "ethnicity" data property
Exp(.get) { "ethnicity" }
// If the value of the data property
// matches "White", then apply this color
"White"
UIColor.orange
"Black"
// If the value of the data property
// matches "Black", then apply this color
UIColor.blue
// If the value of the data property
// matches "Hispanic", then apply this color
"Hispanic"
UIColor.red
// If the value of the data property
// matches "Asian", then apply this color
"Asian"
UIColor.purple
// If the value of the "ethnicity" property does
// not match any of the above strings, use this color
UIColor.black
}
```

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`

operator 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. An expression using the `exponential`

operator 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 in between, the radius will be determined by an exponential function and the value will fall somewhere between `2`

and `180`

.

```
var populationLayer = CircleLayer(id: "population")
populationLayer.source = "ethnicity-source"
populationLayer.sourceLayer = "sf2010"
let stops: [Double: Double] = [
// If the map is at zoom level 12 or below,
// set circle radius to 2
12: 2.0,
// If the map is at zoom level 22 or above,
// set circle radius to 180
22: 180.0
]
// Produce a continuous, smooth series of values
// between pairs of input and output values
let zoomExp = Exp(.interpolate) {
// Set the interpolation type
Exp(.exponential) { 1.75 }
// Get current zoom level
Exp(.zoom)
// Use the stops defined above
stops
}
populationLayer.circleRadius = .expression(zoomExp)
```

For more examples of expressions for zoom-driven styling, see the Maps SDK test application on GitHub.