Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 8 additions & 34 deletions Sources/Examples/All Examples/DistanceExpressionExample.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,43 +44,17 @@ final class DistanceExpressionExample: UIViewController, ExampleProtocol {
// This expression simulates a `CircleLayer` with a radius of 150 meters. For features that will be
// visible at lower zoom levels, add more stops at the zoom levels where the feature will be more
// visible. This keeps the circle's radius more consistent.

let radii: [Double] = [0, 5, 10, 15, 16, 16.5, 17, 17.5, 18, 18.5, 19, 19.5, 20, 20.5, 21, 21.5, 22]

let circleRadiusExp = Exp(.interpolate) {
Exp(.linear)
Exp(.zoom)
0
circleRadius(forZoom: 0)
5
circleRadius(forZoom: 5)
10
circleRadius(forZoom: 10)
15
circleRadius(forZoom: 15)
16
circleRadius(forZoom: 16)
16.5
circleRadius(forZoom: 16.5)
17
circleRadius(forZoom: 17)
17.5
circleRadius(forZoom: 17.5)
18
circleRadius(forZoom: 18)
18.5
circleRadius(forZoom: 18.5)
19
circleRadius(forZoom: 19)
19.5
circleRadius(forZoom: 19.5)
20
circleRadius(forZoom: 20)
20.5
circleRadius(forZoom: 20.5)
21
circleRadius(forZoom: 21)
21.5
circleRadius(forZoom: 21.5)
22
circleRadius(forZoom: 22)

for radius in radii {
radius
circleRadius(forZoom: radius)
}
}
circleLayer.circleRadius = .expression(circleRadiusExp)
circleLayer.circleOpacity = .constant(0.3)
Expand Down
69 changes: 29 additions & 40 deletions Sources/Examples/All Examples/FeatureStateExample.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import UIKit
import MapboxMaps

final class FeatureStateExample: UIViewController, ExampleProtocol {
private struct EarthquakeThreshold {
let magnitude: Double
let colorHEX: String
let radius: Double
}

private var mapView: MapView!
private var descriptionView: EarthquakeDescriptionView!
private var selectedFeature: FeaturesetFeature?
Expand All @@ -16,6 +22,19 @@ final class FeatureStateExample: UIViewController, ExampleProtocol {
return dateFormatter
}()

private let earthquakeThresholds = [
EarthquakeThreshold(magnitude: 1, colorHEX: "#fff7ec", radius: 8),
EarthquakeThreshold(magnitude: 1.5, colorHEX: "#fee8c8", radius: 10),
EarthquakeThreshold(magnitude: 2, colorHEX: "#fdd49e", radius: 12),
EarthquakeThreshold(magnitude: 2.5, colorHEX: "#fdbb84", radius: 14),
EarthquakeThreshold(magnitude: 3, colorHEX: "#fc8d59", radius: 16),
EarthquakeThreshold(magnitude: 3.5, colorHEX: "#ef6548", radius: 18),
EarthquakeThreshold(magnitude: 4.5, colorHEX: "#d7301f", radius: 20),
EarthquakeThreshold(magnitude: 6.5, colorHEX: "#b30000", radius: 22),
EarthquakeThreshold(magnitude: 8.5, colorHEX: "#7f0000", radius: 24),
EarthquakeThreshold(magnitude: 10.5, colorHEX: "#000", radius: 26)
]

override func viewDidLoad() {
super.viewDidLoad()

Expand Down Expand Up @@ -96,26 +115,11 @@ final class FeatureStateExample: UIViewController, ExampleProtocol {
Exp(.interpolate) {
Exp(.linear)
Exp(.get) { "mag" }
1
8
1.5
10
2
12
2.5
14
3
16
3.5
18
4.5
20
6.5
22
8.5
24
10.5
26

for threshold in earthquakeThresholds {
threshold.magnitude
threshold.radius
}
}
5
}
Expand All @@ -136,26 +140,11 @@ final class FeatureStateExample: UIViewController, ExampleProtocol {
Exp(.interpolate) {
Exp(.linear)
Exp(.get) { "mag" }
1
"#fff7ec"
1.5
"#fee8c8"
2
"#fdd49e"
2.5
"#fdbb84"
3
"#fc8d59"
3.5
"#ef6548"
4.5
"#d7301f"
6.5
"#b30000"
8.5
"#7f0000"
10.5
"#000"

for threshold in earthquakeThresholds {
threshold.magnitude
threshold.colorHEX
}
}
"#000"
}
Expand Down
27 changes: 27 additions & 0 deletions Sources/MapboxMaps/Style/Types/ExpressionArgumentBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@ public struct ExpressionArgumentBuilder {
public static func buildBlock(_ arguments: ExpressionArgumentConvertible...) -> [Exp.Argument] {
return arguments.flatMap { $0.expressionArguments }
}

/// :nodoc:
public static func buildOptional(_ component: ExpressionArgumentConvertible?) -> [Exp.Argument] {
return component?.expressionArguments ?? []
}

/// :nodoc:
public static func buildEither(first argument: ExpressionArgumentConvertible) -> [Exp.Argument] {
return argument.expressionArguments
}

/// :nodoc:
public static func buildEither(second argument: ExpressionArgumentConvertible) -> [Exp.Argument] {
return argument.expressionArguments
}

/// :nodoc:
public static func buildArray(_ arguments: [ExpressionArgumentConvertible]) -> [Exp.Argument] {
return arguments.flatMap { $0.expressionArguments }
}

/// :nodoc:
public static func buildLimitedAvailability(_ argument: ExpressionArgumentConvertible) -> [Exp.Argument] {
return argument.expressionArguments
}
}

/// :nodoc:
Expand Down Expand Up @@ -67,6 +92,8 @@ extension Array: ExpressionArgumentConvertible {
return [.stringArray(validStringArray)]
} else if let validNumberArray = self as? [Double] {
return [.numberArray(validNumberArray)]
} else if let argumentArray = self as? [Exp.Argument] {
return argumentArray
} else {
Log.warning("Unsupported array provided to Expression. Only [String] and [Double] are supported.", category: "Expressions")
return []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,84 @@ final class ExpressionTests: XCTestCase {
XCTAssertNotEqual(shortFormExpression, longFormExpression)
}

func testExpressionArgumentResultBuilder() throws {
let values: [Double] = [1, 2, 3, 4]
let eitherFirst: String? = "eitherFirst"
let eitherSecond = "eitherSecond"
let optional: String? = "optional"
let limitedAvailability = "limitedAvailability"

let writtenOutExpression = Exp(.match) {
"foo"

"eitherFirst"
1

eitherSecond
2

"optional"
3

limitedAvailability
4

"array"
Exp(.interpolate) {
Exp(.linear)
Exp(.zoom)
values[0]
values[0]
values[1]
values[1]
values[2]
values[2]
values[3]
values[3]
}
}

let dslExpression = Exp(.match) {
"foo"

if let eitherFirst {
eitherFirst
} else {
"failure"
}
1

if false {
"failure"
} else {
eitherSecond
}
2

if let optional {
optional
}
3

if #available(iOS 13, *) {
limitedAvailability
}
4

"array"
Exp(.interpolate) {
Exp(.linear)
Exp(.zoom)
for value in values {
value
value
}
}
}

XCTAssertEqual(writtenOutExpression, dslExpression)
}

func testEncodeImageOptions() throws {
let color = StyleColor(UIColor.black)
let empty = ImageOptions([:])
Expand Down