ClusterMap
ClusterMap是一个高性能地图聚合的开源库。当您想在地图上展示众多点以提供更好的用户体验和性能时,您可以从多个点中制作聚合点。一个好的起点是使用原生聚合机制。它易于实现,易于使用,且具有零代码即可拥有的动画。原生实现的核心问题是将所有点添加到主线程中的地图。您无法避免这个瓶颈,如果有成千上万的数据点进行操作,这将成为一个问题。ClusterMap使用高效的QuadTree存储并在后台线程中执行所有计算。
与20,000个注释的对比。要获取详细对比,请使用Example-UIKit。
特色功能
- UIKit
- SwiftUI
- Swift并发
- 添加/删除注释
- 聚合注释
- 多个管理者
- 动态禁用聚合
- 自定义单元格大小
- 自定义注释视图
演示
示例示例是一个很好的起点。它展示了如何
- 集成库
- 添加/删除注释
- 重新加载注释
- 配置注释视图
- 配置管理器
- 比较Apple的本地实现与库
安装
ClusterMap可通过Swift包管理器获取。
Swift包管理器
将以下依赖项添加到您的Package.swift文件中
.package(url: "https://github.com/vospennikov/ClusterMap.git", from: "1.1.0")
CocoaPods
ClusterMap可通过CocoaPods获取。要安装它,请将以下行添加到您的Podfile中
pod 'ClusterMap', '1.1.0'
使用方法
基础
《ClusterManager》类负责生成、管理和显示注释聚合。
let clusterManager = ClusterManager()
添加注释
创建一个符合《MKAnnotation》协议的对象。然后使用《add(annotation:)》方法将注释对象添加到一个《ClusterManager》实例中。
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: 21.283921, longitude: -157.831661)
manager.add(annotation)
配置注释视图
实现地图视图的《mapView(_:viewFor:)》代理方法以配置注释视图。返回一个《MKAnnotationView》实例以视觉表示注释。
为了显示聚合,返回一个《ClusterAnnotationView》实例。
extension ViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if let annotation = annotation as? ClusterAnnotation {
return CountClusterAnnotationView(annotation: annotation, reuseIdentifier: "cluster")
} else {
return MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin")
}
}
}
出于性能考虑,你通常应该在地图视图中重复使用《MKAnnotationView》对象。参见示例了解详情。
自定义外观
《ClusterAnnotationView》类公开了《countLabel》属性。你可以根据需要子类化《ClusterAnnotationView》以提供自定义行为。以下是一个子类化《ClusterAnnotationView》并自定义图层《borderColor》的示例。
class CountClusterAnnotationView: ClusterAnnotationView {
override func configure(_ annotation: ClusterAnnotation) {
super.configure(annotation)
layer.borderColor = UIColor.white.cgColor
layer.borderWidth = 1.5
}
}
参见《AnnotationView》以了解详情。
移除注释
要移除注释,可以调用《remove(annotation:)》。然而,注释会在调用《reload()`之前仍然显示。
manager.remove(annotation)
如果《shouldRemoveInvisibleAnnotations》设置为《false》,则删除的注释可能仍会在地图上显示,直到在可见区域调用《reload()`。
重新加载注释
实现地图视图的mapView(_:regionDidChangeAnimated:)
代理方法,当区域变化时重新加载ClusterManager
。
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
clusterManager.reload(mapView: mapView) { finished in
// handle completion
}
}
在添加或删除注释时您都应该调用reload()
。
配置管理器
ClusterManager
类公开了一些属性以配置聚类。
var zoomLevel: Double // The current zoom level of the visible map region.
var maxZoomLevel: Double // The maximum zoom level before disabling clustering.
var minCountForClustering: Int // The minimum number of annotations for a cluster. The default is `2`.
var shouldRemoveInvisibleAnnotations: Bool // Whether to remove invisible annotations. The default is `true`.
var shouldDistributeAnnotationsOnSameCoordinate: Bool // Whether to arrange annotations in a circle if they have the same coordinate. The default is `true`.
var distanceFromContestedLocation: Double // The distance in meters from contested location when the annotations have the same coordinate. The default is `3`.
var clusterPosition: ClusterAlignment // The position of the cluster annotation. The default is `.nearCenter`.
ClusterManagerDelegate
ClusterManagerDelegate
协议提供了许多函数来管理聚类和配置单元格。
// The size of each cell on the grid at a given zoom level.
func cellSize(for zoomLevel: Double) -> Double? { ... }
// Whether to cluster the given annotation.
func shouldClusterAnnotation(_ annotation: MKAnnotation) -> Bool { ... }
文档
版本和main
的文档在此处可查。
致谢
本项目基于Lasha Efremidze的工作,他创建了Cluster。
协议
ClusterMap可在MIT协议下使用。更多信息请参阅LICENSE文件。