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;
}
项目中的聚合效果图: