Compartir a través de


Expresiones de estilo controladas por datos en el SDK de iOS (versión preliminar)

Nota:

Retirada del SDK de Azure Maps para iOS

El SDK nativo de Azure Maps para iOS ya está en desuso y se retirará el 31 de marzo de 2025. Para evitar interrupciones del servicio, migre al SDK web de Azure Maps antes del 31 de marzo de 2025. Para más información, vea la Guía de migración del SDK de Azure Maps para iOS.

Las capas usan predicados y expresiones para determinar qué mostrar y cómo formatearlo. Los predicados se representan mediante la misma clase NSPredicate que filtra los resultados de datos principales o elementos de NSArray en Objective-C. Los predicados se basan en expresiones, representadas por la clase NSExpression.

En este documento se describe el subconjunto específico de la sintaxis de predicado y expresión que admite este SDK. Para obtener una introducción más general a los predicados y expresiones, consulte la Guía de programación de predicados en la documentación para desarrolladores de Apple.

Uso de predicados para filtrar datos vectoriales

La mayoría de las clases de capas muestran objetos Feature que se pueden mostrar u ocultar en función de las propiedades de la característica. Use la opción filter para incluir solo las características de la capa de origen que cumplan una condición que defina.

Operadores

Se admiten los siguientes operadores de comparación:

NSPredicateOperatorType Sintaxis de cadena de formato
NSEqualToPredicateOperatorType key = value
key == value
NSGreaterThanOrEqualToPredicateOperatorType key >= value
key => value
NSLessThanOrEqualToPredicateOperatorType key <= value
key =< value
NSGreaterThanPredicateOperatorType key > value
NSLessThanPredicateOperatorType key < value
NSNotEqualToPredicateOperatorType key != value
key <> value
NSBetweenPredicateOperatorType key BETWEEN { 32, 212 }

Para probar si una característica tiene o carece de una propiedad específica, compare el atributo con NULL o NIL. También se admiten predicados creados con el inicializador NSPredicate(value:). No se admiten operadores de cadena ni operadores personalizados.

Se admiten los siguientes operadores compuestos:

NSCompoundPredicateType Sintaxis de cadena de formato
NSAndPredicateType predicate1 AND predicate2
predicate1 && predicate2
NSOrPredicateType predicate1 OR predicate2
predicate1 \|\| predicate2
NSNotPredicateType NOT predicate
!predicate

Se admiten los siguientes operadores de agregado:

NSPredicateOperatorType Sintaxis de cadena de formato
NSInPredicateOperatorType key IN { 'iOS', 'macOS', 'tvOS', 'watchOS' }
NSContainsPredicateOperatorType { 'iOS', 'macOS', 'tvOS', 'watchOS' } CONTAINS key

Puede usar los operadores IN y CONTAINS para probar si un valor aparece en una colección, si una cadena es una subcadena de una cadena mayor o si la característica evaluada (SELF) se encuentra dentro de un determinado elemento Feature.

Se admiten las siguientes combinaciones de operadores de comparación y modificadores:

NSComparisonPredicateModifier NSPredicateOperatorType Sintaxis de cadena de formato
NSAllPredicateModifier NSNotEqualToPredicateOperatorType ALL haystack != needle
NSAnyPredicateModifier NSEqualToPredicateOperatorType ANY haystack = needle
SOME haystack = needle

Las siguientes opciones de predicado de comparación se admiten para los operadores de comparación y agregado que se usan en el predicado:

NSComparisonPredicateOptions Sintaxis de cadena de formato
NSCaseInsensitivePredicateOption 'QUEBEC' =[c] 'Quebec'
NSDiacriticInsensitivePredicateOption 'Québec' =[d] 'Quebec'

No se admiten otras opciones de predicado de comparación, es decir, l (para la distinción de la configuración regional) y n (para la normalización). Una comparación distingue la configuración regional siempre que no distinga mayúsculas de minúsculas o marcas diacríticas. Las opciones de predicado de comparación no se admiten con modificadores de comparación como ALL y ANY.

Operandos

Los operandos en predicados pueden ser variables, rutas de acceso de clave o casi cualquier otra cosa que pueda aparecer dentro de una expresión.

No se realiza la conversión automática de tipos. Por lo tanto, una característica solo coincide con un predicado si su valor para la propiedad en cuestión es del mismo tipo que el valor especificado en el predicado. Use el operador CAST() para convertir una ruta de acceso o variable de clave en un tipo coincidente:

  • Para convertir un valor en un número, use CAST(key, 'NSNumber').
  • Para convertir un valor en una cadena, use CAST(key, 'NSString').
  • Para convertir un valor en un color, use CAST(key, 'UIColor').
  • Para convertir un objeto UIColor en una matriz, use CAST(noindex(color), 'NSArray').

Para más información sobre la sintaxis de cadenas de formato de predicados, consulte el capítulo "Sintaxis de cadenas de formato de predicados" de la Guía de programación de predicados de la documentación para desarrolladores de Apple.

Ejemplos de operandos

De forma predeterminada, las capas de burbujas y símbolos representan las coordenadas de todas las geometrías de un origen de datos. Este comportamiento puede resaltar los vértices de una línea o un polígono. La opción filter de la capa puede usarse para limitar el tipo de geometría de las características que representa, utilizando NSExpression.geometryTypeAZMVariable dentro de un predicado. En el siguiente ejemplo se limita una capa de burbujas para que solo se representen las características Point.

let layer = BubbleLayer(source: source, options: [
    .filter(
        from: NSPredicate(format: "%@ == \"Point\"", NSExpression.geometryTypeAZMVariable)
    )
])

El siguiente ejemplo permite que se representen las características Point y Polygon.

let layer = BubbleLayer(source: source, options: [
    .filter(
        from: NSCompoundPredicate(orPredicateWithSubpredicates: [
            NSPredicate(format: "%@ == \"Point\"", NSExpression.geometryTypeAZMVariable),
            NSPredicate(format: "%@ == \"Polygon\"", NSExpression.geometryTypeAZMVariable)
        ])
    )
])

Uso de expresiones para configurar opciones de capa

Una expresión puede contener subexpresiones de varios tipos. A continuación se describe cada uno de los tipos de expresiones admitidos.

En algunos ejemplos de esta sección del documento, se utiliza la siguiente característica para mostrar diferentes maneras en que se pueden usar estas expresiones.

{
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [-122.13284, 47.63699]
    },
    "properties": {
        "id": 123,
        "entityType": "restaurant",
        "revenue": 12345,
        "subTitle": "Building 40", 
        "temperature": 64,
        "title": "Cafeteria", 
        "zoneColor": "purple",
        "abcArray": ["a", "b", "c"],
        "array2d": [["a", "b"], ["x", "y"]],
        "_style": {
            "fillColor": "red"
        }
    }
}

En el código siguiente se muestra cómo crear manualmente esta característica GeoJSON en una aplicación.

// Create a point feature.
let feature = Feature(Point(CLLocationCoordinate2D(latitude: 45, longitude: -100)))

// Add properties to the feature.
feature.addProperty("id", value:  123)
feature.addProperty("entityType", value: "restaurant")
feature.addProperty("revenue", value:  12345)
feature.addProperty("subTitle", value: "Building 40")
feature.addProperty("temperature", value:  64)
feature.addProperty("title", value: "Cafeteria")
feature.addProperty("zoneColor", value: "purple")
feature.addProperty("abcArray", value: ["a", "b", "c"])
feature.addProperty("array2d", value: [["a", "b"], ["x", "y"]])
feature.addProperty("_style", value: ["fillColor": "red"])

En el código siguiente se muestra cómo deserializar la versión con cadenas del objeto JSON en una característica GeoJSON en una aplicación.

let featureString = "{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-122.13284,47.63699]},\"properties\":{\"id\":123,\"entityType\":\"restaurant\",\"revenue\":12345,\"subTitle\":\"Building 40\",\"temperature\":64,\"title\":\"Cafeteria\",\"zoneColor\":\"purple\",\"abcArray\":[\"a\",\"b\",\"c\"],\"array2d\":[[\"a\",\"b\"],[\"x\",\"y\"]],\"_style\":{\"fillColor\":\"red\"}}}"

let feature = Feature.fromJson(featureString)

Basado en JSON

El SDK web de Azure Maps también admite expresiones de estilo basadas en datos que se representan mediante una matriz JSON. Estas mismas expresiones se pueden volver a crear mediante la clase NSExpression nativa en el SDK de iOS. Como alternativa, estas expresiones basadas en JSON se pueden compartir con la aplicación iOS (asociada a la respuesta, por ejemplo) y pasarse al método NSExpression(azmJSONObject:). Por ejemplo, observe la siguiente expresión JSON.

var exp = ['get','title'];

La versión Swift de la expresión anterior sería ["get", "title"] y se puede leer en el SDK de iOS como se indica a continuación.

let jsonResponse = ["get", "title"]
let exp = NSExpression(azmJSONObject: jsonResponse)

El uso de este enfoque puede facilitar la reutilización de expresiones de estilo entre aplicaciones móviles y web que usan Azure Maps.

En este vídeo encontrará información general sobre la aplicación de estilos basados en datos en Azure Maps.

Presentación de Internet de las cosas: Aplicación de estilos basados en datos con Azure Maps

Valores constantes

Un valor constante puede ser de cualquiera de los tipos siguientes:

  • UIColor
  • String
  • NSNumber.boolValue
  • NSNumber.doubleValue
  • [Float]
  • [String]
  • NSValue.cgVectorValue
  • NSValue.uiEdgeInsetsValue

Ejemplo de valores constantes

NSExpression(forConstantValue: UIColor.red)
NSExpression(forConstantValue: "constant")
NSExpression(forConstantValue: true)
NSExpression(forConstantValue: 20)
NSExpression(forConstantValue: [20, 21, 22])
NSExpression(forConstantValue: ["constant1", "constant2"])
NSExpression(forConstantValue: NSValue(cgVector: CGVector(dx: 2, dy: -4)))
NSExpression(forConstantValue: NSValue(uiEdgeInsets: UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)))

Rutas de acceso de clave

Una expresión de ruta de acceso de clave hace referencia a una propiedad del objeto Feature que se está evaluando para mostrarse. Por ejemplo, si el diccionario Feature.properties de un polígono contiene la clave floorCount, la ruta de acceso de la clave floorCount hace referencia al valor de la propiedad floorCount al evaluar ese polígono concreto.

Es posible que algunos caracteres no se utilicen directamente como parte de una ruta de acceso de clave en una cadena de formato. Por ejemplo, si la propiedad de una característica se denomina ISO 3166-1:2006, una cadena de formato de expresión de lowercase(ISO 3166-1:2006) o una cadena de formato de predicado de ISO 3166-1:2006 == 'US-OH' generaría una excepción. En su lugar, use un marcador de posición %K o el inicializador NSExpression(forKeyPath:):

NSPredicate(format: "%K == 'US-OH'", "ISO 3166-1:2006")
NSExpression(
   forFunction: "lowercase:",
   arguments: [NSExpression(forKeyPath: "ISO 3166-1:2006")]
)

Functions

De las funciones predefinidas por el método NSExpression(forFunction:arguments:), el siguiente subconjunto se admite en las opciones de capa:

Parámetro initializer Sintaxis de cadena de formato
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)
length: length('Wapakoneta')
castObject:toType: CAST(ele, 'NSString')
CAST(ele, 'NSNumber')

No se admiten las siguientes funciones predefinidas:

Parámetro initializer Sintaxis de cadena de formato
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)

Condicionales

Los condicionales se admiten mediante el método NSExpression(forAZMConditional:trueExpression:falseExpression:) y el operador TERNARY() integrados. Si necesita expresar varios casos ("else-if"), puede anidar un condicional dentro de un condicional o usar la expresión de coincidencia.

Ejemplo de condicionales

En el ejemplo siguiente se recorren diferentes predicados hasta encontrar uno que se evalúe como true y, luego, se devuelve esa expresión true. Si ningún predicado se evalúa como true, se devolverá la última expresión falsa.

let layer = BubbleLayer(
    source: source,
    options: [
        .bubbleColor(
            from: NSExpression(
                // Check to see whether a feature has a zoneColor property
                forAZMConditional: NSPredicate(format: "zoneColor != NIL"),
                // If it has a zoneColor property, use its value as a color.
                trueExpression: NSExpression(forKeyPath: "zoneColor"),
                // if not, do another check
                falseExpression: NSExpression(
                    // Check to see whether it has a temperature property with a value greater than or equal to 100.
                    forConditional: NSPredicate(format: "temperature != nil && temperature >= 100"),
                    // If it has, use red color.
                    trueExpression: NSExpression(forConstantValue: UIColor.red),
                    // If not, use green color.
                    falseExpression: NSExpression(forConstantValue: UIColor.green)
                )
            )
        )
    ]
)

Agregados

Las expresiones de agregado pueden contener matrices de expresiones. En algunos casos, es posible usar la propia matriz en lugar de encapsular la matriz en una expresión de agregado.

Variables

El iOS SDK define las siguientes variables para su uso con opciones de capa.

Identificador de características

Identificador de una característica. Esta variable corresponde a la propiedad NSExpression.featureIdentifierAZMVariable.

Sintaxis de cadena de formato: $featureIdentifier

Propiedades de características

Objeto de propiedades de una característica. Esta variable corresponde a la propiedad NSExpression.featurePropertiesAZMVariable.

Sintaxis de cadena de formato: $featureAttributes

Característica acumulada

El valor de una propiedad de clúster acumulada hasta el momento. Solo se puede usar en la opción clusterProperties de un origen de DataSource agrupado. Esta variable corresponde a la propiedad NSExpression.featureAccumulatedAZMVariable.

Sintaxis de cadena de formato: $featureAccumulated

Tipo Geometry

Tipo de geometría representado por la característica. El tipo de una característica es una de las cadenas siguientes:

  • Point para las características de punto, correspondientes a la clase Point.
  • MultiPoint para las características de la colección de puntos, correspondientes a la clase PointCollection.
  • LineString para las características de polilínea, correspondientes a la clase Polyline.
  • MultiLineString para varias características de polilíneas, correspondientes a la clase MultiPolyline.
  • Polygon para las características de polígono, correspondientes a la clase Polygon.
  • MultiPolygon para varias características de polígonos, correspondientes a la clase MultiPolygon.
  • GeometryCollection para las características de la colección Geometry, correspondientes a la clase GeometryCollection.

Esta variable corresponde a la propiedad NSExpression.geometryTypeAZMVariable.

Sintaxis de cadena de formato: $geometryType

Ejemplo de variables

Consulte Ejemplos de operandos.

Zoom

Nivel de zoom actual. En las opciones de estilo de la capa, esta variable solo puede aparecer como el destino de una interpolación de nivel superior o una expresión de paso. Esta variable corresponde a la propiedad NSExpression.zoomLevelAZMVariable.

Sintaxis de cadena de formato: $zoomLevel

Ejemplo de zoom

De forma predeterminada, los radios de los puntos de datos representados en la capa del mapa térmico tienen un radio de punto fijo para todos los niveles de zoom. A medida que se amplía el mapa, los datos se agregan juntos y la capa de mapa térmico parece diferente. Una expresión zoom puede usarse para ampliar el radio de cada nivel de zoom de forma que cada punto de datos cubra el mismo área físico del mapa. Hará que la capa de mapa térmico parezca más estática y coherente. Cada nivel de zoom del mapa tiene dos veces tantos puntos vertical y horizontalmente como el nivel de zoom anterior. Al escalar el radio, de modo que se duplique con cada nivel de zoom, se creará un mapa de calor que se verá consistente en todos los niveles de zoom. Puede realizarse mediante la expresión zoom con una expresión base 2 exponential interpolation, con el radio de punto establecido para el nivel mínimo de zoom y un radio escalado para el nivel máximo de zoom calculado como pow(2, maxZoom - minZoom) * radius, tal como se muestra a continuación.

let layer = HeatMapLayer(
   source: source,
   options: [
      .heatmapRadius(
         from: NSExpression(
            forAZMInterpolating: .zoomLevelAZMVariable,
            curveType: .exponential,
            parameters: NSExpression(forConstantValue: 2),
            stops: NSExpression(forConstantValue: [
               // For zoom level 1 set the radius to 2 points.
               1: 2,

               // Between zoom level 1 and 19, exponentially scale the radius from 2 points to 2 * 2^(maxZoom - minZoom) points.
               19: pow(2, 19 - 1) * 2
            ])
         )
      )
   ]
)

Densidad de mapa térmico

Estimación de la densidad del kernel de un punto de pantalla en una capa de mapa térmico; en otras palabras, una medida relativa de cuántos puntos de datos están llenos alrededor de un píxel determinado. Esta variable se evalúa como un número entre 0 y 1. Se usa en combinación con una expresión interpolation o step para definir el degradado de color empleado para colorear el mapa térmico. Solo se puede usar en la opción heatmapColor de la capa de mapa térmico. Esta variable corresponde a la propiedad NSExpression.heatmapDensityAZMVariable.

Sintaxis de cadena de formato: $heatmapDensity

Sugerencia

El color del índice 0 de una expresión de interpolación o el color predeterminado de un paso definen el color del área donde no hay ningún dato. El color del índice 0 se puede usar para definir el color de fondo. Muchos prefieren establecer este valor en transparente o en un negro semitransparente.

Ejemplo de densidad de mapa térmico

En este ejemplo se usa una expresión de interpolación lineal para crear un degradado de color suave para representar el mapa térmico.

let layer = HeatMapLayer(
   source: source,
   options: [
      .heatmapColor(
         from: NSExpression(
            forAZMInterpolating: .heatmapDensityAZMVariable,
            curveType: .linear,
            parameters: nil,
            stops: NSExpression(forConstantValue: [
               0: UIColor.magenta.withAlphaComponent(0),
               0.01: UIColor.magenta,
               0.5: UIColor(red: 251 / 255, green: 0, blue: 251 / 255, alpha: 1),
               1: UIColor(red: 0, green: 195 / 255, blue: 1, alpha: 1)
            ])
         )
      )
   ]
)

Además de usar un degradado suave para colorear un mapa térmico, se pueden especificar colores dentro de un conjunto de intervalos mediante una expresión de paso. El uso de una expresión de paso para colorear el mapa térmico separa visualmente la densidad en intervalos, lo que recuerda a un mapa de estilo de contorno o radar.

let layer = HeatMapLayer(
   source: source,
   options: [
      .heatmapColor(
         from: NSExpression(
            forAZMStepping: .heatmapDensityAZMVariable,
            from: NSExpression(forConstantValue: UIColor.clear),
            stops: NSExpression(forConstantValue: [
               0.01: UIColor(red: 0, green: 0, blue: 128 / 255, alpha: 1),
               0.25: UIColor.cyan,
               0.5: UIColor.green,
               0.75: UIColor.yellow,
               1: UIColor.red
            ])
         )
      )
   ]
)

Para más información, consulte el artículo Agregar una capa de mapa térmico.

Progreso de la línea

Número que indica la distancia relativa a lo largo de una línea en un punto determinado a lo largo de la línea. Esta variable se evalúa como 0 al principio de la línea y 1 al final de la línea. Solo puede usarse con la opción LineLayerOption.strokeGradient de la capa de línea. Corresponde a la propiedad NSExpression.lineProgressAZMVariable.

Sintaxis de cadena de formato: $lineProgress

Nota

La opción strokeGradient de la capa de línea requiere que la opción lineMetrics del origen de datos esté establecida en true.

Ejemplo de progreso de línea

En este ejemplo, se usa la expresión NSExpression.lineProgressAZMVariable para aplicar un degradado de color al trazo de una línea.

let layer = LineLayer(
   source: source,
   options: [
      .strokeGradient(
         from: NSExpression(
            forAZMInterpolating: NSExpression.lineProgressAZMVariable,
            curveType: .linear,
            parameters: nil,
            stops: NSExpression(forConstantValue: [
               0: UIColor.blue,
               0.1: UIColor(red: 0.25, green: 0.41, blue: 1, alpha: 1), // Royal Blue
               0.3: UIColor.cyan,
               0.5: UIColor(red: 0, green: 1, blue: 0, alpha: 1), // Lime
               0.7: UIColor.yellow,
               1: UIColor.red
            ])
         )
      )
   ]
)

Vea un ejemplo en vivo.

Métodos específicos de Azure Maps

En la sección siguiente se muestran métodos específicos de Azure Maps que extienden la clase NSExpression.

Expresión match

Una expresión de coincidencia es un tipo de expresión condicional que proporciona la instrucción switch como lógica. La entrada puede ser cualquier expresión, como NSExpression(forKeyPath: "entityType") que devuelve una cadena o un número. Las expresiones coincidentes son un diccionario, que deberá tener claves como expresiones que se evalúan como una sola cadena o un número o una matriz de todas las cadenas o todos los números y valores como cualquier expresión. Si el tipo de expresión de entrada no coincide con el tipo de las claves, el resultado será el valor de reserva predeterminado.

Ejemplos de expresiones de coincidencia

En el ejemplo siguiente se examina la propiedad entityType de una característica Point en una capa de burbuja y se busca una coincidencia. Si se encuentra una coincidencia, se devuelve ese valor especificado o se devuelve el valor de retroceso.

let layer = BubbleLayer(
    source: source,
    options: [
        .bubbleColor(
            from: NSExpression(
                // Get the input value to match.
                forAZMMatchingKey: NSExpression(forKeyPath: "entityType"),
                // List the keys to match and the value to return for each match.
                in: [
                    // If value is "restaurant" return red color.
                    NSExpression(forConstantValue: "restaurant"): NSExpression(forConstantValue: UIColor.red),
                    // If value is "park" return green color.
                    NSExpression(forConstantValue: "park"): NSExpression(forConstantValue: UIColor.green)
                ],
                // Specify a default value to return if no match is found.
                default: NSExpression(forConstantValue: UIColor.black)
            )
        )
    ]
)

En el ejemplo siguiente se usa una expresión que se evalúa como matriz de cadenas para especificar un conjunto de etiquetas que deben devolver el mismo valor. Este enfoque es mucho más eficiente que enumerar cada etiqueta por separado. En este caso, si la propiedad entityType es "restaurant" o "grocery_store", se devolverá el color rojo.

let layer = BubbleLayer(
    source: source,
    options: [
        .bubbleColor(
            from: NSExpression(
                // Get the input value to match.
                forAZMMatchingKey: NSExpression(forKeyPath: "entityType"),
                // List the keys to match and the value to return for each match.
                in: [
                    // If value is "restaurant" or "grocery_store" return red color.
                    NSExpression(forConstantValue: ["restaurant", "grocery_store"]): NSExpression(forConstantValue: UIColor.red),
                    // If value is "park" return green color.
                    NSExpression(forConstantValue: "park"): NSExpression(forConstantValue: UIColor.green)
                ],
                // Specify a default value to return if no match is found.
                default: NSExpression(forConstantValue: UIColor.black)
            )
        )
    ]
)

Expresión coalesce

Una expresión coalesce recorre un conjunto de expresiones hasta que se obtiene el primer valor distinto de null y devuelve ese valor.

Ejemplo de expresión coalesce

En el ejemplo siguiente se usa una expresión coalesce para establecer la opción textField de una capa de símbolos. Si faltase la propiedad title de la característica o está establecida en nil, la expresión intentará buscar la propiedad subTitle y, si faltase o fuera nil, devolverá una cadena vacía.

let layer = SymbolLayer(
    source: source,
    options: [
        .textField(
            from: NSExpression(forAZMFunctionCoalesce: [
                // Try getting the title property.
                NSExpression(forKeyPath: "title"),

                // If there is no title, try getting the subTitle.
                NSExpression(forKeyPath: "subTitle"),

                // Default to an empty string.
                NSExpression(forConstantValue: "")
            ])
        )
    ]
)

Expresión de combinación

Una varias cadenas. Cada valor debe ser una cadena o un número.

Ejemplo de expresión de combinación

En el ejemplo siguiente se une la propiedad temperature de la característica de punto y "°F".

let layer = SymbolLayer(
    source: source,
    options: [
        .textField(
            from: NSExpression(forAZMFunctionJoin: [
                NSExpression(forKeyPath: "temperature"),
                NSExpression(forConstantValue: "°F")
            ])
        ),

        // Some additional style options.
        .textOffset(CGVector(dx: 0, dy: -1.5)),
        .textSize(12),
        .textColor(.white)
    ]
)

La expresión anterior representa una chincheta en el mapa con el texto "64°F" superpuesto sobre ella, como se muestra en la imagen siguiente.

Ejemplo de expresión de combinación

Expresiones de interpolación y de paso

Las expresiones de interpolación o de paso se pueden usar para calcular valores a lo largo de una curva interpolada o una función de paso. Estas expresiones toman una expresión que devuelve un valor numérico como entrada, por ejemplo NSExpression(forKeyPath: "temperature"). El valor de entrada se evalúa con pares de valores de entrada y salida para determinar el valor que mejor se adapta a la curva interpolada o a la función de paso. Los valores de salida se denominan "paradas". Los valores de entrada de cada parada deben ser un número y estar en orden ascendente. Los valores de salida deben ser un número, una matriz de números o un color.

Expresión de interpolación

Una expresión de interpolación puede usarse para calcular un conjunto continuo y fluido de valores mediante la interpolación entre valores de parada.

Hay tres tipos de métodos de interpolación que se pueden usar en una expresión de interpolación:

Nombre Descripción Parámetros
ExpressionInterpolationMode.linear Interpola linealmente entre el par de paradas. nil
ExpressionInterpolationMode.exponential Interpola exponencialmente entre las paradas. Se especifica una base y controla la velocidad a la que aumenta la salida. Los valores más altos hacen que aumente la salida más hacia el extremo superior del intervalo. Un valor de base cercano a 1 genera una salida que aumenta más linealmente. Expresión que se evalúa como un número, especificando la base de la interpolación exponencial.
ExpressionInterpolationMode.cubicBezier Interpola mediante una curva Bézier cúbica definida por los puntos de control especificados. Matriz o expresión de agregado que contiene cuatro expresiones, cada una de las que se evalúa como un número. Los cuatro números son puntos de control para la curva Bézier cúbica.

Este es un ejemplo del aspecto de estos diferentes tipos de interpolaciones.

Lineal Exponencial Bézier cúbica
Gráfico de interpolación lineal Gráfico de interpolación exponencial Gráfico de interpolación de Bézier cúbica
Ejemplo de expresiones de interpolación

En el ejemplo siguiente se usa una expresión de interpolación lineal para establecer la propiedad bubbleColor de una capa de burbuja según la propiedad temperature de la característica de punto. Si el valor de temperature es inferior a 60, se devolverá el color azul. Si es mayor que 60 y menor que 70, se devolverá el amarillo. Si es mayor que 70 y menor que 80, se devolverá el naranja. Si es 80 o superior, se devolverá el rojo.

let layer = BubbleLayer(
    source: source,
    options: [
        .bubbleColor(
            from: NSExpression(
                forAZMInterpolating: NSExpression(forKeyPath: "temperature"),
                curveType: .linear,
                parameters: nil,
                stops: NSExpression(forConstantValue: [
                    50: UIColor.blue,
                    60: UIColor.yellow,
                    70: UIColor.orange,
                    80: UIColor.red
                ])
            )
        )
    ]
)

En la siguiente imagen se muestra cómo se eligen los colores de la expresión anterior.

Ejemplo de expresión de interpolación

Expresión de paso

Una expresión de paso puede usarse para calcular valores de resultados escalonados discretos mediante la evaluación de una función constante a trozos definida por paradas.

Las expresiones de paso devuelven el valor de salida de la parada justo antes del valor de entrada, o el valor from si la entrada es menor que la primera parada.

Ejemplo de expresión de paso

En el ejemplo siguiente se usa una expresión de paso para establecer la propiedad bubbleColor de una capa de burbuja según la propiedad temperature de la característica de punto. Si el valor de temperature es inferior a 60, se devolverá el azul. Si es mayor que 60 y menor que 70, se devolverá el amarillo. Si es mayor que 70 y menor que 80, se devolverá el naranja. Si es 80 o superior, se devolverá el rojo.

let layer = BubbleLayer(
    source: source,
    options: [
        .bubbleColor(
            from: NSExpression(
                forAZMStepping: NSExpression(forKeyPath: "temperature"),
                from: NSExpression(forConstantValue: UIColor.blue),
                stops: NSExpression(forConstantValue: [
                    50: UIColor.blue,
                    60: UIColor.yellow,
                    70: UIColor.orange,
                    80: UIColor.red
                ])
            )
        )
    ]
)

En la siguiente imagen se muestra cómo se eligen los colores de la expresión anterior.

Ejemplo de expresión de paso

Información adicional

Más información sobre las capas que admiten expresiones: