`BaseClusterPlacemarkManager` added
This commit is contained in:
parent
0090c83f87
commit
4c973b393d
|
|
@ -24,7 +24,10 @@ import TIMapUtils
|
|||
import MapKit
|
||||
import UIKit
|
||||
|
||||
open class AppleClusterPlacemarkManager<Model>: BasePlacemarkManager<MKAnnotationView, [ApplePlacemarkManager<Model>], MKMapRect>,
|
||||
open class AppleClusterPlacemarkManager<Model>: BaseClusterPlacemarkManager<MKAnnotationView,
|
||||
[ApplePlacemarkManager<Model>],
|
||||
MKMapRect,
|
||||
CLLocationCoordinate2D>,
|
||||
MKMapViewDelegate {
|
||||
|
||||
public weak var mapViewDelegate: MKMapViewDelegate?
|
||||
|
|
@ -51,16 +54,6 @@ open class AppleClusterPlacemarkManager<Model>: BasePlacemarkManager<MKAnnotatio
|
|||
open func removeMarkers(from map: MKMapView) {
|
||||
map.removeAnnotations(dataModel)
|
||||
}
|
||||
|
||||
/// Manual selecting of a placemark with an incoming point coordinates
|
||||
open func selectMarker(with point: CLLocationCoordinate2D) {
|
||||
dataModel.filter { $0.coordinate == point }.forEach { $0.state = .selected }
|
||||
}
|
||||
|
||||
/// Manual state resetting of all placemarks with currently selected state
|
||||
open func resetMarkersState() {
|
||||
dataModel.filter { $0.state == .selected }.forEach { $0.state = .default }
|
||||
}
|
||||
|
||||
// MARK: - PlacemarkManager
|
||||
|
||||
|
|
|
|||
|
|
@ -31,17 +31,19 @@ open class ApplePlacemarkManager<Model>: BasePlacemarkManager<MKAnnotationView,
|
|||
/// A map where all placemarks are placed
|
||||
public let map: MKMapView
|
||||
|
||||
/// Point (coordinates) itself of the current placemark manager
|
||||
public let coordinate: CLLocationCoordinate2D
|
||||
|
||||
/// Identifier required for correct cluster placement
|
||||
public var clusteringIdentifier: String?
|
||||
|
||||
/// Point (coordinates) itself of the current placemark manager
|
||||
public var coordinate: CLLocationCoordinate2D {
|
||||
placemarkPosition ?? .init()
|
||||
}
|
||||
|
||||
/// Placemark itself of the current placemark manager
|
||||
public private(set) var placemark: MKAnnotationView?
|
||||
|
||||
/// 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
|
||||
|
|
@ -67,10 +69,10 @@ open class ApplePlacemarkManager<Model>: BasePlacemarkManager<MKAnnotationView,
|
|||
tapHandler: TapHandlerClosure?) {
|
||||
|
||||
self.map = map
|
||||
self.coordinate = position
|
||||
self.clusteringIdentifier = clusteringIdentifier
|
||||
|
||||
super.init(dataModel: dataModel,
|
||||
super.init(placemarkPosition: position,
|
||||
dataModel: dataModel,
|
||||
iconFactory: iconFactory,
|
||||
tapHandler: tapHandler)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,10 @@ import TIMapUtils
|
|||
import GoogleMapsUtils
|
||||
import GoogleMaps
|
||||
|
||||
open class GoogleClusterPlacemarkManager<Model>: BasePlacemarkManager<GMSMarker, [GooglePlacemarkManager<Model>], GMSCoordinateBounds>,
|
||||
open class GoogleClusterPlacemarkManager<Model>: BaseClusterPlacemarkManager<GMSMarker,
|
||||
[GooglePlacemarkManager<Model>],
|
||||
GMSCoordinateBounds,
|
||||
CLLocationCoordinate2D>,
|
||||
GMUClusterRendererDelegate,
|
||||
GMUClusterManagerDelegate,
|
||||
GMUClusterIconGenerator {
|
||||
|
|
@ -77,16 +80,6 @@ open class GoogleClusterPlacemarkManager<Model>: BasePlacemarkManager<GMSMarker,
|
|||
open func removeMarkers() {
|
||||
clusterManager?.clearItems()
|
||||
}
|
||||
|
||||
/// Manual selecting of a placemark with an incoming point coordinates
|
||||
open func selectMarker(with point: CLLocationCoordinate2D) {
|
||||
dataModel.filter { $0.position == point }.forEach { $0.state = .selected }
|
||||
}
|
||||
|
||||
/// Manual state resetting of all placemarks with currently selected state
|
||||
open func resetMarkersState() {
|
||||
dataModel.filter { $0.state == .selected }.forEach { $0.state = .default }
|
||||
}
|
||||
|
||||
// MARK: - GMUClusterRendererDelegate
|
||||
|
||||
|
|
@ -121,7 +114,7 @@ open class GoogleClusterPlacemarkManager<Model>: BasePlacemarkManager<GMSMarker,
|
|||
return false
|
||||
}
|
||||
|
||||
return tapHandler?(placemarkManagers, .from(coordinates: placemarkManagers.map { $0.position }) ?? .init()) ?? false
|
||||
return tapHandler?(placemarkManagers, .from(coordinates: placemarkManagers.compactMap { $0.position }) ?? .init()) ?? false
|
||||
}
|
||||
|
||||
open func clusterManager(_ clusterManager: GMUClusterManager, didTap clusterItem: GMUClusterItem) -> Bool {
|
||||
|
|
|
|||
|
|
@ -30,13 +30,15 @@ open class GooglePlacemarkManager<Model>: BasePlacemarkManager<GMSMarker, Model,
|
|||
// MARK: - GMUClusterItem
|
||||
|
||||
/// Point (coordinates) itself of the current placemark manager
|
||||
public let position: CLLocationCoordinate2D
|
||||
public var position: CLLocationCoordinate2D {
|
||||
placemarkPosition ?? .init()
|
||||
}
|
||||
|
||||
/// Placemark itself of the current placemark manager
|
||||
public private(set) var placemark: GMSMarker?
|
||||
|
||||
/// 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
|
||||
|
|
@ -51,9 +53,8 @@ open class GooglePlacemarkManager<Model>: BasePlacemarkManager<GMSMarker, Model,
|
|||
iconFactory: AnyMarkerIconFactory<DataModel>?,
|
||||
tapHandler: TapHandlerClosure?) {
|
||||
|
||||
self.position = position
|
||||
|
||||
super.init(dataModel: dataModel,
|
||||
super.init(placemarkPosition: position,
|
||||
dataModel: dataModel,
|
||||
iconFactory: iconFactory,
|
||||
tapHandler: tapHandler)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Placemark, ClusterDataModel, ClusterPoints, Position: Equatable>:
|
||||
BasePlacemarkManager<Placemark, ClusterDataModel, ClusterPoints> {
|
||||
|
||||
/// Manual selecting of a placemark with an incoming point coordinates
|
||||
open func selectMarker(with point: Position) {
|
||||
guard let dataModel = dataModel as? Array<any PlacemarkManager> 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<any PlacemarkManager> else {
|
||||
return
|
||||
}
|
||||
|
||||
dataModel.filter { $0.state == .selected }.forEach { $0.state = .default }
|
||||
}
|
||||
}
|
||||
|
|
@ -23,17 +23,27 @@
|
|||
import ObjectiveC
|
||||
|
||||
open class BasePlacemarkManager<Placemark, DataModel, Location>: 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<DataModel>?
|
||||
|
||||
public let dataModel: DataModel
|
||||
|
||||
public init(dataModel: DataModel,
|
||||
public init(placemarkPosition: Location? = nil,
|
||||
dataModel: DataModel,
|
||||
iconFactory: AnyMarkerIconFactory<DataModel>?,
|
||||
tapHandler: TapHandlerClosure?) {
|
||||
|
||||
self.placemarkPosition = placemarkPosition
|
||||
self.dataModel = dataModel
|
||||
self.iconFactory = iconFactory
|
||||
self.tapHandler = tapHandler
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -25,7 +25,10 @@ import YandexMapsMobile
|
|||
import UIKit
|
||||
import CoreLocation
|
||||
|
||||
open class YandexClusterPlacemarkManager<Model>: BasePlacemarkManager<YMKCluster, [YandexPlacemarkManager<Model>], [YMKPoint]>,
|
||||
open class YandexClusterPlacemarkManager<Model>: BaseClusterPlacemarkManager<YMKCluster,
|
||||
[YandexPlacemarkManager<Model>],
|
||||
[YMKPoint],
|
||||
YMKPoint>,
|
||||
YMKClusterListener,
|
||||
YMKClusterTapListener {
|
||||
|
||||
|
|
@ -46,7 +49,7 @@ open class YandexClusterPlacemarkManager<Model>: BasePlacemarkManager<YMKCluster
|
|||
|
||||
let clusterizedPlacemarkCollection = map.mapObjects.addClusterizedPlacemarkCollection(with: self)
|
||||
|
||||
let emptyPlacemarks = clusterizedPlacemarkCollection.addEmptyPlacemarks(with: dataModel.map { $0.position })
|
||||
let emptyPlacemarks = clusterizedPlacemarkCollection.addEmptyPlacemarks(with: dataModel.compactMap { $0.placemarkPosition })
|
||||
|
||||
let placemarksZip = zip(emptyPlacemarks, dataModel)
|
||||
|
||||
|
|
@ -65,16 +68,6 @@ open class YandexClusterPlacemarkManager<Model>: BasePlacemarkManager<YMKCluster
|
|||
placemarkCollection?.clear()
|
||||
}
|
||||
|
||||
/// Manual selecting of a placemark with an incoming point coordinates
|
||||
open func selectMarker(with point: YMKPoint) {
|
||||
dataModel.filter { $0.position == point }.forEach { $0.state = .selected }
|
||||
}
|
||||
|
||||
/// Manual state resetting of all placemarks with currently selected state
|
||||
open func resetMarkersState() {
|
||||
dataModel.filter { $0.state == .selected }.forEach { $0.state = .default }
|
||||
}
|
||||
|
||||
// MARK: - YMKClusterListener
|
||||
|
||||
open func onClusterAdded(with cluster: YMKCluster) {
|
||||
|
|
@ -90,7 +83,7 @@ open class YandexClusterPlacemarkManager<Model>: BasePlacemarkManager<YMKCluster
|
|||
|
||||
let managersInCluster = managers(in: cluster)
|
||||
|
||||
return tapHandler(managersInCluster, managersInCluster.map { $0.position })
|
||||
return tapHandler(managersInCluster, managersInCluster.compactMap { $0.placemarkPosition })
|
||||
}
|
||||
|
||||
open func managers(in cluster: YMKCluster) -> [YandexPlacemarkManager<Model>] {
|
||||
|
|
|
|||
|
|
@ -26,14 +26,11 @@ import YandexMapsMobile
|
|||
open class YandexPlacemarkManager<Model>: BasePlacemarkManager<YMKPlacemarkMapObject, Model, YMKPoint>,
|
||||
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<Model>: BasePlacemarkManager<YMKPlacemarkMapOb
|
|||
iconFactory: AnyMarkerIconFactory<Model>,
|
||||
tapHandler: TapHandlerClosure?) {
|
||||
|
||||
self.position = position
|
||||
|
||||
super.init(dataModel: dataModel,
|
||||
super.init(placemarkPosition: position,
|
||||
dataModel: dataModel,
|
||||
iconFactory: iconFactory,
|
||||
tapHandler: tapHandler)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue