Skip to content

Commit 8824517

Browse files
evil159jakra-mb
authored andcommitted
Rename screen shape (#3377)
### GL native * Rename screen shape to screen culling shape * Use Vec2 instead of screen coordinate * Remove culling shape from init options ### Maps iOS * Expose API to set screen culling shape | iOS | Android | | --- | --- | | <video src="https://github.com/user-attachments/assets/e3d4acb8-01b1-4c53-ba76-8e05ff085426"> | <video src="https://github.com/user-attachments/assets/33122660-65ba-4f31-8eae-d180fe630c14"> | Addresses: https://mapbox.atlassian.net/browse/MAPSIOS-1811 and https://mapbox.atlassian.net/browse/MAPSAND-2119 cc @mapbox/sdk-ci --------- Co-authored-by: Jan Krassnigg <[email protected]> GitOrigin-RevId: 68a34816e8e5bacf61a119eb2503fc2cba59337c
1 parent 3ef033d commit 8824517

File tree

13 files changed

+139
-22
lines changed

13 files changed

+139
-22
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Mapbox welcomes participation and contributions from everyone.
44

55
## main
66

7+
* Expose an experimental API to define a non-rectangular screen culling shape(`MapboxMap.screenCullingShape`).
8+
79
## 11.12.0-beta.1 - 9 April, 2025
810

911
* Expose `graphicsPrograms`, `graphicsProgramsCreationTimeMillis` and `fboSwitchCount` for `CumulativeRenderingStatistics`.
@@ -17,7 +19,7 @@ Mapbox welcomes participation and contributions from everyone.
1719
## 11.11.0-rc.1 – 12 March, 2025
1820

1921
* Expose experimental API for setting ColorTheme on style imports.
20-
* Expose use-theme properties for all annotation types and Puck3D layer.
22+
* Expose use-theme properties for all annotation types and Puck3D layer.
2123
* Update CoreMaps to 11.11.0-rc.2.
2224
* Update Common to 24.11.0-rc.2.
2325

LICENSE.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MapboxMaps.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ Pod::Spec.new do |m|
1919
m.source_files = 'Sources/MapboxMaps/**/*.{swift,h}'
2020
m.resource_bundles = { 'MapboxMapsResources' => ['Sources/MapboxMaps/**/*.{xcassets,strings}', 'Sources/MapboxMaps/MapboxMaps.json', 'Sources/MapboxMaps/PrivacyInfo.xcprivacy'] }
2121

22-
m.dependency 'MapboxCoreMaps', '11.13.0-SNAPSHOT-04-23--04-29.git-3eea307'
23-
m.dependency 'MapboxCommon', '24.13.0-SNAPSHOT-04-23--04-29.git-3eea307'
22+
m.dependency 'MapboxCoreMaps', '11.13.0-SNAPSHOT-04-23--05-20.git-ad48dc8'
23+
m.dependency 'MapboxCommon', '24.13.0-SNAPSHOT-04-23--05-20.git-ad48dc8'
2424
m.dependency 'Turf', '4.0.0'
2525

2626
end

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
import PackageDescription
55
import Foundation
66

7-
let commonVersion: Version = "24.13.0-SNAPSHOT-04-23--04-29.git-3eea307"
8-
let coreMapsVersion: Version = "11.13.0-SNAPSHOT-04-23--04-29.git-3eea307"
7+
let commonVersion: Version = "24.13.0-SNAPSHOT-04-23--05-20.git-ad48dc8"
8+
let coreMapsVersion: Version = "11.13.0-SNAPSHOT-04-23--05-20.git-ad48dc8"
99
let turfVersion: Version = "4.0.0"
1010

1111
let mapboxMapsPath: String? = nil

Sources/Examples/All Examples/DebugMapExample.swift

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,37 @@ final class DebugMapExample: UIViewController, ExampleProtocol {
1717
Setting(option: .debug(.light), title: "Show light conditions"),
1818
Setting(option: .debug(.camera), title: "Show camera debug view"),
1919
Setting(option: .debug(.padding), title: "Camera padding"),
20+
Setting(option: .screenShape, title: "Custom culling shape"),
2021
Setting(option: .performance(.init([.perFrame, .cumulative], samplingDurationMillis: 5000)), title: "Performance statistics"),
2122
]
23+
private let customCullingShapeLayer: CAShapeLayer = {
24+
let layer = CAShapeLayer()
25+
layer.strokeColor = UIColor.white.cgColor
26+
layer.fillColor = UIColor.clear.cgColor
27+
layer.lineWidth = 3
28+
layer.lineJoin = .round
29+
layer.shadowColor = UIColor.white.cgColor
30+
layer.shadowRadius = 5
31+
layer.shadowOpacity = 1
32+
layer.shouldRasterize = true
33+
layer.rasterizationScale = UIScreen.main.scale
34+
return layer
35+
}()
36+
private let dimLayer: CAShapeLayer = {
37+
let layer = CAShapeLayer()
38+
layer.fillRule = .evenOdd
39+
layer.fillColor = UIColor.black.withAlphaComponent(0.5).cgColor
40+
41+
return layer
42+
}()
43+
private let customCullingShape = [
44+
CGPoint(x: 0.35, y: 0.34), // top-left
45+
CGPoint(x: 0.65, y: 0.34), // top-right
46+
CGPoint(x: 0.85, y: 0.50), // right
47+
CGPoint(x: 0.65, y: 0.66), // bottom-right
48+
CGPoint(x: 0.35, y: 0.66), // bottom-left
49+
CGPoint(x: 0.15, y: 0.50) // left
50+
]
2251

2352
override func viewDidLoad() {
2453
super.viewDidLoad()
@@ -76,10 +105,49 @@ final class DebugMapExample: UIViewController, ExampleProtocol {
76105
private func handle(statistics: PerformanceStatistics) {
77106
showAlert(with: "\(statistics.topRenderedGroupDescription)\n\(statistics.renderingDurationStatisticsDescription)")
78107
}
108+
109+
override func viewDidLayoutSubviews() {
110+
super.viewDidLayoutSubviews()
111+
112+
let scaledShape = customCullingShape.map { CGPoint(x: $0.x * mapView.bounds.width, y: $0.y * mapView.bounds.height) }
113+
let cutoutPath = UIBezierPath()
114+
cutoutPath.move(to: scaledShape.first!)
115+
scaledShape.dropFirst().forEach(cutoutPath.addLine)
116+
cutoutPath.close()
117+
118+
customCullingShapeLayer.path = cutoutPath.cgPath
119+
120+
let mapViewPath = UIBezierPath(rect: mapView.bounds)
121+
mapViewPath.append(cutoutPath)
122+
mapViewPath.usesEvenOddFillRule = true
123+
124+
dimLayer.path = mapViewPath.cgPath
125+
}
126+
127+
private func setScreenShape() {
128+
mapView.mapboxMap.screenCullingShape = customCullingShape
129+
mapView.layer.addSublayer(dimLayer)
130+
mapView.layer.addSublayer(customCullingShapeLayer)
131+
}
132+
133+
private func removeScreenShape() {
134+
customCullingShapeLayer.removeFromSuperlayer()
135+
dimLayer.removeFromSuperlayer()
136+
mapView.mapboxMap.screenCullingShape = []
137+
}
79138
}
80139

81140
extension DebugMapExample: DebugOptionSettingsDelegate {
82-
func settingsDidChange(debugOptions: MapViewDebugOptions, performanceOptions: PerformanceStatisticsOptions?) {
141+
func settingsDidChange(
142+
debugOptions: MapViewDebugOptions,
143+
performanceOptions: PerformanceStatisticsOptions?,
144+
screenShapeEnabled: Bool
145+
) {
146+
if screenShapeEnabled {
147+
setScreenShape()
148+
} else {
149+
removeScreenShape()
150+
}
83151
mapView.debugOptions = debugOptions
84152

85153
guard let performanceOptions else { return performanceStatisticsCancelable = nil }
@@ -133,16 +201,21 @@ final class SettingsViewController: UIViewController, UITableViewDataSource {
133201
}
134202

135203
@objc private func saveSettings(_ sender: UIBarButtonItem) {
136-
let debugOptions = settings
137-
.filter(\.isEnabled)
204+
let enabledSettings = settings.filter({ $0.isEnabled })
205+
let debugOptions = enabledSettings
138206
.compactMap(\.option.debugOption)
139207
.reduce(MapViewDebugOptions()) { result, next in result.union(next) }
140208

141-
let performanceOptions = settings
142-
.filter(\.isEnabled)
209+
let performanceOptions = enabledSettings
143210
.compactMap(\.option.performanceOption)
144211

145-
delegate?.settingsDidChange(debugOptions: debugOptions, performanceOptions: performanceOptions.first)
212+
let screenShapeEnabled = enabledSettings.contains(where: { $0.option.isScreenShape })
213+
214+
delegate?.settingsDidChange(
215+
debugOptions: debugOptions,
216+
performanceOptions: performanceOptions.first,
217+
screenShapeEnabled: screenShapeEnabled
218+
)
146219
dismiss(animated: true, completion: nil)
147220
}
148221

@@ -211,13 +284,18 @@ private class DebugOptionCell: UITableViewCell {
211284
}
212285

213286
protocol DebugOptionSettingsDelegate: AnyObject {
214-
func settingsDidChange(debugOptions: MapViewDebugOptions, performanceOptions: PerformanceStatisticsOptions?)
287+
func settingsDidChange(
288+
debugOptions: MapViewDebugOptions,
289+
performanceOptions: PerformanceStatisticsOptions?,
290+
screenShapeEnabled: Bool
291+
)
215292
}
216293

217294
private final class Setting {
218295
enum Option {
219296
case debug(MapViewDebugOptions)
220297
case performance(PerformanceStatisticsOptions)
298+
case screenShape
221299
}
222300

223301
let option: Option
@@ -241,6 +319,10 @@ extension Setting.Option {
241319
var performanceOption: PerformanceStatisticsOptions? {
242320
if case let .performance(option) = self { return option } else { return nil }
243321
}
322+
323+
var isScreenShape: Bool {
324+
if case .screenShape = self { return true } else { return false }
325+
}
244326
}
245327

246328
extension PerformanceStatistics {

Sources/MapboxMaps/Documentation.docc/API Catalogs/Free Camera.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44

55
### Symbols
66

7+
- ``Vec2``
78
- ``Vec3``
89
- ``Vec4``

Sources/MapboxMaps/Foundation/Extensions/Core/MapOptions.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ extension MapOptions {
6464
crossSourceCollisions: crossSourceCollisions.NSNumber,
6565
size: mbmSize,
6666
pixelRatio: Float(pixelRatio ?? ScreenShim.nativeScale),
67-
glyphsRasterizationOptions: glyphsRasterizationOptions,
68-
screenShape: nil)
67+
glyphsRasterizationOptions: glyphsRasterizationOptions)
6968
}
7069

7170
/// The map constrain mode. This can be used to limit the map to wrap around
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Foundation
2+
import MapboxCoreMaps
3+
4+
extension Vec2 {
5+
var point: CGPoint {
6+
CGPoint(x: x, y: y)
7+
}
8+
}

Sources/MapboxMaps/Foundation/Extensions/CoreGraphics.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ extension CGPoint {
1111
CoreScreenCoordinate(x: Double(x), y: Double(y))
1212
}
1313

14+
internal var vec2: Vec2 {
15+
Vec2(x: x, y: y)
16+
}
17+
1418
/// Interpolate a point along a fraction of a line between two points.
1519
/// - Parameters:
1620
/// - origin: The starting point for the interpolation.

Sources/MapboxMaps/Foundation/MapInitOptions.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Foundation
2+
@_implementationOnly import MapboxCoreMaps_Private
23

34
/// A protocol used to provide ``MapInitOptions`` when initializing a ``MapView`` with a Storyboard or
45
/// a nib.
@@ -101,9 +102,7 @@ extension MapInitOptions {
101102
crossSourceCollisions: mapOptions.__crossSourceCollisions,
102103
size: Size(width: Float(bounds.width), height: Float(bounds.height)),
103104
pixelRatio: mapOptions.pixelRatio,
104-
glyphsRasterizationOptions: mapOptions.glyphsRasterizationOptions,
105-
screenShape: nil)
106-
105+
glyphsRasterizationOptions: mapOptions.glyphsRasterizationOptions)
107106

108107
// Use the overriding style URI if provided (currently from IB)
109108
let resolvedStyleURI = overridingStyleURI.map { StyleURI(url: $0) } ?? styleURI

0 commit comments

Comments
 (0)