Skip to content

Commit

Permalink
[CP] Typed API for layer slots (#1926)
Browse files Browse the repository at this point in the history
* Typed API for layer slots (#1875)

* Typed API for layer slots

* Add changelog entry

* Rename LayerSlot to Slot

* Update API allowlist

* Update mapbox-maps-ios/CHANGELOG.md

Co-authored-by: Ivan Persidsky <ivan.persidskii@mapbox.com>

* Add API reference link

* Move slot into a seprate file

* Apply suggestions from code review

Co-authored-by: Patrick Leonard <pjleonard37@users.noreply.github.com>

* Fix changelog

* Fix tests

---------

Co-authored-by: Ivan Persidsky <ivan.persidskii@mapbox.com>
Co-authored-by: Patrick Leonard <pjleonard37@users.noreply.github.com>

* Fix changelog

---------

Co-authored-by: Ivan Persidsky <ivan.persidskii@mapbox.com>
Co-authored-by: Patrick Leonard <pjleonard37@users.noreply.github.com>
  • Loading branch information
3 people committed Nov 20, 2023
1 parent 7802b71 commit dcaec9b
Show file tree
Hide file tree
Showing 27 changed files with 117 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ private final class Route {
routeLayer.lineColor = .expression(colorExpression(normal: "#999999", selected: "#57A9FB"))
routeLayer.lineBorderWidth = .constant(2)
routeLayer.lineBorderColor = .expression(colorExpression(normal: "#666666", selected: "#327AC2"))
routeLayer.slot = "middle"
routeLayer.slot = .middle
try! mapView.mapboxMap.addLayer(routeLayer)

// Annotation
Expand Down
6 changes: 4 additions & 2 deletions Apps/Examples/Examples/All Examples/LayerSlotExample.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ public class LayerSlotExample: UIViewController, ExampleProtocol {
}

@objc private func segmentedControlValueChanged(_ sender: UISegmentedControl) {
guard let slotName = sender.titleForSegment(at: sender.selectedSegmentIndex)?.lowercased() else { return }

try! mapView.mapboxMap.updateLayer(withId: self.layer.id, type: FillLayer.self, update: { layer in
layer.slot = sender.titleForSegment(at: sender.selectedSegmentIndex)?.lowercased()
layer.slot = Slot(rawValue: slotName)
})
}

Expand All @@ -60,7 +62,7 @@ public class LayerSlotExample: UIViewController, ExampleProtocol {
layer.fillOutlineColor = .constant(StyleColor(#colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)))

// If a slot is not supplied, the layer is added above all other layers by default.
layer.slot = "bottom"
layer.slot = .bottom

// Create a new GeoJSON data source which gets its data from a polygon.
source.data = .geometry(.polygon(.init([[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ internal class StandardStyleExample: UIViewController, ExampleProtocol {
layer.lineColor = .constant(StyleColor.init(UIColor.orange))
layer.lineWidth = .constant(8)
// The borders renders in the same "bottom" slot with water, but added later, so it renders above.
layer.slot = "bottom"
layer.slot = .bottom

// Create a new GeoJSON data source of the line's coordinates
var source = GeoJSONSource(id: "line-layer")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ struct AnnotationsOrderTestExample: View {
var layer = FillLayer(id: "purple-layer", source: "pl")
layer.fillColor = .constant(StyleColor(.purple))
layer.fillOpacity = .constant(0.3)
layer.slot = "middle"
layer.slot = .middle

var source = GeoJSONSource(id: "pl")
let circlePolygon = Polygon(center: .init(latitude: 17, longitude: 12), radius: 3000000, vertices: 60)
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Mapbox welcomes participation and contributions from everyone.

## main

* Introduce [`Slot`](https://docs.mapbox.com/ios/maps/api/11.0.0-rc.2 -docc/documentation/mapboxmaps/slot) for assining a layer to a slot.

## 11.0.0-rc.2 - 17 November, 2023

### Breaking changes ⚠️
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ not specified | Above all existing layers in the style

```swift
var layer = LineLayer(id: "line-layer", source: "line-source")
layer.slot = "middle"
layer.slot = .middle
mapView.mapboxMap.addLayer(layer)
```

Expand Down Expand Up @@ -117,7 +117,7 @@ In addition to modifying the configuration properties of the imported styles, yo

```swift
var layer = LineLayer(id: "line-layer", source: "line-source")
layer.slot = "middle"
layer.slot = .middle
mapView.mapboxMap.addLayer(layer)
```

Expand Down
24 changes: 24 additions & 0 deletions Sources/MapboxMaps/Foundation/Extensions/Core/Slot.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Foundation

/// A pre-specified location in the style where layer will be added to
/// (such as on top of existing land layers, but below all labels).
public struct Slot: Equatable, Codable, RawRepresentable, ExpressibleByStringLiteral {
/// Above POI labels and behind Place and Transit labels
public static let top = Slot(rawValue: "top")

/// Above lines (roads, etc.) and behind 3D buildings
public static let middle = Slot(rawValue: "middle")

/// Above polygons (land, landuse, water, etc.)
public static let bottom = Slot(rawValue: "bottom")

public let rawValue: String

public init?(rawValue: String) {
self.rawValue = rawValue
}

public init(stringLiteral value: String) {
self.rawValue = value
}
}
6 changes: 3 additions & 3 deletions Sources/MapboxMaps/Style/CustomLayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public struct CustomLayer: Layer {

public let type: LayerType = .custom

public var slot: String?
public var slot: Slot?

public var minZoom: Double?

Expand All @@ -27,7 +27,7 @@ public struct CustomLayer: Layer {
public init(
id: String,
renderer: CustomLayerHost,
slot: String? = nil,
slot: Slot? = nil,
minZoom: Double? = nil,
maxZoom: Double? = nil,
visibility: Value<Visibility> = .constant(.visible)
Expand Down Expand Up @@ -63,7 +63,7 @@ extension CustomLayer {
self.id = try container.decode(String.self, forKey: .id)
self.minZoom = try container.decodeIfPresent(Double.self, forKey: .minZoom)
self.maxZoom = try container.decodeIfPresent(Double.self, forKey: .maxZoom)
self.slot = try container.decodeIfPresent(String.self, forKey: .slot)
self.slot = try container.decodeIfPresent(Slot.self, forKey: .slot)

if let layoutContainer = try? container.nestedContainer(keyedBy: CodingKeys.Layout.self, forKey: .layout),
let visibilityEncoded = try layoutContainer.decodeIfPresent(Value<Visibility>.self, forKey: .visibility) {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Sources/MapboxMaps/Style/Generated/Layers/CircleLayer.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Sources/MapboxMaps/Style/Generated/Layers/FillLayer.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Sources/MapboxMaps/Style/Generated/Layers/HeatmapLayer.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Sources/MapboxMaps/Style/Generated/Layers/LineLayer.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Sources/MapboxMaps/Style/Generated/Layers/ModelLayer.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Sources/MapboxMaps/Style/Generated/Layers/RasterLayer.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Sources/MapboxMaps/Style/Generated/Layers/SkyLayer.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Sources/MapboxMaps/Style/Generated/Layers/SymbolLayer.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Sources/MapboxMaps/Style/Layer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public protocol Layer: Codable, StyleEncodable, StyleDecodable {
var maxZoom: Double? { get set }

/// The slot this layer is assigned to. If specified, and a slot with that name exists, it will be placed at that position in the layer order.
var slot: String? { get set }
var slot: Slot? { get set }
}

extension Layer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ final class CircleAnnotationIntegrationTests: MapViewIntegrationTestCase {
// Test that the value is synced to the layer
manager.syncSourceAndLayerIfNeeded()
var layer = try mapView.mapboxMap.layer(withId: self.manager.layerId, type: CircleLayer.self)
let actualValue = layer.slot
XCTAssertEqual(actualValue, value)
let actualValue = layer.slot?.rawValue
XCTAssertEqual(actualValue, value)

// Test that the property can be reset to nil
manager.slot = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -776,8 +776,8 @@ final class PointAnnotationIntegrationTests: MapViewIntegrationTestCase {
// Test that the value is synced to the layer
manager.syncSourceAndLayerIfNeeded()
var layer = try mapView.mapboxMap.layer(withId: self.manager.layerId, type: SymbolLayer.self)
let actualValue = layer.slot
XCTAssertEqual(actualValue, value)
let actualValue = layer.slot?.rawValue
XCTAssertEqual(actualValue, value)

// Test that the property can be reset to nil
manager.slot = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ final class PolygonAnnotationIntegrationTests: MapViewIntegrationTestCase {
// Test that the value is synced to the layer
manager.syncSourceAndLayerIfNeeded()
var layer = try mapView.mapboxMap.layer(withId: self.manager.layerId, type: FillLayer.self)
let actualValue = layer.slot
XCTAssertEqual(actualValue, value)
let actualValue = layer.slot?.rawValue
XCTAssertEqual(actualValue, value)

// Test that the property can be reset to nil
manager.slot = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ final class PolylineAnnotationIntegrationTests: MapViewIntegrationTestCase {
// Test that the value is synced to the layer
manager.syncSourceAndLayerIfNeeded()
var layer = try mapView.mapboxMap.layer(withId: self.manager.layerId, type: LineLayer.self)
let actualValue = layer.slot
XCTAssertEqual(actualValue, value)
let actualValue = layer.slot?.rawValue
XCTAssertEqual(actualValue, value)

// Test that the property can be reset to nil
manager.slot = nil
Expand Down
Loading

0 comments on commit dcaec9b

Please sign in to comment.