BMKClusterManager 的這樣一個點聚合管理類.原理很簡單,就是當地圖縮放到某個級別的時候讓地圖顯示另外一個類型的大頭針.
百度地圖聚合功能的實現:
{
BMKClusterManager *_clusterManager;//點聚合管理類
NSInteger _clusterZoom;//聚合級別
CGFloat _clusterFloatZoom;//百度地圖聚合的浮點數級別
NSMutableArray *_clusterCaches;//點聚合緩存標註
NSInteger _previousZoom; // 記錄前一次的縮放等級
}
#pragma mark - 更新聚合狀態
//更新聚合狀態
- (void)updateClusters {
_clusterZoom = (NSInteger)_mapView.zoomLevel;
_clusterFloatZoom=_mapView.zoomLevel;
// NSLog(@"當前更新地圖的時候地圖的縮放級別爲: %f",_mapView.zoomLevel);
// NSLog(@"當前更新地圖時地圖的縮放級別取整結果: %ld",_clusterZoom);
//NSLog(@"--現在當前的地圖縮放級別爲 %d",_clusterZoom);
if (_clusterZoom<11) { // 目前是當地圖縮放級別小於 11 級的時候纔開始聚合
if (_dataSource.count < 150) {
return;
}
[self getStationModelToJuHeAnnotation];
@synchronized(_clusterCaches) {
__block NSMutableArray *clusters = [_clusterCaches objectAtIndex:(_clusterZoom -3)];
if (clusters.count > 0) {
[_mapView removeAnnotations:_mapView.annotations];
[_mapView addAnnotations:clusters];
[_mapView addAnnotation:_selfLocalModel];
} else {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
///獲取聚合後的標註
__block NSArray *array = [_clusterManager getClusters:_clusterFloatZoom];
dispatch_async(dispatch_get_main_queue(), ^{
for (BMKCluster *item in array) {
// 獲得每一個聚合之後標註的內容(個數,經緯度)
ClusterAnnotation *annotation = [[ClusterAnnotation alloc] init];
annotation.coordinate = item.coordinate;
annotation.size = item.size;
annotation.title = [NSString stringWithFormat:@"我是%ld個", item.size];
[clusters addObject:annotation];
int yellow=0;
int blue=0;
int gray=0;
for (JuHeModel* model in item.clusterItems) {
if ([model.categary intValue] ==3) {
yellow++;
}else if ([model.categary intValue] == 2){
blue++;
}else if([model.categary intValue] ==1){
gray++;
}
}
annotation.yellowCount=[NSString stringWithFormat:@"%d",yellow];
annotation.blewCount=[NSString stringWithFormat:@"%d",blue];
annotation.grayCount=[NSString stringWithFormat:@"%d",gray];
}
[_mapView removeAnnotations:_mapView.annotations];
[_mapView addAnnotations:clusters];
[_mapView addAnnotation:_selfLocalModel];
});
});
}
}
}else{
if (_previousZoom!= (NSInteger)_mapView.zoomLevel ) {
[_mapView removeAnnotations:_mapView.annotations];
[_mapView addAnnotations:_dataSource];
[_mapView addAnnotation:_selfLocalModel];
}
}
// 記錄前一次的縮放比例
_previousZoom=(NSInteger)_mapView.zoomLevel;
}
-(void)getStationModelToJuHeAnnotation
{
[self addJuHecoordinate:_dataSource];
}
-(void)addJuHecoordinate:(NSArray*)models
{
//點聚合管理類
_clusterManager = [[BMKClusterManager alloc] init];
for (LocalModel* model in models) {
JuHeModel* clusterItem=[[JuHeModel alloc] init];
clusterItem.coor=model.coordinate;
clusterItem.categary=model.category;
[_clusterManager addClusterItem:clusterItem];
}
}
- (void)mapView:(BMKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
NSLog(@"地圖代理中區域發生變化時當前地圖的所縮放級別:%f",mapView.zoomLevel);
if (_previousZoom != (NSInteger)mapView.zoomLevel) {
[self updateClusters];
}
}
// 根據anntation生成對應的View
/**
ClusterAnnotation 遵從BMKAnnotation 協議的大頭針模型
ClusterAnnotationView 爲自定義的聚合模型,目前展示的是外面一圈色帶展示所聚合區域類不同類型的佔比
*/
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id<BMKAnnotation>)annotation
{
[self hideHud];
//普通annotation
if ([annotation isKindOfClass:[ClusterAnnotation class]]) { // 聚合類
NSString *AnnotationViewID = @"ClusterMark";
ClusterAnnotation *cluster = (ClusterAnnotation*)annotation;
ClusterAnnotationView *annotationView = [[ClusterAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
annotationView.size = cluster.size;
// 按返回比例計算
// annotationView.bluScal=[cluster.blewCount intValue] * 1.0 / (cluster.size * 1.0);
// annotationView.yellowScal=[cluster.yellowCount intValue] * 1.0 / (cluster.size * 1.0);
// annotationView.grayScal=[cluster.grayCount intValue] * 1.0 / (cluster.size * 1.0);
// 周圍只選擇藍色一圈
annotationView.bluScal=1.0;
// NSLog(@"%d--%d %f %f %f",cluster.size,cluster.size-2, annotationView.bluScal,annotationView.yellowScal,annotationView.grayScal);
annotationView.draggable = YES;
//annotationView.canShowCallout=NO;
annotationView.annotation = cluster;
return annotationView;
}else if ([annotation isKindOfClass:[LocalModel class]]) { // 非聚合類
/** 根據數據模型 想展示怎樣的大頭針自己定義*/
return newAnnotationView;
}
return nil;
}
項目中的聚合效果圖: