Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce struct variant of CameraOptions #284

Merged
merged 2 commits into from
Apr 21, 2021
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Mapbox welcomes participation and contributions from everyone.
* The setter for `BaseMapView.__map` is now private
* `Snapshotter` no longer conforms to `Observer`, and the method it required is now internal.
* The `BaseMapView.__map` property has been moved to `BaseMapView.mapboxMap.__map`. ([#280](https://github.com/mapbox/mapbox-maps-ios/pull/280))
* A `CameraOptions` struct has been introduced. This shadows the class of the same name from MapboxCoreMaps and. This avoids unintended sharing and better reflects the intended value semantics of the `CameraOptions` concept. ([#284](https://github.com/mapbox/mapbox-maps-ios/pull/284))

## 10.0.0-beta.17 - April 13, 2021

Expand Down
4 changes: 4 additions & 0 deletions Mapbox/MapboxMaps.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@
B5B55D51260E4D4500EBB589 /* GestureManager+GestureHandlerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B55D50260E4D4500EBB589 /* GestureManager+GestureHandlerDelegate.swift */; };
B5B55D5F260E4D7B00EBB589 /* CameraAnimatorDelegateMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B55D56260E4D7500EBB589 /* CameraAnimatorDelegateMock.swift */; };
B5B55D60260E4D7B00EBB589 /* CameraAnimatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B55D55260E4D7500EBB589 /* CameraAnimatorTests.swift */; };
B5B8B74F26308AC300D936E5 /* CameraOptionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B8B74E26308AC300D936E5 /* CameraOptionsTests.swift */; };
B5DDE9602613ACB400998840 /* StyleEncodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DDE95F2613ACB400998840 /* StyleEncodable.swift */; };
C6334944262E28C300D17701 /* StyleTransitionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6334943262E28C300D17701 /* StyleTransitionTests.swift */; };
C64994A9258D5ADE0052C21C /* LocationPuckManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C64994A5258D5ADD0052C21C /* LocationPuckManager.swift */; };
Expand Down Expand Up @@ -628,6 +629,7 @@
B5B55D50260E4D4500EBB589 /* GestureManager+GestureHandlerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GestureManager+GestureHandlerDelegate.swift"; sourceTree = "<group>"; };
B5B55D55260E4D7500EBB589 /* CameraAnimatorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraAnimatorTests.swift; sourceTree = "<group>"; };
B5B55D56260E4D7500EBB589 /* CameraAnimatorDelegateMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraAnimatorDelegateMock.swift; sourceTree = "<group>"; };
B5B8B74E26308AC300D936E5 /* CameraOptionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraOptionsTests.swift; sourceTree = "<group>"; };
B5DDE95F2613ACB400998840 /* StyleEncodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StyleEncodable.swift; sourceTree = "<group>"; };
C6334943262E28C300D17701 /* StyleTransitionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StyleTransitionTests.swift; sourceTree = "<group>"; };
C64994A5258D5ADD0052C21C /* LocationPuckManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationPuckManager.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1415,6 +1417,7 @@
A4FE887B255F364600FBF117 /* Camera */ = {
isa = PBXGroup;
children = (
B5B8B74E26308AC300D936E5 /* CameraOptionsTests.swift */,
B5B55D56260E4D7500EBB589 /* CameraAnimatorDelegateMock.swift */,
B5B55D55260E4D7500EBB589 /* CameraAnimatorTests.swift */,
1FC8DA47243BE4A400A19318 /* MapboxMapsCameraTests.swift */,
Expand Down Expand Up @@ -2143,6 +2146,7 @@
0C32C9B425F979680057ED31 /* ImageSourceIntegrationTests.swift in Sources */,
CAA73A9D256F750B00E14EE0 /* FlyToTests.swift in Sources */,
B53B8763260D73D600C86BAA /* Puck3DIntegrationTests.swift in Sources */,
B5B8B74F26308AC300D936E5 /* CameraOptionsTests.swift in Sources */,
CAD7BA0625A368DE00E64C78 /* ExampleIntegrationTest.swift in Sources */,
C6334944262E28C300D17701 /* StyleTransitionTests.swift in Sources */,
CA99A8702540CD1900D16C78 /* StyleLoadIntegrationTests.swift in Sources */,
Expand Down
16 changes: 8 additions & 8 deletions Sources/MapboxMaps/Foundation/Camera/CameraManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@ public class CameraManager {
let coordinateLocations = coordinates.map { CLLocation(latitude: $0.latitude, longitude: $0.longitude) }

// Construct new camera options with current values
let cameraOptions = mapView.cameraView.camera
let cameraOptions = MapboxCoreMaps.CameraOptions(mapView.cameraView.camera)

let defaultEdgeInsets = EdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

// Create a new camera options with adjusted values
return mapView.mapboxMap.__map.cameraForCoordinates(
return CameraOptions(mapView.mapboxMap.__map.cameraForCoordinates(
forCoordinates: coordinateLocations,
padding: cameraOptions.__padding ?? defaultEdgeInsets,
bearing: cameraOptions.__bearing,
pitch: cameraOptions.__pitch)
pitch: cameraOptions.__pitch))
}

/// Returns the camera that best fits the given coordinate bounds, with optional edge padding, bearing, and pitch values.
Expand All @@ -82,11 +82,11 @@ public class CameraManager {
return CameraOptions()
}

return mapView.mapboxMap.__map.cameraForCoordinateBounds(
return CameraOptions(mapView.mapboxMap.__map.cameraForCoordinateBounds(
for: coordinateBounds,
padding: edgePadding.toMBXEdgeInsetsValue(),
bearing: NSNumber(value: Float(bearing)),
pitch: NSNumber(value: Float(pitch)))
pitch: NSNumber(value: Float(pitch))))
}

/// Returns the camera that best fits the given geometry, with optional edge padding, bearing, and pitch values.
Expand All @@ -105,11 +105,11 @@ public class CameraManager {
return CameraOptions()
}

return mapView.mapboxMap.__map.cameraForGeometry(
return CameraOptions(mapView.mapboxMap.__map.cameraForGeometry(
for: MBXGeometry(geometry: geometry),
padding: edgePadding.toMBXEdgeInsetsValue(),
bearing: NSNumber(value: Float(bearing)),
pitch: NSNumber(value: Float(pitch)))
pitch: NSNumber(value: Float(pitch))))
}

/// Returns the coordinate bounds for a given `Camera` object's viewport.
Expand All @@ -120,7 +120,7 @@ public class CameraManager {
assertionFailure("MapView is nil.")
return CoordinateBounds()
}
return mapView.mapboxMap.__map.coordinateBoundsForCamera(forCamera: camera)
return mapView.mapboxMap.__map.coordinateBoundsForCamera(forCamera: MapboxCoreMaps.CameraOptions(camera))
}

// MARK: Setting a new camera
Expand Down
149 changes: 56 additions & 93 deletions Sources/MapboxMaps/Foundation/Camera/CameraOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,108 +2,60 @@ import Foundation
import CoreLocation
import UIKit

extension CameraOptions {
public struct CameraOptions: Hashable {
public var center: CLLocationCoordinate2D?
public var padding: UIEdgeInsets?
public var anchor: CGPoint?
public var zoom: CGFloat?
public var bearing: CLLocationDirection?
public var pitch: CGFloat?

/**
The `CameraOptions` object contains information about the current state of the camera.
`CameraOptions` represents a set of updates to make to the camera.

- Parameter centerCoordinate: The map coordinate that will represent the center of the viewport.
- Parameter padding: The padding surrounding the `CameraView`'s viewport. Defaults to nil.
- Parameter anchor: Point in this `CameraView`'s coordinate system on which to “anchor”
responses to user-initiated gestures.
- Parameter zoom: The zoom level of the map. Defaults to nil.
- Bearing bearing: The bearing of the viewport, measured in degrees clockwise from true north.
- Parameter pitch: Pitch toward the horizon measured in degrees, with 0 degrees resulting in a two-dimensional map.
- Returns: A `CameraOptions` object that contains all configuration information the `CameraView`
will use to render the map's viewport.
- Parameter center: The geographic coordinate that will be rendered at the midpoint of the area defined by `padding`.
- Parameter padding: Insets from each edge of the map. Impacts the "principal point" of the graphical projection and the location at which `center` is rendered.
- Parameter anchor: Point in the map's coordinate system about which `zoom` and `bearing` should be applied. Mutually exclusive with `center`.
- Parameter zoom: The zoom level of the map.
- Parameter bearing: The bearing of the map, measured in degrees clockwise from true north.
- Parameter pitch: Pitch toward the horizon measured in degrees, with 0 degrees resulting in a top-down view for a two-dimensional map.
- Returns: A `CameraOptions` that contains all configuration information the map will use to determine which part of the map to render.
*/
public convenience init(center: CLLocationCoordinate2D? = nil,
padding: UIEdgeInsets? = nil,
anchor: CGPoint? = nil,
zoom: CGFloat? = nil,
bearing: CLLocationDirection? = nil,
pitch: CGFloat? = nil) {
self.init(__center: center?.location,
padding: padding?.toMBXEdgeInsetsValue(),
anchor: anchor?.screenCoordinate,
zoom: zoom?.NSNumber,
bearing: bearing?.NSNumber,
pitch: pitch?.NSNumber)
public init(center: CLLocationCoordinate2D? = nil,
padding: UIEdgeInsets? = nil,
anchor: CGPoint? = nil,
zoom: CGFloat? = nil,
bearing: CLLocationDirection? = nil,
pitch: CGFloat? = nil) {
self.center = center
self.padding = padding
self.anchor = anchor
self.zoom = zoom
self.bearing = bearing
self.pitch = pitch
}

public var center: CLLocationCoordinate2D? {
get {
return __center?.coordinate
}
set {
__center = newValue?.location
}
internal init(_ objcValue: MapboxCoreMaps.CameraOptions) {
self.init(
center: objcValue.__center?.coordinate,
padding: objcValue.__padding?.toUIEdgeInsetsValue(),
anchor: objcValue.__anchor?.point,
zoom: objcValue.__zoom?.CGFloat,
bearing: objcValue.__bearing?.CLLocationDirection,
pitch: objcValue.__pitch?.CGFloat)
}

public var padding: UIEdgeInsets? {
get {
return __padding?.toUIEdgeInsetsValue()
}
set {
__padding = newValue?.toMBXEdgeInsetsValue()
}
public static func == (lhs: CameraOptions, rhs: CameraOptions) -> Bool {
return lhs.center?.latitude == rhs.center?.latitude
&& lhs.center?.longitude == rhs.center?.longitude
&& lhs.padding == rhs.padding
&& lhs.anchor == rhs.anchor
&& lhs.zoom == rhs.zoom
&& lhs.bearing == rhs.bearing
&& lhs.pitch == rhs.pitch
}

public var anchor: CGPoint? {
get {
return __anchor?.point
}
set {
__anchor = newValue?.screenCoordinate
}
}

public var zoom: CGFloat? {
get {
return __zoom?.CGFloat
}
set {
__zoom = newValue?.NSNumber
}
}

public var bearing: CLLocationDirection? {
get {
return __bearing?.CLLocationDirection
}
set {
__bearing = newValue?.NSNumber
}
}

public var pitch: CGFloat? {
get {
return __pitch?.CGFloat
}
set {
__pitch = newValue?.NSNumber
}
}

// MARK: Equals function

/// :nodoc:
public override func isEqual(_ object: Any?) -> Bool {
guard let other = object as? CameraOptions else {
return false
}
return other.isMember(of: CameraOptions.self)
&& center == other.center
&& padding == other.padding
&& anchor == other.anchor
&& zoom == other.zoom
&& bearing == other.bearing
&& pitch == other.pitch
}

/// :nodoc:
public override var hash: Int {
var hasher = Hasher()
public func hash(into hasher: inout Hasher) {
hasher.combine(center?.latitude)
hasher.combine(center?.longitude)
hasher.combine(padding?.top)
Expand All @@ -115,6 +67,17 @@ extension CameraOptions {
hasher.combine(zoom)
hasher.combine(bearing)
hasher.combine(pitch)
return hasher.finalize()
}
}

extension MapboxCoreMaps.CameraOptions {
internal convenience init(_ swiftValue: CameraOptions) {
self.init(
__center: swiftValue.center?.location,
padding: swiftValue.padding?.toMBXEdgeInsetsValue(),
anchor: swiftValue.anchor?.screenCoordinate,
zoom: swiftValue.zoom?.NSNumber,
bearing: swiftValue.bearing?.NSNumber,
pitch: swiftValue.pitch?.NSNumber)
}
}
2 changes: 1 addition & 1 deletion Sources/MapboxMaps/Foundation/Camera/CameraView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ internal class CameraView: UIView {
if currentCamera != targetCamera {

// Diff the targetCamera with the currentCamera and apply diffed camera properties to map
let diffedCamera = CameraOptions()
var diffedCamera = CameraOptions()

if targetCamera.zoom != currentCamera.zoom, let targetZoom = targetCamera.zoom, !targetZoom.isNaN {
diffedCamera.zoom = targetCamera.zoom
Expand Down
2 changes: 1 addition & 1 deletion Sources/MapboxMaps/Foundation/Extensions/NSNumber.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extension NSNumber {

/// Converts the `Float` value of an `NSNumber` to a `CLLocationDirection` representation.
public var CLLocationDirection: CLLocationDirection {
CoreLocation.CLLocationDirection(floatValue)
CoreLocation.CLLocationDirection(doubleValue)
}

// Useful for converting between NSNumbers and Core enums
Expand Down
4 changes: 2 additions & 2 deletions Sources/MapboxMaps/Foundation/MapboxMap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ public final class MapboxMap {
}

internal var cameraOptions: CameraOptions {
return __map.getCameraOptions(forPadding: nil)
return CameraOptions(__map.getCameraOptions(forPadding: nil))
}

internal func updateCamera(with cameraOptions: CameraOptions) {
__map.setCameraFor(cameraOptions)
__map.setCameraFor(MapboxCoreMaps.CameraOptions(cameraOptions))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ extension GestureManager: GestureHandlerDelegate {

if let cameraOptions = cameraManager.mapView?.mapboxMap.__map.getDragCameraOptionsFor(fromPoint: startPoint.screenCoordinate, toPoint: endPoint.screenCoordinate) {

cameraManager.setCamera(to: cameraOptions,
cameraManager.setCamera(to: CameraOptions(cameraOptions),
animated: false,
duration: 0,
completion: nil)
Expand All @@ -50,7 +50,7 @@ extension GestureManager: GestureHandlerDelegate {
if endPoint != driftEndPoint,
let driftCameraOptions = cameraManager.mapView?.mapboxMap.__map.getDragCameraOptionsFor(fromPoint: endPoint.screenCoordinate, toPoint: driftEndPoint.screenCoordinate) {

cameraManager.setCamera(to: driftCameraOptions,
cameraManager.setCamera(to: CameraOptions(driftCameraOptions),
animated: true,
duration: Double(cameraManager.mapCameraOptions.decelerationRate),
completion: nil)
Expand Down
2 changes: 1 addition & 1 deletion Sources/MapboxMaps/MapView/MapView+Supportable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extension MapView: OrnamentSupportableView {
internal func subscribeCameraChangeHandler(_ handler: @escaping (CameraOptions) -> Void) {
on(.cameraChanged) { [weak self] _ in
guard let validSelf = self else { return }
handler(validSelf.mapboxMap.__map.getCameraOptions(forPadding: nil))
handler(CameraOptions(validSelf.mapboxMap.__map.getCameraOptions(forPadding: nil)))
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions Sources/MapboxMaps/Snapshot/Snapshotter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ public class Snapshotter {
/// Camera configuration for the snapshot
public var camera: CameraOptions {
get {
return mapSnapshotter.getCameraOptions(forPadding: nil)
} set(newValue) {
mapSnapshotter.setCameraFor(newValue)
return CameraOptions(mapSnapshotter.getCameraOptions(forPadding: nil))
}
set {
mapSnapshotter.setCameraFor(MapboxCoreMaps.CameraOptions(newValue))
}
}

Expand Down
Loading