diff --git a/Sources/MapboxMaps/Annotations/Annotation.swift b/Sources/MapboxMaps/Annotations/Annotation.swift index ff8c5ae77470..3e8955a2a24b 100644 --- a/Sources/MapboxMaps/Annotations/Annotation.swift +++ b/Sources/MapboxMaps/Annotations/Annotation.swift @@ -13,14 +13,14 @@ public protocol Annotation { } protocol AnnotationInternal { - associatedtype GeometryType: GeometryConvertible + associatedtype LayerType: Layer + associatedtype GeometryType: GeometryConvertible & OffsetGeometryCalculator var id: String { get set } var layerProperties: [String: Any] { get } var feature: Feature { get } var isSelected: Bool { get set } var isDraggable: Bool { get set } - var _geometry: GeometryType { get set } var tapHandler: ((MapContentGestureContext) -> Bool)? { get set } var longPressHandler: ((MapContentGestureContext) -> Bool)? { get set } @@ -28,6 +28,52 @@ protocol AnnotationInternal { var dragBeginHandler: ((inout Self, MapContentGestureContext) -> Bool)? { get set } var dragChangeHandler: ((inout Self, MapContentGestureContext) -> Void)? { get set } var dragEndHandler: ((inout Self, MapContentGestureContext) -> Void)? { get set } + + mutating func drag(translation: CGPoint, in map: MapboxMapProtocol) + + static func makeLayer(id: String) -> LayerType +} + +extension PointAnnotation { + typealias GeometryType = Point + typealias LayerType = SymbolLayer + + static func makeLayer(id: String) -> SymbolLayer { + var layer = SymbolLayer(id: id, source: id) + // Show all icons and texts by default in point annotations. + layer.iconAllowOverlap = .constant(true) + layer.textAllowOverlap = .constant(true) + layer.iconIgnorePlacement = .constant(true) + layer.textIgnorePlacement = .constant(true) + return layer + } +} + +extension CircleAnnotation { + typealias GeometryType = Point + typealias LayerType = CircleLayer + + static func makeLayer(id: String) -> CircleLayer { + CircleLayer(id: id, source: id) + } +} + +extension PolygonAnnotation { + typealias GeometryType = Polygon + typealias LayerType = FillLayer + + static func makeLayer(id: String) -> FillLayer { + FillLayer(id: id, source: id) + } +} + +extension PolylineAnnotation { + typealias GeometryType = LineString + typealias LayerType = LineLayer + + static func makeLayer(id: String) -> LineLayer { + LineLayer(id: id, source: id) + } } extension Array where Element: Annotation { diff --git a/Sources/MapboxMaps/Annotations/AnnotationManagerImpl.swift b/Sources/MapboxMaps/Annotations/AnnotationManagerImpl.swift index 59c8ad210fe2..3eebd743db9b 100644 --- a/Sources/MapboxMaps/Annotations/AnnotationManagerImpl.swift +++ b/Sources/MapboxMaps/Annotations/AnnotationManagerImpl.swift @@ -18,14 +18,12 @@ protocol AnnotationManagerImplProtocol { func handleDragEnd(context: MapContentGestureContext) } -final class AnnotationManagerImpl: AnnotationManagerImplProtocol { - typealias AnnotationType = Traits.AnnotationType - +final class AnnotationManagerImpl: AnnotationManagerImplProtocol { let id: String weak var delegate: AnnotationManagerImplDelegate? - var annotations: [Traits.AnnotationType] { + var annotations: [AnnotationType] { get { mainAnnotations + draggedAnnotations } set { mainAnnotations = newValue @@ -40,8 +38,8 @@ final class AnnotationManagerImpl: AnnotationMa // Deps private let style: StyleProtocol - private let offsetCalculator: Traits.OffsetCalculator private let mapFeatureQueryable: MapFeatureQueryable + private let mapboxMap: MapboxMapProtocol private let clusterOptions: ClusterOptions? private let layerType: LayerType @@ -54,15 +52,15 @@ final class AnnotationManagerImpl: AnnotationMa private weak var _delegate: AnnotationInteractionDelegate? /// Currently displayed (synced) annotations. - private var displayedAnnotations: [Traits.AnnotationType] = [] + private var displayedAnnotations: [AnnotationType] = [] /// Updated, non-moved annotations. On next display link they will be diffed with `displayedAnnotations` and updated. - private var mainAnnotations = [Traits.AnnotationType]() { + private var mainAnnotations = [AnnotationType]() { didSet { syncSourceOnce.reset() } } /// When annotation is moved for the first time, it migrates to this array from mainAnnotations. - private var draggedAnnotations = [Traits.AnnotationType]() { + private var draggedAnnotations = [AnnotationType]() { didSet { if insertDraggedLayerAndSourceOnce.happened { // Update dragged annotation only when the drag layer is created. @@ -109,7 +107,7 @@ final class AnnotationManagerImpl: AnnotationMa init(params: AnnotationManagerParams, deps: AnnotationManagerDeps) { self.id = params.id self.style = deps.style - self.offsetCalculator = deps.makeOffsetCalculator() + self.mapboxMap = deps.map self.layerPosition = params.layerPosition self.clusterOptions = params.clusterOptions @@ -127,7 +125,7 @@ final class AnnotationManagerImpl: AnnotationMa source.clusterMinPoints = clusterOptions.clusterMinPoints } - let layer = Traits.makeLayer(id: id) + let layer = AnnotationType.makeLayer(id: id) self.layerType = layer.type if let clusterOptions { @@ -140,7 +138,7 @@ final class AnnotationManagerImpl: AnnotationMa try style.addSource(source) } catch { Log.error( - forMessage: "Failed to create source / layer in \(Traits.tag). Error: \(error)", + forMessage: "Failed to create source / layer in \(implementationName). Error: \(error)", category: "Annotations") } @@ -157,7 +155,7 @@ final class AnnotationManagerImpl: AnnotationMa try addClusterLayer(clusterLayer: clusterTextLayer) } catch { Log.error( - forMessage: "Failed to add cluster layer in \(Traits.tag). Error: \(error)", + forMessage: "Failed to add cluster layer in \(implementationName). Error: \(error)", category: "Annotations") } } @@ -193,14 +191,14 @@ final class AnnotationManagerImpl: AnnotationMa try style.removeLayer(withId: "mapbox-iOS-cluster-text-layer-manager-" + id) } catch { Log.error( - forMessage: "Failed to remove cluster layer in \(Traits.tag). Error: \(error)", + forMessage: "Failed to remove cluster layer in \(implementationName). Error: \(error)", category: "Annotations") } } // For SwiftUI - func set(newAnnotations: [(AnyHashable, Traits.AnnotationType)]) { - var resolvedAnnotations = [Traits.AnnotationType]() + func set(newAnnotations: [(AnyHashable, AnnotationType)]) { + var resolvedAnnotations = [AnnotationType]() newAnnotations.forEach { elementId, annotation in var annotation = annotation let stringId = idsMap[elementId] ?? annotation.id @@ -228,7 +226,7 @@ final class AnnotationManagerImpl: AnnotationMa try body() } catch { Log.warning( - forMessage: "Failed to remove \(what) for PointAnnotationManager with id \(id) due to error: \(error)", + forMessage: "Failed to remove \(what) for \(implementationName) with id \(id) due to error: \(error)", category: "Annotations") } } @@ -257,7 +255,7 @@ final class AnnotationManagerImpl: AnnotationMa func syncSourceAndLayerIfNeeded() { guard !destroyOnce.happened else { return } - OSLog.platform.withIntervalSignpost(SignpostName.mapViewDisplayLink, "Participant: \(Traits.tag)") { + OSLog.platform.withIntervalSignpost(SignpostName.mapViewDisplayLink, "Participant: \(implementationName)") { syncSource() syncDragSource() syncLayer() @@ -380,11 +378,11 @@ final class AnnotationManagerImpl: AnnotationMa func handleDragBegin(with featureId: String, context: MapContentGestureContext) -> Bool { guard !isSwiftUI else { return false } - func predicate(annotation: Traits.AnnotationType) -> Bool { + func predicate(annotation: AnnotationType) -> Bool { annotation.id == featureId && annotation.isDraggable } - func tryBeginDragging(_ annotations: inout [Traits.AnnotationType], idx: Int) -> Bool { + func tryBeginDragging(_ annotations: inout [AnnotationType], idx: Int) -> Bool { var annotation = annotations[idx] // If no drag handler set, the dragging is allowed let dragAllowed = annotation.dragBeginHandler?(&annotation, context) ?? true @@ -424,11 +422,9 @@ final class AnnotationManagerImpl: AnnotationMa private func insertDraggedLayerAndSource() { insertDraggedLayerAndSourceOnce { - let source = GeoJSONSource(id: dragId) - let layer = Traits.makeLayer(id: dragId) do { - try style.addSource(source) - try style.addPersistentLayer(layer, layerPosition: .above(id)) + try style.addSource(GeoJSONSource(id: dragId)) + try style.addPersistentLayer(AnnotationType.makeLayer(id: dragId), layerPosition: .above(id)) } catch { Log.error(forMessage: "Add drag source/layer \(error)", category: "Annotations") } @@ -443,10 +439,7 @@ final class AnnotationManagerImpl: AnnotationMa return } - let currentGeometry = draggedAnnotations[draggedAnnotationIndex]._geometry - guard let geometry = offsetCalculator.geometry(for: translation, from: currentGeometry) else { return } - draggedAnnotations[draggedAnnotationIndex]._geometry = geometry - + draggedAnnotations[draggedAnnotationIndex].drag(translation: translation, in: mapboxMap) callDragHandler(\.dragChangeHandler, context: context) } @@ -457,7 +450,7 @@ final class AnnotationManagerImpl: AnnotationMa } private func callDragHandler( - _ keyPath: KeyPath Void)?>, + _ keyPath: KeyPath Void)?>, context: MapContentGestureContext ) { guard let draggedAnnotationIndex, draggedAnnotationIndex < draggedAnnotations.endIndex else { @@ -471,3 +464,7 @@ final class AnnotationManagerImpl: AnnotationMa } } } + +private extension AnnotationManagerImpl { + var implementationName: String { "\(String(describing: AnnotationType.self))Manager" } +} diff --git a/Sources/MapboxMaps/Annotations/AnnotationManagerTraits.swift b/Sources/MapboxMaps/Annotations/AnnotationManagerTraits.swift deleted file mode 100644 index 50b19e3f1f22..000000000000 --- a/Sources/MapboxMaps/Annotations/AnnotationManagerTraits.swift +++ /dev/null @@ -1,64 +0,0 @@ -protocol AnnotationManagerTraits { - associatedtype AnnotationType: Annotation & AnnotationInternal & Equatable - associatedtype LayerType: Layer - associatedtype OffsetCalculator: OffsetGeometryCalculator where OffsetCalculator.GeometryType == AnnotationType.GeometryType - - typealias UpdateOffset = (inout AnnotationType, CGPoint) -> Bool - - static func makeLayer(id: String) -> LayerType - static var tag: String { get } -} - -struct PointAnnotationManagerTraits: AnnotationManagerTraits { - typealias OffsetCalculator = OffsetPointCalculator - typealias AnnotationType = PointAnnotation - typealias LayerType = SymbolLayer - - static func makeLayer(id: String) -> SymbolLayer { - var layer = SymbolLayer(id: id, source: id) - // Show all icons and texts by default in point annotations. - layer.iconAllowOverlap = .constant(true) - layer.textAllowOverlap = .constant(true) - layer.iconIgnorePlacement = .constant(true) - layer.textIgnorePlacement = .constant(true) - return layer - } - - static let tag = "PointAnnotationManager" -} - -struct CircleAnnotationManagerTraits: AnnotationManagerTraits { - typealias OffsetCalculator = OffsetPointCalculator - typealias AnnotationType = CircleAnnotation - typealias LayerType = CircleLayer - - static func makeLayer(id: String) -> CircleLayer { - CircleLayer(id: id, source: id) - } - - static let tag = "CircleAnnotationManager" -} - -struct PolygonAnnotationManagerTraits: AnnotationManagerTraits { - typealias OffsetCalculator = OffsetPolygonCalculator - typealias AnnotationType = PolygonAnnotation - typealias LayerType = FillLayer - - static func makeLayer(id: String) -> FillLayer { - FillLayer(id: id, source: id) - } - - static let tag = "PolygonAnnotationManager" -} - -struct PolylineAnnotationManagerTraits: AnnotationManagerTraits { - typealias OffsetCalculator = OffsetLineStringCalculator - typealias AnnotationType = PolylineAnnotation - typealias LayerType = LineLayer - - static func makeLayer(id: String) -> LineLayer { - LineLayer(id: id, source: id) - } - - static let tag = "PolylineAnnotationManager" -} diff --git a/Sources/MapboxMaps/Annotations/AnnotationOrchestrator.swift b/Sources/MapboxMaps/Annotations/AnnotationOrchestrator.swift index 91245c92e96b..fbea7987e10b 100644 --- a/Sources/MapboxMaps/Annotations/AnnotationOrchestrator.swift +++ b/Sources/MapboxMaps/Annotations/AnnotationOrchestrator.swift @@ -31,10 +31,6 @@ struct AnnotationManagerDeps { let imagesManager: AnnotationImagesManagerProtocol let displayLink: Signal - func makeOffsetCalculator() -> T { - return T.init(mapboxMap: map) - } - static func from(mapboxMap map: MapboxMap, displayLink: Signal) -> AnnotationManagerDeps { AnnotationManagerDeps( map: map, @@ -46,8 +42,8 @@ struct AnnotationManagerDeps { } protocol AnnotationManagerInternal: AnnotationManager { - associatedtype Traits: AnnotationManagerTraits - var impl: AnnotationManagerImpl { get } + associatedtype AnnotationType: Annotation & AnnotationInternal & Equatable + var impl: AnnotationManagerImpl { get } init(params: AnnotationManagerParams, deps: AnnotationManagerDeps) } diff --git a/Sources/MapboxMaps/Annotations/Generated/CircleAnnotation.swift b/Sources/MapboxMaps/Annotations/Generated/CircleAnnotation.swift index af947f7f1484..c4dcc74bd2fa 100644 --- a/Sources/MapboxMaps/Annotations/Generated/CircleAnnotation.swift +++ b/Sources/MapboxMaps/Annotations/Generated/CircleAnnotation.swift @@ -2,23 +2,15 @@ import UIKit public struct CircleAnnotation: Annotation, Equatable, AnnotationInternal { - /// Identifier for this annotation internal(set) public var id: String /// The geometry backing this annotation - public var geometry: Geometry { - .point(point) - } + public var geometry: Geometry { point.geometry } /// The Point backing this annotation public var point: Point - var _geometry: Point { - get { point } - set { point = newValue } - } - /// Toggles the annotation's selection state. /// If the annotation is deselected, it becomes selected. /// If the annotation is selected, it becomes deselected. @@ -117,6 +109,10 @@ public struct CircleAnnotation: Annotation, Equatable, AnnotationInternal { return feature } + mutating func drag(translation: CGPoint, in map: MapboxMapProtocol) { + point = GeometryType.projection(of: point, for: translation, in: map) + } + /// Create a circle annotation with a `Point` and an optional identifier. public init(id: String = UUID().uuidString, point: Point, isSelected: Bool = false, isDraggable: Bool = false) { self.id = id @@ -171,7 +167,6 @@ public struct CircleAnnotation: Annotation, Equatable, AnnotationInternal { } -@_documentation(visibility: public) extension CircleAnnotation { /// Sorts features in ascending order based on this value. Features with a higher sort key will appear above features with a lower sort key. diff --git a/Sources/MapboxMaps/Annotations/Generated/CircleAnnotationManager.swift b/Sources/MapboxMaps/Annotations/Generated/CircleAnnotationManager.swift index aac13d65bf19..b504d885f0ac 100644 --- a/Sources/MapboxMaps/Annotations/Generated/CircleAnnotationManager.swift +++ b/Sources/MapboxMaps/Annotations/Generated/CircleAnnotationManager.swift @@ -2,13 +2,13 @@ /// An instance of `CircleAnnotationManager` is responsible for a collection of `CircleAnnotation`s. public class CircleAnnotationManager: AnnotationManager, AnnotationManagerInternal, AnnotationManagerImplDelegate { - typealias Impl = AnnotationManagerImpl + typealias Impl = AnnotationManagerImpl public var sourceId: String { impl.id } public var layerId: String { impl.id } public var id: String { impl.id } - let impl: AnnotationManagerImpl + let impl: AnnotationManagerImpl /// The collection of ``CircleAnnotation`` being managed. /// diff --git a/Sources/MapboxMaps/Annotations/Generated/PointAnnotation.swift b/Sources/MapboxMaps/Annotations/Generated/PointAnnotation.swift index ae9acfd11e7b..87f85ffe6014 100644 --- a/Sources/MapboxMaps/Annotations/Generated/PointAnnotation.swift +++ b/Sources/MapboxMaps/Annotations/Generated/PointAnnotation.swift @@ -2,23 +2,15 @@ import UIKit public struct PointAnnotation: Annotation, Equatable, AnnotationInternal { - /// Identifier for this annotation internal(set) public var id: String /// The geometry backing this annotation - public var geometry: Geometry { - .point(point) - } + public var geometry: Geometry { point.geometry } /// The Point backing this annotation public var point: Point - var _geometry: Point { - get { point } - set { point = newValue } - } - /// Toggles the annotation's selection state. /// If the annotation is deselected, it becomes selected. /// If the annotation is selected, it becomes deselected. @@ -143,6 +135,10 @@ public struct PointAnnotation: Annotation, Equatable, AnnotationInternal { return feature } + mutating func drag(translation: CGPoint, in map: MapboxMapProtocol) { + point = GeometryType.projection(of: point, for: translation, in: map) + } + /// Create a point annotation with a `Point` and an optional identifier. public init(id: String = UUID().uuidString, point: Point, isSelected: Bool = false, isDraggable: Bool = false) { self.id = id @@ -307,7 +303,6 @@ public struct PointAnnotation: Annotation, Equatable, AnnotationInternal { } } -@_documentation(visibility: public) extension PointAnnotation { /// Part of the icon placed closest to the anchor. diff --git a/Sources/MapboxMaps/Annotations/Generated/PointAnnotationManager.swift b/Sources/MapboxMaps/Annotations/Generated/PointAnnotationManager.swift index e7efc2561167..2eda773ac68b 100644 --- a/Sources/MapboxMaps/Annotations/Generated/PointAnnotationManager.swift +++ b/Sources/MapboxMaps/Annotations/Generated/PointAnnotationManager.swift @@ -2,13 +2,13 @@ /// An instance of `PointAnnotationManager` is responsible for a collection of `PointAnnotation`s. public class PointAnnotationManager: AnnotationManager, AnnotationManagerInternal, AnnotationManagerImplDelegate { - typealias Impl = AnnotationManagerImpl + typealias Impl = AnnotationManagerImpl public var sourceId: String { impl.id } public var layerId: String { impl.id } public var id: String { impl.id } - let impl: AnnotationManagerImpl + let impl: AnnotationManagerImpl /// The collection of ``PointAnnotation`` being managed. /// diff --git a/Sources/MapboxMaps/Annotations/Generated/PolygonAnnotation.swift b/Sources/MapboxMaps/Annotations/Generated/PolygonAnnotation.swift index 393d4d694448..1c0b7c47963f 100644 --- a/Sources/MapboxMaps/Annotations/Generated/PolygonAnnotation.swift +++ b/Sources/MapboxMaps/Annotations/Generated/PolygonAnnotation.swift @@ -2,23 +2,15 @@ import UIKit public struct PolygonAnnotation: Annotation, Equatable, AnnotationInternal { - /// Identifier for this annotation internal(set) public var id: String /// The geometry backing this annotation - public var geometry: Geometry { - .polygon(polygon) - } + public var geometry: Geometry { polygon.geometry } /// The Polygon backing this annotation public var polygon: Polygon - var _geometry: Polygon { - get { polygon } - set { polygon = newValue } - } - /// Toggles the annotation's selection state. /// If the annotation is deselected, it becomes selected. /// If the annotation is selected, it becomes deselected. @@ -114,6 +106,10 @@ public struct PolygonAnnotation: Annotation, Equatable, AnnotationInternal { return feature } + mutating func drag(translation: CGPoint, in map: MapboxMapProtocol) { + polygon = GeometryType.projection(of: polygon, for: translation, in: map) + } + /// Create a polygon annotation with a `Polygon` and an optional identifier. public init(id: String = UUID().uuidString, polygon: Polygon, isSelected: Bool = false, isDraggable: Bool = false) { self.id = id @@ -143,7 +139,6 @@ public struct PolygonAnnotation: Annotation, Equatable, AnnotationInternal { } -@_documentation(visibility: public) extension PolygonAnnotation { /// Sorts features in ascending order based on this value. Features with a higher sort key will appear above features with a lower sort key. diff --git a/Sources/MapboxMaps/Annotations/Generated/PolygonAnnotationManager.swift b/Sources/MapboxMaps/Annotations/Generated/PolygonAnnotationManager.swift index a04c5846e0ac..1f7a5e8b074a 100644 --- a/Sources/MapboxMaps/Annotations/Generated/PolygonAnnotationManager.swift +++ b/Sources/MapboxMaps/Annotations/Generated/PolygonAnnotationManager.swift @@ -2,13 +2,13 @@ /// An instance of `PolygonAnnotationManager` is responsible for a collection of `PolygonAnnotation`s. public class PolygonAnnotationManager: AnnotationManager, AnnotationManagerInternal, AnnotationManagerImplDelegate { - typealias Impl = AnnotationManagerImpl + typealias Impl = AnnotationManagerImpl public var sourceId: String { impl.id } public var layerId: String { impl.id } public var id: String { impl.id } - let impl: AnnotationManagerImpl + let impl: AnnotationManagerImpl /// The collection of ``PolygonAnnotation`` being managed. /// diff --git a/Sources/MapboxMaps/Annotations/Generated/PolylineAnnotation.swift b/Sources/MapboxMaps/Annotations/Generated/PolylineAnnotation.swift index 6cc7ace90587..46f984b4aa19 100644 --- a/Sources/MapboxMaps/Annotations/Generated/PolylineAnnotation.swift +++ b/Sources/MapboxMaps/Annotations/Generated/PolylineAnnotation.swift @@ -2,23 +2,15 @@ import UIKit public struct PolylineAnnotation: Annotation, Equatable, AnnotationInternal { - /// Identifier for this annotation internal(set) public var id: String /// The geometry backing this annotation - public var geometry: Geometry { - .lineString(lineString) - } + public var geometry: Geometry { lineString.geometry } /// The LineString backing this annotation public var lineString: LineString - var _geometry: LineString { - get { lineString } - set { lineString = newValue } - } - /// Toggles the annotation's selection state. /// If the annotation is deselected, it becomes selected. /// If the annotation is selected, it becomes deselected. @@ -121,6 +113,10 @@ public struct PolylineAnnotation: Annotation, Equatable, AnnotationInternal { return feature } + mutating func drag(translation: CGPoint, in map: MapboxMapProtocol) { + lineString = GeometryType.projection(of: lineString, for: translation, in: map) + } + /// Create a polyline annotation with a `LineString` and an optional identifier. public init(id: String = UUID().uuidString, lineString: LineString, isSelected: Bool = false, isDraggable: Bool = false) { self.id = id @@ -184,7 +180,6 @@ public struct PolylineAnnotation: Annotation, Equatable, AnnotationInternal { } -@_documentation(visibility: public) extension PolylineAnnotation { /// The display of lines when joining. diff --git a/Sources/MapboxMaps/Annotations/Generated/PolylineAnnotationManager.swift b/Sources/MapboxMaps/Annotations/Generated/PolylineAnnotationManager.swift index aff5e24a8ade..790844c85450 100644 --- a/Sources/MapboxMaps/Annotations/Generated/PolylineAnnotationManager.swift +++ b/Sources/MapboxMaps/Annotations/Generated/PolylineAnnotationManager.swift @@ -2,13 +2,13 @@ /// An instance of `PolylineAnnotationManager` is responsible for a collection of `PolylineAnnotation`s. public class PolylineAnnotationManager: AnnotationManager, AnnotationManagerInternal, AnnotationManagerImplDelegate { - typealias Impl = AnnotationManagerImpl + typealias Impl = AnnotationManagerImpl public var sourceId: String { impl.id } public var layerId: String { impl.id } public var id: String { impl.id } - let impl: AnnotationManagerImpl + let impl: AnnotationManagerImpl /// The collection of ``PolylineAnnotation`` being managed. /// diff --git a/Sources/MapboxMaps/Annotations/OffsetGeometryCalculator.swift b/Sources/MapboxMaps/Annotations/OffsetGeometryCalculator.swift index f8cc4c6cf5b3..96589c02b888 100644 --- a/Sources/MapboxMaps/Annotations/OffsetGeometryCalculator.swift +++ b/Sources/MapboxMaps/Annotations/OffsetGeometryCalculator.swift @@ -3,18 +3,13 @@ import UIKit protocol OffsetGeometryCalculator { associatedtype GeometryType: GeometryConvertible - func geometry(for translation: CGPoint, from geometry: GeometryType) -> GeometryType? - init(mapboxMap: MapboxMapProtocol) + static func projection(of geometry: GeometryType, for translation: CGPoint, in mapboxMap: MapboxMapProtocol) -> GeometryType } -internal struct OffsetPointCalculator: OffsetGeometryCalculator { - private let mapboxMap: MapboxMapProtocol +extension Point: OffsetGeometryCalculator { + typealias GeometryType = Point - internal init(mapboxMap: MapboxMapProtocol) { - self.mapboxMap = mapboxMap - } - - func geometry(for translation: CGPoint, from geometry: Point) -> Point? { + static func projection(of geometry: Point, for translation: CGPoint, in mapboxMap: MapboxMapProtocol) -> Point { let point = geometry.coordinates let pointScreenCoordinate = mapboxMap.point(for: point) @@ -35,24 +30,20 @@ internal struct OffsetPointCalculator: OffsetGeometryCalculator { zoomLevel: mapboxMap.cameraState.zoom) guard Projection.latitudeRange.contains(targetPoint.coordinates.latitude) else { - return nil + return geometry } return Point(targetPoint.coordinates) } } -internal struct OffsetLineStringCalculator: OffsetGeometryCalculator { - private let mapboxMap: MapboxMapProtocol - - internal init(mapboxMap: MapboxMapProtocol) { - self.mapboxMap = mapboxMap - } +extension LineString: OffsetGeometryCalculator { + typealias GeometryType = LineString - func geometry(for translation: CGPoint, from geometry: LineString) -> LineString? { + static func projection(of geometry: LineString, for translation: CGPoint, in mapboxMap: MapboxMapProtocol) -> LineString { let startPoints = geometry.coordinates if startPoints.isEmpty { - return nil + return geometry } let latitudeSum = startPoints.map(\.latitude).reduce(0, +) let longitudeSum = startPoints.map(\.longitude).reduce(0, +) @@ -82,30 +73,26 @@ internal struct OffsetLineStringCalculator: OffsetGeometryCalculator { } guard let targetPointLatitude = targetPoints.first?.coordinates.latitude else { - return nil + return geometry } guard Projection.latitudeRange.contains(targetPointLatitude) else { - return nil + return geometry } return LineString(.init(coordinates: targetPoints.map {$0.coordinates})) } } -internal struct OffsetPolygonCalculator: OffsetGeometryCalculator { - private let mapboxMap: MapboxMapProtocol - - internal init(mapboxMap: MapboxMapProtocol) { - self.mapboxMap = mapboxMap - } +extension Polygon: OffsetGeometryCalculator { + typealias GeometryType = Polygon // swiftlint:disable:next function_body_length - func geometry(for translation: CGPoint, from geometry: Polygon) -> Polygon? { + static func projection(of geometry: Polygon, for translation: CGPoint, in mapboxMap: MapboxMapProtocol) -> Polygon { var outerRing = [CLLocationCoordinate2D]() var innerRing: [CLLocationCoordinate2D]? let startPoints = geometry.outerRing.coordinates if startPoints.isEmpty { - return nil + return geometry } let latitudeSum = startPoints.map { $0.latitude }.reduce(0, +) @@ -133,17 +120,17 @@ internal struct OffsetPolygonCalculator: OffsetGeometryCalculator { let targetPoints = startPoints.map { Projection.shiftPointWithMercatorCoordinate( - point: Point($0), - shiftMercatorCoordinate: shiftMercatorCoordinate, - zoomLevel: mapboxMap.cameraState.zoom) + point: Point($0), + shiftMercatorCoordinate: shiftMercatorCoordinate, + zoomLevel: mapboxMap.cameraState.zoom) } guard let targetPointLatitude = targetPoints.first?.coordinates.latitude else { - return nil + return geometry } guard Projection.latitudeRange.contains(targetPointLatitude) else { - return nil + return geometry } outerRing = targetPoints.map {$0.coordinates} @@ -154,7 +141,7 @@ internal struct OffsetPolygonCalculator: OffsetGeometryCalculator { for ring in geometry.innerRings { let startPoints = ring.coordinates if startPoints.isEmpty { - return nil + return geometry } let latitudeSum = startPoints.map { $0.latitude }.reduce(0, +) @@ -186,15 +173,15 @@ internal struct OffsetPolygonCalculator: OffsetGeometryCalculator { zoomLevel: mapboxMap.cameraState.zoom)} guard let targetPointLatitude = targetPoints.first?.coordinates.latitude else { - return nil + return geometry } guard Projection.latitudeRange.contains(targetPointLatitude) else { - return nil + return geometry } innerRing = targetPoints.map {$0.coordinates} - guard let innerRing = innerRing else { return nil } + guard let innerRing = innerRing else { return geometry } innerRings.append(.init(coordinates: innerRing)) } diff --git a/Sources/MapboxMaps/ContentBuilders/MapContent/MountedAnnotationGroup.swift b/Sources/MapboxMaps/ContentBuilders/MapContent/MountedAnnotationGroup.swift index 356fda6b0256..2f3899dd6dbe 100644 --- a/Sources/MapboxMaps/ContentBuilders/MapContent/MountedAnnotationGroup.swift +++ b/Sources/MapboxMaps/ContentBuilders/MapContent/MountedAnnotationGroup.swift @@ -2,7 +2,7 @@ import os.log @available(iOS 13.0, *) struct MountedAnnotationGroup: MapContentMountedComponent { - private let annotations: [(AnyHashable, Manager.Traits.AnnotationType)] + private let annotations: [(AnyHashable, Manager.AnnotationType)] private let layerId: String private let clusterOptions: ClusterOptions? private let updateProperties: (Manager) -> Void @@ -10,7 +10,7 @@ struct MountedAnnotationGroup: MapContentMou init( layerId: String, clusterOptions: ClusterOptions?, - annotations: [(AnyHashable, Manager.Traits.AnnotationType)], + annotations: [(AnyHashable, Manager.AnnotationType)], updateProperties: @escaping (Manager) -> Void ) { self.layerId = layerId diff --git a/Tests/MapboxMapsTests/Annotations/AnnotationManagerImplTests.swift b/Tests/MapboxMapsTests/Annotations/AnnotationManagerImplTests.swift index 6ecf433e35f7..1f35ce26abd1 100644 --- a/Tests/MapboxMapsTests/Annotations/AnnotationManagerImplTests.swift +++ b/Tests/MapboxMapsTests/Annotations/AnnotationManagerImplTests.swift @@ -4,7 +4,7 @@ import XCTest final class AnnotationManagerImplTests: XCTestCase { private var harness: AnnotationManagerTestingHarness! private var style: MockStyle { harness.style } - private var me: AnnotationManagerImpl! + private var me: AnnotationManagerImpl! private var annotations = [PointAnnotation]() let id = "default"