bmt22033
bmt22033

Reputation: 7240

Building an expression dynamically using Mapbox Maps iOS SDK v10?

I'm using the Mapbox Maps iOS SDK v10 in an app and I have a layer that renders circles on the map which represent the location of various features. Each feature has several properties including a string "type" like "CAR", "BOAT", "AIRCRAFT", etc. I'm using a color expression to determine what color each circle should be based on the "type" value of the feature. Currently, that expression is constructed like this:

let colorExpression = Exp(.match) {
    Exp(.get) { "type" }
    "CAR"
    UIColor.systemBlue
    "BOAT"
    UIColor.systemRed
    "AIRCRAFT"
    UIColor.systemGreen
    UIColor.systemGray // default color if some other "type" value
}

This worked well enough initially because there were a limited number of values for a feature's "type" property so hard coding those values was a workable solution. However, the feature data comes from a server and, from time to time, new feature "types" are introduced. So instead of needing to add more hard-coded type values and make a new build of the app every time this happens (which I don't always know about in advance), I'd like to be able to build this expression "dynamically" using data that I get back from the API call to the server.

For example, assume that post-deserialization, I have types and UIColor values in a dictionary like this:

var typeColors: [String: UIColor] = [
   "CAR" : UIColor.systemBlue,
   "BOAT" : UIColor.systemRed,
   "AIRCRAFT" : UIColor.systemGreen,
   "BICYCLE" : UIColor.systemYellow
]

I would like to iterate that dictionary and construct the color expression using those key value pairs. Something along the lines of:

var typeColorArray: [Any] = []
for (k, v) in typeColors {
    typeColorArray.append(k)
    typeColorArray.append(v)
}

let colorExpression = Exp(.match) {
    Exp(.get) { "type" }
    typeColorArray
    UIColor.systemGray // default color if some other "type" value
}

The Mapbox iOS SDK docs are not terribly verbose with regard to the expression DSL and I couldn't find an example quite like this in the examples hosted in the GitHub repo (https://github.com/mapbox/mapbox-maps-ios/tree/main/Apps/Examples/Examples/All%20Examples). Does anyone know if it's possible to create a color expression like this?

Upvotes: 0

Views: 300

Answers (1)

和天下
和天下

Reputation: 1

        let dic: [Double: UIColor] = [
            0: UIColor.red,
            0.5: UIColor.blue,
            1: UIColor.white
        ]
        var gradientExpressionArguments: [Expression.Argument] = [
            Expression.Argument.expression(Exp(.linear)),
            Expression.Argument.expression(Exp(.lineProgress))
        ]
        
        for (stop, color) in dic.sorted(by: { $0.key < $1.key }) {
            gradientExpressionArguments.append(.number(Double(stop)))
                 let components = color.cgColor.components!
            gradientExpressionArguments.append(.string("rgba(\(String(format: "%.2f", components[0]*255.0)),\(String(format: "%.2f", components[1]*255.0)),\(String(format: "%.2f", components[2]*255.0)),1.00)"))
             }

        let gradientExpression = Exp(operator: .interpolate, arguments:gradientExpressionArguments )
        layer.lineGradient = .expression(gradientExpression)


Upvotes: 0

Related Questions