diff --git a/TIAppleMapUtils/Sources/AppleClusterPlacemarkManager.swift b/TIAppleMapUtils/Sources/AppleClusterPlacemarkManager.swift index e5016f73..c13dd8b8 100644 --- a/TIAppleMapUtils/Sources/AppleClusterPlacemarkManager.swift +++ b/TIAppleMapUtils/Sources/AppleClusterPlacemarkManager.swift @@ -24,7 +24,10 @@ import TIMapUtils import MapKit import UIKit -open class AppleClusterPlacemarkManager: BasePlacemarkManager], MKMapRect>, +open class AppleClusterPlacemarkManager: BaseClusterPlacemarkManager], + MKMapRect, + CLLocationCoordinate2D>, MKMapViewDelegate { public weak var mapViewDelegate: MKMapViewDelegate? @@ -51,16 +54,6 @@ open class AppleClusterPlacemarkManager: BasePlacemarkManager: BasePlacemarkManager: BasePlacemarkManager: BasePlacemarkManager], GMSCoordinateBounds>, +open class GoogleClusterPlacemarkManager: BaseClusterPlacemarkManager], + GMSCoordinateBounds, + CLLocationCoordinate2D>, GMUClusterRendererDelegate, GMUClusterManagerDelegate, GMUClusterIconGenerator { @@ -77,16 +80,6 @@ open class GoogleClusterPlacemarkManager: BasePlacemarkManager: BasePlacemarkManager Bool { diff --git a/TIGoogleMapUtils/Sources/GooglePlacemarkManager.swift b/TIGoogleMapUtils/Sources/GooglePlacemarkManager.swift index 9907ec26..6cc058e1 100644 --- a/TIGoogleMapUtils/Sources/GooglePlacemarkManager.swift +++ b/TIGoogleMapUtils/Sources/GooglePlacemarkManager.swift @@ -30,13 +30,15 @@ open class GooglePlacemarkManager: BasePlacemarkManager: BasePlacemarkManager?, tapHandler: TapHandlerClosure?) { - self.position = position - - super.init(dataModel: dataModel, + super.init(placemarkPosition: position, + dataModel: dataModel, iconFactory: iconFactory, tapHandler: tapHandler) } diff --git a/TIMapUtils/Sources/Managers/BaseClusterPlacemarkManager.swift b/TIMapUtils/Sources/Managers/BaseClusterPlacemarkManager.swift new file mode 100644 index 00000000..493a1980 --- /dev/null +++ b/TIMapUtils/Sources/Managers/BaseClusterPlacemarkManager.swift @@ -0,0 +1,62 @@ +// +// Copyright (c) 2023 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/** + Base cluster placemark manager + + - Parameters: + - `Placemark`: a generic parameter describing a cluster placemark itself + - `ClusterDataModel`: an array of single placemarks managers for a cluster + - `ClusterPoints`: a collection of cluster placemark objects + - `Position`: a type of a single manager's placemark position + */ +open class BaseClusterPlacemarkManager: + BasePlacemarkManager { + + /// Manual selecting of a placemark with an incoming point coordinates + open func selectMarker(with point: Position) { + guard let dataModel = dataModel as? Array else { + return + } + + dataModel + .filter { + guard let placemarkPosition = $0.placemarkPosition as? Position else { + return false + } + + return placemarkPosition == point + } + .forEach { + $0.state = .selected + } + } + + /// Manual state resetting of all placemarks with currently selected state + open func resetMarkersState() { + guard let dataModel = dataModel as? Array else { + return + } + + dataModel.filter { $0.state == .selected }.forEach { $0.state = .default } + } +} diff --git a/TIMapUtils/Sources/Managers/BasePlacemarkManager.swift b/TIMapUtils/Sources/Managers/BasePlacemarkManager.swift index b5793049..519d3452 100644 --- a/TIMapUtils/Sources/Managers/BasePlacemarkManager.swift +++ b/TIMapUtils/Sources/Managers/BasePlacemarkManager.swift @@ -23,17 +23,27 @@ import ObjectiveC open class BasePlacemarkManager: NSObject, PlacemarkManager, PlacemarkConfigurator { + public typealias TapHandlerClosure = (DataModel, Location) -> Bool + /// The current state of a manager's placemark + open var state: MarkerState = .default + + /// Point (coordinates) itself of the current placemark manager + public let placemarkPosition: Location? + + /// Model for the current placemark manager + public let dataModel: DataModel + public var tapHandler: TapHandlerClosure? public var iconFactory: AnyMarkerIconFactory? - public let dataModel: DataModel - - public init(dataModel: DataModel, + public init(placemarkPosition: Location? = nil, + dataModel: DataModel, iconFactory: AnyMarkerIconFactory?, tapHandler: TapHandlerClosure?) { + self.placemarkPosition = placemarkPosition self.dataModel = dataModel self.iconFactory = iconFactory self.tapHandler = tapHandler diff --git a/TIMapUtils/Sources/Managers/PlacemarkManager.swift b/TIMapUtils/Sources/Managers/PlacemarkManager.swift index 59066c3b..98731ad3 100644 --- a/TIMapUtils/Sources/Managers/PlacemarkManager.swift +++ b/TIMapUtils/Sources/Managers/PlacemarkManager.swift @@ -20,13 +20,15 @@ // THE SOFTWARE. // -public protocol PlacemarkManager { +public protocol PlacemarkManager: AnyObject { associatedtype DataModel associatedtype Position typealias TapHandlerClosure = (DataModel, Position) -> Bool + var placemarkPosition: Position? { get } var dataModel: DataModel { get } + var state: MarkerState { get set } /// /// Validates whether the current tap could be handled or not diff --git a/TIYandexMapUtils/Sources/YandexClusterPlacemarkManager.swift b/TIYandexMapUtils/Sources/YandexClusterPlacemarkManager.swift index d4cdf37e..472f2502 100644 --- a/TIYandexMapUtils/Sources/YandexClusterPlacemarkManager.swift +++ b/TIYandexMapUtils/Sources/YandexClusterPlacemarkManager.swift @@ -25,7 +25,10 @@ import YandexMapsMobile import UIKit import CoreLocation -open class YandexClusterPlacemarkManager: BasePlacemarkManager], [YMKPoint]>, +open class YandexClusterPlacemarkManager: BaseClusterPlacemarkManager], + [YMKPoint], + YMKPoint>, YMKClusterListener, YMKClusterTapListener { @@ -46,7 +49,7 @@ open class YandexClusterPlacemarkManager: BasePlacemarkManager: BasePlacemarkManager: BasePlacemarkManager [YandexPlacemarkManager] { diff --git a/TIYandexMapUtils/Sources/YandexPlacemarkManager.swift b/TIYandexMapUtils/Sources/YandexPlacemarkManager.swift index 8aff0742..2e18e9e2 100644 --- a/TIYandexMapUtils/Sources/YandexPlacemarkManager.swift +++ b/TIYandexMapUtils/Sources/YandexPlacemarkManager.swift @@ -26,14 +26,11 @@ import YandexMapsMobile open class YandexPlacemarkManager: BasePlacemarkManager, YMKMapObjectTapListener { - /// Point (coordinates) itself of the current placemark manager - public let position: YMKPoint - /// Placemark itself of the current placemark manager public private(set) var placemark: YMKPlacemarkMapObject? /// The current state of a manager's placemark - public var state: MarkerState = .default { + override public var state: MarkerState { didSet { guard let placemark = placemark else { return @@ -50,9 +47,8 @@ open class YandexPlacemarkManager: BasePlacemarkManager, tapHandler: TapHandlerClosure?) { - self.position = position - - super.init(dataModel: dataModel, + super.init(placemarkPosition: position, + dataModel: dataModel, iconFactory: iconFactory, tapHandler: tapHandler) }